@zimic/ws 0.1.2-canary.8 → 0.2.0-canary.0

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/dist/index.d.ts CHANGED
@@ -1,19 +1,3 @@
1
- declare class WebSocketTimeoutError extends Error {
2
- constructor(message: string);
3
- }
4
-
5
- declare class WebSocketCloseTimeoutError extends WebSocketTimeoutError {
6
- constructor(reachedTimeout: number);
7
- }
8
-
9
- declare class WebSocketMessageAbortError extends WebSocketTimeoutError {
10
- constructor();
11
- }
12
-
13
- declare class WebSocketOpenTimeoutError extends WebSocketTimeoutError {
14
- constructor(reachedTimeout: number);
15
- }
16
-
17
1
  type JSON = {
18
2
  [key: string]: JSON;
19
3
  } | JSON[] | string | number | boolean | null | undefined;
@@ -91,6 +75,7 @@ type JSONStringified$1<Value> = string & {
91
75
  [JSON.value]: JSONSerialized<Value>;
92
76
  };
93
77
 
78
+ type PossiblePromise<Type> = Type | PromiseLike<Type>;
94
79
  declare const brand: unique symbol;
95
80
  /**
96
81
  * A utility type to create a branded type. This is useful for creating types that are distinct from each other even if
@@ -111,61 +96,85 @@ type JSONStringified<Value> = JSONStringified$1<Value>;
111
96
  type BaseWebSocketSchema = JSONValue | string | Blob | BufferSource;
112
97
  type WebSocketSchema<Schema extends BaseWebSocketSchema = BaseWebSocketSchema> = Branded<Schema, 'WebSocketSchema'>;
113
98
  type WebSocketMessageData<Schema extends WebSocketSchema> = Schema extends Blob ? Schema : Schema extends BufferSource ? Schema : Schema extends string ? Schema : JSONStringified<Schema>;
114
- interface WebSocketEventMap<Schema extends WebSocketSchema> {
115
- open: Event;
116
- message: MessageEvent<WebSocketMessageData<Schema>>;
117
- close: CloseEvent;
118
- error: Event;
99
+
100
+ declare class WebSocketTimeoutError extends Error {
101
+ constructor(message: string);
102
+ }
103
+
104
+ declare class WebSocketCloseTimeoutError extends WebSocketTimeoutError {
105
+ constructor(reachedTimeout: number);
119
106
  }
120
- type WebSocketEventType<Schema extends WebSocketSchema = WebSocketSchema> = keyof WebSocketEventMap<Schema>;
121
- type WebSocketEvent<Schema extends WebSocketSchema = WebSocketSchema, Type extends WebSocketEventType = WebSocketEventType> = WebSocketEventMap<Schema>[Type];
122
107
 
123
- type WebSocketClientEventListener<Schema extends WebSocketSchema, Type extends WebSocketEventType<Schema>> = (this: WebSocketClient<Schema>, event: WebSocketEvent<Schema, Type>) => unknown;
108
+ declare class WebSocketOpenTimeoutError extends WebSocketTimeoutError {
109
+ constructor(reachedTimeout: number);
110
+ }
111
+
112
+ interface WebSocketClientOpenOptions {
113
+ timeout?: number;
114
+ }
115
+ type WebSocketClientCloseOptions = WebSocketClientOpenOptions;
116
+
117
+ declare namespace WebSocketClient {
118
+ export type ReadyState = typeof WebSocketClient.CONNECTING | typeof WebSocketClient.OPEN | typeof WebSocketClient.CLOSING | typeof WebSocketClient.CLOSED;
119
+ export type OpenEvent<_Schema extends WebSocketSchema> = globalThis.Event;
120
+ export type MessageEvent<Schema extends WebSocketSchema> = globalThis.MessageEvent<WebSocketMessageData<Schema>>;
121
+ export type CloseEvent<_Schema extends WebSocketSchema> = globalThis.CloseEvent;
122
+ export type ErrorEvent<_Schema extends WebSocketSchema> = globalThis.Event;
123
+ interface Events<Schema extends WebSocketSchema = WebSocketSchema> {
124
+ open: OpenEvent<Schema>;
125
+ message: MessageEvent<Schema>;
126
+ close: CloseEvent<Schema>;
127
+ error: ErrorEvent<Schema>;
128
+ }
129
+ export type EventType = keyof Events<WebSocketSchema>;
130
+ export type Event<Schema extends WebSocketSchema = WebSocketSchema, Type extends EventType = EventType> = Events<Schema>[Type];
131
+ interface EventListenerParameters<Schema extends WebSocketSchema> {
132
+ open: [event: Event<Schema, 'open'>];
133
+ message: [event: Event<Schema, 'message'>];
134
+ close: [event: Event<Schema, 'close'>];
135
+ error: [event: Event<Schema, 'error'>];
136
+ }
137
+ export type EventListener<Schema extends WebSocketSchema, Type extends EventType> = (this: WebSocketClient<Schema>, ...parameters: EventListenerParameters<Schema>[Type]) => PossiblePromise<void>;
138
+ export { };
139
+ }
124
140
  declare class WebSocketClient<Schema extends WebSocketSchema> implements Omit<WebSocket, `${string}EventListener` | `on${string}`> {
125
- private _url;
126
- private protocols?;
141
+ #private;
127
142
  private socket?;
128
- private _binaryType;
129
- private _onopen;
130
- private _onmessage;
131
- private _onclose;
132
- private _onerror;
133
- private listeners;
134
- constructor(_url: string, protocols?: string | string[] | undefined);
135
- static CONNECTING: 0;
143
+ private unitaryListeners;
144
+ private listenerToRawListener;
145
+ constructor(socket: WebSocket);
146
+ constructor(_url: string, protocols?: string | string[]);
147
+ static get CONNECTING(): 0;
136
148
  get CONNECTING(): 0;
137
- static OPEN: 1;
149
+ static get OPEN(): 1;
138
150
  get OPEN(): 1;
139
- static CLOSING: 2;
151
+ static get CLOSING(): 2;
140
152
  get CLOSING(): 2;
141
- static CLOSED: 3;
153
+ static get CLOSED(): 3;
142
154
  get CLOSED(): 3;
143
155
  get binaryType(): "blob" | "arraybuffer";
144
156
  set binaryType(value: 'blob' | 'arraybuffer');
145
157
  get url(): string;
146
158
  get protocol(): string;
147
159
  get extensions(): string;
148
- get readyState(): 0 | 1 | 2 | 3;
160
+ get readyState(): WebSocketClient.ReadyState;
149
161
  get bufferedAmount(): number;
150
- open(options?: {
151
- timeout?: number;
152
- }): Promise<void>;
153
- close(code?: number, reason?: string, options?: {
154
- timeout?: number;
155
- }): Promise<void>;
162
+ open(options?: WebSocketClientOpenOptions): Promise<void>;
163
+ private applyListeners;
164
+ close(code?: number, reason?: string, options?: WebSocketClientCloseOptions): Promise<void>;
156
165
  send(data: WebSocketMessageData<Schema>): void;
157
- addEventListener<Type extends WebSocketEventType<Schema>>(type: Type, listener: (this: WebSocketClient<Schema>, event: WebSocketEvent<Schema, Type>) => unknown, options?: boolean | AddEventListenerOptions): void;
158
- removeEventListener<Type extends WebSocketEventType<Schema>>(type: Type, listener: (this: WebSocketClient<Schema>, event: WebSocketEvent<Schema, Type>) => unknown, options?: boolean | EventListenerOptions): void;
159
- get onopen(): WebSocketClientEventListener<Schema, "open"> | null;
160
- set onopen(listener: WebSocketClientEventListener<Schema, 'open'> | null);
161
- get onmessage(): WebSocketClientEventListener<Schema, "message"> | null;
162
- set onmessage(listener: WebSocketClientEventListener<Schema, 'message'> | null);
163
- get onclose(): WebSocketClientEventListener<Schema, "close"> | null;
164
- set onclose(listener: WebSocketClientEventListener<Schema, 'close'> | null);
165
- get onerror(): WebSocketClientEventListener<Schema, "error"> | null;
166
- set onerror(listener: WebSocketClientEventListener<Schema, 'error'> | null);
167
- private setUnitaryEventListener;
168
- dispatchEvent<Type extends WebSocketEventType<Schema>>(event: WebSocketEvent<Schema, Type>): boolean;
166
+ addEventListener<Type extends WebSocketClient.EventType>(type: Type, listener: WebSocketClient.EventListener<Schema, Type>, options?: boolean | AddEventListenerOptions): void;
167
+ removeEventListener<Type extends WebSocketClient.EventType>(type: Type, listener: WebSocketClient.EventListener<Schema, Type>, options?: boolean | EventListenerOptions): void;
168
+ get onopen(): WebSocketClient.EventListener<Schema, "open"> | null;
169
+ set onopen(listener: WebSocketClient.EventListener<Schema, 'open'> | null);
170
+ get onmessage(): WebSocketClient.EventListener<Schema, "message"> | null;
171
+ set onmessage(listener: WebSocketClient.EventListener<Schema, 'message'> | null);
172
+ get onclose(): WebSocketClient.EventListener<Schema, "close"> | null;
173
+ set onclose(listener: WebSocketClient.EventListener<Schema, 'close'> | null);
174
+ get onerror(): WebSocketClient.EventListener<Schema, "error"> | null;
175
+ set onerror(listener: WebSocketClient.EventListener<Schema, 'error'> | null);
176
+ private setEventListener;
177
+ dispatchEvent<Type extends WebSocketClient.EventType>(event: WebSocketClient.Event<Schema, Type>): boolean;
169
178
  }
170
179
 
171
- export { WebSocketClient, WebSocketCloseTimeoutError, WebSocketMessageAbortError, WebSocketOpenTimeoutError, WebSocketTimeoutError };
180
+ export { WebSocketClient, type WebSocketClientCloseOptions, type WebSocketClientOpenOptions, WebSocketCloseTimeoutError, type WebSocketMessageData, WebSocketOpenTimeoutError, type WebSocketSchema, WebSocketTimeoutError };
package/dist/index.js CHANGED
@@ -1,11 +1,5 @@
1
1
  'use strict';
2
2
 
3
- var NodeWebSocket = require('ws');
4
-
5
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
6
-
7
- var NodeWebSocket__default = /*#__PURE__*/_interopDefault(NodeWebSocket);
8
-
9
3
  // src/errors/WebSocketTimeoutError.ts
