msw 2.13.2 → 2.13.4

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 (217) hide show
  1. package/cli/init.js +1 -1
  2. package/lib/browser/index.js +252 -72
  3. package/lib/browser/index.js.map +1 -1
  4. package/lib/browser/index.mjs +252 -72
  5. package/lib/browser/index.mjs.map +1 -1
  6. package/lib/core/{HttpResponse-DlRR1D-f.d.mts → HttpResponse-BF4NGRsf.d.mts} +1 -1
  7. package/lib/core/{HttpResponse-CksOMVAa.d.ts → HttpResponse-yukpQS4a.d.ts} +1 -1
  8. package/lib/core/HttpResponse.d.mts +1 -1
  9. package/lib/core/HttpResponse.d.ts +1 -1
  10. package/lib/core/experimental/compat.d.mts +2 -2
  11. package/lib/core/experimental/compat.d.ts +2 -2
  12. package/lib/core/experimental/compat.js +1 -0
  13. package/lib/core/experimental/compat.js.map +1 -1
  14. package/lib/core/experimental/compat.mjs +1 -0
  15. package/lib/core/experimental/compat.mjs.map +1 -1
  16. package/lib/core/experimental/define-network.d.mts +2 -2
  17. package/lib/core/experimental/define-network.d.ts +2 -2
  18. package/lib/core/experimental/define-network.js +4 -0
  19. package/lib/core/experimental/define-network.js.map +1 -1
  20. package/lib/core/experimental/define-network.mjs +6 -0
  21. package/lib/core/experimental/define-network.mjs.map +1 -1
  22. package/lib/core/experimental/frames/http-frame.d.mts +2 -2
  23. package/lib/core/experimental/frames/http-frame.d.ts +2 -2
  24. package/lib/core/experimental/frames/http-frame.js +2 -0
  25. package/lib/core/experimental/frames/http-frame.js.map +1 -1
  26. package/lib/core/experimental/frames/http-frame.mjs +5 -1
  27. package/lib/core/experimental/frames/http-frame.mjs.map +1 -1
  28. package/lib/core/experimental/frames/network-frame.d.mts +2 -2
  29. package/lib/core/experimental/frames/network-frame.d.ts +2 -2
  30. package/lib/core/experimental/frames/websocket-frame.d.mts +2 -2
  31. package/lib/core/experimental/frames/websocket-frame.d.ts +2 -2
  32. package/lib/core/experimental/frames/websocket-frame.js +2 -0
  33. package/lib/core/experimental/frames/websocket-frame.js.map +1 -1
  34. package/lib/core/experimental/frames/websocket-frame.mjs +2 -0
  35. package/lib/core/experimental/frames/websocket-frame.mjs.map +1 -1
  36. package/lib/core/experimental/handlers-controller.d.mts +1 -1
  37. package/lib/core/experimental/handlers-controller.d.ts +1 -1
  38. package/lib/core/experimental/handlers-controller.js +3 -1
  39. package/lib/core/experimental/handlers-controller.js.map +1 -1
  40. package/lib/core/experimental/handlers-controller.mjs +3 -1
  41. package/lib/core/experimental/handlers-controller.mjs.map +1 -1
  42. package/lib/core/experimental/index.d.mts +2 -2
  43. package/lib/core/experimental/index.d.ts +2 -2
  44. package/lib/core/experimental/index.js +0 -1
  45. package/lib/core/experimental/index.js.map +1 -1
  46. package/lib/core/experimental/index.mjs +1 -2
  47. package/lib/core/experimental/index.mjs.map +1 -1
  48. package/lib/core/experimental/on-unhandled-frame.d.mts +2 -2
  49. package/lib/core/experimental/on-unhandled-frame.d.ts +2 -2
  50. package/lib/core/experimental/on-unhandled-frame.js +1 -0
  51. package/lib/core/experimental/on-unhandled-frame.js.map +1 -1
  52. package/lib/core/experimental/on-unhandled-frame.mjs +1 -0
  53. package/lib/core/experimental/on-unhandled-frame.mjs.map +1 -1
  54. package/lib/core/experimental/setup-api.d.mts +1 -1
  55. package/lib/core/experimental/setup-api.d.ts +1 -1
  56. package/lib/core/experimental/setup-api.js +1 -0
  57. package/lib/core/experimental/setup-api.js.map +1 -1
  58. package/lib/core/experimental/setup-api.mjs +1 -0
  59. package/lib/core/experimental/setup-api.mjs.map +1 -1
  60. package/lib/core/experimental/sources/interceptor-source.d.mts +2 -2
  61. package/lib/core/experimental/sources/interceptor-source.d.ts +2 -2
  62. package/lib/core/experimental/sources/interceptor-source.js.map +1 -1
  63. package/lib/core/experimental/sources/interceptor-source.mjs +1 -3
  64. package/lib/core/experimental/sources/interceptor-source.mjs.map +1 -1
  65. package/lib/core/experimental/sources/network-source.d.mts +3 -3
  66. package/lib/core/experimental/sources/network-source.d.ts +3 -3
  67. package/lib/core/experimental/sources/network-source.js +1 -0
  68. package/lib/core/experimental/sources/network-source.js.map +1 -1
  69. package/lib/core/experimental/sources/network-source.mjs +2 -0
  70. package/lib/core/experimental/sources/network-source.mjs.map +1 -1
  71. package/lib/core/getResponse.d.mts +1 -1
  72. package/lib/core/getResponse.d.ts +1 -1
  73. package/lib/core/graphql.d.mts +1 -1
  74. package/lib/core/graphql.d.ts +1 -1
  75. package/lib/core/graphql.js +1 -0
  76. package/lib/core/graphql.js.map +1 -1
  77. package/lib/core/graphql.mjs +2 -0
  78. package/lib/core/graphql.mjs.map +1 -1
  79. package/lib/core/handlers/GraphQLHandler.d.mts +1 -1
  80. package/lib/core/handlers/GraphQLHandler.d.ts +1 -1
  81. package/lib/core/handlers/GraphQLHandler.js +1 -0
  82. package/lib/core/handlers/GraphQLHandler.js.map +1 -1
  83. package/lib/core/handlers/GraphQLHandler.mjs +4 -1
  84. package/lib/core/handlers/GraphQLHandler.mjs.map +1 -1
  85. package/lib/core/handlers/HttpHandler.d.mts +1 -1
  86. package/lib/core/handlers/HttpHandler.d.ts +1 -1
  87. package/lib/core/handlers/HttpHandler.js +1 -0
  88. package/lib/core/handlers/HttpHandler.js.map +1 -1
  89. package/lib/core/handlers/HttpHandler.mjs +1 -0
  90. package/lib/core/handlers/HttpHandler.mjs.map +1 -1
  91. package/lib/core/handlers/RequestHandler.d.mts +1 -1
  92. package/lib/core/handlers/RequestHandler.d.ts +1 -1
  93. package/lib/core/handlers/RequestHandler.js +1 -0
  94. package/lib/core/handlers/RequestHandler.js.map +1 -1
  95. package/lib/core/handlers/RequestHandler.mjs +2 -0
  96. package/lib/core/handlers/RequestHandler.mjs.map +1 -1
  97. package/lib/core/http.d.mts +1 -1
  98. package/lib/core/http.d.ts +1 -1
  99. package/lib/core/http.js +1 -0
  100. package/lib/core/http.js.map +1 -1
  101. package/lib/core/http.mjs +2 -0
  102. package/lib/core/http.mjs.map +1 -1
  103. package/lib/core/index.d.mts +1 -1
  104. package/lib/core/index.d.ts +1 -1
  105. package/lib/core/passthrough.d.mts +1 -1
  106. package/lib/core/passthrough.d.ts +1 -1
  107. package/lib/core/sse.d.mts +4 -18
  108. package/lib/core/sse.d.ts +4 -18
  109. package/lib/core/sse.js +105 -45
  110. package/lib/core/sse.js.map +1 -1
  111. package/lib/core/sse.mjs +105 -45
  112. package/lib/core/sse.mjs.map +1 -1
  113. package/lib/core/utils/HttpResponse/decorators.d.mts +1 -1
  114. package/lib/core/utils/HttpResponse/decorators.d.ts +1 -1
  115. package/lib/core/utils/cookieStore.js.map +1 -1
  116. package/lib/core/utils/cookieStore.mjs.map +1 -1
  117. package/lib/core/utils/executeHandlers.d.mts +1 -1
  118. package/lib/core/utils/executeHandlers.d.ts +1 -1
  119. package/lib/core/utils/executeHandlers.js +1 -0
  120. package/lib/core/utils/executeHandlers.js.map +1 -1
  121. package/lib/core/utils/executeHandlers.mjs +1 -0
  122. package/lib/core/utils/executeHandlers.mjs.map +1 -1
  123. package/lib/core/utils/handleRequest.d.mts +1 -1
  124. package/lib/core/utils/handleRequest.d.ts +1 -1
  125. package/lib/core/utils/handleRequest.js.map +1 -1
  126. package/lib/core/utils/handleRequest.mjs.map +1 -1
  127. package/lib/core/utils/internal/isHandlerKind.d.mts +1 -1
  128. package/lib/core/utils/internal/isHandlerKind.d.ts +1 -1
  129. package/lib/core/utils/internal/parseGraphQLRequest.d.mts +1 -1
  130. package/lib/core/utils/internal/parseGraphQLRequest.d.ts +1 -1
  131. package/lib/core/utils/internal/parseMultipartData.d.mts +1 -1
  132. package/lib/core/utils/internal/parseMultipartData.d.ts +1 -1
  133. package/lib/core/utils/internal/parseMultipartData.js +1 -0
  134. package/lib/core/utils/internal/parseMultipartData.js.map +1 -1
  135. package/lib/core/utils/internal/parseMultipartData.mjs +1 -0
  136. package/lib/core/utils/internal/parseMultipartData.mjs.map +1 -1
  137. package/lib/core/utils/internal/pipeEvents.js +1 -0
  138. package/lib/core/utils/internal/pipeEvents.js.map +1 -1
  139. package/lib/core/utils/internal/pipeEvents.mjs +1 -0
  140. package/lib/core/utils/internal/pipeEvents.mjs.map +1 -1
  141. package/lib/core/utils/internal/requestHandlerUtils.d.mts +1 -1
  142. package/lib/core/utils/internal/requestHandlerUtils.d.ts +1 -1
  143. package/lib/core/utils/internal/requestHandlerUtils.js.map +1 -1
  144. package/lib/core/utils/internal/requestHandlerUtils.mjs.map +1 -1
  145. package/lib/core/ws/WebSocketClientManager.js.map +1 -1
  146. package/lib/core/ws/WebSocketClientManager.mjs.map +1 -1
  147. package/lib/core/ws/WebSocketIndexedDBClientStore.js +1 -0
  148. package/lib/core/ws/WebSocketIndexedDBClientStore.js.map +1 -1
  149. package/lib/core/ws/WebSocketIndexedDBClientStore.mjs +1 -0
  150. package/lib/core/ws/WebSocketIndexedDBClientStore.mjs.map +1 -1
  151. package/lib/core/ws/WebSocketMemoryClientStore.js +1 -0
  152. package/lib/core/ws/WebSocketMemoryClientStore.js.map +1 -1
  153. package/lib/core/ws/WebSocketMemoryClientStore.mjs +1 -0
  154. package/lib/core/ws/WebSocketMemoryClientStore.mjs.map +1 -1
  155. package/lib/core/ws/handleWebSocketEvent.d.mts +1 -1
  156. package/lib/core/ws/handleWebSocketEvent.d.ts +1 -1
  157. package/lib/core/ws/handleWebSocketEvent.js.map +1 -1
  158. package/lib/core/ws/handleWebSocketEvent.mjs.map +1 -1
  159. package/lib/core/ws.js.map +1 -1
  160. package/lib/core/ws.mjs.map +1 -1
  161. package/lib/iife/index.js +6081 -5821
  162. package/lib/iife/index.js.map +1 -1
  163. package/lib/mockServiceWorker.js +1 -1
  164. package/lib/native/index.js.map +1 -1
  165. package/lib/native/index.mjs.map +1 -1
  166. package/lib/node/index.js.map +1 -1
  167. package/lib/node/index.mjs.map +1 -1
  168. package/lib/shims/cookie.js +152 -62
  169. package/lib/shims/cookie.mjs +152 -62
  170. package/package.json +34 -41
  171. package/src/browser/glossary.ts +1 -1
  172. package/src/browser/setup-worker.ts +2 -2
  173. package/src/browser/sources/service-worker-source.ts +125 -28
  174. package/src/browser/utils/deserializeRequest.ts +0 -1
  175. package/src/browser/utils/should-invalidate-worker.test.ts +122 -0
  176. package/src/browser/utils/should-invalidate-worker.ts +13 -0
  177. package/src/browser/utils/workerChannel.ts +43 -21
  178. package/src/core/experimental/define-network.ts +10 -2
  179. package/src/core/experimental/frames/http-frame.test.ts +2 -1
  180. package/src/core/experimental/frames/http-frame.ts +6 -2
  181. package/src/core/experimental/frames/websocket-frame.test.ts +2 -4
  182. package/src/core/experimental/frames/websocket-frame.ts +3 -2
  183. package/src/core/experimental/handlers-controller.ts +1 -1
  184. package/src/core/experimental/index.ts +1 -1
  185. package/src/core/experimental/on-unhandled-frame.test.ts +2 -4
  186. package/src/core/experimental/setup-api.ts +3 -3
  187. package/src/core/experimental/sources/interceptor-source.ts +2 -6
  188. package/src/core/experimental/sources/network-source.ts +1 -1
  189. package/src/core/graphql.ts +8 -8
  190. package/src/core/handlers/GraphQLHandler.test.ts +3 -4
  191. package/src/core/handlers/GraphQLHandler.ts +15 -11
  192. package/src/core/handlers/HttpHandler.test.ts +3 -2
  193. package/src/core/handlers/HttpHandler.ts +7 -7
  194. package/src/core/handlers/RequestHandler.ts +5 -5
  195. package/src/core/http.ts +5 -5
  196. package/src/core/sse.ts +157 -56
  197. package/src/core/utils/cookieStore.ts +1 -1
  198. package/src/core/utils/executeHandlers.ts +2 -4
  199. package/src/core/utils/handleRequest.test.ts +5 -4
  200. package/src/core/utils/handleRequest.ts +3 -3
  201. package/src/core/utils/internal/parseGraphQLRequest.test.ts +2 -4
  202. package/src/core/utils/internal/parseMultipartData.ts +1 -1
  203. package/src/core/utils/internal/pipeEvents.ts +2 -1
  204. package/src/core/utils/internal/requestHandlerUtils.ts +1 -1
  205. package/src/core/utils/request/onUnhandledRequest.test.ts +2 -4
  206. package/src/core/ws/WebSocketClientManager.test.ts +2 -4
  207. package/src/core/ws/WebSocketClientManager.ts +1 -1
  208. package/src/core/ws/WebSocketIndexedDBClientStore.ts +3 -5
  209. package/src/core/ws/WebSocketMemoryClientStore.ts +3 -5
  210. package/src/core/ws/handleWebSocketEvent.ts +3 -3
  211. package/src/core/ws.ts +1 -1
  212. package/src/native/index.ts +2 -2
  213. package/src/node/async-handlers-controller.ts +2 -2
  214. package/src/node/setup-server-common.ts +4 -4
  215. package/src/node/setup-server.ts +2 -2
  216. package/lib/core/{network-frame-usYiHS0K.d.ts → on-unhandled-frame-BBR-P3kV.d.ts} +12 -12
  217. package/lib/core/{network-frame-B7A0ggXE.d.mts → on-unhandled-frame-Cr1KOZ0I.d.mts} +12 -12
