{"version":3,"sources":["websocket-interface.ts"],"sourcesContent":["import { CommunicationInterface, CommunicationInterfaceSocket } from \"../communication-interface.ts\";\nimport { getOnlineState } from \"../online-state.ts\";\n\n/**\n * WebSocket interface socket, used by WebSocket client and server interfaces\n */\nexport class WebSocketInterfaceSocket extends CommunicationInterfaceSocket {\n    constructor(public readonly webSocket: WebSocket) {\n        super();\n    }\n\n    handleReceive = (event: MessageEvent) => {\n        this.receive(event.data)\n    }\n\n    open() {\n        this.webSocket.addEventListener('message', this.handleReceive);\n    }\n\n    close() {\n        this.webSocket.removeEventListener('message', this.handleReceive);\n    }\n\n    send(datex: ArrayBuffer) {\n        try {\n            this.webSocket.send(datex)\n            return true;\n        }\n        catch {\n            return false;\n        }\n    }\n}\n\n/**\n * Common base class for WebSocket client and server interfaces\n */\nexport abstract class WebSocketInterface extends CommunicationInterface<WebSocketInterfaceSocket> {\n\n    #webSockets = new Map<WebSocket, {\n        errorHandler: () => void,\n        openHandler: () => void\n    }>()\n\n    initWebSocket(webSocket: WebSocket) {\n        return new Promise<boolean>(resolve => {\n            try {\n                webSocket.binaryType = 'arraybuffer';\n\n                const socket = new WebSocketInterfaceSocket(webSocket)\n        \n                let connectionOpen = false;\n                const errorHandler = () => {\n                    // don't trigger any further errorHandlers\n                    webSocket.removeEventListener('close', errorHandler);\n                    webSocket.removeEventListener('error', errorHandler);\n\n                    this.#webSockets.delete(webSocket);\n                    if (webSocket.readyState !== WebSocket.CLOSED) {\n                        // make sure the socket is closed\n                        try {webSocket.close()} catch {/*ignore*/} \n                    }\n\n                    if (!connectionOpen) resolve(false);\n                    else {\n                        this.removeSocket(socket);\n                        this.onWebSocketClosed(socket)\n                    }\n                };\n\n                const openHandler = async () => {\n                    await this.addSocket(socket);\n                    connectionOpen = true;\n                    this.onWebSocketOpened(webSocket);\n                    resolve(true);\n                };\n\n                // webSocket already open, call openHandler immediately\n                if (webSocket.readyState === WebSocket.OPEN) {\n                    openHandler();\n                }\n\n                webSocket.addEventListener('open', openHandler);\n                webSocket.addEventListener('error', errorHandler);\n                webSocket.addEventListener('close', errorHandler);\n                \n                const onlineState = getOnlineState();\n                effect(()=>{\n                    if (!onlineState.val)\n                        errorHandler();\n                });\n                \n                this.#webSockets.set(webSocket, {\n                    errorHandler,\n                    openHandler\n                })\n            }\n            catch {\n                resolve(false)\n            }\n        })\n    }\n\n    /**\n     * Called when a new WebSocket connection is opened\n     */\n    abstract onWebSocketOpened(webSocket: WebSocket): void\n\n    /**\n     * Called when a WebSocket connection is closed\n     */\n    abstract onWebSocketClosed(socket: WebSocketInterfaceSocket): void\n\n    disconnect() {\n        for (const [webSocket, {errorHandler, openHandler}] of this.#webSockets.entries()) {\n            try {\n                webSocket.removeEventListener('open', openHandler);\n                webSocket.removeEventListener('error', errorHandler);\n                webSocket.removeEventListener('close', errorHandler);\n                webSocket.close();\n            }\n            catch {}\n        }\n        this.#webSockets.clear();\n    }\n\n    cloneSocket(socket: WebSocketInterfaceSocket) {\n        return new WebSocketInterfaceSocket(socket.webSocket);\n    }\n}"],"names":["CommunicationInterface","CommunicationInterfaceSocket","getOnlineState","WebSocketInterfaceSocket","constructor","webSocket","handleReceive","event","receive","data","open","addEventListener","close","removeEventListener","send","datex","WebSocketInterface","Map","initWebSocket","Promise","resolve","binaryType","socket","connectionOpen","errorHandler","delete","readyState","WebSocket","CLOSED","removeSocket","onWebSocketClosed","openHandler","addSocket","onWebSocketOpened","OPEN","onlineState","effect","val","set","disconnect","entries","clear","cloneSocket"],"mappings":"AAAA,SAASA,sBAAsB,EAAEC,4BAA4B,QAAQ,gCAAgC;AACrG,SAASC,cAAc,QAAQ,qBAAqB;AAKpD,OAAO,MAAMC,iCAAiCF;;IAC1CG,YAAY,AAAgBC,SAAoB,CAAE;QAC9C,KAAK,SADmBA,YAAAA,gBAI5BC,gBAAgB,CAACC;YACb,IAAI,CAACC,OAAO,CAACD,MAAME,IAAI;QAC3B;IAJA;IAEAH,cAEC;IAEDI,OAAO;QACH,IAAI,CAACL,SAAS,CAACM,gBAAgB,CAAC,WAAW,IAAI,CAACL,aAAa;IACjE;IAEAM,QAAQ;QACJ,IAAI,CAACP,SAAS,CAACQ,mBAAmB,CAAC,WAAW,IAAI,CAACP,aAAa;IACpE;IAEAQ,KAAKC,KAAkB,EAAE;QACrB,IAAI;YAEA,OADA,IAAI,CAACV,SAAS,CAACS,IAAI,CAACC,QACb,CAAA;QACX,EACA,OAAM;YACF,OAAO,CAAA;QACX;IACJ;AACJ;AAKA,OAAO,MAAeC,2BAA2BhB;IAE7C,CAAA,UAAW,GAAG,IAAIiB,MAGd;IAEJC,cAAcb,SAAoB,EAAE;QAChC,OAAO,IAAIc,QAAiBC,CAAAA;YACxB,IAAI;gBACAf,UAAUgB,UAAU,GAAG;gBAEvB,IAAMC,SAAS,IAAInB,yBAAyBE,YAExCkB,iBAAiB,CAAA,GACfC,eAAe;oBAMjB,IAJAnB,UAAUQ,mBAAmB,CAAC,SAASW,eACvCnB,UAAUQ,mBAAmB,CAAC,SAASW,eAEvC,IAAI,CAAC,CAAA,UAAW,CAACC,MAAM,CAACpB,YACpBA,UAAUqB,UAAU,KAAKC,UAAUC,MAAM,EAEzC,IAAI;wBAACvB,UAAUO,KAAK;oBAAE,EAAE,OAAM,CAAW;oBAGxCW,kBAED,IAAI,CAACM,YAAY,CAACP,SAClB,IAAI,CAACQ,iBAAiB,CAACR,WAHNF,QAAQ,CAAA;gBAKjC,GAEMW,cAAc;oBAChB,MAAM,IAAI,CAACC,SAAS,CAACV,SACrBC,iBAAiB,CAAA,GACjB,IAAI,CAACU,iBAAiB,CAAC5B,YACvBe,QAAQ,CAAA;gBACZ;gBAGIf,UAAUqB,UAAU,KAAKC,UAAUO,IAAI,IACvCH,eAGJ1B,UAAUM,gBAAgB,CAAC,QAAQoB,cACnC1B,UAAUM,gBAAgB,CAAC,SAASa,eACpCnB,UAAUM,gBAAgB,CAAC,SAASa;gBAEpC,IAAMW,cAAcjC;gBACpBkC,OAAO;oBACED,YAAYE,GAAG,IAChBb;gBACR,IAEA,IAAI,CAAC,CAAA,UAAW,CAACc,GAAG,CAACjC,WAAW;oBAC5BmB;oBACAO;gBACJ;YACJ,EACA,OAAM;gBACFX,QAAQ,CAAA;YACZ;QACJ;IACJ;IAYAmB,aAAa;QACT,KAAK,IAAM,CAAClC,WAAW,EAACmB,YAAY,EAAEO,WAAW,EAAC,CAAC,IAAI,IAAI,CAAC,CAAA,UAAW,CAACS,OAAO,GAC3E,IAAI;YACAnC,UAAUQ,mBAAmB,CAAC,QAAQkB,cACtC1B,UAAUQ,mBAAmB,CAAC,SAASW,eACvCnB,UAAUQ,mBAAmB,CAAC,SAASW,eACvCnB,UAAUO,KAAK;QACnB,EACA,OAAM,CAAC;QAEX,IAAI,CAAC,CAAA,UAAW,CAAC6B,KAAK;IAC1B;IAEAC,YAAYpB,MAAgC,EAAE;QAC1C,OAAO,IAAInB,yBAAyBmB,OAAOjB,SAAS;IACxD;AACJ","sourceRoot":"/lib/datex-core-js-legacy-0.3.15/network/communication-interfaces/","file":"websocket-interface.ts"}