msw 2.2.3 → 2.3.0-ws.rc-1
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/cli/init.js +0 -0
- package/config/scripts/postinstall.js +0 -0
- package/lib/browser/index.d.mts +7 -6
- package/lib/browser/index.d.ts +7 -6
- package/lib/browser/index.js +32 -15
- package/lib/browser/index.js.map +1 -1
- package/lib/browser/index.mjs +32 -15
- package/lib/browser/index.mjs.map +1 -1
- package/lib/core/{GraphQLHandler-jOzqbxSK.d.ts → GraphQLHandler-Cbu12sb0.d.ts} +1 -1
- package/lib/core/{GraphQLHandler-AenIUdwE.d.mts → GraphQLHandler-QGQY_9Rc.d.mts} +1 -1
- package/lib/core/{HttpResponse-wcp03c7-.d.mts → HttpResponse-BWB1yDNM.d.mts} +2 -2
- package/lib/core/{HttpResponse-_514VQ9z.d.ts → HttpResponse-DeJBWGN5.d.ts} +2 -2
- package/lib/core/HttpResponse.d.mts +1 -1
- package/lib/core/HttpResponse.d.ts +1 -1
- package/lib/core/SetupApi.d.mts +15 -12
- package/lib/core/SetupApi.d.ts +15 -12
- package/lib/core/SetupApi.js +3 -1
- package/lib/core/SetupApi.js.map +1 -1
- package/lib/core/SetupApi.mjs +3 -1
- package/lib/core/SetupApi.mjs.map +1 -1
- package/lib/core/getResponse.d.mts +1 -1
- package/lib/core/getResponse.d.ts +1 -1
- package/lib/core/graphql.d.mts +2 -2
- package/lib/core/graphql.d.ts +2 -2
- package/lib/core/handlers/GraphQLHandler.d.mts +2 -2
- package/lib/core/handlers/GraphQLHandler.d.ts +2 -2
- package/lib/core/handlers/HttpHandler.d.mts +1 -1
- package/lib/core/handlers/HttpHandler.d.ts +1 -1
- package/lib/core/handlers/RequestHandler.d.mts +1 -1
- package/lib/core/handlers/RequestHandler.d.ts +1 -1
- package/lib/core/handlers/WebSocketHandler.d.mts +38 -0
- package/lib/core/handlers/WebSocketHandler.d.ts +38 -0
- package/lib/core/handlers/WebSocketHandler.js +65 -0
- package/lib/core/handlers/WebSocketHandler.js.map +1 -0
- package/lib/core/handlers/WebSocketHandler.mjs +47 -0
- package/lib/core/handlers/WebSocketHandler.mjs.map +1 -0
- package/lib/core/http.d.mts +1 -1
- package/lib/core/http.d.ts +1 -1
- package/lib/core/index.d.mts +5 -2
- package/lib/core/index.d.ts +5 -2
- package/lib/core/index.js +3 -1
- package/lib/core/index.js.map +1 -1
- package/lib/core/index.mjs +3 -1
- package/lib/core/index.mjs.map +1 -1
- package/lib/core/passthrough.d.mts +1 -1
- package/lib/core/passthrough.d.ts +1 -1
- package/lib/core/utils/HttpResponse/decorators.d.mts +1 -1
- package/lib/core/utils/HttpResponse/decorators.d.ts +1 -1
- package/lib/core/utils/executeHandlers.d.mts +1 -1
- package/lib/core/utils/executeHandlers.d.ts +1 -1
- package/lib/core/utils/executeHandlers.js +4 -0
- package/lib/core/utils/executeHandlers.js.map +1 -1
- package/lib/core/utils/executeHandlers.mjs +6 -0
- package/lib/core/utils/executeHandlers.mjs.map +1 -1
- package/lib/core/utils/handleRequest.d.mts +2 -2
- package/lib/core/utils/handleRequest.d.ts +2 -2
- package/lib/core/utils/handleRequest.js.map +1 -1
- package/lib/core/utils/handleRequest.mjs.map +1 -1
- package/lib/core/utils/handleWebSocketEvent.d.mts +10 -0
- package/lib/core/utils/handleWebSocketEvent.d.ts +10 -0
- package/lib/core/utils/handleWebSocketEvent.js +56 -0
- package/lib/core/utils/handleWebSocketEvent.js.map +1 -0
- package/lib/core/utils/handleWebSocketEvent.mjs +40 -0
- package/lib/core/utils/handleWebSocketEvent.mjs.map +1 -0
- package/lib/core/utils/internal/parseGraphQLRequest.d.mts +2 -2
- package/lib/core/utils/internal/parseGraphQLRequest.d.ts +2 -2
- package/lib/core/utils/internal/parseMultipartData.d.mts +1 -1
- package/lib/core/utils/internal/parseMultipartData.d.ts +1 -1
- package/lib/core/utils/internal/requestHandlerUtils.d.mts +1 -1
- package/lib/core/utils/internal/requestHandlerUtils.d.ts +1 -1
- package/lib/core/utils/matching/matchRequestUrl.d.mts +2 -1
- package/lib/core/utils/matching/matchRequestUrl.d.ts +2 -1
- package/lib/core/utils/matching/matchRequestUrl.js +4 -0
- package/lib/core/utils/matching/matchRequestUrl.js.map +1 -1
- package/lib/core/utils/matching/matchRequestUrl.mjs +4 -0
- package/lib/core/utils/matching/matchRequestUrl.mjs.map +1 -1
- package/lib/core/ws/WebSocketClientManager.d.mts +64 -0
- package/lib/core/ws/WebSocketClientManager.d.ts +64 -0
- package/lib/core/ws/WebSocketClientManager.js +123 -0
- package/lib/core/ws/WebSocketClientManager.js.map +1 -0
- package/lib/core/ws/WebSocketClientManager.mjs +103 -0
- package/lib/core/ws/WebSocketClientManager.mjs.map +1 -0
- package/lib/core/ws/webSocketInterceptor.d.mts +5 -0
- package/lib/core/ws/webSocketInterceptor.d.ts +5 -0
- package/lib/core/ws/webSocketInterceptor.js +26 -0
- package/lib/core/ws/webSocketInterceptor.js.map +1 -0
- package/lib/core/ws/webSocketInterceptor.mjs +6 -0
- package/lib/core/ws/webSocketInterceptor.mjs.map +1 -0
- package/lib/core/ws/ws.d.mts +44 -0
- package/lib/core/ws/ws.d.ts +44 -0
- package/lib/core/ws/ws.js +82 -0
- package/lib/core/ws/ws.js.map +1 -0
- package/lib/core/ws/ws.mjs +65 -0
- package/lib/core/ws/ws.mjs.map +1 -0
- package/lib/iife/index.js +703 -17
- package/lib/iife/index.js.map +1 -1
- package/lib/mockServiceWorker.js +1 -1
- package/lib/native/index.d.mts +6 -5
- package/lib/native/index.d.ts +6 -5
- package/lib/native/index.js +7 -0
- package/lib/native/index.js.map +1 -1
- package/lib/native/index.mjs +7 -0
- package/lib/native/index.mjs.map +1 -1
- package/lib/node/index.d.mts +8 -7
- package/lib/node/index.d.ts +8 -7
- package/lib/node/index.js +7 -0
- package/lib/node/index.js.map +1 -1
- package/lib/node/index.mjs +7 -0
- package/lib/node/index.mjs.map +1 -1
- package/package.json +27 -22
- package/src/browser/setupWorker/glossary.ts +10 -10
- package/src/browser/setupWorker/setupWorker.ts +17 -3
- package/src/core/SetupApi.ts +28 -20
- package/src/core/handlers/WebSocketHandler.ts +89 -0
- package/src/core/index.ts +3 -0
- package/src/core/utils/executeHandlers.ts +6 -2
- package/src/core/utils/handleRequest.ts +1 -2
- package/src/core/utils/handleWebSocketEvent.ts +49 -0
- package/src/core/utils/matching/matchRequestUrl.test.ts +44 -0
- package/src/core/utils/matching/matchRequestUrl.ts +4 -0
- package/src/core/ws/WebSocketClientManager.test.ts +159 -0
- package/src/core/ws/WebSocketClientManager.ts +170 -0
- package/src/core/ws/webSocketInterceptor.ts +3 -0
- package/src/core/ws/ws.test.ts +23 -0
- package/src/core/ws/ws.ts +108 -0
- package/src/node/SetupServerApi.ts +8 -7
- package/src/node/SetupServerCommonApi.ts +10 -1
- package/src/node/glossary.ts +5 -7
- package/src/node/setupServer.ts +2 -1
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
WebSocketData,
|
|
3
|
+
WebSocketClientConnection,
|
|
4
|
+
WebSocketClientConnectionProtocol,
|
|
5
|
+
} from '@mswjs/interceptors/WebSocket'
|
|
6
|
+
|
|
7
|
+
export type WebSocketBroadcastChannelMessage =
|
|
8
|
+
| {
|
|
9
|
+
type: 'connection:open'
|
|
10
|
+
payload: {
|
|
11
|
+
clientId: string
|
|
12
|
+
url: string
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
| {
|
|
16
|
+
type: 'extraneous:send'
|
|
17
|
+
payload: {
|
|
18
|
+
clientId: string
|
|
19
|
+
data: WebSocketData
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
| {
|
|
23
|
+
type: 'extraneous:close'
|
|
24
|
+
payload: {
|
|
25
|
+
clientId: string
|
|
26
|
+
code?: number
|
|
27
|
+
reason?: string
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const kAddByClientId = Symbol('kAddByClientId')
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* A manager responsible for accumulating WebSocket client
|
|
35
|
+
* connections across different browser runtimes.
|
|
36
|
+
*/
|
|
37
|
+
export class WebSocketClientManager {
|
|
38
|
+
/**
|
|
39
|
+
* All active WebSocket client connections.
|
|
40
|
+
*/
|
|
41
|
+
public clients: Set<WebSocketClientConnectionProtocol>
|
|
42
|
+
|
|
43
|
+
constructor(private channel: BroadcastChannel) {
|
|
44
|
+
this.clients = new Set()
|
|
45
|
+
|
|
46
|
+
this.channel.addEventListener('message', (message) => {
|
|
47
|
+
const { type, payload } = message.data as WebSocketBroadcastChannelMessage
|
|
48
|
+
|
|
49
|
+
switch (type) {
|
|
50
|
+
case 'connection:open': {
|
|
51
|
+
// When another runtime notifies about a new connection,
|
|
52
|
+
// create a connection wrapper class and add it to the set.
|
|
53
|
+
this.onRemoteConnection(payload.clientId, new URL(payload.url))
|
|
54
|
+
break
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Adds the given `WebSocket` client connection to the set
|
|
62
|
+
* of all connections. The given connection is always the complete
|
|
63
|
+
* connection object because `addConnection()` is called only
|
|
64
|
+
* for the opened connections in the same runtime.
|
|
65
|
+
*/
|
|
66
|
+
public addConnection(client: WebSocketClientConnection): void {
|
|
67
|
+
this.clients.add(client)
|
|
68
|
+
|
|
69
|
+
// Signal to other runtimes about this connection.
|
|
70
|
+
this.channel.postMessage({
|
|
71
|
+
type: 'connection:open',
|
|
72
|
+
payload: {
|
|
73
|
+
clientId: client.id,
|
|
74
|
+
url: client.url.toString(),
|
|
75
|
+
},
|
|
76
|
+
} as WebSocketBroadcastChannelMessage)
|
|
77
|
+
|
|
78
|
+
// Instruct the current client how to handle events
|
|
79
|
+
// coming from other runtimes (e.g. when calling `.broadcast()`).
|
|
80
|
+
const handleExtraneousMessage = (
|
|
81
|
+
message: MessageEvent<WebSocketBroadcastChannelMessage>,
|
|
82
|
+
) => {
|
|
83
|
+
const { type, payload } = message.data
|
|
84
|
+
|
|
85
|
+
// Ignore broadcasted messages for other clients.
|
|
86
|
+
if (
|
|
87
|
+
typeof payload === 'object' &&
|
|
88
|
+
'clientId' in payload &&
|
|
89
|
+
payload.clientId !== client.id
|
|
90
|
+
) {
|
|
91
|
+
return
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
switch (type) {
|
|
95
|
+
case 'extraneous:send': {
|
|
96
|
+
client.send(payload.data)
|
|
97
|
+
break
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
case 'extraneous:close': {
|
|
101
|
+
client.close(payload.code, payload.reason)
|
|
102
|
+
break
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const abortController = new AbortController()
|
|
108
|
+
|
|
109
|
+
this.channel.addEventListener('message', handleExtraneousMessage, {
|
|
110
|
+
signal: abortController.signal,
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
// Once closed, this connection cannot be operated on.
|
|
114
|
+
// This must include the extraneous runtimes as well.
|
|
115
|
+
client.addEventListener('close', () => abortController.abort(), {
|
|
116
|
+
once: true,
|
|
117
|
+
})
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Adds a client connection wrapper to operate with
|
|
122
|
+
* WebSocket client connections in other runtimes.
|
|
123
|
+
*/
|
|
124
|
+
private onRemoteConnection(id: string, url: URL): void {
|
|
125
|
+
this.clients.add(
|
|
126
|
+
// Create a connection-compatible instance that can
|
|
127
|
+
// operate with this client from a different runtime
|
|
128
|
+
// using the BroadcastChannel messages.
|
|
129
|
+
new WebSocketRemoteClientConnection(id, url, this.channel),
|
|
130
|
+
)
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* A wrapper class to operate with WebSocket client connections
|
|
136
|
+
* from other runtimes. This class maintains 1-1 public API
|
|
137
|
+
* compatibility to the `WebSocketClientConnection` but relies
|
|
138
|
+
* on the given `BroadcastChannel` to communicate instructions
|
|
139
|
+
* with the client connections from other runtimes.
|
|
140
|
+
*/
|
|
141
|
+
export class WebSocketRemoteClientConnection
|
|
142
|
+
implements WebSocketClientConnectionProtocol
|
|
143
|
+
{
|
|
144
|
+
constructor(
|
|
145
|
+
public readonly id: string,
|
|
146
|
+
public readonly url: URL,
|
|
147
|
+
private channel: BroadcastChannel,
|
|
148
|
+
) {}
|
|
149
|
+
|
|
150
|
+
send(data: WebSocketData): void {
|
|
151
|
+
this.channel.postMessage({
|
|
152
|
+
type: 'extraneous:send',
|
|
153
|
+
payload: {
|
|
154
|
+
clientId: this.id,
|
|
155
|
+
data,
|
|
156
|
+
},
|
|
157
|
+
} as WebSocketBroadcastChannelMessage)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
close(code?: number | undefined, reason?: string | undefined): void {
|
|
161
|
+
this.channel.postMessage({
|
|
162
|
+
type: 'extraneous:close',
|
|
163
|
+
payload: {
|
|
164
|
+
clientId: this.id,
|
|
165
|
+
code,
|
|
166
|
+
reason,
|
|
167
|
+
},
|
|
168
|
+
} as WebSocketBroadcastChannelMessage)
|
|
169
|
+
}
|
|
170
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @vitest-environment node-websocket
|
|
3
|
+
*/
|
|
4
|
+
import { ws } from './ws'
|
|
5
|
+
|
|
6
|
+
it('exports the "link()" method', () => {
|
|
7
|
+
expect(ws).toHaveProperty('link')
|
|
8
|
+
expect(ws.link).toBeInstanceOf(Function)
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
it('throws an error when calling "ws.link()" without a URL argument', () => {
|
|
12
|
+
expect(() =>
|
|
13
|
+
// @ts-expect-error Intentionally invalid call.
|
|
14
|
+
ws.link(),
|
|
15
|
+
).toThrow('Expected a WebSocket server URL but got undefined')
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
it('throws an error when given a non-path argument to "ws.link()"', () => {
|
|
19
|
+
expect(() =>
|
|
20
|
+
// @ts-expect-error Intentionally invalid argument.
|
|
21
|
+
ws.link(2),
|
|
22
|
+
).toThrow('Expected a WebSocket server URL but got number')
|
|
23
|
+
})
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { invariant } from 'outvariant'
|
|
2
|
+
import type {
|
|
3
|
+
WebSocketClientConnectionProtocol,
|
|
4
|
+
WebSocketData,
|
|
5
|
+
} from '@mswjs/interceptors/WebSocket'
|
|
6
|
+
import {
|
|
7
|
+
WebSocketHandler,
|
|
8
|
+
kEmitter,
|
|
9
|
+
type WebSocketHandlerEventMap,
|
|
10
|
+
} from '../handlers/WebSocketHandler'
|
|
11
|
+
import { Path, isPath } from '../utils/matching/matchRequestUrl'
|
|
12
|
+
import { WebSocketClientManager } from './WebSocketClientManager'
|
|
13
|
+
|
|
14
|
+
const wsBroadcastChannel = new BroadcastChannel('msw:ws-client-manager')
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Intercepts outgoing WebSocket connections to the given URL.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* const chat = ws.link('wss://chat.example.com')
|
|
21
|
+
* chat.on('connection', ({ client }) => {
|
|
22
|
+
* client.send('hello from server!')
|
|
23
|
+
* })
|
|
24
|
+
*/
|
|
25
|
+
function createWebSocketLinkHandler(url: Path) {
|
|
26
|
+
invariant(url, 'Expected a WebSocket server URL but got undefined')
|
|
27
|
+
|
|
28
|
+
invariant(
|
|
29
|
+
isPath(url),
|
|
30
|
+
'Expected a WebSocket server URL but got %s',
|
|
31
|
+
typeof url,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
const clientManager = new WebSocketClientManager(wsBroadcastChannel)
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
clients: clientManager.clients,
|
|
38
|
+
on<K extends keyof WebSocketHandlerEventMap>(
|
|
39
|
+
event: K,
|
|
40
|
+
listener: (...args: WebSocketHandlerEventMap[K]) => void,
|
|
41
|
+
): WebSocketHandler {
|
|
42
|
+
const handler = new WebSocketHandler(url)
|
|
43
|
+
|
|
44
|
+
// Add the connection event listener for when the
|
|
45
|
+
// handler matches and emits a connection event.
|
|
46
|
+
// When that happens, store that connection in the
|
|
47
|
+
// set of all connections for reference.
|
|
48
|
+
handler[kEmitter].on('connection', ({ client }) => {
|
|
49
|
+
clientManager.addConnection(client)
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
// The "handleWebSocketEvent" function will invoke
|
|
53
|
+
// the "run()" method on the WebSocketHandler.
|
|
54
|
+
// If the handler matches, it will emit the "connection"
|
|
55
|
+
// event. Attach the user-defined listener to that event.
|
|
56
|
+
handler[kEmitter].on(event, listener)
|
|
57
|
+
|
|
58
|
+
return handler
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Broadcasts the given data to all WebSocket clients.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* const service = ws.link('wss://example.com')
|
|
66
|
+
* service.on('connection', () => {
|
|
67
|
+
* service.broadcast('hello, everyone!')
|
|
68
|
+
* })
|
|
69
|
+
*/
|
|
70
|
+
broadcast(data: WebSocketData): void {
|
|
71
|
+
// This will invoke "send()" on the immediate clients
|
|
72
|
+
// in this runtime and post a message to the broadcast channel
|
|
73
|
+
// to trigger send for the clients in other runtimes.
|
|
74
|
+
this.broadcastExcept([], data)
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Broadcasts the given data to all WebSocket clients
|
|
79
|
+
* except the ones provided in the `clients` argument.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* const service = ws.link('wss://example.com')
|
|
83
|
+
* service.on('connection', ({ client }) => {
|
|
84
|
+
* service.broadcastExcept(client, 'hi, the rest of you!')
|
|
85
|
+
* })
|
|
86
|
+
*/
|
|
87
|
+
broadcastExcept(
|
|
88
|
+
clients:
|
|
89
|
+
| WebSocketClientConnectionProtocol
|
|
90
|
+
| Array<WebSocketClientConnectionProtocol>,
|
|
91
|
+
data: WebSocketData,
|
|
92
|
+
): void {
|
|
93
|
+
const ignoreClients = Array.prototype
|
|
94
|
+
.concat(clients)
|
|
95
|
+
.map((client) => client.id)
|
|
96
|
+
|
|
97
|
+
clientManager.clients.forEach((otherClient) => {
|
|
98
|
+
if (!ignoreClients.includes(otherClient.id)) {
|
|
99
|
+
otherClient.send(data)
|
|
100
|
+
}
|
|
101
|
+
})
|
|
102
|
+
},
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export const ws = {
|
|
107
|
+
link: createWebSocketLinkHandler,
|
|
108
|
+
}
|
|
@@ -4,14 +4,15 @@ import { XMLHttpRequestInterceptor } from '@mswjs/interceptors/XMLHttpRequest'
|
|
|
4
4
|
import { FetchInterceptor } from '@mswjs/interceptors/fetch'
|
|
5
5
|
import { HandlersController } from '~/core/SetupApi'
|
|
6
6
|
import type { RequestHandler } from '~/core/handlers/RequestHandler'
|
|
7
|
+
import type { WebSocketHandler } from '~/core/handlers/WebSocketHandler'
|
|
7
8
|
import type { SetupServer } from './glossary'
|
|
8
9
|
import { SetupServerCommonApi } from './SetupServerCommonApi'
|
|
9
10
|
|
|
10
11
|
const store = new AsyncLocalStorage<RequestHandlersContext>()
|
|
11
12
|
|
|
12
13
|
type RequestHandlersContext = {
|
|
13
|
-
initialHandlers: Array<RequestHandler>
|
|
14
|
-
handlers: Array<RequestHandler>
|
|
14
|
+
initialHandlers: Array<RequestHandler | WebSocketHandler>
|
|
15
|
+
handlers: Array<RequestHandler | WebSocketHandler>
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
/**
|
|
@@ -22,7 +23,7 @@ type RequestHandlersContext = {
|
|
|
22
23
|
class AsyncHandlersController implements HandlersController {
|
|
23
24
|
private rootContext: RequestHandlersContext
|
|
24
25
|
|
|
25
|
-
constructor(initialHandlers: Array<RequestHandler>) {
|
|
26
|
+
constructor(initialHandlers: Array<RequestHandler | WebSocketHandler>) {
|
|
26
27
|
this.rootContext = { initialHandlers, handlers: [] }
|
|
27
28
|
}
|
|
28
29
|
|
|
@@ -30,18 +31,18 @@ class AsyncHandlersController implements HandlersController {
|
|
|
30
31
|
return store.getStore() || this.rootContext
|
|
31
32
|
}
|
|
32
33
|
|
|
33
|
-
public prepend(runtimeHandlers: Array<RequestHandler>) {
|
|
34
|
+
public prepend(runtimeHandlers: Array<RequestHandler | WebSocketHandler>) {
|
|
34
35
|
this.context.handlers.unshift(...runtimeHandlers)
|
|
35
36
|
}
|
|
36
37
|
|
|
37
|
-
public reset(nextHandlers: Array<RequestHandler>) {
|
|
38
|
+
public reset(nextHandlers: Array<RequestHandler | WebSocketHandler>) {
|
|
38
39
|
const context = this.context
|
|
39
40
|
context.handlers = []
|
|
40
41
|
context.initialHandlers =
|
|
41
42
|
nextHandlers.length > 0 ? nextHandlers : context.initialHandlers
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
public currentHandlers(): Array<RequestHandler> {
|
|
45
|
+
public currentHandlers(): Array<RequestHandler | WebSocketHandler> {
|
|
45
46
|
const { initialHandlers, handlers } = this.context
|
|
46
47
|
return handlers.concat(initialHandlers)
|
|
47
48
|
}
|
|
@@ -51,7 +52,7 @@ export class SetupServerApi
|
|
|
51
52
|
extends SetupServerCommonApi
|
|
52
53
|
implements SetupServer
|
|
53
54
|
{
|
|
54
|
-
constructor(handlers: Array<RequestHandler>) {
|
|
55
|
+
constructor(handlers: Array<RequestHandler | WebSocketHandler>) {
|
|
55
56
|
super(
|
|
56
57
|
[ClientRequestInterceptor, XMLHttpRequestInterceptor, FetchInterceptor],
|
|
57
58
|
handlers,
|
|
@@ -14,9 +14,12 @@ import type { LifeCycleEventsMap, SharedOptions } from '~/core/sharedOptions'
|
|
|
14
14
|
import { SetupApi } from '~/core/SetupApi'
|
|
15
15
|
import { handleRequest } from '~/core/utils/handleRequest'
|
|
16
16
|
import type { RequestHandler } from '~/core/handlers/RequestHandler'
|
|
17
|
+
import type { WebSocketHandler } from '~/core/handlers/WebSocketHandler'
|
|
17
18
|
import { mergeRight } from '~/core/utils/internal/mergeRight'
|
|
18
19
|
import { devUtils } from '~/core/utils/internal/devUtils'
|
|
19
20
|
import type { SetupServerCommon } from './glossary'
|
|
21
|
+
import { handleWebSocketEvent } from '~/core/utils/handleWebSocketEvent'
|
|
22
|
+
import { webSocketInterceptor } from '~/core/ws/webSocketInterceptor'
|
|
20
23
|
|
|
21
24
|
export const DEFAULT_LISTEN_OPTIONS: RequiredDeep<SharedOptions> = {
|
|
22
25
|
onUnhandledRequest: 'warn',
|
|
@@ -34,7 +37,7 @@ export class SetupServerCommonApi
|
|
|
34
37
|
|
|
35
38
|
constructor(
|
|
36
39
|
interceptors: Array<{ new (): Interceptor<HttpRequestEventMap> }>,
|
|
37
|
-
handlers: Array<RequestHandler>,
|
|
40
|
+
handlers: Array<RequestHandler | WebSocketHandler>,
|
|
38
41
|
) {
|
|
39
42
|
super(...handlers)
|
|
40
43
|
|
|
@@ -81,6 +84,10 @@ export class SetupServerCommonApi
|
|
|
81
84
|
)
|
|
82
85
|
},
|
|
83
86
|
)
|
|
87
|
+
|
|
88
|
+
handleWebSocketEvent(() => {
|
|
89
|
+
return this.handlersController.currentHandlers()
|
|
90
|
+
})
|
|
84
91
|
}
|
|
85
92
|
|
|
86
93
|
public listen(options: Partial<SharedOptions> = {}): void {
|
|
@@ -91,9 +98,11 @@ export class SetupServerCommonApi
|
|
|
91
98
|
|
|
92
99
|
// Apply the interceptor when starting the server.
|
|
93
100
|
this.interceptor.apply()
|
|
101
|
+
webSocketInterceptor.apply()
|
|
94
102
|
|
|
95
103
|
this.subscriptions.push(() => {
|
|
96
104
|
this.interceptor.dispose()
|
|
105
|
+
webSocketInterceptor.dispose()
|
|
97
106
|
})
|
|
98
107
|
|
|
99
108
|
// Assert that the interceptor has been applied successfully.
|
package/src/node/glossary.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import type { PartialDeep } from 'type-fest'
|
|
2
|
-
import type {
|
|
3
|
-
|
|
4
|
-
RequestHandlerDefaultInfo,
|
|
5
|
-
} from '~/core/handlers/RequestHandler'
|
|
2
|
+
import type { RequestHandler } from '~/core/handlers/RequestHandler'
|
|
3
|
+
import type { WebSocketHandler } from '~/core/handlers/WebSocketHandler'
|
|
6
4
|
import type {
|
|
7
5
|
LifeCycleEventEmitter,
|
|
8
6
|
LifeCycleEventsMap,
|
|
@@ -29,7 +27,7 @@ export interface SetupServerCommon {
|
|
|
29
27
|
*
|
|
30
28
|
* @see {@link https://mswjs.io/docs/api/setup-server/use `server.use()` API reference}
|
|
31
29
|
*/
|
|
32
|
-
use(...handlers: Array<RequestHandler>): void
|
|
30
|
+
use(...handlers: Array<RequestHandler | WebSocketHandler>): void
|
|
33
31
|
|
|
34
32
|
/**
|
|
35
33
|
* Marks all request handlers that respond using `res.once()` as unused.
|
|
@@ -43,14 +41,14 @@ export interface SetupServerCommon {
|
|
|
43
41
|
*
|
|
44
42
|
* @see {@link https://mswjs.io/docs/api/setup-server/reset-handlers `server.reset-handlers()` API reference}
|
|
45
43
|
*/
|
|
46
|
-
resetHandlers(...nextHandlers: Array<RequestHandler>): void
|
|
44
|
+
resetHandlers(...nextHandlers: Array<RequestHandler | WebSocketHandler>): void
|
|
47
45
|
|
|
48
46
|
/**
|
|
49
47
|
* Returns a readonly list of currently active request handlers.
|
|
50
48
|
*
|
|
51
49
|
* @see {@link https://mswjs.io/docs/api/setup-server/list-handlers `server.listHandlers()` API reference}
|
|
52
50
|
*/
|
|
53
|
-
listHandlers(): ReadonlyArray<RequestHandler
|
|
51
|
+
listHandlers(): ReadonlyArray<RequestHandler | WebSocketHandler>
|
|
54
52
|
|
|
55
53
|
/**
|
|
56
54
|
* Life-cycle events.
|
package/src/node/setupServer.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { RequestHandler } from '~/core/handlers/RequestHandler'
|
|
2
|
+
import type { WebSocketHandler } from '~/core/handlers/WebSocketHandler'
|
|
2
3
|
import { SetupServerApi } from './SetupServerApi'
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -8,7 +9,7 @@ import { SetupServerApi } from './SetupServerApi'
|
|
|
8
9
|
* @see {@link https://mswjs.io/docs/api/setup-server `setupServer()` API reference}
|
|
9
10
|
*/
|
|
10
11
|
export const setupServer = (
|
|
11
|
-
...handlers: Array<RequestHandler>
|
|
12
|
+
...handlers: Array<RequestHandler | WebSocketHandler>
|
|
12
13
|
): SetupServerApi => {
|
|
13
14
|
return new SetupServerApi(handlers)
|
|
14
15
|
}
|