"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createWebSocketServer = exports.HMR_HEADER = void 0;
const chalk_1 = __importDefault(require("chalk"));
const ws_1 = __importDefault(require("ws"));
exports.HMR_HEADER = 'vite-hmr';
function createWebSocketServer(server, logger) {
    const wss = new ws_1.default.Server({ noServer: true });
    server.on('upgrade', (req, socket, head) => {
        if (req.headers['sec-websocket-protocol'] === exports.HMR_HEADER) {
            wss.handleUpgrade(req, socket, head, (ws) => {
                wss.emit('connection', ws, req);
            });
        }
    });
    wss.on('connection', (socket) => {
        socket.send(JSON.stringify({ type: 'connected' }));
        if (bufferedError) {
            socket.send(JSON.stringify(bufferedError));
            bufferedError = null;
        }
    });
    wss.on('error', (e) => {
        if (e.code !== 'EADDRINUSE') {
            logger.error(chalk_1.default.red(`WebSocket server error:\n${e.stack || e.message}`));
        }
    });
    // On page reloads, if a file fails to compile and returns 500, the server
    // sends the error payload before the client connection is established.
    // If we have no open clients, buffer the error and send it to the next
    // connected client.
    let bufferedError = null;
    return {
        send(payload) {
            if (payload.type === 'error' && !wss.clients.size) {
                bufferedError = payload;
                return;
            }
            const stringified = JSON.stringify(payload);
            wss.clients.forEach((client) => {
                if (client.readyState === ws_1.default.OPEN) {
                    client.send(stringified);
                }
            });
        },
        close() {
            return new Promise((resolve, reject) => {
                wss.close((err) => {
                    if (err) {
                        reject(err);
                    }
                    else {
                        resolve();
                    }
                });
            });
        }
    };
}
exports.createWebSocketServer = createWebSocketServer;
//# sourceMappingURL=ws.js.map