@@ -1,16 +1,16 @@
1
1
  import type { OperationTypeNode } from 'graphql'
2
2
  import {
3
- ResponseResolver,
4
- RequestHandlerOptions,
3
+ type ResponseResolver,
4
+ type RequestHandlerOptions,
5
5
  } from './handlers/RequestHandler'
6
6
  import {
7
7
  GraphQLHandler,
8
- GraphQLVariables,
9
- GraphQLOperationType,
10
- GraphQLResolverExtras,
11
- GraphQLResponseBody,
12
- GraphQLQuery,
13
- GraphQLPredicate,
8
+ type GraphQLVariables,
9
+ type GraphQLOperationType,
10
+ type GraphQLResolverExtras,
11
+ type GraphQLResponseBody,
12
+ type GraphQLQuery,
13
+ type GraphQLPredicate,
14
14
  } from './handlers/GraphQLHandler'
15
15
  import type { Path } from './utils/matching/matchRequestUrl'
16
16
 
@@ -1,14 +1,13 @@
1
1
  // @vitest-environment jsdom
2
2
  import { createRequestId, encodeBuffer } from '@mswjs/interceptors'
3
3
  import { OperationTypeNode, parse } from 'graphql'
4
- import {
5
- GraphQLHandler,
4
+ import type {
6
5
  GraphQLRequestBody,
7
6
  GraphQLResolverExtras,
8
- isDocumentNode,
9
7
  } from './GraphQLHandler'
8
+ import { GraphQLHandler, isDocumentNode } from './GraphQLHandler'
10
9
  import { HttpResponse } from '../HttpResponse'
11
- import { ResponseResolver } from './RequestHandler'
10
+ import type { ResponseResolver } from './RequestHandler'
12
11
 
13
12
  const resolver: ResponseResolver<GraphQLResolverExtras<{ userId: string }>> = ({
14
13
  variables,
@@ -6,30 +6,34 @@ import {
6
6
  type OperationTypeNode,
7
7
  } from 'graphql'
8
8
  import {
9
- DefaultBodyType,
10
9
  RequestHandler,
11
- RequestHandlerDefaultInfo,
12
- RequestHandlerExecutionResult,
13
- RequestHandlerOptions,
14
- ResponseResolver,
10
+ type DefaultBodyType,
11
+ type RequestHandlerDefaultInfo,
12
+ type RequestHandlerExecutionResult,
13
+ type RequestHandlerOptions,
14
+ type ResponseResolver,
15
15
  } from './RequestHandler'
16
16
  import { getTimestamp } from '../utils/logging/getTimestamp'
17
17
  import { getStatusCodeColor } from '../utils/logging/getStatusCodeColor'
18
18
  import { serializeRequest } from '../utils/logging/serializeRequest'
19
19
  import { serializeResponse } from '../utils/logging/serializeResponse'
20
- import { Match, matchRequestUrl, Path } from '../utils/matching/matchRequestUrl'
21
20
  import {
22
- ParsedGraphQLRequest,
23
- GraphQLMultipartRequestBody,
21
+ type Match,
22
+ matchRequestUrl,
23
+ type Path,
24
+ } from '../utils/matching/matchRequestUrl'
25
+ import {
26
+ type ParsedGraphQLRequest,
27
+ type GraphQLMultipartRequestBody,
24
28
  parseGraphQLRequest,
25
29
  parseDocumentNode,
26
- ParsedGraphQLQuery,
30
+ type ParsedGraphQLQuery,
27
31
  } from '../utils/internal/parseGraphQLRequest'
28
32
  import { toPublicUrl } from '../utils/request/toPublicUrl'
29
33
  import { devUtils } from '../utils/internal/devUtils'
30
34
  import { getAllRequestCookies } from '../utils/request/getRequestCookies'
31
- import { ResponseResolutionContext } from 'src/iife'
32
- import { kDefaultContentType, StrictRequest } from '../HttpResponse'
35
+ import { type ResponseResolutionContext } from '../utils/executeHandlers'
36
+ import { kDefaultContentType, type StrictRequest } from '../HttpResponse'
33
37
  import { getAllAcceptedMimeTypes } from '../utils/request/getAllAcceptedMimeTypes'
34
38
 
35
39
  export interface DocumentTypeDecoration<
@@ -1,8 +1,9 @@
1
1
  // @vitest-environment jsdom
2
2
  import { createRequestId } from '@mswjs/interceptors'
3
- import { HttpHandler, HttpRequestResolverExtras } from './HttpHandler'
3
+ import type { HttpRequestResolverExtras } from './HttpHandler'
4
+ import { HttpHandler } from './HttpHandler'
4
5
  import { HttpResponse } from '..'
5
- import { ResponseResolver } from './RequestHandler'
6
+ import type { ResponseResolver } from './RequestHandler'
6
7
 
7
8
  const resolver: ResponseResolver<
8
9
  HttpRequestResolverExtras<{ userId: string }>
@@ -1,4 +1,4 @@
1
- import { ResponseResolutionContext } from '../utils/executeHandlers'
1
+ import { type ResponseResolutionContext } from '../utils/executeHandlers'
2
2
  import { devUtils } from '../utils/internal/devUtils'
3
3
  import { isStringEqual } from '../utils/internal/isStringEqual'
4
4
  import { getStatusCodeColor } from '../utils/logging/getStatusCodeColor'
@@ -7,18 +7,18 @@ import { serializeRequest } from '../utils/logging/serializeRequest'
7
7
  import { serializeResponse } from '../utils/logging/serializeResponse'
8
8
  import {
9
9
  matchRequestUrl,
10
- Match,
11
- Path,
12
- PathParams,
10
+ type Match,
11
+ type Path,
12
+ type PathParams,
13
13
  } from '../utils/matching/matchRequestUrl'
14
14
  import { toPublicUrl } from '../utils/request/toPublicUrl'
15
15
  import { getAllRequestCookies } from '../utils/request/getRequestCookies'
16
16
  import { cleanUrl } from '../utils/url/cleanUrl'
17
17
  import {
18
18
  RequestHandler,
19
- RequestHandlerDefaultInfo,
20
- RequestHandlerOptions,
21
- ResponseResolver,
19
+ type RequestHandlerDefaultInfo,
20
+ type RequestHandlerOptions,
21
+ type ResponseResolver,
22
22
  } from './RequestHandler'
23
23
 
24
24
  export type HttpHandlerMethod = string | RegExp
@@ -1,15 +1,15 @@
1
1
  import { getCallFrame } from '../utils/internal/getCallFrame'
2
2
  import {
3
- AsyncIterable,
4
- Iterable,
5
3
  isIterable,
4
+ type AsyncIterable,
5
+ type Iterable,
6
6
  } from '../utils/internal/isIterable'
7
7
  import type { ResponseResolutionContext } from '../utils/executeHandlers'
8
8
  import type { MaybePromise } from '../typeUtils'
9
+ import type { HttpResponse } from '../HttpResponse'
9
10
  import {
10
- StrictRequest,
11
- HttpResponse,
12
- DefaultUnsafeFetchResponse,
11
+ type StrictRequest,
12
+ type DefaultUnsafeFetchResponse,
13
13
  } from '../HttpResponse'
14
14
  import type { GraphQLRequestBody } from './GraphQLHandler'
15
15
 
package/src/core/http.ts CHANGED
@@ -1,13 +1,13 @@
1
1
  import {
2
- DefaultBodyType,
3
- RequestHandlerOptions,
4
- ResponseResolver,
2
+ type DefaultBodyType,
3
+ type RequestHandlerOptions,
4
+ type ResponseResolver,
5
5
  } from './handlers/RequestHandler'
6
6
  import {
7
7
  HttpMethods,
8
8
  HttpHandler,
9
- HttpRequestResolverExtras,
10
- HttpRequestPredicate,
9
+ type HttpRequestResolverExtras,
10
+ type HttpRequestPredicate,
11
11
  } from './handlers/HttpHandler'
12
12
  import type { PathParams } from './utils/matching/matchRequestUrl'
13
13
 
package/src/core/sse.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { invariant } from 'outvariant'
2
+ import { DeferredPromise } from '@open-draft/deferred-promise'
2
3
  import { Emitter } from 'strict-event-emitter'
3
4
  import type { ResponseResolver } from './handlers/RequestHandler'
4
5
  import {
@@ -89,26 +90,19 @@ class ServerSentEventHandler<
89
90
  )
90
91
 
91
92
  super('GET', path, async (info) => {
92
- const stream = new ReadableStream({
93
- start: async (controller) => {
94
- const client = new ServerSentEventClient<EventMap>({
95
- controller,
96
- emitter: this.#emitter,
97
- })
98
- const server = new ServerSentEventServer({
99
- request: info.request,
100
- client,
101
- })
102
-
103
- await resolver({
104
- ...info,
105
- client,
106
- server,
107
- })
108
- },
93
+ const { client, server, response } = createEventStream<EventMap>(
94
+ info.request,
95
+ )
96
+
97
+ client[kClientEmitter] = this.#emitter
98
+
99
+ await resolver({
100
+ ...info,
101
+ client,
102
+ server,
109
103
  })
110
104
 
111
- return new Response(stream, SSE_RESPONSE_INIT)
105
+ return response
112
106
  })
113
107
 
114
108
  this.#emitter = new Emitter<ServerSentEventClientEventMap>()
@@ -222,32 +216,24 @@ type ToEventDiscriminatedUnion<T> = Values<{
222
216
  }>
223
217
 
224
218
  type ServerSentEventClientEventMap = {
225
- message: [
226
- payload: {
227
- id?: string
228
- event: string
229
- data?: unknown
230
- frames: Array<string>
231
- },
232
- ]
219
+ message: [payload: EventStreamMessage]
233
220
  error: []
234
221
  close: []
235
222
  }
236
223
 
224
+ const kClientEmitter = Symbol.for('kClientEmitter')
225
+
237
226
  class ServerSentEventClient<
238
227
  EventMap extends EventMapConstraint = { message: unknown },
239
228
  > {
229
+ private [kClientEmitter]?: Emitter<ServerSentEventClientEventMap>
230
+
240
231
  #encoder: TextEncoder
241
- #controller: ReadableStreamDefaultController
242
- #emitter: Emitter<ServerSentEventClientEventMap>
232
+ #writer: WritableStreamDefaultWriter
243
233
 
244
- constructor(args: {
245
- controller: ReadableStreamDefaultController
246
- emitter: Emitter<ServerSentEventClientEventMap>
247
- }) {
234
+ constructor(writable: WritableStream) {
248
235
  this.#encoder = new TextEncoder()
249
- this.#controller = args.controller
250
- this.#emitter = args.emitter
236
+ this.#writer = writable.getWriter()
251
237
  }
252
238
 
253
239
  /**
@@ -303,22 +289,37 @@ class ServerSentEventClient<
303
289
  * error.
304
290
  */
305
291
  public error(): void {
306
- this.#controller.error()
307
- this.#emitter.emit('error')
292
+ this.#writer.abort().catch((error) => {
293
+ console.error(error)
294
+ devUtils.error(
295
+ 'Failed to abort server-side EventSource. Please see the original error above.',
296
+ )
297
+ })
298
+ this[kClientEmitter]?.emit('error')
308
299
  }
309
300
 
310
301
  /**
311
302
  * Closes the underlying `EventSource`, closing the connection.
312
303
  */
313
304
  public close(): void {
314
- this.#controller.close()
315
- this.#emitter.emit('close')
305
+ this.#writer.close().catch((error) => {
306
+ console.error(error)
307
+ devUtils.error(
308
+ 'Failed to close server-side EventSource. Please see the original error above.',
309
+ )
310
+ })
311
+ this[kClientEmitter]?.emit('close')
316
312
  }
317
313
 
318
314
  #sendRetry(retry: number): void {
319
- if (typeof retry === 'number') {
320
- this.#controller.enqueue(this.#encoder.encode(`retry:${retry}\n\n`))
321
- }
315
+ this.#writer
316
+ .write(this.#encoder.encode(`retry:${retry}\n\n`))
317
+ .catch((error) => {
318
+ console.error(error)
319
+ devUtils.error(
320
+ 'Failed to send a retry packet to server-side EventSource. Please see the original error above.',
321
+ )
322
+ })
322
323
  }
323
324
 
324
325
  #sendMessage(message: {
@@ -349,9 +350,16 @@ class ServerSentEventClient<
349
350
 
350
351
  frames.push('', '')
351
352
 
352
- this.#controller.enqueue(this.#encoder.encode(frames.join('\n')))
353
+ this.#writer
354
+ .write(this.#encoder.encode(frames.join('\n')))
355
+ .catch((error) => {
356
+ console.error(error)
357
+ devUtils.error(
358
+ 'Failed to send a message to server-side EventSource. Please see the original error above.',
359
+ )
360
+ })
353
361
 
354
- this.#emitter.emit('message', {
362
+ this[kClientEmitter]?.emit('message', {
355
363
  id: message.id,
356
364
  event: message.event?.toString() || 'message',
357
365
  data: message.data,
@@ -383,6 +391,7 @@ class ServerSentEventServer {
383
391
  */
384
392
  accept: 'msw/passthrough',
385
393
  },
394
+ signal: this.#request.signal,
386
395
  })
387
396
 
388
397
  source[kOnAnyMessage] = (event) => {
@@ -429,6 +438,7 @@ class ServerSentEventServer {
429
438
 
430
439
  interface ObservableEventSourceInit extends EventSourceInit {
431
440
  headers?: HeadersInit
441
+ signal?: AbortSignal
432
442
  }
433
443
 
434
444
  type EventHandler<EventType extends Event> = (
@@ -489,6 +499,18 @@ class ObservableEventSource extends EventTarget implements EventSource {
489
499
  signal: this[kAbortController].signal,
490
500
  })
491
501
 
502
+ if (init?.signal) {
503
+ if (init.signal.aborted) {
504
+ this.close()
505
+ return
506
+ }
507
+
508
+ init.signal.addEventListener('abort', () => this.close(), {
509
+ once: true,
510
+ signal: this[kAbortController].signal,
511
+ })
512
+ }
513
+
492
514
  this.connect()
493
515
  }
494
516
 
@@ -518,7 +540,7 @@ class ObservableEventSource extends EventTarget implements EventSource {
518
540
  get onerror(): EventHandler<Event> | null {
519
541
  return this[kOnError]
520
542
  }
521
- set oneerror(handler: EventHandler<Event>) {
543
+ set onerror(handler: EventHandler<Event>) {
522
544
  if (this[kOnError]) {
523
545
  this.removeEventListener('error', { handleEvent: this[kOnError] })
524
546
  }
@@ -642,10 +664,6 @@ class ObservableEventSource extends EventTarget implements EventSource {
642
664
  this[kLastEventId] = message.id
643
665
  }
644
666
 
645
- if (message.retry) {
646
- this[kReconnectionTime] = message.retry
647
- }
648
-
649
667
  const messageEvent = new MessageEvent(
650
668
  message.event ? message.event : 'message',
651
669
  {
@@ -659,6 +677,9 @@ class ObservableEventSource extends EventTarget implements EventSource {
659
677
  this[kOnAnyMessage]?.(messageEvent)
660
678
  this.dispatchEvent(messageEvent)
661
679
  },
680
+ retry: (reconnectionTime) => {
681
+ this[kReconnectionTime] = reconnectionTime
682
+ },
662
683
  abort: () => {
663
684
  throw new Error('Stream abort is not implemented')
664
685
  },
@@ -693,7 +714,25 @@ class ObservableEventSource extends EventTarget implements EventSource {
693
714
  this.dispatchEvent(new Event('error'))
694
715
  })
695
716
 
696
- await delay(this[kReconnectionTime])
717
+ const signal = this[kAbortController].signal
718
+
719
+ if (signal.aborted) {
720
+ return
721
+ }
722
+
723
+ const aborted = new DeferredPromise<void>()
724
+ const onAbort = () => aborted.resolve()
725
+ signal.addEventListener('abort', onAbort, { once: true })
726
+
727
+ await Promise.race([delay(this[kReconnectionTime]), aborted]).finally(
728
+ () => {
729
+ signal.removeEventListener('abort', onAbort)
730
+ },
731
+ )
732
+
733
+ if (signal.aborted) {
734
+ return
735
+ }
697
736
 
698
737
  queueMicrotask(async () => {
699
738
  if (this.readyState !== this.CONNECTING) {
@@ -743,7 +782,6 @@ interface EventSourceMessage {
743
782
  id?: string
744
783
  event?: string
745
784
  data?: string
746
- retry?: number
747
785
  }
748
786
 
749
787
  class EventSourceParsingStream extends WritableStream {
@@ -758,12 +796,12 @@ class EventSourceParsingStream extends WritableStream {
758
796
  id: undefined,
759
797
  event: undefined,
760
798
  data: undefined,
761
- retry: undefined,
762
799
  }
763
800
 
764
801
  constructor(
765
802
  private underlyingSink: {
766
803
  message: (message: EventSourceMessage) => void
804
+ retry?: (reconnectionTime: number) => void
767
805
  abort?: (reason: any) => void
768
806
  close?: () => void
769
807
  },
@@ -789,7 +827,6 @@ class EventSourceParsingStream extends WritableStream {
789
827
  id: undefined,
790
828
  event: undefined,
791
829
  data: undefined,
792
- retry: undefined,
793
830
  }
794
831
  }
795
832
 
@@ -903,10 +940,12 @@ class EventSourceParsingStream extends WritableStream {
903
940
  }
904
941
 
905
942
  case 'retry': {
906
- const retry = parseInt(value, 10)
907
-
908
- if (!isNaN(retry)) {
909
- this.message.retry = retry
943
+ /**
944
+ * Apply the retry immediately. Don't buffer onto the current message.
945
+ * @see https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation
946
+ */
947
+ if (/^\d+$/.test(value)) {
948
+ this.underlyingSink.retry?.(parseInt(value, 10))
910
949
  }
911
950
  break
912
951
  }
@@ -914,3 +953,65 @@ class EventSourceParsingStream extends WritableStream {
914
953
  }
915
954
  }
916
955
  }
956
+
957
+ interface EventStreamMessage {
958
+ id?: string
959
+ event: string
960
+ data?: unknown
961
+ frames: Array<string>
962
+ }
963
+
964
+ interface EventStream<EventMap extends EventMapConstraint> {
965
+ client: ServerSentEventClient<EventMap>
966
+ server: ServerSentEventServer
967
+ response: Response
968
+ }
969
+
970
+ /**
971
+ * Create an event stream out of the given Fetch API `Request`.
972
+ * Returns the following properties:
973
+ * - `client`, to operate on the intercepted request;
974
+ * - `server`, to establish and manage the actual server connection;
975
+ * - `response`, a `Response` to use as the mock response's body.
976
+ *
977
+ * @example
978
+ * http.post('/resource', ({ request }) => {
979
+ * const { client, server, response } = createEventStream(request)
980
+ * client.send({ data: 'hello world' })
981
+ * return response
982
+ * })
983
+ */
984
+ function createEventStream<EventMap extends EventMapConstraint>(
985
+ request: Request,
986
+ ): EventStream<EventMap> {
987
+ invariant(
988
+ !request.signal.aborted,
989
+ 'Failed to call "createEventStream" on the "%s %s" request: request aborted',
990
+ request.method,
991
+ request.url,
992
+ )
993
+
994
+ const { readable, writable } = new TransformStream()
995
+
996
+ const client = new ServerSentEventClient<EventMap>(writable)
997
+ const server = new ServerSentEventServer({
998
+ request,
999
+ client,
1000
+ })
1001
+
1002
+ const response = new Response(readable, SSE_RESPONSE_INIT)
1003
+
1004
+ request.signal.addEventListener(
1005
+ 'abort',
1006
+ () => {
1007
+ client.close()
1008
+ },
1009
+ { once: true },
1010
+ )
1011
+
1012
+ return {
1013
+ client,
1014
+ server,
1015
+ response,
1016
+ }
1017
+ }
@@ -4,7 +4,7 @@ import {
4
4
  Cookie,
5
5
  CookieJar,
6
6
  MemoryCookieStore,
7
- SerializedCookie,
7
+ type SerializedCookie,
8
8
  type MemoryCookieStoreIndex,
9
9
  } from 'tough-cookie'
10
10
  import { jsonParse } from './internal/jsonParse'
@@ -1,7 +1,5 @@
1
- import {
2
- RequestHandler,
3
- type RequestHandlerExecutionResult,
4
- } from '../handlers/RequestHandler'
1
+ import type { RequestHandler } from '../handlers/RequestHandler'
2
+ import { type RequestHandlerExecutionResult } from '../handlers/RequestHandler'
5
3
 
6
4
  export interface HandlersExecutionResult {
7
5
  handler: RequestHandler
@@ -1,11 +1,12 @@
1
1
  // @vitest-environment jsdom
2
2
  import { Emitter } from 'strict-event-emitter'
3
3
  import { createRequestId } from '@mswjs/interceptors'
4
- import { LifeCycleEventsMap, SharedOptions } from '../sharedOptions'
5
- import { RequestHandler } from '../handlers/RequestHandler'
4
+ import type { LifeCycleEventsMap, SharedOptions } from '../sharedOptions'
5
+ import type { RequestHandler } from '../handlers/RequestHandler'
6
6
  import { http } from '../http'
7
- import { handleRequest, HandleRequestOptions } from './handleRequest'
8
- import { RequiredDeep } from '../typeUtils'
7
+ import type { HandleRequestOptions } from './handleRequest'
8
+ import { handleRequest } from './handleRequest'
9
+ import type { RequiredDeep } from '../typeUtils'
9
10
  import { HttpResponse } from '../HttpResponse'
10
11
  import { passthrough } from '../passthrough'
11
12
 
@@ -1,7 +1,7 @@
1
1
  import { until } from 'until-async'
2
- import { Emitter } from 'strict-event-emitter'
3
- import { LifeCycleEventsMap, SharedOptions } from '../sharedOptions'
4
- import { RequiredDeep } from '../typeUtils'
2
+ import type { Emitter } from 'strict-event-emitter'
3
+ import type { LifeCycleEventsMap, SharedOptions } from '../sharedOptions'
4
+ import type { RequiredDeep } from '../typeUtils'
5
5
  import type { RequestHandler } from '../handlers/RequestHandler'
6
6
  import {
7
7
  type HandlersExecutionResult,
@@ -3,10 +3,8 @@
3
3
  */
4
4
  import { encodeBuffer } from '@mswjs/interceptors'
5
5
  import { OperationTypeNode } from 'graphql'
6
- import {
7
- ParsedGraphQLRequest,
8
- parseGraphQLRequest,
9
- } from './parseGraphQLRequest'
6
+ import type { ParsedGraphQLRequest } from './parseGraphQLRequest'
7
+ import { parseGraphQLRequest } from './parseGraphQLRequest'
10
8
 
11
9
  test('returns true given a GraphQL-compatible request', async () => {
12
10
  const getRequest = new Request(
@@ -1,5 +1,5 @@
1
1
  import { stringToHeaders } from 'headers-polyfill'
2
- import { DefaultRequestMultipartBody } from '../../handlers/RequestHandler'
2
+ import { type DefaultRequestMultipartBody } from '../../handlers/RequestHandler'
3
3
 
4
4
  interface ParsedContentHeaders {
5
5
  name: string
@@ -1,4 +1,5 @@
1
- import { Emitter, EventMap } from 'strict-event-emitter'
1
+ import type { Emitter } from 'strict-event-emitter'
2
+ import { type EventMap } from 'strict-event-emitter'
2
3
 
3
4
  /**
4
5
  * Pipes all emitted events from one emitter to another.
@@ -1,4 +1,4 @@
1
- import { RequestHandler } from '../../handlers/RequestHandler'
1
+ import type { RequestHandler } from '../../handlers/RequestHandler'
2
2
 
3
3
  export function use(
4
4
  currentHandlers: Array<RequestHandler>,
@@ -1,8 +1,6 @@
1
1
  // @vitest-environment jsdom
2
- import {
3
- onUnhandledRequest,
4
- UnhandledRequestCallback,
5
- } from './onUnhandledRequest'
2
+ import type { UnhandledRequestCallback } from './onUnhandledRequest'
3
+ import { onUnhandledRequest } from './onUnhandledRequest'
6
4
 
7
5
  const fixtures = {
8
6
  warningWithoutSuggestions: (url = `/api`) => `\
@@ -1,10 +1,8 @@
1
1
  // @vitest-environment node-websocket
2
2
  import { setMaxListeners } from 'node:events'
3
3
  import { WebSocketClientConnection } from '@mswjs/interceptors/WebSocket'
4
- import {
5
- WebSocketClientManager,
6
- WebSocketBroadcastChannelMessage,
7
- } from './WebSocketClientManager'
4
+ import type { WebSocketBroadcastChannelMessage } from './WebSocketClientManager'
5
+ import { WebSocketClientManager } from './WebSocketClientManager'
8
6
  import { TestWebSocketTransport } from '../../../test/support/ws-test-utils'
9
7
 
10
8
  const channel = new BroadcastChannel('test:channel')
@@ -3,7 +3,7 @@ import type {
3
3
  WebSocketClientConnectionProtocol,
4
4
  WebSocketClientEventMap,
5
5
  } from '@mswjs/interceptors/WebSocket'
6
- import { WebSocketClientStore } from './WebSocketClientStore'
6
+ import type { WebSocketClientStore } from './WebSocketClientStore'
7
7
  import { WebSocketMemoryClientStore } from './WebSocketMemoryClientStore'
8
8
  import { WebSocketIndexedDBClientStore } from './WebSocketIndexedDBClientStore'
9
9
 
@@ -1,9 +1,7 @@
1
1
  import { DeferredPromise } from '@open-draft/deferred-promise'
2
- import { WebSocketClientConnectionProtocol } from '@mswjs/interceptors/WebSocket'
3
- import {
4
- type SerializedWebSocketClient,
5
- WebSocketClientStore,
6
- } from './WebSocketClientStore'
2
+ import type { WebSocketClientConnectionProtocol } from '@mswjs/interceptors/WebSocket'
3
+ import type { WebSocketClientStore } from './WebSocketClientStore'
4
+ import { type SerializedWebSocketClient } from './WebSocketClientStore'
7
5
 
8
6
  const DB_NAME = 'msw-websocket-clients'
9
7
  const DB_STORE_NAME = 'clients'