"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.WsMiddlewareStack = void 0;
const events_1 = __importDefault(require("events"));
class WsMiddlewareStack {
    fns = [];
    use(fn) {
        this.fns.push(fn);
        return this;
    }
    attach(ws, onMessage) {
        ws.on("message", async (data) => {
            let i = 0;
            const next = async (err) => {
                if (err) {
                    console.error("WS middleware rejected message:", err.message);
                    ws.close(1008, err.message);
                    return;
                }
                const fn = this.fns[i++];
                if (fn) {
                    await fn(ws, data, next);
                }
                else {
                    onMessage(data);
                }
            };
            await next();
        });
    }
    wrapSocket(ws) {
        const innerEmitter = new events_1.default();
        ws.on("message", async (data) => {
            let i = 0;
            const next = async (err) => {
                if (err) {
                    console.error("WS middleware rejected message:", err.message);
                    ws.close(1008, err.message);
                    return;
                }
                const fn = this.fns[i++];
                if (fn) {
                    await fn(ws, data, next);
                }
                else {
                    innerEmitter.emit("message", data);
                }
            };
            await next();
        });
        const originalOn = ws.on.bind(ws);
        ws.on = (event, listener) => {
            if (event === "message") {
                innerEmitter.on("message", listener);
                return ws;
            }
            return originalOn(event, listener);
        };
    }
}
exports.WsMiddlewareStack = WsMiddlewareStack;
//# sourceMappingURL=WsMiddleware.js.map