{"version":3,"file":"WebSocketTransport.mjs","sources":["../../src/transport/WebSocketTransport.ts"],"sourcesContent":["import NodeWebSocket from \"ws\";\nimport { CloseCode } from \"@colyseus/shared-types\";\nimport type { ITransport, ITransportEventMap } from \"./ITransport.ts\";\n\nconst WebSocket = globalThis.WebSocket || NodeWebSocket;\n\n// Once per process — the fallback is per-send, and a 60Hz input ring would\n// otherwise flood the console.\nlet warnedNoUnreliableChannel = false;\n\nexport class WebSocketTransport implements ITransport {\n    ws: WebSocket | NodeWebSocket;\n    protocols?: string | string[];\n\n    events: ITransportEventMap;\n\n    constructor(events: ITransportEventMap) {\n        this.events = events;\n    }\n\n    public send(data: Buffer | Uint8Array): void {\n        this.ws.send(data);\n    }\n\n    /**\n     * WebSocket has no unreliable channel, so this falls back to the reliable\n     * one — which is what every caller is written against (see `sendRequest`,\n     * and the input handle's redundancy ring). Dropping instead loses every\n     * `mode:\"unreliable\"` input and request silently: the server never sees\n     * them, and the client's pending set grows without bound because nothing\n     * is ever acked.\n     *\n     * The cost of falling back is bandwidth, not correctness — an input ring\n     * carries `historySize` redundant slots the ordered channel doesn't need,\n     * and the server dedupes them by wire seq exactly as it would over\n     * datagrams. Use `@colyseus/h3-transport` for real unreliable delivery.\n     */\n    public sendUnreliable(data: Buffer | Uint8Array): void {\n        if (!warnedNoUnreliableChannel) {\n            warnedNoUnreliableChannel = true;\n            console.warn(\"@colyseus/sdk: the WebSocket transport has no unreliable channel — sending `mode:\\\"unreliable\\\"` traffic reliably instead. Use @colyseus/h3-transport (WebTransport) for datagram delivery.\");\n        }\n        this.send(data);\n    }\n\n    /**\n     * @param url URL to connect to\n     * @param headers custom headers to send with the connection (only supported in Node.js. Web Browsers do not allow setting custom headers)\n     */\n    public connect(url: string, headers?: any): void {\n        try {\n            // Node or Bun environments (supports custom headers)\n            this.ws = new WebSocket(url, { headers, protocols: this.protocols });\n\n        } catch (e) {\n            // browser environment (custom headers not supported)\n            this.ws = new WebSocket(url, this.protocols);\n        }\n\n        this.ws.binaryType = 'arraybuffer';\n        this.ws.onopen = (event) => this.events.onopen?.(event);\n        this.ws.onmessage = (event) => this.events.onmessage?.(event);\n        this.ws.onclose = (event) => this.events.onclose?.(event);\n        this.ws.onerror = (event) => this.events.onerror?.(event);\n    }\n\n    public close(code?: number, reason?: string) {\n        //\n        // trigger the onclose event immediately if the code is MAY_TRY_RECONNECT\n        // when \"offline\" event is triggered, the close frame is delayed. this\n        // way client can try to reconnect immediately.\n        //\n        if (code === CloseCode.MAY_TRY_RECONNECT && this.events.onclose) {\n            this.ws.onclose = null;\n            this.events.onclose({ code, reason });\n        }\n\n        // then we close the connection\n        this.ws.close(code, reason);\n    }\n\n    get isOpen() {\n        return this.ws.readyState === WebSocket.OPEN;\n    }\n\n}\n"],"names":[],"mappings":";;;;;;;;;AAIA,MAAM,SAAS,GAAG,UAAU,CAAC,SAAS,IAAI,aAAa;AAEvD;AACA;AACA,IAAI,yBAAyB,GAAG,KAAK;MAExB,kBAAkB,CAAA;AAC3B,IAAA,EAAE;AACF,IAAA,SAAS;AAET,IAAA,MAAM;AAEN,IAAA,WAAA,CAAY,MAA0B,EAAA;AAClC,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM;IACxB;AAEO,IAAA,IAAI,CAAC,IAAyB,EAAA;AACjC,QAAA,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;IACtB;AAEA;;;;;;;;;;;;AAYG;AACI,IAAA,cAAc,CAAC,IAAyB,EAAA;QAC3C,IAAI,CAAC,yBAAyB,EAAE;YAC5B,yBAAyB,GAAG,IAAI;AAChC,YAAA,OAAO,CAAC,IAAI,CAAC,6LAA6L,CAAC;QAC/M;AACA,QAAA,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IACnB;AAEA;;;AAGG;IACI,OAAO,CAAC,GAAW,EAAE,OAAa,EAAA;AACrC,QAAA,IAAI;;AAEA,YAAA,IAAI,CAAC,EAAE,GAAG,IAAI,SAAS,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;QAExE;QAAE,OAAO,CAAC,EAAE;;AAER,YAAA,IAAI,CAAC,EAAE,GAAG,IAAI,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC;QAChD;AAEA,QAAA,IAAI,CAAC,EAAE,CAAC,UAAU,GAAG,aAAa;AAClC,QAAA,IAAI,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,KAAK,KAAK,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC;AACvD,QAAA,IAAI,CAAC,EAAE,CAAC,SAAS,GAAG,CAAC,KAAK,KAAK,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,KAAK,CAAC;AAC7D,QAAA,IAAI,CAAC,EAAE,CAAC,OAAO,GAAG,CAAC,KAAK,KAAK,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;AACzD,QAAA,IAAI,CAAC,EAAE,CAAC,OAAO,GAAG,CAAC,KAAK,KAAK,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;IAC7D;IAEO,KAAK,CAAC,IAAa,EAAE,MAAe,EAAA;;;;;;AAMvC,QAAA,IAAI,IAAI,KAAK,SAAS,CAAC,iBAAiB,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;AAC7D,YAAA,IAAI,CAAC,EAAE,CAAC,OAAO,GAAG,IAAI;YACtB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QACzC;;QAGA,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC;IAC/B;AAEA,IAAA,IAAI,MAAM,GAAA;QACN,OAAO,IAAI,CAAC,EAAE,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI;IAChD;AAEH;;;;"}