msw 2.14.6 → 2.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/lib/browser/index.js +233 -93
- package/lib/browser/index.js.map +1 -1
- package/lib/browser/index.mjs +233 -93
- package/lib/browser/index.mjs.map +1 -1
- package/lib/core/{HttpResponse-CQwYpuKo.d.mts → HttpResponse-BE_Y2Ak9.d.mts} +19 -1
- package/lib/core/{HttpResponse-BFS34nkx.d.ts → HttpResponse-DL-P1EeG.d.ts} +19 -1
- package/lib/core/HttpResponse.d.mts +1 -1
- package/lib/core/HttpResponse.d.ts +1 -1
- package/lib/core/HttpResponse.js +2 -2
- package/lib/core/HttpResponse.js.map +1 -1
- package/lib/core/HttpResponse.mjs +2 -2
- package/lib/core/HttpResponse.mjs.map +1 -1
- package/lib/core/experimental/compat.d.mts +2 -2
- package/lib/core/experimental/compat.d.ts +2 -2
- package/lib/core/experimental/define-network.d.mts +2 -2
- package/lib/core/experimental/define-network.d.ts +2 -2
- package/lib/core/experimental/frames/http-frame.d.mts +2 -2
- package/lib/core/experimental/frames/http-frame.d.ts +2 -2
- package/lib/core/experimental/frames/network-frame.d.mts +2 -2
- package/lib/core/experimental/frames/network-frame.d.ts +2 -2
- package/lib/core/experimental/frames/network-frame.js +2 -0
- package/lib/core/experimental/frames/network-frame.js.map +1 -1
- package/lib/core/experimental/frames/network-frame.mjs +2 -0
- package/lib/core/experimental/frames/network-frame.mjs.map +1 -1
- package/lib/core/experimental/frames/websocket-frame.d.mts +2 -2
- package/lib/core/experimental/frames/websocket-frame.d.ts +2 -2
- package/lib/core/experimental/handlers-controller.d.mts +1 -1
- package/lib/core/experimental/handlers-controller.d.ts +1 -1
- package/lib/core/experimental/index.d.mts +2 -2
- package/lib/core/experimental/index.d.ts +2 -2
- package/lib/core/experimental/on-unhandled-frame.d.mts +2 -2
- package/lib/core/experimental/on-unhandled-frame.d.ts +2 -2
- package/lib/core/experimental/setup-api.d.mts +1 -1
- package/lib/core/experimental/setup-api.d.ts +1 -1
- package/lib/core/experimental/sources/interceptor-source.d.mts +2 -2
- package/lib/core/experimental/sources/interceptor-source.d.ts +2 -2
- package/lib/core/experimental/sources/network-source.d.mts +2 -2
- package/lib/core/experimental/sources/network-source.d.ts +2 -2
- package/lib/core/getResponse.d.mts +1 -1
- package/lib/core/getResponse.d.ts +1 -1
- package/lib/core/graphql.d.mts +1 -1
- package/lib/core/graphql.d.ts +1 -1
- package/lib/core/handlers/GraphQLHandler.d.mts +1 -1
- package/lib/core/handlers/GraphQLHandler.d.ts +1 -1
- 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/RequestHandler.js +88 -23
- package/lib/core/handlers/RequestHandler.js.map +1 -1
- package/lib/core/handlers/RequestHandler.mjs +88 -23
- package/lib/core/handlers/RequestHandler.mjs.map +1 -1
- package/lib/core/handlers/WebSocketHandler.js +7 -6
- package/lib/core/handlers/WebSocketHandler.js.map +1 -1
- package/lib/core/handlers/WebSocketHandler.mjs +7 -6
- package/lib/core/handlers/WebSocketHandler.mjs.map +1 -1
- package/lib/core/http.d.mts +1 -1
- package/lib/core/http.d.ts +1 -1
- package/lib/core/index.d.mts +1 -1
- package/lib/core/index.d.ts +1 -1
- package/lib/core/{on-unhandled-frame-BBR-P3kV.d.ts → on-unhandled-frame-0KmwUmeV.d.ts} +1 -1
- package/lib/core/{on-unhandled-frame-Cr1KOZ0I.d.mts → on-unhandled-frame-gkokW4Rr.d.mts} +1 -1
- package/lib/core/passthrough.d.mts +1 -1
- package/lib/core/passthrough.d.ts +1 -1
- package/lib/core/sse.d.mts +2 -2
- package/lib/core/sse.d.ts +2 -2
- package/lib/core/sse.js +83 -60
- package/lib/core/sse.js.map +1 -1
- package/lib/core/sse.mjs +83 -60
- package/lib/core/sse.mjs.map +1 -1
- package/lib/core/utils/HttpResponse/decorators.d.mts +8 -3
- package/lib/core/utils/HttpResponse/decorators.d.ts +8 -3
- package/lib/core/utils/HttpResponse/decorators.js +14 -1
- package/lib/core/utils/HttpResponse/decorators.js.map +1 -1
- package/lib/core/utils/HttpResponse/decorators.mjs +14 -1
- package/lib/core/utils/HttpResponse/decorators.mjs.map +1 -1
- package/lib/core/utils/executeHandlers.d.mts +1 -1
- package/lib/core/utils/executeHandlers.d.ts +1 -1
- package/lib/core/utils/handleRequest.d.mts +1 -1
- package/lib/core/utils/handleRequest.d.ts +1 -1
- package/lib/core/utils/internal/attachSiblingHandlers.d.mts +1 -1
- package/lib/core/utils/internal/attachSiblingHandlers.d.ts +1 -1
- package/lib/core/utils/internal/attachSiblingHandlers.js +1 -1
- package/lib/core/utils/internal/attachSiblingHandlers.js.map +1 -1
- package/lib/core/utils/internal/attachSiblingHandlers.mjs +1 -1
- package/lib/core/utils/internal/attachSiblingHandlers.mjs.map +1 -1
- package/lib/core/utils/internal/isHandlerKind.d.mts +1 -1
- package/lib/core/utils/internal/isHandlerKind.d.ts +1 -1
- package/lib/core/utils/internal/observe-response-body-stream.d.mts +18 -0
- package/lib/core/utils/internal/observe-response-body-stream.d.ts +18 -0
- package/lib/core/utils/internal/observe-response-body-stream.js +64 -0
- package/lib/core/utils/internal/observe-response-body-stream.js.map +1 -0
- package/lib/core/utils/internal/observe-response-body-stream.mjs +44 -0
- package/lib/core/utils/internal/observe-response-body-stream.mjs.map +1 -0
- package/lib/core/utils/internal/parseGraphQLRequest.d.mts +1 -1
- package/lib/core/utils/internal/parseGraphQLRequest.d.ts +1 -1
- package/lib/core/utils/internal/parseMultipartData.d.mts +1 -1
- package/lib/core/utils/internal/parseMultipartData.d.ts +1 -1
- package/lib/core/ws/WebSocketClientManager.js +4 -0
- package/lib/core/ws/WebSocketClientManager.js.map +1 -1
- package/lib/core/ws/WebSocketClientManager.mjs +4 -0
- package/lib/core/ws/WebSocketClientManager.mjs.map +1 -1
- package/lib/core/ws/handleWebSocketEvent.d.mts +1 -1
- package/lib/core/ws/handleWebSocketEvent.d.ts +1 -1
- package/lib/iife/index.js +4668 -1105
- package/lib/iife/index.js.map +1 -1
- package/lib/mockServiceWorker.js +21 -9
- package/package.json +4 -5
- package/src/core/handlers/HttpHandler.test.ts +89 -0
- package/src/core/handlers/RequestHandler.ts +142 -32
- package/src/core/sse.ts +100 -57
- package/src/core/utils/HttpResponse/decorators.ts +23 -2
- package/src/core/utils/internal/observe-response-body-stream.test.ts +64 -0
- package/src/core/utils/internal/observe-response-body-stream.ts +77 -0
- package/src/mockServiceWorker.js +19 -7
|
@@ -30,12 +30,12 @@ var import_interceptors = require("@mswjs/interceptors");
|
|
|
30
30
|
var import_matchRequestUrl = require("../utils/matching/matchRequestUrl");
|
|
31
31
|
var import_getCallFrame = require("../utils/internal/getCallFrame");
|
|
32
32
|
var import_attachWebSocketLogger = require("../ws/utils/attachWebSocketLogger");
|
|
33
|
-
const kEmitter = Symbol("kEmitter");
|
|
34
|
-
const kSender = Symbol("kSender");
|
|
35
|
-
const kConnect = Symbol("kConnect");
|
|
36
|
-
const kAutoConnect = Symbol("kAutoConnect");
|
|
37
|
-
const kStopPropagationPatched = Symbol("kStopPropagationPatched");
|
|
38
|
-
const KOnStopPropagation = Symbol("KOnStopPropagation");
|
|
33
|
+
const kEmitter = /* @__PURE__ */ Symbol("kEmitter");
|
|
34
|
+
const kSender = /* @__PURE__ */ Symbol("kSender");
|
|
35
|
+
const kConnect = /* @__PURE__ */ Symbol("kConnect");
|
|
36
|
+
const kAutoConnect = /* @__PURE__ */ Symbol("kAutoConnect");
|
|
37
|
+
const kStopPropagationPatched = /* @__PURE__ */ Symbol("kStopPropagationPatched");
|
|
38
|
+
const KOnStopPropagation = /* @__PURE__ */ Symbol("KOnStopPropagation");
|
|
39
39
|
class WebSocketHandler {
|
|
40
40
|
constructor(url) {
|
|
41
41
|
this.url = url;
|
|
@@ -43,6 +43,7 @@ class WebSocketHandler {
|
|
|
43
43
|
this[kEmitter] = new import_strict_event_emitter.Emitter();
|
|
44
44
|
this.callFrame = (0, import_getCallFrame.getCallFrame)(new Error());
|
|
45
45
|
}
|
|
46
|
+
url;
|
|
46
47
|
id;
|
|
47
48
|
callFrame;
|
|
48
49
|
kind = "websocket";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/handlers/WebSocketHandler.ts"],"sourcesContent":["import { Emitter } from 'strict-event-emitter'\nimport { createRequestId, resolveWebSocketUrl } from '@mswjs/interceptors'\nimport type {\n WebSocketClientConnectionProtocol,\n WebSocketConnectionData,\n WebSocketServerConnectionProtocol,\n} from '@mswjs/interceptors/WebSocket'\nimport {\n type Match,\n type Path,\n type PathParams,\n matchRequestUrl,\n} from '../utils/matching/matchRequestUrl'\nimport { getCallFrame } from '../utils/internal/getCallFrame'\nimport { attachWebSocketLogger } from '../ws/utils/attachWebSocketLogger'\n\ntype WebSocketHandlerParsedResult = {\n match: Match\n}\n\nexport type WebSocketHandlerEventMap = {\n connection: [args: WebSocketHandlerConnection]\n}\n\nexport interface WebSocketHandlerConnection {\n client: WebSocketClientConnectionProtocol\n server: WebSocketServerConnectionProtocol\n info: WebSocketConnectionData['info']\n params: PathParams\n}\n\nexport interface WebSocketResolutionContext {\n baseUrl?: string\n [kAutoConnect]?: boolean\n}\n\nexport const kEmitter = Symbol('kEmitter')\nexport const kSender = Symbol('kSender')\nexport const kConnect = Symbol('kConnect')\nexport const kAutoConnect = Symbol('kAutoConnect')\n\nconst kStopPropagationPatched = Symbol('kStopPropagationPatched')\nconst KOnStopPropagation = Symbol('KOnStopPropagation')\n\nexport class WebSocketHandler {\n public id: string\n public callFrame?: string\n public kind = 'websocket' as const\n\n protected [kEmitter]: Emitter<WebSocketHandlerEventMap>\n\n constructor(protected readonly url: Path) {\n this.id = createRequestId()\n\n this[kEmitter] = new Emitter()\n this.callFrame = getCallFrame(new Error())\n }\n\n public parse(args: {\n url: string | URL\n resolutionContext?: WebSocketResolutionContext\n }): WebSocketHandlerParsedResult {\n const clientUrl = new URL(args.url)\n\n // Resolve the WebSocket handler path:\n // - Plain string URLs resolved as per the specification (via Interceptors).\n // - String URLs starting with a wildcard are preserved (prepending a scheme there will break them).\n // - RegExp paths are preserved.\n const resolvedHandlerUrl =\n this.url instanceof RegExp || this.url.startsWith('*')\n ? this.url\n : this.#resolveWebSocketUrl(this.url, args.resolutionContext?.baseUrl)\n\n /**\n * @note Remove the Socket.IO path prefix from the WebSocket\n * client URL. This is an exception to keep the users from\n * including the implementation details in their handlers.\n */\n clientUrl.pathname = clientUrl.pathname.replace(/^\\/socket.io\\//, '/')\n\n const match = matchRequestUrl(\n clientUrl,\n resolvedHandlerUrl,\n args.resolutionContext?.baseUrl,\n )\n\n return {\n match,\n }\n }\n\n public predicate(args: {\n url: string | URL\n parsedResult: WebSocketHandlerParsedResult\n }): boolean {\n return args.parsedResult.match.matches\n }\n\n public test(\n url: string | URL,\n resolutionContext?: WebSocketResolutionContext & { strict?: boolean },\n ): boolean {\n return this.#match(url, resolutionContext) != null\n }\n\n public async run(\n connection: WebSocketConnectionData,\n resolutionContext?: WebSocketResolutionContext,\n ): Promise<WebSocketHandlerConnection | null> {\n const parsedResult = this.#match(connection.client.url, resolutionContext)\n\n if (parsedResult == null) {\n return null\n }\n\n const resolvedConnection: WebSocketHandlerConnection = {\n ...connection,\n params: parsedResult.match.params || {},\n }\n\n if (resolutionContext?.[kAutoConnect] ?? true) {\n if (this[kConnect](resolvedConnection)) {\n return resolvedConnection\n }\n\n return null\n }\n\n return resolvedConnection\n }\n\n #match(\n url: string | URL,\n resolutionContext?: WebSocketResolutionContext & { strict?: boolean },\n ): WebSocketHandlerParsedResult | null {\n const resolvedUrl = this.#resolveWebSocketUrl(\n url.toString(),\n resolutionContext?.baseUrl,\n )\n const parsedResult = this.parse({\n url: resolvedUrl,\n resolutionContext,\n })\n\n if (\n this.predicate({\n url,\n parsedResult,\n })\n ) {\n return parsedResult\n }\n\n return null\n }\n\n protected [kConnect](connection: WebSocketHandlerConnection): boolean {\n // Support `event.stopPropagation()` for various client/server events.\n connection.client.addEventListener(\n 'message',\n createStopPropagationListener(this),\n )\n connection.client.addEventListener(\n 'close',\n createStopPropagationListener(this),\n )\n\n connection.server.addEventListener(\n 'open',\n createStopPropagationListener(this),\n )\n connection.server.addEventListener(\n 'message',\n createStopPropagationListener(this),\n )\n connection.server.addEventListener(\n 'error',\n createStopPropagationListener(this),\n )\n connection.server.addEventListener(\n 'close',\n createStopPropagationListener(this),\n )\n\n /**\n * @fixme Use \"rettime\" and await these events to have\n * exceptions propagate properly.\n */\n return this[kEmitter].emit('connection', connection)\n }\n\n public log(connection: WebSocketConnectionData): () => void {\n return attachWebSocketLogger(connection)\n }\n\n #resolveWebSocketUrl(url: string, baseUrl?: string): string {\n const resolvedUrl = resolveWebSocketUrl(\n baseUrl\n ? /**\n * @note Resolve against the base URL preemtively because `resolveWebSocketUrl` only\n * resolves against `location.href`, which is missing in Node.js. Base URL allows\n * the handler to accept a relative URL in Node.js.\n */\n new URL(url, baseUrl)\n : url,\n )\n\n /**\n * @note Omit the trailing slash.\n * While the browser always produces a trailing slash at the end of a WebSocket URL,\n * having it in as the handler's predicate would mean it is *required* in the actual URL.\n */\n return resolvedUrl.replace(/\\/$/, '')\n }\n}\n\nfunction createStopPropagationListener(handler: WebSocketHandler) {\n return function stopPropagationListener(event: Event) {\n const propagationStoppedAt = Reflect.get(event, 'kPropagationStoppedAt') as\n | string\n | undefined\n\n if (propagationStoppedAt && handler.id !== propagationStoppedAt) {\n event.stopImmediatePropagation()\n return\n }\n\n Object.defineProperty(event, KOnStopPropagation, {\n value(this: WebSocketHandler) {\n Object.defineProperty(event, 'kPropagationStoppedAt', {\n value: handler.id,\n })\n },\n configurable: true,\n })\n\n // Since the same event instance is shared between all client/server objects,\n // make sure to patch its `stopPropagation` method only once.\n if (!Reflect.get(event, kStopPropagationPatched)) {\n event.stopPropagation = new Proxy(event.stopPropagation, {\n apply: (target, thisArg, args) => {\n Reflect.get(event, KOnStopPropagation)?.call(handler)\n return Reflect.apply(target, thisArg, args)\n },\n })\n\n Object.defineProperty(event, kStopPropagationPatched, {\n value: true,\n // If something else attempts to redefine this, throw.\n configurable: false,\n })\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/core/handlers/WebSocketHandler.ts"],"sourcesContent":["import { Emitter } from 'strict-event-emitter'\nimport { createRequestId, resolveWebSocketUrl } from '@mswjs/interceptors'\nimport type {\n WebSocketClientConnectionProtocol,\n WebSocketConnectionData,\n WebSocketServerConnectionProtocol,\n} from '@mswjs/interceptors/WebSocket'\nimport {\n type Match,\n type Path,\n type PathParams,\n matchRequestUrl,\n} from '../utils/matching/matchRequestUrl'\nimport { getCallFrame } from '../utils/internal/getCallFrame'\nimport { attachWebSocketLogger } from '../ws/utils/attachWebSocketLogger'\n\ntype WebSocketHandlerParsedResult = {\n match: Match\n}\n\nexport type WebSocketHandlerEventMap = {\n connection: [args: WebSocketHandlerConnection]\n}\n\nexport interface WebSocketHandlerConnection {\n client: WebSocketClientConnectionProtocol\n server: WebSocketServerConnectionProtocol\n info: WebSocketConnectionData['info']\n params: PathParams\n}\n\nexport interface WebSocketResolutionContext {\n baseUrl?: string\n [kAutoConnect]?: boolean\n}\n\nexport const kEmitter = Symbol('kEmitter')\nexport const kSender = Symbol('kSender')\nexport const kConnect = Symbol('kConnect')\nexport const kAutoConnect = Symbol('kAutoConnect')\n\nconst kStopPropagationPatched = Symbol('kStopPropagationPatched')\nconst KOnStopPropagation = Symbol('KOnStopPropagation')\n\nexport class WebSocketHandler {\n public id: string\n public callFrame?: string\n public kind = 'websocket' as const\n\n protected [kEmitter]: Emitter<WebSocketHandlerEventMap>\n\n constructor(protected readonly url: Path) {\n this.id = createRequestId()\n\n this[kEmitter] = new Emitter()\n this.callFrame = getCallFrame(new Error())\n }\n\n public parse(args: {\n url: string | URL\n resolutionContext?: WebSocketResolutionContext\n }): WebSocketHandlerParsedResult {\n const clientUrl = new URL(args.url)\n\n // Resolve the WebSocket handler path:\n // - Plain string URLs resolved as per the specification (via Interceptors).\n // - String URLs starting with a wildcard are preserved (prepending a scheme there will break them).\n // - RegExp paths are preserved.\n const resolvedHandlerUrl =\n this.url instanceof RegExp || this.url.startsWith('*')\n ? this.url\n : this.#resolveWebSocketUrl(this.url, args.resolutionContext?.baseUrl)\n\n /**\n * @note Remove the Socket.IO path prefix from the WebSocket\n * client URL. This is an exception to keep the users from\n * including the implementation details in their handlers.\n */\n clientUrl.pathname = clientUrl.pathname.replace(/^\\/socket.io\\//, '/')\n\n const match = matchRequestUrl(\n clientUrl,\n resolvedHandlerUrl,\n args.resolutionContext?.baseUrl,\n )\n\n return {\n match,\n }\n }\n\n public predicate(args: {\n url: string | URL\n parsedResult: WebSocketHandlerParsedResult\n }): boolean {\n return args.parsedResult.match.matches\n }\n\n public test(\n url: string | URL,\n resolutionContext?: WebSocketResolutionContext & { strict?: boolean },\n ): boolean {\n return this.#match(url, resolutionContext) != null\n }\n\n public async run(\n connection: WebSocketConnectionData,\n resolutionContext?: WebSocketResolutionContext,\n ): Promise<WebSocketHandlerConnection | null> {\n const parsedResult = this.#match(connection.client.url, resolutionContext)\n\n if (parsedResult == null) {\n return null\n }\n\n const resolvedConnection: WebSocketHandlerConnection = {\n ...connection,\n params: parsedResult.match.params || {},\n }\n\n if (resolutionContext?.[kAutoConnect] ?? true) {\n if (this[kConnect](resolvedConnection)) {\n return resolvedConnection\n }\n\n return null\n }\n\n return resolvedConnection\n }\n\n #match(\n url: string | URL,\n resolutionContext?: WebSocketResolutionContext & { strict?: boolean },\n ): WebSocketHandlerParsedResult | null {\n const resolvedUrl = this.#resolveWebSocketUrl(\n url.toString(),\n resolutionContext?.baseUrl,\n )\n const parsedResult = this.parse({\n url: resolvedUrl,\n resolutionContext,\n })\n\n if (\n this.predicate({\n url,\n parsedResult,\n })\n ) {\n return parsedResult\n }\n\n return null\n }\n\n protected [kConnect](connection: WebSocketHandlerConnection): boolean {\n // Support `event.stopPropagation()` for various client/server events.\n connection.client.addEventListener(\n 'message',\n createStopPropagationListener(this),\n )\n connection.client.addEventListener(\n 'close',\n createStopPropagationListener(this),\n )\n\n connection.server.addEventListener(\n 'open',\n createStopPropagationListener(this),\n )\n connection.server.addEventListener(\n 'message',\n createStopPropagationListener(this),\n )\n connection.server.addEventListener(\n 'error',\n createStopPropagationListener(this),\n )\n connection.server.addEventListener(\n 'close',\n createStopPropagationListener(this),\n )\n\n /**\n * @fixme Use \"rettime\" and await these events to have\n * exceptions propagate properly.\n */\n return this[kEmitter].emit('connection', connection)\n }\n\n public log(connection: WebSocketConnectionData): () => void {\n return attachWebSocketLogger(connection)\n }\n\n #resolveWebSocketUrl(url: string, baseUrl?: string): string {\n const resolvedUrl = resolveWebSocketUrl(\n baseUrl\n ? /**\n * @note Resolve against the base URL preemtively because `resolveWebSocketUrl` only\n * resolves against `location.href`, which is missing in Node.js. Base URL allows\n * the handler to accept a relative URL in Node.js.\n */\n new URL(url, baseUrl)\n : url,\n )\n\n /**\n * @note Omit the trailing slash.\n * While the browser always produces a trailing slash at the end of a WebSocket URL,\n * having it in as the handler's predicate would mean it is *required* in the actual URL.\n */\n return resolvedUrl.replace(/\\/$/, '')\n }\n}\n\nfunction createStopPropagationListener(handler: WebSocketHandler) {\n return function stopPropagationListener(event: Event) {\n const propagationStoppedAt = Reflect.get(event, 'kPropagationStoppedAt') as\n | string\n | undefined\n\n if (propagationStoppedAt && handler.id !== propagationStoppedAt) {\n event.stopImmediatePropagation()\n return\n }\n\n Object.defineProperty(event, KOnStopPropagation, {\n value(this: WebSocketHandler) {\n Object.defineProperty(event, 'kPropagationStoppedAt', {\n value: handler.id,\n })\n },\n configurable: true,\n })\n\n // Since the same event instance is shared between all client/server objects,\n // make sure to patch its `stopPropagation` method only once.\n if (!Reflect.get(event, kStopPropagationPatched)) {\n event.stopPropagation = new Proxy(event.stopPropagation, {\n apply: (target, thisArg, args) => {\n Reflect.get(event, KOnStopPropagation)?.call(handler)\n return Reflect.apply(target, thisArg, args)\n },\n })\n\n Object.defineProperty(event, kStopPropagationPatched, {\n value: true,\n // If something else attempts to redefine this, throw.\n configurable: false,\n })\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -5,12 +5,12 @@ import {
|
|
|
5
5
|
} from '../utils/matching/matchRequestUrl.mjs';
|
|
6
6
|
import { getCallFrame } from '../utils/internal/getCallFrame.mjs';
|
|
7
7
|
import { attachWebSocketLogger } from '../ws/utils/attachWebSocketLogger.mjs';
|
|
8
|
-
const kEmitter = Symbol("kEmitter");
|
|
9
|
-
const kSender = Symbol("kSender");
|
|
10
|
-
const kConnect = Symbol("kConnect");
|
|
11
|
-
const kAutoConnect = Symbol("kAutoConnect");
|
|
12
|
-
const kStopPropagationPatched = Symbol("kStopPropagationPatched");
|
|
13
|
-
const KOnStopPropagation = Symbol("KOnStopPropagation");
|
|
8
|
+
const kEmitter = /* @__PURE__ */ Symbol("kEmitter");
|
|
9
|
+
const kSender = /* @__PURE__ */ Symbol("kSender");
|
|
10
|
+
const kConnect = /* @__PURE__ */ Symbol("kConnect");
|
|
11
|
+
const kAutoConnect = /* @__PURE__ */ Symbol("kAutoConnect");
|
|
12
|
+
const kStopPropagationPatched = /* @__PURE__ */ Symbol("kStopPropagationPatched");
|
|
13
|
+
const KOnStopPropagation = /* @__PURE__ */ Symbol("KOnStopPropagation");
|
|
14
14
|
class WebSocketHandler {
|
|
15
15
|
constructor(url) {
|
|
16
16
|
this.url = url;
|
|
@@ -18,6 +18,7 @@ class WebSocketHandler {
|
|
|
18
18
|
this[kEmitter] = new Emitter();
|
|
19
19
|
this.callFrame = getCallFrame(new Error());
|
|
20
20
|
}
|
|
21
|
+
url;
|
|
21
22
|
id;
|
|
22
23
|
callFrame;
|
|
23
24
|
kind = "websocket";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/handlers/WebSocketHandler.ts"],"sourcesContent":["import { Emitter } from 'strict-event-emitter'\nimport { createRequestId, resolveWebSocketUrl } from '@mswjs/interceptors'\nimport type {\n WebSocketClientConnectionProtocol,\n WebSocketConnectionData,\n WebSocketServerConnectionProtocol,\n} from '@mswjs/interceptors/WebSocket'\nimport {\n type Match,\n type Path,\n type PathParams,\n matchRequestUrl,\n} from '../utils/matching/matchRequestUrl'\nimport { getCallFrame } from '../utils/internal/getCallFrame'\nimport { attachWebSocketLogger } from '../ws/utils/attachWebSocketLogger'\n\ntype WebSocketHandlerParsedResult = {\n match: Match\n}\n\nexport type WebSocketHandlerEventMap = {\n connection: [args: WebSocketHandlerConnection]\n}\n\nexport interface WebSocketHandlerConnection {\n client: WebSocketClientConnectionProtocol\n server: WebSocketServerConnectionProtocol\n info: WebSocketConnectionData['info']\n params: PathParams\n}\n\nexport interface WebSocketResolutionContext {\n baseUrl?: string\n [kAutoConnect]?: boolean\n}\n\nexport const kEmitter = Symbol('kEmitter')\nexport const kSender = Symbol('kSender')\nexport const kConnect = Symbol('kConnect')\nexport const kAutoConnect = Symbol('kAutoConnect')\n\nconst kStopPropagationPatched = Symbol('kStopPropagationPatched')\nconst KOnStopPropagation = Symbol('KOnStopPropagation')\n\nexport class WebSocketHandler {\n public id: string\n public callFrame?: string\n public kind = 'websocket' as const\n\n protected [kEmitter]: Emitter<WebSocketHandlerEventMap>\n\n constructor(protected readonly url: Path) {\n this.id = createRequestId()\n\n this[kEmitter] = new Emitter()\n this.callFrame = getCallFrame(new Error())\n }\n\n public parse(args: {\n url: string | URL\n resolutionContext?: WebSocketResolutionContext\n }): WebSocketHandlerParsedResult {\n const clientUrl = new URL(args.url)\n\n // Resolve the WebSocket handler path:\n // - Plain string URLs resolved as per the specification (via Interceptors).\n // - String URLs starting with a wildcard are preserved (prepending a scheme there will break them).\n // - RegExp paths are preserved.\n const resolvedHandlerUrl =\n this.url instanceof RegExp || this.url.startsWith('*')\n ? this.url\n : this.#resolveWebSocketUrl(this.url, args.resolutionContext?.baseUrl)\n\n /**\n * @note Remove the Socket.IO path prefix from the WebSocket\n * client URL. This is an exception to keep the users from\n * including the implementation details in their handlers.\n */\n clientUrl.pathname = clientUrl.pathname.replace(/^\\/socket.io\\//, '/')\n\n const match = matchRequestUrl(\n clientUrl,\n resolvedHandlerUrl,\n args.resolutionContext?.baseUrl,\n )\n\n return {\n match,\n }\n }\n\n public predicate(args: {\n url: string | URL\n parsedResult: WebSocketHandlerParsedResult\n }): boolean {\n return args.parsedResult.match.matches\n }\n\n public test(\n url: string | URL,\n resolutionContext?: WebSocketResolutionContext & { strict?: boolean },\n ): boolean {\n return this.#match(url, resolutionContext) != null\n }\n\n public async run(\n connection: WebSocketConnectionData,\n resolutionContext?: WebSocketResolutionContext,\n ): Promise<WebSocketHandlerConnection | null> {\n const parsedResult = this.#match(connection.client.url, resolutionContext)\n\n if (parsedResult == null) {\n return null\n }\n\n const resolvedConnection: WebSocketHandlerConnection = {\n ...connection,\n params: parsedResult.match.params || {},\n }\n\n if (resolutionContext?.[kAutoConnect] ?? true) {\n if (this[kConnect](resolvedConnection)) {\n return resolvedConnection\n }\n\n return null\n }\n\n return resolvedConnection\n }\n\n #match(\n url: string | URL,\n resolutionContext?: WebSocketResolutionContext & { strict?: boolean },\n ): WebSocketHandlerParsedResult | null {\n const resolvedUrl = this.#resolveWebSocketUrl(\n url.toString(),\n resolutionContext?.baseUrl,\n )\n const parsedResult = this.parse({\n url: resolvedUrl,\n resolutionContext,\n })\n\n if (\n this.predicate({\n url,\n parsedResult,\n })\n ) {\n return parsedResult\n }\n\n return null\n }\n\n protected [kConnect](connection: WebSocketHandlerConnection): boolean {\n // Support `event.stopPropagation()` for various client/server events.\n connection.client.addEventListener(\n 'message',\n createStopPropagationListener(this),\n )\n connection.client.addEventListener(\n 'close',\n createStopPropagationListener(this),\n )\n\n connection.server.addEventListener(\n 'open',\n createStopPropagationListener(this),\n )\n connection.server.addEventListener(\n 'message',\n createStopPropagationListener(this),\n )\n connection.server.addEventListener(\n 'error',\n createStopPropagationListener(this),\n )\n connection.server.addEventListener(\n 'close',\n createStopPropagationListener(this),\n )\n\n /**\n * @fixme Use \"rettime\" and await these events to have\n * exceptions propagate properly.\n */\n return this[kEmitter].emit('connection', connection)\n }\n\n public log(connection: WebSocketConnectionData): () => void {\n return attachWebSocketLogger(connection)\n }\n\n #resolveWebSocketUrl(url: string, baseUrl?: string): string {\n const resolvedUrl = resolveWebSocketUrl(\n baseUrl\n ? /**\n * @note Resolve against the base URL preemtively because `resolveWebSocketUrl` only\n * resolves against `location.href`, which is missing in Node.js. Base URL allows\n * the handler to accept a relative URL in Node.js.\n */\n new URL(url, baseUrl)\n : url,\n )\n\n /**\n * @note Omit the trailing slash.\n * While the browser always produces a trailing slash at the end of a WebSocket URL,\n * having it in as the handler's predicate would mean it is *required* in the actual URL.\n */\n return resolvedUrl.replace(/\\/$/, '')\n }\n}\n\nfunction createStopPropagationListener(handler: WebSocketHandler) {\n return function stopPropagationListener(event: Event) {\n const propagationStoppedAt = Reflect.get(event, 'kPropagationStoppedAt') as\n | string\n | undefined\n\n if (propagationStoppedAt && handler.id !== propagationStoppedAt) {\n event.stopImmediatePropagation()\n return\n }\n\n Object.defineProperty(event, KOnStopPropagation, {\n value(this: WebSocketHandler) {\n Object.defineProperty(event, 'kPropagationStoppedAt', {\n value: handler.id,\n })\n },\n configurable: true,\n })\n\n // Since the same event instance is shared between all client/server objects,\n // make sure to patch its `stopPropagation` method only once.\n if (!Reflect.get(event, kStopPropagationPatched)) {\n event.stopPropagation = new Proxy(event.stopPropagation, {\n apply: (target, thisArg, args) => {\n Reflect.get(event, KOnStopPropagation)?.call(handler)\n return Reflect.apply(target, thisArg, args)\n },\n })\n\n Object.defineProperty(event, kStopPropagationPatched, {\n value: true,\n // If something else attempts to redefine this, throw.\n configurable: false,\n })\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/core/handlers/WebSocketHandler.ts"],"sourcesContent":["import { Emitter } from 'strict-event-emitter'\nimport { createRequestId, resolveWebSocketUrl } from '@mswjs/interceptors'\nimport type {\n WebSocketClientConnectionProtocol,\n WebSocketConnectionData,\n WebSocketServerConnectionProtocol,\n} from '@mswjs/interceptors/WebSocket'\nimport {\n type Match,\n type Path,\n type PathParams,\n matchRequestUrl,\n} from '../utils/matching/matchRequestUrl'\nimport { getCallFrame } from '../utils/internal/getCallFrame'\nimport { attachWebSocketLogger } from '../ws/utils/attachWebSocketLogger'\n\ntype WebSocketHandlerParsedResult = {\n match: Match\n}\n\nexport type WebSocketHandlerEventMap = {\n connection: [args: WebSocketHandlerConnection]\n}\n\nexport interface WebSocketHandlerConnection {\n client: WebSocketClientConnectionProtocol\n server: WebSocketServerConnectionProtocol\n info: WebSocketConnectionData['info']\n params: PathParams\n}\n\nexport interface WebSocketResolutionContext {\n baseUrl?: string\n [kAutoConnect]?: boolean\n}\n\nexport const kEmitter = Symbol('kEmitter')\nexport const kSender = Symbol('kSender')\nexport const kConnect = Symbol('kConnect')\nexport const kAutoConnect = Symbol('kAutoConnect')\n\nconst kStopPropagationPatched = Symbol('kStopPropagationPatched')\nconst KOnStopPropagation = Symbol('KOnStopPropagation')\n\nexport class WebSocketHandler {\n public id: string\n public callFrame?: string\n public kind = 'websocket' as const\n\n protected [kEmitter]: Emitter<WebSocketHandlerEventMap>\n\n constructor(protected readonly url: Path) {\n this.id = createRequestId()\n\n this[kEmitter] = new Emitter()\n this.callFrame = getCallFrame(new Error())\n }\n\n public parse(args: {\n url: string | URL\n resolutionContext?: WebSocketResolutionContext\n }): WebSocketHandlerParsedResult {\n const clientUrl = new URL(args.url)\n\n // Resolve the WebSocket handler path:\n // - Plain string URLs resolved as per the specification (via Interceptors).\n // - String URLs starting with a wildcard are preserved (prepending a scheme there will break them).\n // - RegExp paths are preserved.\n const resolvedHandlerUrl =\n this.url instanceof RegExp || this.url.startsWith('*')\n ? this.url\n : this.#resolveWebSocketUrl(this.url, args.resolutionContext?.baseUrl)\n\n /**\n * @note Remove the Socket.IO path prefix from the WebSocket\n * client URL. This is an exception to keep the users from\n * including the implementation details in their handlers.\n */\n clientUrl.pathname = clientUrl.pathname.replace(/^\\/socket.io\\//, '/')\n\n const match = matchRequestUrl(\n clientUrl,\n resolvedHandlerUrl,\n args.resolutionContext?.baseUrl,\n )\n\n return {\n match,\n }\n }\n\n public predicate(args: {\n url: string | URL\n parsedResult: WebSocketHandlerParsedResult\n }): boolean {\n return args.parsedResult.match.matches\n }\n\n public test(\n url: string | URL,\n resolutionContext?: WebSocketResolutionContext & { strict?: boolean },\n ): boolean {\n return this.#match(url, resolutionContext) != null\n }\n\n public async run(\n connection: WebSocketConnectionData,\n resolutionContext?: WebSocketResolutionContext,\n ): Promise<WebSocketHandlerConnection | null> {\n const parsedResult = this.#match(connection.client.url, resolutionContext)\n\n if (parsedResult == null) {\n return null\n }\n\n const resolvedConnection: WebSocketHandlerConnection = {\n ...connection,\n params: parsedResult.match.params || {},\n }\n\n if (resolutionContext?.[kAutoConnect] ?? true) {\n if (this[kConnect](resolvedConnection)) {\n return resolvedConnection\n }\n\n return null\n }\n\n return resolvedConnection\n }\n\n #match(\n url: string | URL,\n resolutionContext?: WebSocketResolutionContext & { strict?: boolean },\n ): WebSocketHandlerParsedResult | null {\n const resolvedUrl = this.#resolveWebSocketUrl(\n url.toString(),\n resolutionContext?.baseUrl,\n )\n const parsedResult = this.parse({\n url: resolvedUrl,\n resolutionContext,\n })\n\n if (\n this.predicate({\n url,\n parsedResult,\n })\n ) {\n return parsedResult\n }\n\n return null\n }\n\n protected [kConnect](connection: WebSocketHandlerConnection): boolean {\n // Support `event.stopPropagation()` for various client/server events.\n connection.client.addEventListener(\n 'message',\n createStopPropagationListener(this),\n )\n connection.client.addEventListener(\n 'close',\n createStopPropagationListener(this),\n )\n\n connection.server.addEventListener(\n 'open',\n createStopPropagationListener(this),\n )\n connection.server.addEventListener(\n 'message',\n createStopPropagationListener(this),\n )\n connection.server.addEventListener(\n 'error',\n createStopPropagationListener(this),\n )\n connection.server.addEventListener(\n 'close',\n createStopPropagationListener(this),\n )\n\n /**\n * @fixme Use \"rettime\" and await these events to have\n * exceptions propagate properly.\n */\n return this[kEmitter].emit('connection', connection)\n }\n\n public log(connection: WebSocketConnectionData): () => void {\n return attachWebSocketLogger(connection)\n }\n\n #resolveWebSocketUrl(url: string, baseUrl?: string): string {\n const resolvedUrl = resolveWebSocketUrl(\n baseUrl\n ? /**\n * @note Resolve against the base URL preemtively because `resolveWebSocketUrl` only\n * resolves against `location.href`, which is missing in Node.js. Base URL allows\n * the handler to accept a relative URL in Node.js.\n */\n new URL(url, baseUrl)\n : url,\n )\n\n /**\n * @note Omit the trailing slash.\n * While the browser always produces a trailing slash at the end of a WebSocket URL,\n * having it in as the handler's predicate would mean it is *required* in the actual URL.\n */\n return resolvedUrl.replace(/\\/$/, '')\n }\n}\n\nfunction createStopPropagationListener(handler: WebSocketHandler) {\n return function stopPropagationListener(event: Event) {\n const propagationStoppedAt = Reflect.get(event, 'kPropagationStoppedAt') as\n | string\n | undefined\n\n if (propagationStoppedAt && handler.id !== propagationStoppedAt) {\n event.stopImmediatePropagation()\n return\n }\n\n Object.defineProperty(event, KOnStopPropagation, {\n value(this: WebSocketHandler) {\n Object.defineProperty(event, 'kPropagationStoppedAt', {\n value: handler.id,\n })\n },\n configurable: true,\n })\n\n // Since the same event instance is shared between all client/server objects,\n // make sure to patch its `stopPropagation` method only once.\n if (!Reflect.get(event, kStopPropagationPatched)) {\n event.stopPropagation = new Proxy(event.stopPropagation, {\n apply: (target, thisArg, args) => {\n Reflect.get(event, KOnStopPropagation)?.call(handler)\n return Reflect.apply(target, thisArg, args)\n },\n })\n\n Object.defineProperty(event, kStopPropagationPatched, {\n value: true,\n // If something else attempts to redefine this, throw.\n configurable: false,\n })\n }\n }\n}\n"],"mappings":"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","names":[]}
|
package/lib/core/http.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { D as DefaultBodyType,
|
|
1
|
+
import { D as DefaultBodyType, l as ResponseResolver, j as RequestHandlerOptions } from './HttpResponse-BE_Y2Ak9.mjs';
|
|
2
2
|
import { HttpRequestPredicate, HttpRequestResolverExtras, HttpHandler } from './handlers/HttpHandler.mjs';
|
|
3
3
|
import { PathParams } from './utils/matching/matchRequestUrl.mjs';
|
|
4
4
|
import '@mswjs/interceptors';
|
package/lib/core/http.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { D as DefaultBodyType,
|
|
1
|
+
import { D as DefaultBodyType, l as ResponseResolver, j as RequestHandlerOptions } from './HttpResponse-DL-P1EeG.js';
|
|
2
2
|
import { HttpRequestPredicate, HttpRequestResolverExtras, HttpHandler } from './handlers/HttpHandler.js';
|
|
3
3
|
import { PathParams } from './utils/matching/matchRequestUrl.js';
|
|
4
4
|
import '@mswjs/interceptors';
|
package/lib/core/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { SetupApi } from './experimental/setup-api.mjs';
|
|
2
|
-
export { A as AsyncResponseResolverReturnType, D as DefaultBodyType,
|
|
2
|
+
export { A as AsyncResponseResolverReturnType, D as DefaultBodyType, a as DefaultRequestMultipartBody, G as GraphQLCustomPredicate, b as GraphQLHandler, c as GraphQLJsonRequestBody, d as GraphQLOperationType, e as GraphQLQuery, f as GraphQLRequestBody, g as GraphQLResponseBody, h as GraphQLVariables, H as HttpResponse, i as HttpResponseInit, J as JsonBodyType, P as ParsedGraphQLRequest, R as RequestHandler, j as RequestHandlerOptions, k as ResponseResolutionContext, l as ResponseResolver, m as ResponseResolverInfo, n as ResponseResolverReturnType, S as StrictRequest, o as StrictResponse } from './HttpResponse-BE_Y2Ak9.mjs';
|
|
3
3
|
export { HttpRequestHandler, HttpResponseResolver, http } from './http.mjs';
|
|
4
4
|
export { HttpCustomPredicate, HttpHandler, HttpHandlerInfo, HttpHandlerMethod, HttpMethods, HttpRequestParsedResult, HttpRequestResolverExtras, RequestQuery } from './handlers/HttpHandler.mjs';
|
|
5
5
|
export { GraphQLLinkHandlers, GraphQLOperationHandler, GraphQLRequestHandler, GraphQLResponseResolver, graphql } from './graphql.mjs';
|
package/lib/core/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { SetupApi } from './experimental/setup-api.js';
|
|
2
|
-
export { A as AsyncResponseResolverReturnType, D as DefaultBodyType,
|
|
2
|
+
export { A as AsyncResponseResolverReturnType, D as DefaultBodyType, a as DefaultRequestMultipartBody, G as GraphQLCustomPredicate, b as GraphQLHandler, c as GraphQLJsonRequestBody, d as GraphQLOperationType, e as GraphQLQuery, f as GraphQLRequestBody, g as GraphQLResponseBody, h as GraphQLVariables, H as HttpResponse, i as HttpResponseInit, J as JsonBodyType, P as ParsedGraphQLRequest, R as RequestHandler, j as RequestHandlerOptions, k as ResponseResolutionContext, l as ResponseResolver, m as ResponseResolverInfo, n as ResponseResolverReturnType, S as StrictRequest, o as StrictResponse } from './HttpResponse-DL-P1EeG.js';
|
|
3
3
|
export { HttpRequestHandler, HttpResponseResolver, http } from './http.js';
|
|
4
4
|
export { HttpCustomPredicate, HttpHandler, HttpHandlerInfo, HttpHandlerMethod, HttpMethods, HttpRequestParsedResult, HttpRequestResolverExtras, RequestQuery } from './handlers/HttpHandler.js';
|
|
5
5
|
export { GraphQLLinkHandlers, GraphQLOperationHandler, GraphQLRequestHandler, GraphQLResponseResolver, graphql } from './graphql.js';
|
|
@@ -53,4 +53,4 @@ type UnhandledFrameDefaults = {
|
|
|
53
53
|
};
|
|
54
54
|
declare function executeUnhandledFrameHandle(frame: AnyNetworkFrame, handle: UnhandledFrameHandle): Promise<void>;
|
|
55
55
|
|
|
56
|
-
export { type AnyNetworkFrame as A, type ExtractFrameEvents as E, NetworkFrame as N, type UnhandledFrameCallback as U, type NetworkFrameResolutionContext as a, type UnhandledFrameHandle as b, type
|
|
56
|
+
export { type AnyNetworkFrame as A, type ExtractFrameEvents as E, NetworkFrame as N, type UnhandledFrameCallback as U, type NetworkFrameResolutionContext as a, type UnhandledFrameHandle as b, type UnhandledFrameDefaults as c, type UnhandledFrameStrategy as d, executeUnhandledFrameHandle as e };
|
|
@@ -53,4 +53,4 @@ type UnhandledFrameDefaults = {
|
|
|
53
53
|
};
|
|
54
54
|
declare function executeUnhandledFrameHandle(frame: AnyNetworkFrame, handle: UnhandledFrameHandle): Promise<void>;
|
|
55
55
|
|
|
56
|
-
export { type AnyNetworkFrame as A, type ExtractFrameEvents as E, NetworkFrame as N, type UnhandledFrameCallback as U, type NetworkFrameResolutionContext as a, type UnhandledFrameHandle as b, type
|
|
56
|
+
export { type AnyNetworkFrame as A, type ExtractFrameEvents as E, NetworkFrame as N, type UnhandledFrameCallback as U, type NetworkFrameResolutionContext as a, type UnhandledFrameHandle as b, type UnhandledFrameDefaults as c, type UnhandledFrameStrategy as d, executeUnhandledFrameHandle as e };
|
package/lib/core/sse.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { l as ResponseResolver } from './HttpResponse-BE_Y2Ak9.mjs';
|
|
2
2
|
import { HttpRequestResolverExtras, HttpHandler } from './handlers/HttpHandler.mjs';
|
|
3
3
|
import { PathParams, Path } from './utils/matching/matchRequestUrl.mjs';
|
|
4
4
|
import '@mswjs/interceptors';
|
|
@@ -66,7 +66,7 @@ declare class ServerSentEventClient<EventMap extends EventMapConstraint = {
|
|
|
66
66
|
}> {
|
|
67
67
|
#private;
|
|
68
68
|
private [kClientEmitter]?;
|
|
69
|
-
constructor(
|
|
69
|
+
constructor(controller: ReadableStreamDefaultController<Uint8Array>);
|
|
70
70
|
/**
|
|
71
71
|
* Sends the given payload to the intercepted `EventSource`.
|
|
72
72
|
*/
|
package/lib/core/sse.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { l as ResponseResolver } from './HttpResponse-DL-P1EeG.js';
|
|
2
2
|
import { HttpRequestResolverExtras, HttpHandler } from './handlers/HttpHandler.js';
|
|
3
3
|
import { PathParams, Path } from './utils/matching/matchRequestUrl.js';
|
|
4
4
|
import '@mswjs/interceptors';
|
|
@@ -66,7 +66,7 @@ declare class ServerSentEventClient<EventMap extends EventMapConstraint = {
|
|
|
66
66
|
}> {
|
|
67
67
|
#private;
|
|
68
68
|
private [kClientEmitter]?;
|
|
69
|
-
constructor(
|
|
69
|
+
constructor(controller: ReadableStreamDefaultController<Uint8Array>);
|
|
70
70
|
/**
|
|
71
71
|
* Sends the given payload to the intercepted `EventSource`.
|
|
72
72
|
*/
|
package/lib/core/sse.js
CHANGED
|
@@ -23,7 +23,7 @@ __export(sse_exports, {
|
|
|
23
23
|
module.exports = __toCommonJS(sse_exports);
|
|
24
24
|
var import_outvariant = require("outvariant");
|
|
25
25
|
var import_deferred_promise = require("@open-draft/deferred-promise");
|
|
26
|
-
var
|
|
26
|
+
var import_rettime = require("rettime");
|
|
27
27
|
var import_HttpHandler = require("./handlers/HttpHandler");
|
|
28
28
|
var import_delay = require("./delay");
|
|
29
29
|
var import_getTimestamp = require("./utils/logging/getTimestamp");
|
|
@@ -41,7 +41,7 @@ const SSE_RESPONSE_INIT = {
|
|
|
41
41
|
}
|
|
42
42
|
};
|
|
43
43
|
class ServerSentEventHandler extends import_HttpHandler.HttpHandler {
|
|
44
|
-
#
|
|
44
|
+
#loggableRequests;
|
|
45
45
|
constructor(path, resolver) {
|
|
46
46
|
(0, import_outvariant.invariant)(
|
|
47
47
|
typeof EventSource !== "undefined",
|
|
@@ -52,15 +52,20 @@ class ServerSentEventHandler extends import_HttpHandler.HttpHandler {
|
|
|
52
52
|
const { client, server, response } = createEventStream(
|
|
53
53
|
info.request
|
|
54
54
|
);
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
55
|
+
const emitter = new import_rettime.Emitter();
|
|
56
|
+
client[kClientEmitter] = emitter;
|
|
57
|
+
if (this.#loggableRequests.has(info.request)) {
|
|
58
|
+
this.#attachClientLogger(info.request, emitter);
|
|
59
|
+
}
|
|
60
|
+
await resolver(
|
|
61
|
+
Object.assign(info, {
|
|
62
|
+
client,
|
|
63
|
+
server
|
|
64
|
+
})
|
|
65
|
+
);
|
|
61
66
|
return response;
|
|
62
67
|
});
|
|
63
|
-
this.#
|
|
68
|
+
this.#loggableRequests = /* @__PURE__ */ new WeakSet();
|
|
64
69
|
}
|
|
65
70
|
async predicate(args) {
|
|
66
71
|
if (args.request.headers.get("accept") !== "text/event-stream") {
|
|
@@ -76,25 +81,24 @@ class ServerSentEventHandler extends import_HttpHandler.HttpHandler {
|
|
|
76
81
|
*/
|
|
77
82
|
response: new Response("[streaming]", SSE_RESPONSE_INIT)
|
|
78
83
|
});
|
|
79
|
-
this.#
|
|
84
|
+
this.#loggableRequests.add(args.request);
|
|
80
85
|
}
|
|
81
86
|
return matches;
|
|
82
87
|
}
|
|
83
|
-
async log(
|
|
88
|
+
async log(args) {
|
|
89
|
+
args.response.body?.cancel();
|
|
84
90
|
return;
|
|
85
91
|
}
|
|
86
92
|
#attachClientLogger(request, emitter) {
|
|
87
93
|
const publicUrl = (0, import_toPublicUrl.toPublicUrl)(request.url);
|
|
88
|
-
emitter.on("message", (
|
|
94
|
+
emitter.on("message", ({ data }) => {
|
|
89
95
|
console.groupCollapsed(
|
|
90
|
-
import_devUtils.devUtils.formatMessage(
|
|
91
|
-
`${(0, import_getTimestamp.getTimestamp)()} SSE %s %c\u21E3%c ${payload.event}`
|
|
92
|
-
),
|
|
96
|
+
import_devUtils.devUtils.formatMessage(`${(0, import_getTimestamp.getTimestamp)()} SSE %s %c\u21E3%c ${data.event}`),
|
|
93
97
|
publicUrl,
|
|
94
98
|
`color:${import_attachWebSocketLogger.colors.mocked}`,
|
|
95
99
|
"color:inherit"
|
|
96
100
|
);
|
|
97
|
-
console.log(
|
|
101
|
+
console.log(data.frames);
|
|
98
102
|
console.groupEnd();
|
|
99
103
|
});
|
|
100
104
|
emitter.on("error", () => {
|
|
@@ -119,14 +123,16 @@ class ServerSentEventHandler extends import_HttpHandler.HttpHandler {
|
|
|
119
123
|
});
|
|
120
124
|
}
|
|
121
125
|
}
|
|
122
|
-
const kClientEmitter = Symbol.for("kClientEmitter");
|
|
126
|
+
const kClientEmitter = /* @__PURE__ */ Symbol.for("kClientEmitter");
|
|
123
127
|
class ServerSentEventClient {
|
|
124
128
|
[kClientEmitter];
|
|
125
129
|
#encoder;
|
|
126
|
-
#
|
|
127
|
-
|
|
130
|
+
#controller;
|
|
131
|
+
#closed;
|
|
132
|
+
constructor(controller) {
|
|
128
133
|
this.#encoder = new TextEncoder();
|
|
129
|
-
this.#
|
|
134
|
+
this.#controller = controller;
|
|
135
|
+
this.#closed = new import_deferred_promise.DeferredPromise();
|
|
130
136
|
}
|
|
131
137
|
/**
|
|
132
138
|
* Sends the given payload to the intercepted `EventSource`.
|
|
@@ -169,35 +175,44 @@ class ServerSentEventClient {
|
|
|
169
175
|
* error.
|
|
170
176
|
*/
|
|
171
177
|
error() {
|
|
172
|
-
this.#
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
this[kClientEmitter]?.emit("error");
|
|
178
|
+
if (this.#closed.state !== "pending") {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
this.#controller.error();
|
|
182
|
+
this.#closed.resolve();
|
|
183
|
+
this[kClientEmitter]?.emit(new import_rettime.TypedEvent("error"));
|
|
179
184
|
}
|
|
180
185
|
/**
|
|
181
186
|
* Closes the underlying `EventSource`, closing the connection.
|
|
182
187
|
*/
|
|
183
188
|
close() {
|
|
184
|
-
this.#
|
|
189
|
+
if (this.#closed.state !== "pending") {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
try {
|
|
193
|
+
this.#controller.close();
|
|
194
|
+
this.#closed.resolve();
|
|
195
|
+
} catch {
|
|
196
|
+
}
|
|
197
|
+
this[kClientEmitter]?.emit(new import_rettime.TypedEvent("close"));
|
|
198
|
+
}
|
|
199
|
+
#enqueue(chunk) {
|
|
200
|
+
if (this.#closed.state !== "pending") {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
try {
|
|
204
|
+
this.#controller.enqueue(chunk);
|
|
205
|
+
} catch (error) {
|
|
185
206
|
console.error(error);
|
|
186
207
|
import_devUtils.devUtils.error(
|
|
187
|
-
"Failed to
|
|
208
|
+
"Failed to write to server-side EventSource. Please see the original error above."
|
|
188
209
|
);
|
|
189
|
-
}
|
|
190
|
-
this[kClientEmitter]?.emit("close");
|
|
210
|
+
}
|
|
191
211
|
}
|
|
192
212
|
#sendRetry(retry) {
|
|
193
|
-
this.#
|
|
213
|
+
this.#enqueue(this.#encoder.encode(`retry:${retry}
|
|
194
214
|
|
|
195
|
-
`))
|
|
196
|
-
console.error(error);
|
|
197
|
-
import_devUtils.devUtils.error(
|
|
198
|
-
"Failed to send a retry packet to server-side EventSource. Please see the original error above."
|
|
199
|
-
);
|
|
200
|
-
});
|
|
215
|
+
`));
|
|
201
216
|
}
|
|
202
217
|
#sendMessage(message) {
|
|
203
218
|
const frames = [];
|
|
@@ -213,18 +228,17 @@ class ServerSentEventClient {
|
|
|
213
228
|
}
|
|
214
229
|
}
|
|
215
230
|
frames.push("", "");
|
|
216
|
-
this.#
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
});
|
|
231
|
+
this.#enqueue(this.#encoder.encode(frames.join("\n")));
|
|
232
|
+
this[kClientEmitter]?.emit(
|
|
233
|
+
new import_rettime.TypedEvent("message", {
|
|
234
|
+
data: {
|
|
235
|
+
id: message.id,
|
|
236
|
+
event: message.event?.toString() || "message",
|
|
237
|
+
data: message.data,
|
|
238
|
+
frames
|
|
239
|
+
}
|
|
240
|
+
})
|
|
241
|
+
);
|
|
228
242
|
}
|
|
229
243
|
}
|
|
230
244
|
class ServerSentEventServer {
|
|
@@ -283,14 +297,14 @@ class ServerSentEventServer {
|
|
|
283
297
|
return source;
|
|
284
298
|
}
|
|
285
299
|
}
|
|
286
|
-
const kRequest = Symbol("kRequest");
|
|
287
|
-
const kReconnectionTime = Symbol("kReconnectionTime");
|
|
288
|
-
const kLastEventId = Symbol("kLastEventId");
|
|
289
|
-
const kAbortController = Symbol("kAbortController");
|
|
290
|
-
const kOnOpen = Symbol("kOnOpen");
|
|
291
|
-
const kOnMessage = Symbol("kOnMessage");
|
|
292
|
-
const kOnAnyMessage = Symbol("kOnAnyMessage");
|
|
293
|
-
const kOnError = Symbol("kOnError");
|
|
300
|
+
const kRequest = /* @__PURE__ */ Symbol("kRequest");
|
|
301
|
+
const kReconnectionTime = /* @__PURE__ */ Symbol("kReconnectionTime");
|
|
302
|
+
const kLastEventId = /* @__PURE__ */ Symbol("kLastEventId");
|
|
303
|
+
const kAbortController = /* @__PURE__ */ Symbol("kAbortController");
|
|
304
|
+
const kOnOpen = /* @__PURE__ */ Symbol("kOnOpen");
|
|
305
|
+
const kOnMessage = /* @__PURE__ */ Symbol("kOnMessage");
|
|
306
|
+
const kOnAnyMessage = /* @__PURE__ */ Symbol("kOnAnyMessage");
|
|
307
|
+
const kOnError = /* @__PURE__ */ Symbol("kOnError");
|
|
294
308
|
class ObservableEventSource extends EventTarget {
|
|
295
309
|
static CONNECTING = 0;
|
|
296
310
|
static OPEN = 1;
|
|
@@ -527,6 +541,7 @@ class EventSourceParsingStream extends WritableStream {
|
|
|
527
541
|
this.decoder = new TextDecoder();
|
|
528
542
|
this.position = 0;
|
|
529
543
|
}
|
|
544
|
+
underlyingSink;
|
|
530
545
|
decoder;
|
|
531
546
|
buffer;
|
|
532
547
|
position;
|
|
@@ -644,8 +659,16 @@ function createEventStream(request) {
|
|
|
644
659
|
request.method,
|
|
645
660
|
request.url
|
|
646
661
|
);
|
|
647
|
-
|
|
648
|
-
const
|
|
662
|
+
let controller;
|
|
663
|
+
const readable = new ReadableStream({
|
|
664
|
+
start(defaultController) {
|
|
665
|
+
controller = defaultController;
|
|
666
|
+
},
|
|
667
|
+
cancel() {
|
|
668
|
+
client.close();
|
|
669
|
+
}
|
|
670
|
+
});
|
|
671
|
+
const client = new ServerSentEventClient(controller);
|
|
649
672
|
const server = new ServerSentEventServer({
|
|
650
673
|
request,
|
|
651
674
|
client
|