msw 2.12.13 → 2.13.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.
Files changed (272) hide show
  1. package/lib/browser/index.d.mts +29 -19
  2. package/lib/browser/index.d.ts +29 -19
  3. package/lib/browser/index.js +1763 -1321
  4. package/lib/browser/index.js.map +1 -1
  5. package/lib/browser/index.mjs +1769 -1321
  6. package/lib/browser/index.mjs.map +1 -1
  7. package/lib/core/{HttpResponse-Dj6ibgFJ.d.ts → HttpResponse-CksOMVAa.d.ts} +5 -5
  8. package/lib/core/{HttpResponse-Be4eT3x6.d.mts → HttpResponse-DlRR1D-f.d.mts} +5 -5
  9. package/lib/core/HttpResponse.d.mts +1 -1
  10. package/lib/core/HttpResponse.d.ts +1 -1
  11. package/lib/core/experimental/compat.d.mts +17 -0
  12. package/lib/core/experimental/compat.d.ts +17 -0
  13. package/lib/core/experimental/compat.js +54 -0
  14. package/lib/core/experimental/compat.js.map +1 -0
  15. package/lib/core/experimental/compat.mjs +36 -0
  16. package/lib/core/experimental/compat.mjs.map +1 -0
  17. package/lib/core/experimental/define-network.d.mts +75 -0
  18. package/lib/core/experimental/define-network.d.ts +75 -0
  19. package/lib/core/experimental/define-network.js +124 -0
  20. package/lib/core/experimental/define-network.js.map +1 -0
  21. package/lib/core/experimental/define-network.mjs +107 -0
  22. package/lib/core/experimental/define-network.mjs.map +1 -0
  23. package/lib/core/experimental/frames/http-frame.d.mts +77 -0
  24. package/lib/core/experimental/frames/http-frame.d.ts +77 -0
  25. package/lib/core/experimental/frames/http-frame.js +194 -0
  26. package/lib/core/experimental/frames/http-frame.js.map +1 -0
  27. package/lib/core/experimental/frames/http-frame.mjs +176 -0
  28. package/lib/core/experimental/frames/http-frame.mjs.map +1 -0
  29. package/lib/core/experimental/frames/network-frame.d.mts +12 -0
  30. package/lib/core/experimental/frames/network-frame.d.ts +12 -0
  31. package/lib/core/{handlers/common.js → experimental/frames/network-frame.js} +19 -3
  32. package/lib/core/experimental/frames/network-frame.js.map +1 -0
  33. package/lib/core/experimental/frames/network-frame.mjs +13 -0
  34. package/lib/core/experimental/frames/network-frame.mjs.map +1 -0
  35. package/lib/core/experimental/frames/websocket-frame.d.mts +55 -0
  36. package/lib/core/experimental/frames/websocket-frame.d.ts +55 -0
  37. package/lib/core/experimental/frames/websocket-frame.js +129 -0
  38. package/lib/core/experimental/frames/websocket-frame.js.map +1 -0
  39. package/lib/core/experimental/frames/websocket-frame.mjs +116 -0
  40. package/lib/core/experimental/frames/websocket-frame.mjs.map +1 -0
  41. package/lib/core/experimental/handlers-controller.d.mts +35 -0
  42. package/lib/core/experimental/handlers-controller.d.ts +35 -0
  43. package/lib/core/experimental/handlers-controller.js +121 -0
  44. package/lib/core/experimental/handlers-controller.js.map +1 -0
  45. package/lib/core/experimental/handlers-controller.mjs +101 -0
  46. package/lib/core/experimental/handlers-controller.mjs.map +1 -0
  47. package/lib/core/experimental/index.d.mts +17 -0
  48. package/lib/core/experimental/index.d.ts +17 -0
  49. package/lib/core/experimental/index.js +36 -0
  50. package/lib/core/experimental/index.js.map +1 -0
  51. package/lib/core/experimental/index.mjs +20 -0
  52. package/lib/core/experimental/index.mjs.map +1 -0
  53. package/lib/core/experimental/on-unhandled-frame.d.mts +12 -0
  54. package/lib/core/experimental/on-unhandled-frame.d.ts +12 -0
  55. package/lib/core/experimental/on-unhandled-frame.js +90 -0
  56. package/lib/core/experimental/on-unhandled-frame.js.map +1 -0
  57. package/lib/core/experimental/on-unhandled-frame.mjs +70 -0
  58. package/lib/core/experimental/on-unhandled-frame.mjs.map +1 -0
  59. package/lib/core/experimental/request-utils.d.mts +12 -0
  60. package/lib/core/experimental/request-utils.d.ts +12 -0
  61. package/lib/core/experimental/request-utils.js +50 -0
  62. package/lib/core/experimental/request-utils.js.map +1 -0
  63. package/lib/core/experimental/request-utils.mjs +30 -0
  64. package/lib/core/experimental/request-utils.mjs.map +1 -0
  65. package/lib/core/experimental/setup-api.d.mts +33 -0
  66. package/lib/core/experimental/setup-api.d.ts +33 -0
  67. package/lib/core/experimental/setup-api.js +61 -0
  68. package/lib/core/experimental/setup-api.js.map +1 -0
  69. package/lib/core/experimental/setup-api.mjs +43 -0
  70. package/lib/core/experimental/setup-api.mjs.map +1 -0
  71. package/lib/core/experimental/sources/interceptor-source.d.mts +28 -0
  72. package/lib/core/experimental/sources/interceptor-source.d.ts +28 -0
  73. package/lib/core/experimental/sources/interceptor-source.js +142 -0
  74. package/lib/core/experimental/sources/interceptor-source.js.map +1 -0
  75. package/lib/core/experimental/sources/interceptor-source.mjs +124 -0
  76. package/lib/core/experimental/sources/interceptor-source.mjs.map +1 -0
  77. package/lib/core/experimental/sources/network-source.d.mts +31 -0
  78. package/lib/core/experimental/sources/network-source.d.ts +31 -0
  79. package/lib/core/experimental/sources/network-source.js +50 -0
  80. package/lib/core/experimental/sources/network-source.js.map +1 -0
  81. package/lib/core/experimental/sources/network-source.mjs +30 -0
  82. package/lib/core/experimental/sources/network-source.mjs.map +1 -0
  83. package/lib/core/getResponse.d.mts +1 -1
  84. package/lib/core/getResponse.d.ts +1 -1
  85. package/lib/core/graphql.d.mts +1 -1
  86. package/lib/core/graphql.d.ts +1 -1
  87. package/lib/core/handlers/GraphQLHandler.d.mts +1 -1
  88. package/lib/core/handlers/GraphQLHandler.d.ts +1 -1
  89. package/lib/core/handlers/HttpHandler.d.mts +1 -1
  90. package/lib/core/handlers/HttpHandler.d.ts +1 -1
  91. package/lib/core/handlers/RequestHandler.d.mts +1 -1
  92. package/lib/core/handlers/RequestHandler.d.ts +1 -1
  93. package/lib/core/handlers/RequestHandler.js +5 -6
  94. package/lib/core/handlers/RequestHandler.js.map +1 -1
  95. package/lib/core/handlers/RequestHandler.mjs +5 -6
  96. package/lib/core/handlers/RequestHandler.mjs.map +1 -1
  97. package/lib/core/handlers/WebSocketHandler.d.mts +8 -4
  98. package/lib/core/handlers/WebSocketHandler.d.ts +8 -4
  99. package/lib/core/handlers/WebSocketHandler.js +18 -5
  100. package/lib/core/handlers/WebSocketHandler.js.map +1 -1
  101. package/lib/core/handlers/WebSocketHandler.mjs +18 -5
  102. package/lib/core/handlers/WebSocketHandler.mjs.map +1 -1
  103. package/lib/core/http.d.mts +1 -1
  104. package/lib/core/http.d.ts +1 -1
  105. package/lib/core/index.d.mts +7 -12
  106. package/lib/core/index.d.ts +7 -12
  107. package/lib/core/index.js +2 -2
  108. package/lib/core/index.js.map +1 -1
  109. package/lib/core/index.mjs +1 -1
  110. package/lib/core/index.mjs.map +1 -1
  111. package/lib/core/network-frame-B7A0ggXE.d.mts +56 -0
  112. package/lib/core/network-frame-usYiHS0K.d.ts +56 -0
  113. package/lib/core/passthrough.d.mts +1 -1
  114. package/lib/core/passthrough.d.ts +1 -1
  115. package/lib/core/sharedOptions.d.mts +6 -2
  116. package/lib/core/sharedOptions.d.ts +6 -2
  117. package/lib/core/sharedOptions.js.map +1 -1
  118. package/lib/core/sse.d.mts +1 -1
  119. package/lib/core/sse.d.ts +1 -1
  120. package/lib/core/sse.js.map +1 -1
  121. package/lib/core/sse.mjs.map +1 -1
  122. package/lib/core/utils/HttpResponse/decorators.d.mts +1 -1
  123. package/lib/core/utils/HttpResponse/decorators.d.ts +1 -1
  124. package/lib/core/utils/cookieStore.js.map +1 -1
  125. package/lib/core/utils/cookieStore.mjs.map +1 -1
  126. package/lib/core/utils/executeHandlers.d.mts +1 -1
  127. package/lib/core/utils/executeHandlers.d.ts +1 -1
  128. package/lib/core/utils/handleRequest.d.mts +2 -1
  129. package/lib/core/utils/handleRequest.d.ts +2 -1
  130. package/lib/core/utils/internal/isHandlerKind.d.mts +3 -3
  131. package/lib/core/utils/internal/isHandlerKind.d.ts +3 -3
  132. package/lib/core/utils/internal/isHandlerKind.js +2 -1
  133. package/lib/core/utils/internal/isHandlerKind.js.map +1 -1
  134. package/lib/core/utils/internal/isHandlerKind.mjs +2 -1
  135. package/lib/core/utils/internal/isHandlerKind.mjs.map +1 -1
  136. package/lib/core/utils/internal/parseGraphQLRequest.d.mts +1 -1
  137. package/lib/core/utils/internal/parseGraphQLRequest.d.ts +1 -1
  138. package/lib/core/utils/internal/parseMultipartData.d.mts +1 -1
  139. package/lib/core/utils/internal/parseMultipartData.d.ts +1 -1
  140. package/lib/core/utils/internal/requestHandlerUtils.d.mts +1 -1
  141. package/lib/core/utils/internal/requestHandlerUtils.d.ts +1 -1
  142. package/lib/core/utils/matching/matchRequestUrl.js +1 -1
  143. package/lib/core/utils/matching/matchRequestUrl.js.map +1 -1
  144. package/lib/core/utils/matching/matchRequestUrl.mjs +1 -1
  145. package/lib/core/utils/matching/matchRequestUrl.mjs.map +1 -1
  146. package/lib/core/utils/request/onUnhandledRequest.d.mts +2 -2
  147. package/lib/core/utils/request/onUnhandledRequest.d.ts +2 -2
  148. package/lib/core/utils/request/onUnhandledRequest.js.map +1 -1
  149. package/lib/core/utils/request/onUnhandledRequest.mjs.map +1 -1
  150. package/lib/core/ws/handleWebSocketEvent.d.mts +1 -1
  151. package/lib/core/ws/handleWebSocketEvent.d.ts +1 -1
  152. package/lib/core/ws/handleWebSocketEvent.js +1 -1
  153. package/lib/core/ws/handleWebSocketEvent.js.map +1 -1
  154. package/lib/core/ws/handleWebSocketEvent.mjs +1 -1
  155. package/lib/core/ws/handleWebSocketEvent.mjs.map +1 -1
  156. package/lib/core/ws/utils/attachWebSocketLogger.d.mts +1 -1
  157. package/lib/core/ws/utils/attachWebSocketLogger.d.ts +1 -1
  158. package/lib/core/ws/utils/attachWebSocketLogger.js +39 -10
  159. package/lib/core/ws/utils/attachWebSocketLogger.js.map +1 -1
  160. package/lib/core/ws/utils/attachWebSocketLogger.mjs +39 -10
  161. package/lib/core/ws/utils/attachWebSocketLogger.mjs.map +1 -1
  162. package/lib/core/ws.d.mts +3 -3
  163. package/lib/core/ws.d.ts +3 -3
  164. package/lib/core/ws.js.map +1 -1
  165. package/lib/core/ws.mjs.map +1 -1
  166. package/lib/iife/index.js +2022 -1433
  167. package/lib/iife/index.js.map +1 -1
  168. package/lib/mockServiceWorker.js +1 -1
  169. package/lib/native/index.d.mts +21 -29
  170. package/lib/native/index.d.ts +21 -29
  171. package/lib/native/index.js +48 -116
  172. package/lib/native/index.js.map +1 -1
  173. package/lib/native/index.mjs +51 -118
  174. package/lib/native/index.mjs.map +1 -1
  175. package/lib/node/index.d.mts +55 -33
  176. package/lib/node/index.d.ts +55 -33
  177. package/lib/node/index.js +152 -154
  178. package/lib/node/index.js.map +1 -1
  179. package/lib/node/index.mjs +156 -156
  180. package/lib/node/index.mjs.map +1 -1
  181. package/package.json +10 -2
  182. package/src/browser/{setupWorker/glossary.ts → glossary.ts} +16 -33
  183. package/src/browser/index.ts +2 -3
  184. package/src/browser/{setupWorker/setupWorker.node.test.ts → setup-worker.node.test.ts} +2 -4
  185. package/src/browser/setup-worker.ts +148 -0
  186. package/src/browser/sources/fallback-http-source.ts +56 -0
  187. package/src/browser/sources/service-worker-source.ts +455 -0
  188. package/src/browser/tsconfig.browser.json +7 -2
  189. package/src/browser/utils/deserializeRequest.ts +1 -1
  190. package/src/browser/{setupWorker/start/utils/getWorkerByRegistration.ts → utils/get-worker-by-registration.ts} +3 -1
  191. package/src/browser/{setupWorker/start/utils/getWorkerInstance.ts → utils/get-worker-instance.ts} +4 -4
  192. package/src/browser/utils/pruneGetRequestBody.test.ts +1 -3
  193. package/src/browser/utils/pruneGetRequestBody.ts +1 -1
  194. package/src/browser/utils/validate-worker-scope.ts +19 -0
  195. package/src/browser/utils/workerChannel.ts +2 -2
  196. package/src/core/experimental/compat.ts +50 -0
  197. package/src/core/experimental/define-network.test.ts +124 -0
  198. package/src/core/experimental/define-network.ts +215 -0
  199. package/src/core/experimental/frames/http-frame.test.ts +360 -0
  200. package/src/core/experimental/frames/http-frame.ts +271 -0
  201. package/src/core/experimental/frames/network-frame.ts +64 -0
  202. package/src/core/experimental/frames/websocket-frame.test.ts +280 -0
  203. package/src/core/experimental/frames/websocket-frame.ts +188 -0
  204. package/src/core/experimental/handlers-controller.test.ts +198 -0
  205. package/src/core/experimental/handlers-controller.ts +145 -0
  206. package/src/core/experimental/index.ts +16 -0
  207. package/src/core/experimental/on-unhandled-frame.test.ts +360 -0
  208. package/src/core/experimental/on-unhandled-frame.ts +110 -0
  209. package/src/core/experimental/request-utils.test.ts +70 -0
  210. package/src/core/experimental/request-utils.ts +39 -0
  211. package/src/core/experimental/setup-api.ts +59 -0
  212. package/src/core/experimental/sources/interceptor-source.ts +185 -0
  213. package/src/core/experimental/sources/network-source.test.ts +74 -0
  214. package/src/core/experimental/sources/network-source.ts +56 -0
  215. package/src/core/handlers/RequestHandler.ts +9 -10
  216. package/src/core/handlers/WebSocketHandler.ts +27 -11
  217. package/src/core/index.ts +3 -7
  218. package/src/core/sharedOptions.ts +9 -4
  219. package/src/core/sse.ts +1 -1
  220. package/src/core/utils/cookieStore.ts +2 -1
  221. package/src/core/utils/internal/isHandlerKind.test.ts +20 -22
  222. package/src/core/utils/internal/isHandlerKind.ts +5 -9
  223. package/src/core/utils/matching/matchRequestUrl.test.ts +87 -3
  224. package/src/core/utils/matching/matchRequestUrl.ts +2 -2
  225. package/src/core/utils/request/onUnhandledRequest.ts +2 -2
  226. package/src/core/ws/WebSocketClientManager.test.ts +2 -10
  227. package/src/core/ws/handleWebSocketEvent.ts +5 -1
  228. package/src/core/ws/utils/attachWebSocketLogger.ts +43 -11
  229. package/src/core/ws.test.ts +1 -3
  230. package/src/core/ws.ts +6 -6
  231. package/src/iife/index.ts +1 -1
  232. package/src/native/index.ts +34 -11
  233. package/src/node/async-handlers-controller.test.ts +50 -0
  234. package/src/node/async-handlers-controller.ts +69 -0
  235. package/src/node/glossary.ts +19 -18
  236. package/src/node/index.ts +6 -2
  237. package/src/node/setup-server-common.ts +100 -0
  238. package/src/node/setup-server.ts +91 -0
  239. package/src/tsconfig.core.json +8 -0
  240. package/src/tsconfig.node.json +8 -3
  241. package/src/tsconfig.src.json +0 -2
  242. package/src/tsconfig.worker.json +2 -1
  243. package/lib/core/SetupApi.d.mts +0 -44
  244. package/lib/core/SetupApi.d.ts +0 -44
  245. package/lib/core/SetupApi.js +0 -112
  246. package/lib/core/SetupApi.js.map +0 -1
  247. package/lib/core/SetupApi.mjs +0 -92
  248. package/lib/core/SetupApi.mjs.map +0 -1
  249. package/lib/core/handlers/common.d.mts +0 -3
  250. package/lib/core/handlers/common.d.ts +0 -3
  251. package/lib/core/handlers/common.js.map +0 -1
  252. package/lib/core/handlers/common.mjs +0 -1
  253. package/lib/core/handlers/common.mjs.map +0 -1
  254. package/src/browser/setupWorker/setupWorker.ts +0 -184
  255. package/src/browser/setupWorker/start/createFallbackRequestListener.ts +0 -71
  256. package/src/browser/setupWorker/start/createRequestListener.ts +0 -138
  257. package/src/browser/setupWorker/start/createResponseListener.ts +0 -57
  258. package/src/browser/setupWorker/start/createStartHandler.ts +0 -137
  259. package/src/browser/setupWorker/start/utils/enableMocking.ts +0 -30
  260. package/src/browser/setupWorker/start/utils/prepareStartHandler.test.ts +0 -59
  261. package/src/browser/setupWorker/start/utils/prepareStartHandler.ts +0 -44
  262. package/src/browser/setupWorker/start/utils/printStartMessage.test.ts +0 -84
  263. package/src/browser/setupWorker/start/utils/printStartMessage.ts +0 -51
  264. package/src/browser/setupWorker/start/utils/validateWorkerScope.ts +0 -18
  265. package/src/browser/setupWorker/stop/utils/printStopMessage.test.ts +0 -26
  266. package/src/browser/setupWorker/stop/utils/printStopMessage.ts +0 -13
  267. package/src/browser/utils/checkWorkerIntegrity.ts +0 -42
  268. package/src/core/SetupApi.ts +0 -127
  269. package/src/core/handlers/common.ts +0 -1
  270. package/src/node/SetupServerApi.ts +0 -87
  271. package/src/node/SetupServerCommonApi.ts +0 -169
  272. package/src/node/setupServer.ts +0 -15