10
4
  var WebSocketTimeoutError = class extends Error {
11
5
  constructor(message) {
@@ -22,14 +16,6 @@ var WebSocketCloseTimeoutError = class extends WebSocketTimeoutError {
22
16
  }
23
17
  };
24
18
 
25
- // src/errors/WebSocketMessageAbortError.ts
26
- var WebSocketMessageAbortError = class extends WebSocketTimeoutError {
27
- constructor() {
28
- super("Web socket message was aborted.");
29
- this.name = "WebSocketMessageAbortError";
30
- }
31
- };
32
-
33
19
  // src/errors/WebSocketOpenTimeoutError.ts
34
20
  var WebSocketOpenTimeoutError = class extends WebSocketTimeoutError {
35
21
  constructor(reachedTimeout) {
@@ -37,33 +23,32 @@ var WebSocketOpenTimeoutError = class extends WebSocketTimeoutError {
37
23
  this.name = "WebSocketOpenTimeoutError";
38
24
  }
39
25
  };
40
- var isNativeWebSocketAvailable = typeof WebSocket !== "undefined";
41
- var ClientSocket = isNativeWebSocketAvailable ? WebSocket : NodeWebSocket__default.default;
42
26
 
43
27
  // src/client/utils/lifecycle.ts
44
- async function openClientSocket(socket, options = {}) {
45
- const { timeout: timeoutDuration } = options;
28
+ var DEFAULT_WEB_SOCKET_LIFECYCLE_TIMEOUT = 60 * 1e3;
29
+ async function openWebSocketClient(socket, options = {}) {
30
+ const { timeout: timeoutDuration = DEFAULT_WEB_SOCKET_LIFECYCLE_TIMEOUT } = options;
46
31
  const isAlreadyOpen = socket.readyState === socket.OPEN;
47
32
  if (isAlreadyOpen) {
48
33
  return;
49
34
  }
50
35
  await new Promise((resolve, reject) => {
51
- function removeAllSocketListeners() {
36
+ const openTimeout = setTimeout(() => {
37
+ const timeoutError = new WebSocketOpenTimeoutError(timeoutDuration);
38
+ handleError(timeoutError);
39
+ }, timeoutDuration);
40
+ function removeListenersAndTimeout() {
41
+ clearTimeout(openTimeout);
52
42
  socket.removeEventListener("open", handleOpenSuccess);
53
43
  socket.removeEventListener("error", handleError);
54
44
  socket.removeEventListener("close", handleError);
55
45
  }
56
46
  function handleError(error) {
57
- removeAllSocketListeners();
47
+ removeListenersAndTimeout();
58
48
  reject(error);
59
49
  }
60
- const openTimeout = timeoutDuration === void 0 ? void 0 : setTimeout(() => {
61
- const timeoutError = new WebSocketOpenTimeoutError(timeoutDuration);
62
- handleError(timeoutError);
63
- }, timeoutDuration);
64
50
  function handleOpenSuccess() {
65
- removeAllSocketListeners();
66
- clearTimeout(openTimeout);
51
+ removeListenersAndTimeout();
67
52
  resolve();
68
53
  }
69
54
  socket.addEventListener("open", handleOpenSuccess);
@@ -71,28 +56,28 @@ async function openClientSocket(socket, options = {}) {
71
56
  socket.addEventListener("close", handleError);
72
57
  });
73
58
  }
74
- async function closeClientSocket(socket, options = {}) {
75
- const { timeout: timeoutDuration } = options;
59
+ async function closeWebSocketClient(socket, options) {
60
+ const { timeout: timeoutDuration = DEFAULT_WEB_SOCKET_LIFECYCLE_TIMEOUT } = options;
76
61
  const isAlreadyClosed = socket.readyState === socket.CLOSED;
77
62
  if (isAlreadyClosed) {
78
63
  return;
79
64
  }
80
65
  await new Promise((resolve, reject) => {
81
- function removeAllSocketListeners() {
66
+ const closeTimeout = setTimeout(() => {
67
+ const timeoutError = new WebSocketCloseTimeoutError(timeoutDuration);
68
+ handleError(timeoutError);
69
+ }, timeoutDuration);
70
+ function removeListenersAndTimeout() {
71
+ clearTimeout(closeTimeout);
82
72
  socket.removeEventListener("error", handleError);
83
73
  socket.removeEventListener("close", handleClose);
84
74
  }
85
75
  function handleError(error) {
86
- removeAllSocketListeners();
76
+ removeListenersAndTimeout();
87
77
  reject(error);
88
78
  }
89
- const closeTimeout = timeoutDuration === void 0 ? void 0 : setTimeout(() => {
90
- const timeoutError = new WebSocketCloseTimeoutError(timeoutDuration);
91
- handleError(timeoutError);
92
- }, timeoutDuration);
93
79
  function handleClose() {
94
- removeAllSocketListeners();
95
- clearTimeout(closeTimeout);
80
+ removeListenersAndTimeout();
96
81
  resolve();
97
82
  }
98
83
  socket.addEventListener("error", handleError);
@@ -103,49 +88,66 @@ async function closeClientSocket(socket, options = {}) {
103
88
 
104
89
  // src/client/WebSocketClient.ts
105
90
  var WebSocketClient = class _WebSocketClient {
106
- constructor(_url, protocols) {
107
- this._url = _url;
108
- this.protocols = protocols;
109
- }
110
91
  socket;
111
- _binaryType = "blob";
112
- _onopen = null;
113
- _onmessage = null;
114
- _onclose = null;
115
- _onerror = null;
116
- listeners = {
92
+ #url;
93
+ #protocols;
94
+ #binaryType = "blob";
95
+ unitaryListeners = {
96
+ open: null,
97
+ message: null,
98
+ close: null,
99
+ error: null
100
+ };
101
+ listenerToRawListener = {
117
102
  open: /* @__PURE__ */ new Map(),
118
103
  message: /* @__PURE__ */ new Map(),
119
104
  close: /* @__PURE__ */ new Map(),
120
105
  error: /* @__PURE__ */ new Map()
121
106
  };
122
- static CONNECTING = ClientSocket.CONNECTING;
107
+ constructor(urlOrSocket, protocols) {
108
+ if (typeof urlOrSocket === "string") {
109
+ this.#url = urlOrSocket;
110
+ } else {
111
+ this.#url = urlOrSocket.url;
112
+ this.socket = urlOrSocket;
113
+ }
114
+ this.#protocols = protocols;
115
+ }
116
+ static get CONNECTING() {
117
+ return WebSocket.CONNECTING;
118
+ }
123
119
  get CONNECTING() {
124
120
  return _WebSocketClient.CONNECTING;
125
121
  }
126
- static OPEN = ClientSocket.OPEN;
122
+ static get OPEN() {
123
+ return WebSocket.OPEN;
124
+ }
127
125
  get OPEN() {
128
126
  return _WebSocketClient.OPEN;
129
127
  }
130
- static CLOSING = ClientSocket.CLOSING;
128
+ static get CLOSING() {
129
+ return WebSocket.CLOSING;
130
+ }
131
131
  get CLOSING() {
132
132
  return _WebSocketClient.CLOSING;
133
133
  }
134
- static CLOSED = ClientSocket.CLOSED;
134
+ static get CLOSED() {
135
+ return WebSocket.CLOSED;
136
+ }
135
137
  get CLOSED() {
136
138
  return _WebSocketClient.CLOSED;
137
139
  }
138
140
  get binaryType() {
139
- return this.socket?.binaryType ?? this._binaryType;
141
+ return this.socket?.binaryType ?? this.#binaryType;
140
142
  }
141
143
  set binaryType(value) {
142
- this._binaryType = value;
144
+ this.#binaryType = value;
143
145
  if (this.socket) {
144
146
  this.socket.binaryType = value;
145
147
  }
146
148
  }
147
149
  get url() {
148
- return this.socket?.url ?? this._url;
150
+ return this.socket?.url ?? this.#url;
149
151
  }
150
152
  get protocol() {
151
153
  return this.socket?.protocol ?? "";
@@ -154,35 +156,52 @@ var WebSocketClient = class _WebSocketClient {
154
156
  return this.socket?.extensions ?? "";
155
157
  }
156
158
  get readyState() {
157
- return this.socket?.readyState ?? ClientSocket.CLOSED;
159
+ const readyState = this.socket?.readyState ?? WebSocket.CLOSED;
160
+ return readyState;
158
161
  }
159
162
  get bufferedAmount() {
160
163
  return this.socket?.bufferedAmount ?? 0;
161
164
  }
162
- async open(options = {}) {
163
- this.socket = new ClientSocket(this._url, this.protocols);
164
- if (this.socket.binaryType !== this._binaryType) {
165
- this.socket.binaryType = this._binaryType;
165
+ async open(options) {
166
+ if (this.readyState === _WebSocketClient.OPEN) {
167
+ return;
168
+ }
169
+ await this.close();
170
+ const socket = new WebSocket(this.#url, this.#protocols);
171
+ try {
172
+ if (socket.binaryType !== this.binaryType) {
173
+ socket.binaryType = this.binaryType;
174
+ }
175
+ this.applyListeners(socket);
176
+ await openWebSocketClient(socket, options);
177
+ } catch (error) {
178
+ socket.close();
179
+ throw error;
180
+ }
181
+ this.socket = socket;
182
+ }
183
+ applyListeners(socket) {
184
+ for (const type of ["open", "message", "close", "error"]) {
185
+ const unitaryListener = this[`on${type}`];
186
+ const rawUnitaryListener = unitaryListener ? this.listenerToRawListener[type].get(unitaryListener) : void 0;
187
+ if (rawUnitaryListener) {
188
+ socket[`on${type}`] = rawUnitaryListener;
189
+ }
190
+ for (const rawListener of this.listenerToRawListener[type].values()) {
191
+ const isRawUnitaryListener = rawListener === rawUnitaryListener;
192
+ if (!isRawUnitaryListener) {
193
+ socket.addEventListener(type, rawListener);
194
+ }
195
+ }
166
196
  }
167
- await openClientSocket(this.socket, options);
168
197
  }
169
- async close(code, reason, options = {}) {
198
+ async close(code, reason, options) {
170
199
  if (!this.socket) {
171
200
  return;
172
201
  }
173
202
  try {
174
- await closeClientSocket(this.socket, { ...options, code, reason });
203
+ await closeWebSocketClient(this.socket, { ...options, code, reason });
175
204
  } finally {
176
- this.onopen = null;
177
- this.onmessage = null;
178
- this.onclose = null;
179
- this.onerror = null;
180
- for (const [type, listenerToRawListener] of Object.entries(this.listeners)) {
181
- for (const rawListener of listenerToRawListener.values()) {
182
- this.socket.removeEventListener(type, rawListener);
183
- }
184
- listenerToRawListener.clear();
185
- }
186
205
  this.socket = void 0;
187
206
  }
188
207
  }
@@ -192,67 +211,69 @@ var WebSocketClient = class _WebSocketClient {
192
211
  addEventListener(type, listener, options) {
193
212
  const rawListener = listener.bind(this);
194
213
  this.socket?.addEventListener(type, rawListener, options);
195
- this.listeners[type].set(listener, rawListener);
214
+ this.listenerToRawListener[type].set(listener, rawListener);
196
215
  }
197
216
  removeEventListener(type, listener, options) {
198
- const rawListener = this.listeners[type].get(listener);
217
+ const rawListener = this.listenerToRawListener[type].get(listener);
199
218
  if (rawListener) {
200
219
  this.socket?.removeEventListener(type, rawListener, options);
201
- this.listeners[type].delete(listener);
220
+ this.listenerToRawListener[type].delete(listener);
202
221
  }
203
222
  }
204
223
  get onopen() {
205
- return this._onopen;
224
+ return this.unitaryListeners.open;
206
225
  }
207
226
  set onopen(listener) {
208
- this.setUnitaryEventListener("open", listener);
227
+ this.setEventListener("open", listener);
209
228
  }
210
229
  get onmessage() {
211
- return this._onmessage;
230
+ return this.unitaryListeners.message;
212
231
  }
213
232
  set onmessage(listener) {
214
- this.setUnitaryEventListener("message", listener);
233
+ this.setEventListener("message", listener);
215
234
  }
216
235
  get onclose() {
217
- return this._onclose;
236
+ return this.unitaryListeners.close;
218
237
  }
219
238
  set onclose(listener) {
220
- this.setUnitaryEventListener("close", listener);
239
+ this.setEventListener("close", listener);
221
240
  }
222
241
  get onerror() {
223
- return this._onerror;
242
+ return this.unitaryListeners.error;
224
243
  }
225
244
  set onerror(listener) {
226
- this.setUnitaryEventListener("error", listener);
245
+ this.setEventListener("error", listener);
227
246
  }
228
- setUnitaryEventListener(type, listener) {
247
+ setEventListener(type, listener) {
248
+ const currentListener = this.unitaryListeners[type];
249
+ if (currentListener) {
250
+ const rawListener = this.listenerToRawListener[type].get(currentListener);
251
+ if (this.socket && rawListener) {
252
+ this.socket[`on${type}`] = null;
253
+ }
254
+ this.listenerToRawListener[type].delete(currentListener);
255
+ }
229
256
  if (listener) {
230
257
  const rawListener = listener.bind(this);
231
- this.listeners[type].set(listener, rawListener);
258
+ this.listenerToRawListener[type].set(listener, rawListener);
232
259
  if (this.socket) {
233
260
  this.socket[`on${type}`] = rawListener;
234
261
  }
235
- this[`_on${type}`] = listener;
262
+ this.unitaryListeners[type] = listener;
236
263
  } else {
237
- const currentListener = this[`_on${type}`];
238
- if (currentListener) {
239
- this.listeners[type].delete(currentListener);
240
- }
241
264
  if (this.socket) {
242
265
  this.socket[`on${type}`] = null;
243
266
  }
244
- this[`_on${type}`] = null;
267
+ this.unitaryListeners[type] = null;
245
268
  }
246
269
  }
247
270
  dispatchEvent(event) {
248
271
  return this.socket?.dispatchEvent(event) ?? false;
249
272
  }
250
273
  };
251
- var WebSocketClient_default = WebSocketClient;
252
274
 
253
- exports.WebSocketClient = WebSocketClient_default;
275
+ exports.WebSocketClient = WebSocketClient;
254
276
  exports.WebSocketCloseTimeoutError = WebSocketCloseTimeoutError;
255
- exports.WebSocketMessageAbortError = WebSocketMessageAbortError;
256
277
  exports.WebSocketOpenTimeoutError = WebSocketOpenTimeoutError;
257
278
  exports.WebSocketTimeoutError = WebSocketTimeoutError;
258
279
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors/WebSocketTimeoutError.ts","../src/errors/WebSocketCloseTimeoutError.ts","../src/errors/WebSocketMessageAbortError.ts","../src/errors/WebSocketOpenTimeoutError.ts","../src/client/ClientSocket.ts","../src/client/utils/lifecycle.ts","../src/client/WebSocketClient.ts"],"names":["NodeWebSocket"],"mappings":"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","file":"index.js","sourcesContent":["export class WebSocketTimeoutError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'WebSocketTimeoutError';\n }\n}\n","import { WebSocketTimeoutError } from './WebSocketTimeoutError';\n\nexport class WebSocketCloseTimeoutError extends WebSocketTimeoutError {\n constructor(reachedTimeout: number) {\n super(`Web socket close timed out after ${reachedTimeout}ms.`);\n this.name = 'WebSocketCloseTimeoutError';\n }\n}\n","import { WebSocketTimeoutError } from './WebSocketTimeoutError';\n\nexport class WebSocketMessageAbortError extends WebSocketTimeoutError {\n constructor() {\n super('Web socket message was aborted.');\n this.name = 'WebSocketMessageAbortError';\n }\n}\n","import { WebSocketTimeoutError } from './WebSocketTimeoutError';\n\nexport class WebSocketOpenTimeoutError extends WebSocketTimeoutError {\n constructor(reachedTimeout: number) {\n super(`Web socket open timed out after ${reachedTimeout}ms.`);\n this.name = 'WebSocketOpenTimeoutError';\n }\n}\n","import NodeWebSocket from 'ws';\n\n// WebSocket is available natively in browsers and Node.js >=22.\nconst isNativeWebSocketAvailable = typeof WebSocket !== 'undefined';\n\nexport const ClientSocket = (isNativeWebSocketAvailable ? WebSocket : NodeWebSocket) as typeof WebSocket;\nexport type ClientSocket = InstanceType<typeof ClientSocket>;\n","import { WebSocketCloseTimeoutError } from '@/errors/WebSocketCloseTimeoutError';\nimport { WebSocketOpenTimeoutError } from '@/errors/WebSocketOpenTimeoutError';\n\nimport { ClientSocket } from '../ClientSocket';\n\nexport async function openClientSocket(socket: ClientSocket, options: { timeout?: number } = {}) {\n const { timeout: timeoutDuration } = options;\n\n const isAlreadyOpen = socket.readyState === socket.OPEN;\n\n if (isAlreadyOpen) {\n return;\n }\n\n await new Promise<void>((resolve, reject) => {\n function removeAllSocketListeners() {\n socket.removeEventListener('open', handleOpenSuccess); // eslint-disable-line @typescript-eslint/no-use-before-define\n socket.removeEventListener('error', handleError); // eslint-disable-line @typescript-eslint/no-use-before-define\n socket.removeEventListener('close', handleError); // eslint-disable-line @typescript-eslint/no-use-before-define\n }\n\n function handleError(error: unknown) {\n removeAllSocketListeners();\n reject(error);\n }\n\n const openTimeout =\n timeoutDuration === undefined\n ? undefined\n : setTimeout(() => {\n const timeoutError = new WebSocketOpenTimeoutError(timeoutDuration);\n handleError(timeoutError);\n }, timeoutDuration);\n\n function handleOpenSuccess() {\n removeAllSocketListeners();\n clearTimeout(openTimeout);\n resolve();\n }\n\n socket.addEventListener('open', handleOpenSuccess);\n socket.addEventListener('error', handleError);\n socket.addEventListener('close', handleError);\n });\n}\n\nexport async function closeClientSocket(\n socket: ClientSocket,\n options: { code?: number; reason?: string; timeout?: number } = {},\n) {\n const { timeout: timeoutDuration } = options;\n\n const isAlreadyClosed = socket.readyState === socket.CLOSED;\n\n if (isAlreadyClosed) {\n return;\n }\n\n await new Promise<void>((resolve, reject) => {\n function removeAllSocketListeners() {\n socket.removeEventListener('error', handleError); // eslint-disable-line @typescript-eslint/no-use-before-define\n socket.removeEventListener('close', handleClose); // eslint-disable-line @typescript-eslint/no-use-before-define\n }\n\n function handleError(error: unknown) {\n removeAllSocketListeners();\n reject(error);\n }\n\n const closeTimeout =\n timeoutDuration === undefined\n ? undefined\n : setTimeout(() => {\n const timeoutError = new WebSocketCloseTimeoutError(timeoutDuration);\n handleError(timeoutError);\n }, timeoutDuration);\n\n function handleClose() {\n removeAllSocketListeners();\n clearTimeout(closeTimeout);\n resolve();\n }\n\n socket.addEventListener('error', handleError);\n socket.addEventListener('close', handleClose);\n\n socket.close(options.code, options.reason);\n });\n}\n","import { WebSocketEvent, WebSocketEventType, WebSocketMessageData, WebSocketSchema } from '@/types/schema';\n\nimport { ClientSocket } from './ClientSocket';\nimport { closeClientSocket, openClientSocket } from './utils/lifecycle';\n\nexport type WebSocketClientEventListener<Schema extends WebSocketSchema, Type extends WebSocketEventType<Schema>> = (\n this: WebSocketClient<Schema>,\n event: WebSocketEvent<Schema, Type>,\n) => unknown;\n\ntype WebSocketClientRawEventListener = (this: ClientSocket, event: Event) => unknown;\n\nclass WebSocketClient<Schema extends WebSocketSchema> implements Omit<\n WebSocket,\n `${string}EventListener` | `on${string}`\n> {\n private socket?: ClientSocket;\n private _binaryType: BinaryType = 'blob';\n\n private _onopen: WebSocketClientEventListener<Schema, 'open'> | null = null;\n private _onmessage: WebSocketClientEventListener<Schema, 'message'> | null = null;\n private _onclose: WebSocketClientEventListener<Schema, 'close'> | null = null;\n private _onerror: WebSocketClientEventListener<Schema, 'error'> | null = null;\n\n private listeners: {\n [Type in WebSocketEventType<Schema>]: Map<\n WebSocketClientEventListener<Schema, Type>,\n WebSocketClientRawEventListener\n >;\n } = {\n open: new Map(),\n message: new Map(),\n close: new Map(),\n error: new Map(),\n };\n\n constructor(\n private _url: string,\n private protocols?: string | string[],\n ) {}\n\n static CONNECTING = ClientSocket.CONNECTING;\n\n get CONNECTING() {\n return WebSocketClient.CONNECTING;\n }\n\n static OPEN = ClientSocket.OPEN;\n\n get OPEN() {\n return WebSocketClient.OPEN;\n }\n\n static CLOSING = ClientSocket.CLOSING;\n\n get CLOSING() {\n return WebSocketClient.CLOSING;\n }\n\n static CLOSED = ClientSocket.CLOSED;\n\n get CLOSED() {\n return WebSocketClient.CLOSED;\n }\n\n get binaryType() {\n return this.socket?.binaryType ?? this._binaryType;\n }\n\n set binaryType(value: 'blob' | 'arraybuffer') {\n this._binaryType = value;\n\n if (this.socket) {\n this.socket.binaryType = value;\n }\n }\n\n get url() {\n return this.socket?.url ?? this._url;\n }\n\n get protocol() {\n return this.socket?.protocol ?? '';\n }\n\n get extensions() {\n return this.socket?.extensions ?? '';\n }\n\n get readyState() {\n return this.socket?.readyState ?? ClientSocket.CLOSED;\n }\n\n get bufferedAmount() {\n return this.socket?.bufferedAmount ?? 0;\n }\n\n async open(options: { timeout?: number } = {}) {\n this.socket = new ClientSocket(this._url, this.protocols);\n\n if (this.socket.binaryType !== this._binaryType) {\n this.socket.binaryType = this._binaryType;\n }\n\n await openClientSocket(this.socket, options);\n }\n\n async close(code?: number, reason?: string, options: { timeout?: number } = {}) {\n if (!this.socket) {\n return;\n }\n\n try {\n await closeClientSocket(this.socket, { ...options, code, reason });\n } finally {\n this.onopen = null;\n this.onmessage = null;\n this.onclose = null;\n this.onerror = null;\n\n for (const [type, listenerToRawListener] of Object.entries(this.listeners)) {\n for (const rawListener of listenerToRawListener.values()) {\n this.socket.removeEventListener(type, rawListener);\n }\n\n listenerToRawListener.clear();\n }\n\n this.socket = undefined;\n }\n }\n\n send(data: WebSocketMessageData<Schema>) {\n this.socket?.send(data);\n }\n\n addEventListener<Type extends WebSocketEventType<Schema>>(\n type: Type,\n listener: (this: WebSocketClient<Schema>, event: WebSocketEvent<Schema, Type>) => unknown,\n options?: boolean | AddEventListenerOptions,\n ) {\n const rawListener = listener.bind(this) as WebSocketClientRawEventListener;\n\n this.socket?.addEventListener(type, rawListener, options);\n this.listeners[type].set(listener, rawListener);\n }\n\n removeEventListener<Type extends WebSocketEventType<Schema>>(\n type: Type,\n listener: (this: WebSocketClient<Schema>, event: WebSocketEvent<Schema, Type>) => unknown,\n options?: boolean | EventListenerOptions,\n ) {\n const rawListener = this.listeners[type].get(listener);\n\n if (rawListener) {\n this.socket?.removeEventListener(type, rawListener, options);\n this.listeners[type].delete(listener);\n }\n }\n\n get onopen() {\n return this._onopen;\n }\n\n set onopen(listener: WebSocketClientEventListener<Schema, 'open'> | null) {\n this.setUnitaryEventListener('open', listener);\n }\n\n get onmessage() {\n return this._onmessage;\n }\n\n set onmessage(listener: WebSocketClientEventListener<Schema, 'message'> | null) {\n this.setUnitaryEventListener('message', listener);\n }\n\n get onclose() {\n return this._onclose;\n }\n\n set onclose(listener: WebSocketClientEventListener<Schema, 'close'> | null) {\n this.setUnitaryEventListener('close', listener);\n }\n\n get onerror() {\n return this._onerror;\n }\n\n set onerror(listener: WebSocketClientEventListener<Schema, 'error'> | null) {\n this.setUnitaryEventListener('error', listener);\n }\n\n private setUnitaryEventListener<Type extends WebSocketEventType<Schema>>(\n type: Type,\n listener: WebSocketClientEventListener<Schema, Type> | null,\n ) {\n type PrivateUnitaryListener = typeof listener;\n\n if (listener) {\n const rawListener = listener.bind(this) as WebSocketClientRawEventListener;\n this.listeners[type].set(listener, rawListener);\n\n if (this.socket) {\n this.socket[`on${type}`] = rawListener;\n }\n\n (this[`_on${type}`] as PrivateUnitaryListener) = listener;\n } else {\n const currentListener = this[`_on${type}`] as PrivateUnitaryListener;\n\n if (currentListener) {\n this.listeners[type].delete(currentListener);\n }\n\n if (this.socket) {\n this.socket[`on${type}`] = null;\n }\n\n (this[`_on${type}`] as PrivateUnitaryListener) = null;\n }\n }\n\n dispatchEvent<Type extends WebSocketEventType<Schema>>(event: WebSocketEvent<Schema, Type>) {\n return this.socket?.dispatchEvent(event) ?? false;\n }\n}\n\nexport default WebSocketClient;\n"]}
1
+ {"version":3,"sources":["../src/errors/WebSocketTimeoutError.ts","../src/errors/WebSocketCloseTimeoutError.ts","../src/errors/WebSocketOpenTimeoutError.ts","../src/client/utils/lifecycle.ts","../src/client/WebSocketClient.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export class WebSocketTimeoutError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'WebSocketTimeoutError';\n }\n}\n","import { WebSocketTimeoutError } from './WebSocketTimeoutError';\n\nexport class WebSocketCloseTimeoutError extends WebSocketTimeoutError {\n constructor(reachedTimeout: number) {\n super(`Web socket close timed out after ${reachedTimeout}ms.`);\n this.name = 'WebSocketCloseTimeoutError';\n }\n}\n","import { WebSocketTimeoutError } from './WebSocketTimeoutError';\n\nexport class WebSocketOpenTimeoutError extends WebSocketTimeoutError {\n constructor(reachedTimeout: number) {\n super(`Web socket open timed out after ${reachedTimeout}ms.`);\n this.name = 'WebSocketOpenTimeoutError';\n }\n}\n","import { WebSocketCloseTimeoutError } from '@/errors/WebSocketCloseTimeoutError';\nimport { WebSocketOpenTimeoutError } from '@/errors/WebSocketOpenTimeoutError';\n\nexport const DEFAULT_WEB_SOCKET_LIFECYCLE_TIMEOUT = 60 * 1000;\n\nexport interface WebSocketClientOpenOptions {\n timeout?: number;\n}\n\nexport async function openWebSocketClient(socket: WebSocket, options: WebSocketClientOpenOptions = {}) {\n const { timeout: timeoutDuration = DEFAULT_WEB_SOCKET_LIFECYCLE_TIMEOUT } = options;\n\n const isAlreadyOpen = socket.readyState === socket.OPEN;\n\n if (isAlreadyOpen) {\n return;\n }\n\n await new Promise<void>((resolve, reject) => {\n const openTimeout = setTimeout(() => {\n const timeoutError = new WebSocketOpenTimeoutError(timeoutDuration);\n handleError(timeoutError); // eslint-disable-line @typescript-eslint/no-use-before-define\n }, timeoutDuration);\n\n function removeListenersAndTimeout() {\n clearTimeout(openTimeout);\n\n socket.removeEventListener('open', handleOpenSuccess); // eslint-disable-line @typescript-eslint/no-use-before-define\n socket.removeEventListener('error', handleError); // eslint-disable-line @typescript-eslint/no-use-before-define\n socket.removeEventListener('close', handleError); // eslint-disable-line @typescript-eslint/no-use-before-define\n }\n\n function handleError(error: unknown) {\n removeListenersAndTimeout();\n reject(error);\n }\n\n function handleOpenSuccess() {\n removeListenersAndTimeout();\n resolve();\n }\n\n socket.addEventListener('open', handleOpenSuccess);\n socket.addEventListener('error', handleError);\n socket.addEventListener('close', handleError);\n });\n}\n\nexport type WebSocketClientCloseOptions = WebSocketClientOpenOptions;\n\nexport async function closeWebSocketClient(\n socket: WebSocket,\n options: WebSocketClientCloseOptions & { code?: number; reason?: string },\n) {\n const { timeout: timeoutDuration = DEFAULT_WEB_SOCKET_LIFECYCLE_TIMEOUT } = options;\n\n const isAlreadyClosed = socket.readyState === socket.CLOSED;\n\n if (isAlreadyClosed) {\n return;\n }\n\n await new Promise<void>((resolve, reject) => {\n const closeTimeout = setTimeout(() => {\n const timeoutError = new WebSocketCloseTimeoutError(timeoutDuration);\n handleError(timeoutError); // eslint-disable-line @typescript-eslint/no-use-before-define\n }, timeoutDuration);\n\n function removeListenersAndTimeout() {\n clearTimeout(closeTimeout);\n\n socket.removeEventListener('error', handleError); // eslint-disable-line @typescript-eslint/no-use-before-define\n socket.removeEventListener('close', handleClose); // eslint-disable-line @typescript-eslint/no-use-before-define\n }\n\n function handleError(error: unknown) {\n removeListenersAndTimeout();\n reject(error);\n }\n\n function handleClose() {\n removeListenersAndTimeout();\n resolve();\n }\n\n socket.addEventListener('error', handleError);\n socket.addEventListener('close', handleClose);\n\n socket.close(options.code, options.reason);\n });\n}\n","import { PossiblePromise } from '@zimic/utils/types';\n\nimport { WebSocketMessageData, WebSocketSchema } from '@/types/schema';\n\nimport {\n closeWebSocketClient,\n openWebSocketClient,\n WebSocketClientCloseOptions,\n WebSocketClientOpenOptions,\n} from './utils/lifecycle';\n\nexport namespace WebSocketClient {\n export type ReadyState =\n | typeof WebSocketClient.CONNECTING\n | typeof WebSocketClient.OPEN\n | typeof WebSocketClient.CLOSING\n | typeof WebSocketClient.CLOSED;\n\n // The schema is not used in the event types, but it's included for consistency and future extensibility.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n export type OpenEvent<_Schema extends WebSocketSchema> = globalThis.Event;\n\n export type MessageEvent<Schema extends WebSocketSchema> = globalThis.MessageEvent<WebSocketMessageData<Schema>>;\n\n // The schema is not used in the event types, but it's included for consistency and future extensibility.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n export type CloseEvent<_Schema extends WebSocketSchema> = globalThis.CloseEvent;\n\n // The schema is not used in the event types, but it's included for consistency and future extensibility.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n export type ErrorEvent<_Schema extends WebSocketSchema> = globalThis.Event;\n\n interface Events<Schema extends WebSocketSchema = WebSocketSchema> {\n open: OpenEvent<Schema>;\n message: MessageEvent<Schema>;\n close: CloseEvent<Schema>;\n error: ErrorEvent<Schema>;\n }\n\n export type EventType = keyof Events<WebSocketSchema>;\n\n export type Event<\n Schema extends WebSocketSchema = WebSocketSchema,\n Type extends EventType = EventType,\n > = Events<Schema>[Type];\n\n interface EventListenerParameters<Schema extends WebSocketSchema> {\n open: [event: Event<Schema, 'open'>];\n message: [event: Event<Schema, 'message'>];\n close: [event: Event<Schema, 'close'>];\n error: [event: Event<Schema, 'error'>];\n }\n\n export type EventListener<Schema extends WebSocketSchema, Type extends EventType> = (\n this: WebSocketClient<Schema>,\n ...parameters: EventListenerParameters<Schema>[Type]\n ) => PossiblePromise<void>;\n}\n\ntype WebSocketClientRawEventListener = (this: WebSocket, event: Event) => PossiblePromise<void>;\n\nexport class WebSocketClient<Schema extends WebSocketSchema> implements Omit<\n WebSocket,\n `${string}EventListener` | `on${string}`\n> {\n private socket?: WebSocket;\n\n #url: string;\n #protocols?: string | string[];\n #binaryType: BinaryType = 'blob';\n\n private unitaryListeners: {\n [Type in WebSocketClient.EventType]: WebSocketClient.EventListener<Schema, Type> | null;\n } = {\n open: null,\n message: null,\n close: null,\n error: null,\n };\n\n private listenerToRawListener: {\n [Type in WebSocketClient.EventType]: Map<\n WebSocketClient.EventListener<Schema, Type>,\n WebSocketClientRawEventListener\n >;\n } = {\n open: new Map(),\n message: new Map(),\n close: new Map(),\n error: new Map(),\n };\n\n constructor(socket: WebSocket);\n constructor(_url: string, protocols?: string | string[]);\n constructor(urlOrSocket: WebSocket | string, protocols?: string | string[]) {\n if (typeof urlOrSocket === 'string') {\n this.#url = urlOrSocket;\n } else {\n this.#url = urlOrSocket.url;\n this.socket = urlOrSocket;\n }\n\n this.#protocols = protocols;\n }\n\n static get CONNECTING() {\n return WebSocket.CONNECTING;\n }\n\n get CONNECTING() {\n return WebSocketClient.CONNECTING;\n }\n\n static get OPEN() {\n return WebSocket.OPEN;\n }\n\n get OPEN() {\n return WebSocketClient.OPEN;\n }\n\n static get CLOSING() {\n return WebSocket.CLOSING;\n }\n\n get CLOSING() {\n return WebSocketClient.CLOSING;\n }\n\n static get CLOSED() {\n return WebSocket.CLOSED;\n }\n\n get CLOSED() {\n return WebSocketClient.CLOSED;\n }\n\n get binaryType() {\n return this.socket?.binaryType ?? this.#binaryType;\n }\n\n set binaryType(value: 'blob' | 'arraybuffer') {\n this.#binaryType = value;\n\n if (this.socket) {\n this.socket.binaryType = value;\n }\n }\n\n get url() {\n return this.socket?.url ?? this.#url;\n }\n\n get protocol() {\n return this.socket?.protocol ?? '';\n }\n\n get extensions() {\n return this.socket?.extensions ?? '';\n }\n\n get readyState(): WebSocketClient.ReadyState {\n const readyState = this.socket?.readyState ?? WebSocket.CLOSED;\n return readyState as WebSocketClient.ReadyState;\n }\n\n get bufferedAmount() {\n return this.socket?.bufferedAmount ?? 0;\n }\n\n async open(options?: WebSocketClientOpenOptions) {\n if (this.readyState === WebSocketClient.OPEN) {\n return;\n }\n\n await this.close();\n\n const socket = new WebSocket(this.#url, this.#protocols);\n\n try {\n if (socket.binaryType !== this.binaryType) {\n socket.binaryType = this.binaryType;\n }\n\n this.applyListeners(socket);\n\n await openWebSocketClient(socket, options);\n } catch (error) {\n socket.close();\n throw error;\n }\n\n this.socket = socket;\n }\n\n private applyListeners(socket: WebSocket) {\n for (const type of ['open', 'message', 'close', 'error'] as const) {\n const unitaryListener = this[`on${type}`] as WebSocketClient.EventListener<Schema, typeof type> | null;\n const rawUnitaryListener = unitaryListener ? this.listenerToRawListener[type].get(unitaryListener) : undefined;\n\n if (rawUnitaryListener) {\n socket[`on${type}`] = rawUnitaryListener;\n }\n\n for (const rawListener of this.listenerToRawListener[type].values()) {\n const isRawUnitaryListener = rawListener === rawUnitaryListener;\n\n if (!isRawUnitaryListener) {\n socket.addEventListener(type, rawListener);\n }\n }\n }\n }\n\n async close(code?: number, reason?: string, options?: WebSocketClientCloseOptions) {\n if (!this.socket) {\n return;\n }\n\n try {\n await closeWebSocketClient(this.socket, { ...options, code, reason });\n } finally {\n this.socket = undefined;\n }\n }\n\n send(data: WebSocketMessageData<Schema>) {\n this.socket?.send(data);\n }\n\n addEventListener<Type extends WebSocketClient.EventType>(\n type: Type,\n listener: WebSocketClient.EventListener<Schema, Type>,\n options?: boolean | AddEventListenerOptions,\n ) {\n const rawListener = listener.bind(this) as WebSocketClientRawEventListener;\n\n this.socket?.addEventListener(type, rawListener, options);\n this.listenerToRawListener[type].set(listener, rawListener);\n }\n\n removeEventListener<Type extends WebSocketClient.EventType>(\n type: Type,\n listener: WebSocketClient.EventListener<Schema, Type>,\n options?: boolean | EventListenerOptions,\n ) {\n const rawListener = this.listenerToRawListener[type].get(listener);\n\n if (rawListener) {\n this.socket?.removeEventListener(type, rawListener, options);\n this.listenerToRawListener[type].delete(listener);\n }\n }\n\n get onopen() {\n return this.unitaryListeners.open;\n }\n\n set onopen(listener: WebSocketClient.EventListener<Schema, 'open'> | null) {\n this.setEventListener('open', listener);\n }\n\n get onmessage() {\n return this.unitaryListeners.message;\n }\n\n set onmessage(listener: WebSocketClient.EventListener<Schema, 'message'> | null) {\n this.setEventListener('message', listener);\n }\n\n get onclose() {\n return this.unitaryListeners.close;\n }\n\n set onclose(listener: WebSocketClient.EventListener<Schema, 'close'> | null) {\n this.setEventListener('close', listener);\n }\n\n get onerror() {\n return this.unitaryListeners.error;\n }\n\n set onerror(listener: WebSocketClient.EventListener<Schema, 'error'> | null) {\n this.setEventListener('error', listener);\n }\n\n private setEventListener<\n Type extends WebSocketClient.EventType,\n Listener extends WebSocketClient.EventListener<Schema, Type> | null,\n >(type: Type, listener: Listener) {\n const currentListener = this.unitaryListeners[type];\n\n if (currentListener) {\n const rawListener = this.listenerToRawListener[type].get(currentListener);\n\n if (this.socket && rawListener) {\n this.socket[`on${type}`] = null;\n }\n\n this.listenerToRawListener[type].delete(currentListener);\n }\n\n if (listener) {\n const rawListener = listener.bind(this) as WebSocketClientRawEventListener;\n this.listenerToRawListener[type].set(listener, rawListener);\n\n if (this.socket) {\n this.socket[`on${type}`] = rawListener;\n }\n\n (this.unitaryListeners[type] as Listener) = listener;\n } else {\n if (this.socket) {\n this.socket[`on${type}`] = null;\n }\n\n (this.unitaryListeners[type] as Listener | null) = null;\n }\n }\n\n dispatchEvent<Type extends WebSocketClient.EventType>(event: WebSocketClient.Event<Schema, Type>) {\n return this.socket?.dispatchEvent(event) ?? false;\n }\n}\n"]}