msw 2.3.0-ws.rc-8 → 2.3.0-ws.rc-10

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.
Files changed (65) hide show
  1. package/lib/browser/index.js +15 -8
  2. package/lib/browser/index.js.map +1 -1
  3. package/lib/browser/index.mjs +15 -8
  4. package/lib/browser/index.mjs.map +1 -1
  5. package/lib/core/index.d.mts +2 -2
  6. package/lib/core/index.d.ts +2 -2
  7. package/lib/core/index.js.map +1 -1
  8. package/lib/core/index.mjs.map +1 -1
  9. package/lib/core/utils/handleRequest.d.mts +2 -2
  10. package/lib/core/utils/handleRequest.d.ts +2 -2
  11. package/lib/core/utils/handleRequest.js.map +1 -1
  12. package/lib/core/utils/handleRequest.mjs.map +1 -1
  13. package/lib/core/ws/WebSocketClientManager.d.mts +1 -3
  14. package/lib/core/ws/WebSocketClientManager.d.ts +1 -3
  15. package/lib/core/ws/WebSocketClientManager.js +1 -2
  16. package/lib/core/ws/WebSocketClientManager.js.map +1 -1
  17. package/lib/core/ws/WebSocketClientManager.mjs +1 -2
  18. package/lib/core/ws/WebSocketClientManager.mjs.map +1 -1
  19. package/lib/core/ws/WebSocketClientStore.d.mts +2 -2
  20. package/lib/core/ws/WebSocketClientStore.d.ts +2 -2
  21. package/lib/core/ws/WebSocketClientStore.js.map +1 -1
  22. package/lib/core/ws/WebSocketClientStore.mjs.map +1 -1
  23. package/lib/core/ws/WebSocketIndexedDBClientStore.js +27 -6
  24. package/lib/core/ws/WebSocketIndexedDBClientStore.js.map +1 -1
  25. package/lib/core/ws/WebSocketIndexedDBClientStore.mjs +27 -6
  26. package/lib/core/ws/WebSocketIndexedDBClientStore.mjs.map +1 -1
  27. package/lib/core/ws/handleWebSocketEvent.d.mts +2 -0
  28. package/lib/core/ws/handleWebSocketEvent.d.ts +2 -0
  29. package/lib/core/ws/handleWebSocketEvent.js +30 -13
  30. package/lib/core/ws/handleWebSocketEvent.js.map +1 -1
  31. package/lib/core/ws/handleWebSocketEvent.mjs +32 -13
  32. package/lib/core/ws/handleWebSocketEvent.mjs.map +1 -1
  33. package/lib/core/ws/utils/attachWebSocketLogger.js +2 -2
  34. package/lib/core/ws/utils/attachWebSocketLogger.js.map +1 -1
  35. package/lib/core/ws/utils/attachWebSocketLogger.mjs +2 -2
  36. package/lib/core/ws/utils/attachWebSocketLogger.mjs.map +1 -1
  37. package/lib/core/ws.d.mts +8 -6
  38. package/lib/core/ws.d.ts +8 -6
  39. package/lib/core/ws.js +2 -2
  40. package/lib/core/ws.js.map +1 -1
  41. package/lib/core/ws.mjs +2 -2
  42. package/lib/core/ws.mjs.map +1 -1
  43. package/lib/iife/index.js +128 -58
  44. package/lib/iife/index.js.map +1 -1
  45. package/lib/mockServiceWorker.js +1 -1
  46. package/lib/native/index.js +10 -5
  47. package/lib/native/index.js.map +1 -1
  48. package/lib/native/index.mjs +10 -5
  49. package/lib/native/index.mjs.map +1 -1
  50. package/lib/node/index.js +10 -5
  51. package/lib/node/index.js.map +1 -1
  52. package/lib/node/index.mjs +10 -5
  53. package/lib/node/index.mjs.map +1 -1
  54. package/package.json +2 -2
  55. package/src/browser/setupWorker/setupWorker.ts +5 -7
  56. package/src/browser/setupWorker/start/createRequestListener.ts +7 -1
  57. package/src/core/index.ts +2 -0
  58. package/src/core/utils/handleRequest.ts +2 -1
  59. package/src/core/ws/WebSocketClientManager.ts +1 -5
  60. package/src/core/ws/WebSocketClientStore.ts +1 -1
  61. package/src/core/ws/WebSocketIndexedDBClientStore.ts +39 -6
  62. package/src/core/ws/handleWebSocketEvent.ts +40 -14
  63. package/src/core/ws/utils/attachWebSocketLogger.ts +2 -2
  64. package/src/core/ws.ts +15 -9
  65. package/src/node/SetupServerCommonApi.ts +17 -6
@@ -2,15 +2,20 @@ import type { WebSocketConnectionData } from '@mswjs/interceptors/lib/browser/in
2
2
  import { RequestHandler } from '../handlers/RequestHandler'