@@ -5,7 +5,7 @@ import {
5
5
  import { isHandlerKind } from '../utils/internal/isHandlerKind.mjs';
6
6
  function handleWebSocketEvent(options) {
7
7
  webSocketInterceptor.on("connection", async (connection) => {
8
- const handlers = options.getHandlers().filter(isHandlerKind("EventHandler"));
8
+ const handlers = options.getHandlers().filter(isHandlerKind("websocket"));
9
9
  if (handlers.length > 0) {
10
10
  options?.onMockedConnection(connection);
11
11
  await Promise.all(
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/ws/handleWebSocketEvent.ts"],"sourcesContent":["import type { WebSocketConnectionData } from '@mswjs/interceptors/WebSocket'\nimport { RequestHandler } from '../handlers/RequestHandler'\nimport { WebSocketHandler } from '../handlers/WebSocketHandler'\nimport { webSocketInterceptor } from './webSocketInterceptor'\nimport {\n onUnhandledRequest,\n UnhandledRequestStrategy,\n} from '../utils/request/onUnhandledRequest'\nimport { isHandlerKind } from '../utils/internal/isHandlerKind'\n\ninterface HandleWebSocketEventOptions {\n getUnhandledRequestStrategy: () => UnhandledRequestStrategy\n getHandlers: () => Array<RequestHandler | WebSocketHandler>\n onMockedConnection: (connection: WebSocketConnectionData) => void\n onPassthroughConnection: (onnection: WebSocketConnectionData) => void\n}\n\nexport function handleWebSocketEvent(options: HandleWebSocketEventOptions) {\n webSocketInterceptor.on('connection', async (connection) => {\n const handlers = options.getHandlers().filter(isHandlerKind('EventHandler'))\n\n // Ignore this connection if the user hasn't defined any handlers.\n if (handlers.length > 0) {\n options?.onMockedConnection(connection)\n\n await Promise.all(\n handlers.map((handler) => {\n // Iterate over the handlers and forward the connection\n // event to WebSocket event handlers. This is equivalent\n // to dispatching that event onto multiple listeners.\n return handler.run(connection)\n }),\n )\n\n return\n }\n\n // Construct a request representing this WebSocket connection.\n const request = new Request(connection.client.url, {\n headers: {\n upgrade: 'websocket',\n connection: 'upgrade',\n },\n })\n await onUnhandledRequest(\n request,\n options.getUnhandledRequestStrategy(),\n ).catch((error) => {\n const errorEvent = new Event('error')\n Object.defineProperty(errorEvent, 'cause', {\n enumerable: true,\n configurable: false,\n value: error,\n })\n connection.client.socket.dispatchEvent(errorEvent)\n })\n\n options?.onPassthroughConnection(connection)\n\n // If none of the \"ws\" handlers matched,\n // establish the WebSocket connection as-is.\n connection.server.connect()\n })\n}\n"],"mappings":"AAGA,SAAS,4BAA4B;AACrC;AAAA,EACE;AAAA,OAEK;AACP,SAAS,qBAAqB;AASvB,SAAS,qBAAqB,SAAsC;AACzE,uBAAqB,GAAG,cAAc,OAAO,eAAe;AAC1D,UAAM,WAAW,QAAQ,YAAY,EAAE,OAAO,cAAc,cAAc,CAAC;AAG3E,QAAI,SAAS,SAAS,GAAG;AACvB,eAAS,mBAAmB,UAAU;AAEtC,YAAM,QAAQ;AAAA,QACZ,SAAS,IAAI,CAAC,YAAY;AAIxB,iBAAO,QAAQ,IAAI,UAAU;AAAA,QAC/B,CAAC;AAAA,MACH;AAEA;AAAA,IACF;AAGA,UAAM,UAAU,IAAI,QAAQ,WAAW,OAAO,KAAK;AAAA,MACjD,SAAS;AAAA,QACP,SAAS;AAAA,QACT,YAAY;AAAA,MACd;AAAA,IACF,CAAC;AACD,UAAM;AAAA,MACJ;AAAA,MACA,QAAQ,4BAA4B;AAAA,IACtC,EAAE,MAAM,CAAC,UAAU;AACjB,YAAM,aAAa,IAAI,MAAM,OAAO;AACpC,aAAO,eAAe,YAAY,SAAS;AAAA,QACzC,YAAY;AAAA,QACZ,cAAc;AAAA,QACd,OAAO;AAAA,MACT,CAAC;AACD,iBAAW,OAAO,OAAO,cAAc,UAAU;AAAA,IACnD,CAAC;AAED,aAAS,wBAAwB,UAAU;AAI3C,eAAW,OAAO,QAAQ;AAAA,EAC5B,CAAC;AACH;","names":[]}
1
+ {"version":3,"sources":["../../../src/core/ws/handleWebSocketEvent.ts"],"sourcesContent":["import type { WebSocketConnectionData } from '@mswjs/interceptors/WebSocket'\nimport { RequestHandler } from '../handlers/RequestHandler'\nimport { WebSocketHandler } from '../handlers/WebSocketHandler'\nimport { webSocketInterceptor } from './webSocketInterceptor'\nimport {\n onUnhandledRequest,\n UnhandledRequestStrategy,\n} from '../utils/request/onUnhandledRequest'\nimport { isHandlerKind } from '../utils/internal/isHandlerKind'\n\ninterface HandleWebSocketEventOptions {\n getUnhandledRequestStrategy: () => UnhandledRequestStrategy\n getHandlers: () => Array<RequestHandler | WebSocketHandler>\n onMockedConnection: (connection: WebSocketConnectionData) => void\n onPassthroughConnection: (onnection: WebSocketConnectionData) => void\n}\n\nexport function handleWebSocketEvent(options: HandleWebSocketEventOptions) {\n webSocketInterceptor.on('connection', async (connection) => {\n /**\n * @todo @fixme Reference the handlers controller here and use `.getHandlersByKind`.\n * That one relies on the pre-grouped handlers map and will be more performant.\n */\n const handlers = options.getHandlers().filter(isHandlerKind('websocket'))\n\n // Ignore this connection if the user hasn't defined any handlers.\n if (handlers.length > 0) {\n options?.onMockedConnection(connection)\n\n await Promise.all(\n handlers.map((handler) => {\n // Iterate over the handlers and forward the connection\n // event to WebSocket event handlers. This is equivalent\n // to dispatching that event onto multiple listeners.\n return handler.run(connection)\n }),\n )\n\n return\n }\n\n // Construct a request representing this WebSocket connection.\n const request = new Request(connection.client.url, {\n headers: {\n upgrade: 'websocket',\n connection: 'upgrade',\n },\n })\n await onUnhandledRequest(\n request,\n options.getUnhandledRequestStrategy(),\n ).catch((error) => {\n const errorEvent = new Event('error')\n Object.defineProperty(errorEvent, 'cause', {\n enumerable: true,\n configurable: false,\n value: error,\n })\n connection.client.socket.dispatchEvent(errorEvent)\n })\n\n options?.onPassthroughConnection(connection)\n\n // If none of the \"ws\" handlers matched,\n // establish the WebSocket connection as-is.\n connection.server.connect()\n })\n}\n"],"mappings":"AAGA,SAAS,4BAA4B;AACrC;AAAA,EACE;AAAA,OAEK;AACP,SAAS,qBAAqB;AASvB,SAAS,qBAAqB,SAAsC;AACzE,uBAAqB,GAAG,cAAc,OAAO,eAAe;AAK1D,UAAM,WAAW,QAAQ,YAAY,EAAE,OAAO,cAAc,WAAW,CAAC;AAGxE,QAAI,SAAS,SAAS,GAAG;AACvB,eAAS,mBAAmB,UAAU;AAEtC,YAAM,QAAQ;AAAA,QACZ,SAAS,IAAI,CAAC,YAAY;AAIxB,iBAAO,QAAQ,IAAI,UAAU;AAAA,QAC/B,CAAC;AAAA,MACH;AAEA;AAAA,IACF;AAGA,UAAM,UAAU,IAAI,QAAQ,WAAW,OAAO,KAAK;AAAA,MACjD,SAAS;AAAA,QACP,SAAS;AAAA,QACT,YAAY;AAAA,MACd;AAAA,IACF,CAAC;AACD,UAAM;AAAA,MACJ;AAAA,MACA,QAAQ,4BAA4B;AAAA,IACtC,EAAE,MAAM,CAAC,UAAU;AACjB,YAAM,aAAa,IAAI,MAAM,OAAO;AACpC,aAAO,eAAe,YAAY,SAAS;AAAA,QACzC,YAAY;AAAA,QACZ,cAAc;AAAA,QACd,OAAO;AAAA,MACT,CAAC;AACD,iBAAW,OAAO,OAAO,cAAc,UAAU;AAAA,IACnD,CAAC;AAED,aAAS,wBAAwB,UAAU;AAI3C,eAAW,OAAO,QAAQ;AAAA,EAC5B,CAAC;AACH;","names":[]}
@@ -6,7 +6,7 @@ declare const colors: {
6
6
  incoming: string;
7
7
  mocked: string;
8
8
  };
9
- declare function attachWebSocketLogger(connection: WebSocketConnectionData): void;
9
+ declare function attachWebSocketLogger(connection: WebSocketConnectionData): () => void;
10
10
  /**
11
11
  * Prints the WebSocket connection.
12
12
  * This is meant to be logged by every WebSocket handler
@@ -6,7 +6,7 @@ declare const colors: {
6
6
  incoming: string;
7
7
  mocked: string;
8
8
  };
9
- declare function attachWebSocketLogger(connection: WebSocketConnectionData): void;
9
+ declare function attachWebSocketLogger(connection: WebSocketConnectionData): () => void;
10
10
  /**
11
11
  * Prints the WebSocket connection.
12
12
  * This is meant to be logged by every WebSocket handler
@@ -36,16 +36,30 @@ const colors = {
36
36
  };
37
37
  function attachWebSocketLogger(connection) {
38
38
  const { client, server } = connection;
39
+ const controller = new AbortController();
39
40
  logConnectionOpen(client);
40
- client.addEventListener("message", (event) => {
41
- logOutgoingClientMessage(event);
42
- });
43
- client.addEventListener("close", (event) => {
44
- logConnectionClose(event);
45
- });
46
- client.socket.addEventListener("error", (event) => {
47
- logClientError(event);
48
- });
41
+ client.addEventListener(
42
+ "message",
43
+ (event) => {
44
+ logOutgoingClientMessage(event);
45
+ },
46
+ { signal: controller.signal }
47
+ );
48
+ client.addEventListener(
49
+ "close",
50
+ (event) => {
51
+ logConnectionClose(event);
52
+ },
53
+ { signal: controller.signal }
54
+ );
55
+ client.socket.addEventListener(
56
+ "error",
57
+ (event) => {
58
+ logClientError(event);
59
+ },
60
+ { signal: controller.signal }
61
+ );
62
+ const { send: originalClientSend } = client;
49
63
  client.send = new Proxy(client.send, {
50
64
  apply(target, thisArg, args) {
51
65
  const [data] = args;
@@ -75,8 +89,12 @@ function attachWebSocketLogger(connection) {
75
89
  logIncomingServerMessage(event);
76
90
  });
77
91
  },
78
- { once: true }
92
+ {
93
+ once: true,
94
+ signal: controller.signal
95
+ }
79
96
  );
97
+ const { send: originalServerSend } = server;
80
98
  server.send = new Proxy(server.send, {
81
99
  apply(target, thisArg, args) {
82
100
  const [data] = args;
@@ -97,6 +115,17 @@ function attachWebSocketLogger(connection) {
97
115
  return Reflect.apply(target, thisArg, args);
98
116
  }
99
117
  });
118
+ controller.signal.addEventListener(
119
+ "abort",
120
+ () => {
121
+ client.send = originalClientSend;
122
+ server.send = originalServerSend;
123
+ },
124
+ { once: true }
125
+ );
126
+ return () => {
127
+ controller.abort();
128
+ };
100
129
  }
101
130
  function logConnectionOpen(client) {
102
131
  const publicUrl = (0, import_toPublicUrl.toPublicUrl)(client.url);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/core/ws/utils/attachWebSocketLogger.ts"],"sourcesContent":["import type {\n WebSocketClientConnection,\n WebSocketConnectionData,\n WebSocketData,\n} from '@mswjs/interceptors/WebSocket'\nimport { devUtils } from '../../utils/internal/devUtils'\nimport { getTimestamp } from '../../utils/logging/getTimestamp'\nimport { toPublicUrl } from '../../utils/request/toPublicUrl'\nimport { getMessageLength } from './getMessageLength'\nimport { getPublicData } from './getPublicData'\n\nexport const colors = {\n system: '#3b82f6',\n outgoing: '#22c55e',\n incoming: '#ef4444',\n mocked: '#ff6a33',\n}\n\nexport function attachWebSocketLogger(\n connection: WebSocketConnectionData,\n): void {\n const { client, server } = connection\n\n logConnectionOpen(client)\n\n // Log the events sent from the WebSocket client.\n // WebSocket client connection object is written from the\n // server's perspective so these message events are outgoing.\n /**\n * @todo Provide the reference to the exact event handler\n * that called this `client.send()`.\n */\n client.addEventListener('message', (event) => {\n logOutgoingClientMessage(event)\n })\n\n client.addEventListener('close', (event) => {\n logConnectionClose(event)\n })\n\n // Log client errors (connection closures due to errors).\n client.socket.addEventListener('error', (event) => {\n logClientError(event)\n })\n\n client.send = new Proxy(client.send, {\n apply(target, thisArg, args) {\n const [data] = args\n const messageEvent = new MessageEvent('message', { data })\n Object.defineProperties(messageEvent, {\n currentTarget: {\n enumerable: true,\n writable: false,\n value: client.socket,\n },\n target: {\n enumerable: true,\n writable: false,\n value: client.socket,\n },\n })\n\n queueMicrotask(() => {\n logIncomingMockedClientMessage(messageEvent)\n })\n\n return Reflect.apply(target, thisArg, args)\n },\n })\n\n server.addEventListener(\n 'open',\n () => {\n server.addEventListener('message', (event) => {\n logIncomingServerMessage(event)\n })\n },\n { once: true },\n )\n\n // Log outgoing client events initiated by the event handler.\n // The actual client never sent these but the handler did.\n server.send = new Proxy(server.send, {\n apply(target, thisArg, args) {\n const [data] = args\n const messageEvent = new MessageEvent('message', { data })\n Object.defineProperties(messageEvent, {\n currentTarget: {\n enumerable: true,\n writable: false,\n value: server.socket,\n },\n target: {\n enumerable: true,\n writable: false,\n value: server.socket,\n },\n })\n\n logOutgoingMockedClientMessage(messageEvent)\n\n return Reflect.apply(target, thisArg, args)\n },\n })\n}\n\n/**\n * Prints the WebSocket connection.\n * This is meant to be logged by every WebSocket handler\n * that intercepted this connection. This helps you see\n * what handlers observe this connection.\n */\nexport function logConnectionOpen(client: WebSocketClientConnection) {\n const publicUrl = toPublicUrl(client.url)\n\n console.groupCollapsed(\n devUtils.formatMessage(`${getTimestamp()} %c▶%c ${publicUrl}`),\n `color:${colors.system}`,\n 'color:inherit',\n )\n // eslint-disable-next-line no-console\n console.log('Client:', client.socket)\n console.groupEnd()\n}\n\nfunction logConnectionClose(event: CloseEvent) {\n const target = event.target as WebSocket\n const publicUrl = toPublicUrl(target.url)\n\n console.groupCollapsed(\n devUtils.formatMessage(\n `${getTimestamp({ milliseconds: true })} %c■%c ${publicUrl}`,\n ),\n `color:${colors.system}`,\n 'color:inherit',\n )\n // eslint-disable-next-line no-console\n console.log(event)\n console.groupEnd()\n}\n\nfunction logClientError(event: Event) {\n const socket = event.target as WebSocket\n const publicUrl = toPublicUrl(socket.url)\n\n console.groupCollapsed(\n devUtils.formatMessage(\n `${getTimestamp({ milliseconds: true })} %c\\u00D7%c ${publicUrl}`,\n ),\n `color:${colors.system}`,\n 'color:inherit',\n )\n // eslint-disable-next-line no-console\n console.log(event)\n console.groupEnd()\n}\n\n/**\n * Prints the outgoing client message.\n */\nasync function logOutgoingClientMessage(event: MessageEvent<WebSocketData>) {\n const byteLength = getMessageLength(event.data)\n const publicData = await getPublicData(event.data)\n const arrow = event.defaultPrevented ? '⇡' : '⬆'\n\n console.groupCollapsed(\n devUtils.formatMessage(\n `${getTimestamp({ milliseconds: true })} %c${arrow}%c ${publicData} %c${byteLength}%c`,\n ),\n `color:${colors.outgoing}`,\n 'color:inherit',\n 'color:gray;font-weight:normal',\n 'color:inherit;font-weight:inherit',\n )\n // eslint-disable-next-line no-console\n console.log(event)\n console.groupEnd()\n}\n\n/**\n * Prints the outgoing client message initiated\n * by `server.send()` in the event handler.\n */\nasync function logOutgoingMockedClientMessage(\n event: MessageEvent<WebSocketData>,\n) {\n const byteLength = getMessageLength(event.data)\n const publicData = await getPublicData(event.data)\n\n console.groupCollapsed(\n devUtils.formatMessage(\n `${getTimestamp({ milliseconds: true })} %c⬆%c ${publicData} %c${byteLength}%c`,\n ),\n `color:${colors.mocked}`,\n 'color:inherit',\n 'color:gray;font-weight:normal',\n 'color:inherit;font-weight:inherit',\n )\n // eslint-disable-next-line no-console\n console.log(event)\n console.groupEnd()\n}\n\n/**\n * Prints the outgoing client message initiated\n * by `client.send()` in the event handler.\n */\nasync function logIncomingMockedClientMessage(\n event: MessageEvent<WebSocketData>,\n) {\n const byteLength = getMessageLength(event.data)\n const publicData = await getPublicData(event.data)\n\n console.groupCollapsed(\n devUtils.formatMessage(\n `${getTimestamp({ milliseconds: true })} %c⬇%c ${publicData} %c${byteLength}%c`,\n ),\n `color:${colors.mocked}`,\n 'color:inherit',\n 'color:gray;font-weight:normal',\n 'color:inherit;font-weight:inherit',\n )\n // eslint-disable-next-line no-console\n console.log(event)\n console.groupEnd()\n}\n\nasync function logIncomingServerMessage(event: MessageEvent<WebSocketData>) {\n const byteLength = getMessageLength(event.data)\n const publicData = await getPublicData(event.data)\n const arrow = event.defaultPrevented ? '⇣' : '⬇'\n\n console.groupCollapsed(\n devUtils.formatMessage(\n `${getTimestamp({ milliseconds: true })} %c${arrow}%c ${publicData} %c${byteLength}%c`,\n ),\n `color:${colors.incoming}`,\n 'color:inherit',\n 'color:gray;font-weight:normal',\n 'color:inherit;font-weight:inherit',\n )\n // eslint-disable-next-line no-console\n console.log(event)\n console.groupEnd()\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/core/ws/utils/attachWebSocketLogger.ts"],"sourcesContent":["import type {\n WebSocketClientConnection,\n WebSocketConnectionData,\n WebSocketData,\n} from '@mswjs/interceptors/WebSocket'\nimport { devUtils } from '../../utils/internal/devUtils'\nimport { getTimestamp } from '../../utils/logging/getTimestamp'\nimport { toPublicUrl } from '../../utils/request/toPublicUrl'\nimport { getMessageLength } from './getMessageLength'\nimport { getPublicData } from './getPublicData'\n\nexport const colors = {\n system: '#3b82f6',\n outgoing: '#22c55e',\n incoming: '#ef4444',\n mocked: '#ff6a33',\n}\n\nexport function attachWebSocketLogger(\n connection: WebSocketConnectionData,\n): () => void {\n const { client, server } = connection\n const controller = new AbortController()\n\n logConnectionOpen(client)\n\n // Log the events sent from the WebSocket client.\n // WebSocket client connection object is written from the\n // server's perspective so these message events are outgoing.\n /**\n * @todo Provide the reference to the exact event handler\n * that called this `client.send()`.\n */\n client.addEventListener(\n 'message',\n (event) => {\n logOutgoingClientMessage(event)\n },\n { signal: controller.signal },\n )\n\n client.addEventListener(\n 'close',\n (event) => {\n logConnectionClose(event)\n },\n { signal: controller.signal },\n )\n\n // Log client errors (connection closures due to errors).\n client.socket.addEventListener(\n 'error',\n (event) => {\n logClientError(event)\n },\n { signal: controller.signal },\n )\n\n const { send: originalClientSend } = client\n client.send = new Proxy(client.send, {\n apply(target, thisArg, args) {\n const [data] = args\n const messageEvent = new MessageEvent('message', { data })\n Object.defineProperties(messageEvent, {\n currentTarget: {\n enumerable: true,\n writable: false,\n value: client.socket,\n },\n target: {\n enumerable: true,\n writable: false,\n value: client.socket,\n },\n })\n\n queueMicrotask(() => {\n logIncomingMockedClientMessage(messageEvent)\n })\n\n return Reflect.apply(target, thisArg, args)\n },\n })\n\n server.addEventListener(\n 'open',\n () => {\n server.addEventListener('message', (event) => {\n logIncomingServerMessage(event)\n })\n },\n {\n once: true,\n signal: controller.signal,\n },\n )\n\n // Log outgoing client events initiated by the event handler.\n // The actual client never sent these but the handler did.\n const { send: originalServerSend } = server\n server.send = new Proxy(server.send, {\n apply(target, thisArg, args) {\n const [data] = args\n const messageEvent = new MessageEvent('message', { data })\n Object.defineProperties(messageEvent, {\n currentTarget: {\n enumerable: true,\n writable: false,\n value: server.socket,\n },\n target: {\n enumerable: true,\n writable: false,\n value: server.socket,\n },\n })\n\n logOutgoingMockedClientMessage(messageEvent)\n\n return Reflect.apply(target, thisArg, args)\n },\n })\n\n // Undo method proxies.\n controller.signal.addEventListener(\n 'abort',\n () => {\n client.send = originalClientSend\n server.send = originalServerSend\n },\n { once: true },\n )\n\n return () => {\n controller.abort()\n }\n}\n\n/**\n * Prints the WebSocket connection.\n * This is meant to be logged by every WebSocket handler\n * that intercepted this connection. This helps you see\n * what handlers observe this connection.\n */\nexport function logConnectionOpen(client: WebSocketClientConnection) {\n const publicUrl = toPublicUrl(client.url)\n\n console.groupCollapsed(\n devUtils.formatMessage(`${getTimestamp()} %c▶%c ${publicUrl}`),\n `color:${colors.system}`,\n 'color:inherit',\n )\n // eslint-disable-next-line no-console\n console.log('Client:', client.socket)\n console.groupEnd()\n}\n\nfunction logConnectionClose(event: CloseEvent) {\n const target = event.target as WebSocket\n const publicUrl = toPublicUrl(target.url)\n\n console.groupCollapsed(\n devUtils.formatMessage(\n `${getTimestamp({ milliseconds: true })} %c■%c ${publicUrl}`,\n ),\n `color:${colors.system}`,\n 'color:inherit',\n )\n // eslint-disable-next-line no-console\n console.log(event)\n console.groupEnd()\n}\n\nfunction logClientError(event: Event) {\n const socket = event.target as WebSocket\n const publicUrl = toPublicUrl(socket.url)\n\n console.groupCollapsed(\n devUtils.formatMessage(\n `${getTimestamp({ milliseconds: true })} %c\\u00D7%c ${publicUrl}`,\n ),\n `color:${colors.system}`,\n 'color:inherit',\n )\n // eslint-disable-next-line no-console\n console.log(event)\n console.groupEnd()\n}\n\n/**\n * Prints the outgoing client message.\n */\nasync function logOutgoingClientMessage(event: MessageEvent<WebSocketData>) {\n const byteLength = getMessageLength(event.data)\n const publicData = await getPublicData(event.data)\n const arrow = event.defaultPrevented ? '⇡' : '⬆'\n\n console.groupCollapsed(\n devUtils.formatMessage(\n `${getTimestamp({ milliseconds: true })} %c${arrow}%c ${publicData} %c${byteLength}%c`,\n ),\n `color:${colors.outgoing}`,\n 'color:inherit',\n 'color:gray;font-weight:normal',\n 'color:inherit;font-weight:inherit',\n )\n // eslint-disable-next-line no-console\n console.log(event)\n console.groupEnd()\n}\n\n/**\n * Prints the outgoing client message initiated\n * by `server.send()` in the event handler.\n */\nasync function logOutgoingMockedClientMessage(\n event: MessageEvent<WebSocketData>,\n) {\n const byteLength = getMessageLength(event.data)\n const publicData = await getPublicData(event.data)\n\n console.groupCollapsed(\n devUtils.formatMessage(\n `${getTimestamp({ milliseconds: true })} %c⬆%c ${publicData} %c${byteLength}%c`,\n ),\n `color:${colors.mocked}`,\n 'color:inherit',\n 'color:gray;font-weight:normal',\n 'color:inherit;font-weight:inherit',\n )\n // eslint-disable-next-line no-console\n console.log(event)\n console.groupEnd()\n}\n\n/**\n * Prints the outgoing client message initiated\n * by `client.send()` in the event handler.\n */\nasync function logIncomingMockedClientMessage(\n event: MessageEvent<WebSocketData>,\n) {\n const byteLength = getMessageLength(event.data)\n const publicData = await getPublicData(event.data)\n\n console.groupCollapsed(\n devUtils.formatMessage(\n `${getTimestamp({ milliseconds: true })} %c⬇%c ${publicData} %c${byteLength}%c`,\n ),\n `color:${colors.mocked}`,\n 'color:inherit',\n 'color:gray;font-weight:normal',\n 'color:inherit;font-weight:inherit',\n )\n // eslint-disable-next-line no-console\n console.log(event)\n console.groupEnd()\n}\n\nasync function logIncomingServerMessage(event: MessageEvent<WebSocketData>) {\n const byteLength = getMessageLength(event.data)\n const publicData = await getPublicData(event.data)\n const arrow = event.defaultPrevented ? '⇣' : '⬇'\n\n console.groupCollapsed(\n devUtils.formatMessage(\n `${getTimestamp({ milliseconds: true })} %c${arrow}%c ${publicData} %c${byteLength}%c`,\n ),\n `color:${colors.incoming}`,\n 'color:inherit',\n 'color:gray;font-weight:normal',\n 'color:inherit;font-weight:inherit',\n )\n // eslint-disable-next-line no-console\n console.log(event)\n console.groupEnd()\n}\n"],"mappings":"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","names":[]}
@@ -11,16 +11,30 @@ const colors = {
11
11
  };
12
12
  function attachWebSocketLogger(connection) {
13
13
  const { client, server } = connection;
14
+ const controller = new AbortController();
14
15
  logConnectionOpen(client);
15
- client.addEventListener("message", (event) => {
16
- logOutgoingClientMessage(event);
17
- });
18
- client.addEventListener("close", (event) => {
19
- logConnectionClose(event);
20
- });
21
- client.socket.addEventListener("error", (event) => {
22
- logClientError(event);
23
- });
16
+ client.addEventListener(
17
+ "message",
18
+ (event) => {
19
+ logOutgoingClientMessage(event);
20
+ },
21
+ { signal: controller.signal }
22
+ );
23
+ client.addEventListener(
24
+ "close",
25
+ (event) => {
26
+ logConnectionClose(event);
27
+ },
28
+ { signal: controller.signal }
29
+ );
30
+ client.socket.addEventListener(
31
+ "error",
32
+ (event) => {
33
+ logClientError(event);
34
+ },
35
+ { signal: controller.signal }
36
+ );
37
+ const { send: originalClientSend } = client;
24
38
  client.send = new Proxy(client.send, {
25
39
  apply(target, thisArg, args) {
26
40
  const [data] = args;
@@ -50,8 +64,12 @@ function attachWebSocketLogger(connection) {
50
64
  logIncomingServerMessage(event);
51
65
  });
52
66
  },
53
- { once: true }
67
+ {
68
+ once: true,
69
+ signal: controller.signal
70
+ }
54
71
  );
72
+ const { send: originalServerSend } = server;
55
73
  server.send = new Proxy(server.send, {
56
74
  apply(target, thisArg, args) {
57
75
  const [data] = args;
@@ -72,6 +90,17 @@ function attachWebSocketLogger(connection) {
72
90
  return Reflect.apply(target, thisArg, args);
73
91
  }
74
92
  });
93
+ controller.signal.addEventListener(
94
+ "abort",
95
+ () => {
96
+ client.send = originalClientSend;
97
+ server.send = originalServerSend;
98
+ },
99
+ { once: true }
100
+ );
101
+ return () => {
102
+ controller.abort();
103
+ };
75
104
  }
76
105
  function logConnectionOpen(client) {
77
106
  const publicUrl = toPublicUrl(client.url);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/core/ws/utils/attachWebSocketLogger.ts"],"sourcesContent":["import type {\n WebSocketClientConnection,\n WebSocketConnectionData,\n WebSocketData,\n} from '@mswjs/interceptors/WebSocket'\nimport { devUtils } from '../../utils/internal/devUtils'\nimport { getTimestamp } from '../../utils/logging/getTimestamp'\nimport { toPublicUrl } from '../../utils/request/toPublicUrl'\nimport { getMessageLength } from './getMessageLength'\nimport { getPublicData } from './getPublicData'\n\nexport const colors = {\n system: '#3b82f6',\n outgoing: '#22c55e',\n incoming: '#ef4444',\n mocked: '#ff6a33',\n}\n\nexport function attachWebSocketLogger(\n connection: WebSocketConnectionData,\n): void {\n const { client, server } = connection\n\n logConnectionOpen(client)\n\n // Log the events sent from the WebSocket client.\n // WebSocket client connection object is written from the\n // server's perspective so these message events are outgoing.\n /**\n * @todo Provide the reference to the exact event handler\n * that called this `client.send()`.\n */\n client.addEventListener('message', (event) => {\n logOutgoingClientMessage(event)\n })\n\n client.addEventListener('close', (event) => {\n logConnectionClose(event)\n })\n\n // Log client errors (connection closures due to errors).\n client.socket.addEventListener('error', (event) => {\n logClientError(event)\n })\n\n client.send = new Proxy(client.send, {\n apply(target, thisArg, args) {\n const [data] = args\n const messageEvent = new MessageEvent('message', { data })\n Object.defineProperties(messageEvent, {\n currentTarget: {\n enumerable: true,\n writable: false,\n value: client.socket,\n },\n target: {\n enumerable: true,\n writable: false,\n value: client.socket,\n },\n })\n\n queueMicrotask(() => {\n logIncomingMockedClientMessage(messageEvent)\n })\n\n return Reflect.apply(target, thisArg, args)\n },\n })\n\n server.addEventListener(\n 'open',\n () => {\n server.addEventListener('message', (event) => {\n logIncomingServerMessage(event)\n })\n },\n { once: true },\n )\n\n // Log outgoing client events initiated by the event handler.\n // The actual client never sent these but the handler did.\n server.send = new Proxy(server.send, {\n apply(target, thisArg, args) {\n const [data] = args\n const messageEvent = new MessageEvent('message', { data })\n Object.defineProperties(messageEvent, {\n currentTarget: {\n enumerable: true,\n writable: false,\n value: server.socket,\n },\n target: {\n enumerable: true,\n writable: false,\n value: server.socket,\n },\n })\n\n logOutgoingMockedClientMessage(messageEvent)\n\n return Reflect.apply(target, thisArg, args)\n },\n })\n}\n\n/**\n * Prints the WebSocket connection.\n * This is meant to be logged by every WebSocket handler\n * that intercepted this connection. This helps you see\n * what handlers observe this connection.\n */\nexport function logConnectionOpen(client: WebSocketClientConnection) {\n const publicUrl = toPublicUrl(client.url)\n\n console.groupCollapsed(\n devUtils.formatMessage(`${getTimestamp()} %c▶%c ${publicUrl}`),\n `color:${colors.system}`,\n 'color:inherit',\n )\n // eslint-disable-next-line no-console\n console.log('Client:', client.socket)\n console.groupEnd()\n}\n\nfunction logConnectionClose(event: CloseEvent) {\n const target = event.target as WebSocket\n const publicUrl = toPublicUrl(target.url)\n\n console.groupCollapsed(\n devUtils.formatMessage(\n `${getTimestamp({ milliseconds: true })} %c■%c ${publicUrl}`,\n ),\n `color:${colors.system}`,\n 'color:inherit',\n )\n // eslint-disable-next-line no-console\n console.log(event)\n console.groupEnd()\n}\n\nfunction logClientError(event: Event) {\n const socket = event.target as WebSocket\n const publicUrl = toPublicUrl(socket.url)\n\n console.groupCollapsed(\n devUtils.formatMessage(\n `${getTimestamp({ milliseconds: true })} %c\\u00D7%c ${publicUrl}`,\n ),\n `color:${colors.system}`,\n 'color:inherit',\n )\n // eslint-disable-next-line no-console\n console.log(event)\n console.groupEnd()\n}\n\n/**\n * Prints the outgoing client message.\n */\nasync function logOutgoingClientMessage(event: MessageEvent<WebSocketData>) {\n const byteLength = getMessageLength(event.data)\n const publicData = await getPublicData(event.data)\n const arrow = event.defaultPrevented ? '⇡' : '⬆'\n\n console.groupCollapsed(\n devUtils.formatMessage(\n `${getTimestamp({ milliseconds: true })} %c${arrow}%c ${publicData} %c${byteLength}%c`,\n ),\n `color:${colors.outgoing}`,\n 'color:inherit',\n 'color:gray;font-weight:normal',\n 'color:inherit;font-weight:inherit',\n )\n // eslint-disable-next-line no-console\n console.log(event)\n console.groupEnd()\n}\n\n/**\n * Prints the outgoing client message initiated\n * by `server.send()` in the event handler.\n */\nasync function logOutgoingMockedClientMessage(\n event: MessageEvent<WebSocketData>,\n) {\n const byteLength = getMessageLength(event.data)\n const publicData = await getPublicData(event.data)\n\n console.groupCollapsed(\n devUtils.formatMessage(\n `${getTimestamp({ milliseconds: true })} %c⬆%c ${publicData} %c${byteLength}%c`,\n ),\n `color:${colors.mocked}`,\n 'color:inherit',\n 'color:gray;font-weight:normal',\n 'color:inherit;font-weight:inherit',\n )\n // eslint-disable-next-line no-console\n console.log(event)\n console.groupEnd()\n}\n\n/**\n * Prints the outgoing client message initiated\n * by `client.send()` in the event handler.\n */\nasync function logIncomingMockedClientMessage(\n event: MessageEvent<WebSocketData>,\n) {\n const byteLength = getMessageLength(event.data)\n const publicData = await getPublicData(event.data)\n\n console.groupCollapsed(\n devUtils.formatMessage(\n `${getTimestamp({ milliseconds: true })} %c⬇%c ${publicData} %c${byteLength}%c`,\n ),\n `color:${colors.mocked}`,\n 'color:inherit',\n 'color:gray;font-weight:normal',\n 'color:inherit;font-weight:inherit',\n )\n // eslint-disable-next-line no-console\n console.log(event)\n console.groupEnd()\n}\n\nasync function logIncomingServerMessage(event: MessageEvent<WebSocketData>) {\n const byteLength = getMessageLength(event.data)\n const publicData = await getPublicData(event.data)\n const arrow = event.defaultPrevented ? '⇣' : '⬇'\n\n console.groupCollapsed(\n devUtils.formatMessage(\n `${getTimestamp({ milliseconds: true })} %c${arrow}%c ${publicData} %c${byteLength}%c`,\n ),\n `color:${colors.incoming}`,\n 'color:inherit',\n 'color:gray;font-weight:normal',\n 'color:inherit;font-weight:inherit',\n )\n // eslint-disable-next-line no-console\n console.log(event)\n console.groupEnd()\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/core/ws/utils/attachWebSocketLogger.ts"],"sourcesContent":["import type {\n WebSocketClientConnection,\n WebSocketConnectionData,\n WebSocketData,\n} from '@mswjs/interceptors/WebSocket'\nimport { devUtils } from '../../utils/internal/devUtils'\nimport { getTimestamp } from '../../utils/logging/getTimestamp'\nimport { toPublicUrl } from '../../utils/request/toPublicUrl'\nimport { getMessageLength } from './getMessageLength'\nimport { getPublicData } from './getPublicData'\n\nexport const colors = {\n system: '#3b82f6',\n outgoing: '#22c55e',\n incoming: '#ef4444',\n mocked: '#ff6a33',\n}\n\nexport function attachWebSocketLogger(\n connection: WebSocketConnectionData,\n): () => void {\n const { client, server } = connection\n const controller = new AbortController()\n\n logConnectionOpen(client)\n\n // Log the events sent from the WebSocket client.\n // WebSocket client connection object is written from the\n // server's perspective so these message events are outgoing.\n /**\n * @todo Provide the reference to the exact event handler\n * that called this `client.send()`.\n */\n client.addEventListener(\n 'message',\n (event) => {\n logOutgoingClientMessage(event)\n },\n { signal: controller.signal },\n )\n\n client.addEventListener(\n 'close',\n (event) => {\n logConnectionClose(event)\n },\n { signal: controller.signal },\n )\n\n // Log client errors (connection closures due to errors).\n client.socket.addEventListener(\n 'error',\n (event) => {\n logClientError(event)\n },\n { signal: controller.signal },\n )\n\n const { send: originalClientSend } = client\n client.send = new Proxy(client.send, {\n apply(target, thisArg, args) {\n const [data] = args\n const messageEvent = new MessageEvent('message', { data })\n Object.defineProperties(messageEvent, {\n currentTarget: {\n enumerable: true,\n writable: false,\n value: client.socket,\n },\n target: {\n enumerable: true,\n writable: false,\n value: client.socket,\n },\n })\n\n queueMicrotask(() => {\n logIncomingMockedClientMessage(messageEvent)\n })\n\n return Reflect.apply(target, thisArg, args)\n },\n })\n\n server.addEventListener(\n 'open',\n () => {\n server.addEventListener('message', (event) => {\n logIncomingServerMessage(event)\n })\n },\n {\n once: true,\n signal: controller.signal,\n },\n )\n\n // Log outgoing client events initiated by the event handler.\n // The actual client never sent these but the handler did.\n const { send: originalServerSend } = server\n server.send = new Proxy(server.send, {\n apply(target, thisArg, args) {\n const [data] = args\n const messageEvent = new MessageEvent('message', { data })\n Object.defineProperties(messageEvent, {\n currentTarget: {\n enumerable: true,\n writable: false,\n value: server.socket,\n },\n target: {\n enumerable: true,\n writable: false,\n value: server.socket,\n },\n })\n\n logOutgoingMockedClientMessage(messageEvent)\n\n return Reflect.apply(target, thisArg, args)\n },\n })\n\n // Undo method proxies.\n controller.signal.addEventListener(\n 'abort',\n () => {\n client.send = originalClientSend\n server.send = originalServerSend\n },\n { once: true },\n )\n\n return () => {\n controller.abort()\n }\n}\n\n/**\n * Prints the WebSocket connection.\n * This is meant to be logged by every WebSocket handler\n * that intercepted this connection. This helps you see\n * what handlers observe this connection.\n */\nexport function logConnectionOpen(client: WebSocketClientConnection) {\n const publicUrl = toPublicUrl(client.url)\n\n console.groupCollapsed(\n devUtils.formatMessage(`${getTimestamp()} %c▶%c ${publicUrl}`),\n `color:${colors.system}`,\n 'color:inherit',\n )\n // eslint-disable-next-line no-console\n console.log('Client:', client.socket)\n console.groupEnd()\n}\n\nfunction logConnectionClose(event: CloseEvent) {\n const target = event.target as WebSocket\n const publicUrl = toPublicUrl(target.url)\n\n console.groupCollapsed(\n devUtils.formatMessage(\n `${getTimestamp({ milliseconds: true })} %c■%c ${publicUrl}`,\n ),\n `color:${colors.system}`,\n 'color:inherit',\n )\n // eslint-disable-next-line no-console\n console.log(event)\n console.groupEnd()\n}\n\nfunction logClientError(event: Event) {\n const socket = event.target as WebSocket\n const publicUrl = toPublicUrl(socket.url)\n\n console.groupCollapsed(\n devUtils.formatMessage(\n `${getTimestamp({ milliseconds: true })} %c\\u00D7%c ${publicUrl}`,\n ),\n `color:${colors.system}`,\n 'color:inherit',\n )\n // eslint-disable-next-line no-console\n console.log(event)\n console.groupEnd()\n}\n\n/**\n * Prints the outgoing client message.\n */\nasync function logOutgoingClientMessage(event: MessageEvent<WebSocketData>) {\n const byteLength = getMessageLength(event.data)\n const publicData = await getPublicData(event.data)\n const arrow = event.defaultPrevented ? '⇡' : '⬆'\n\n console.groupCollapsed(\n devUtils.formatMessage(\n `${getTimestamp({ milliseconds: true })} %c${arrow}%c ${publicData} %c${byteLength}%c`,\n ),\n `color:${colors.outgoing}`,\n 'color:inherit',\n 'color:gray;font-weight:normal',\n 'color:inherit;font-weight:inherit',\n )\n // eslint-disable-next-line no-console\n console.log(event)\n console.groupEnd()\n}\n\n/**\n * Prints the outgoing client message initiated\n * by `server.send()` in the event handler.\n */\nasync function logOutgoingMockedClientMessage(\n event: MessageEvent<WebSocketData>,\n) {\n const byteLength = getMessageLength(event.data)\n const publicData = await getPublicData(event.data)\n\n console.groupCollapsed(\n devUtils.formatMessage(\n `${getTimestamp({ milliseconds: true })} %c⬆%c ${publicData} %c${byteLength}%c`,\n ),\n `color:${colors.mocked}`,\n 'color:inherit',\n 'color:gray;font-weight:normal',\n 'color:inherit;font-weight:inherit',\n )\n // eslint-disable-next-line no-console\n console.log(event)\n console.groupEnd()\n}\n\n/**\n * Prints the outgoing client message initiated\n * by `client.send()` in the event handler.\n */\nasync function logIncomingMockedClientMessage(\n event: MessageEvent<WebSocketData>,\n) {\n const byteLength = getMessageLength(event.data)\n const publicData = await getPublicData(event.data)\n\n console.groupCollapsed(\n devUtils.formatMessage(\n `${getTimestamp({ milliseconds: true })} %c⬇%c ${publicData} %c${byteLength}%c`,\n ),\n `color:${colors.mocked}`,\n 'color:inherit',\n 'color:gray;font-weight:normal',\n 'color:inherit;font-weight:inherit',\n )\n // eslint-disable-next-line no-console\n console.log(event)\n console.groupEnd()\n}\n\nasync function logIncomingServerMessage(event: MessageEvent<WebSocketData>) {\n const byteLength = getMessageLength(event.data)\n const publicData = await getPublicData(event.data)\n const arrow = event.defaultPrevented ? '⇣' : '⬇'\n\n console.groupCollapsed(\n devUtils.formatMessage(\n `${getTimestamp({ milliseconds: true })} %c${arrow}%c ${publicData} %c${byteLength}%c`,\n ),\n `color:${colors.incoming}`,\n 'color:inherit',\n 'color:gray;font-weight:normal',\n 'color:inherit;font-weight:inherit',\n )\n // eslint-disable-next-line no-console\n console.log(event)\n console.groupEnd()\n}\n"],"mappings":"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","names":[]}
package/lib/core/ws.d.mts CHANGED
@@ -22,7 +22,7 @@ type WebSocketLink = {
22
22
  *
23
23
  * @see {@link https://mswjs.io/docs/api/ws#onevent-listener `on()` API reference}
24
24
  */
25
- addEventListener<EventType extends keyof WebSocketHandlerEventMap>(event: EventType, listener: WebSocketEventListener<EventType>): WebSocketHandler;
25
+ addEventListener: <EventType extends keyof WebSocketHandlerEventMap>(event: EventType, listener: WebSocketEventListener<EventType>) => WebSocketHandler;
26
26
  /**
27
27
  * Broadcasts the given data to all WebSocket clients.
28
28
  *
@@ -34,7 +34,7 @@ type WebSocketLink = {
34
34
  *
35
35
  * @see {@link https://mswjs.io/docs/api/ws#broadcastdata `broadcast()` API reference}
36
36
  */
37
- broadcast(data: WebSocketData): void;
37
+ broadcast: (data: WebSocketData) => void;
38
38
  /**
39
39
  * Broadcasts the given data to all WebSocket clients
40
40
  * except the ones provided in the `clients` argument.
@@ -47,7 +47,7 @@ type WebSocketLink = {
47
47
  *
48
48
  * @see {@link https://mswjs.io/docs/api/ws#broadcastexceptclients-data `broadcast()` API reference}
49
49
  */
50
- broadcastExcept(clients: WebSocketClientConnectionProtocol | Array<WebSocketClientConnectionProtocol>, data: WebSocketData): void;
50
+ broadcastExcept: (clients: WebSocketClientConnectionProtocol | Array<WebSocketClientConnectionProtocol>, data: WebSocketData) => void;
51
51
  };
52
52
  /**
53
53
  * Intercepts outgoing WebSocket connections to the given URL.
package/lib/core/ws.d.ts CHANGED
@@ -22,7 +22,7 @@ type WebSocketLink = {
22
22
  *
23
23
  * @see {@link https://mswjs.io/docs/api/ws#onevent-listener `on()` API reference}
24
24
  */
25
- addEventListener<EventType extends keyof WebSocketHandlerEventMap>(event: EventType, listener: WebSocketEventListener<EventType>): WebSocketHandler;
25
+ addEventListener: <EventType extends keyof WebSocketHandlerEventMap>(event: EventType, listener: WebSocketEventListener<EventType>) => WebSocketHandler;
26
26
  /**
27
27
  * Broadcasts the given data to all WebSocket clients.
28
28
  *
@@ -34,7 +34,7 @@ type WebSocketLink = {
34
34
  *
35
35
  * @see {@link https://mswjs.io/docs/api/ws#broadcastdata `broadcast()` API reference}
36
36
  */
37
- broadcast(data: WebSocketData): void;
37
+ broadcast: (data: WebSocketData) => void;
38
38
  /**
39
39
  * Broadcasts the given data to all WebSocket clients
40
40
  * except the ones provided in the `clients` argument.
@@ -47,7 +47,7 @@ type WebSocketLink = {
47
47
  *
48
48
  * @see {@link https://mswjs.io/docs/api/ws#broadcastexceptclients-data `broadcast()` API reference}
49
49
  */
50
- broadcastExcept(clients: WebSocketClientConnectionProtocol | Array<WebSocketClientConnectionProtocol>, data: WebSocketData): void;
50
+ broadcastExcept: (clients: WebSocketClientConnectionProtocol | Array<WebSocketClientConnectionProtocol>, data: WebSocketData) => void;
51
51
  };
52
52
  /**
53
53
  * Intercepts outgoing WebSocket connections to the given URL.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/ws.ts"],"sourcesContent":["import { invariant } from 'outvariant'\nimport type {\n WebSocketData,\n WebSocketClientConnectionProtocol,\n} from '@mswjs/interceptors/WebSocket'\nimport {\n WebSocketHandler,\n kEmitter,\n type WebSocketHandlerEventMap,\n} from './handlers/WebSocketHandler'\nimport { hasRefCounted } from './utils/internal/hasRefCounted'\nimport { Path, isPath } from './utils/matching/matchRequestUrl'\nimport { WebSocketClientManager } from './ws/WebSocketClientManager'\n\nconst webSocketChannel = new BroadcastChannel('msw:websocket-client-manager')\n\nif (hasRefCounted(webSocketChannel)) {\n // Allows the Node.js thread to exit if it is the only active handle in the event system.\n // https://nodejs.org/api/worker_threads.html#broadcastchannelunref\n webSocketChannel.unref()\n}\n\nexport type WebSocketEventListener<\n EventType extends keyof WebSocketHandlerEventMap,\n> = (...args: WebSocketHandlerEventMap[EventType]) => void\n\nexport type WebSocketLink = {\n /**\n * A set of all WebSocket clients connected\n * to this link.\n *\n * @see {@link https://mswjs.io/docs/api/ws#clients `clients` API reference}\n */\n clients: Set<WebSocketClientConnectionProtocol>\n\n /**\n * Adds an event listener to this WebSocket link.\n *\n * @example\n * const chat = ws.link('wss://chat.example.com')\n * chat.addEventListener('connection', listener)\n *\n * @see {@link https://mswjs.io/docs/api/ws#onevent-listener `on()` API reference}\n */\n addEventListener<EventType extends keyof WebSocketHandlerEventMap>(\n event: EventType,\n listener: WebSocketEventListener<EventType>,\n ): WebSocketHandler\n\n /**\n * Broadcasts the given data to all WebSocket clients.\n *\n * @example\n * const service = ws.link('wss://example.com')\n * service.addEventListener('connection', () => {\n * service.broadcast('hello, everyone!')\n * })\n *\n * @see {@link https://mswjs.io/docs/api/ws#broadcastdata `broadcast()` API reference}\n */\n broadcast(data: WebSocketData): void\n\n /**\n * Broadcasts the given data to all WebSocket clients\n * except the ones provided in the `clients` argument.\n *\n * @example\n * const service = ws.link('wss://example.com')\n * service.addEventListener('connection', ({ client }) => {\n * service.broadcastExcept(client, 'hi, the rest of you!')\n * })\n *\n * @see {@link https://mswjs.io/docs/api/ws#broadcastexceptclients-data `broadcast()` API reference}\n */\n broadcastExcept(\n clients:\n | WebSocketClientConnectionProtocol\n | Array<WebSocketClientConnectionProtocol>,\n data: WebSocketData,\n ): void\n}\n\n/**\n * Intercepts outgoing WebSocket connections to the given URL.\n *\n * @example\n * const chat = ws.link('wss://chat.example.com')\n * chat.addEventListener('connection', ({ client }) => {\n * client.send('hello from server!')\n * })\n */\nfunction createWebSocketLinkHandler(url: Path): WebSocketLink {\n invariant(url, 'Expected a WebSocket server URL but got undefined')\n\n invariant(\n isPath(url),\n 'Expected a WebSocket server URL to be a valid path but got %s',\n typeof url,\n )\n\n const clientManager = new WebSocketClientManager(webSocketChannel)\n\n return {\n get clients() {\n return clientManager.clients\n },\n addEventListener(event, listener) {\n const handler = new WebSocketHandler(url)\n\n // Add the connection event listener for when the\n // handler matches and emits a connection event.\n // When that happens, store that connection in the\n // set of all connections for reference.\n handler[kEmitter].on('connection', async ({ client }) => {\n await clientManager.addConnection(client)\n })\n\n // The \"handleWebSocketEvent\" function will invoke\n // the \"run()\" method on the WebSocketHandler.\n // If the handler matches, it will emit the \"connection\"\n // event. Attach the user-defined listener to that event.\n handler[kEmitter].on(event, listener)\n\n return handler\n },\n\n broadcast(data) {\n // This will invoke \"send()\" on the immediate clients\n // in this runtime and post a message to the broadcast channel\n // to trigger send for the clients in other runtimes.\n this.broadcastExcept([], data)\n },\n\n broadcastExcept(clients, data) {\n const ignoreClients = Array.prototype\n .concat(clients)\n .map((client) => client.id)\n\n clientManager.clients.forEach((otherClient) => {\n if (!ignoreClients.includes(otherClient.id)) {\n otherClient.send(data)\n }\n })\n },\n }\n}\n\n/**\n * A namespace to intercept and mock WebSocket connections.\n *\n * @example\n * const chat = ws.link('wss://chat.example.com')\n *\n * @see {@link https://mswjs.io/docs/api/ws `ws` API reference}\n * @see {@link https://mswjs.io/docs/basics/handling-websocket-events Handling WebSocket events}\n */\nexport const ws = {\n link: createWebSocketLinkHandler,\n}\n\nexport { WebSocketData }\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAA0B;AAK1B,8BAIO;AACP,2BAA8B;AAC9B,6BAA6B;AAC7B,oCAAuC;AAEvC,MAAM,mBAAmB,IAAI,iBAAiB,8BAA8B;AAE5E,QAAI,oCAAc,gBAAgB,GAAG;AAGnC,mBAAiB,MAAM;AACzB;AAuEA,SAAS,2BAA2B,KAA0B;AAC5D,mCAAU,KAAK,mDAAmD;AAElE;AAAA,QACE,+BAAO,GAAG;AAAA,IACV;AAAA,IACA,OAAO;AAAA,EACT;AAEA,QAAM,gBAAgB,IAAI,qDAAuB,gBAAgB;AAEjE,SAAO;AAAA,IACL,IAAI,UAAU;AACZ,aAAO,cAAc;AAAA,IACvB;AAAA,IACA,iBAAiB,OAAO,UAAU;AAChC,YAAM,UAAU,IAAI,yCAAiB,GAAG;AAMxC,cAAQ,gCAAQ,EAAE,GAAG,cAAc,OAAO,EAAE,OAAO,MAAM;AACvD,cAAM,cAAc,cAAc,MAAM;AAAA,MAC1C,CAAC;AAMD,cAAQ,gCAAQ,EAAE,GAAG,OAAO,QAAQ;AAEpC,aAAO;AAAA,IACT;AAAA,IAEA,UAAU,MAAM;AAId,WAAK,gBAAgB,CAAC,GAAG,IAAI;AAAA,IAC/B;AAAA,IAEA,gBAAgB,SAAS,MAAM;AAC7B,YAAM,gBAAgB,MAAM,UACzB,OAAO,OAAO,EACd,IAAI,CAAC,WAAW,OAAO,EAAE;AAE5B,oBAAc,QAAQ,QAAQ,CAAC,gBAAgB;AAC7C,YAAI,CAAC,cAAc,SAAS,YAAY,EAAE,GAAG;AAC3C,sBAAY,KAAK,IAAI;AAAA,QACvB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAWO,MAAM,KAAK;AAAA,EAChB,MAAM;AACR;","names":[]}
1
+ {"version":3,"sources":["../../src/core/ws.ts"],"sourcesContent":["import { invariant } from 'outvariant'\nimport type {\n WebSocketData,\n WebSocketClientConnectionProtocol,\n} from '@mswjs/interceptors/WebSocket'\nimport {\n WebSocketHandler,\n kEmitter,\n type WebSocketHandlerEventMap,\n} from './handlers/WebSocketHandler'\nimport { hasRefCounted } from './utils/internal/hasRefCounted'\nimport { type Path, isPath } from './utils/matching/matchRequestUrl'\nimport { WebSocketClientManager } from './ws/WebSocketClientManager'\n\nconst webSocketChannel = new BroadcastChannel('msw:websocket-client-manager')\n\nif (hasRefCounted(webSocketChannel)) {\n // Allows the Node.js thread to exit if it is the only active handle in the event system.\n // https://nodejs.org/api/worker_threads.html#broadcastchannelunref\n webSocketChannel.unref()\n}\n\nexport type WebSocketEventListener<\n EventType extends keyof WebSocketHandlerEventMap,\n> = (...args: WebSocketHandlerEventMap[EventType]) => void\n\nexport type WebSocketLink = {\n /**\n * A set of all WebSocket clients connected\n * to this link.\n *\n * @see {@link https://mswjs.io/docs/api/ws#clients `clients` API reference}\n */\n clients: Set<WebSocketClientConnectionProtocol>\n\n /**\n * Adds an event listener to this WebSocket link.\n *\n * @example\n * const chat = ws.link('wss://chat.example.com')\n * chat.addEventListener('connection', listener)\n *\n * @see {@link https://mswjs.io/docs/api/ws#onevent-listener `on()` API reference}\n */\n addEventListener: <EventType extends keyof WebSocketHandlerEventMap>(\n event: EventType,\n listener: WebSocketEventListener<EventType>,\n ) => WebSocketHandler\n\n /**\n * Broadcasts the given data to all WebSocket clients.\n *\n * @example\n * const service = ws.link('wss://example.com')\n * service.addEventListener('connection', () => {\n * service.broadcast('hello, everyone!')\n * })\n *\n * @see {@link https://mswjs.io/docs/api/ws#broadcastdata `broadcast()` API reference}\n */\n broadcast: (data: WebSocketData) => void\n\n /**\n * Broadcasts the given data to all WebSocket clients\n * except the ones provided in the `clients` argument.\n *\n * @example\n * const service = ws.link('wss://example.com')\n * service.addEventListener('connection', ({ client }) => {\n * service.broadcastExcept(client, 'hi, the rest of you!')\n * })\n *\n * @see {@link https://mswjs.io/docs/api/ws#broadcastexceptclients-data `broadcast()` API reference}\n */\n broadcastExcept: (\n clients:\n | WebSocketClientConnectionProtocol\n | Array<WebSocketClientConnectionProtocol>,\n data: WebSocketData,\n ) => void\n}\n\n/**\n * Intercepts outgoing WebSocket connections to the given URL.\n *\n * @example\n * const chat = ws.link('wss://chat.example.com')\n * chat.addEventListener('connection', ({ client }) => {\n * client.send('hello from server!')\n * })\n */\nfunction createWebSocketLinkHandler(url: Path): WebSocketLink {\n invariant(url, 'Expected a WebSocket server URL but got undefined')\n\n invariant(\n isPath(url),\n 'Expected a WebSocket server URL to be a valid path but got %s',\n typeof url,\n )\n\n const clientManager = new WebSocketClientManager(webSocketChannel)\n\n return {\n get clients() {\n return clientManager.clients\n },\n addEventListener(event, listener) {\n const handler = new WebSocketHandler(url)\n\n // Add the connection event listener for when the\n // handler matches and emits a connection event.\n // When that happens, store that connection in the\n // set of all connections for reference.\n handler[kEmitter].on('connection', async ({ client }) => {\n await clientManager.addConnection(client)\n })\n\n // The \"handleWebSocketEvent\" function will invoke\n // the \"run()\" method on the WebSocketHandler.\n // If the handler matches, it will emit the \"connection\"\n // event. Attach the user-defined listener to that event.\n handler[kEmitter].on(event, listener)\n\n return handler\n },\n\n broadcast(data) {\n // This will invoke \"send()\" on the immediate clients\n // in this runtime and post a message to the broadcast channel\n // to trigger send for the clients in other runtimes.\n this.broadcastExcept([], data)\n },\n\n broadcastExcept(clients, data) {\n const ignoreClients = Array.prototype\n .concat(clients)\n .map((client) => client.id)\n\n clientManager.clients.forEach((otherClient) => {\n if (!ignoreClients.includes(otherClient.id)) {\n otherClient.send(data)\n }\n })\n },\n }\n}\n\n/**\n * A namespace to intercept and mock WebSocket connections.\n *\n * @example\n * const chat = ws.link('wss://chat.example.com')\n *\n * @see {@link https://mswjs.io/docs/api/ws `ws` API reference}\n * @see {@link https://mswjs.io/docs/basics/handling-websocket-events Handling WebSocket events}\n */\nexport const ws = {\n link: createWebSocketLinkHandler,\n}\n\nexport { WebSocketData }\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAA0B;AAK1B,8BAIO;AACP,2BAA8B;AAC9B,6BAAkC;AAClC,oCAAuC;AAEvC,MAAM,mBAAmB,IAAI,iBAAiB,8BAA8B;AAE5E,QAAI,oCAAc,gBAAgB,GAAG;AAGnC,mBAAiB,MAAM;AACzB;AAuEA,SAAS,2BAA2B,KAA0B;AAC5D,mCAAU,KAAK,mDAAmD;AAElE;AAAA,QACE,+BAAO,GAAG;AAAA,IACV;AAAA,IACA,OAAO;AAAA,EACT;AAEA,QAAM,gBAAgB,IAAI,qDAAuB,gBAAgB;AAEjE,SAAO;AAAA,IACL,IAAI,UAAU;AACZ,aAAO,cAAc;AAAA,IACvB;AAAA,IACA,iBAAiB,OAAO,UAAU;AAChC,YAAM,UAAU,IAAI,yCAAiB,GAAG;AAMxC,cAAQ,gCAAQ,EAAE,GAAG,cAAc,OAAO,EAAE,OAAO,MAAM;AACvD,cAAM,cAAc,cAAc,MAAM;AAAA,MAC1C,CAAC;AAMD,cAAQ,gCAAQ,EAAE,GAAG,OAAO,QAAQ;AAEpC,aAAO;AAAA,IACT;AAAA,IAEA,UAAU,MAAM;AAId,WAAK,gBAAgB,CAAC,GAAG,IAAI;AAAA,IAC/B;AAAA,IAEA,gBAAgB,SAAS,MAAM;AAC7B,YAAM,gBAAgB,MAAM,UACzB,OAAO,OAAO,EACd,IAAI,CAAC,WAAW,OAAO,EAAE;AAE5B,oBAAc,QAAQ,QAAQ,CAAC,gBAAgB;AAC7C,YAAI,CAAC,cAAc,SAAS,YAAY,EAAE,GAAG;AAC3C,sBAAY,KAAK,IAAI;AAAA,QACvB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAWO,MAAM,KAAK;AAAA,EAChB,MAAM;AACR;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/ws.ts"],"sourcesContent":["import { invariant } from 'outvariant'\nimport type {\n WebSocketData,\n WebSocketClientConnectionProtocol,\n} from '@mswjs/interceptors/WebSocket'\nimport {\n WebSocketHandler,\n kEmitter,\n type WebSocketHandlerEventMap,\n} from './handlers/WebSocketHandler'\nimport { hasRefCounted } from './utils/internal/hasRefCounted'\nimport { Path, isPath } from './utils/matching/matchRequestUrl'\nimport { WebSocketClientManager } from './ws/WebSocketClientManager'\n\nconst webSocketChannel = new BroadcastChannel('msw:websocket-client-manager')\n\nif (hasRefCounted(webSocketChannel)) {\n // Allows the Node.js thread to exit if it is the only active handle in the event system.\n // https://nodejs.org/api/worker_threads.html#broadcastchannelunref\n webSocketChannel.unref()\n}\n\nexport type WebSocketEventListener<\n EventType extends keyof WebSocketHandlerEventMap,\n> = (...args: WebSocketHandlerEventMap[EventType]) => void\n\nexport type WebSocketLink = {\n /**\n * A set of all WebSocket clients connected\n * to this link.\n *\n * @see {@link https://mswjs.io/docs/api/ws#clients `clients` API reference}\n */\n clients: Set<WebSocketClientConnectionProtocol>\n\n /**\n * Adds an event listener to this WebSocket link.\n *\n * @example\n * const chat = ws.link('wss://chat.example.com')\n * chat.addEventListener('connection', listener)\n *\n * @see {@link https://mswjs.io/docs/api/ws#onevent-listener `on()` API reference}\n */\n addEventListener<EventType extends keyof WebSocketHandlerEventMap>(\n event: EventType,\n listener: WebSocketEventListener<EventType>,\n ): WebSocketHandler\n\n /**\n * Broadcasts the given data to all WebSocket clients.\n *\n * @example\n * const service = ws.link('wss://example.com')\n * service.addEventListener('connection', () => {\n * service.broadcast('hello, everyone!')\n * })\n *\n * @see {@link https://mswjs.io/docs/api/ws#broadcastdata `broadcast()` API reference}\n */\n broadcast(data: WebSocketData): void\n\n /**\n * Broadcasts the given data to all WebSocket clients\n * except the ones provided in the `clients` argument.\n *\n * @example\n * const service = ws.link('wss://example.com')\n * service.addEventListener('connection', ({ client }) => {\n * service.broadcastExcept(client, 'hi, the rest of you!')\n * })\n *\n * @see {@link https://mswjs.io/docs/api/ws#broadcastexceptclients-data `broadcast()` API reference}\n */\n broadcastExcept(\n clients:\n | WebSocketClientConnectionProtocol\n | Array<WebSocketClientConnectionProtocol>,\n data: WebSocketData,\n ): void\n}\n\n/**\n * Intercepts outgoing WebSocket connections to the given URL.\n *\n * @example\n * const chat = ws.link('wss://chat.example.com')\n * chat.addEventListener('connection', ({ client }) => {\n * client.send('hello from server!')\n * })\n */\nfunction createWebSocketLinkHandler(url: Path): WebSocketLink {\n invariant(url, 'Expected a WebSocket server URL but got undefined')\n\n invariant(\n isPath(url),\n 'Expected a WebSocket server URL to be a valid path but got %s',\n typeof url,\n )\n\n const clientManager = new WebSocketClientManager(webSocketChannel)\n\n return {\n get clients() {\n return clientManager.clients\n },\n addEventListener(event, listener) {\n const handler = new WebSocketHandler(url)\n\n // Add the connection event listener for when the\n // handler matches and emits a connection event.\n // When that happens, store that connection in the\n // set of all connections for reference.\n handler[kEmitter].on('connection', async ({ client }) => {\n await clientManager.addConnection(client)\n })\n\n // The \"handleWebSocketEvent\" function will invoke\n // the \"run()\" method on the WebSocketHandler.\n // If the handler matches, it will emit the \"connection\"\n // event. Attach the user-defined listener to that event.\n handler[kEmitter].on(event, listener)\n\n return handler\n },\n\n broadcast(data) {\n // This will invoke \"send()\" on the immediate clients\n // in this runtime and post a message to the broadcast channel\n // to trigger send for the clients in other runtimes.\n this.broadcastExcept([], data)\n },\n\n broadcastExcept(clients, data) {\n const ignoreClients = Array.prototype\n .concat(clients)\n .map((client) => client.id)\n\n clientManager.clients.forEach((otherClient) => {\n if (!ignoreClients.includes(otherClient.id)) {\n otherClient.send(data)\n }\n })\n },\n }\n}\n\n/**\n * A namespace to intercept and mock WebSocket connections.\n *\n * @example\n * const chat = ws.link('wss://chat.example.com')\n *\n * @see {@link https://mswjs.io/docs/api/ws `ws` API reference}\n * @see {@link https://mswjs.io/docs/basics/handling-websocket-events Handling WebSocket events}\n */\nexport const ws = {\n link: createWebSocketLinkHandler,\n}\n\nexport { WebSocketData }\n"],"mappings":"AAAA,SAAS,iBAAiB;AAK1B;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP,SAAS,qBAAqB;AAC9B,SAAe,cAAc;AAC7B,SAAS,8BAA8B;AAEvC,MAAM,mBAAmB,IAAI,iBAAiB,8BAA8B;AAE5E,IAAI,cAAc,gBAAgB,GAAG;AAGnC,mBAAiB,MAAM;AACzB;AAuEA,SAAS,2BAA2B,KAA0B;AAC5D,YAAU,KAAK,mDAAmD;AAElE;AAAA,IACE,OAAO,GAAG;AAAA,IACV;AAAA,IACA,OAAO;AAAA,EACT;AAEA,QAAM,gBAAgB,IAAI,uBAAuB,gBAAgB;AAEjE,SAAO;AAAA,IACL,IAAI,UAAU;AACZ,aAAO,cAAc;AAAA,IACvB;AAAA,IACA,iBAAiB,OAAO,UAAU;AAChC,YAAM,UAAU,IAAI,iBAAiB,GAAG;AAMxC,cAAQ,QAAQ,EAAE,GAAG,cAAc,OAAO,EAAE,OAAO,MAAM;AACvD,cAAM,cAAc,cAAc,MAAM;AAAA,MAC1C,CAAC;AAMD,cAAQ,QAAQ,EAAE,GAAG,OAAO,QAAQ;AAEpC,aAAO;AAAA,IACT;AAAA,IAEA,UAAU,MAAM;AAId,WAAK,gBAAgB,CAAC,GAAG,IAAI;AAAA,IAC/B;AAAA,IAEA,gBAAgB,SAAS,MAAM;AAC7B,YAAM,gBAAgB,MAAM,UACzB,OAAO,OAAO,EACd,IAAI,CAAC,WAAW,OAAO,EAAE;AAE5B,oBAAc,QAAQ,QAAQ,CAAC,gBAAgB;AAC7C,YAAI,CAAC,cAAc,SAAS,YAAY,EAAE,GAAG;AAC3C,sBAAY,KAAK,IAAI;AAAA,QACvB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAWO,MAAM,KAAK;AAAA,EAChB,MAAM;AACR;","names":[]}
1
+ {"version":3,"sources":["../../src/core/ws.ts"],"sourcesContent":["import { invariant } from 'outvariant'\nimport type {\n WebSocketData,\n WebSocketClientConnectionProtocol,\n} from '@mswjs/interceptors/WebSocket'\nimport {\n WebSocketHandler,\n kEmitter,\n type WebSocketHandlerEventMap,\n} from './handlers/WebSocketHandler'\nimport { hasRefCounted } from './utils/internal/hasRefCounted'\nimport { type Path, isPath } from './utils/matching/matchRequestUrl'\nimport { WebSocketClientManager } from './ws/WebSocketClientManager'\n\nconst webSocketChannel = new BroadcastChannel('msw:websocket-client-manager')\n\nif (hasRefCounted(webSocketChannel)) {\n // Allows the Node.js thread to exit if it is the only active handle in the event system.\n // https://nodejs.org/api/worker_threads.html#broadcastchannelunref\n webSocketChannel.unref()\n}\n\nexport type WebSocketEventListener<\n EventType extends keyof WebSocketHandlerEventMap,\n> = (...args: WebSocketHandlerEventMap[EventType]) => void\n\nexport type WebSocketLink = {\n /**\n * A set of all WebSocket clients connected\n * to this link.\n *\n * @see {@link https://mswjs.io/docs/api/ws#clients `clients` API reference}\n */\n clients: Set<WebSocketClientConnectionProtocol>\n\n /**\n * Adds an event listener to this WebSocket link.\n *\n * @example\n * const chat = ws.link('wss://chat.example.com')\n * chat.addEventListener('connection', listener)\n *\n * @see {@link https://mswjs.io/docs/api/ws#onevent-listener `on()` API reference}\n */\n addEventListener: <EventType extends keyof WebSocketHandlerEventMap>(\n event: EventType,\n listener: WebSocketEventListener<EventType>,\n ) => WebSocketHandler\n\n /**\n * Broadcasts the given data to all WebSocket clients.\n *\n * @example\n * const service = ws.link('wss://example.com')\n * service.addEventListener('connection', () => {\n * service.broadcast('hello, everyone!')\n * })\n *\n * @see {@link https://mswjs.io/docs/api/ws#broadcastdata `broadcast()` API reference}\n */\n broadcast: (data: WebSocketData) => void\n\n /**\n * Broadcasts the given data to all WebSocket clients\n * except the ones provided in the `clients` argument.\n *\n * @example\n * const service = ws.link('wss://example.com')\n * service.addEventListener('connection', ({ client }) => {\n * service.broadcastExcept(client, 'hi, the rest of you!')\n * })\n *\n * @see {@link https://mswjs.io/docs/api/ws#broadcastexceptclients-data `broadcast()` API reference}\n */\n broadcastExcept: (\n clients:\n | WebSocketClientConnectionProtocol\n | Array<WebSocketClientConnectionProtocol>,\n data: WebSocketData,\n ) => void\n}\n\n/**\n * Intercepts outgoing WebSocket connections to the given URL.\n *\n * @example\n * const chat = ws.link('wss://chat.example.com')\n * chat.addEventListener('connection', ({ client }) => {\n * client.send('hello from server!')\n * })\n */\nfunction createWebSocketLinkHandler(url: Path): WebSocketLink {\n invariant(url, 'Expected a WebSocket server URL but got undefined')\n\n invariant(\n isPath(url),\n 'Expected a WebSocket server URL to be a valid path but got %s',\n typeof url,\n )\n\n const clientManager = new WebSocketClientManager(webSocketChannel)\n\n return {\n get clients() {\n return clientManager.clients\n },\n addEventListener(event, listener) {\n const handler = new WebSocketHandler(url)\n\n // Add the connection event listener for when the\n // handler matches and emits a connection event.\n // When that happens, store that connection in the\n // set of all connections for reference.\n handler[kEmitter].on('connection', async ({ client }) => {\n await clientManager.addConnection(client)\n })\n\n // The \"handleWebSocketEvent\" function will invoke\n // the \"run()\" method on the WebSocketHandler.\n // If the handler matches, it will emit the \"connection\"\n // event. Attach the user-defined listener to that event.\n handler[kEmitter].on(event, listener)\n\n return handler\n },\n\n broadcast(data) {\n // This will invoke \"send()\" on the immediate clients\n // in this runtime and post a message to the broadcast channel\n // to trigger send for the clients in other runtimes.\n this.broadcastExcept([], data)\n },\n\n broadcastExcept(clients, data) {\n const ignoreClients = Array.prototype\n .concat(clients)\n .map((client) => client.id)\n\n clientManager.clients.forEach((otherClient) => {\n if (!ignoreClients.includes(otherClient.id)) {\n otherClient.send(data)\n }\n })\n },\n }\n}\n\n/**\n * A namespace to intercept and mock WebSocket connections.\n *\n * @example\n * const chat = ws.link('wss://chat.example.com')\n *\n * @see {@link https://mswjs.io/docs/api/ws `ws` API reference}\n * @see {@link https://mswjs.io/docs/basics/handling-websocket-events Handling WebSocket events}\n */\nexport const ws = {\n link: createWebSocketLinkHandler,\n}\n\nexport { WebSocketData }\n"],"mappings":"AAAA,SAAS,iBAAiB;AAK1B;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP,SAAS,qBAAqB;AAC9B,SAAoB,cAAc;AAClC,SAAS,8BAA8B;AAEvC,MAAM,mBAAmB,IAAI,iBAAiB,8BAA8B;AAE5E,IAAI,cAAc,gBAAgB,GAAG;AAGnC,mBAAiB,MAAM;AACzB;AAuEA,SAAS,2BAA2B,KAA0B;AAC5D,YAAU,KAAK,mDAAmD;AAElE;AAAA,IACE,OAAO,GAAG;AAAA,IACV;AAAA,IACA,OAAO;AAAA,EACT;AAEA,QAAM,gBAAgB,IAAI,uBAAuB,gBAAgB;AAEjE,SAAO;AAAA,IACL,IAAI,UAAU;AACZ,aAAO,cAAc;AAAA,IACvB;AAAA,IACA,iBAAiB,OAAO,UAAU;AAChC,YAAM,UAAU,IAAI,iBAAiB,GAAG;AAMxC,cAAQ,QAAQ,EAAE,GAAG,cAAc,OAAO,EAAE,OAAO,MAAM;AACvD,cAAM,cAAc,cAAc,MAAM;AAAA,MAC1C,CAAC;AAMD,cAAQ,QAAQ,EAAE,GAAG,OAAO,QAAQ;AAEpC,aAAO;AAAA,IACT;AAAA,IAEA,UAAU,MAAM;AAId,WAAK,gBAAgB,CAAC,GAAG,IAAI;AAAA,IAC/B;AAAA,IAEA,gBAAgB,SAAS,MAAM;AAC7B,YAAM,gBAAgB,MAAM,UACzB,OAAO,OAAO,EACd,IAAI,CAAC,WAAW,OAAO,EAAE;AAE5B,oBAAc,QAAQ,QAAQ,CAAC,gBAAgB;AAC7C,YAAI,CAAC,cAAc,SAAS,YAAY,EAAE,GAAG;AAC3C,sBAAY,KAAK,IAAI;AAAA,QACvB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAWO,MAAM,KAAK;AAAA,EAChB,MAAM;AACR;","names":[]}