msw 2.11.0 → 2.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/lib/browser/index.d.mts +0 -3
  2. package/lib/browser/index.d.ts +0 -3
  3. package/lib/browser/index.js +503 -294
  4. package/lib/browser/index.js.map +1 -1
  5. package/lib/browser/index.mjs +503 -294
  6. package/lib/browser/index.mjs.map +1 -1
  7. package/lib/core/{HttpResponse-DiuKTgC7.d.mts → HttpResponse-B4YmE-GJ.d.mts} +1 -1
  8. package/lib/core/{HttpResponse-DlQEvD4q.d.ts → HttpResponse-BbwAqLE_.d.ts} +1 -1
  9. package/lib/core/HttpResponse.d.mts +1 -1
  10. package/lib/core/HttpResponse.d.ts +1 -1
  11. package/lib/core/HttpResponse.js.map +1 -1
  12. package/lib/core/HttpResponse.mjs.map +1 -1
  13. package/lib/core/SetupApi.d.mts +1 -1
  14. package/lib/core/SetupApi.d.ts +1 -1
  15. package/lib/core/getResponse.d.mts +1 -1
  16. package/lib/core/getResponse.d.ts +1 -1
  17. package/lib/core/graphql.d.mts +1 -1
  18. package/lib/core/graphql.d.ts +1 -1
  19. package/lib/core/handlers/GraphQLHandler.d.mts +1 -1
  20. package/lib/core/handlers/GraphQLHandler.d.ts +1 -1
  21. package/lib/core/handlers/GraphQLHandler.js.map +1 -1
  22. package/lib/core/handlers/GraphQLHandler.mjs.map +1 -1
  23. package/lib/core/handlers/HttpHandler.d.mts +1 -1
  24. package/lib/core/handlers/HttpHandler.d.ts +1 -1
  25. package/lib/core/handlers/HttpHandler.js.map +1 -1
  26. package/lib/core/handlers/HttpHandler.mjs.map +1 -1
  27. package/lib/core/handlers/RequestHandler.d.mts +1 -1
  28. package/lib/core/handlers/RequestHandler.d.ts +1 -1
  29. package/lib/core/http.d.mts +1 -1
  30. package/lib/core/http.d.ts +1 -1
  31. package/lib/core/index.d.mts +1 -1
  32. package/lib/core/index.d.ts +1 -1
  33. package/lib/core/passthrough.d.mts +1 -1
  34. package/lib/core/passthrough.d.ts +1 -1
  35. package/lib/core/utils/HttpResponse/decorators.d.mts +1 -1
  36. package/lib/core/utils/HttpResponse/decorators.d.ts +1 -1
  37. package/lib/core/utils/cookieStore.d.mts +10 -2
  38. package/lib/core/utils/cookieStore.d.ts +10 -2
  39. package/lib/core/utils/cookieStore.js +49 -146
  40. package/lib/core/utils/cookieStore.js.map +1 -1
  41. package/lib/core/utils/cookieStore.mjs +53 -136
  42. package/lib/core/utils/cookieStore.mjs.map +1 -1
  43. package/lib/core/utils/executeHandlers.d.mts +1 -1
  44. package/lib/core/utils/executeHandlers.d.ts +1 -1
  45. package/lib/core/utils/handleRequest.d.mts +1 -1
  46. package/lib/core/utils/handleRequest.d.ts +1 -1
  47. package/lib/core/utils/handleRequest.js +1 -1
  48. package/lib/core/utils/handleRequest.js.map +1 -1
  49. package/lib/core/utils/handleRequest.mjs +1 -1
  50. package/lib/core/utils/handleRequest.mjs.map +1 -1
  51. package/lib/core/utils/internal/devUtils.js.map +1 -1
  52. package/lib/core/utils/internal/devUtils.mjs.map +1 -1
  53. package/lib/core/utils/internal/getCallFrame.js +2 -2
  54. package/lib/core/utils/internal/getCallFrame.js.map +1 -1
  55. package/lib/core/utils/internal/getCallFrame.mjs +2 -2
  56. package/lib/core/utils/internal/getCallFrame.mjs.map +1 -1
  57. package/lib/core/utils/internal/isHandlerKind.d.mts +1 -1
  58. package/lib/core/utils/internal/isHandlerKind.d.ts +1 -1
  59. package/lib/core/utils/internal/parseGraphQLRequest.d.mts +1 -1
  60. package/lib/core/utils/internal/parseGraphQLRequest.d.ts +1 -1
  61. package/lib/core/utils/internal/parseGraphQLRequest.js +1 -0
  62. package/lib/core/utils/internal/parseGraphQLRequest.js.map +1 -1
  63. package/lib/core/utils/internal/parseGraphQLRequest.mjs +1 -0
  64. package/lib/core/utils/internal/parseGraphQLRequest.mjs.map +1 -1
  65. package/lib/core/utils/internal/parseMultipartData.d.mts +1 -1
  66. package/lib/core/utils/internal/parseMultipartData.d.ts +1 -1
  67. package/lib/core/utils/internal/requestHandlerUtils.d.mts +1 -1
  68. package/lib/core/utils/internal/requestHandlerUtils.d.ts +1 -1
  69. package/lib/core/utils/matching/matchRequestUrl.js +1 -1
  70. package/lib/core/utils/matching/matchRequestUrl.js.map +1 -1
  71. package/lib/core/utils/matching/matchRequestUrl.mjs +1 -1
  72. package/lib/core/utils/matching/matchRequestUrl.mjs.map +1 -1
  73. package/lib/core/utils/request/getRequestCookies.js +1 -1
  74. package/lib/core/utils/request/getRequestCookies.js.map +1 -1
  75. package/lib/core/utils/request/getRequestCookies.mjs +1 -1
  76. package/lib/core/utils/request/getRequestCookies.mjs.map +1 -1
  77. package/lib/core/utils/request/storeResponseCookies.d.mts +1 -1
  78. package/lib/core/utils/request/storeResponseCookies.d.ts +1 -1
  79. package/lib/core/utils/request/storeResponseCookies.js +2 -2
  80. package/lib/core/utils/request/storeResponseCookies.js.map +1 -1
  81. package/lib/core/utils/request/storeResponseCookies.mjs +2 -2
  82. package/lib/core/utils/request/storeResponseCookies.mjs.map +1 -1
  83. package/lib/core/utils/url/cleanUrl.js +1 -1
  84. package/lib/core/utils/url/cleanUrl.js.map +1 -1
  85. package/lib/core/utils/url/cleanUrl.mjs +1 -1
  86. package/lib/core/utils/url/cleanUrl.mjs.map +1 -1
  87. package/lib/core/utils/url/isAbsoluteUrl.js +1 -1
  88. package/lib/core/utils/url/isAbsoluteUrl.js.map +1 -1
  89. package/lib/core/utils/url/isAbsoluteUrl.mjs +1 -1
  90. package/lib/core/utils/url/isAbsoluteUrl.mjs.map +1 -1
  91. package/lib/core/ws/WebSocketIndexedDBClientStore.js.map +1 -1
  92. package/lib/core/ws/WebSocketIndexedDBClientStore.mjs.map +1 -1
  93. package/lib/core/ws/handleWebSocketEvent.d.mts +1 -1
  94. package/lib/core/ws/handleWebSocketEvent.d.ts +1 -1
  95. package/lib/core/ws/utils/attachWebSocketLogger.js.map +1 -1
  96. package/lib/core/ws/utils/attachWebSocketLogger.mjs.map +1 -1
  97. package/lib/iife/index.js +6885 -16153
  98. package/lib/iife/index.js.map +1 -1
  99. package/lib/mockServiceWorker.js +16 -12
  100. package/lib/node/index.js.map +1 -1
  101. package/lib/node/index.mjs.map +1 -1
  102. package/package.json +22 -15
  103. package/src/browser/setupWorker/glossary.ts +9 -114
  104. package/src/browser/setupWorker/setupWorker.ts +83 -120
  105. package/src/browser/setupWorker/start/createRequestListener.ts +20 -24
  106. package/src/browser/setupWorker/start/createResponseListener.ts +15 -22
  107. package/src/browser/setupWorker/start/createStartHandler.ts +24 -18
  108. package/src/browser/setupWorker/start/utils/enableMocking.ts +18 -21
  109. package/src/browser/setupWorker/start/utils/printStartMessage.ts +0 -2
  110. package/src/browser/utils/checkWorkerIntegrity.ts +22 -14
  111. package/src/browser/utils/workerChannel.ts +146 -0
  112. package/src/core/HttpResponse.ts +3 -3
  113. package/src/core/handlers/GraphQLHandler.test.ts +1 -1
  114. package/src/core/handlers/GraphQLHandler.ts +0 -3
  115. package/src/core/handlers/HttpHandler.ts +0 -2
  116. package/src/core/utils/cookieStore.ts +56 -198
  117. package/src/core/utils/handleRequest.ts +1 -1
  118. package/src/core/utils/internal/devUtils.ts +0 -2
  119. package/src/core/utils/internal/getCallFrame.ts +2 -2
  120. package/src/core/utils/internal/parseGraphQLRequest.ts +1 -0
  121. package/src/core/utils/matching/matchRequestUrl.ts +2 -2
  122. package/src/core/utils/request/getRequestCookies.ts +1 -1
  123. package/src/core/utils/request/onUnhandledRequest.test.ts +1 -1
  124. package/src/core/utils/request/storeResponseCookies.ts +3 -3
  125. package/src/core/utils/request/toPublicUrl.test.ts +1 -1
  126. package/src/core/utils/url/cleanUrl.ts +1 -1
  127. package/src/core/utils/url/isAbsoluteUrl.ts +1 -1
  128. package/src/core/ws/WebSocketClientManager.test.ts +1 -1
  129. package/src/core/ws/WebSocketIndexedDBClientStore.ts +0 -4
  130. package/src/core/ws/utils/attachWebSocketLogger.ts +0 -14
  131. package/src/mockServiceWorker.js +14 -10
  132. package/src/node/SetupServerApi.ts +1 -1
  133. package/src/browser/setupWorker/start/createFallbackStart.ts +0 -21
  134. package/src/browser/setupWorker/start/utils/createMessageChannel.ts +0 -32
  135. package/src/browser/setupWorker/stop/createFallbackStop.ts +0 -11
  136. package/src/browser/setupWorker/stop/createStop.ts +0 -35
