msw 2.2.13 → 2.3.0-ws.rc-2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli/init.js +0 -0
- package/config/scripts/postinstall.js +0 -0
- package/lib/browser/index.d.mts +7 -6
- package/lib/browser/index.d.ts +7 -6
- package/lib/browser/index.js +26 -7
- package/lib/browser/index.js.map +1 -1
- package/lib/browser/index.mjs +26 -7
- package/lib/browser/index.mjs.map +1 -1
- package/lib/core/{GraphQLHandler-bom2Dn82.d.ts → GraphQLHandler-3gvpA65n.d.ts} +1 -1
- package/lib/core/{GraphQLHandler-yJ_I6j54.d.mts → GraphQLHandler-4DPdxG0R.d.mts} +1 -1
- package/lib/core/{HttpResponse-vQNlixkj.d.ts → HttpResponse-aJY-D0oG.d.ts} +2 -2
- package/lib/core/{HttpResponse-3-NyzyF7.d.mts → HttpResponse-xuSipbNt.d.mts} +2 -2
- package/lib/core/HttpResponse.d.mts +1 -1
- package/lib/core/HttpResponse.d.ts +1 -1
- package/lib/core/SetupApi.d.mts +15 -12
- package/lib/core/SetupApi.d.ts +15 -12
- package/lib/core/SetupApi.js +3 -1
- package/lib/core/SetupApi.js.map +1 -1
- package/lib/core/SetupApi.mjs +3 -1
- package/lib/core/SetupApi.mjs.map +1 -1
- package/lib/core/getResponse.d.mts +1 -1
- package/lib/core/getResponse.d.ts +1 -1
- package/lib/core/graphql.d.mts +2 -2
- package/lib/core/graphql.d.ts +2 -2
- package/lib/core/handlers/GraphQLHandler.d.mts +2 -2
- package/lib/core/handlers/GraphQLHandler.d.ts +2 -2
- package/lib/core/handlers/HttpHandler.d.mts +1 -1
- package/lib/core/handlers/HttpHandler.d.ts +1 -1
- package/lib/core/handlers/RequestHandler.d.mts +1 -1
- package/lib/core/handlers/RequestHandler.d.ts +1 -1
- package/lib/core/handlers/WebSocketHandler.d.mts +32 -0
- package/lib/core/handlers/WebSocketHandler.d.ts +32 -0
- package/lib/core/handlers/WebSocketHandler.js +62 -0
- package/lib/core/handlers/WebSocketHandler.js.map +1 -0
- package/lib/core/handlers/WebSocketHandler.mjs +44 -0
- package/lib/core/handlers/WebSocketHandler.mjs.map +1 -0
- package/lib/core/http.d.mts +1 -1
- package/lib/core/http.d.ts +1 -1
- package/lib/core/index.d.mts +5 -2
- package/lib/core/index.d.ts +5 -2
- package/lib/core/index.js +5 -1
- package/lib/core/index.js.map +1 -1
- package/lib/core/index.mjs +7 -1
- package/lib/core/index.mjs.map +1 -1
- package/lib/core/passthrough.d.mts +1 -1
- package/lib/core/passthrough.d.ts +1 -1
- package/lib/core/utils/HttpResponse/decorators.d.mts +1 -1
- package/lib/core/utils/HttpResponse/decorators.d.ts +1 -1
- package/lib/core/utils/executeHandlers.d.mts +1 -1
- package/lib/core/utils/executeHandlers.d.ts +1 -1
- package/lib/core/utils/executeHandlers.js +4 -0
- package/lib/core/utils/executeHandlers.js.map +1 -1
- package/lib/core/utils/executeHandlers.mjs +6 -0
- package/lib/core/utils/executeHandlers.mjs.map +1 -1
- package/lib/core/utils/handleRequest.d.mts +2 -2
- package/lib/core/utils/handleRequest.d.ts +2 -2
- package/lib/core/utils/handleRequest.js.map +1 -1
- package/lib/core/utils/handleRequest.mjs.map +1 -1
- package/lib/core/utils/handleWebSocketEvent.d.mts +16 -0
- package/lib/core/utils/handleWebSocketEvent.d.ts +16 -0
- package/lib/core/utils/handleWebSocketEvent.js +59 -0
- package/lib/core/utils/handleWebSocketEvent.js.map +1 -0
- package/lib/core/utils/handleWebSocketEvent.mjs +39 -0
- package/lib/core/utils/handleWebSocketEvent.mjs.map +1 -0
- package/lib/core/utils/internal/parseGraphQLRequest.d.mts +2 -2
- package/lib/core/utils/internal/parseGraphQLRequest.d.ts +2 -2
- package/lib/core/utils/internal/parseMultipartData.d.mts +1 -1
- package/lib/core/utils/internal/parseMultipartData.d.ts +1 -1
- package/lib/core/utils/internal/requestHandlerUtils.d.mts +1 -1
- package/lib/core/utils/internal/requestHandlerUtils.d.ts +1 -1
- package/lib/core/utils/logging/getTimestamp.d.mts +4 -1
- package/lib/core/utils/logging/getTimestamp.d.ts +4 -1
- package/lib/core/utils/logging/getTimestamp.js +6 -2
- package/lib/core/utils/logging/getTimestamp.js.map +1 -1
- package/lib/core/utils/logging/getTimestamp.mjs +6 -2
- package/lib/core/utils/logging/getTimestamp.mjs.map +1 -1
- package/lib/core/utils/matching/matchRequestUrl.d.mts +2 -1
- package/lib/core/utils/matching/matchRequestUrl.d.ts +2 -1
- package/lib/core/utils/matching/matchRequestUrl.js +4 -0
- package/lib/core/utils/matching/matchRequestUrl.js.map +1 -1
- package/lib/core/utils/matching/matchRequestUrl.mjs +4 -0
- package/lib/core/utils/matching/matchRequestUrl.mjs.map +1 -1
- package/lib/core/ws/WebSocketClientManager.d.mts +64 -0
- package/lib/core/ws/WebSocketClientManager.d.ts +64 -0
- package/lib/core/ws/WebSocketClientManager.js +123 -0
- package/lib/core/ws/WebSocketClientManager.js.map +1 -0
- package/lib/core/ws/WebSocketClientManager.mjs +103 -0
- package/lib/core/ws/WebSocketClientManager.mjs.map +1 -0
- package/lib/core/ws/utils/attachWebSocketLogger.d.mts +34 -0
- package/lib/core/ws/utils/attachWebSocketLogger.d.ts +34 -0
- package/lib/core/ws/utils/attachWebSocketLogger.js +211 -0
- package/lib/core/ws/utils/attachWebSocketLogger.js.map +1 -0
- package/lib/core/ws/utils/attachWebSocketLogger.mjs +191 -0
- package/lib/core/ws/utils/attachWebSocketLogger.mjs.map +1 -0
- package/lib/core/ws/utils/getMessageLength.d.mts +11 -0
- package/lib/core/ws/utils/getMessageLength.d.ts +11 -0
- package/lib/core/ws/utils/getMessageLength.js +33 -0
- package/lib/core/ws/utils/getMessageLength.js.map +1 -0
- package/lib/core/ws/utils/getMessageLength.mjs +13 -0
- package/lib/core/ws/utils/getMessageLength.mjs.map +1 -0
- package/lib/core/ws/utils/getPublicData.d.mts +5 -0
- package/lib/core/ws/utils/getPublicData.d.ts +5 -0
- package/lib/core/ws/utils/getPublicData.js +36 -0
- package/lib/core/ws/utils/getPublicData.js.map +1 -0
- package/lib/core/ws/utils/getPublicData.mjs +16 -0
- package/lib/core/ws/utils/getPublicData.mjs.map +1 -0
- package/lib/core/ws/utils/truncateMessage.d.mts +3 -0
- package/lib/core/ws/utils/truncateMessage.d.ts +3 -0
- package/lib/core/ws/utils/truncateMessage.js +31 -0
- package/lib/core/ws/utils/truncateMessage.js.map +1 -0
- package/lib/core/ws/utils/truncateMessage.mjs +11 -0
- package/lib/core/ws/utils/truncateMessage.mjs.map +1 -0
- package/lib/core/ws/webSocketInterceptor.d.mts +5 -0
- package/lib/core/ws/webSocketInterceptor.d.ts +5 -0
- package/lib/core/ws/webSocketInterceptor.js +26 -0
- package/lib/core/ws/webSocketInterceptor.js.map +1 -0
- package/lib/core/ws/webSocketInterceptor.mjs +6 -0
- package/lib/core/ws/webSocketInterceptor.mjs.map +1 -0
- package/lib/core/ws/ws.d.mts +44 -0
- package/lib/core/ws/ws.d.ts +44 -0
- package/lib/core/ws/ws.js +82 -0
- package/lib/core/ws/ws.js.map +1 -0
- package/lib/core/ws/ws.mjs +65 -0
- package/lib/core/ws/ws.mjs.map +1 -0
- package/lib/iife/index.js +967 -11
- package/lib/iife/index.js.map +1 -1
- package/lib/mockServiceWorker.js +1 -1
- package/lib/native/index.d.mts +6 -5
- package/lib/native/index.d.ts +6 -5
- package/lib/native/index.js +13 -0
- package/lib/native/index.js.map +1 -1
- package/lib/native/index.mjs +13 -0
- package/lib/native/index.mjs.map +1 -1
- package/lib/node/index.d.mts +8 -7
- package/lib/node/index.d.ts +8 -7
- package/lib/node/index.js +13 -0
- package/lib/node/index.js.map +1 -1
- package/lib/node/index.mjs +13 -0
- package/lib/node/index.mjs.map +1 -1
- package/package.json +26 -21
- package/src/browser/setupWorker/glossary.ts +10 -10
- package/src/browser/setupWorker/setupWorker.ts +34 -3
- package/src/core/SetupApi.ts +28 -20
- package/src/core/handlers/WebSocketHandler.ts +71 -0
- package/src/core/index.ts +8 -1
- package/src/core/utils/executeHandlers.ts +6 -2
- package/src/core/utils/handleRequest.ts +1 -2
- package/src/core/utils/handleWebSocketEvent.ts +59 -0
- package/src/core/utils/logging/getTimestamp.test.ts +20 -6
- package/src/core/utils/logging/getTimestamp.ts +11 -6
- package/src/core/utils/matching/matchRequestUrl.test.ts +44 -0
- package/src/core/utils/matching/matchRequestUrl.ts +4 -0
- package/src/core/ws/WebSocketClientManager.test.ts +159 -0
- package/src/core/ws/WebSocketClientManager.ts +170 -0
- package/src/core/ws/utils/attachWebSocketLogger.ts +262 -0
- package/src/core/ws/utils/getMessageLength.test.ts +16 -0
- package/src/core/ws/utils/getMessageLength.ts +19 -0
- package/src/core/ws/utils/getPublicData.test.ts +38 -0
- package/src/core/ws/utils/getPublicData.ts +17 -0
- package/src/core/ws/utils/truncateMessage.test.ts +12 -0
- package/src/core/ws/utils/truncateMessage.ts +9 -0
- package/src/core/ws/webSocketInterceptor.ts +3 -0
- package/src/core/ws/ws.test.ts +23 -0
- package/src/core/ws/ws.ts +108 -0
- package/src/node/SetupServerApi.ts +8 -7
- package/src/node/SetupServerCommonApi.ts +14 -1
- package/src/node/glossary.ts +5 -7
- package/src/node/setupServer.ts +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/core/utils/matching/matchRequestUrl.ts"],"sourcesContent":["import { match } from 'path-to-regexp'\nimport { getCleanUrl } from '@mswjs/interceptors'\nimport { normalizePath } from './normalizePath'\n\nexport type Path = string | RegExp\nexport type PathParams<KeyType extends keyof any = string> = {\n [ParamName in KeyType]: string | ReadonlyArray<string>\n}\n\nexport interface Match {\n matches: boolean\n params?: PathParams\n}\n\n/**\n * Coerce a path supported by MSW into a path\n * supported by \"path-to-regexp\".\n */\nexport function coercePath(path: string): string {\n return (\n path\n /**\n * Replace wildcards (\"*\") with unnamed capturing groups\n * because \"path-to-regexp\" doesn't support wildcards.\n * Ignore path parameter' modifiers (i.e. \":name*\").\n */\n .replace(\n /([:a-zA-Z_-]*)(\\*{1,2})+/g,\n (_, parameterName: string | undefined, wildcard: string) => {\n const expression = '(.*)'\n\n if (!parameterName) {\n return expression\n }\n\n return parameterName.startsWith(':')\n ? `${parameterName}${wildcard}`\n : `${parameterName}${expression}`\n },\n )\n /**\n * Escape the port so that \"path-to-regexp\" can match\n * absolute URLs including port numbers.\n */\n .replace(/([^\\/])(:)(?=\\d+)/, '$1\\\\$2')\n /**\n * Escape the protocol so that \"path-to-regexp\" could match\n * absolute URL.\n * @see https://github.com/pillarjs/path-to-regexp/issues/259\n */\n .replace(/^([^\\/]+)(:)(?=\\/\\/)/, '$1\\\\$2')\n )\n}\n\n/**\n * Returns the result of matching given request URL against a mask.\n */\nexport function matchRequestUrl(url: URL, path: Path, baseUrl?: string): Match {\n const normalizedPath = normalizePath(path, baseUrl)\n const cleanPath =\n typeof normalizedPath === 'string'\n ? coercePath(normalizedPath)\n : normalizedPath\n\n const cleanUrl = getCleanUrl(url)\n const result = match(cleanPath, { decode: decodeURIComponent })(cleanUrl)\n const params = (result && (result.params as PathParams)) || {}\n\n return {\n matches: result !== false,\n params,\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAAsB;AACtB,0BAA4B;AAC5B,2BAA8B;AAgBvB,SAAS,WAAW,MAAsB;AAC/C,SACE,KAMG;AAAA,IACC;AAAA,IACA,CAAC,GAAG,eAAmC,aAAqB;AAC1D,YAAM,aAAa;AAEnB,UAAI,CAAC,eAAe;AAClB,eAAO;AAAA,MACT;AAEA,aAAO,cAAc,WAAW,GAAG,IAC/B,GAAG,aAAa,GAAG,QAAQ,KAC3B,GAAG,aAAa,GAAG,UAAU;AAAA,IACnC;AAAA,EACF,EAKC,QAAQ,qBAAqB,QAAQ,EAMrC,QAAQ,wBAAwB,QAAQ;AAE/C;AAKO,SAAS,gBAAgB,KAAU,MAAY,SAAyB;AAC7E,QAAM,qBAAiB,oCAAc,MAAM,OAAO;AAClD,QAAM,YACJ,OAAO,mBAAmB,WACtB,WAAW,cAAc,IACzB;AAEN,QAAM,eAAW,iCAAY,GAAG;AAChC,QAAM,aAAS,6BAAM,WAAW,EAAE,QAAQ,mBAAmB,CAAC,EAAE,QAAQ;AACxE,QAAM,SAAU,UAAW,OAAO,UAA0B,CAAC;AAE7D,SAAO;AAAA,IACL,SAAS,WAAW;AAAA,IACpB;AAAA,EACF;AACF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/core/utils/matching/matchRequestUrl.ts"],"sourcesContent":["import { match } from 'path-to-regexp'\nimport { getCleanUrl } from '@mswjs/interceptors'\nimport { normalizePath } from './normalizePath'\n\nexport type Path = string | RegExp\nexport type PathParams<KeyType extends keyof any = string> = {\n [ParamName in KeyType]: string | ReadonlyArray<string>\n}\n\nexport interface Match {\n matches: boolean\n params?: PathParams\n}\n\n/**\n * Coerce a path supported by MSW into a path\n * supported by \"path-to-regexp\".\n */\nexport function coercePath(path: string): string {\n return (\n path\n /**\n * Replace wildcards (\"*\") with unnamed capturing groups\n * because \"path-to-regexp\" doesn't support wildcards.\n * Ignore path parameter' modifiers (i.e. \":name*\").\n */\n .replace(\n /([:a-zA-Z_-]*)(\\*{1,2})+/g,\n (_, parameterName: string | undefined, wildcard: string) => {\n const expression = '(.*)'\n\n if (!parameterName) {\n return expression\n }\n\n return parameterName.startsWith(':')\n ? `${parameterName}${wildcard}`\n : `${parameterName}${expression}`\n },\n )\n /**\n * Escape the port so that \"path-to-regexp\" can match\n * absolute URLs including port numbers.\n */\n .replace(/([^\\/])(:)(?=\\d+)/, '$1\\\\$2')\n /**\n * Escape the protocol so that \"path-to-regexp\" could match\n * absolute URL.\n * @see https://github.com/pillarjs/path-to-regexp/issues/259\n */\n .replace(/^([^\\/]+)(:)(?=\\/\\/)/, '$1\\\\$2')\n )\n}\n\n/**\n * Returns the result of matching given request URL against a mask.\n */\nexport function matchRequestUrl(url: URL, path: Path, baseUrl?: string): Match {\n const normalizedPath = normalizePath(path, baseUrl)\n const cleanPath =\n typeof normalizedPath === 'string'\n ? coercePath(normalizedPath)\n : normalizedPath\n\n const cleanUrl = getCleanUrl(url)\n const result = match(cleanPath, { decode: decodeURIComponent })(cleanUrl)\n const params = (result && (result.params as PathParams)) || {}\n\n return {\n matches: result !== false,\n params,\n }\n}\n\nexport function isPath(value: unknown): value is Path {\n return typeof value === 'string' || value instanceof RegExp\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAAsB;AACtB,0BAA4B;AAC5B,2BAA8B;AAgBvB,SAAS,WAAW,MAAsB;AAC/C,SACE,KAMG;AAAA,IACC;AAAA,IACA,CAAC,GAAG,eAAmC,aAAqB;AAC1D,YAAM,aAAa;AAEnB,UAAI,CAAC,eAAe;AAClB,eAAO;AAAA,MACT;AAEA,aAAO,cAAc,WAAW,GAAG,IAC/B,GAAG,aAAa,GAAG,QAAQ,KAC3B,GAAG,aAAa,GAAG,UAAU;AAAA,IACnC;AAAA,EACF,EAKC,QAAQ,qBAAqB,QAAQ,EAMrC,QAAQ,wBAAwB,QAAQ;AAE/C;AAKO,SAAS,gBAAgB,KAAU,MAAY,SAAyB;AAC7E,QAAM,qBAAiB,oCAAc,MAAM,OAAO;AAClD,QAAM,YACJ,OAAO,mBAAmB,WACtB,WAAW,cAAc,IACzB;AAEN,QAAM,eAAW,iCAAY,GAAG;AAChC,QAAM,aAAS,6BAAM,WAAW,EAAE,QAAQ,mBAAmB,CAAC,EAAE,QAAQ;AACxE,QAAM,SAAU,UAAW,OAAO,UAA0B,CAAC;AAE7D,SAAO;AAAA,IACL,SAAS,WAAW;AAAA,IACpB;AAAA,EACF;AACF;AAEO,SAAS,OAAO,OAA+B;AACpD,SAAO,OAAO,UAAU,YAAY,iBAAiB;AACvD;","names":[]}
|
|
@@ -24,8 +24,12 @@ function matchRequestUrl(url, path, baseUrl) {
|
|
|
24
24
|
params
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
|
+
function isPath(value) {
|
|
28
|
+
return typeof value === "string" || value instanceof RegExp;
|
|
29
|
+
}
|
|
27
30
|
export {
|
|
28
31
|
coercePath,
|
|
32
|
+
isPath,
|
|
29
33
|
matchRequestUrl
|
|
30
34
|
};
|
|
31
35
|
//# sourceMappingURL=matchRequestUrl.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/core/utils/matching/matchRequestUrl.ts"],"sourcesContent":["import { match } from 'path-to-regexp'\nimport { getCleanUrl } from '@mswjs/interceptors'\nimport { normalizePath } from './normalizePath'\n\nexport type Path = string | RegExp\nexport type PathParams<KeyType extends keyof any = string> = {\n [ParamName in KeyType]: string | ReadonlyArray<string>\n}\n\nexport interface Match {\n matches: boolean\n params?: PathParams\n}\n\n/**\n * Coerce a path supported by MSW into a path\n * supported by \"path-to-regexp\".\n */\nexport function coercePath(path: string): string {\n return (\n path\n /**\n * Replace wildcards (\"*\") with unnamed capturing groups\n * because \"path-to-regexp\" doesn't support wildcards.\n * Ignore path parameter' modifiers (i.e. \":name*\").\n */\n .replace(\n /([:a-zA-Z_-]*)(\\*{1,2})+/g,\n (_, parameterName: string | undefined, wildcard: string) => {\n const expression = '(.*)'\n\n if (!parameterName) {\n return expression\n }\n\n return parameterName.startsWith(':')\n ? `${parameterName}${wildcard}`\n : `${parameterName}${expression}`\n },\n )\n /**\n * Escape the port so that \"path-to-regexp\" can match\n * absolute URLs including port numbers.\n */\n .replace(/([^\\/])(:)(?=\\d+)/, '$1\\\\$2')\n /**\n * Escape the protocol so that \"path-to-regexp\" could match\n * absolute URL.\n * @see https://github.com/pillarjs/path-to-regexp/issues/259\n */\n .replace(/^([^\\/]+)(:)(?=\\/\\/)/, '$1\\\\$2')\n )\n}\n\n/**\n * Returns the result of matching given request URL against a mask.\n */\nexport function matchRequestUrl(url: URL, path: Path, baseUrl?: string): Match {\n const normalizedPath = normalizePath(path, baseUrl)\n const cleanPath =\n typeof normalizedPath === 'string'\n ? coercePath(normalizedPath)\n : normalizedPath\n\n const cleanUrl = getCleanUrl(url)\n const result = match(cleanPath, { decode: decodeURIComponent })(cleanUrl)\n const params = (result && (result.params as PathParams)) || {}\n\n return {\n matches: result !== false,\n params,\n }\n}\n"],"mappings":"AAAA,SAAS,aAAa;AACtB,SAAS,mBAAmB;AAC5B,SAAS,qBAAqB;AAgBvB,SAAS,WAAW,MAAsB;AAC/C,SACE,KAMG;AAAA,IACC;AAAA,IACA,CAAC,GAAG,eAAmC,aAAqB;AAC1D,YAAM,aAAa;AAEnB,UAAI,CAAC,eAAe;AAClB,eAAO;AAAA,MACT;AAEA,aAAO,cAAc,WAAW,GAAG,IAC/B,GAAG,aAAa,GAAG,QAAQ,KAC3B,GAAG,aAAa,GAAG,UAAU;AAAA,IACnC;AAAA,EACF,EAKC,QAAQ,qBAAqB,QAAQ,EAMrC,QAAQ,wBAAwB,QAAQ;AAE/C;AAKO,SAAS,gBAAgB,KAAU,MAAY,SAAyB;AAC7E,QAAM,iBAAiB,cAAc,MAAM,OAAO;AAClD,QAAM,YACJ,OAAO,mBAAmB,WACtB,WAAW,cAAc,IACzB;AAEN,QAAM,WAAW,YAAY,GAAG;AAChC,QAAM,SAAS,MAAM,WAAW,EAAE,QAAQ,mBAAmB,CAAC,EAAE,QAAQ;AACxE,QAAM,SAAU,UAAW,OAAO,UAA0B,CAAC;AAE7D,SAAO;AAAA,IACL,SAAS,WAAW;AAAA,IACpB;AAAA,EACF;AACF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/core/utils/matching/matchRequestUrl.ts"],"sourcesContent":["import { match } from 'path-to-regexp'\nimport { getCleanUrl } from '@mswjs/interceptors'\nimport { normalizePath } from './normalizePath'\n\nexport type Path = string | RegExp\nexport type PathParams<KeyType extends keyof any = string> = {\n [ParamName in KeyType]: string | ReadonlyArray<string>\n}\n\nexport interface Match {\n matches: boolean\n params?: PathParams\n}\n\n/**\n * Coerce a path supported by MSW into a path\n * supported by \"path-to-regexp\".\n */\nexport function coercePath(path: string): string {\n return (\n path\n /**\n * Replace wildcards (\"*\") with unnamed capturing groups\n * because \"path-to-regexp\" doesn't support wildcards.\n * Ignore path parameter' modifiers (i.e. \":name*\").\n */\n .replace(\n /([:a-zA-Z_-]*)(\\*{1,2})+/g,\n (_, parameterName: string | undefined, wildcard: string) => {\n const expression = '(.*)'\n\n if (!parameterName) {\n return expression\n }\n\n return parameterName.startsWith(':')\n ? `${parameterName}${wildcard}`\n : `${parameterName}${expression}`\n },\n )\n /**\n * Escape the port so that \"path-to-regexp\" can match\n * absolute URLs including port numbers.\n */\n .replace(/([^\\/])(:)(?=\\d+)/, '$1\\\\$2')\n /**\n * Escape the protocol so that \"path-to-regexp\" could match\n * absolute URL.\n * @see https://github.com/pillarjs/path-to-regexp/issues/259\n */\n .replace(/^([^\\/]+)(:)(?=\\/\\/)/, '$1\\\\$2')\n )\n}\n\n/**\n * Returns the result of matching given request URL against a mask.\n */\nexport function matchRequestUrl(url: URL, path: Path, baseUrl?: string): Match {\n const normalizedPath = normalizePath(path, baseUrl)\n const cleanPath =\n typeof normalizedPath === 'string'\n ? coercePath(normalizedPath)\n : normalizedPath\n\n const cleanUrl = getCleanUrl(url)\n const result = match(cleanPath, { decode: decodeURIComponent })(cleanUrl)\n const params = (result && (result.params as PathParams)) || {}\n\n return {\n matches: result !== false,\n params,\n }\n}\n\nexport function isPath(value: unknown): value is Path {\n return typeof value === 'string' || value instanceof RegExp\n}\n"],"mappings":"AAAA,SAAS,aAAa;AACtB,SAAS,mBAAmB;AAC5B,SAAS,qBAAqB;AAgBvB,SAAS,WAAW,MAAsB;AAC/C,SACE,KAMG;AAAA,IACC;AAAA,IACA,CAAC,GAAG,eAAmC,aAAqB;AAC1D,YAAM,aAAa;AAEnB,UAAI,CAAC,eAAe;AAClB,eAAO;AAAA,MACT;AAEA,aAAO,cAAc,WAAW,GAAG,IAC/B,GAAG,aAAa,GAAG,QAAQ,KAC3B,GAAG,aAAa,GAAG,UAAU;AAAA,IACnC;AAAA,EACF,EAKC,QAAQ,qBAAqB,QAAQ,EAMrC,QAAQ,wBAAwB,QAAQ;AAE/C;AAKO,SAAS,gBAAgB,KAAU,MAAY,SAAyB;AAC7E,QAAM,iBAAiB,cAAc,MAAM,OAAO;AAClD,QAAM,YACJ,OAAO,mBAAmB,WACtB,WAAW,cAAc,IACzB;AAEN,QAAM,WAAW,YAAY,GAAG;AAChC,QAAM,SAAS,MAAM,WAAW,EAAE,QAAQ,mBAAmB,CAAC,EAAE,QAAQ;AACxE,QAAM,SAAU,UAAW,OAAO,UAA0B,CAAC;AAE7D,SAAO;AAAA,IACL,SAAS,WAAW;AAAA,IACpB;AAAA,EACF;AACF;AAEO,SAAS,OAAO,OAA+B;AACpD,SAAO,OAAO,UAAU,YAAY,iBAAiB;AACvD;","names":[]}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { WebSocketData, WebSocketClientConnectionProtocol, WebSocketClientConnection } from '@mswjs/interceptors/WebSocket';
|
|
2
|
+
|
|
3
|
+
type WebSocketBroadcastChannelMessage = {
|
|
4
|
+
type: 'connection:open';
|
|
5
|
+
payload: {
|
|
6
|
+
clientId: string;
|
|
7
|
+
url: string;
|
|
8
|
+
};
|
|
9
|
+
} | {
|
|
10
|
+
type: 'extraneous:send';
|
|
11
|
+
payload: {
|
|
12
|
+
clientId: string;
|
|
13
|
+
data: WebSocketData;
|
|
14
|
+
};
|
|
15
|
+
} | {
|
|
16
|
+
type: 'extraneous:close';
|
|
17
|
+
payload: {
|
|
18
|
+
clientId: string;
|
|
19
|
+
code?: number;
|
|
20
|
+
reason?: string;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
declare const kAddByClientId: unique symbol;
|
|
24
|
+
/**
|
|
25
|
+
* A manager responsible for accumulating WebSocket client
|
|
26
|
+
* connections across different browser runtimes.
|
|
27
|
+
*/
|
|
28
|
+
declare class WebSocketClientManager {
|
|
29
|
+
private channel;
|
|
30
|
+
/**
|
|
31
|
+
* All active WebSocket client connections.
|
|
32
|
+
*/
|
|
33
|
+
clients: Set<WebSocketClientConnectionProtocol>;
|
|
34
|
+
constructor(channel: BroadcastChannel);
|
|
35
|
+
/**
|
|
36
|
+
* Adds the given `WebSocket` client connection to the set
|
|
37
|
+
* of all connections. The given connection is always the complete
|
|
38
|
+
* connection object because `addConnection()` is called only
|
|
39
|
+
* for the opened connections in the same runtime.
|
|
40
|
+
*/
|
|
41
|
+
addConnection(client: WebSocketClientConnection): void;
|
|
42
|
+
/**
|
|
43
|
+
* Adds a client connection wrapper to operate with
|
|
44
|
+
* WebSocket client connections in other runtimes.
|
|
45
|
+
*/
|
|
46
|
+
private onRemoteConnection;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* A wrapper class to operate with WebSocket client connections
|
|
50
|
+
* from other runtimes. This class maintains 1-1 public API
|
|
51
|
+
* compatibility to the `WebSocketClientConnection` but relies
|
|
52
|
+
* on the given `BroadcastChannel` to communicate instructions
|
|
53
|
+
* with the client connections from other runtimes.
|
|
54
|
+
*/
|
|
55
|
+
declare class WebSocketRemoteClientConnection implements WebSocketClientConnectionProtocol {
|
|
56
|
+
readonly id: string;
|
|
57
|
+
readonly url: URL;
|
|
58
|
+
private channel;
|
|
59
|
+
constructor(id: string, url: URL, channel: BroadcastChannel);
|
|
60
|
+
send(data: WebSocketData): void;
|
|
61
|
+
close(code?: number | undefined, reason?: string | undefined): void;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export { type WebSocketBroadcastChannelMessage, WebSocketClientManager, WebSocketRemoteClientConnection, kAddByClientId };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { WebSocketData, WebSocketClientConnectionProtocol, WebSocketClientConnection } from '@mswjs/interceptors/WebSocket';
|
|
2
|
+
|
|
3
|
+
type WebSocketBroadcastChannelMessage = {
|
|
4
|
+
type: 'connection:open';
|
|
5
|
+
payload: {
|
|
6
|
+
clientId: string;
|
|
7
|
+
url: string;
|
|
8
|
+
};
|
|
9
|
+
} | {
|
|
10
|
+
type: 'extraneous:send';
|
|
11
|
+
payload: {
|
|
12
|
+
clientId: string;
|
|
13
|
+
data: WebSocketData;
|
|
14
|
+
};
|
|
15
|
+
} | {
|
|
16
|
+
type: 'extraneous:close';
|
|
17
|
+
payload: {
|
|
18
|
+
clientId: string;
|
|
19
|
+
code?: number;
|
|
20
|
+
reason?: string;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
declare const kAddByClientId: unique symbol;
|
|
24
|
+
/**
|
|
25
|
+
* A manager responsible for accumulating WebSocket client
|
|
26
|
+
* connections across different browser runtimes.
|
|
27
|
+
*/
|
|
28
|
+
declare class WebSocketClientManager {
|
|
29
|
+
private channel;
|
|
30
|
+
/**
|
|
31
|
+
* All active WebSocket client connections.
|
|
32
|
+
*/
|
|
33
|
+
clients: Set<WebSocketClientConnectionProtocol>;
|
|
34
|
+
constructor(channel: BroadcastChannel);
|
|
35
|
+
/**
|
|
36
|
+
* Adds the given `WebSocket` client connection to the set
|
|
37
|
+
* of all connections. The given connection is always the complete
|
|
38
|
+
* connection object because `addConnection()` is called only
|
|
39
|
+
* for the opened connections in the same runtime.
|
|
40
|
+
*/
|
|
41
|
+
addConnection(client: WebSocketClientConnection): void;
|
|
42
|
+
/**
|
|
43
|
+
* Adds a client connection wrapper to operate with
|
|
44
|
+
* WebSocket client connections in other runtimes.
|
|
45
|
+
*/
|
|
46
|
+
private onRemoteConnection;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* A wrapper class to operate with WebSocket client connections
|
|
50
|
+
* from other runtimes. This class maintains 1-1 public API
|
|
51
|
+
* compatibility to the `WebSocketClientConnection` but relies
|
|
52
|
+
* on the given `BroadcastChannel` to communicate instructions
|
|
53
|
+
* with the client connections from other runtimes.
|
|
54
|
+
*/
|
|
55
|
+
declare class WebSocketRemoteClientConnection implements WebSocketClientConnectionProtocol {
|
|
56
|
+
readonly id: string;
|
|
57
|
+
readonly url: URL;
|
|
58
|
+
private channel;
|
|
59
|
+
constructor(id: string, url: URL, channel: BroadcastChannel);
|
|
60
|
+
send(data: WebSocketData): void;
|
|
61
|
+
close(code?: number | undefined, reason?: string | undefined): void;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export { type WebSocketBroadcastChannelMessage, WebSocketClientManager, WebSocketRemoteClientConnection, kAddByClientId };
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var WebSocketClientManager_exports = {};
|
|
20
|
+
__export(WebSocketClientManager_exports, {
|
|
21
|
+
WebSocketClientManager: () => WebSocketClientManager,
|
|
22
|
+
WebSocketRemoteClientConnection: () => WebSocketRemoteClientConnection,
|
|
23
|
+
kAddByClientId: () => kAddByClientId
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(WebSocketClientManager_exports);
|
|
26
|
+
const kAddByClientId = Symbol("kAddByClientId");
|
|
27
|
+
class WebSocketClientManager {
|
|
28
|
+
constructor(channel) {
|
|
29
|
+
this.channel = channel;
|
|
30
|
+
this.clients = /* @__PURE__ */ new Set();
|
|
31
|
+
this.channel.addEventListener("message", (message) => {
|
|
32
|
+
const { type, payload } = message.data;
|
|
33
|
+
switch (type) {
|
|
34
|
+
case "connection:open": {
|
|
35
|
+
this.onRemoteConnection(payload.clientId, new URL(payload.url));
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* All active WebSocket client connections.
|
|
43
|
+
*/
|
|
44
|
+
clients;
|
|
45
|
+
/**
|
|
46
|
+
* Adds the given `WebSocket` client connection to the set
|
|
47
|
+
* of all connections. The given connection is always the complete
|
|
48
|
+
* connection object because `addConnection()` is called only
|
|
49
|
+
* for the opened connections in the same runtime.
|
|
50
|
+
*/
|
|
51
|
+
addConnection(client) {
|
|
52
|
+
this.clients.add(client);
|
|
53
|
+
this.channel.postMessage({
|
|
54
|
+
type: "connection:open",
|
|
55
|
+
payload: {
|
|
56
|
+
clientId: client.id,
|
|
57
|
+
url: client.url.toString()
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
const handleExtraneousMessage = (message) => {
|
|
61
|
+
const { type, payload } = message.data;
|
|
62
|
+
if (typeof payload === "object" && "clientId" in payload && payload.clientId !== client.id) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
switch (type) {
|
|
66
|
+
case "extraneous:send": {
|
|
67
|
+
client.send(payload.data);
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
case "extraneous:close": {
|
|
71
|
+
client.close(payload.code, payload.reason);
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
const abortController = new AbortController();
|
|
77
|
+
this.channel.addEventListener("message", handleExtraneousMessage, {
|
|
78
|
+
signal: abortController.signal
|
|
79
|
+
});
|
|
80
|
+
client.addEventListener("close", () => abortController.abort(), {
|
|
81
|
+
once: true
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Adds a client connection wrapper to operate with
|
|
86
|
+
* WebSocket client connections in other runtimes.
|
|
87
|
+
*/
|
|
88
|
+
onRemoteConnection(id, url) {
|
|
89
|
+
this.clients.add(
|
|
90
|
+
// Create a connection-compatible instance that can
|
|
91
|
+
// operate with this client from a different runtime
|
|
92
|
+
// using the BroadcastChannel messages.
|
|
93
|
+
new WebSocketRemoteClientConnection(id, url, this.channel)
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
class WebSocketRemoteClientConnection {
|
|
98
|
+
constructor(id, url, channel) {
|
|
99
|
+
this.id = id;
|
|
100
|
+
this.url = url;
|
|
101
|
+
this.channel = channel;
|
|
102
|
+
}
|
|
103
|
+
send(data) {
|
|
104
|
+
this.channel.postMessage({
|
|
105
|
+
type: "extraneous:send",
|
|
106
|
+
payload: {
|
|
107
|
+
clientId: this.id,
|
|
108
|
+
data
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
close(code, reason) {
|
|
113
|
+
this.channel.postMessage({
|
|
114
|
+
type: "extraneous:close",
|
|
115
|
+
payload: {
|
|
116
|
+
clientId: this.id,
|
|
117
|
+
code,
|
|
118
|
+
reason
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=WebSocketClientManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/core/ws/WebSocketClientManager.ts"],"sourcesContent":["import type {\n WebSocketData,\n WebSocketClientConnection,\n WebSocketClientConnectionProtocol,\n} from '@mswjs/interceptors/WebSocket'\n\nexport type WebSocketBroadcastChannelMessage =\n | {\n type: 'connection:open'\n payload: {\n clientId: string\n url: string\n }\n }\n | {\n type: 'extraneous:send'\n payload: {\n clientId: string\n data: WebSocketData\n }\n }\n | {\n type: 'extraneous:close'\n payload: {\n clientId: string\n code?: number\n reason?: string\n }\n }\n\nexport const kAddByClientId = Symbol('kAddByClientId')\n\n/**\n * A manager responsible for accumulating WebSocket client\n * connections across different browser runtimes.\n */\nexport class WebSocketClientManager {\n /**\n * All active WebSocket client connections.\n */\n public clients: Set<WebSocketClientConnectionProtocol>\n\n constructor(private channel: BroadcastChannel) {\n this.clients = new Set()\n\n this.channel.addEventListener('message', (message) => {\n const { type, payload } = message.data as WebSocketBroadcastChannelMessage\n\n switch (type) {\n case 'connection:open': {\n // When another runtime notifies about a new connection,\n // create a connection wrapper class and add it to the set.\n this.onRemoteConnection(payload.clientId, new URL(payload.url))\n break\n }\n }\n })\n }\n\n /**\n * Adds the given `WebSocket` client connection to the set\n * of all connections. The given connection is always the complete\n * connection object because `addConnection()` is called only\n * for the opened connections in the same runtime.\n */\n public addConnection(client: WebSocketClientConnection): void {\n this.clients.add(client)\n\n // Signal to other runtimes about this connection.\n this.channel.postMessage({\n type: 'connection:open',\n payload: {\n clientId: client.id,\n url: client.url.toString(),\n },\n } as WebSocketBroadcastChannelMessage)\n\n // Instruct the current client how to handle events\n // coming from other runtimes (e.g. when calling `.broadcast()`).\n const handleExtraneousMessage = (\n message: MessageEvent<WebSocketBroadcastChannelMessage>,\n ) => {\n const { type, payload } = message.data\n\n // Ignore broadcasted messages for other clients.\n if (\n typeof payload === 'object' &&\n 'clientId' in payload &&\n payload.clientId !== client.id\n ) {\n return\n }\n\n switch (type) {\n case 'extraneous:send': {\n client.send(payload.data)\n break\n }\n\n case 'extraneous:close': {\n client.close(payload.code, payload.reason)\n break\n }\n }\n }\n\n const abortController = new AbortController()\n\n this.channel.addEventListener('message', handleExtraneousMessage, {\n signal: abortController.signal,\n })\n\n // Once closed, this connection cannot be operated on.\n // This must include the extraneous runtimes as well.\n client.addEventListener('close', () => abortController.abort(), {\n once: true,\n })\n }\n\n /**\n * Adds a client connection wrapper to operate with\n * WebSocket client connections in other runtimes.\n */\n private onRemoteConnection(id: string, url: URL): void {\n this.clients.add(\n // Create a connection-compatible instance that can\n // operate with this client from a different runtime\n // using the BroadcastChannel messages.\n new WebSocketRemoteClientConnection(id, url, this.channel),\n )\n }\n}\n\n/**\n * A wrapper class to operate with WebSocket client connections\n * from other runtimes. This class maintains 1-1 public API\n * compatibility to the `WebSocketClientConnection` but relies\n * on the given `BroadcastChannel` to communicate instructions\n * with the client connections from other runtimes.\n */\nexport class WebSocketRemoteClientConnection\n implements WebSocketClientConnectionProtocol\n{\n constructor(\n public readonly id: string,\n public readonly url: URL,\n private channel: BroadcastChannel,\n ) {}\n\n send(data: WebSocketData): void {\n this.channel.postMessage({\n type: 'extraneous:send',\n payload: {\n clientId: this.id,\n data,\n },\n } as WebSocketBroadcastChannelMessage)\n }\n\n close(code?: number | undefined, reason?: string | undefined): void {\n this.channel.postMessage({\n type: 'extraneous:close',\n payload: {\n clientId: this.id,\n code,\n reason,\n },\n } as WebSocketBroadcastChannelMessage)\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA8BO,MAAM,iBAAiB,OAAO,gBAAgB;AAM9C,MAAM,uBAAuB;AAAA,EAMlC,YAAoB,SAA2B;AAA3B;AAClB,SAAK,UAAU,oBAAI,IAAI;AAEvB,SAAK,QAAQ,iBAAiB,WAAW,CAAC,YAAY;AACpD,YAAM,EAAE,MAAM,QAAQ,IAAI,QAAQ;AAElC,cAAQ,MAAM;AAAA,QACZ,KAAK,mBAAmB;AAGtB,eAAK,mBAAmB,QAAQ,UAAU,IAAI,IAAI,QAAQ,GAAG,CAAC;AAC9D;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAjBO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAyBA,cAAc,QAAyC;AAC5D,SAAK,QAAQ,IAAI,MAAM;AAGvB,SAAK,QAAQ,YAAY;AAAA,MACvB,MAAM;AAAA,MACN,SAAS;AAAA,QACP,UAAU,OAAO;AAAA,QACjB,KAAK,OAAO,IAAI,SAAS;AAAA,MAC3B;AAAA,IACF,CAAqC;AAIrC,UAAM,0BAA0B,CAC9B,YACG;AACH,YAAM,EAAE,MAAM,QAAQ,IAAI,QAAQ;AAGlC,UACE,OAAO,YAAY,YACnB,cAAc,WACd,QAAQ,aAAa,OAAO,IAC5B;AACA;AAAA,MACF;AAEA,cAAQ,MAAM;AAAA,QACZ,KAAK,mBAAmB;AACtB,iBAAO,KAAK,QAAQ,IAAI;AACxB;AAAA,QACF;AAAA,QAEA,KAAK,oBAAoB;AACvB,iBAAO,MAAM,QAAQ,MAAM,QAAQ,MAAM;AACzC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,UAAM,kBAAkB,IAAI,gBAAgB;AAE5C,SAAK,QAAQ,iBAAiB,WAAW,yBAAyB;AAAA,MAChE,QAAQ,gBAAgB;AAAA,IAC1B,CAAC;AAID,WAAO,iBAAiB,SAAS,MAAM,gBAAgB,MAAM,GAAG;AAAA,MAC9D,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,mBAAmB,IAAY,KAAgB;AACrD,SAAK,QAAQ;AAAA;AAAA;AAAA;AAAA,MAIX,IAAI,gCAAgC,IAAI,KAAK,KAAK,OAAO;AAAA,IAC3D;AAAA,EACF;AACF;AASO,MAAM,gCAEb;AAAA,EACE,YACkB,IACA,KACR,SACR;AAHgB;AACA;AACR;AAAA,EACP;AAAA,EAEH,KAAK,MAA2B;AAC9B,SAAK,QAAQ,YAAY;AAAA,MACvB,MAAM;AAAA,MACN,SAAS;AAAA,QACP,UAAU,KAAK;AAAA,QACf;AAAA,MACF;AAAA,IACF,CAAqC;AAAA,EACvC;AAAA,EAEA,MAAM,MAA2B,QAAmC;AAClE,SAAK,QAAQ,YAAY;AAAA,MACvB,MAAM;AAAA,MACN,SAAS;AAAA,QACP,UAAU,KAAK;AAAA,QACf;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAqC;AAAA,EACvC;AACF;","names":[]}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
const kAddByClientId = Symbol("kAddByClientId");
|
|
2
|
+
class WebSocketClientManager {
|
|
3
|
+
constructor(channel) {
|
|
4
|
+
this.channel = channel;
|
|
5
|
+
this.clients = /* @__PURE__ */ new Set();
|
|
6
|
+
this.channel.addEventListener("message", (message) => {
|
|
7
|
+
const { type, payload } = message.data;
|
|
8
|
+
switch (type) {
|
|
9
|
+
case "connection:open": {
|
|
10
|
+
this.onRemoteConnection(payload.clientId, new URL(payload.url));
|
|
11
|
+
break;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* All active WebSocket client connections.
|
|
18
|
+
*/
|
|
19
|
+
clients;
|
|
20
|
+
/**
|
|
21
|
+
* Adds the given `WebSocket` client connection to the set
|
|
22
|
+
* of all connections. The given connection is always the complete
|
|
23
|
+
* connection object because `addConnection()` is called only
|
|
24
|
+
* for the opened connections in the same runtime.
|
|
25
|
+
*/
|
|
26
|
+
addConnection(client) {
|
|
27
|
+
this.clients.add(client);
|
|
28
|
+
this.channel.postMessage({
|
|
29
|
+
type: "connection:open",
|
|
30
|
+
payload: {
|
|
31
|
+
clientId: client.id,
|
|
32
|
+
url: client.url.toString()
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
const handleExtraneousMessage = (message) => {
|
|
36
|
+
const { type, payload } = message.data;
|
|
37
|
+
if (typeof payload === "object" && "clientId" in payload && payload.clientId !== client.id) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
switch (type) {
|
|
41
|
+
case "extraneous:send": {
|
|
42
|
+
client.send(payload.data);
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
case "extraneous:close": {
|
|
46
|
+
client.close(payload.code, payload.reason);
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
const abortController = new AbortController();
|
|
52
|
+
this.channel.addEventListener("message", handleExtraneousMessage, {
|
|
53
|
+
signal: abortController.signal
|
|
54
|
+
});
|
|
55
|
+
client.addEventListener("close", () => abortController.abort(), {
|
|
56
|
+
once: true
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Adds a client connection wrapper to operate with
|
|
61
|
+
* WebSocket client connections in other runtimes.
|
|
62
|
+
*/
|
|
63
|
+
onRemoteConnection(id, url) {
|
|
64
|
+
this.clients.add(
|
|
65
|
+
// Create a connection-compatible instance that can
|
|
66
|
+
// operate with this client from a different runtime
|
|
67
|
+
// using the BroadcastChannel messages.
|
|
68
|
+
new WebSocketRemoteClientConnection(id, url, this.channel)
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
class WebSocketRemoteClientConnection {
|
|
73
|
+
constructor(id, url, channel) {
|
|
74
|
+
this.id = id;
|
|
75
|
+
this.url = url;
|
|
76
|
+
this.channel = channel;
|
|
77
|
+
}
|
|
78
|
+
send(data) {
|
|
79
|
+
this.channel.postMessage({
|
|
80
|
+
type: "extraneous:send",
|
|
81
|
+
payload: {
|
|
82
|
+
clientId: this.id,
|
|
83
|
+
data
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
close(code, reason) {
|
|
88
|
+
this.channel.postMessage({
|
|
89
|
+
type: "extraneous:close",
|
|
90
|
+
payload: {
|
|
91
|
+
clientId: this.id,
|
|
92
|
+
code,
|
|
93
|
+
reason
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
export {
|
|
99
|
+
WebSocketClientManager,
|
|
100
|
+
WebSocketRemoteClientConnection,
|
|
101
|
+
kAddByClientId
|
|
102
|
+
};
|
|
103
|
+
//# sourceMappingURL=WebSocketClientManager.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/core/ws/WebSocketClientManager.ts"],"sourcesContent":["import type {\n WebSocketData,\n WebSocketClientConnection,\n WebSocketClientConnectionProtocol,\n} from '@mswjs/interceptors/WebSocket'\n\nexport type WebSocketBroadcastChannelMessage =\n | {\n type: 'connection:open'\n payload: {\n clientId: string\n url: string\n }\n }\n | {\n type: 'extraneous:send'\n payload: {\n clientId: string\n data: WebSocketData\n }\n }\n | {\n type: 'extraneous:close'\n payload: {\n clientId: string\n code?: number\n reason?: string\n }\n }\n\nexport const kAddByClientId = Symbol('kAddByClientId')\n\n/**\n * A manager responsible for accumulating WebSocket client\n * connections across different browser runtimes.\n */\nexport class WebSocketClientManager {\n /**\n * All active WebSocket client connections.\n */\n public clients: Set<WebSocketClientConnectionProtocol>\n\n constructor(private channel: BroadcastChannel) {\n this.clients = new Set()\n\n this.channel.addEventListener('message', (message) => {\n const { type, payload } = message.data as WebSocketBroadcastChannelMessage\n\n switch (type) {\n case 'connection:open': {\n // When another runtime notifies about a new connection,\n // create a connection wrapper class and add it to the set.\n this.onRemoteConnection(payload.clientId, new URL(payload.url))\n break\n }\n }\n })\n }\n\n /**\n * Adds the given `WebSocket` client connection to the set\n * of all connections. The given connection is always the complete\n * connection object because `addConnection()` is called only\n * for the opened connections in the same runtime.\n */\n public addConnection(client: WebSocketClientConnection): void {\n this.clients.add(client)\n\n // Signal to other runtimes about this connection.\n this.channel.postMessage({\n type: 'connection:open',\n payload: {\n clientId: client.id,\n url: client.url.toString(),\n },\n } as WebSocketBroadcastChannelMessage)\n\n // Instruct the current client how to handle events\n // coming from other runtimes (e.g. when calling `.broadcast()`).\n const handleExtraneousMessage = (\n message: MessageEvent<WebSocketBroadcastChannelMessage>,\n ) => {\n const { type, payload } = message.data\n\n // Ignore broadcasted messages for other clients.\n if (\n typeof payload === 'object' &&\n 'clientId' in payload &&\n payload.clientId !== client.id\n ) {\n return\n }\n\n switch (type) {\n case 'extraneous:send': {\n client.send(payload.data)\n break\n }\n\n case 'extraneous:close': {\n client.close(payload.code, payload.reason)\n break\n }\n }\n }\n\n const abortController = new AbortController()\n\n this.channel.addEventListener('message', handleExtraneousMessage, {\n signal: abortController.signal,\n })\n\n // Once closed, this connection cannot be operated on.\n // This must include the extraneous runtimes as well.\n client.addEventListener('close', () => abortController.abort(), {\n once: true,\n })\n }\n\n /**\n * Adds a client connection wrapper to operate with\n * WebSocket client connections in other runtimes.\n */\n private onRemoteConnection(id: string, url: URL): void {\n this.clients.add(\n // Create a connection-compatible instance that can\n // operate with this client from a different runtime\n // using the BroadcastChannel messages.\n new WebSocketRemoteClientConnection(id, url, this.channel),\n )\n }\n}\n\n/**\n * A wrapper class to operate with WebSocket client connections\n * from other runtimes. This class maintains 1-1 public API\n * compatibility to the `WebSocketClientConnection` but relies\n * on the given `BroadcastChannel` to communicate instructions\n * with the client connections from other runtimes.\n */\nexport class WebSocketRemoteClientConnection\n implements WebSocketClientConnectionProtocol\n{\n constructor(\n public readonly id: string,\n public readonly url: URL,\n private channel: BroadcastChannel,\n ) {}\n\n send(data: WebSocketData): void {\n this.channel.postMessage({\n type: 'extraneous:send',\n payload: {\n clientId: this.id,\n data,\n },\n } as WebSocketBroadcastChannelMessage)\n }\n\n close(code?: number | undefined, reason?: string | undefined): void {\n this.channel.postMessage({\n type: 'extraneous:close',\n payload: {\n clientId: this.id,\n code,\n reason,\n },\n } as WebSocketBroadcastChannelMessage)\n }\n}\n"],"mappings":"AA8BO,MAAM,iBAAiB,OAAO,gBAAgB;AAM9C,MAAM,uBAAuB;AAAA,EAMlC,YAAoB,SAA2B;AAA3B;AAClB,SAAK,UAAU,oBAAI,IAAI;AAEvB,SAAK,QAAQ,iBAAiB,WAAW,CAAC,YAAY;AACpD,YAAM,EAAE,MAAM,QAAQ,IAAI,QAAQ;AAElC,cAAQ,MAAM;AAAA,QACZ,KAAK,mBAAmB;AAGtB,eAAK,mBAAmB,QAAQ,UAAU,IAAI,IAAI,QAAQ,GAAG,CAAC;AAC9D;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAjBO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAyBA,cAAc,QAAyC;AAC5D,SAAK,QAAQ,IAAI,MAAM;AAGvB,SAAK,QAAQ,YAAY;AAAA,MACvB,MAAM;AAAA,MACN,SAAS;AAAA,QACP,UAAU,OAAO;AAAA,QACjB,KAAK,OAAO,IAAI,SAAS;AAAA,MAC3B;AAAA,IACF,CAAqC;AAIrC,UAAM,0BAA0B,CAC9B,YACG;AACH,YAAM,EAAE,MAAM,QAAQ,IAAI,QAAQ;AAGlC,UACE,OAAO,YAAY,YACnB,cAAc,WACd,QAAQ,aAAa,OAAO,IAC5B;AACA;AAAA,MACF;AAEA,cAAQ,MAAM;AAAA,QACZ,KAAK,mBAAmB;AACtB,iBAAO,KAAK,QAAQ,IAAI;AACxB;AAAA,QACF;AAAA,QAEA,KAAK,oBAAoB;AACvB,iBAAO,MAAM,QAAQ,MAAM,QAAQ,MAAM;AACzC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,UAAM,kBAAkB,IAAI,gBAAgB;AAE5C,SAAK,QAAQ,iBAAiB,WAAW,yBAAyB;AAAA,MAChE,QAAQ,gBAAgB;AAAA,IAC1B,CAAC;AAID,WAAO,iBAAiB,SAAS,MAAM,gBAAgB,MAAM,GAAG;AAAA,MAC9D,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,mBAAmB,IAAY,KAAgB;AACrD,SAAK,QAAQ;AAAA;AAAA;AAAA;AAAA,MAIX,IAAI,gCAAgC,IAAI,KAAK,KAAK,OAAO;AAAA,IAC3D;AAAA,EACF;AACF;AASO,MAAM,gCAEb;AAAA,EACE,YACkB,IACA,KACR,SACR;AAHgB;AACA;AACR;AAAA,EACP;AAAA,EAEH,KAAK,MAA2B;AAC9B,SAAK,QAAQ,YAAY;AAAA,MACvB,MAAM;AAAA,MACN,SAAS;AAAA,QACP,UAAU,KAAK;AAAA,QACf;AAAA,MACF;AAAA,IACF,CAAqC;AAAA,EACvC;AAAA,EAEA,MAAM,MAA2B,QAAmC;AAClE,SAAK,QAAQ,YAAY;AAAA,MACvB,MAAM;AAAA,MACN,SAAS;AAAA,QACP,UAAU,KAAK;AAAA,QACf;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAqC;AAAA,EACvC;AACF;","names":[]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { WebSocketConnectionData, WebSocketClientConnection, WebSocketData } from '@mswjs/interceptors/WebSocket';
|
|
2
|
+
|
|
3
|
+
declare function attachWebSocketLogger(connection: WebSocketConnectionData): void;
|
|
4
|
+
/**
|
|
5
|
+
* Prints the WebSocket connection.
|
|
6
|
+
* This is meant to be logged by every WebSocket handler
|
|
7
|
+
* that intercepted this connection. This helps you see
|
|
8
|
+
* what handlers observe this connection.
|
|
9
|
+
*/
|
|
10
|
+
declare function logConnectionOpen(client: WebSocketClientConnection): void;
|
|
11
|
+
/**
|
|
12
|
+
* Prints the outgoing client message.
|
|
13
|
+
*/
|
|
14
|
+
declare function logOutgoingClientMessage(event: MessageEvent<WebSocketData>): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Prints the outgoing client message initiated
|
|
17
|
+
* by `server.send()` in the event handler.
|
|
18
|
+
*/
|
|
19
|
+
declare function logOutgoingMockedClientMessage(event: MessageEvent<WebSocketData>): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Prings the message received by the WebSocket client.
|
|
22
|
+
* This is fired when the "message" event is dispatched
|
|
23
|
+
* on the actual WebSocket client instance, and translates to
|
|
24
|
+
* the client receiving a message from the server.
|
|
25
|
+
*/
|
|
26
|
+
declare function logIncomingClientMessage(event: MessageEvent<WebSocketData>): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Prints the outgoing client message initiated
|
|
29
|
+
* by `client.send()` in the event handler.
|
|
30
|
+
*/
|
|
31
|
+
declare function logIncomingMockedClientMessage(event: MessageEvent<WebSocketData>): Promise<void>;
|
|
32
|
+
declare function logIncomingServerMessage(event: MessageEvent<WebSocketData>): Promise<void>;
|
|
33
|
+
|
|
34
|
+
export { attachWebSocketLogger, logConnectionOpen, logIncomingClientMessage, logIncomingMockedClientMessage, logIncomingServerMessage, logOutgoingClientMessage, logOutgoingMockedClientMessage };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { WebSocketConnectionData, WebSocketClientConnection, WebSocketData } from '@mswjs/interceptors/WebSocket';
|
|
2
|
+
|
|
3
|
+
declare function attachWebSocketLogger(connection: WebSocketConnectionData): void;
|
|
4
|
+
/**
|
|
5
|
+
* Prints the WebSocket connection.
|
|
6
|
+
* This is meant to be logged by every WebSocket handler
|
|
7
|
+
* that intercepted this connection. This helps you see
|
|
8
|
+
* what handlers observe this connection.
|
|
9
|
+
*/
|
|
10
|
+
declare function logConnectionOpen(client: WebSocketClientConnection): void;
|
|
11
|
+
/**
|
|
12
|
+
* Prints the outgoing client message.
|
|
13
|
+
*/
|
|
14
|
+
declare function logOutgoingClientMessage(event: MessageEvent<WebSocketData>): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Prints the outgoing client message initiated
|
|
17
|
+
* by `server.send()` in the event handler.
|
|
18
|
+
*/
|
|
19
|
+
declare function logOutgoingMockedClientMessage(event: MessageEvent<WebSocketData>): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Prings the message received by the WebSocket client.
|
|
22
|
+
* This is fired when the "message" event is dispatched
|
|
23
|
+
* on the actual WebSocket client instance, and translates to
|
|
24
|
+
* the client receiving a message from the server.
|
|
25
|
+
*/
|
|
26
|
+
declare function logIncomingClientMessage(event: MessageEvent<WebSocketData>): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Prints the outgoing client message initiated
|
|
29
|
+
* by `client.send()` in the event handler.
|
|
30
|
+
*/
|
|
31
|
+
declare function logIncomingMockedClientMessage(event: MessageEvent<WebSocketData>): Promise<void>;
|
|
32
|
+
declare function logIncomingServerMessage(event: MessageEvent<WebSocketData>): Promise<void>;
|
|
33
|
+
|
|
34
|
+
export { attachWebSocketLogger, logConnectionOpen, logIncomingClientMessage, logIncomingMockedClientMessage, logIncomingServerMessage, logOutgoingClientMessage, logOutgoingMockedClientMessage };
|