3
3
  import { WebSocketHandler, kDispatchEvent } from '../handlers/WebSocketHandler'
4
4
  import { webSocketInterceptor } from './webSocketInterceptor'
5
+ import {
6
+ onUnhandledRequest,
7
+ UnhandledRequestStrategy,
8
+ } from '../utils/request/onUnhandledRequest'
5
9
 
6
10
  interface HandleWebSocketEventOptions {
11
+ getUnhandledRequestStrategy: () => UnhandledRequestStrategy
7
12
  getHandlers: () => Array<RequestHandler | WebSocketHandler>
8
13
  onMockedConnection: (connection: WebSocketConnectionData) => void
9
14
  onPassthroughConnection: (onnection: WebSocketConnectionData) => void
10
15
  }
11
16
 
12
17
  export function handleWebSocketEvent(options: HandleWebSocketEventOptions) {
13
- webSocketInterceptor.on('connection', (connection) => {
18
+ webSocketInterceptor.on('connection', async (connection) => {
14
19
  const handlers = options.getHandlers()
15
20
 
16
21
  const connectionEvent = new MessageEvent('connection', {
@@ -21,20 +26,21 @@ export function handleWebSocketEvent(options: HandleWebSocketEventOptions) {
21
26
  // match the "ws.link()" endpoint predicate. Don't dispatch
22
27
  // anything yet so the logger can be attached to the connection
23
28
  // before it potentially sends events.
24
- const matchingHandlers = handlers.filter<WebSocketHandler>(
25
- (handler): handler is WebSocketHandler => {
26
- if (handler instanceof WebSocketHandler) {
27
- return handler.predicate({
28
- event: connectionEvent,
29
- parsedResult: handler.parse({
30
- event: connectionEvent,
31
- }),
32
- })
33
- }
29
+ const matchingHandlers: Array<WebSocketHandler> = []
34
30
 
35
- return false
36
- },
37
- )
31
+ for (const handler of handlers) {
32
+ if (
33
+ handler instanceof WebSocketHandler &&
34
+ handler.predicate({
35
+ event: connectionEvent,
36
+ parsedResult: handler.parse({
37
+ event: connectionEvent,
38
+ }),
39
+ })
40
+ ) {
41
+ matchingHandlers.push(handler)
42
+ }
43
+ }
38
44
 
39
45
  if (matchingHandlers.length > 0) {
40
46
  options?.onMockedConnection(connection)
@@ -46,6 +52,26 @@ export function handleWebSocketEvent(options: HandleWebSocketEventOptions) {
46
52
  handler[kDispatchEvent](connectionEvent)
47
53
  }
48
54
  } else {
55
+ // Construct a request representing this WebSocket connection.
56
+ const request = new Request(connection.client.url, {
57
+ headers: {
58
+ upgrade: 'websocket',
59
+ connection: 'upgrade',
60
+ },
61
+ })
62
+ await onUnhandledRequest(
63
+ request,
64
+ options.getUnhandledRequestStrategy(),
65
+ ).catch((error) => {
66
+ const errorEvent = new Event('error')
67
+ Object.defineProperty(errorEvent, 'cause', {
68
+ enumerable: true,
69
+ configurable: false,
70
+ value: error,
71
+ })
72
+ connection.client.socket.dispatchEvent(errorEvent)
73
+ })
74
+
49
75
  options?.onPassthroughConnection(connection)
50
76
 
51
77
  // If none of the "ws" handlers matched,
@@ -92,12 +92,12 @@ export function attachWebSocketLogger(
92
92
  currentTarget: {
93
93
  enumerable: true,
94
94
  writable: false,
95
- value: server['realWebSocket'],
95
+ value: server.socket,
96
96
  },
97
97
  target: {
98
98
  enumerable: true,
99
99
  writable: false,
100
- value: server['realWebSocket'],
100
+ value: server.socket,
101
101
  },
102
102
  })
103
103
 
package/src/core/ws.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { invariant } from 'outvariant'
2
2
  import type {
3
- WebSocketClientConnectionProtocol,
4
3
  WebSocketData,
4
+ WebSocketClientConnectionProtocol,
5
5
  } from '@mswjs/interceptors/WebSocket'
6
6
  import {
7
7
  WebSocketHandler,
@@ -25,6 +25,10 @@ if (isBroadcastChannelWithUnref(webSocketChannel)) {
25
25
  webSocketChannel.unref()
26
26
  }
27
27
 
28
+ export type WebSocketEventListener<
29
+ EventType extends keyof WebSocketHandlerEventMap,
30
+ > = (...args: WebSocketHandlerEventMap[EventType]) => void
31
+
28
32
  export type WebSocketLink = {
29
33
  /**
30
34
  * A set of all WebSocket clients connected
@@ -39,13 +43,13 @@ export type WebSocketLink = {
39
43
  *
40
44
  * @example
41
45
  * const chat = ws.link('wss://chat.example.com')
42
- * chat.on('connection', listener)
46
+ * chat.addEventListener('connection', listener)
43
47
  *
44
48
  * @see {@link https://mswjs.io/docs/api/ws#onevent-listener `on()` API reference}
45
49
  */
46
- on<EventType extends keyof WebSocketHandlerEventMap>(
50
+ addEventListener<EventType extends keyof WebSocketHandlerEventMap>(
47
51
  event: EventType,
48
- listener: (...args: WebSocketHandlerEventMap[EventType]) => void,
52
+ listener: WebSocketEventListener<EventType>,
49
53
  ): WebSocketHandler
50
54
 
51
55
  /**
@@ -53,7 +57,7 @@ export type WebSocketLink = {
53
57
  *
54
58
  * @example
55
59
  * const service = ws.link('wss://example.com')
56
- * service.on('connection', () => {
60
+ * service.addEventListener('connection', () => {
57
61
  * service.broadcast('hello, everyone!')
58
62
  * })
59
63
  *
@@ -67,7 +71,7 @@ export type WebSocketLink = {
67
71
  *
68
72
  * @example
69
73
  * const service = ws.link('wss://example.com')
70
- * service.on('connection', ({ client }) => {
74
+ * service.addEventListener('connection', ({ client }) => {
71
75
  * service.broadcastExcept(client, 'hi, the rest of you!')
72
76
  * })
73
77
  *
@@ -86,7 +90,7 @@ export type WebSocketLink = {
86
90
  *
87
91
  * @example
88
92
  * const chat = ws.link('wss://chat.example.com')
89
- * chat.on('connection', ({ client }) => {
93
+ * chat.addEventListener('connection', ({ client }) => {
90
94
  * client.send('hello from server!')
91
95
  * })
92
96
  */
@@ -99,13 +103,13 @@ function createWebSocketLinkHandler(url: Path): WebSocketLink {
99
103
  typeof url,
100
104
  )
101
105
 
102
- const clientManager = new WebSocketClientManager(webSocketChannel, url)
106
+ const clientManager = new WebSocketClientManager(webSocketChannel)
103
107
 
104
108
  return {
105
109
  get clients() {
106
110
  return clientManager.clients
107
111
  },
108
- on(event, listener) {
112
+ addEventListener(event, listener) {
109
113
  const handler = new WebSocketHandler(url)
110
114
 
111
115
  // Add the connection event listener for when the
@@ -158,3 +162,5 @@ function createWebSocketLinkHandler(url: Path): WebSocketLink {
158
162
  export const ws = {
159
163
  link: createWebSocketLinkHandler,
160
164
  }
165
+
166
+ export { WebSocketData }
@@ -14,6 +14,8 @@ 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 { HttpHandler } from '~/core/handlers/HttpHandler'
18
+ import { GraphQLHandler } from '~/core/handlers/GraphQLHandler'
17
19
  import type { WebSocketHandler } from '~/core/handlers/WebSocketHandler'
18
20
  import { mergeRight } from '~/core/utils/internal/mergeRight'
19
21
  import { InternalError, devUtils } from '~/core/utils/internal/devUtils'
@@ -61,7 +63,12 @@ export class SetupServerCommonApi
61
63
  const response = await handleRequest(
62
64
  request,
63
65
  requestId,
64
- this.handlersController.currentHandlers(),
66
+ this.handlersController.currentHandlers().filter((handler) => {
67
+ return (
68
+ handler instanceof HttpHandler ||
69
+ handler instanceof GraphQLHandler
70
+ )
71
+ }),
65
72
  this.resolvedOptions,
66
73
  this.emitter,
67
74
  )
@@ -94,7 +101,12 @@ export class SetupServerCommonApi
94
101
  },
95
102
  )
96
103
 
104
+ // Preconfigure the WebSocket interception but don't enable it just yet.
105
+ // It will be enabled when the server starts.
97
106
  handleWebSocketEvent({
107
+ getUnhandledRequestStrategy: () => {
108
+ return this.resolvedOptions.onUnhandledRequest
109
+ },
98
110
  getHandlers: () => {
99
111
  return this.handlersController.currentHandlers()
100
112
  },
@@ -111,12 +123,11 @@ export class SetupServerCommonApi
111
123
 
112
124
  // Apply the interceptor when starting the server.
113
125
  this.interceptor.apply()
114
- webSocketInterceptor.apply()
126
+ this.subscriptions.push(() => this.interceptor.dispose())
115
127
 
116
- this.subscriptions.push(() => {
117
- this.interceptor.dispose()
118
- webSocketInterceptor.dispose()
119
- })
128
+ // Apply the WebSocket interception.
129
+ webSocketInterceptor.apply()
130
+ this.subscriptions.push(() => webSocketInterceptor.dispose())
120
131
 
121
132
  // Assert that the interceptor has been applied successfully.
122
133
  // Also guards us from forgetting to call "interceptor.apply()"