msw 2.12.14 → 2.13.1

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 (266) 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/request/onUnhandledRequest.d.mts +2 -2
  143. package/lib/core/utils/request/onUnhandledRequest.d.ts +2 -2
  144. package/lib/core/utils/request/onUnhandledRequest.js.map +1 -1
  145. package/lib/core/utils/request/onUnhandledRequest.mjs.map +1 -1
  146. package/lib/core/ws/handleWebSocketEvent.d.mts +1 -1
  147. package/lib/core/ws/handleWebSocketEvent.d.ts +1 -1
  148. package/lib/core/ws/handleWebSocketEvent.js +1 -1
  149. package/lib/core/ws/handleWebSocketEvent.js.map +1 -1
  150. package/lib/core/ws/handleWebSocketEvent.mjs +1 -1
  151. package/lib/core/ws/handleWebSocketEvent.mjs.map +1 -1
  152. package/lib/core/ws/utils/attachWebSocketLogger.d.mts +1 -1
  153. package/lib/core/ws/utils/attachWebSocketLogger.d.ts +1 -1
  154. package/lib/core/ws/utils/attachWebSocketLogger.js +39 -10
  155. package/lib/core/ws/utils/attachWebSocketLogger.js.map +1 -1
  156. package/lib/core/ws/utils/attachWebSocketLogger.mjs +39 -10
  157. package/lib/core/ws/utils/attachWebSocketLogger.mjs.map +1 -1
  158. package/lib/core/ws.d.mts +3 -3
  159. package/lib/core/ws.d.ts +3 -3
  160. package/lib/core/ws.js.map +1 -1
  161. package/lib/core/ws.mjs.map +1 -1
  162. package/lib/iife/index.js +2021 -1432
  163. package/lib/iife/index.js.map +1 -1
  164. package/lib/mockServiceWorker.js +1 -1
  165. package/lib/native/index.d.mts +21 -29
  166. package/lib/native/index.d.ts +21 -29
  167. package/lib/native/index.js +48 -116
  168. package/lib/native/index.js.map +1 -1
  169. package/lib/native/index.mjs +51 -118
  170. package/lib/native/index.mjs.map +1 -1
  171. package/lib/node/index.d.mts +55 -33
  172. package/lib/node/index.d.ts +55 -33
  173. package/lib/node/index.js +152 -154
  174. package/lib/node/index.js.map +1 -1
  175. package/lib/node/index.mjs +156 -156
  176. package/lib/node/index.mjs.map +1 -1
  177. package/package.json +10 -2
  178. package/src/browser/{setupWorker/glossary.ts → glossary.ts} +16 -33
  179. package/src/browser/index.ts +2 -3
  180. package/src/browser/{setupWorker/setupWorker.node.test.ts → setup-worker.node.test.ts} +2 -4
  181. package/src/browser/setup-worker.ts +148 -0
  182. package/src/browser/sources/fallback-http-source.ts +56 -0
  183. package/src/browser/sources/service-worker-source.ts +455 -0
  184. package/src/browser/tsconfig.browser.json +7 -2
  185. package/src/browser/utils/deserializeRequest.ts +1 -1
  186. package/src/browser/{setupWorker/start/utils/getWorkerByRegistration.ts → utils/get-worker-by-registration.ts} +3 -1
  187. package/src/browser/{setupWorker/start/utils/getWorkerInstance.ts → utils/get-worker-instance.ts} +4 -4
  188. package/src/browser/utils/pruneGetRequestBody.test.ts +1 -3
  189. package/src/browser/utils/pruneGetRequestBody.ts +1 -1
  190. package/src/browser/utils/validate-worker-scope.ts +19 -0
  191. package/src/browser/utils/workerChannel.ts +2 -2
  192. package/src/core/experimental/compat.ts +50 -0
  193. package/src/core/experimental/define-network.test.ts +124 -0
  194. package/src/core/experimental/define-network.ts +215 -0
  195. package/src/core/experimental/frames/http-frame.test.ts +360 -0
  196. package/src/core/experimental/frames/http-frame.ts +271 -0
  197. package/src/core/experimental/frames/network-frame.ts +64 -0
  198. package/src/core/experimental/frames/websocket-frame.test.ts +280 -0
  199. package/src/core/experimental/frames/websocket-frame.ts +188 -0
  200. package/src/core/experimental/handlers-controller.test.ts +198 -0
  201. package/src/core/experimental/handlers-controller.ts +145 -0
  202. package/src/core/experimental/index.ts +16 -0
  203. package/src/core/experimental/on-unhandled-frame.test.ts +360 -0
  204. package/src/core/experimental/on-unhandled-frame.ts +110 -0
  205. package/src/core/experimental/request-utils.test.ts +70 -0
  206. package/src/core/experimental/request-utils.ts +39 -0
  207. package/src/core/experimental/setup-api.ts +59 -0
  208. package/src/core/experimental/sources/interceptor-source.ts +185 -0
  209. package/src/core/experimental/sources/network-source.test.ts +74 -0
  210. package/src/core/experimental/sources/network-source.ts +56 -0
  211. package/src/core/handlers/RequestHandler.ts +9 -10
  212. package/src/core/handlers/WebSocketHandler.ts +27 -11
  213. package/src/core/index.ts +3 -7
  214. package/src/core/sharedOptions.ts +9 -4
  215. package/src/core/sse.ts +1 -1
  216. package/src/core/utils/cookieStore.ts +2 -1
  217. package/src/core/utils/internal/isHandlerKind.test.ts +20 -22
  218. package/src/core/utils/internal/isHandlerKind.ts +5 -9
  219. package/src/core/utils/request/onUnhandledRequest.ts +2 -2
  220. package/src/core/ws/WebSocketClientManager.test.ts +2 -10
  221. package/src/core/ws/handleWebSocketEvent.ts +5 -1
  222. package/src/core/ws/utils/attachWebSocketLogger.ts +43 -11
  223. package/src/core/ws.test.ts +1 -3
  224. package/src/core/ws.ts +6 -6
  225. package/src/iife/index.ts +1 -1
  226. package/src/native/index.ts +34 -11
  227. package/src/node/async-handlers-controller.test.ts +50 -0
  228. package/src/node/async-handlers-controller.ts +69 -0
  229. package/src/node/glossary.ts +19 -18
  230. package/src/node/index.ts +6 -2
  231. package/src/node/setup-server-common.ts +100 -0
  232. package/src/node/setup-server.ts +91 -0
  233. package/src/tsconfig.core.json +8 -0
  234. package/src/tsconfig.node.json +8 -3
  235. package/src/tsconfig.src.json +0 -2
  236. package/src/tsconfig.worker.json +2 -1
  237. package/lib/core/SetupApi.d.mts +0 -44
  238. package/lib/core/SetupApi.d.ts +0 -44
  239. package/lib/core/SetupApi.js +0 -112
  240. package/lib/core/SetupApi.js.map +0 -1
  241. package/lib/core/SetupApi.mjs +0 -92
  242. package/lib/core/SetupApi.mjs.map +0 -1
  243. package/lib/core/handlers/common.d.mts +0 -3
  244. package/lib/core/handlers/common.d.ts +0 -3
  245. package/lib/core/handlers/common.js.map +0 -1
  246. package/lib/core/handlers/common.mjs +0 -1
  247. package/lib/core/handlers/common.mjs.map +0 -1
  248. package/src/browser/setupWorker/setupWorker.ts +0 -184
  249. package/src/browser/setupWorker/start/createFallbackRequestListener.ts +0 -71
  250. package/src/browser/setupWorker/start/createRequestListener.ts +0 -138
  251. package/src/browser/setupWorker/start/createResponseListener.ts +0 -57
  252. package/src/browser/setupWorker/start/createStartHandler.ts +0 -137
  253. package/src/browser/setupWorker/start/utils/enableMocking.ts +0 -30
  254. package/src/browser/setupWorker/start/utils/prepareStartHandler.test.ts +0 -59
  255. package/src/browser/setupWorker/start/utils/prepareStartHandler.ts +0 -44
  256. package/src/browser/setupWorker/start/utils/printStartMessage.test.ts +0 -84
  257. package/src/browser/setupWorker/start/utils/printStartMessage.ts +0 -51
  258. package/src/browser/setupWorker/start/utils/validateWorkerScope.ts +0 -18
  259. package/src/browser/setupWorker/stop/utils/printStopMessage.test.ts +0 -26
  260. package/src/browser/setupWorker/stop/utils/printStopMessage.ts +0 -13
  261. package/src/browser/utils/checkWorkerIntegrity.ts +0 -42
  262. package/src/core/SetupApi.ts +0 -127
  263. package/src/core/handlers/common.ts +0 -1
  264. package/src/node/SetupServerApi.ts +0 -87
  265. package/src/node/SetupServerCommonApi.ts +0 -169
  266. package/src/node/setupServer.ts +0 -15