@@ -124,8 +124,23 @@ function isNodeProcess() {
124
124
  return false;
125
125
  }
126
126
 
127
+ // src/browser/setupWorker/start/utils/prepareStartHandler.ts
128
+ var import_mergeRight = require("../core/utils/internal/mergeRight");
129
+ var DEFAULT_START_OPTIONS = {
130
+ serviceWorker: {
131
+ url: "/mockServiceWorker.js",
132
+ options: null
133
+ },
134
+ quiet: false,
135
+ waitUntilReady: true,
136
+ onUnhandledRequest: "warn",
137
+ findWorker(scriptURL, mockServiceWorkerUrl) {
138
+ return scriptURL === mockServiceWorkerUrl;
139
+ }
140
+ };
141
+
127
142
  // src/browser/setupWorker/start/createStartHandler.ts
128
- var import_devUtils7 = require("../core/utils/internal/devUtils");
143
+ var import_devUtils6 = require("../core/utils/internal/devUtils");
129
144
 
130
145
  // node_modules/.pnpm/@open-draft+until@2.1.0/node_modules/@open-draft/until/lib/index.mjs
131
146
  var until = async (promise) => {
@@ -219,8 +234,71 @@ Learn more about creating the Service Worker script: https://mswjs.io/docs/cli/i
219
234
  return registrationResult.data;
220
235
  };
221
236
 
222
- // src/browser/setupWorker/start/utils/enableMocking.ts
223
- var import_devUtils3 = require("../core/utils/internal/devUtils");
237
+ // node_modules/.pnpm/@open-draft+deferred-promise@2.2.0/node_modules/@open-draft/deferred-promise/build/index.mjs
238
+ function createDeferredExecutor() {
239
+ const executor = (resolve, reject) => {
240
+ executor.state = "pending";
241
+ executor.resolve = (data) => {
242
+ if (executor.state !== "pending") {
243
+ return;
244
+ }
245
+ executor.result = data;
246
+ const onFulfilled = (value) => {
247
+ executor.state = "fulfilled";
248
+ return value;
249
+ };
250
+ return resolve(
251
+ data instanceof Promise ? data : Promise.resolve(data).then(onFulfilled)
252
+ );
253
+ };
254
+ executor.reject = (reason) => {
255
+ if (executor.state !== "pending") {
256
+ return;
257
+ }
258
+ queueMicrotask(() => {
259
+ executor.state = "rejected";
260
+ });
261
+ return reject(executor.rejectionReason = reason);
262
+ };
263
+ };
264
+ return executor;
265
+ }
266
+ var DeferredPromise = class extends Promise {
267
+ #executor;
268
+ resolve;
269
+ reject;
270
+ constructor(executor = null) {
271
+ const deferredExecutor = createDeferredExecutor();
272
+ super((originalResolve, originalReject) => {
273
+ deferredExecutor(originalResolve, originalReject);
274
+ executor?.(deferredExecutor.resolve, deferredExecutor.reject);
275
+ });
276
+ this.#executor = deferredExecutor;
277
+ this.resolve = this.#executor.resolve;
278
+ this.reject = this.#executor.reject;
279
+ }
280
+ get state() {
281
+ return this.#executor.state;
282
+ }
283
+ get rejectionReason() {
284
+ return this.#executor.rejectionReason;
285
+ }
286
+ then(onFulfilled, onRejected) {
287
+ return this.#decorate(super.then(onFulfilled, onRejected));
288
+ }
289
+ catch(onRejected) {
290
+ return this.#decorate(super.catch(onRejected));
291
+ }
292
+ finally(onfinally) {
293
+ return this.#decorate(super.finally(onfinally));
294
+ }
295
+ #decorate(promise) {
296
+ return Object.defineProperties(promise, {
297
+ resolve: { configurable: true, value: this.resolve },
298
+ reject: { configurable: true, value: this.reject }
299
+ });
300
+ }
301
+ };
224
302
 
225
303
  // src/browser/setupWorker/start/utils/printStartMessage.ts
226
304
  var import_devUtils2 = require("../core/utils/internal/devUtils");
@@ -252,35 +330,23 @@ function printStartMessage(args = {}) {
252
330
  }
