@mswjs/interceptors 0.26.9 → 0.26.11
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/README.md +74 -74
- package/lib/browser/interceptors/WebSocket/index.d.ts +20 -14
- package/lib/browser/interceptors/WebSocket/index.js +161 -126
- package/lib/browser/interceptors/WebSocket/index.js.map +1 -1
- package/lib/browser/interceptors/WebSocket/index.mjs +165 -130
- package/lib/browser/interceptors/WebSocket/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/interceptors/WebSocket/WebSocketServerConnection.ts +87 -21
- package/src/interceptors/WebSocket/index.ts +12 -12
package/README.md
CHANGED
|
@@ -292,8 +292,8 @@ interceptor.on(
|
|
|
292
292
|
|
|
293
293
|
You can intercept a WebSocket communication using the `WebSocketInterceptor` class.
|
|
294
294
|
|
|
295
|
-
> [!
|
|
296
|
-
>
|
|
295
|
+
> [!IMPORTANT]
|
|
296
|
+
> This library only supports intercepting WebSocket connections created using the global WHATWG `WebSocket` class. Third-party transports, such as HTTP/XHR polling, are not supported by design due to their contrived nature.
|
|
297
297
|
|
|
298
298
|
```js
|
|
299
299
|
import { WebSocketInterceptor } from '@mswjs/interceptors/WebSocket'
|
|
@@ -303,6 +303,13 @@ const interceptor = new WebSocketInterceptor()
|
|
|
303
303
|
|
|
304
304
|
Unlike the HTTP-based interceptors that share the same `request`/`response` events, the WebSocket interceptor only emits the `connection` event and let's you handle the incoming/outgoing events in its listener.
|
|
305
305
|
|
|
306
|
+
### Important defaults
|
|
307
|
+
|
|
308
|
+
1. Intercepted WebSocket connections are _not_ opened. To open the actual WebSocket connection, call [`server.connect()`](#connect) in the interceptor.
|
|
309
|
+
1. Once connected to the actual server, the outgoing client events are _not_ forwarded to that server. You must add a message listener for the `client` and forward the events manually using [`server.send()`](#senddata-1).
|
|
310
|
+
1. Once connected to the actual server, the incoming server events _are_ forwarded to the client by default. You can prevent that forwarding by calling `event.preventDefault()` in the message event listener for the `server`.
|
|
311
|
+
1. Once connected to the actual server, the `close` event received from that server is forwarded to the intercepted client by default. You can prevent that forwarding by calling `event.preventDefault()` in the close event listener for the `server`.
|
|
312
|
+
|
|
306
313
|
### WebSocket connection
|
|
307
314
|
|
|
308
315
|
Whenever a WebSocket instance is constructed, the `connection` event is emitted on the WebSocket interceptor.
|
|
@@ -315,121 +322,114 @@ intereceptor.on('connection', ({ client }) => {
|
|
|
315
322
|
|
|
316
323
|
The `connection` event exposes the following arguments:
|
|
317
324
|
|
|
318
|
-
| Name | Type
|
|
319
|
-
| -------- |
|
|
320
|
-
| `client` | `
|
|
321
|
-
| `server` | `
|
|
325
|
+
| Name | Type | Description |
|
|
326
|
+
| -------- | --------------------------------------------------------- | ---------------------------------------------------------------- |
|
|
327
|
+
| `client` | [`WebSocketClientConnection`](#websocketclientconnection) | An object representing a connected WebSocket client instance. |
|
|
328
|
+
| `server` | [`WebSocketServerConnection`](#websocketserverconnection) | An object representing the original WebSocket server connection. |
|
|
322
329
|
|
|
323
|
-
###
|
|
330
|
+
### `WebSocketClientConnection`
|
|
324
331
|
|
|
325
|
-
|
|
332
|
+
#### `.addEventListener(type, listener)`
|
|
326
333
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
// Intercept all outgoing events from the client.
|
|
330
|
-
client.addEventListener('message', (event) => {
|
|
331
|
-
console.log('received:', event.data)
|
|
332
|
-
})
|
|
333
|
-
})
|
|
334
|
-
```
|
|
334
|
+
- `type`, `"message"`
|
|
335
|
+
- `listener`, `(event: MessageEvent<WebSocketData>) => void`
|
|
335
336
|
|
|
336
|
-
|
|
337
|
+
Adds an event listener to the given event type of the WebSocket client.
|
|
337
338
|
|
|
338
|
-
|
|
339
|
+
| Event name | Description |
|
|
340
|
+
| ---------- | ----------------------------------------------------------------- |
|
|
341
|
+
| `message` | Dispatched when data is sent by the intercepted WebSocket client. |
|
|
339
342
|
|
|
340
343
|
```js
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
// with the given "hello" string as the data.
|
|
344
|
-
client.send('hello')
|
|
344
|
+
client.addEventListener('message', (event) => {
|
|
345
|
+
console.log('outgoing:', event.data)
|
|
345
346
|
})
|
|
346
347
|
```
|
|
347
348
|
|
|
348
|
-
|
|
349
|
+
#### `.removeEventListener(type, listener)`
|
|
349
350
|
|
|
350
|
-
|
|
351
|
+
- `type`, `"message"`
|
|
352
|
+
- `listener`, `(event: MessageEvent<WebSocketData>) => void`
|
|
351
353
|
|
|
352
|
-
|
|
354
|
+
Removes the listener for the given event type.
|
|
353
355
|
|
|
354
|
-
|
|
356
|
+
#### `.send(data)`
|
|
355
357
|
|
|
356
|
-
|
|
357
|
-
interceptor.on('connection', ({ client, server }) => {
|
|
358
|
-
// First, connect to the original server.
|
|
359
|
-
server.connect()
|
|
358
|
+
- `data`, `string | Blob | ArrayBuffer`
|
|
360
359
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
360
|
+
Sends the data to the intercepted WebSocket client.
|
|
361
|
+
|
|
362
|
+
```js
|
|
363
|
+
client.send('text')
|
|
364
|
+
client.send(new Blob(['blob']))
|
|
365
|
+
client.send(new TextEncoder().encode('array buffer'))
|
|
364
366
|
```
|
|
365
367
|
|
|
366
|
-
|
|
368
|
+
#### `.close(code, reason)`
|
|
367
369
|
|
|
368
|
-
|
|
370
|
+
- `code`, close [status code](https://www.rfc-editor.org/rfc/rfc6455#section-7.4.1).
|
|
371
|
+
- `reason`, [close reason](https://www.rfc-editor.org/rfc/rfc6455#section-7.1.6).
|
|
369
372
|
|
|
370
|
-
|
|
373
|
+
Closes the client connection. Unlike the regular `WebSocket.prototype.close()`, the `client.close()` method can accept a non-configurable status codes, such as 1001, 1003, etc.
|
|
371
374
|
|
|
372
375
|
```js
|
|
373
|
-
|
|
374
|
-
|
|
376
|
+
// Gracefully close the connection with the
|
|
377
|
+
// intercepted WebSocket client.
|
|
378
|
+
client.close()
|
|
379
|
+
```
|
|
375
380
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
381
|
+
```js
|
|
382
|
+
// Terminate the connection by emulating
|
|
383
|
+
// the server unable to process the received data.
|
|
384
|
+
client.close(1003)
|
|
380
385
|
```
|
|
381
386
|
|
|
382
|
-
|
|
387
|
+
### `WebSocketServerConnection`
|
|
383
388
|
|
|
384
|
-
|
|
389
|
+
#### `.connect()`
|
|
385
390
|
|
|
386
|
-
|
|
387
|
-
interceptor.on('connection', ({ client, server }) => {
|
|
388
|
-
server.connect()
|
|
391
|
+
Establishes the connection to the original WebSocket server. Connection cannot be awaited. Any data sent via `server.send()` while connecting is buffered and flushed once the connection is open.
|
|
389
392
|
|
|
390
|
-
|
|
391
|
-
if (event.data === 'hello from server') {
|
|
392
|
-
// Never forward this event to the client.
|
|
393
|
-
event.preventDefault()
|
|
393
|
+
#### `.addEventListener(type, listener)`
|
|
394
394
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
return
|
|
398
|
-
}
|
|
399
|
-
})
|
|
400
|
-
})
|
|
401
|
-
```
|
|
395
|
+
- `type`, `"message"`
|
|
396
|
+
- `listener`, `(event: MessageEvent<WebSocketData>) => void`
|
|
402
397
|
|
|
403
|
-
|
|
398
|
+
Adds an event listener to the given event type of the WebSocket server.
|
|
404
399
|
|
|
405
|
-
|
|
400
|
+
| Event name | Description |
|
|
401
|
+
| ---------- | -------------------------------------------------------------------- |
|
|
402
|
+
| `message` | Dispatched when data is received from the original WebSocket server. |
|
|
406
403
|
|
|
407
404
|
```js
|
|
408
|
-
|
|
409
|
-
|
|
405
|
+
server.addEventListener('message', (event) => {
|
|
406
|
+
console.log('incoming:', event.data)
|
|
410
407
|
})
|
|
411
408
|
```
|
|
412
409
|
|
|
413
|
-
|
|
410
|
+
#### `.removeEventListener(type, listener)`
|
|
414
411
|
|
|
415
|
-
|
|
412
|
+
- `type`, `"message"`
|
|
413
|
+
- `listener`, `(event: MessageEvent<WebSocketData>) => void`
|
|
416
414
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
})
|
|
421
|
-
```
|
|
415
|
+
Removes the listener for the given event type.
|
|
416
|
+
|
|
417
|
+
#### `.send(data)`
|
|
422
418
|
|
|
423
|
-
|
|
419
|
+
- `data`, `string | Blob | ArrayBuffer`
|
|
420
|
+
|
|
421
|
+
Sends the data to the original WebSocket server. Useful in a combination with the client-sent events forwarding:
|
|
424
422
|
|
|
425
423
|
```js
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
// cannot accept the data sent from the client.
|
|
429
|
-
client.close(1003)
|
|
424
|
+
client.addEventListener('message', (event) => {
|
|
425
|
+
server.send(event.data)
|
|
430
426
|
})
|
|
431
427
|
```
|
|
432
428
|
|
|
429
|
+
#### `.close()`
|
|
430
|
+
|
|
431
|
+
Closes the connection with the original WebSocket server. Unlike `client.close()`, closing the server connection does not accept any arguments and always asumes a graceful closure. Sending data via `server.send()` after the connection has been closed will have no effect.
|
|
432
|
+
|
|
433
433
|
## API
|
|
434
434
|
|
|
435
435
|
### `Interceptor`
|
|
@@ -165,6 +165,7 @@ declare class WebSocketServerConnection {
|
|
|
165
165
|
* A WebSocket instance connected to the original server.
|
|
166
166
|
*/
|
|
167
167
|
private realWebSocket?;
|
|
168
|
+
private mockCloseController;
|
|
168
169
|
private [kEmitter];
|
|
169
170
|
constructor(socket: WebSocketOverride, transport: WebSocketClassTransport, createConnection: () => WebSocket);
|
|
170
171
|
/**
|
|
@@ -183,7 +184,7 @@ declare class WebSocketServerConnection {
|
|
|
183
184
|
*/
|
|
184
185
|
addEventListener<K extends keyof WebSocketEventMap>(event: K, listener: (this: WebSocket, event: WebSocketEventMap[K]) => void, options?: AddEventListenerOptions | boolean): void;
|
|
185
186
|
/**
|
|
186
|
-
*
|
|
187
|
+
* Remove the listener for the given event.
|
|
187
188
|
*/
|
|
188
189
|
removeEventListener<K extends keyof WebSocketEventMap>(event: K, listener: (this: WebSocket, event: WebSocketEventMap[K]) => void, options?: EventListenerOptions | boolean): void;
|
|
189
190
|
/**
|
|
@@ -194,21 +195,26 @@ declare class WebSocketServerConnection {
|
|
|
194
195
|
* server.send(new TextEncoder().encode('hello'))
|
|
195
196
|
*/
|
|
196
197
|
send(data: WebSocketData): void;
|
|
198
|
+
/**
|
|
199
|
+
* Close the actual server connection.
|
|
200
|
+
*/
|
|
201
|
+
close(): void;
|
|
202
|
+
private handleMockClose;
|
|
203
|
+
private handleRealClose;
|
|
197
204
|
}
|
|
198
205
|
|
|
199
206
|
type WebSocketEventMap$1 = {
|
|
200
|
-
connection: [
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
];
|
|
207
|
+
connection: [args: WebSocketConnectionData];
|
|
208
|
+
};
|
|
209
|
+
type WebSocketConnectionData = {
|
|
210
|
+
/**
|
|
211
|
+
* The incoming WebSocket client connection.
|
|
212
|
+
*/
|
|
213
|
+
client: WebSocketClientConnection;
|
|
214
|
+
/**
|
|
215
|
+
* The original WebSocket server connection.
|
|
216
|
+
*/
|
|
217
|
+
server: WebSocketServerConnection;
|
|
212
218
|
};
|
|
213
219
|
/**
|
|
214
220
|
* Intercept the outgoing WebSocket connections created using
|
|
@@ -221,4 +227,4 @@ declare class WebSocketInterceptor extends Interceptor<WebSocketEventMap$1> {
|
|
|
221
227
|
protected setup(): void;
|
|
222
228
|
}
|
|
223
229
|
|
|
224
|
-
export { WebSocketClientConnection, WebSocketClientConnectionProtocol, WebSocketData, WebSocketEventMap$1 as WebSocketEventMap, WebSocketInterceptor, WebSocketServerConnection, WebSocketTransport };
|
|
230
|
+
export { WebSocketClientConnection, WebSocketClientConnectionProtocol, WebSocketConnectionData, WebSocketData, WebSocketEventMap$1 as WebSocketEventMap, WebSocketInterceptor, WebSocketServerConnection, WebSocketTransport };
|
|
@@ -101,132 +101,6 @@ kEmitter;
|
|
|
101
101
|
|
|
102
102
|
// src/interceptors/WebSocket/WebSocketServerConnection.ts
|
|
103
103
|
var _outvariant = require('outvariant');
|
|
104
|
-
var kEmitter2 = Symbol("kEmitter");
|
|
105
|
-
var WebSocketServerConnection = class {
|
|
106
|
-
constructor(socket, transport, createConnection) {
|
|
107
|
-
this.socket = socket;
|
|
108
|
-
this.transport = transport;
|
|
109
|
-
this.createConnection = createConnection;
|
|
110
|
-
this[kEmitter2] = new EventTarget();
|
|
111
|
-
this.transport.onIncoming = (event) => {
|
|
112
|
-
const messageEvent = bindEvent(
|
|
113
|
-
this.realWebSocket,
|
|
114
|
-
new CancelableMessageEvent("message", {
|
|
115
|
-
data: event.data,
|
|
116
|
-
origin: event.origin,
|
|
117
|
-
cancelable: true
|
|
118
|
-
})
|
|
119
|
-
);
|
|
120
|
-
this[kEmitter2].dispatchEvent(messageEvent);
|
|
121
|
-
if (!messageEvent.defaultPrevented) {
|
|
122
|
-
this.socket.dispatchEvent(
|
|
123
|
-
bindEvent(
|
|
124
|
-
/**
|
|
125
|
-
* @note Bind the forwarded original server events
|
|
126
|
-
* to the mock WebSocket instance so it would
|
|
127
|
-
* dispatch them straight away.
|
|
128
|
-
*/
|
|
129
|
-
this.socket,
|
|
130
|
-
// Clone the message event again to prevent
|
|
131
|
-
// the "already being dispatched" exception.
|
|
132
|
-
new MessageEvent("message", {
|
|
133
|
-
data: event.data,
|
|
134
|
-
origin: event.origin
|
|
135
|
-
})
|
|
136
|
-
)
|
|
137
|
-
);
|
|
138
|
-
}
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Server ready state.
|
|
143
|
-
* Proxies the ready state of the original WebSocket instance,
|
|
144
|
-
* if set. If the original connection hasn't been established,
|
|
145
|
-
* defaults to `-1`.
|
|
146
|
-
*/
|
|
147
|
-
get readyState() {
|
|
148
|
-
if (this.realWebSocket) {
|
|
149
|
-
return this.realWebSocket.readyState;
|
|
150
|
-
}
|
|
151
|
-
return -1;
|
|
152
|
-
}
|
|
153
|
-
/**
|
|
154
|
-
* Open connection to the original WebSocket server.
|
|
155
|
-
*/
|
|
156
|
-
connect() {
|
|
157
|
-
_outvariant.invariant.call(void 0,
|
|
158
|
-
this.readyState === -1,
|
|
159
|
-
'Failed to call "connect()" on the original WebSocket instance: the connection already open'
|
|
160
|
-
);
|
|
161
|
-
const ws = this.createConnection();
|
|
162
|
-
ws.binaryType = this.socket.binaryType;
|
|
163
|
-
this.socket.addEventListener(
|
|
164
|
-
"close",
|
|
165
|
-
(event) => {
|
|
166
|
-
ws.close(event.code, event.reason);
|
|
167
|
-
},
|
|
168
|
-
{ once: true }
|
|
169
|
-
);
|
|
170
|
-
ws.addEventListener("message", (event) => {
|
|
171
|
-
this.transport.onIncoming(event);
|
|
172
|
-
});
|
|
173
|
-
ws.addEventListener("error", () => {
|
|
174
|
-
this.socket.dispatchEvent(bindEvent(this.socket, new Event("error")));
|
|
175
|
-
});
|
|
176
|
-
this.realWebSocket = ws;
|
|
177
|
-
}
|
|
178
|
-
/**
|
|
179
|
-
* Listen for the incoming events from the original WebSocket server.
|
|
180
|
-
*/
|
|
181
|
-
addEventListener(event, listener, options) {
|
|
182
|
-
this[kEmitter2].addEventListener(
|
|
183
|
-
event,
|
|
184
|
-
listener.bind(this.realWebSocket),
|
|
185
|
-
options
|
|
186
|
-
);
|
|
187
|
-
}
|
|
188
|
-
/**
|
|
189
|
-
* Removes the listener for the given event.
|
|
190
|
-
*/
|
|
191
|
-
removeEventListener(event, listener, options) {
|
|
192
|
-
this[kEmitter2].removeEventListener(
|
|
193
|
-
event,
|
|
194
|
-
listener,
|
|
195
|
-
options
|
|
196
|
-
);
|
|
197
|
-
}
|
|
198
|
-
/**
|
|
199
|
-
* Send data to the original WebSocket server.
|
|
200
|
-
* @example
|
|
201
|
-
* server.send('hello')
|
|
202
|
-
* server.send(new Blob(['hello']))
|
|
203
|
-
* server.send(new TextEncoder().encode('hello'))
|
|
204
|
-
*/
|
|
205
|
-
send(data) {
|
|
206
|
-
const { realWebSocket } = this;
|
|
207
|
-
_outvariant.invariant.call(void 0,
|
|
208
|
-
realWebSocket,
|
|
209
|
-
'Failed to call "server.send()" for "%s": the connection is not open. Did you forget to call "await server.connect()"?',
|
|
210
|
-
this.socket.url
|
|
211
|
-
);
|
|
212
|
-
if (realWebSocket.readyState === realWebSocket.CONNECTING) {
|
|
213
|
-
realWebSocket.addEventListener(
|
|
214
|
-
"open",
|
|
215
|
-
() => {
|
|
216
|
-
realWebSocket.send(data);
|
|
217
|
-
},
|
|
218
|
-
{ once: true }
|
|
219
|
-
);
|
|
220
|
-
return;
|
|
221
|
-
}
|
|
222
|
-
realWebSocket.send(data);
|
|
223
|
-
}
|
|
224
|
-
};
|
|
225
|
-
kEmitter2;
|
|
226
|
-
|
|
227
|
-
// src/interceptors/WebSocket/WebSocketTransport.ts
|
|
228
|
-
var WebSocketTransport = class {
|
|
229
|
-
};
|
|
230
104
|
|
|
231
105
|
// src/interceptors/WebSocket/WebSocketOverride.ts
|
|
232
106
|
|
|
@@ -377,6 +251,167 @@ function getDataSize(data) {
|
|
|
377
251
|
return data.byteLength;
|
|
378
252
|
}
|
|
379
253
|
|
|
254
|
+
// src/interceptors/WebSocket/WebSocketServerConnection.ts
|
|
255
|
+
var kEmitter2 = Symbol("kEmitter");
|
|
256
|
+
var WebSocketServerConnection = class {
|
|
257
|
+
constructor(socket, transport, createConnection) {
|
|
258
|
+
this.socket = socket;
|
|
259
|
+
this.transport = transport;
|
|
260
|
+
this.createConnection = createConnection;
|
|
261
|
+
this[kEmitter2] = new EventTarget();
|
|
262
|
+
this.mockCloseController = new AbortController();
|
|
263
|
+
this.transport.onIncoming = (event) => {
|
|
264
|
+
const messageEvent = bindEvent(
|
|
265
|
+
this.realWebSocket,
|
|
266
|
+
new CancelableMessageEvent("message", {
|
|
267
|
+
data: event.data,
|
|
268
|
+
origin: event.origin,
|
|
269
|
+
cancelable: true
|
|
270
|
+
})
|
|
271
|
+
);
|
|
272
|
+
this[kEmitter2].dispatchEvent(messageEvent);
|
|
273
|
+
if (!messageEvent.defaultPrevented) {
|
|
274
|
+
this.socket.dispatchEvent(
|
|
275
|
+
bindEvent(
|
|
276
|
+
/**
|
|
277
|
+
* @note Bind the forwarded original server events
|
|
278
|
+
* to the mock WebSocket instance so it would
|
|
279
|
+
* dispatch them straight away.
|
|
280
|
+
*/
|
|
281
|
+
this.socket,
|
|
282
|
+
// Clone the message event again to prevent
|
|
283
|
+
// the "already being dispatched" exception.
|
|
284
|
+
new MessageEvent("message", {
|
|
285
|
+
data: event.data,
|
|
286
|
+
origin: event.origin
|
|
287
|
+
})
|
|
288
|
+
)
|
|
289
|
+
);
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Server ready state.
|
|
295
|
+
* Proxies the ready state of the original WebSocket instance,
|
|
296
|
+
* if set. If the original connection hasn't been established,
|
|
297
|
+
* defaults to `-1`.
|
|
298
|
+
*/
|
|
299
|
+
get readyState() {
|
|
300
|
+
if (this.realWebSocket) {
|
|
301
|
+
return this.realWebSocket.readyState;
|
|
302
|
+
}
|
|
303
|
+
return -1;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Open connection to the original WebSocket server.
|
|
307
|
+
*/
|
|
308
|
+
connect() {
|
|
309
|
+
_outvariant.invariant.call(void 0,
|
|
310
|
+
!this.realWebSocket || this.realWebSocket.readyState !== WebSocket.OPEN,
|
|
311
|
+
'Failed to call "connect()" on the original WebSocket instance: the connection already open'
|
|
312
|
+
);
|
|
313
|
+
const realWebSocket = this.createConnection();
|
|
314
|
+
realWebSocket.binaryType = this.socket.binaryType;
|
|
315
|
+
realWebSocket.addEventListener("message", (event) => {
|
|
316
|
+
this.transport.onIncoming(event);
|
|
317
|
+
});
|
|
318
|
+
this.socket.addEventListener("close", this.handleMockClose.bind(this), {
|
|
319
|
+
signal: this.mockCloseController.signal
|
|
320
|
+
});
|
|
321
|
+
realWebSocket.addEventListener("close", this.handleRealClose.bind(this));
|
|
322
|
+
realWebSocket.addEventListener("error", () => {
|
|
323
|
+
this.socket.dispatchEvent(bindEvent(this.socket, new Event("error")));
|
|
324
|
+
});
|
|
325
|
+
this.realWebSocket = realWebSocket;
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Listen for the incoming events from the original WebSocket server.
|
|
329
|
+
*/
|
|
330
|
+
addEventListener(event, listener, options) {
|
|
331
|
+
this[kEmitter2].addEventListener(
|
|
332
|
+
event,
|
|
333
|
+
listener.bind(this.realWebSocket),
|
|
334
|
+
options
|
|
335
|
+
);
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Remove the listener for the given event.
|
|
339
|
+
*/
|
|
340
|
+
removeEventListener(event, listener, options) {
|
|
341
|
+
this[kEmitter2].removeEventListener(
|
|
342
|
+
event,
|
|
343
|
+
listener,
|
|
344
|
+
options
|
|
345
|
+
);
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Send data to the original WebSocket server.
|
|
349
|
+
* @example
|
|
350
|
+
* server.send('hello')
|
|
351
|
+
* server.send(new Blob(['hello']))
|
|
352
|
+
* server.send(new TextEncoder().encode('hello'))
|
|
353
|
+
*/
|
|
354
|
+
send(data) {
|
|
355
|
+
const { realWebSocket } = this;
|
|
356
|
+
_outvariant.invariant.call(void 0,
|
|
357
|
+
realWebSocket,
|
|
358
|
+
'Failed to call "server.send()" for "%s": the connection is not open. Did you forget to call "server.connect()"?',
|
|
359
|
+
this.socket.url
|
|
360
|
+
);
|
|
361
|
+
if (realWebSocket.readyState === WebSocket.CLOSING || realWebSocket.readyState === WebSocket.CLOSED) {
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
if (realWebSocket.readyState === WebSocket.CONNECTING) {
|
|
365
|
+
realWebSocket.addEventListener(
|
|
366
|
+
"open",
|
|
367
|
+
() => {
|
|
368
|
+
realWebSocket.send(data);
|
|
369
|
+
},
|
|
370
|
+
{ once: true }
|
|
371
|
+
);
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
realWebSocket.send(data);
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Close the actual server connection.
|
|
378
|
+
*/
|
|
379
|
+
close() {
|
|
380
|
+
const { realWebSocket } = this;
|
|
381
|
+
_outvariant.invariant.call(void 0,
|
|
382
|
+
realWebSocket,
|
|
383
|
+
'Failed to close server connection for "%s": the connection is not open. Did you forget to call "server.connect()"?',
|
|
384
|
+
this.socket.url
|
|
385
|
+
);
|
|
386
|
+
realWebSocket.removeEventListener("close", this.handleRealClose);
|
|
387
|
+
if (realWebSocket.readyState === WebSocket.CLOSING || realWebSocket.readyState === WebSocket.CLOSED) {
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
realWebSocket.close();
|
|
391
|
+
}
|
|
392
|
+
handleMockClose(_event) {
|
|
393
|
+
if (this.realWebSocket) {
|
|
394
|
+
this.realWebSocket.close();
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
handleRealClose(event) {
|
|
398
|
+
this.mockCloseController.abort();
|
|
399
|
+
const closeEvent = bindEvent(
|
|
400
|
+
this.realWebSocket,
|
|
401
|
+
new CloseEvent("close", event)
|
|
402
|
+
);
|
|
403
|
+
this[kEmitter2].dispatchEvent(closeEvent);
|
|
404
|
+
if (!closeEvent.defaultPrevented) {
|
|
405
|
+
this.socket[kClose](event.code, event.reason);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
kEmitter2;
|
|
410
|
+
|
|
411
|
+
// src/interceptors/WebSocket/WebSocketTransport.ts
|
|
412
|
+
var WebSocketTransport = class {
|
|
413
|
+
};
|
|
414
|
+
|
|
380
415
|
// src/interceptors/WebSocket/WebSocketClassTransport.ts
|
|
381
416
|
var WebSocketClassTransport = class extends WebSocketTransport {
|
|
382
417
|
constructor(socket) {
|