insite-ws 2.0.1 → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bun.lockb CHANGED
Binary file
@@ -0,0 +1,26 @@
1
+ import EventEmitter from "eventemitter3";
2
+ import { Options } from "./types";
3
+ export declare class InSiteWebSocket extends EventEmitter {
4
+ #private;
5
+ constructor(url: string, options?: Options);
6
+ readonly isWebSocket = true;
7
+ readonly isWebSocketServer = false;
8
+ readonly isWebSocketServerClient = false;
9
+ url: string;
10
+ name: string;
11
+ protocols?: string[];
12
+ autoReconnect: boolean;
13
+ send?(data: ArrayBufferLike | ArrayBufferView | Blob | string): void;
14
+ webSocket: null | WebSocket;
15
+ get isConnecting(): boolean | null;
16
+ get isOpen(): boolean | null;
17
+ get isClosing(): boolean | null;
18
+ get isClosed(): boolean | null;
19
+ open(options?: Options): Promise<unknown>;
20
+ connect: (options?: Options) => Promise<unknown>;
21
+ close(code?: number, reason?: string): Promise<unknown>;
22
+ disconnect: (code?: number, reason?: string) => Promise<unknown>;
23
+ sendMessage(...args: unknown[]): void;
24
+ static defib(this: InSiteWebSocket): void;
25
+ }
26
+ //# sourceMappingURL=WebSocket.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebSocket.d.ts","sourceRoot":"","sources":["../../src/client/WebSocket.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,eAAe,CAAC;AAGzC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAUlC,qBAAa,eAAgB,SAAQ,YAAY;;gBACpC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,OAAY;IA6B9C,QAAQ,CAAC,WAAW,QAAQ;IAC5B,QAAQ,CAAC,iBAAiB,SAAS;IACnC,QAAQ,CAAC,uBAAuB,SAAS;IAEzC,GAAG,EAAE,MAAM,CAAC;IAEZ,IAAI,EAAE,MAAM,CAAC;IAEb,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IAErB,aAAa,EAAE,OAAO,CAAC;IAEvB,IAAI,CAAC,CAAC,IAAI,EAAE,eAAe,GAAG,eAAe,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI;IAEpE,SAAS,EAAE,IAAI,GAAG,SAAS,CAAQ;IAInC,IAAI,YAAY,mBAEf;IAED,IAAI,MAAM,mBAET;IAED,IAAI,SAAS,mBAEZ;IAED,IAAI,QAAQ,mBAEX;IAqEK,IAAI,CAAC,OAAO,GAAE,OAAY;IAmChC,OAAO,aAnCa,OAAO,sBAmCP;IAEpB,KAAK,CAAC,IAAI,SAAO,EAAE,MAAM,SAAW;IAcpC,UAAU,uDAAc;IAaxB,WAAW,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE;IAe9B,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,eAAe;CAWlC"}
@@ -0,0 +1,2 @@
1
+ export * from "./WebSocket";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC"}
@@ -0,0 +1,2 @@
1
+ var T=Object.defineProperty;var E=t=>{throw TypeError(t)};var $=(t,s,e)=>s in t?T(t,s,{enumerable:!0,configurable:!0,writable:!0,value:e}):t[s]=e;var n=(t,s,e)=>$(t,typeof s!="symbol"?s+"":s,e),O=(t,s,e)=>s.has(t)||E("Cannot "+e);var i=(t,s,e)=>(O(t,s,"read from private field"),e?e.call(t):s.get(t)),r=(t,s,e)=>s.has(t)?E("Cannot add the same private member more than once"):s instanceof WeakSet?s.add(t):s.set(t,e),h=(t,s,e,o)=>(O(t,s,"write to private field"),o?o.call(t,e):s.set(t,e),e);import D from"eventemitter3";import{debounce as G,noop as W}from"@nesvet/n";var I=2e3,V=0,y=new WeakMap,u,l,a,f,p,S,b,m,d,w,v=class v extends D{constructor(e,o={}){super();n(this,"isWebSocket",!0);n(this,"isWebSocketServer",!1);n(this,"isWebSocketServerClient",!1);n(this,"url");n(this,"name");n(this,"protocols");n(this,"autoReconnect");n(this,"webSocket",null);r(this,u,G(v.defib,65e3));r(this,l);r(this,a);r(this,f,()=>{i(this,l).call(this),h(this,l,void 0),h(this,a,void 0),this.emit("open"),i(this,u).call(this)});r(this,p,({data:e})=>{if(i(this,u).call(this),e)try{let[o,...c]=JSON.parse(e);this.emit("message",o,...c),this.emit(`message:${o}`,...c)}catch(o){i(this,S).call(this,o)}else this.webSocket.send("")});r(this,S,e=>{e instanceof Event&&(e=void 0),i(this,a)&&(i(this,a).call(this,e),h(this,l,void 0),h(this,a,void 0)),this.emit("error",e)});r(this,b);r(this,m,e=>{process.env.NODE_ENV==="development"&&console.info(`WebSocket ${this.name} is closed with code ${e.code} and reason "${e.reason}"`),i(this,u).clear(),this.emit("close",e),this.autoReconnect&&![1002,3500,4e3].includes(e.code)&&(process.env.NODE_ENV==="development"&&console.info(`WebSocket ${this.name} will try to reconnect in 2 sec\u2026`),h(this,b,setTimeout(()=>this.open().catch(W),I)))});n(this,"connect",this.open);n(this,"disconnect",this.close);r(this,d,[]);r(this,w,()=>{for(let e of i(this,d))this.webSocket.send(e);i(this,d).length=0});this.url=e;let{name:c=(V++).toString(),protocols:C,immediately:L=!0,autoReconnect:R=!0,on:k}=o;if(this.name=c,this.protocols=C,this.autoReconnect=!!R,k)for(let g in k)k[g]&&this.on(g,k[g]);this.url&&L&&this.open().catch(W)}get isConnecting(){return this.webSocket?this.webSocket.readyState===this.webSocket.CONNECTING:null}get isOpen(){return this.webSocket?this.webSocket.readyState===this.webSocket.OPEN:null}get isClosing(){return this.webSocket?this.webSocket.readyState===this.webSocket.CLOSING:null}get isClosed(){return this.webSocket?this.webSocket.readyState===this.webSocket.CLOSED:null}async open(e={}){return clearTimeout(i(this,b)),await this.close(4e3,"reopen"),e.url&&(this.url=e.url),e.protocols&&(this.protocols=e.protocols),this.webSocket&&y.get(this.webSocket)!==this.url&&this.emit("server-change"),new Promise((o,c)=>{h(this,l,o),h(this,a,c),this.webSocket=new WebSocket(this.url,this.protocols),this.webSocket.addEventListener("open",i(this,f)),this.webSocket.addEventListener("message",i(this,p)),this.webSocket.addEventListener("error",i(this,S)),this.webSocket.addEventListener("close",i(this,m)),this.send=this.webSocket.send.bind(this.webSocket),y.set(this.webSocket,this.url),this.emit("connecting")})}close(e=3500,o="manual"){return clearTimeout(i(this,b)),new Promise(c=>{this.isConnecting||this.isOpen?(this.webSocket.addEventListener("close",c),this.webSocket.close(e,o)):c(null)})}sendMessage(...e){let o=JSON.stringify(e);this.isOpen?this.webSocket.send(o):(i(this,d).length||this.once("open",i(this,w)),i(this,d).push(o))}static defib(){this.isOpen&&(process.env.NODE_ENV==="development"&&console.info(`WebSocket ${this.name} has no heartbeat - going offline`),this.webSocket.close())}};u=new WeakMap,l=new WeakMap,a=new WeakMap,f=new WeakMap,p=new WeakMap,S=new WeakMap,b=new WeakMap,m=new WeakMap,d=new WeakMap,w=new WeakMap;var N=v;export{N as InSiteWebSocket};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/client/WebSocket.ts"],
4
+ "sourcesContent": ["import EventEmitter from \"eventemitter3\";\nimport { debounce, noop } from \"@nesvet/n\";\nimport { heartbeatGap, heartbeatInterval } from \"../common\";\nimport { Options } from \"./types\";\n\n\nconst reconnectTimeout = 2000;\n\nlet i = 0;\n\nconst webSocketUrlWeakMap = new WeakMap<WebSocket, string>();\n\n\nexport class InSiteWebSocket extends EventEmitter {\n\tconstructor(url: string, options: Options = {}) {\n\t\tsuper();\n\t\t\n\t\tthis.url = url;\n\t\t\n\t\tconst {\n\t\t\tname = (i++).toString(),\n\t\t\tprotocols,\n\t\t\timmediately = true,\n\t\t\tautoReconnect = true,\n\t\t\ton\n\t\t} = options;\n\t\t\n\t\tthis.name = name;\n\t\t\n\t\tthis.protocols = protocols;\n\t\t\n\t\tthis.autoReconnect = !!autoReconnect;\n\t\t\n\t\tif (on)\n\t\t\tfor (const eventName in on)\n\t\t\t\tif (on[eventName])\n\t\t\t\t\tthis.on(eventName, on[eventName]);\n\t\t\n\t\tif (this.url && immediately)\n\t\t\tthis.open().catch(noop);\n\t\t\n\t}\n\t\n\treadonly isWebSocket = true;\n\treadonly isWebSocketServer = false;\n\treadonly isWebSocketServerClient = false;\n\t\n\turl: string;\n\t\n\tname: string;\n\t\n\tprotocols?: string[];\n\t\n\tautoReconnect: boolean;\n\t\n\tsend?(data: ArrayBufferLike | ArrayBufferView | Blob | string): void;\n\t\n\twebSocket: null | WebSocket = null;\n\t\n\t#defib = debounce(InSiteWebSocket.defib, heartbeatInterval + heartbeatGap);\n\t\n\tget isConnecting() {\n\t\treturn this.webSocket ? this.webSocket.readyState === this.webSocket.CONNECTING : null;\n\t}\n\t\n\tget isOpen() {\n\t\treturn this.webSocket ? this.webSocket.readyState === this.webSocket.OPEN : null;\n\t}\n\t\n\tget isClosing() {\n\t\treturn this.webSocket ? this.webSocket.readyState === this.webSocket.CLOSING : null;\n\t}\n\t\n\tget isClosed() {\n\t\treturn this.webSocket ? this.webSocket.readyState === this.webSocket.CLOSED : null;\n\t}\n\t\n\t#openResolve?: (value?: unknown) => void;\n\t#openReject?: (reason?: unknown) => void;\n\t\n\t#handleWebSocketOpen = () => {\n\t\t\n\t\tthis.#openResolve!();\n\t\tthis.#openResolve = undefined;\n\t\tthis.#openReject = undefined;\n\t\t\n\t\tthis.emit(\"open\");\n\t\t\n\t\tthis.#defib();\n\t\t\n\t};\n\t\n\t#handleWebSocketMessage = ({ data: message }: MessageEvent) => {\n\t\t\n\t\tthis.#defib();\n\t\t\n\t\tif (message)\n\t\t\ttry {\n\t\t\t\tconst [ kind, ...rest ] = JSON.parse(message);\n\t\t\t\t\n\t\t\t\tthis.emit(\"message\", kind, ...rest);\n\t\t\t\tthis.emit(`message:${kind}`, ...rest);\n\t\t\t} catch (error) {\n\t\t\t\tthis.#handleWebSocketError(error as Error);\n\t\t\t}\n\t\telse\n\t\t\tthis.webSocket!.send(\"\");\n\t\t\n\t};\n\t\n\t#handleWebSocketError = (error: Error | Event | undefined) => {\n\t\tif (error instanceof Event)\n\t\t\terror = undefined;\n\t\t\n\t\tif (this.#openReject) {\n\t\t\tthis.#openReject(error);\n\t\t\tthis.#openResolve = undefined;\n\t\t\tthis.#openReject = undefined;\n\t\t}\n\t\t\n\t\tthis.emit(\"error\", error);\n\t\t\n\t};\n\t\n\t#reconnectTimeout?: number;\n\t\n\t#handleWebSocketClose = (event: CloseEvent) => {\n\t\t\n\t\tif (process.env.NODE_ENV === \"development\")\n\t\t\tconsole.info(`WebSocket ${this.name} is closed with code ${event.code} and reason \"${event.reason}\"`);\n\t\t\n\t\tthis.#defib.clear();\n\t\t\n\t\tthis.emit(\"close\", event);\n\t\t\n\t\tif (this.autoReconnect && ![ 1002, 3500, 4000 ].includes(event.code)) {\n\t\t\tif (process.env.NODE_ENV === \"development\")\n\t\t\t\tconsole.info(`WebSocket ${this.name} will try to reconnect in 2 sec\u2026`);\n\t\t\t\n\t\t\tthis.#reconnectTimeout = setTimeout(() => this.open().catch(noop), reconnectTimeout) as unknown as number;\n\t\t}\n\t\t\n\t};\n\t\n\tasync open(options: Options = {}) {\n\t\t\n\t\tclearTimeout(this.#reconnectTimeout);\n\t\t\n\t\tawait this.close(4000, \"reopen\");\n\t\t\n\t\tif (options.url)\n\t\t\tthis.url = options.url;\n\t\t\n\t\tif (options.protocols)\n\t\t\tthis.protocols = options.protocols;\n\t\t\n\t\tif (this.webSocket && webSocketUrlWeakMap.get(this.webSocket) !== this.url)\n\t\t\tthis.emit(\"server-change\");\n\t\t\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.#openResolve = resolve;\n\t\t\tthis.#openReject = reject;\n\t\t\t\n\t\t\tthis.webSocket = new WebSocket(this.url, this.protocols);\n\t\t\t\n\t\t\tthis.webSocket.addEventListener(\"open\", this.#handleWebSocketOpen);\n\t\t\tthis.webSocket.addEventListener(\"message\", this.#handleWebSocketMessage);\n\t\t\tthis.webSocket.addEventListener(\"error\", this.#handleWebSocketError);\n\t\t\tthis.webSocket.addEventListener(\"close\", this.#handleWebSocketClose);\n\t\t\t\n\t\t\tthis.send = this.webSocket.send.bind(this.webSocket);\n\t\t\t\n\t\t\twebSocketUrlWeakMap.set(this.webSocket, this.url);\n\t\t\t\n\t\t\tthis.emit(\"connecting\");\n\t\t\t\n\t\t});\n\t}\n\t\n\tconnect = this.open;\n\t\n\tclose(code = 3500, reason = \"manual\") {\n\t\t\n\t\tclearTimeout(this.#reconnectTimeout);\n\t\t\n\t\treturn new Promise(resolve => {\n\t\t\tif (this.isConnecting || this.isOpen) {\n\t\t\t\tthis.webSocket!.addEventListener(\"close\", resolve);\n\t\t\t\tthis.webSocket!.close(code, reason);\n\t\t\t} else\n\t\t\t\tresolve(null);\n\t\t\t\n\t\t});\n\t}\n\t\n\tdisconnect = this.close;\n\t\n\t#queue: string[] = [];\n\t\n\t#releaseQueue = () => {\n\t\t\n\t\tfor (const message of this.#queue)\n\t\t\tthis.webSocket!.send(message);\n\t\t\n\t\tthis.#queue.length = 0;\n\t\t\n\t};\n\t\n\tsendMessage(...args: unknown[]) {\n\t\tconst message = JSON.stringify(args);\n\t\t\n\t\tif (this.isOpen)\n\t\t\tthis.webSocket!.send(message);\n\t\telse {\n\t\t\tif (!this.#queue.length)\n\t\t\t\tthis.once(\"open\", this.#releaseQueue);\n\t\t\t\n\t\t\tthis.#queue.push(message);\n\t\t}\n\t\t\n\t}\n\t\n\t\n\tstatic defib(this: InSiteWebSocket) {\n\t\t\n\t\tif (this.isOpen) {\n\t\t\tif (process.env.NODE_ENV === \"development\")\n\t\t\t\tconsole.info(`WebSocket ${this.name} has no heartbeat - going offline`);\n\t\t\t\n\t\t\tthis.webSocket!.close();\n\t\t}\n\t\t\n\t}\n\t\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["EventEmitter", "debounce", "noop", "reconnectTimeout", "i", "webSocketUrlWeakMap", "_defib", "_openResolve", "_openReject", "_handleWebSocketOpen", "_handleWebSocketMessage", "_handleWebSocketError", "_reconnectTimeout", "_handleWebSocketClose", "_queue", "_releaseQueue", "_InSiteWebSocket", "EventEmitter", "url", "options", "__publicField", "__privateAdd", "debounce", "__privateGet", "__privateSet", "message", "kind", "rest", "error", "event", "noop", "name", "protocols", "immediately", "autoReconnect", "on", "eventName", "resolve", "reject", "code", "reason", "args", "InSiteWebSocket"]
7
+ }
@@ -0,0 +1,9 @@
1
+ export type Options = {
2
+ url?: string;
3
+ name?: string;
4
+ protocols?: string[];
5
+ immediately?: boolean;
6
+ autoReconnect?: boolean;
7
+ on?: Record<string, (...args: unknown[]) => void>;
8
+ };
9
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/client/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,OAAO,GAAG;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC,CAAC;CAClD,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare const heartbeatInterval = 5000;
2
+ export declare const heartbeatGap = 60000;
3
+ //# sourceMappingURL=common.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,OAAQ,CAAC;AACvC,eAAO,MAAM,YAAY,QAAS,CAAC"}
@@ -0,0 +1,16 @@
1
+ /// <reference types="node" />
2
+ import http from "node:http";
3
+ import WebSocket, { WebSocketServer } from "ws";
4
+ import { Options } from "./types";
5
+ import { InSiteWebSocketServerClient } from "./WebSocketServerClient";
6
+ export declare class InSiteWebSocketServer extends WebSocketServer<typeof InSiteWebSocketServerClient> {
7
+ constructor(options: Options, props?: Record<string, unknown>, handleListen?: (() => void));
8
+ readonly isWebSocketServer = true;
9
+ readonly isWebSocketServerClient = false;
10
+ readonly isWebSocket = false;
11
+ static handleConnection(this: InSiteWebSocketServer, ws: InSiteWebSocketServerClient | WebSocket, request: http.IncomingMessage): void;
12
+ static handleClientMessage(this: InSiteWebSocketServerClient, data: WebSocket.RawData): void;
13
+ static handleClientError(this: InSiteWebSocketServerClient, error: Error | Event | undefined): void;
14
+ static handleClientClose(this: InSiteWebSocketServerClient, ...args: unknown[]): void;
15
+ }
16
+ //# sourceMappingURL=WebSocketServer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebSocketServer.d.ts","sourceRoot":"","sources":["../../src/server/WebSocketServer.ts"],"names":[],"mappings":";AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,SAAS,EAAE,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAEhD,OAAO,EAAsB,OAAO,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAGtE,qBAAa,qBAAsB,SAAQ,eAAe,CAAC,OAAO,2BAA2B,CAAC;gBACjF,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC;IA0B1F,QAAQ,CAAC,iBAAiB,QAAQ;IAClC,QAAQ,CAAC,uBAAuB,SAAS;IACzC,QAAQ,CAAC,WAAW,SAAS;IAG7B,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,qBAAqB,EAAE,EAAE,EAAE,2BAA2B,GAAG,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,eAAe;IAwD/H,MAAM,CAAC,mBAAmB,CAAC,IAAI,EAAE,2BAA2B,EAAE,IAAI,EAAE,SAAS,CAAC,OAAO;IAsBrF,MAAM,CAAC,iBAAiB,CAAC,IAAI,EAAE,2BAA2B,EAAE,KAAK,EAAE,KAAK,GAAG,KAAK,GAAG,SAAS;IAW5F,MAAM,CAAC,iBAAiB,CAAC,IAAI,EAAE,2BAA2B,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE;CAa9E"}
@@ -0,0 +1,24 @@
1
+ /// <reference types="node" />
2
+ import { WebSocket } from "ws";
3
+ import { defibSymbol, heartbeatIntervalSymbol, pingTsSymbol } from "./symbols";
4
+ import { InSiteWebSocketServer } from "./WebSocketServer";
5
+ export declare class InSiteWebSocketServerClient extends WebSocket {
6
+ get isConnecting(): boolean;
7
+ get isOpen(): boolean;
8
+ get isClosing(): boolean;
9
+ get isClosed(): boolean;
10
+ readonly isWebSocketServerClient = true;
11
+ readonly isWebSocketServer = false;
12
+ readonly isWebSocket = false;
13
+ wss?: InSiteWebSocketServer;
14
+ userAgent: string;
15
+ remoteAddress: string;
16
+ [defibSymbol]: import("@nesvet/n").Debounced<void>;
17
+ latency: number;
18
+ [pingTsSymbol]?: number;
19
+ [heartbeatIntervalSymbol]: NodeJS.Timeout;
20
+ sendMessage(...args: unknown[]): void;
21
+ static makeDefib(this: InSiteWebSocketServerClient): import("@nesvet/n").Debounced<void>;
22
+ static makeHeartbeatInterval(this: InSiteWebSocketServerClient): NodeJS.Timeout;
23
+ }
24
+ //# sourceMappingURL=WebSocketServerClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebSocketServerClient.d.ts","sourceRoot":"","sources":["../../src/server/WebSocketServerClient.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAG/B,OAAO,EAAE,WAAW,EAAE,uBAAuB,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC/E,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAG1D,qBAAa,2BAA4B,SAAQ,SAAS;IAEzD,IAAI,YAAY,YAEf;IAED,IAAI,MAAM,YAET;IAED,IAAI,SAAS,YAEZ;IAED,IAAI,QAAQ,YAEX;IAED,QAAQ,CAAC,uBAAuB,QAAQ;IACxC,QAAQ,CAAC,iBAAiB,SAAS;IACnC,QAAQ,CAAC,WAAW,SAAS;IAE7B,GAAG,CAAC,EAAE,qBAAqB,CAAC;IAE5B,SAAS,SAAM;IAEf,aAAa,SAAM;IAEnB,CAAC,WAAW,CAAC,sCAAoD;IAEjE,OAAO,SAAK;IAEZ,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC;IAExB,CAAC,uBAAuB,CAAC,iBAAgE;IAEzF,WAAW,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE;IAK9B,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,2BAA2B;IAIlD,MAAM,CAAC,qBAAqB,CAAC,IAAI,EAAE,2BAA2B;CAS9D"}
@@ -0,0 +1,3 @@
1
+ export * from "./WebSocketServer";
2
+ export * from "./WebSocketServerClient";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC"}
@@ -0,0 +1,2 @@
1
+ import f from"node:http";import C from"node:https";import{WebSocketServer as v}from"ws";var l=Symbol("heartbeatInterval"),o=Symbol("defib"),a=Symbol("pingTs");import{WebSocket as d}from"ws";import{debounce as g}from"@nesvet/n";var r=class s extends d{get isConnecting(){return this.readyState===this.CONNECTING}get isOpen(){return this.readyState===this.OPEN}get isClosing(){return this.readyState===this.CLOSING}get isClosed(){return this.readyState===this.CLOSED}isWebSocketServerClient=!0;isWebSocketServer=!1;isWebSocket=!1;wss;userAgent="";remoteAddress="";[o]=s.makeDefib.call(this);latency=0;[a];[l]=s.makeHeartbeatInterval.call(this);sendMessage(...e){return this.send(JSON.stringify(e))}static makeDefib(){return g(()=>this.terminate(),65e3)}static makeHeartbeatInterval(){return setInterval(()=>{this[a]=Date.now(),this.send("")},5e3)}};var b=class s extends v{constructor(e,t,i){let{ssl:n,port:m,server:c=n?C.createServer({...n}):f.createServer(),...h}=e;super({...h,WebSocket:r,server:c}),t&&(typeof t=="function"?i=t:Object.assign(this,t)),this.on("connection",s.handleConnection),c.listen(m,i)}isWebSocketServer=!0;isWebSocketServerClient=!1;isWebSocket=!1;static handleConnection(e,t){if(!(e instanceof r)){Object.defineProperties(e,{isConnecting:{get:Object.getOwnPropertyDescriptor(r.prototype,"isConnecting").get},isOpen:{get:Object.getOwnPropertyDescriptor(r.prototype,"isOpen").get},isClosing:{get:Object.getOwnPropertyDescriptor(r.prototype,"isClosing").get},isClosed:{get:Object.getOwnPropertyDescriptor(r.prototype,"isClosed").get}});let{terminate:i}=e;Object.assign(e,{isWebSocketServerClient:!0,isWebSocketServer:!1,isWebSocket:!1,[o]:r.makeDefib.call(e),latency:0,[l]:r.makeHeartbeatInterval.call(e),sendMessage:r.prototype.sendMessage,terminate(){try{i.call(e)}catch(n){console.error(n)}}})}Object.assign(e,{wss:this,userAgent:t.headers["user-agent"],remoteAddress:t.headers["x-real-ip"]??t.headers["x-forwarded-for"]??"127.0.0.1"}),e[o](),e.on("message",s.handleClientMessage),e.on("error",s.handleClientError),e.on("close",s.handleClientClose),this.emit("client-connect",e,t)}static handleClientMessage(e){let t=e.toString();if(this[o](),t)try{let[i,...n]=JSON.parse(t);this.emit(`message:${i}`,...n),this.wss.emit("client-message",this,i,...n),this.wss.emit(`client-message:${i}`,this,...n)}catch(i){s.handleClientError.call(this,i)}else this[a]&&(this.latency=Date.now()-this[a],delete this[a])}static handleClientError(e){e instanceof Event&&(e=void 0),process.env.NODE_ENV==="development"&&console.error("WebSocketServer Client error",e),this.wss.emit("client-error",this,e)}static handleClientClose(...e){process.env.NODE_ENV==="development"&&console.info("WebSocketServer Client closed",...e),this[o].clear(),clearInterval(this[l]),this.wss.emit("client-close",this),this.wss.emit("client-closed",this)}};export{b as InSiteWebSocketServer,r as InSiteWebSocketServerClient};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/server/WebSocketServer.ts", "../../src/server/symbols.ts", "../../src/server/WebSocketServerClient.ts"],
4
+ "sourcesContent": ["import http from \"node:http\";\nimport https from \"node:https\";\nimport WebSocket, { WebSocketServer } from \"ws\";\nimport { defibSymbol, heartbeatIntervalSymbol, pingTsSymbol } from \"./symbols\";\nimport { CompatibleListener, Options } from \"./types\";\nimport { InSiteWebSocketServerClient } from \"./WebSocketServerClient\";\n\n\nexport class InSiteWebSocketServer extends WebSocketServer<typeof InSiteWebSocketServerClient> {\n\tconstructor(options: Options, props?: Record<string, unknown>, handleListen?: (() => void)) {\n\t\tconst {\n\t\t\tssl,\n\t\t\tport,\n\t\t\tserver = ssl ? https.createServer({ ...ssl }) : http.createServer(),\n\t\t\t...wssOptions\n\t\t} = options;\n\t\t\n\t\tsuper({\n\t\t\t...wssOptions,\n\t\t\tWebSocket: InSiteWebSocketServerClient,\n\t\t\tserver\n\t\t});\n\t\t\n\t\tif (props)\n\t\t\tif (typeof props == \"function\")\n\t\t\t\thandleListen = props;\n\t\t\telse\n\t\t\t\tObject.assign(this, props);\n\t\t\n\t\tthis.on(\"connection\", InSiteWebSocketServer.handleConnection as CompatibleListener);\n\t\t\n\t\tserver.listen(port, handleListen);\n\t\t\n\t}\n\t\n\treadonly isWebSocketServer = true;\n\treadonly isWebSocketServerClient = false;\n\treadonly isWebSocket = false;\n\t\n\t\n\tstatic handleConnection(this: InSiteWebSocketServer, ws: InSiteWebSocketServerClient | WebSocket, request: http.IncomingMessage) {\n\t\tif (!(ws instanceof InSiteWebSocketServerClient)) { /* Compatibility with Bun */\n\t\t\tObject.defineProperties(ws, {\n\t\t\t\tisConnecting: {\n\t\t\t\t\tget: Object.getOwnPropertyDescriptor(InSiteWebSocketServerClient.prototype, \"isConnecting\")!.get\n\t\t\t\t},\n\t\t\t\tisOpen: {\n\t\t\t\t\tget: Object.getOwnPropertyDescriptor(InSiteWebSocketServerClient.prototype, \"isOpen\")!.get\n\t\t\t\t},\n\t\t\t\tisClosing: {\n\t\t\t\t\tget: Object.getOwnPropertyDescriptor(InSiteWebSocketServerClient.prototype, \"isClosing\")!.get\n\t\t\t\t},\n\t\t\t\tisClosed: {\n\t\t\t\t\tget: Object.getOwnPropertyDescriptor(InSiteWebSocketServerClient.prototype, \"isClosed\")!.get\n\t\t\t\t}\n\t\t\t});\n\t\t\t\n\t\t\tconst { terminate } = ws;\n\t\t\t\n\t\t\tObject.assign(ws, {\n\t\t\t\tisWebSocketServerClient: true,\n\t\t\t\tisWebSocketServer: false,\n\t\t\t\tisWebSocket: false,\n\t\t\t\t[defibSymbol]: InSiteWebSocketServerClient.makeDefib.call(ws as InSiteWebSocketServerClient),\n\t\t\t\tlatency: 0,\n\t\t\t\t[heartbeatIntervalSymbol]: InSiteWebSocketServerClient.makeHeartbeatInterval.call(ws as InSiteWebSocketServerClient),\n\t\t\t\tsendMessage: InSiteWebSocketServerClient.prototype.sendMessage,\n\t\t\t\tterminate() { /* Workaround Bun's WebSocket#terminate bug */\n\t\t\t\t\t\n\t\t\t\t\ttry {\n\t\t\t\t\t\tterminate.call(ws);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tconsole.error(error);\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\t\n\t\tObject.assign(ws, {\n\t\t\twss: this,\n\t\t\tuserAgent: request.headers[\"user-agent\"],\n\t\t\tremoteAddress: request.headers[\"x-real-ip\"] ?? request.headers[\"x-forwarded-for\"] ?? \"127.0.0.1\"\n\t\t});\n\t\t\n\t\t(ws as InSiteWebSocketServerClient)[defibSymbol]();\n\t\t\n\t\tws.on(\"message\", InSiteWebSocketServer.handleClientMessage as CompatibleListener);\n\t\tws.on(\"error\", InSiteWebSocketServer.handleClientError as CompatibleListener);\n\t\tws.on(\"close\", InSiteWebSocketServer.handleClientClose as CompatibleListener);\n\t\t\n\t\tthis.emit(\"client-connect\", ws, request);\n\t\t\n\t}\n\t\n\t\n\tstatic handleClientMessage(this: InSiteWebSocketServerClient, data: WebSocket.RawData) {\n\t\tconst message = data.toString();\n\t\t\n\t\tthis[defibSymbol]();\n\t\t\n\t\tif (message)\n\t\t\ttry {\n\t\t\t\tconst [ kind, ...rest ] = JSON.parse(message);\n\t\t\t\t\n\t\t\t\tthis.emit(`message:${kind}`, ...rest);\n\t\t\t\tthis.wss!.emit(\"client-message\", this, kind, ...rest);\n\t\t\t\tthis.wss!.emit(`client-message:${kind}`, this, ...rest);\n\t\t\t} catch (error) {\n\t\t\t\tInSiteWebSocketServer.handleClientError.call(this, error as Error);\n\t\t\t}\n\t\telse if (this[pingTsSymbol]) {\n\t\t\tthis.latency = Date.now() - this[pingTsSymbol];\n\t\t\tdelete this[pingTsSymbol];\n\t\t}\n\t\t\n\t}\n\t\n\tstatic handleClientError(this: InSiteWebSocketServerClient, error: Error | Event | undefined) {\n\t\tif (error instanceof Event)\n\t\t\terror = undefined;\n\t\t\n\t\tif (process.env.NODE_ENV === \"development\")\n\t\t\tconsole.error(\"WebSocketServer Client error\", error);\n\t\t\n\t\tthis.wss!.emit(\"client-error\", this, error);\n\t\t\n\t}\n\t\n\tstatic handleClientClose(this: InSiteWebSocketServerClient, ...args: unknown[]) {\n\t\t\n\t\tif (process.env.NODE_ENV === \"development\")\n\t\t\tconsole.info(\"WebSocketServer Client closed\", ...args);\n\t\t\n\t\tthis[defibSymbol].clear();\n\t\tclearInterval(this[heartbeatIntervalSymbol]);\n\t\t\n\t\tthis.wss!.emit(\"client-close\", this);\n\t\tthis.wss!.emit(\"client-closed\", this);\n\t\t\n\t}\n\t\n}\n", "export const heartbeatIntervalSymbol = Symbol(\"heartbeatInterval\");\nexport const defibSymbol = Symbol(\"defib\");\nexport const pingTsSymbol = Symbol(\"pingTs\");\n", "import { WebSocket } from \"ws\";\nimport { debounce } from \"@nesvet/n\";\nimport { heartbeatGap, heartbeatInterval } from \"../common\";\nimport { defibSymbol, heartbeatIntervalSymbol, pingTsSymbol } from \"./symbols\";\nimport { InSiteWebSocketServer } from \"./WebSocketServer\";\n\n\nexport class InSiteWebSocketServerClient extends WebSocket {\n\t\n\tget isConnecting() {\n\t\treturn this.readyState === this.CONNECTING;\n\t}\n\t\n\tget isOpen() {\n\t\treturn this.readyState === this.OPEN;\n\t}\n\t\n\tget isClosing() {\n\t\treturn this.readyState === this.CLOSING;\n\t}\n\t\n\tget isClosed() {\n\t\treturn this.readyState === this.CLOSED;\n\t}\n\t\n\treadonly isWebSocketServerClient = true;\n\treadonly isWebSocketServer = false;\n\treadonly isWebSocket = false;\n\t\n\twss?: InSiteWebSocketServer;\n\t\n\tuserAgent = \"\";\n\t\n\tremoteAddress = \"\";\n\t\n\t[defibSymbol] = InSiteWebSocketServerClient.makeDefib.call(this);\n\t\n\tlatency = 0;\n\t\n\t[pingTsSymbol]?: number;\n\t\n\t[heartbeatIntervalSymbol] = InSiteWebSocketServerClient.makeHeartbeatInterval.call(this);\n\t\n\tsendMessage(...args: unknown[]) {\n\t\treturn this.send(JSON.stringify(args));\n\t}\n\t\n\t\n\tstatic makeDefib(this: InSiteWebSocketServerClient) {\n\t\treturn debounce(() => this.terminate(), heartbeatInterval + heartbeatGap);\n\t}\n\t\n\tstatic makeHeartbeatInterval(this: InSiteWebSocketServerClient) {\n\t\treturn setInterval(() => {\n\t\t\t\n\t\t\tthis[pingTsSymbol] = Date.now();\n\t\t\tthis.send(\"\");\n\t\t\t\n\t\t}, heartbeatInterval);\n\t}\n\t\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["http", "https", "WebSocketServer", "heartbeatIntervalSymbol", "defibSymbol", "pingTsSymbol", "WebSocket", "debounce", "InSiteWebSocketServerClient", "_InSiteWebSocketServerClient", "WebSocket", "defibSymbol", "pingTsSymbol", "heartbeatIntervalSymbol", "args", "debounce", "InSiteWebSocketServer", "_InSiteWebSocketServer", "WebSocketServer", "options", "props", "handleListen", "ssl", "port", "server", "https", "http", "wssOptions", "InSiteWebSocketServerClient", "ws", "request", "terminate", "defibSymbol", "heartbeatIntervalSymbol", "error", "data", "message", "kind", "rest", "pingTsSymbol", "args"]
7
+ }
@@ -0,0 +1,4 @@
1
+ export declare const heartbeatIntervalSymbol: unique symbol;
2
+ export declare const defibSymbol: unique symbol;
3
+ export declare const pingTsSymbol: unique symbol;
4
+ //# sourceMappingURL=symbols.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"symbols.d.ts","sourceRoot":"","sources":["../../src/server/symbols.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,uBAAuB,eAA8B,CAAC;AACnE,eAAO,MAAM,WAAW,eAAkB,CAAC;AAC3C,eAAO,MAAM,YAAY,eAAmB,CAAC"}
@@ -0,0 +1,15 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ import http from "node:http";
4
+ import https from "node:https";
5
+ import WebSocket from "ws";
6
+ export type Options = {
7
+ ssl?: {
8
+ cert: string;
9
+ key: string;
10
+ };
11
+ port: number;
12
+ server?: http.Server | https.Server;
13
+ } & WebSocket.ServerOptions;
14
+ export type CompatibleListener = () => void;
15
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/server/types.ts"],"names":[],"mappings":";;AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,KAAK,MAAM,YAAY,CAAC;AAC/B,OAAO,SAAS,MAAM,IAAI,CAAC;AAG3B,MAAM,MAAM,OAAO,GAAG;IACrB,GAAG,CAAC,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,GAAG,EAAE,MAAM,CAAC;KACZ,CAAC;IACF,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;CACpC,GAAG,SAAS,CAAC,aAAa,CAAC;AAE5B,MAAM,MAAM,kBAAkB,GAAG,MAAM,IAAI,CAAC"}
package/package.json CHANGED
@@ -1,20 +1,17 @@
1
1
  {
2
2
  "name": "insite-ws",
3
- "version": "2.0.1",
3
+ "version": "2.0.3",
4
4
  "description": "inSite WebSockets",
5
5
  "type": "module",
6
- "main": "./dist/server.js",
7
- "module": "./dist/server.js",
8
6
  "exports": {
9
- ".": "./dist/server.js",
10
- "./server": "./dist/server.js",
11
- "./client": "./dist/client.js"
7
+ "./server": "./dist/server/index.js",
8
+ "./client": "./dist/client/index.js"
12
9
  },
13
10
  "packageManager": "bun@1.1.18",
14
11
  "scripts": {
15
12
  "test": "echo \"Error: no test specified\" && exit 1",
16
13
  "build": "bun .conveyer.js",
17
- "postbuild": "tsc -p ./src/server && tsc -p ./src/client"
14
+ "postbuild": "tsc -p ."
18
15
  },
19
16
  "repository": {
20
17
  "type": "git",
@@ -34,8 +31,8 @@
34
31
  },
35
32
  "devDependencies": {
36
33
  "@nesvet/conveyer": "^2.2.1",
37
- "@nesvet/eslint-config": "^2.0.21",
38
- "@types/node": "^20.14.9",
34
+ "@nesvet/eslint-config": "^2.0.22",
35
+ "@types/node": "^20.14.10",
39
36
  "@types/ws": "^8.5.10"
40
37
  }
41
38
  }
