@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 +66 -57
- package/dist/index.js +114 -93
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +114 -88
- package/dist/index.mjs.map +1 -1
- package/dist/server.d.ts +203 -14
- package/dist/server.js +390 -38
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +391 -39
- package/dist/server.mjs.map +1 -1
- package/package.json +4 -4
- package/src/client/WebSocketClient.ts +183 -87
- package/src/client/utils/lifecycle.ts +33 -31
- package/src/index.ts +4 -2
- package/src/server/WebSocketServer.ts +178 -23
- package/src/server/errors/ClosedWebSocketServerError.ts +8 -0
- package/src/server/index.ts +2 -1
- package/src/server/utils/lifecycle.ts +47 -42
- package/src/types/schema.ts +0 -14
- package/src/client/ClientSocket.ts +0 -7
- package/src/errors/WebSocketMessageAbortError.ts +0 -8
- package/src/server/ServerSocket.ts +0 -1
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
|
-
|
|
115
|
-
|
|
116
|
-
message:
|
|
117
|
-
|
|
118
|
-
|
|
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
|
-
|
|
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
|
|
126
|
-
private protocols?;
|
|
141
|
+
#private;
|
|
127
142
|
private socket?;
|
|
128
|
-
private
|
|
129
|
-
private
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
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():
|
|
160
|
+
get readyState(): WebSocketClient.ReadyState;
|
|
149
161
|
get bufferedAmount(): number;
|
|
150
|
-
open(options?:
|
|
151
|
-
|
|
152
|
-
|
|
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
|
|
158
|
-
removeEventListener<Type extends
|
|
159
|
-
get onopen():
|
|
160
|
-
set onopen(listener:
|
|
161
|
-
get onmessage():
|
|
162
|
-
set onmessage(listener:
|
|
163
|
-
get onclose():
|
|
164
|
-
set onclose(listener:
|
|
165
|
-
get onerror():
|
|
166
|
-
set onerror(listener:
|
|
167
|
-
private
|
|
168
|
-
dispatchEvent<Type extends
|
|
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,
|
|
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
|
-
|
|
45
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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
|
-
|
|
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
|
|
122
|
+
static get OPEN() {
|
|
123
|
+
return WebSocket.OPEN;
|
|
124
|
+
}
|
|
127
125
|
get OPEN() {
|
|
128
126
|
return _WebSocketClient.OPEN;
|
|
129
127
|
}
|
|
130
|
-
static CLOSING
|
|
128
|
+
static get CLOSING() {
|
|
129
|
+
return WebSocket.CLOSING;
|
|
130
|
+
}
|
|
131
131
|
get CLOSING() {
|
|
132
132
|
return _WebSocketClient.CLOSING;
|
|
133
133
|
}
|
|
134
|
-
static 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
|
|
141
|
+
return this.socket?.binaryType ?? this.#binaryType;
|
|
140
142
|
}
|
|
141
143
|
set binaryType(value) {
|
|
142
|
-
this
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
164
|
-
|
|
165
|
-
|
|
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
|
|
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.
|
|
214
|
+
this.listenerToRawListener[type].set(listener, rawListener);
|
|
196
215
|
}
|
|
197
216
|
removeEventListener(type, listener, options) {
|
|
198
|
-
const rawListener = this.
|
|
217
|
+
const rawListener = this.listenerToRawListener[type].get(listener);
|
|
199
218
|
if (rawListener) {
|
|
200
219
|
this.socket?.removeEventListener(type, rawListener, options);
|
|
201
|
-
this.
|
|
220
|
+
this.listenerToRawListener[type].delete(listener);
|
|
202
221
|
}
|
|
203
222
|
}
|
|
204
223
|
get onopen() {
|
|
205
|
-
return this.
|
|
224
|
+
return this.unitaryListeners.open;
|
|
206
225
|
}
|
|
207
226
|
set onopen(listener) {
|
|
208
|
-
this.
|
|
227
|
+
this.setEventListener("open", listener);
|
|
209
228
|
}
|
|
210
229
|
get onmessage() {
|
|
211
|
-
return this.
|
|
230
|
+
return this.unitaryListeners.message;
|
|
212
231
|
}
|
|
213
232
|
set onmessage(listener) {
|
|
214
|
-
this.
|
|
233
|
+
this.setEventListener("message", listener);
|
|
215
234
|
}
|
|
216
235
|
get onclose() {
|
|
217
|
-
return this.
|
|
236
|
+
return this.unitaryListeners.close;
|
|
218
237
|
}
|
|
219
238
|
set onclose(listener) {
|
|
220
|
-
this.
|
|
239
|
+
this.setEventListener("close", listener);
|
|
221
240
|
}
|
|
222
241
|
get onerror() {
|
|
223
|
-
return this.
|
|
242
|
+
return this.unitaryListeners.error;
|
|
224
243
|
}
|
|
225
244
|
set onerror(listener) {
|
|
226
|
-
this.
|
|
245
|
+
this.setEventListener("error", listener);
|
|
227
246
|
}
|
|
228
|
-
|
|
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.
|
|
258
|
+
this.listenerToRawListener[type].set(listener, rawListener);
|
|
232
259
|
if (this.socket) {
|
|
233
260
|
this.socket[`on${type}`] = rawListener;
|
|
234
261
|
}
|
|
235
|
-
this[
|
|
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[
|
|
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 =
|
|
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"]}
|