@@ -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":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,sBAAyB;AACzB,0BAA6B;AAC7B,yBAA4B;AAC5B,8BAAiC;AACjC,2BAA8B;AAEvB,MAAM,SAAS;AAAA,EACpB,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,UAAU;AAAA,EACV,QAAQ;AACV;AAEO,SAAS,sBACd,YACM;AACN,QAAM,EAAE,QAAQ,OAAO,IAAI;AAE3B,oBAAkB,MAAM;AASxB,SAAO,iBAAiB,WAAW,CAAC,UAAU;AAC5C,6BAAyB,KAAK;AAAA,EAChC,CAAC;AAED,SAAO,iBAAiB,SAAS,CAAC,UAAU;AAC1C,uBAAmB,KAAK;AAAA,EAC1B,CAAC;AAGD,SAAO,OAAO,iBAAiB,SAAS,CAAC,UAAU;AACjD,mBAAe,KAAK;AAAA,EACtB,CAAC;AAED,SAAO,OAAO,IAAI,MAAM,OAAO,MAAM;AAAA,IACnC,MAAM,QAAQ,SAAS,MAAM;AAC3B,YAAM,CAAC,IAAI,IAAI;AACf,YAAM,eAAe,IAAI,aAAa,WAAW,EAAE,KAAK,CAAC;AACzD,aAAO,iBAAiB,cAAc;AAAA,QACpC,eAAe;AAAA,UACb,YAAY;AAAA,UACZ,UAAU;AAAA,UACV,OAAO,OAAO;AAAA,QAChB;AAAA,QACA,QAAQ;AAAA,UACN,YAAY;AAAA,UACZ,UAAU;AAAA,UACV,OAAO,OAAO;AAAA,QAChB;AAAA,MACF,CAAC;AAED,qBAAe,MAAM;AACnB,uCAA+B,YAAY;AAAA,MAC7C,CAAC;AAED,aAAO,QAAQ,MAAM,QAAQ,SAAS,IAAI;AAAA,IAC5C;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AACJ,aAAO,iBAAiB,WAAW,CAAC,UAAU;AAC5C,iCAAyB,KAAK;AAAA,MAChC,CAAC;AAAA,IACH;AAAA,IACA,EAAE,MAAM,KAAK;AAAA,EACf;AAIA,SAAO,OAAO,IAAI,MAAM,OAAO,MAAM;AAAA,IACnC,MAAM,QAAQ,SAAS,MAAM;AAC3B,YAAM,CAAC,IAAI,IAAI;AACf,YAAM,eAAe,IAAI,aAAa,WAAW,EAAE,KAAK,CAAC;AACzD,aAAO,iBAAiB,cAAc;AAAA,QACpC,eAAe;AAAA,UACb,YAAY;AAAA,UACZ,UAAU;AAAA,UACV,OAAO,OAAO;AAAA,QAChB;AAAA,QACA,QAAQ;AAAA,UACN,YAAY;AAAA,UACZ,UAAU;AAAA,UACV,OAAO,OAAO;AAAA,QAChB;AAAA,MACF,CAAC;AAED,qCAA+B,YAAY;AAE3C,aAAO,QAAQ,MAAM,QAAQ,SAAS,IAAI;AAAA,IAC5C;AAAA,EACF,CAAC;AACH;AAQO,SAAS,kBAAkB,QAAmC;AACnE,QAAM,gBAAY,gCAAY,OAAO,GAAG;AAExC,UAAQ;AAAA,IACN,yBAAS,cAAc,OAAG,kCAAa,CAAC,eAAU,SAAS,EAAE;AAAA,IAC7D,SAAS,OAAO,MAAM;AAAA,IACtB;AAAA,EACF;AAEA,UAAQ,IAAI,WAAW,OAAO,MAAM;AACpC,UAAQ,SAAS;AACnB;AAEA,SAAS,mBAAmB,OAAmB;AAC7C,QAAM,SAAS,MAAM;AACrB,QAAM,gBAAY,gCAAY,OAAO,GAAG;AAExC,UAAQ;AAAA,IACN,yBAAS;AAAA,MACP,OAAG,kCAAa,EAAE,cAAc,KAAK,CAAC,CAAC,eAAU,SAAS;AAAA,IAC5D;AAAA,IACA,SAAS,OAAO,MAAM;AAAA,IACtB;AAAA,EACF;AAEA,UAAQ,IAAI,KAAK;AACjB,UAAQ,SAAS;AACnB;AAEA,SAAS,eAAe,OAAc;AACpC,QAAM,SAAS,MAAM;AACrB,QAAM,gBAAY,gCAAY,OAAO,GAAG;AAExC,UAAQ;AAAA,IACN,yBAAS;AAAA,MACP,OAAG,kCAAa,EAAE,cAAc,KAAK,CAAC,CAAC,aAAe,SAAS;AAAA,IACjE;AAAA,IACA,SAAS,OAAO,MAAM;AAAA,IACtB;AAAA,EACF;AAEA,UAAQ,IAAI,KAAK;AACjB,UAAQ,SAAS;AACnB;AAKA,eAAe,yBAAyB,OAAoC;AAC1E,QAAM,iBAAa,0CAAiB,MAAM,IAAI;AAC9C,QAAM,aAAa,UAAM,oCAAc,MAAM,IAAI;AACjD,QAAM,QAAQ,MAAM,mBAAmB,WAAM;AAE7C,UAAQ;AAAA,IACN,yBAAS;AAAA,MACP,OAAG,kCAAa,EAAE,cAAc,KAAK,CAAC,CAAC,MAAM,KAAK,MAAM,UAAU,MAAM,UAAU;AAAA,IACpF;AAAA,IACA,SAAS,OAAO,QAAQ;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,UAAQ,IAAI,KAAK;AACjB,UAAQ,SAAS;AACnB;AAMA,eAAe,+BACb,OACA;AACA,QAAM,iBAAa,0CAAiB,MAAM,IAAI;AAC9C,QAAM,aAAa,UAAM,oCAAc,MAAM,IAAI;AAEjD,UAAQ;AAAA,IACN,yBAAS;AAAA,MACP,OAAG,kCAAa,EAAE,cAAc,KAAK,CAAC,CAAC,eAAU,UAAU,MAAM,UAAU;AAAA,IAC7E;AAAA,IACA,SAAS,OAAO,MAAM;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,UAAQ,IAAI,KAAK;AACjB,UAAQ,SAAS;AACnB;AAMA,eAAe,+BACb,OACA;AACA,QAAM,iBAAa,0CAAiB,MAAM,IAAI;AAC9C,QAAM,aAAa,UAAM,oCAAc,MAAM,IAAI;AAEjD,UAAQ;AAAA,IACN,yBAAS;AAAA,MACP,OAAG,kCAAa,EAAE,cAAc,KAAK,CAAC,CAAC,eAAU,UAAU,MAAM,UAAU;AAAA,IAC7E;AAAA,IACA,SAAS,OAAO,MAAM;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,UAAQ,IAAI,KAAK;AACjB,UAAQ,SAAS;AACnB;AAEA,eAAe,yBAAyB,OAAoC;AAC1E,QAAM,iBAAa,0CAAiB,MAAM,IAAI;AAC9C,QAAM,aAAa,UAAM,oCAAc,MAAM,IAAI;AACjD,QAAM,QAAQ,MAAM,mBAAmB,WAAM;AAE7C,UAAQ;AAAA,IACN,yBAAS;AAAA,MACP,OAAG,kCAAa,EAAE,cAAc,KAAK,CAAC,CAAC,MAAM,KAAK,MAAM,UAAU,MAAM,UAAU;AAAA,IACpF;AAAA,IACA,SAAS,OAAO,QAAQ;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,UAAQ,IAAI,KAAK;AACjB,UAAQ,SAAS;AACnB;","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":"AAKA,SAAS,gBAAgB;AACzB,SAAS,oBAAoB;AAC7B,SAAS,mBAAmB;AAC5B,SAAS,wBAAwB;AACjC,SAAS,qBAAqB;AAEvB,MAAM,SAAS;AAAA,EACpB,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,UAAU;AAAA,EACV,QAAQ;AACV;AAEO,SAAS,sBACd,YACY;AACZ,QAAM,EAAE,QAAQ,OAAO,IAAI;AAC3B,QAAM,aAAa,IAAI,gBAAgB;AAEvC,oBAAkB,MAAM;AASxB,SAAO;AAAA,IACL;AAAA,IACA,CAAC,UAAU;AACT,+BAAyB,KAAK;AAAA,IAChC;AAAA,IACA,EAAE,QAAQ,WAAW,OAAO;AAAA,EAC9B;AAEA,SAAO;AAAA,IACL;AAAA,IACA,CAAC,UAAU;AACT,yBAAmB,KAAK;AAAA,IAC1B;AAAA,IACA,EAAE,QAAQ,WAAW,OAAO;AAAA,EAC9B;AAGA,SAAO,OAAO;AAAA,IACZ;AAAA,IACA,CAAC,UAAU;AACT,qBAAe,KAAK;AAAA,IACtB;AAAA,IACA,EAAE,QAAQ,WAAW,OAAO;AAAA,EAC9B;AAEA,QAAM,EAAE,MAAM,mBAAmB,IAAI;AACrC,SAAO,OAAO,IAAI,MAAM,OAAO,MAAM;AAAA,IACnC,MAAM,QAAQ,SAAS,MAAM;AAC3B,YAAM,CAAC,IAAI,IAAI;AACf,YAAM,eAAe,IAAI,aAAa,WAAW,EAAE,KAAK,CAAC;AACzD,aAAO,iBAAiB,cAAc;AAAA,QACpC,eAAe;AAAA,UACb,YAAY;AAAA,UACZ,UAAU;AAAA,UACV,OAAO,OAAO;AAAA,QAChB;AAAA,QACA,QAAQ;AAAA,UACN,YAAY;AAAA,UACZ,UAAU;AAAA,UACV,OAAO,OAAO;AAAA,QAChB;AAAA,MACF,CAAC;AAED,qBAAe,MAAM;AACnB,uCAA+B,YAAY;AAAA,MAC7C,CAAC;AAED,aAAO,QAAQ,MAAM,QAAQ,SAAS,IAAI;AAAA,IAC5C;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AACJ,aAAO,iBAAiB,WAAW,CAAC,UAAU;AAC5C,iCAAyB,KAAK;AAAA,MAChC,CAAC;AAAA,IACH;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,QAAQ,WAAW;AAAA,IACrB;AAAA,EACF;AAIA,QAAM,EAAE,MAAM,mBAAmB,IAAI;AACrC,SAAO,OAAO,IAAI,MAAM,OAAO,MAAM;AAAA,IACnC,MAAM,QAAQ,SAAS,MAAM;AAC3B,YAAM,CAAC,IAAI,IAAI;AACf,YAAM,eAAe,IAAI,aAAa,WAAW,EAAE,KAAK,CAAC;AACzD,aAAO,iBAAiB,cAAc;AAAA,QACpC,eAAe;AAAA,UACb,YAAY;AAAA,UACZ,UAAU;AAAA,UACV,OAAO,OAAO;AAAA,QAChB;AAAA,QACA,QAAQ;AAAA,UACN,YAAY;AAAA,UACZ,UAAU;AAAA,UACV,OAAO,OAAO;AAAA,QAChB;AAAA,MACF,CAAC;AAED,qCAA+B,YAAY;AAE3C,aAAO,QAAQ,MAAM,QAAQ,SAAS,IAAI;AAAA,IAC5C;AAAA,EACF,CAAC;AAGD,aAAW,OAAO;AAAA,IAChB;AAAA,IACA,MAAM;AACJ,aAAO,OAAO;AACd,aAAO,OAAO;AAAA,IAChB;AAAA,IACA,EAAE,MAAM,KAAK;AAAA,EACf;AAEA,SAAO,MAAM;AACX,eAAW,MAAM;AAAA,EACnB;AACF;AAQO,SAAS,kBAAkB,QAAmC;AACnE,QAAM,YAAY,YAAY,OAAO,GAAG;AAExC,UAAQ;AAAA,IACN,SAAS,cAAc,GAAG,aAAa,CAAC,eAAU,SAAS,EAAE;AAAA,IAC7D,SAAS,OAAO,MAAM;AAAA,IACtB;AAAA,EACF;AAEA,UAAQ,IAAI,WAAW,OAAO,MAAM;AACpC,UAAQ,SAAS;AACnB;AAEA,SAAS,mBAAmB,OAAmB;AAC7C,QAAM,SAAS,MAAM;AACrB,QAAM,YAAY,YAAY,OAAO,GAAG;AAExC,UAAQ;AAAA,IACN,SAAS;AAAA,MACP,GAAG,aAAa,EAAE,cAAc,KAAK,CAAC,CAAC,eAAU,SAAS;AAAA,IAC5D;AAAA,IACA,SAAS,OAAO,MAAM;AAAA,IACtB;AAAA,EACF;AAEA,UAAQ,IAAI,KAAK;AACjB,UAAQ,SAAS;AACnB;AAEA,SAAS,eAAe,OAAc;AACpC,QAAM,SAAS,MAAM;AACrB,QAAM,YAAY,YAAY,OAAO,GAAG;AAExC,UAAQ;AAAA,IACN,SAAS;AAAA,MACP,GAAG,aAAa,EAAE,cAAc,KAAK,CAAC,CAAC,aAAe,SAAS;AAAA,IACjE;AAAA,IACA,SAAS,OAAO,MAAM;AAAA,IACtB;AAAA,EACF;AAEA,UAAQ,IAAI,KAAK;AACjB,UAAQ,SAAS;AACnB;AAKA,eAAe,yBAAyB,OAAoC;AAC1E,QAAM,aAAa,iBAAiB,MAAM,IAAI;AAC9C,QAAM,aAAa,MAAM,cAAc,MAAM,IAAI;AACjD,QAAM,QAAQ,MAAM,mBAAmB,WAAM;AAE7C,UAAQ;AAAA,IACN,SAAS;AAAA,MACP,GAAG,aAAa,EAAE,cAAc,KAAK,CAAC,CAAC,MAAM,KAAK,MAAM,UAAU,MAAM,UAAU;AAAA,IACpF;AAAA,IACA,SAAS,OAAO,QAAQ;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,UAAQ,IAAI,KAAK;AACjB,UAAQ,SAAS;AACnB;AAMA,eAAe,+BACb,OACA;AACA,QAAM,aAAa,iBAAiB,MAAM,IAAI;AAC9C,QAAM,aAAa,MAAM,cAAc,MAAM,IAAI;AAEjD,UAAQ;AAAA,IACN,SAAS;AAAA,MACP,GAAG,aAAa,EAAE,cAAc,KAAK,CAAC,CAAC,eAAU,UAAU,MAAM,UAAU;AAAA,IAC7E;AAAA,IACA,SAAS,OAAO,MAAM;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,UAAQ,IAAI,KAAK;AACjB,UAAQ,SAAS;AACnB;AAMA,eAAe,+BACb,OACA;AACA,QAAM,aAAa,iBAAiB,MAAM,IAAI;AAC9C,QAAM,aAAa,MAAM,cAAc,MAAM,IAAI;AAEjD,UAAQ;AAAA,IACN,SAAS;AAAA,MACP,GAAG,aAAa,EAAE,cAAc,KAAK,CAAC,CAAC,eAAU,UAAU,MAAM,UAAU;AAAA,IAC7E;AAAA,IACA,SAAS,OAAO,MAAM;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,UAAQ,IAAI,KAAK;AACjB,UAAQ,SAAS;AACnB;AAEA,eAAe,yBAAyB,OAAoC;AAC1E,QAAM,aAAa,iBAAiB,MAAM,IAAI;AAC9C,QAAM,aAAa,MAAM,cAAc,MAAM,IAAI;AACjD,QAAM,QAAQ,MAAM,mBAAmB,WAAM;AAE7C,UAAQ;AAAA,IACN,SAAS;AAAA,MACP,GAAG,aAAa,EAAE,cAAc,KAAK,CAAC,CAAC,MAAM,KAAK,MAAM,UAAU,MAAM,UAAU;AAAA,IACpF;AAAA,IACA,SAAS,OAAO,QAAQ;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,UAAQ,IAAI,KAAK;AACjB,UAAQ,SAAS;AACnB;","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":[]}