package/dist/client.d.ts DELETED
@@ -1,43 +0,0 @@
1
- declare module "common" {
2
- export const heartbeatInterval = 5000;
3
- export const heartbeatGap = 60000;
4
- }
5
- declare module "client/types" {
6
- export type Options = {
7
- url?: string;
8
- name?: string;
9
- protocols?: string[];
10
- immediately?: boolean;
11
- autoReconnect?: boolean;
12
- on?: Record<string, (...args: unknown[]) => void>;
13
- };
14
- }
15
- declare module "client/WebSocket" {
16
- import EventEmitter from "eventemitter3";
17
- import { Options } from "client/types";
18
- export class InSiteWebSocket extends EventEmitter {
19
- #private;
20
- constructor(url: string, options?: Options);
21
- readonly isWebSocket = true;
22
- url: string;
23
- name: string;
24
- protocols?: string[];
25
- autoReconnect: boolean;
26
- send?(data: ArrayBufferLike | ArrayBufferView | Blob | string): void;
27
- webSocket: null | WebSocket;
28
- get isConnecting(): boolean | null;
29
- get isOpen(): boolean | null;
30
- get isClosing(): boolean | null;
31
- get isClosed(): boolean | null;
32
- open(options?: Options): Promise<unknown>;
33
- connect: (options?: Options) => Promise<unknown>;
34
- close(code?: number, reason?: string): Promise<unknown>;
35
- disconnect: (code?: number, reason?: string) => Promise<unknown>;
36
- sendMessage(...args: unknown[]): void;
37
- static defib(this: InSiteWebSocket): void;
38
- }
39
- }
40
- declare module "client/index" {
41
- export * from "client/WebSocket";
42
- }
43
- //# sourceMappingURL=client.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/common.ts","../src/client/types.ts","../src/client/WebSocket.ts","../src/client/index.ts"],"names":[],"mappings":";IAAA,MAAM,CAAC,MAAM,iBAAiB,OAAQ,CAAC;IACvC,MAAM,CAAC,MAAM,YAAY,QAAS,CAAC;;;ICDnC,MAAM,MAAM,OAAO,GAAG;QACrB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QACrB,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,aAAa,CAAC,EAAE,OAAO,CAAC;QACxB,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC,CAAC;KAClD,CAAC;;;ICPF,OAAO,YAAY,MAAM,eAAe,CAAC;IAGzC,OAAO,EAAE,OAAO,EAAE,qBAAgB;IAUlC,MAAM,OAAO,eAAgB,SAAQ,YAAY;;oBACpC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,OAAY;QA6B9C,QAAQ,CAAC,WAAW,QAAQ;QAE5B,GAAG,EAAE,MAAM,CAAC;QAEZ,IAAI,EAAE,MAAM,CAAC;QAEb,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QAErB,aAAa,EAAE,OAAO,CAAC;QAEvB,IAAI,CAAC,CAAC,IAAI,EAAE,eAAe,GAAG,eAAe,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI;QAEpE,SAAS,EAAE,IAAI,GAAG,SAAS,CAAQ;QAInC,IAAI,YAAY,mBAEf;QAED,IAAI,MAAM,mBAET;QAED,IAAI,SAAS,mBAEZ;QAED,IAAI,QAAQ,mBAEX;QAqEK,IAAI,CAAC,OAAO,GAAE,OAAY;QAmChC,OAAO,aAnCa,OAAO,sBAmCP;QAEpB,KAAK,CAAC,IAAI,SAAO,EAAE,MAAM,SAAW;QAcpC,UAAU,uDAAc;QAaxB,WAAW,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE;QAe9B,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,eAAe;KAWlC;;;ICxOD,iCAA4B"}
package/dist/client.js DELETED
@@ -1,2 +0,0 @@
1
- var T=Object.defineProperty;var v=t=>{throw TypeError(t)};var $=(t,s,e)=>s in t?T(t,s,{enumerable:!0,configurable:!0,writable:!0,value:e}):t[s]=e;var r=(t,s,e)=>$(t,typeof s!="symbol"?s+"":s,e),O=(t,s,e)=>s.has(t)||v("Cannot "+e);var i=(t,s,e)=>(O(t,s,"read from private field"),e?e.call(t):s.get(t)),n=(t,s,e)=>s.has(t)?v("Cannot add the same private member more than once"):s instanceof WeakSet?s.add(t):s.set(t,e),h=(t,s,e,o)=>(O(t,s,"write to private field"),o?o.call(t,e):s.set(t,e),e);import D from"eventemitter3";import{debounce as G,noop as N}from"@nesvet/n";var I=2e3,V=0,W=new WeakMap,u,l,a,f,p,S,b,m,d,w,E=class E extends D{constructor(e,o={}){super();r(this,"isWebSocket",!0);r(this,"url");r(this,"name");r(this,"protocols");r(this,"autoReconnect");r(this,"webSocket",null);n(this,u,G(E.defib,65e3));n(this,l);n(this,a);n(this,f,()=>{i(this,l).call(this),h(this,l,void 0),h(this,a,void 0),this.emit("open"),i(this,u).call(this)});n(this,p,({data:e})=>{if(i(this,u).call(this),e)try{let[o,...c]=JSON.parse(e);this.emit("message",o,...c),this.emit(`message:${o}`,...c)}catch(o){i(this,S).call(this,o)}else this.webSocket.send("")});n(this,S,e=>{e instanceof Event&&(e=void 0),i(this,a)&&(i(this,a).call(this,e),h(this,l,void 0),h(this,a,void 0)),this.emit("error",e)});n(this,b);n(this,m,e=>{process.env.NODE_ENV==="development"&&console.info(`WebSocket ${this.name} is closed with code ${e.code} and reason "${e.reason}"`),i(this,u).clear(),this.emit("close",e),this.autoReconnect&&![1002,3500,4e3].includes(e.code)&&(process.env.NODE_ENV==="development"&&console.info(`WebSocket ${this.name} will try to reconnect in 2 sec\u2026`),h(this,b,setTimeout(()=>this.open().catch(N),I)))});r(this,"connect",this.open);r(this,"disconnect",this.close);n(this,d,[]);n(this,w,()=>{for(let e of i(this,d))this.webSocket.send(e);i(this,d).length=0});this.url=e;let{name:c=(V++).toString(),protocols:C,immediately:L=!0,autoReconnect:R=!0,on:k}=o;if(this.name=c,this.protocols=C,this.autoReconnect=!!R,k)for(let g in k)k[g]&&this.on(g,k[g]);this.url&&L&&this.open().catch(N)}get isConnecting(){return this.webSocket?this.webSocket.readyState===this.webSocket.CONNECTING:null}get isOpen(){return this.webSocket?this.webSocket.readyState===this.webSocket.OPEN:null}get isClosing(){return this.webSocket?this.webSocket.readyState===this.webSocket.CLOSING:null}get isClosed(){return this.webSocket?this.webSocket.readyState===this.webSocket.CLOSED:null}async open(e={}){return clearTimeout(i(this,b)),await this.close(4e3,"reopen"),e.url&&(this.url=e.url),e.protocols&&(this.protocols=e.protocols),this.webSocket&&W.get(this.webSocket)!==this.url&&this.emit("server-change"),new Promise((o,c)=>{h(this,l,o),h(this,a,c),this.webSocket=new WebSocket(this.url,this.protocols),this.webSocket.addEventListener("open",i(this,f)),this.webSocket.addEventListener("message",i(this,p)),this.webSocket.addEventListener("error",i(this,S)),this.webSocket.addEventListener("close",i(this,m)),this.send=this.webSocket.send.bind(this.webSocket),W.set(this.webSocket,this.url),this.emit("connecting")})}close(e=3500,o="manual"){return clearTimeout(i(this,b)),new Promise(c=>{this.isConnecting||this.isOpen?(this.webSocket.addEventListener("close",c),this.webSocket.close(e,o)):c(null)})}sendMessage(...e){let o=JSON.stringify(e);this.isOpen?this.webSocket.send(o):(i(this,d).length||this.once("open",i(this,w)),i(this,d).push(o))}static defib(){this.isOpen&&(process.env.NODE_ENV==="development"&&console.info(`WebSocket ${this.name} has no heartbeat - going offline`),this.webSocket.close())}};u=new WeakMap,l=new WeakMap,a=new WeakMap,f=new WeakMap,p=new WeakMap,S=new WeakMap,b=new WeakMap,m=new WeakMap,d=new WeakMap,w=new WeakMap;var y=E;export{y as InSiteWebSocket};
2
- //# sourceMappingURL=client.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/client/WebSocket.ts"],
4
- "sourcesContent": ["import EventEmitter from \"eventemitter3\";\nimport { debounce, noop } from \"@nesvet/n\";\nimport { heartbeatGap, heartbeatInterval } from \"../common\";\nimport { Options } from \"./types\";\n\n\nconst reconnectTimeout = 2000;\n\nlet i = 0;\n\nconst webSocketUrlWeakMap = new WeakMap<WebSocket, string>();\n\n\nexport class InSiteWebSocket extends EventEmitter {\n\tconstructor(url: string, options: Options = {}) {\n\t\tsuper();\n\t\t\n\t\tthis.url = url;\n\t\t\n\t\tconst {\n\t\t\tname = (i++).toString(),\n\t\t\tprotocols,\n\t\t\timmediately = true,\n\t\t\tautoReconnect = true,\n\t\t\ton\n\t\t} = options;\n\t\t\n\t\tthis.name = name;\n\t\t\n\t\tthis.protocols = protocols;\n\t\t\n\t\tthis.autoReconnect = !!autoReconnect;\n\t\t\n\t\tif (on)\n\t\t\tfor (const eventName in on)\n\t\t\t\tif (on[eventName])\n\t\t\t\t\tthis.on(eventName, on[eventName]);\n\t\t\n\t\tif (this.url && immediately)\n\t\t\tthis.open().catch(noop);\n\t\t\n\t}\n\t\n\treadonly isWebSocket = true;\n\t\n\turl: string;\n\t\n\tname: string;\n\t\n\tprotocols?: string[];\n\t\n\tautoReconnect: boolean;\n\t\n\tsend?(data: ArrayBufferLike | ArrayBufferView | Blob | string): void;\n\t\n\twebSocket: null | WebSocket = null;\n\t\n\t#defib = debounce(InSiteWebSocket.defib, heartbeatInterval + heartbeatGap);\n\t\n\tget isConnecting() {\n\t\treturn this.webSocket ? this.webSocket.readyState === this.webSocket.CONNECTING : null;\n\t}\n\t\n\tget isOpen() {\n\t\treturn this.webSocket ? this.webSocket.readyState === this.webSocket.OPEN : null;\n\t}\n\t\n\tget isClosing() {\n\t\treturn this.webSocket ? this.webSocket.readyState === this.webSocket.CLOSING : null;\n\t}\n\t\n\tget isClosed() {\n\t\treturn this.webSocket ? this.webSocket.readyState === this.webSocket.CLOSED : null;\n\t}\n\t\n\t#openResolve?: (value?: unknown) => void;\n\t#openReject?: (reason?: unknown) => void;\n\t\n\t#handleWebSocketOpen = () => {\n\t\t\n\t\tthis.#openResolve!();\n\t\tthis.#openResolve = undefined;\n\t\tthis.#openReject = undefined;\n\t\t\n\t\tthis.emit(\"open\");\n\t\t\n\t\tthis.#defib();\n\t\t\n\t};\n\t\n\t#handleWebSocketMessage = ({ data: message }: MessageEvent) => {\n\t\t\n\t\tthis.#defib();\n\t\t\n\t\tif (message)\n\t\t\ttry {\n\t\t\t\tconst [ kind, ...rest ] = JSON.parse(message);\n\t\t\t\t\n\t\t\t\tthis.emit(\"message\", kind, ...rest);\n\t\t\t\tthis.emit(`message:${kind}`, ...rest);\n\t\t\t} catch (error) {\n\t\t\t\tthis.#handleWebSocketError(error as Error);\n\t\t\t}\n\t\telse\n\t\t\tthis.webSocket!.send(\"\");\n\t\t\n\t};\n\t\n\t#handleWebSocketError = (error: Error | Event | undefined) => {\n\t\tif (error instanceof Event)\n\t\t\terror = undefined;\n\t\t\n\t\tif (this.#openReject) {\n\t\t\tthis.#openReject(error);\n\t\t\tthis.#openResolve = undefined;\n\t\t\tthis.#openReject = undefined;\n\t\t}\n\t\t\n\t\tthis.emit(\"error\", error);\n\t\t\n\t};\n\t\n\t#reconnectTimeout?: number;\n\t\n\t#handleWebSocketClose = (event: CloseEvent) => {\n\t\t\n\t\tif (process.env.NODE_ENV === \"development\")\n\t\t\tconsole.info(`WebSocket ${this.name} is closed with code ${event.code} and reason \"${event.reason}\"`);\n\t\t\n\t\tthis.#defib.clear();\n\t\t\n\t\tthis.emit(\"close\", event);\n\t\t\n\t\tif (this.autoReconnect && ![ 1002, 3500, 4000 ].includes(event.code)) {\n\t\t\tif (process.env.NODE_ENV === \"development\")\n\t\t\t\tconsole.info(`WebSocket ${this.name} will try to reconnect in 2 sec\u2026`);\n\t\t\t\n\t\t\tthis.#reconnectTimeout = setTimeout(() => this.open().catch(noop), reconnectTimeout) as unknown as number;\n\t\t}\n\t\t\n\t};\n\t\n\tasync open(options: Options = {}) {\n\t\t\n\t\tclearTimeout(this.#reconnectTimeout);\n\t\t\n\t\tawait this.close(4000, \"reopen\");\n\t\t\n\t\tif (options.url)\n\t\t\tthis.url = options.url;\n\t\t\n\t\tif (options.protocols)\n\t\t\tthis.protocols = options.protocols;\n\t\t\n\t\tif (this.webSocket && webSocketUrlWeakMap.get(this.webSocket) !== this.url)\n\t\t\tthis.emit(\"server-change\");\n\t\t\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.#openResolve = resolve;\n\t\t\tthis.#openReject = reject;\n\t\t\t\n\t\t\tthis.webSocket = new WebSocket(this.url, this.protocols);\n\t\t\t\n\t\t\tthis.webSocket.addEventListener(\"open\", this.#handleWebSocketOpen);\n\t\t\tthis.webSocket.addEventListener(\"message\", this.#handleWebSocketMessage);\n\t\t\tthis.webSocket.addEventListener(\"error\", this.#handleWebSocketError);\n\t\t\tthis.webSocket.addEventListener(\"close\", this.#handleWebSocketClose);\n\t\t\t\n\t\t\tthis.send = this.webSocket.send.bind(this.webSocket);\n\t\t\t\n\t\t\twebSocketUrlWeakMap.set(this.webSocket, this.url);\n\t\t\t\n\t\t\tthis.emit(\"connecting\");\n\t\t\t\n\t\t});\n\t}\n\t\n\tconnect = this.open;\n\t\n\tclose(code = 3500, reason = \"manual\") {\n\t\t\n\t\tclearTimeout(this.#reconnectTimeout);\n\t\t\n\t\treturn new Promise(resolve => {\n\t\t\tif (this.isConnecting || this.isOpen) {\n\t\t\t\tthis.webSocket!.addEventListener(\"close\", resolve);\n\t\t\t\tthis.webSocket!.close(code, reason);\n\t\t\t} else\n\t\t\t\tresolve(null);\n\t\t\t\n\t\t});\n\t}\n\t\n\tdisconnect = this.close;\n\t\n\t#queue: string[] = [];\n\t\n\t#releaseQueue = () => {\n\t\t\n\t\tfor (const message of this.#queue)\n\t\t\tthis.webSocket!.send(message);\n\t\t\n\t\tthis.#queue.length = 0;\n\t\t\n\t};\n\t\n\tsendMessage(...args: unknown[]) {\n\t\tconst message = JSON.stringify(args);\n\t\t\n\t\tif (this.isOpen)\n\t\t\tthis.webSocket!.send(message);\n\t\telse {\n\t\t\tif (!this.#queue.length)\n\t\t\t\tthis.once(\"open\", this.#releaseQueue);\n\t\t\t\n\t\t\tthis.#queue.push(message);\n\t\t}\n\t\t\n\t}\n\t\n\t\n\tstatic defib(this: InSiteWebSocket) {\n\t\t\n\t\tif (this.isOpen) {\n\t\t\tif (process.env.NODE_ENV === \"development\")\n\t\t\t\tconsole.info(`WebSocket ${this.name} has no heartbeat - going offline`);\n\t\t\t\n\t\t\tthis.webSocket!.close();\n\t\t}\n\t\t\n\t}\n\t\n}\n"],
5
- "mappings": "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",
6
- "names": ["EventEmitter", "debounce", "noop", "reconnectTimeout", "i", "webSocketUrlWeakMap", "_defib", "_openResolve", "_openReject", "_handleWebSocketOpen", "_handleWebSocketMessage", "_handleWebSocketError", "_reconnectTimeout", "_handleWebSocketClose", "_queue", "_releaseQueue", "_InSiteWebSocket", "EventEmitter", "url", "options", "__publicField", "__privateAdd", "debounce", "__privateGet", "__privateSet", "message", "kind", "rest", "error", "event", "noop", "name", "protocols", "immediately", "autoReconnect", "on", "eventName", "resolve", "reject", "code", "reason", "args", "InSiteWebSocket"]
7
- }
package/dist/server.d.ts DELETED
@@ -1,68 +0,0 @@
1
- /// <reference types="node" />
2
- /// <reference types="node" />
3
- /// <reference types="ws" />
4
- /// <reference types="node" />
5
- /// <reference types="node" />
6
- declare module "server/symbols" {
7
- export const heartbeatIntervalSymbol: unique symbol;
8
- export const defibSymbol: unique symbol;
9
- export const pingTsSymbol: unique symbol;
10
- }
11
- declare module "server/types" {
12
- import http from "node:http";
13
- import https from "node:https";
14
- import WebSocket from "ws";
15
- export type Options = {
16
- ssl?: {
17
- cert: string;
18
- key: string;
19
- };
20
- port: number;
21
- server?: http.Server | https.Server;
22
- } & WebSocket.ServerOptions;
23
- export type CompatibleListener = () => void;
24
- }
25
- declare module "common" {
26
- export const heartbeatInterval = 5000;
27
- export const heartbeatGap = 60000;
28
- }
29
- declare module "server/WebSocketServerClient" {
30
- import { WebSocket } from "ws";
31
- import { defibSymbol, heartbeatIntervalSymbol, pingTsSymbol } from "server/symbols";
32
- import { InSiteWebSocketServer } from "server/WebSocketServer";
33
- export class InSiteWebSocketServerClient extends WebSocket {
34
- get isConnecting(): boolean;
35
- get isOpen(): boolean;
36
- get isClosing(): boolean;
37
- get isClosed(): boolean;
38
- readonly isWebSocketServerClient = true;
39
- wss?: InSiteWebSocketServer;
40
- userAgent: string;
41
- remoteAddress: string;
42
- [defibSymbol]: import("@nesvet/n").Debounced<void>;
43
- latency: number;
44
- [pingTsSymbol]?: number;
45
- [heartbeatIntervalSymbol]: NodeJS.Timeout;
46
- sendMessage(...args: unknown[]): void;
47
- static makeDefib(this: InSiteWebSocketServerClient): import("@nesvet/n").Debounced<void>;
48
- static makeHeartbeatInterval(this: InSiteWebSocketServerClient): NodeJS.Timeout;
49
- }
50
- }
51
- declare module "server/WebSocketServer" {
52
- import http from "node:http";
53
- import WebSocket, { WebSocketServer } from "ws";
54
- import { Options } from "server/types";
55
- import { InSiteWebSocketServerClient } from "server/WebSocketServerClient";
56
- export class InSiteWebSocketServer extends WebSocketServer<typeof InSiteWebSocketServerClient> {
57
- constructor(options: Options, props?: Record<string, unknown>, handleListen?: (() => void));
58
- readonly isWebSocketServer = true;
59
- static handleConnection(this: InSiteWebSocketServer, ws: InSiteWebSocketServerClient | WebSocket, request: http.IncomingMessage): void;
60
- static handleClientMessage(this: InSiteWebSocketServerClient, data: WebSocket.RawData): void;
61
- static handleClientError(this: InSiteWebSocketServerClient, error: Error | Event | undefined): void;
62
- static handleClientClose(this: InSiteWebSocketServerClient, ...args: unknown[]): void;
63
- }
64
- }
65
- declare module "server/index" {
66
- export * from "server/WebSocketServer";
67
- }
68
- //# sourceMappingURL=server.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server/symbols.ts","../src/server/types.ts","../src/common.ts","../src/server/WebSocketServerClient.ts","../src/server/WebSocketServer.ts","../src/server/index.ts"],"names":[],"mappings":";;;;;;IAAA,MAAM,CAAC,MAAM,uBAAuB,eAA8B,CAAC;IACnE,MAAM,CAAC,MAAM,WAAW,eAAkB,CAAC;IAC3C,MAAM,CAAC,MAAM,YAAY,eAAmB,CAAC;;;ICF7C,OAAO,IAAI,MAAM,WAAW,CAAC;IAC7B,OAAO,KAAK,MAAM,YAAY,CAAC;IAC/B,OAAO,SAAS,MAAM,IAAI,CAAC;IAG3B,MAAM,MAAM,OAAO,GAAG;QACrB,GAAG,CAAC,EAAE;YACL,IAAI,EAAE,MAAM,CAAC;YACb,GAAG,EAAE,MAAM,CAAC;SACZ,CAAC;QACF,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;KACpC,GAAG,SAAS,CAAC,aAAa,CAAC;IAE5B,MAAM,MAAM,kBAAkB,GAAG,MAAM,IAAI,CAAC;;;ICd5C,MAAM,CAAC,MAAM,iBAAiB,OAAQ,CAAC;IACvC,MAAM,CAAC,MAAM,YAAY,QAAS,CAAC;;;ICDnC,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;IAG/B,OAAO,EAAE,WAAW,EAAE,uBAAuB,EAAE,YAAY,EAAE,uBAAkB;IAC/E,OAAO,EAAE,qBAAqB,EAAE,+BAA0B;IAG1D,MAAM,OAAO,2BAA4B,SAAQ,SAAS;QAEzD,IAAI,YAAY,YAEf;QAED,IAAI,MAAM,YAET;QAED,IAAI,SAAS,YAEZ;QAED,IAAI,QAAQ,YAEX;QAED,QAAQ,CAAC,uBAAuB,QAAQ;QAExC,GAAG,CAAC,EAAE,qBAAqB,CAAC;QAE5B,SAAS,SAAM;QAEf,aAAa,SAAM;QAEnB,CAAC,WAAW,CAAC,sCAAoD;QAEjE,OAAO,SAAK;QAEZ,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC;QAExB,CAAC,uBAAuB,CAAC,iBAAgE;QAEzF,WAAW,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE;QAK9B,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,2BAA2B;QAIlD,MAAM,CAAC,qBAAqB,CAAC,IAAI,EAAE,2BAA2B;KAS9D;;;IC3DD,OAAO,IAAI,MAAM,WAAW,CAAC;IAE7B,OAAO,SAAS,EAAE,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;IAEhD,OAAO,EAAsB,OAAO,EAAE,qBAAgB;IACtD,OAAO,EAAE,2BAA2B,EAAE,qCAAgC;IAGtE,MAAM,OAAO,qBAAsB,SAAQ,eAAe,CAAC,OAAO,2BAA2B,CAAC;oBACjF,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC;QA0B1F,QAAQ,CAAC,iBAAiB,QAAQ;QAGlC,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,qBAAqB,EAAE,EAAE,EAAE,2BAA2B,GAAG,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,eAAe;QAsD/H,MAAM,CAAC,mBAAmB,CAAC,IAAI,EAAE,2BAA2B,EAAE,IAAI,EAAE,SAAS,CAAC,OAAO;QAsBrF,MAAM,CAAC,iBAAiB,CAAC,IAAI,EAAE,2BAA2B,EAAE,KAAK,EAAE,KAAK,GAAG,KAAK,GAAG,SAAS;QAW5F,MAAM,CAAC,iBAAiB,CAAC,IAAI,EAAE,2BAA2B,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE;KAa9E;;;IC1ID,uCAAkC"}
package/dist/server.js DELETED
@@ -1,2 +0,0 @@
1
- import C from"node:http";import f from"node:https";import{WebSocketServer as v}from"ws";var l=Symbol("heartbeatInterval"),o=Symbol("defib"),a=Symbol("pingTs");import{WebSocket as d}from"ws";import{debounce as g}from"@nesvet/n";var r=class n extends d{get isConnecting(){return this.readyState===this.CONNECTING}get isOpen(){return this.readyState===this.OPEN}get isClosing(){return this.readyState===this.CLOSING}get isClosed(){return this.readyState===this.CLOSED}isWebSocketServerClient=!0;wss;userAgent="";remoteAddress="";[o]=n.makeDefib.call(this);latency=0;[a];[l]=n.makeHeartbeatInterval.call(this);sendMessage(...e){return this.send(JSON.stringify(e))}static makeDefib(){return g(()=>this.terminate(),65e3)}static makeHeartbeatInterval(){return setInterval(()=>{this[a]=Date.now(),this.send("")},5e3)}};var b=class n extends v{constructor(e,t,i){let{ssl:s,port:h,server:c=s?f.createServer({...s}):C.createServer(),...m}=e;super({...m,WebSocket:r,server:c}),t&&(typeof t=="function"?i=t:Object.assign(this,t)),this.on("connection",n.handleConnection),c.listen(h,i)}isWebSocketServer=!0;static handleConnection(e,t){if(!(e instanceof r)){Object.defineProperties(e,{isConnecting:{get:Object.getOwnPropertyDescriptor(r.prototype,"isConnecting").get},isOpen:{get:Object.getOwnPropertyDescriptor(r.prototype,"isOpen").get},isClosing:{get:Object.getOwnPropertyDescriptor(r.prototype,"isClosing").get},isClosed:{get:Object.getOwnPropertyDescriptor(r.prototype,"isClosed").get}});let{terminate:i}=e;Object.assign(e,{isWebSocketServerClient:!0,[o]:r.makeDefib.call(e),latency:0,[l]:r.makeHeartbeatInterval.call(e),sendMessage:r.prototype.sendMessage,terminate(){try{i.call(e)}catch(s){console.error(s)}}})}Object.assign(e,{wss:this,userAgent:t.headers["user-agent"],remoteAddress:t.headers["x-real-ip"]??t.headers["x-forwarded-for"]??"127.0.0.1"}),e[o](),e.on("message",n.handleClientMessage),e.on("error",n.handleClientError),e.on("close",n.handleClientClose),this.emit("client-connect",e,t)}static handleClientMessage(e){let t=e.toString();if(this[o](),t)try{let[i,...s]=JSON.parse(t);this.emit(`message:${i}`,...s),this.wss.emit("client-message",this,i,...s),this.wss.emit(`client-message:${i}`,this,...s)}catch(i){n.handleClientError.call(this,i)}else this[a]&&(this.latency=Date.now()-this[a],delete this[a])}static handleClientError(e){e instanceof Event&&(e=void 0),process.env.NODE_ENV==="development"&&console.error("WebSocketServer Client error",e),this.wss.emit("client-error",this,e)}static handleClientClose(...e){process.env.NODE_ENV==="development"&&console.info("WebSocketServer Client closed",...e),this[o].clear(),clearInterval(this[l]),this.wss.emit("client-close",this),this.wss.emit("client-closed",this)}};export{b as InSiteWebSocketServer};
2
- //# sourceMappingURL=server.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/server/WebSocketServer.ts", "../src/server/symbols.ts", "../src/server/WebSocketServerClient.ts"],
4
- "sourcesContent": ["import http from \"node:http\";\nimport https from \"node:https\";\nimport WebSocket, { WebSocketServer } from \"ws\";\nimport { defibSymbol, heartbeatIntervalSymbol, pingTsSymbol } from \"./symbols\";\nimport { CompatibleListener, Options } from \"./types\";\nimport { InSiteWebSocketServerClient } from \"./WebSocketServerClient\";\n\n\nexport class InSiteWebSocketServer extends WebSocketServer<typeof InSiteWebSocketServerClient> {\n\tconstructor(options: Options, props?: Record<string, unknown>, handleListen?: (() => void)) {\n\t\tconst {\n\t\t\tssl,\n\t\t\tport,\n\t\t\tserver = ssl ? https.createServer({ ...ssl }) : http.createServer(),\n\t\t\t...wssOptions\n\t\t} = options;\n\t\t\n\t\tsuper({\n\t\t\t...wssOptions,\n\t\t\tWebSocket: InSiteWebSocketServerClient,\n\t\t\tserver\n\t\t});\n\t\t\n\t\tif (props)\n\t\t\tif (typeof props == \"function\")\n\t\t\t\thandleListen = props;\n\t\t\telse\n\t\t\t\tObject.assign(this, props);\n\t\t\n\t\tthis.on(\"connection\", InSiteWebSocketServer.handleConnection as CompatibleListener);\n\t\t\n\t\tserver.listen(port, handleListen);\n\t\t\n\t}\n\t\n\treadonly isWebSocketServer = true;\n\t\n\t\n\tstatic handleConnection(this: InSiteWebSocketServer, ws: InSiteWebSocketServerClient | WebSocket, request: http.IncomingMessage) {\n\t\tif (!(ws instanceof InSiteWebSocketServerClient)) { /* Compatibility with Bun */\n\t\t\tObject.defineProperties(ws, {\n\t\t\t\tisConnecting: {\n\t\t\t\t\tget: Object.getOwnPropertyDescriptor(InSiteWebSocketServerClient.prototype, \"isConnecting\")!.get\n\t\t\t\t},\n\t\t\t\tisOpen: {\n\t\t\t\t\tget: Object.getOwnPropertyDescriptor(InSiteWebSocketServerClient.prototype, \"isOpen\")!.get\n\t\t\t\t},\n\t\t\t\tisClosing: {\n\t\t\t\t\tget: Object.getOwnPropertyDescriptor(InSiteWebSocketServerClient.prototype, \"isClosing\")!.get\n\t\t\t\t},\n\t\t\t\tisClosed: {\n\t\t\t\t\tget: Object.getOwnPropertyDescriptor(InSiteWebSocketServerClient.prototype, \"isClosed\")!.get\n\t\t\t\t}\n\t\t\t});\n\t\t\t\n\t\t\tconst { terminate } = ws;\n\t\t\t\n\t\t\tObject.assign(ws, {\n\t\t\t\tisWebSocketServerClient: true,\n\t\t\t\t[defibSymbol]: InSiteWebSocketServerClient.makeDefib.call(ws as InSiteWebSocketServerClient),\n\t\t\t\tlatency: 0,\n\t\t\t\t[heartbeatIntervalSymbol]: InSiteWebSocketServerClient.makeHeartbeatInterval.call(ws as InSiteWebSocketServerClient),\n\t\t\t\tsendMessage: InSiteWebSocketServerClient.prototype.sendMessage,\n\t\t\t\tterminate() { /* Workaround Bun's WebSocket#terminate bug */\n\t\t\t\t\t\n\t\t\t\t\ttry {\n\t\t\t\t\t\tterminate.call(ws);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tconsole.error(error);\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\t\n\t\tObject.assign(ws, {\n\t\t\twss: this,\n\t\t\tuserAgent: request.headers[\"user-agent\"],\n\t\t\tremoteAddress: request.headers[\"x-real-ip\"] ?? request.headers[\"x-forwarded-for\"] ?? \"127.0.0.1\"\n\t\t});\n\t\t\n\t\t(ws as InSiteWebSocketServerClient)[defibSymbol]();\n\t\t\n\t\tws.on(\"message\", InSiteWebSocketServer.handleClientMessage as CompatibleListener);\n\t\tws.on(\"error\", InSiteWebSocketServer.handleClientError as CompatibleListener);\n\t\tws.on(\"close\", InSiteWebSocketServer.handleClientClose as CompatibleListener);\n\t\t\n\t\tthis.emit(\"client-connect\", ws, request);\n\t\t\n\t}\n\t\n\t\n\tstatic handleClientMessage(this: InSiteWebSocketServerClient, data: WebSocket.RawData) {\n\t\tconst message = data.toString();\n\t\t\n\t\tthis[defibSymbol]();\n\t\t\n\t\tif (message)\n\t\t\ttry {\n\t\t\t\tconst [ kind, ...rest ] = JSON.parse(message);\n\t\t\t\t\n\t\t\t\tthis.emit(`message:${kind}`, ...rest);\n\t\t\t\tthis.wss!.emit(\"client-message\", this, kind, ...rest);\n\t\t\t\tthis.wss!.emit(`client-message:${kind}`, this, ...rest);\n\t\t\t} catch (error) {\n\t\t\t\tInSiteWebSocketServer.handleClientError.call(this, error as Error);\n\t\t\t}\n\t\telse if (this[pingTsSymbol]) {\n\t\t\tthis.latency = Date.now() - this[pingTsSymbol];\n\t\t\tdelete this[pingTsSymbol];\n\t\t}\n\t\t\n\t}\n\t\n\tstatic handleClientError(this: InSiteWebSocketServerClient, error: Error | Event | undefined) {\n\t\tif (error instanceof Event)\n\t\t\terror = undefined;\n\t\t\n\t\tif (process.env.NODE_ENV === \"development\")\n\t\t\tconsole.error(\"WebSocketServer Client error\", error);\n\t\t\n\t\tthis.wss!.emit(\"client-error\", this, error);\n\t\t\n\t}\n\t\n\tstatic handleClientClose(this: InSiteWebSocketServerClient, ...args: unknown[]) {\n\t\t\n\t\tif (process.env.NODE_ENV === \"development\")\n\t\t\tconsole.info(\"WebSocketServer Client closed\", ...args);\n\t\t\n\t\tthis[defibSymbol].clear();\n\t\tclearInterval(this[heartbeatIntervalSymbol]);\n\t\t\n\t\tthis.wss!.emit(\"client-close\", this);\n\t\tthis.wss!.emit(\"client-closed\", this);\n\t\t\n\t}\n\t\n}\n", "export const heartbeatIntervalSymbol = Symbol(\"heartbeatInterval\");\nexport const defibSymbol = Symbol(\"defib\");\nexport const pingTsSymbol = Symbol(\"pingTs\");\n", "import { WebSocket } from \"ws\";\nimport { debounce } from \"@nesvet/n\";\nimport { heartbeatGap, heartbeatInterval } from \"../common\";\nimport { defibSymbol, heartbeatIntervalSymbol, pingTsSymbol } from \"./symbols\";\nimport { InSiteWebSocketServer } from \"./WebSocketServer\";\n\n\nexport class InSiteWebSocketServerClient extends WebSocket {\n\t\n\tget isConnecting() {\n\t\treturn this.readyState === this.CONNECTING;\n\t}\n\t\n\tget isOpen() {\n\t\treturn this.readyState === this.OPEN;\n\t}\n\t\n\tget isClosing() {\n\t\treturn this.readyState === this.CLOSING;\n\t}\n\t\n\tget isClosed() {\n\t\treturn this.readyState === this.CLOSED;\n\t}\n\t\n\treadonly isWebSocketServerClient = true;\n\t\n\twss?: InSiteWebSocketServer;\n\t\n\tuserAgent = \"\";\n\t\n\tremoteAddress = \"\";\n\t\n\t[defibSymbol] = InSiteWebSocketServerClient.makeDefib.call(this);\n\t\n\tlatency = 0;\n\t\n\t[pingTsSymbol]?: number;\n\t\n\t[heartbeatIntervalSymbol] = InSiteWebSocketServerClient.makeHeartbeatInterval.call(this);\n\t\n\tsendMessage(...args: unknown[]) {\n\t\treturn this.send(JSON.stringify(args));\n\t}\n\t\n\t\n\tstatic makeDefib(this: InSiteWebSocketServerClient) {\n\t\treturn debounce(() => this.terminate(), heartbeatInterval + heartbeatGap);\n\t}\n\t\n\tstatic makeHeartbeatInterval(this: InSiteWebSocketServerClient) {\n\t\treturn setInterval(() => {\n\t\t\t\n\t\t\tthis[pingTsSymbol] = Date.now();\n\t\t\tthis.send(\"\");\n\t\t\t\n\t\t}, heartbeatInterval);\n\t}\n\t\n}\n"],
5
- "mappings": "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",
6
- "names": ["http", "https", "WebSocketServer", "heartbeatIntervalSymbol", "defibSymbol", "pingTsSymbol", "WebSocket", "debounce", "InSiteWebSocketServerClient", "_InSiteWebSocketServerClient", "WebSocket", "defibSymbol", "pingTsSymbol", "heartbeatIntervalSymbol", "args", "debounce", "InSiteWebSocketServer", "_InSiteWebSocketServer", "WebSocketServer", "options", "props", "handleListen", "ssl", "port", "server", "https", "http", "wssOptions", "InSiteWebSocketServerClient", "ws", "request", "terminate", "defibSymbol", "heartbeatIntervalSymbol", "error", "data", "message", "kind", "rest", "pingTsSymbol", "args"]
7
- }