UNPKG

partysocket

Version:
1 lines 26.1 kB
{"version":3,"sources":["../src/ws.ts"],"sourcesContent":["// TODO: lose this eslint-disable\n\n/*!\n * Reconnecting WebSocket\n * by Pedro Ladaria <pedro.ladaria@gmail.com>\n * https://github.com/pladaria/reconnecting-websocket\n * License MIT\n */\n\nimport type { TypedEventTarget } from \"./type-helper\";\n\nif (!globalThis.EventTarget || !globalThis.Event) {\n console.error(`\n PartySocket requires a global 'EventTarget' class to be available!\n You can polyfill this global by adding this to your code before any partysocket imports: \n \n \\`\\`\\`\n import 'partysocket/event-target-polyfill';\n \\`\\`\\`\n Please file an issue at https://github.com/partykit/partykit if you're still having trouble.\n`);\n}\n\nexport class ErrorEvent extends Event {\n public message: string;\n public error: Error;\n // biome-ignore lint/suspicious/noExplicitAny: vibes\n constructor(error: Error, target: any) {\n super(\"error\", target);\n this.message = error.message;\n this.error = error;\n }\n}\n\nexport class CloseEvent extends Event {\n public code: number;\n public reason: string;\n public wasClean = true;\n // biome-ignore lint/style/useDefaultParameterLast: legacy\n // biome-ignore lint/suspicious/noExplicitAny: legacy\n constructor(code = 1000, reason = \"\", target: any) {\n super(\"close\", target);\n this.code = code;\n this.reason = reason;\n }\n}\nexport interface WebSocketEventMap {\n close: CloseEvent;\n error: ErrorEvent;\n message: MessageEvent;\n open: Event;\n}\n\nconst Events = {\n Event,\n ErrorEvent,\n CloseEvent\n};\n\nfunction assert(condition: unknown, msg?: string): asserts condition {\n if (!condition) {\n throw new Error(msg);\n }\n}\n\nfunction cloneEventBrowser(e: Event) {\n // biome-ignore lint/suspicious/noExplicitAny: legacy\n return new (e as any).constructor(e.type, e) as Event;\n}\n\nfunction cloneEventNode(e: Event) {\n if (\"data\" in e) {\n const evt = new MessageEvent(e.type, e);\n return evt;\n }\n\n if (\"code\" in e || \"reason\" in e) {\n const evt = new CloseEvent(\n // @ts-expect-error we need to fix event/listener types\n (e.code || 1999) as number,\n // @ts-expect-error we need to fix event/listener types\n (e.reason || \"unknown reason\") as string,\n e\n );\n return evt;\n }\n\n if (\"error\" in e) {\n const evt = new ErrorEvent(e.error as Error, e);\n return evt;\n }\n\n const evt = new Event(e.type, e);\n return evt;\n}\n\nconst isNode =\n typeof process !== \"undefined\" &&\n typeof process.versions?.node !== \"undefined\" &&\n typeof document === \"undefined\";\n\nconst cloneEvent = isNode ? cloneEventNode : cloneEventBrowser;\n\nexport type Options = {\n // biome-ignore lint/suspicious/noExplicitAny: legacy\n WebSocket?: any;\n maxReconnectionDelay?: number;\n minReconnectionDelay?: number;\n reconnectionDelayGrowFactor?: number;\n minUptime?: number;\n connectionTimeout?: number;\n maxRetries?: number;\n maxEnqueuedMessages?: number;\n startClosed?: boolean;\n debug?: boolean;\n // biome-ignore lint/suspicious/noExplicitAny: legacy\n debugLogger?: (...args: any[]) => void;\n};\n\nconst DEFAULT = {\n maxReconnectionDelay: 10000,\n minReconnectionDelay: 1000 + Math.random() * 4000,\n minUptime: 5000,\n reconnectionDelayGrowFactor: 1.3,\n connectionTimeout: 4000,\n maxRetries: Number.POSITIVE_INFINITY,\n maxEnqueuedMessages: Number.POSITIVE_INFINITY,\n startClosed: false,\n debug: false\n};\n\nlet didWarnAboutMissingWebSocket = false;\n\nexport type UrlProvider = string | (() => string) | (() => Promise<string>);\nexport type ProtocolsProvider =\n | null\n | string\n | string[]\n | (() => string | string[] | null)\n | (() => Promise<string | string[] | null>);\n\nexport type Message = string | ArrayBuffer | Blob | ArrayBufferView;\n\nexport default class ReconnectingWebSocket extends (EventTarget as TypedEventTarget<WebSocketEventMap>) {\n private _ws: WebSocket | undefined;\n private _retryCount = -1;\n private _uptimeTimeout: ReturnType<typeof setTimeout> | undefined;\n private _connectTimeout: ReturnType<typeof setTimeout> | undefined;\n private _shouldReconnect = true;\n private _connectLock = false;\n private _binaryType: BinaryType = \"blob\";\n private _closeCalled = false;\n private _messageQueue: Message[] = [];\n\n private _debugLogger = console.log.bind(console);\n\n protected _url: UrlProvider;\n protected _protocols?: ProtocolsProvider;\n protected _options: Options;\n\n constructor(\n url: UrlProvider,\n protocols?: ProtocolsProvider,\n options: Options = {}\n ) {\n super();\n this._url = url;\n this._protocols = protocols;\n this._options = options;\n if (this._options.startClosed) {\n this._shouldReconnect = false;\n }\n if (this._options.debugLogger) {\n this._debugLogger = this._options.debugLogger;\n }\n this._connect();\n }\n\n static get CONNECTING() {\n return 0;\n }\n static get OPEN() {\n return 1;\n }\n static get CLOSING() {\n return 2;\n }\n static get CLOSED() {\n return 3;\n }\n\n get CONNECTING() {\n return ReconnectingWebSocket.CONNECTING;\n }\n get OPEN() {\n return ReconnectingWebSocket.OPEN;\n }\n get CLOSING() {\n return ReconnectingWebSocket.CLOSING;\n }\n get CLOSED() {\n return ReconnectingWebSocket.CLOSED;\n }\n\n get binaryType() {\n return this._ws ? this._ws.binaryType : this._binaryType;\n }\n\n set binaryType(value: BinaryType) {\n this._binaryType = value;\n if (this._ws) {\n this._ws.binaryType = value;\n }\n }\n\n /**\n * Returns the number or connection retries\n */\n get retryCount(): number {\n return Math.max(this._retryCount, 0);\n }\n\n /**\n * The number of bytes of data that have been queued using calls to send() but not yet\n * transmitted to the network. This value resets to zero once all queued data has been sent.\n * This value does not reset to zero when the connection is closed; if you keep calling send(),\n * this will continue to climb. Read only\n */\n get bufferedAmount(): number {\n const bytes = this._messageQueue.reduce((acc, message) => {\n if (typeof message === \"string\") {\n acc += message.length; // not byte size\n } else if (message instanceof Blob) {\n acc += message.size;\n } else {\n acc += message.byteLength;\n }\n return acc;\n }, 0);\n return bytes + (this._ws ? this._ws.bufferedAmount : 0);\n }\n\n /**\n * The extensions selected by the server. This is currently only the empty string or a list of\n * extensions as negotiated by the connection\n */\n get extensions(): string {\n return this._ws ? this._ws.extensions : \"\";\n }\n\n /**\n * A string indicating the name of the sub-protocol the server selected;\n * this will be one of the strings specified in the protocols parameter when creating the\n * WebSocket object\n */\n get protocol(): string {\n return this._ws ? this._ws.protocol : \"\";\n }\n\n /**\n * The current state of the connection; this is one of the Ready state constants\n */\n get readyState(): number {\n if (this._ws) {\n return this._ws.readyState;\n }\n return this._options.startClosed\n ? ReconnectingWebSocket.CLOSED\n : ReconnectingWebSocket.CONNECTING;\n }\n\n /**\n * The URL as resolved by the constructor\n */\n get url(): string {\n return this._ws ? this._ws.url : \"\";\n }\n\n /**\n * Whether the websocket object is now in reconnectable state\n */\n get shouldReconnect(): boolean {\n return this._shouldReconnect;\n }\n\n /**\n * An event listener to be called when the WebSocket connection's readyState changes to CLOSED\n */\n public onclose: ((event: CloseEvent) => void) | null = null;\n\n /**\n * An event listener to be called when an error occurs\n */\n public onerror: ((event: ErrorEvent) => void) | null = null;\n\n /**\n * An event listener to be called when a message is received from the server\n */\n public onmessage: ((event: MessageEvent) => void) | null = null;\n\n /**\n * An event listener to be called when the WebSocket connection's readyState changes to OPEN;\n * this indicates that the connection is ready to send and receive data\n */\n public onopen: ((event: Event) => void) | null = null;\n\n /**\n * Closes the WebSocket connection or connection attempt, if any. If the connection is already\n * CLOSED, this method does nothing\n */\n public close(code = 1000, reason?: string) {\n this._closeCalled = true;\n this._shouldReconnect = false;\n this._clearTimeouts();\n if (!this._ws) {\n this._debug(\"close enqueued: no ws instance\");\n return;\n }\n if (this._ws.readyState === this.CLOSED) {\n this._debug(\"close: already closed\");\n return;\n }\n this._ws.close(code, reason);\n }\n\n /**\n * Closes the WebSocket connection or connection attempt and connects again.\n * Resets retry counter;\n */\n public reconnect(code?: number, reason?: string) {\n this._shouldReconnect = true;\n this._closeCalled = false;\n this._retryCount = -1;\n if (!this._ws || this._ws.readyState === this.CLOSED) {\n this._connect();\n } else {\n this._disconnect(code, reason);\n this._connect();\n }\n }\n\n /**\n * Enqueue specified data to be transmitted to the server over the WebSocket connection\n */\n public send(data: Message) {\n if (this._ws && this._ws.readyState === this.OPEN) {\n this._debug(\"send\", data);\n this._ws.send(data);\n } else {\n const { maxEnqueuedMessages = DEFAULT.maxEnqueuedMessages } =\n this._options;\n if (this._messageQueue.length < maxEnqueuedMessages) {\n this._debug(\"enqueue\", data);\n this._messageQueue.push(data);\n }\n }\n }\n\n private _debug(...args: unknown[]) {\n if (this._options.debug) {\n this._debugLogger(\"RWS>\", ...args);\n }\n }\n\n private _getNextDelay() {\n const {\n reconnectionDelayGrowFactor = DEFAULT.reconnectionDelayGrowFactor,\n minReconnectionDelay = DEFAULT.minReconnectionDelay,\n maxReconnectionDelay = DEFAULT.maxReconnectionDelay\n } = this._options;\n let delay = 0;\n if (this._retryCount > 0) {\n delay =\n minReconnectionDelay *\n reconnectionDelayGrowFactor ** (this._retryCount - 1);\n if (delay > maxReconnectionDelay) {\n delay = maxReconnectionDelay;\n }\n }\n this._debug(\"next delay\", delay);\n return delay;\n }\n\n private _wait(): Promise<void> {\n return new Promise((resolve) => {\n setTimeout(resolve, this._getNextDelay());\n });\n }\n\n private _getNextProtocols(\n protocolsProvider: ProtocolsProvider | null\n ): Promise<string | string[] | null> {\n if (!protocolsProvider) return Promise.resolve(null);\n\n if (\n typeof protocolsProvider === \"string\" ||\n Array.isArray(protocolsProvider)\n ) {\n return Promise.resolve(protocolsProvider);\n }\n\n if (typeof protocolsProvider === \"function\") {\n const protocols = protocolsProvider();\n if (!protocols) return Promise.resolve(null);\n\n if (typeof protocols === \"string\" || Array.isArray(protocols)) {\n return Promise.resolve(protocols);\n }\n\n // @ts-expect-error redundant check\n if (protocols.then) {\n return protocols;\n }\n }\n\n throw Error(\"Invalid protocols\");\n }\n\n private _getNextUrl(urlProvider: UrlProvider): Promise<string> {\n if (typeof urlProvider === \"string\") {\n return Promise.resolve(urlProvider);\n }\n if (typeof urlProvider === \"function\") {\n const url = urlProvider();\n if (typeof url === \"string\") {\n return Promise.resolve(url);\n }\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n if (url.then) {\n return url;\n }\n\n // return url;\n }\n throw Error(\"Invalid URL\");\n }\n\n private _connect() {\n if (this._connectLock || !this._shouldReconnect) {\n return;\n }\n this._connectLock = true;\n\n const {\n maxRetries = DEFAULT.maxRetries,\n connectionTimeout = DEFAULT.connectionTimeout\n } = this._options;\n\n if (this._retryCount >= maxRetries) {\n this._debug(\"max retries reached\", this._retryCount, \">=\", maxRetries);\n return;\n }\n\n this._retryCount++;\n\n this._debug(\"connect\", this._retryCount);\n this._removeListeners();\n\n this._wait()\n .then(() =>\n Promise.all([\n this._getNextUrl(this._url),\n this._getNextProtocols(this._protocols || null)\n ])\n )\n .then(([url, protocols]) => {\n // close could be called before creating the ws\n if (this._closeCalled) {\n this._connectLock = false;\n return;\n }\n if (\n !this._options.WebSocket &&\n typeof WebSocket === \"undefined\" &&\n !didWarnAboutMissingWebSocket\n ) {\n console.error(`‼️ No WebSocket implementation available. You should define options.WebSocket. \n\nFor example, if you're using node.js, run \\`npm install ws\\`, and then in your code:\n\nimport PartySocket from 'partysocket';\nimport WS from 'ws';\n\nconst partysocket = new PartySocket({\n host: \"127.0.0.1:1999\",\n room: \"test-room\",\n WebSocket: WS\n});\n\n`);\n didWarnAboutMissingWebSocket = true;\n }\n const WS: typeof WebSocket = this._options.WebSocket || WebSocket;\n this._debug(\"connect\", { url, protocols });\n this._ws = protocols ? new WS(url, protocols) : new WS(url);\n\n this._ws.binaryType = this._binaryType;\n this._connectLock = false;\n this._addListeners();\n\n this._connectTimeout = setTimeout(\n () => this._handleTimeout(),\n connectionTimeout\n );\n })\n // via https://github.com/pladaria/reconnecting-websocket/pull/166\n .catch((err) => {\n this._connectLock = false;\n this._handleError(new Events.ErrorEvent(Error(err.message), this));\n });\n }\n\n private _handleTimeout() {\n this._debug(\"timeout event\");\n this._handleError(new Events.ErrorEvent(Error(\"TIMEOUT\"), this));\n }\n\n private _disconnect(code = 1000, reason?: string) {\n this._clearTimeouts();\n if (!this._ws) {\n return;\n }\n this._removeListeners();\n try {\n if (this._ws.readyState === this.OPEN) {\n this._ws.close(code, reason);\n }\n this._handleClose(new Events.CloseEvent(code, reason, this));\n } catch (error) {\n // ignore\n }\n }\n\n private _acceptOpen() {\n this._debug(\"accept open\");\n this._retryCount = 0;\n }\n\n private _handleOpen = (event: Event) => {\n this._debug(\"open event\");\n const { minUptime = DEFAULT.minUptime } = this._options;\n\n clearTimeout(this._connectTimeout);\n this._uptimeTimeout = setTimeout(() => this._acceptOpen(), minUptime);\n\n assert(this._ws, \"WebSocket is not defined\");\n\n this._ws.binaryType = this._binaryType;\n\n // send enqueued messages (messages sent before websocket open event)\n this._messageQueue.forEach((message) => this._ws?.send(message));\n this._messageQueue = [];\n\n if (this.onopen) {\n this.onopen(event);\n }\n this.dispatchEvent(cloneEvent(event));\n };\n\n private _handleMessage = (event: MessageEvent) => {\n this._debug(\"message event\");\n\n if (this.onmessage) {\n this.onmessage(event);\n }\n this.dispatchEvent(cloneEvent(event));\n };\n\n private _handleError = (event: ErrorEvent) => {\n this._debug(\"error event\", event.message);\n this._disconnect(\n undefined,\n event.message === \"TIMEOUT\" ? \"timeout\" : undefined\n );\n\n if (this.onerror) {\n this.onerror(event);\n }\n this._debug(\"exec error listeners\");\n this.dispatchEvent(cloneEvent(event));\n\n this._connect();\n };\n\n private _handleClose = (event: CloseEvent) => {\n this._debug(\"close event\");\n this._clearTimeouts();\n\n if (this._shouldReconnect) {\n this._connect();\n }\n\n if (this.onclose) {\n this.onclose(event);\n }\n this.dispatchEvent(cloneEvent(event));\n };\n\n private _removeListeners() {\n if (!this._ws) {\n return;\n }\n this._debug(\"removeListeners\");\n this._ws.removeEventListener(\"open\", this._handleOpen);\n this._ws.removeEventListener(\"close\", this._handleClose);\n this._ws.removeEventListener(\"message\", this._handleMessage);\n // @ts-expect-error we need to fix event/listerner types\n this._ws.removeEventListener(\"error\", this._handleError);\n }\n\n private _addListeners() {\n if (!this._ws) {\n return;\n }\n this._debug(\"addListeners\");\n this._ws.addEventListener(\"open\", this._handleOpen);\n this._ws.addEventListener(\"close\", this._handleClose);\n this._ws.addEventListener(\"message\", this._handleMessage);\n // @ts-expect-error we need to fix event/listener types\n this._ws.addEventListener(\"error\", this._handleError);\n }\n\n private _clearTimeouts() {\n clearTimeout(this._connectTimeout);\n clearTimeout(this._uptimeTimeout);\n }\n}\n"],"mappings":"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","names":["evt","_a"]}