253
331
 
254
332
  // src/browser/setupWorker/start/utils/enableMocking.ts
255
- async function enableMocking(context, options) {
256
- context.workerChannel.send("MOCK_ACTIVATE");
257
- const { payload } = await context.events.once("MOCKING_ENABLED");
258
- if (context.isMockingEnabled) {
259
- import_devUtils3.devUtils.warn(
260
- `Found a redundant "worker.start()" call. Note that starting the worker while mocking is already enabled will have no effect. Consider removing this "worker.start()" call.`
261
- );
262
- return;
263
- }
264
- context.isMockingEnabled = true;
265
- printStartMessage({
266
- quiet: options.quiet,
267
- workerScope: context.registration?.scope,
268
- workerUrl: context.worker?.scriptURL,
269
- client: payload.client
333
+ function enableMocking(context, options) {
334
+ const mockingEnabledPromise = new DeferredPromise();
335
+ context.workerChannel.postMessage("MOCK_ACTIVATE");
336
+ context.workerChannel.once("MOCKING_ENABLED", async (event) => {
337
+ context.isMockingEnabled = true;
338
+ const worker = await context.workerPromise;
339
+ printStartMessage({
340
+ quiet: options.quiet,
341
+ workerScope: context.registration?.scope,
342
+ workerUrl: worker.scriptURL,
343
+ client: event.data.client
344
+ });
345
+ mockingEnabledPromise.resolve(true);
270
346
  });
347
+ return mockingEnabledPromise;
271
348
  }
272
349
 
273
- // src/browser/setupWorker/start/utils/createMessageChannel.ts
274
- var WorkerChannel = class {
275
- constructor(port) {
276
- this.port = port;
277
- }
278
- postMessage(event, ...rest) {
279
- const [data, transfer] = rest;
280
- this.port.postMessage({ type: event, data }, { transfer });
281
- }
282
- };
283
-
284
350
  // src/browser/utils/pruneGetRequestBody.ts
285
351
  function pruneGetRequestBody(request) {
286
352
  if (["HEAD", "GET"].includes(request.method)) {
@@ -300,14 +366,17 @@ function deserializeRequest(serializedRequest) {
300
366
  // src/browser/setupWorker/start/createRequestListener.ts
301
367
  var import_RequestHandler = require("../core/handlers/RequestHandler");
302
368
  var import_handleRequest = require("../core/utils/handleRequest");
303
- var import_devUtils4 = require("../core/utils/internal/devUtils");
369
+ var import_devUtils3 = require("../core/utils/internal/devUtils");
304
370
  var import_toResponseInit = require("../core/utils/toResponseInit");
305
371
  var import_isHandlerKind = require("../core/utils/internal/isHandlerKind");
306
372
  var createRequestListener = (context, options) => {
307
- return async (event, message) => {
308
- const messageChannel = new WorkerChannel(event.ports[0]);
309
- const requestId = message.payload.id;
310
- const request = deserializeRequest(message.payload);
373
+ return async (event) => {
374
+ if (!context.isMockingEnabled && context.workerStoppedAt && event.data.interceptedAt > context.workerStoppedAt) {
375
+ event.postMessage("PASSTHROUGH");
376
+ return;
377
+ }
378
+ const requestId = event.data.id;
379
+ const request = deserializeRequest(event.data);
311
380
  const requestCloneForLogs = request.clone();
312
381
  const requestClone = request.clone();
313
382
  import_RequestHandler.RequestHandler.cache.set(request, requestClone);
@@ -320,7 +389,7 @@ var createRequestListener = (context, options) => {
320
389
  context.emitter,
321
390
  {
322
391
  onPassthroughResponse() {
323
- messageChannel.postMessage("PASSTHROUGH");
392
+ event.postMessage("PASSTHROUGH");
324
393
  },
325
394
  async onMockedResponse(response, { handler, parsedResult }) {
326
395
  const responseClone = response.clone();
@@ -328,7 +397,7 @@ var createRequestListener = (context, options) => {
328
397
  const responseInit = (0, import_toResponseInit.toResponseInit)(response);
329
398
  if (context.supports.readableStreamTransfer) {
330
399
  const responseStreamOrNull = response.body;
331
- messageChannel.postMessage(
400
+ event.postMessage(
332
401
  "MOCK_RESPONSE",
333
402
  {
334
403
  ...responseInit,
@@ -338,7 +407,7 @@ var createRequestListener = (context, options) => {
338
407
  );
339
408
  } else {
340
409
  const responseBufferOrNull = response.body === null ? null : await responseClone.arrayBuffer();
341
- messageChannel.postMessage("MOCK_RESPONSE", {
410
+ event.postMessage("MOCK_RESPONSE", {
342
411
  ...responseInit,
343
412
  body: responseBufferOrNull
344
413
  });
@@ -357,7 +426,7 @@ var createRequestListener = (context, options) => {
357
426
  );
358
427
  } catch (error2) {
359
428
  if (error2 instanceof Error) {
360
- import_devUtils4.devUtils.error(
429
+ import_devUtils3.devUtils.error(
361
430
  `Uncaught exception in the request handler for "%s %s":
362
431
 
363
432
  %s
@@ -367,7 +436,7 @@ This exception has been gracefully handled as a 500 response, however, it's stro
367
436
  request.url,
368
437
  error2.stack ?? error2
369
438
  );
370
- messageChannel.postMessage("MOCK_RESPONSE", {
439
+ event.postMessage("MOCK_RESPONSE", {
371
440
  status: 500,
372
441
  statusText: "Request Handler Error",
373
442
  headers: {
@@ -385,21 +454,26 @@ This exception has been gracefully handled as a 500 response, however, it's stro
385
454
  };
386
455
 
387
456
  // src/browser/utils/checkWorkerIntegrity.ts
388
- var import_devUtils5 = require("../core/utils/internal/devUtils");
389
- async function checkWorkerIntegrity(context) {
390
- context.workerChannel.send("INTEGRITY_CHECK_REQUEST");
391
- const { payload } = await context.events.once("INTEGRITY_CHECK_RESPONSE");
392
- if (payload.checksum !== "f5825c521429caf22a4dd13b66e243af") {
393
- import_devUtils5.devUtils.warn(
394
- `The currently registered Service Worker has been generated by a different version of MSW (${payload.packageVersion}) and may not be fully compatible with the installed version.
457
+ var import_devUtils4 = require("../core/utils/internal/devUtils");
458
+ function checkWorkerIntegrity(context) {
459
+ const integrityCheckPromise = new DeferredPromise();
460
+ context.workerChannel.postMessage("INTEGRITY_CHECK_REQUEST");
461
+ context.workerChannel.once("INTEGRITY_CHECK_RESPONSE", (event) => {
462
+ const { checksum, packageVersion } = event.data;
463
+ if (checksum !== "4db4a41e972cec1b64cc569c66952d82") {
464
+ import_devUtils4.devUtils.warn(
465
+ `The currently registered Service Worker has been generated by a different version of MSW (${packageVersion}) and may not be fully compatible with the installed version.
395
466
 
396
467
  It's recommended you update your worker script by running this command:
397
468
 
398
469
  \u2022 npx msw init <PUBLIC_DIR>
399
470
 
400
471
  You can also automate this process and make the worker script update automatically upon the library installations. Read more: https://mswjs.io/docs/cli/init.`
401
- );
402
- }
472
+ );
473
+ }
474
+ integrityCheckPromise.resolve();
475
+ });
476
+ return integrityCheckPromise;
403
477
  }
404
478
 
405
479
  // node_modules/.pnpm/@mswjs+interceptors@0.39.1/node_modules/@mswjs/interceptors/lib/browser/chunk-6HYIRFX2.mjs
@@ -1142,22 +1216,22 @@ var BatchInterceptor = class extends Interceptor {
1142
1216
 
1143
1217
  // src/browser/setupWorker/start/createResponseListener.ts
1144
1218
  function createResponseListener(context) {
1145
- return (_, message) => {
1146
- const { payload: responseJson } = message;
1147
- const request = deserializeRequest(responseJson.request);
1148
- if (responseJson.response.type?.includes("opaque")) {
1219
+ return (event) => {
1220
+ const responseMessage = event.data;
1221
+ const request = deserializeRequest(responseMessage.request);
1222
+ if (responseMessage.response.type?.includes("opaque")) {
1149
1223
  return;
1150
1224
  }
1151
- const response = responseJson.response.status === 0 ? Response.error() : new FetchResponse(
1225
+ const response = responseMessage.response.status === 0 ? Response.error() : new FetchResponse(
1152
1226
  /**
1153
1227
  * Responses may be streams here, but when we create a response object
1154
1228
  * with null-body status codes, like 204, 205, 304 Response will
1155
1229
  * throw when passed a non-null body, so ensure it's null here
1156
1230
  * for those codes
1157
1231
  */
1158
- FetchResponse.isResponseWithBody(responseJson.response.status) ? responseJson.response.body : null,
1232
+ FetchResponse.isResponseWithBody(responseMessage.response.status) ? responseMessage.response.body : null,
1159
1233
  {
1160
- ...responseJson,
1234
+ ...responseMessage,
1161
1235
  /**
1162
1236
  * Set response URL if it's not set already.
1163
1237
  * @see https://github.com/mswjs/msw/issues/2030
@@ -1167,9 +1241,9 @@ function createResponseListener(context) {
1167
1241
  }
1168
1242
  );
1169
1243
  context.emitter.emit(
1170
- responseJson.isMockedResponse ? "response:mocked" : "response:bypass",
1244
+ responseMessage.isMockedResponse ? "response:mocked" : "response:bypass",
1171
1245
  {
1172
- requestId: responseJson.request.id,
1246
+ requestId: responseMessage.request.id,
1173
1247
  request,
1174
1248
  response
1175
1249
  }
@@ -1178,10 +1252,10 @@ function createResponseListener(context) {
1178
1252
  }
1179
1253
 
1180
1254
  // src/browser/setupWorker/start/utils/validateWorkerScope.ts
1181
- var import_devUtils6 = require("../core/utils/internal/devUtils");
1255
+ var import_devUtils5 = require("../core/utils/internal/devUtils");
1182
1256
  function validateWorkerScope(registration, options) {
1183
1257
  if (!options?.quiet && !location.href.startsWith(registration.scope)) {
1184
- import_devUtils6.devUtils.warn(
1258
+ import_devUtils5.devUtils.warn(
1185
1259
  `Cannot intercept requests on this page because it's outside of the worker's scope ("${registration.scope}"). If you wish to mock API requests on this page, you must resolve this scope issue.
1186
1260
 
1187
1261
  - (Recommended) Register the worker at the root level ("/") of your application.
@@ -1194,7 +1268,7 @@ function validateWorkerScope(registration, options) {
1194
1268
  var createStartHandler = (context) => {
1195
1269
  return function start(options, customOptions) {
1196
1270
  const startWorkerInstance = async () => {
1197
- context.events.removeAllListeners();
1271
+ context.workerChannel.removeAllListeners();
1198
1272
  context.workerChannel.on(
1199
1273
  "REQUEST",
1200
1274
  createRequestListener(context, options)
@@ -1207,14 +1281,14 @@ var createStartHandler = (context) => {
1207
1281
  );
1208
1282
  const [worker, registration] = instance;
1209
1283
  if (!worker) {
1210
- const missingWorkerMessage = customOptions?.findWorker ? import_devUtils7.devUtils.formatMessage(
1284
+ const missingWorkerMessage = customOptions?.findWorker ? import_devUtils6.devUtils.formatMessage(
1211
1285
  `Failed to locate the Service Worker registration using a custom "findWorker" predicate.
1212
1286
 
1213
1287
  Please ensure that the custom predicate properly locates the Service Worker registration at "%s".
1214
1288
  More details: https://mswjs.io/docs/api/setup-worker/start#findworker
1215
1289
  `,
1216
1290
  options.serviceWorker.url
1217
- ) : import_devUtils7.devUtils.formatMessage(
1291
+ ) : import_devUtils6.devUtils.formatMessage(
1218
1292
  `Failed to locate the Service Worker registration.
1219
1293
 
1220
1294
  This most likely means that the worker script URL "%s" cannot resolve against the actual public hostname (%s). This may happen if your application runs behind a proxy, or has a dynamic hostname.
@@ -1225,23 +1299,23 @@ Please consider using a custom "serviceWorker.url" option to point to the actual
1225
1299
  );
1226
1300
  throw new Error(missingWorkerMessage);
1227
1301
  }
1228
- context.worker = worker;
1302
+ context.workerPromise.resolve(worker);
1229
1303
  context.registration = registration;
1230
- context.events.addListener(window, "beforeunload", () => {
1304
+ window.addEventListener("beforeunload", () => {
1231
1305
  if (worker.state !== "redundant") {
1232
- context.workerChannel.send("CLIENT_CLOSED");
1306
+ context.workerChannel.postMessage("CLIENT_CLOSED");
1233
1307
  }
1234
1308
  window.clearInterval(context.keepAliveInterval);
1235
1309
  window.postMessage({ type: "msw/worker:stop" });
1236
1310
  });
1237
1311
  await checkWorkerIntegrity(context).catch((error2) => {
1238
- import_devUtils7.devUtils.error(
1239
- "Error while checking the worker script integrity. Please report this on GitHub (https://github.com/mswjs/msw/issues), including the original error below."
1312
+ import_devUtils6.devUtils.error(
1313
+ "Error while checking the worker script integrity. Please report this on GitHub (https://github.com/mswjs/msw/issues) and include the original error below."
1240
1314
  );
1241
1315
  console.error(error2);
1242
1316
  });
1243
1317
  context.keepAliveInterval = window.setInterval(
1244
- () => context.workerChannel.send("KEEPALIVE_REQUEST"),
1318
+ () => context.workerChannel.postMessage("KEEPALIVE_REQUEST"),
1245
1319
  5e3
1246
1320
  );
1247
1321
  validateWorkerScope(registration, context.startOptions);
@@ -1251,16 +1325,19 @@ Please consider using a custom "serviceWorker.url" option to point to the actual
1251
1325
  async (registration) => {
1252
1326
  const pendingInstance = registration.installing || registration.waiting;
1253
1327
  if (pendingInstance) {
1254
- await new Promise((resolve) => {
1255
- pendingInstance.addEventListener("statechange", () => {
1256
- if (pendingInstance.state === "activated") {
1257
- return resolve();
1258
- }
1259
- });
1328
+ const activationPromise = new DeferredPromise();
1329
+ pendingInstance.addEventListener("statechange", () => {
1330
+ if (pendingInstance.state === "activated") {
1331
+ activationPromise.resolve();
1332
+ }
1260
1333
  });
1334
+ await activationPromise;
1261
1335
  }
1262
1336
  await enableMocking(context, options).catch((error2) => {
1263
- throw new Error(`Failed to enable mocking: ${error2?.message}`);
1337
+ import_devUtils6.devUtils.error(
1338
+ "Failed to enable mocking. Please report this on GitHub (https://github.com/mswjs/msw/issues) and include the original error below."
1339
+ );
1340
+ throw error2;
1264
1341
  });
1265
1342
  return registration;
1266
1343
  }
@@ -1269,115 +1346,311 @@ Please consider using a custom "serviceWorker.url" option to point to the actual
1269
1346
  };
1270
1347
  };
1271
1348
 
1272
- // src/browser/setupWorker/stop/createStop.ts
1273
- var import_devUtils9 = require("../core/utils/internal/devUtils");
1274
-
1275
- // src/browser/setupWorker/stop/utils/printStopMessage.ts
1349
+ // src/browser/setupWorker/setupWorker.ts
1276
1350
  var import_devUtils8 = require("../core/utils/internal/devUtils");
1277
- function printStopMessage(args = {}) {
1278
- if (args.quiet) {
1279
- return;
1351
+ var import_SetupApi = require("../core/SetupApi");
1352
+ var import_mergeRight2 = require("../core/utils/internal/mergeRight");
1353
+
1354
+ // src/browser/utils/supportsReadableStreamTransfer.ts
1355
+ function supportsReadableStreamTransfer() {
1356
+ try {
1357
+ const stream = new ReadableStream({
1358
+ start: (controller) => controller.close()
1359
+ });
1360
+ const message = new MessageChannel();
1361
+ message.port1.postMessage(stream, [stream]);
1362
+ return true;
1363
+ } catch {
1364
+ return false;
1280
1365
  }
1281
- console.log(
1282
- `%c${import_devUtils8.devUtils.formatMessage("Mocking disabled.")}`,
1283
- "color:orangered;font-weight:bold;"
1284
- );
1285
1366
  }
1286
1367
 
1287
- // src/browser/setupWorker/stop/createStop.ts
1288
- var createStop = (context) => {
1289
- return function stop() {
1290
- if (!context.isMockingEnabled) {
1291
- import_devUtils9.devUtils.warn(
1292
- 'Found a redundant "worker.stop()" call. Note that stopping the worker while mocking already stopped has no effect. Consider removing this "worker.stop()" call.'
1293
- );
1294
- return;
1295
- }
1296
- context.workerChannel.send("MOCK_DEACTIVATE");
1297
- context.isMockingEnabled = false;
1298
- window.clearInterval(context.keepAliveInterval);
1299
- window.postMessage({ type: "msw/worker:stop" });
1300
- printStopMessage({ quiet: context.startOptions?.quiet });
1301
- };
1302
- };
1368
+ // src/browser/setupWorker/setupWorker.ts
1369
+ var import_webSocketInterceptor = require("../core/ws/webSocketInterceptor");
1370
+ var import_handleWebSocketEvent = require("../core/ws/handleWebSocketEvent");
1371
+ var import_attachWebSocketLogger = require("../core/ws/utils/attachWebSocketLogger");
1303
1372
 
1304
- // src/browser/setupWorker/start/utils/prepareStartHandler.ts
1305
- var import_mergeRight = require("../core/utils/internal/mergeRight");
1306
- var DEFAULT_START_OPTIONS = {
1307
- serviceWorker: {
1308
- url: "/mockServiceWorker.js",
1309
- options: null
1310
- },
1311
- quiet: false,
1312
- waitUntilReady: true,
1313
- onUnhandledRequest: "warn",
1314
- findWorker(scriptURL, mockServiceWorkerUrl) {
1315
- return scriptURL === mockServiceWorkerUrl;
1373
+ // node_modules/.pnpm/rettime@0.7.0/node_modules/rettime/build/index.js
1374
+ var kDefaultPrevented = Symbol("kDefaultPrevented");
1375
+ var kPropagationStopped = Symbol("kPropagationStopped");
1376
+ var kImmediatePropagationStopped = Symbol("kImmediatePropagationStopped");
1377
+ var TypedEvent = class extends MessageEvent {
1378
+ /**
1379
+ * @note Keep a placeholder property with the return type
1380
+ * because the type must be set somewhere in order to be
1381
+ * correctly associated and inferred from the event.
1382
+ */
1383
+ #returnType;
1384
+ [kDefaultPrevented];
1385
+ [kPropagationStopped];
1386
+ [kImmediatePropagationStopped];
1387
+ constructor(...args) {
1388
+ super(args[0], args[1]);
1389
+ this[kDefaultPrevented] = false;
1390
+ }
1391
+ get defaultPrevented() {
1392
+ return this[kDefaultPrevented];
1393
+ }
1394
+ preventDefault() {
1395
+ super.preventDefault();
1396
+ this[kDefaultPrevented] = true;
1397
+ }
1398
+ stopImmediatePropagation() {
1399
+ super.stopImmediatePropagation();
1400
+ this[kImmediatePropagationStopped] = true;
1316
1401
  }
1317
1402
  };
1318
-
1319
- // node_modules/.pnpm/@open-draft+deferred-promise@2.2.0/node_modules/@open-draft/deferred-promise/build/index.mjs
1320
- function createDeferredExecutor() {
1321
- const executor = (resolve, reject) => {
1322
- executor.state = "pending";
1323
- executor.resolve = (data) => {
1324
- if (executor.state !== "pending") {
1325
- return;
1403
+ var kListenerOptions = Symbol("kListenerOptions");
1404
+ var Emitter2 = class {
1405
+ #listeners;
1406
+ constructor() {
1407
+ this.#listeners = {};
1408
+ }
1409
+ /**
1410
+ * Adds a listener for the given event type.
1411
+ *
1412
+ * @returns {AbortController} An `AbortController` that can be used to remove the listener.
1413
+ */
1414
+ on(type, listener, options) {
1415
+ return this.#addListener(type, listener, options);
1416
+ }
1417
+ /**
1418
+ * Adds a one-time listener for the given event type.
1419
+ *
1420
+ * @returns {AbortController} An `AbortController` that can be used to remove the listener.
1421
+ */
1422
+ once(type, listener, options) {
1423
+ return this.on(type, listener, { ...options || {}, once: true });
1424
+ }
1425
+ /**
1426
+ * Prepends a listener for the given event type.
1427
+ *
1428
+ * @returns {AbortController} An `AbortController` that can be used to remove the listener.
1429
+ */
1430
+ earlyOn(type, listener, options) {
1431
+ return this.#addListener(type, listener, options, "prepend");
1432
+ }
1433
+ /**
1434
+ * Prepends a one-time listener for the given event type.
1435
+ */
1436
+ earlyOnce(type, listener, options) {
1437
+ return this.earlyOn(type, listener, { ...options || {}, once: true });
1438
+ }
1439
+ /**
1440
+ * Emits the given typed event.
1441
+ *
1442
+ * @returns {boolean} Returns `true` if the event had any listeners, `false` otherwise.
1443
+ */
1444
+ emit(event) {
1445
+ if (this.listenerCount(event.type) === 0) {
1446
+ return false;
1447
+ }
1448
+ const proxiedEvent = this.#proxyEvent(event);
1449
+ for (const listener of this.#listeners[event.type]) {
1450
+ if (proxiedEvent.event[kPropagationStopped] != null && proxiedEvent.event[kPropagationStopped] !== this) {
1451
+ return false;
1326
1452
  }
1327
- executor.result = data;
1328
- const onFulfilled = (value) => {
1329
- executor.state = "fulfilled";
1330
- return value;
1331
- };
1332
- return resolve(
1333
- data instanceof Promise ? data : Promise.resolve(data).then(onFulfilled)
1453
+ if (proxiedEvent.event[kImmediatePropagationStopped]) {
1454
+ break;
1455
+ }
1456
+ this.#callListener(proxiedEvent.event, listener);
1457
+ }
1458
+ proxiedEvent.revoke();
1459
+ return true;
1460
+ }
1461
+ /**
1462
+ * Emits the given typed event and returns a promise that resolves
1463
+ * when all the listeners for that event have settled.
1464
+ *
1465
+ * @returns {Promise<Array<Emitter.ListenerReturnType>>} A promise that resolves
1466
+ * with the return values of all listeners.
1467
+ */
1468
+ async emitAsPromise(event) {
1469
+ if (this.listenerCount(event.type) === 0) {
1470
+ return [];
1471
+ }
1472
+ const pendingListeners = [];
1473
+ const proxiedEvent = this.#proxyEvent(event);
1474
+ for (const listener of this.#listeners[event.type]) {
1475
+ if (proxiedEvent.event[kPropagationStopped] != null && proxiedEvent.event[kPropagationStopped] !== this) {
1476
+ return [];
1477
+ }
1478
+ if (proxiedEvent.event[kImmediatePropagationStopped]) {
1479
+ break;
1480
+ }
1481
+ pendingListeners.push(
1482
+ // Awaiting individual listeners guarantees their call order.
1483
+ await Promise.resolve(this.#callListener(proxiedEvent.event, listener))
1334
1484
  );
1335
- };
1336
- executor.reject = (reason) => {
1337
- if (executor.state !== "pending") {
1485
+ }
1486
+ proxiedEvent.revoke();
1487
+ return Promise.allSettled(pendingListeners).then((results) => {
1488
+ return results.map(
1489
+ (result) => result.status === "fulfilled" ? result.value : result.reason
1490
+ );
1491
+ });
1492
+ }
1493
+ /**
1494
+ * Emits the given event and returns a generator that yields
1495
+ * the result of each listener in the order of their registration.
1496
+ * This way, you stop exhausting the listeners once you get the expected value.
1497
+ */
1498
+ *emitAsGenerator(event) {
1499
+ if (this.listenerCount(event.type) === 0) {
1500
+ return;
1501
+ }
1502
+ const proxiedEvent = this.#proxyEvent(event);
1503
+ for (const listener of this.#listeners[event.type]) {
1504
+ if (proxiedEvent.event[kPropagationStopped] != null && proxiedEvent.event[kPropagationStopped] !== this) {
1338
1505
  return;
1339
1506
  }
1340
- queueMicrotask(() => {
1341
- executor.state = "rejected";
1507
+ if (proxiedEvent.event[kImmediatePropagationStopped]) {
1508
+ break;
1509
+ }
1510
+ yield this.#callListener(proxiedEvent.event, listener);
1511
+ }
1512
+ proxiedEvent.revoke();
1513
+ }
1514
+ /**
1515
+ * Removes a listener for the given event type.
1516
+ */
1517
+ removeListener(type, listener) {
1518
+ if (this.listenerCount(type) === 0) {
1519
+ return;
1520
+ }
1521
+ const nextListeners = [];
1522
+ for (const existingListener of this.#listeners[type]) {
1523
+ if (existingListener !== listener) {
1524
+ nextListeners.push(existingListener);
1525
+ }
1526
+ }
1527
+ this.#listeners[type] = nextListeners;
1528
+ }
1529
+ /**
1530
+ * Removes all listeners for the given event type.
1531
+ * If no event type is provided, removes all existing listeners.
1532
+ */
1533
+ removeAllListeners(type) {
1534
+ if (type == null) {
1535
+ this.#listeners = {};
1536
+ return;
1537
+ }
1538
+ this.#listeners[type] = [];
1539
+ }
1540
+ /**
1541
+ * Returns the list of listeners for the given event type.
1542
+ * If no even type is provided, returns all listeners.
1543
+ */
1544
+ listeners(type) {
1545
+ if (type == null) {
1546
+ return Object.values(this.#listeners).flat();
1547
+ }
1548
+ return this.#listeners[type] || [];
1549
+ }
1550
+ /**
1551
+ * Returns the number of listeners for the given event type.
1552
+ * If no even type is provided, returns the total number of listeners.
1553
+ */
1554
+ listenerCount(type) {
1555
+ return this.listeners(type).length;
1556
+ }
1557
+ #addListener(type, listener, options, insertMode = "append") {
1558
+ this.#listeners[type] ??= [];
1559
+ if (insertMode === "prepend") {
1560
+ this.#listeners[type].unshift(listener);
1561
+ } else {
1562
+ this.#listeners[type].push(listener);
1563
+ }
1564
+ if (options) {
1565
+ Object.defineProperty(listener, kListenerOptions, {
1566
+ value: options,
1567
+ enumerable: false,
1568
+ writable: false
1342
1569
  });
1343
- return reject(executor.rejectionReason = reason);
1344
- };
1345
- };
1346
- return executor;
1347
- }
1348
- var DeferredPromise = class extends Promise {
1349
- #executor;
1350
- resolve;
1351
- reject;
1352
- constructor(executor = null) {
1353
- const deferredExecutor = createDeferredExecutor();
1354
- super((originalResolve, originalReject) => {
1355
- deferredExecutor(originalResolve, originalReject);
1356
- executor?.(deferredExecutor.resolve, deferredExecutor.reject);
1570
+ if (options.signal) {
1571
+ options.signal.addEventListener(
1572
+ "abort",
1573
+ () => {
1574
+ this.removeListener(type, listener);
1575
+ },
1576
+ { once: true }
1577
+ );
1578
+ }
1579
+ }
1580
+ return this;
1581
+ }
1582
+ #proxyEvent(event) {
1583
+ const { stopPropagation } = event;
1584
+ event.stopPropagation = new Proxy(event.stopPropagation, {
1585
+ apply: (target, thisArg, argArray) => {
1586
+ event[kPropagationStopped] = this;
1587
+ return Reflect.apply(target, thisArg, argArray);
1588
+ }
1357
1589
  });
1358
- this.#executor = deferredExecutor;
1359
- this.resolve = this.#executor.resolve;
1360
- this.reject = this.#executor.reject;
1590
+ return {
1591
+ event,
1592
+ revoke() {
1593
+ event.stopPropagation = stopPropagation;
1594
+ }
1595
+ };
1361
1596
  }
1362
- get state() {
1363
- return this.#executor.state;
1597
+ #callListener(event, listener) {
1598
+ const returnValue = listener.call(this, event);
1599
+ if (listener[kListenerOptions]?.once) {
1600
+ this.removeListener(event.type, listener);
1601
+ }
1602
+ return returnValue;
1364
1603
  }
1365
- get rejectionReason() {
1366
- return this.#executor.rejectionReason;
1604
+ };
1605
+
1606
+ // src/browser/utils/workerChannel.ts
1607
+ var import_isObject = require("../core/utils/internal/isObject");
1608
+ var WorkerEvent = class extends TypedEvent {
1609
+ #workerEvent;
1610
+ constructor(workerEvent) {
1611
+ const type = workerEvent.data.type;
1612
+ const data = workerEvent.data.payload;
1613
+ super(
1614
+ // @ts-expect-error Troublesome `TypedEvent` extension.
1615
+ type,
1616
+ { data }
1617
+ );
1618
+ this.#workerEvent = workerEvent;
1367
1619
  }
1368
- then(onFulfilled, onRejected) {
1369
- return this.#decorate(super.then(onFulfilled, onRejected));
1620
+ get ports() {
1621
+ return this.#workerEvent.ports;
1370
1622
  }
1371
- catch(onRejected) {
1372
- return this.#decorate(super.catch(onRejected));
1623
+ /**
1624
+ * Reply directly to this event using its `MessagePort`.
1625
+ */
1626
+ postMessage(type, ...rest) {
1627
+ this.#workerEvent.ports[0].postMessage(
1628
+ { type, data: rest[0] },
1629
+ { transfer: rest[1] }
1630
+ );
1373
1631
  }
1374
- finally(onfinally) {
1375
- return this.#decorate(super.finally(onfinally));
1632
+ };
1633
+ var WorkerChannel = class extends Emitter2 {
1634
+ constructor(options) {
1635
+ super();
1636
+ this.options = options;
1637
+ navigator.serviceWorker.addEventListener("message", async (event) => {
1638
+ const worker = await this.options.worker;
1639
+ if (event.source != null && event.source !== worker) {
1640
+ return;
1641
+ }
1642
+ if (event.data && (0, import_isObject.isObject)(event.data) && "type" in event.data) {
1643
+ this.emit(new WorkerEvent(event));
1644
+ }
1645
+ });
1376
1646
  }
1377
- #decorate(promise) {
1378
- return Object.defineProperties(promise, {
1379
- resolve: { configurable: true, value: this.resolve },
1380
- reject: { configurable: true, value: this.reject }
1647
+ /**
1648
+ * Send data to the Service Worker controlling this client.
1649
+ * This triggers the `message` event listener on ServiceWorkerGlobalScope.
1650
+ */
1651
+ postMessage(type) {
1652
+ this.options.worker.then((worker) => {
1653
+ worker.postMessage(type);
1381
1654
  });
1382
1655
  }
1383
1656
  };
@@ -1445,7 +1718,7 @@ async function emitAsync(emitter, eventName, ...data) {
1445
1718
  await listener.apply(emitter, data);
1446
1719
  }
1447
1720
  }
1448
- function isObject(value, loose = false) {
1721
+ function isObject2(value, loose = false) {
1449
1722
  return loose ? Object.prototype.toString.call(value).startsWith("[object ") : Object.prototype.toString.call(value) === "[object Object]";
1450
1723
  }
1451
1724
  function isPropertyAccessible(obj, key) {
@@ -1478,7 +1751,7 @@ function isResponseError(response) {
1478
1751
  return response != null && response instanceof Response && isPropertyAccessible(response, "type") && response.type === "error";
1479
1752
  }
1480
1753
  function isResponseLike(value) {
1481
- return isObject(value, true) && isPropertyAccessible(value, "status") && isPropertyAccessible(value, "statusText") && isPropertyAccessible(value, "bodyUsed");
1754
+ return isObject2(value, true) && isPropertyAccessible(value, "status") && isPropertyAccessible(value, "statusText") && isPropertyAccessible(value, "bodyUsed");
1482
1755
  }
1483
1756
  function isNodeLikeError(error2) {
1484
1757
  if (error2 == null) {
@@ -1503,7 +1776,7 @@ async function handleRequest2(options) {
1503
1776
  await options.onResponse(response);
1504
1777
  return true;
1505
1778
  }
1506
- if (isObject(response)) {
1779
+ if (isObject2(response)) {
1507
1780
  options.onError(response);
1508
1781
  return true;
1509
1782
  }
@@ -2714,162 +2987,66 @@ function createFallbackRequestListener(context, options) {
2714
2987
  return interceptor;
2715
2988
  }
2716
2989
 
2717
- // src/browser/setupWorker/start/createFallbackStart.ts
2718
- function createFallbackStart(context) {
2719
- return async function start(options) {
2720
- context.fallbackInterceptor = createFallbackRequestListener(
2721
- context,
2722
- options
2723
- );
2724
- printStartMessage({
2725
- message: "Mocking enabled (fallback mode).",
2726
- quiet: options.quiet
2727
- });
2728
- return void 0;
2729
- };
2730
- }
2731
-
2732
- // src/browser/setupWorker/stop/createFallbackStop.ts
2733
- function createFallbackStop(context) {
2734
- return function stop() {
2735
- context.fallbackInterceptor?.dispose();
2736
- printStopMessage({ quiet: context.startOptions?.quiet });
2737
- };
2738
- }
2739
-
2740
- // src/browser/setupWorker/setupWorker.ts
2741
- var import_devUtils10 = require("../core/utils/internal/devUtils");
2742
- var import_SetupApi = require("../core/SetupApi");
2743
- var import_mergeRight2 = require("../core/utils/internal/mergeRight");
2744
-
2745
- // src/browser/utils/supportsReadableStreamTransfer.ts
2746
- function supportsReadableStreamTransfer() {
2747
- try {
2748
- const stream = new ReadableStream({
2749
- start: (controller) => controller.close()
2750
- });
2751
- const message = new MessageChannel();
2752
- message.port1.postMessage(stream, [stream]);
2753
- return true;
2754
- } catch {
2755
- return false;
2990
+ // src/browser/setupWorker/stop/utils/printStopMessage.ts
2991
+ var import_devUtils7 = require("../core/utils/internal/devUtils");
2992
+ function printStopMessage(args = {}) {
2993
+ if (args.quiet) {
2994
+ return;
2756
2995
  }
2996
+ console.log(
2997
+ `%c${import_devUtils7.devUtils.formatMessage("Mocking disabled.")}`,
2998
+ "color:orangered;font-weight:bold;"
2999
+ );
2757
3000
  }
2758
3001
 
2759
3002
  // src/browser/setupWorker/setupWorker.ts
2760
- var import_webSocketInterceptor = require("../core/ws/webSocketInterceptor");
2761
- var import_handleWebSocketEvent = require("../core/ws/handleWebSocketEvent");
2762
- var import_attachWebSocketLogger = require("../core/ws/utils/attachWebSocketLogger");
2763
3003
  var SetupWorkerApi = class extends import_SetupApi.SetupApi {
2764
3004
  context;
2765
- startHandler = null;
2766
- stopHandler = null;
2767
- listeners;
2768
3005
  constructor(...handlers) {
2769
3006
  super(...handlers);
2770
3007
  invariant(
2771
3008
  !isNodeProcess(),
2772
- import_devUtils10.devUtils.formatMessage(
3009
+ import_devUtils8.devUtils.formatMessage(
2773
3010
  "Failed to execute `setupWorker` in a non-browser environment. Consider using `setupServer` for Node.js environment instead."
2774
3011
  )
2775
3012
  );
2776
- this.listeners = [];
2777
3013
  this.context = this.createWorkerContext();
2778
3014
  }
2779
3015
  createWorkerContext() {
2780
- const context = {
3016
+ const workerPromise = new DeferredPromise();
3017
+ return {
2781
3018
  // Mocking is not considered enabled until the worker
2782
3019
  // signals back the successful activation event.
2783
3020
  isMockingEnabled: false,
2784
3021
  startOptions: null,
2785
- worker: null,
3022
+ workerPromise,
3023
+ registration: void 0,
2786
3024
  getRequestHandlers: () => {
2787
3025
  return this.handlersController.currentHandlers();
2788
3026
  },
2789
- registration: null,
2790
3027
  emitter: this.emitter,
2791
- workerChannel: {
2792
- on: (eventType, callback) => {
2793
- this.context.events.addListener(navigator.serviceWorker, "message", (event) => {
2794
- if (event.source !== this.context.worker) {
2795
- return;
2796
- }
2797
- const message = event.data;
2798
- if (!message) {
2799
- return;
2800
- }
2801
- if (message.type === eventType) {
2802
- callback(event, message);
2803
- }
2804
- });
2805
- },
2806
- send: (type) => {
2807
- this.context.worker?.postMessage(type);
2808
- }
2809
- },
2810
- events: {
2811
- addListener: (target, eventType, callback) => {
2812
- target.addEventListener(eventType, callback);
2813
- this.listeners.push({
2814
- eventType,
2815
- target,
2816
- callback
2817
- });
2818
- return () => {
2819
- target.removeEventListener(eventType, callback);
2820
- };
2821
- },
2822
- removeAllListeners: () => {
2823
- for (const { target, eventType, callback } of this.listeners) {
2824
- target.removeEventListener(eventType, callback);
2825
- }
2826
- this.listeners = [];
2827
- },
2828
- once: (eventType) => {
2829
- const bindings = [];
2830
- return new Promise((resolve, reject) => {
2831
- const handleIncomingMessage = (event) => {
2832
- try {
2833
- const message = event.data;
2834
- if (message.type === eventType) {
2835
- resolve(message);
2836
- }
2837
- } catch (error2) {
2838
- reject(error2);
2839
- }
2840
- };
2841
- bindings.push(
2842
- this.context.events.addListener(
2843
- navigator.serviceWorker,
2844
- "message",
2845
- handleIncomingMessage
2846
- ),
2847
- this.context.events.addListener(
2848
- navigator.serviceWorker,
2849
- "messageerror",
2850
- reject
2851
- )
2852
- );
2853
- }).finally(() => {
2854
- bindings.forEach((unbind) => unbind());
2855
- });
2856
- }
2857
- },
3028
+ workerChannel: new WorkerChannel({
3029
+ worker: workerPromise
3030
+ }),
2858
3031
  supports: {
2859
- serviceWorkerApi: !("serviceWorker" in navigator) || location.protocol === "file:",
3032
+ serviceWorkerApi: "serviceWorker" in navigator && location.protocol !== "file:",
2860
3033
  readableStreamTransfer: supportsReadableStreamTransfer()
2861
3034
  }
2862
3035
  };
2863
- this.startHandler = context.supports.serviceWorkerApi ? createFallbackStart(context) : createStartHandler(context);
2864
- this.stopHandler = context.supports.serviceWorkerApi ? createFallbackStop(context) : createStop(context);
2865
- return context;
2866
3036
  }
2867
3037
  async start(options = {}) {
2868
- if (options.waitUntilReady === true) {
2869
- import_devUtils10.devUtils.warn(
3038
+ if ("waitUntilReady" in options) {
3039
+ import_devUtils8.devUtils.warn(
2870
3040
  'The "waitUntilReady" option has been deprecated. Please remove it from this "worker.start()" call. Follow the recommended Browser integration (https://mswjs.io/docs/integrations/browser) to eliminate any race conditions between the Service Worker registration and any requests made by your application on initial render.'
2871
3041
  );
2872
3042
  }
3043
+ if (this.context.isMockingEnabled) {
3044
+ import_devUtils8.devUtils.warn(
3045
+ `Found a redundant "worker.start()" call. Note that starting the worker while mocking is already enabled will have no effect. Consider removing this "worker.start()" call.`
3046
+ );
3047
+ return this.context.registration;
3048
+ }
3049
+ this.context.workerStoppedAt = void 0;
2873
3050
  this.context.startOptions = (0, import_mergeRight2.mergeRight)(
2874
3051
  DEFAULT_START_OPTIONS,
2875
3052
  options
@@ -2893,13 +3070,45 @@ var SetupWorkerApi = class extends import_SetupApi.SetupApi {
2893
3070
  this.subscriptions.push(() => {
2894
3071
  import_webSocketInterceptor.webSocketInterceptor.dispose();
2895
3072
  });
2896
- return await this.startHandler(this.context.startOptions, options);
3073
+ if (!this.context.supports.serviceWorkerApi) {
3074
+ const fallbackInterceptor = createFallbackRequestListener(
3075
+ this.context,
3076
+ this.context.startOptions
3077
+ );
3078
+ this.subscriptions.push(() => {
3079
+ fallbackInterceptor.dispose();
3080
+ });
3081
+ this.context.isMockingEnabled = true;
3082
+ printStartMessage({
3083
+ message: "Mocking enabled (fallback mode).",
3084
+ quiet: this.context.startOptions.quiet
3085
+ });
3086
+ return void 0;
3087
+ }
3088
+ const startHandler = createStartHandler(this.context);
3089
+ const registration = await startHandler(this.context.startOptions, options);
3090
+ this.context.isMockingEnabled = true;
3091
+ return registration;
2897
3092
  }
2898
3093
  stop() {
2899
3094
  super.dispose();
2900
- this.context.events.removeAllListeners();
3095
+ if (!this.context.isMockingEnabled) {
3096
+ import_devUtils8.devUtils.warn(
3097
+ 'Found a redundant "worker.stop()" call. Notice that stopping the worker after it has already been stopped has no effect. Consider removing this "worker.stop()" call.'
3098
+ );
3099
+ return;
3100
+ }
3101
+ this.context.isMockingEnabled = false;
3102
+ this.context.workerStoppedAt = Date.now();
2901
3103
  this.context.emitter.removeAllListeners();
2902
- this.stopHandler();
3104
+ if (this.context.supports.serviceWorkerApi) {
3105
+ this.context.workerChannel.removeAllListeners("RESPONSE");
3106
+ window.clearInterval(this.context.keepAliveInterval);
3107
+ }
3108
+ window.postMessage({ type: "msw/worker:stop" });
3109
+ printStopMessage({
3110
+ quiet: this.context.startOptions?.quiet
3111
+ });
2903
3112
  }
2904
3113
  };
2905
3114
  function setupWorker(...handlers) {