@zimic/interceptor 1.5.1 → 1.5.2-canary.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 (42) hide show
  1. package/dist/{chunk-3WCEMV5U.js → chunk-6YD4TBYJ.js} +13 -4
  2. package/dist/chunk-6YD4TBYJ.js.map +1 -0
  3. package/dist/{chunk-YQNDAJTN.mjs → chunk-MCLPYYCY.mjs} +13 -4
  4. package/dist/chunk-MCLPYYCY.mjs.map +1 -0
  5. package/dist/cli.js +16 -16
  6. package/dist/cli.js.map +1 -1
  7. package/dist/cli.mjs +2 -2
  8. package/dist/cli.mjs.map +1 -1
  9. package/dist/http.d.ts +24 -8
  10. package/dist/http.js +368 -289
  11. package/dist/http.js.map +1 -1
  12. package/dist/http.mjs +367 -288
  13. package/dist/http.mjs.map +1 -1
  14. package/dist/server.js +6 -6
  15. package/dist/server.mjs +1 -1
  16. package/package.json +10 -10
  17. package/src/http/errors/HttpTimesCheckError.ts +9 -9
  18. package/src/http/index.ts +6 -1
  19. package/src/http/interceptor/HttpInterceptorImplementation.ts +74 -21
  20. package/src/http/interceptor/HttpInterceptorStore.ts +11 -13
  21. package/src/http/interceptor/LocalHttpInterceptor.ts +1 -10
  22. package/src/http/interceptor/RemoteHttpInterceptor.ts +16 -22
  23. package/src/http/interceptor/errors/UnknownHttpInterceptorPlatformError.ts +3 -1
  24. package/src/http/interceptor/factory.ts +3 -0
  25. package/src/http/interceptor/types/options.ts +1 -1
  26. package/src/http/interceptorWorker/HttpInterceptorWorker.ts +14 -3
  27. package/src/http/interceptorWorker/LocalHttpInterceptorWorker.ts +25 -93
  28. package/src/http/requestHandler/HttpRequestHandlerImplementation.ts +5 -9
  29. package/src/http/requestHandler/LocalHttpRequestHandler.ts +2 -5
  30. package/src/http/requestHandler/RemoteHttpRequestHandler.ts +17 -20
  31. package/src/http/requestHandler/types/public.ts +3 -8
  32. package/src/http/requestHandler/types/requests.ts +31 -3
  33. package/src/http/utils/logging.ts +54 -0
  34. package/src/interceptor/LocalMSWWorkerStore.ts +123 -0
  35. package/src/{http/interceptorWorker → interceptor}/types/msw.ts +1 -2
  36. package/src/server/utils/auth.ts +1 -1
  37. package/src/utils/fetch.ts +2 -2
  38. package/src/utils/logging.ts +0 -54
  39. package/src/utils/webSocket/WebSocketHandler.ts +1 -1
  40. package/dist/chunk-3WCEMV5U.js.map +0 -1
  41. package/dist/chunk-YQNDAJTN.mjs.map +0 -1
  42. /package/src/{http/interceptorWorker → interceptor}/errors/UnregisteredBrowserServiceWorkerError.ts +0 -0
package/dist/http.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { InvalidFormDataError as InvalidFormDataError$1, InvalidJSONError as InvalidJSONError$1, HTTP_METHODS, HttpHeaders, HttpSearchParams, HttpFormData, parseHttpBody } from '@zimic/http';
2
- import color2 from 'picocolors';
2
+ import color from 'picocolors';
3
3
  import { http, bypass, passthrough } from 'msw';
4
4
  import ClientSocket from 'isomorphic-ws';
5
5
 
@@ -23,8 +23,25 @@ var NotRunningHttpInterceptorError = class extends Error {
23
23
  };
24
24
  var NotRunningHttpInterceptorError_default = NotRunningHttpInterceptorError;
25
25
 
26
+ // ../zimic-utils/dist/validation.mjs
27
+ var ValidationError = class extends TypeError {
28
+ constructor(message) {
29
+ super(message);
30
+ this.name = "ValidationError";
31
+ }
32
+ };
33
+ var ValidationError_default = ValidationError;
34
+ function assertTypeOf(field, value, expectedType, options) {
35
+ const actualType = typeof value;
36
+ if (actualType !== expectedType && !(options?.nullable && value === null) && !(options?.optional && value === void 0)) {
37
+ const receivedType = value === null ? "null" : actualType;
38
+ throw new ValidationError_default(`Expected ${field} to be ${expectedType}, but got ${receivedType}.`);
39
+ }
40
+ }
41
+ var assertTypeOf_default = assertTypeOf;
42
+
26
43
  // src/http/interceptor/errors/UnknownHttpInterceptorPlatformError.ts
27
- var UnknownHttpInterceptorPlatformError = class extends Error {
44
+ var UnknownHttpInterceptorPlatformError = class extends ValidationError_default {
28
45
  /* istanbul ignore next -- @preserve
29
46
  * Ignoring because checking unknown platforms is currently not possible in our Vitest setup. */
30
47
  constructor() {
@@ -65,7 +82,7 @@ var RequestSavingSafeLimitExceededError_default = RequestSavingSafeLimitExceeded
65
82
  // src/cli/browser/shared/constants.ts
66
83
  var SERVICE_WORKER_FILE_NAME = "mockServiceWorker.js";
67
84
 
68
- // src/http/interceptorWorker/errors/UnregisteredBrowserServiceWorkerError.ts
85
+ // src/interceptor/errors/UnregisteredBrowserServiceWorkerError.ts
69
86
  var UnregisteredBrowserServiceWorkerError = class extends Error {
70
87
  constructor() {
71
88
  super(
@@ -230,130 +247,31 @@ function jsonEquals(value, otherValue) {
230
247
  });
231
248
  }
232
249
  var jsonEquals_default = jsonEquals;
233
-
234
- // ../zimic-utils/dist/chunk-W66SQPEM.mjs
235
- function createCachedDynamicImport(importModuleDynamically) {
236
- let cachedImportResult;
237
- return async function importModuleDynamicallyWithCache() {
238
- cachedImportResult ??= await importModuleDynamically();
239
- return cachedImportResult;
240
- };
241
- }
242
- var createCachedDynamicImport_default = createCachedDynamicImport;
243
-
244
- // ../zimic-utils/dist/logging.mjs
245
- var Logger = class _Logger {
246
- prefix;
247
- raw;
248
- constructor(options = {}) {
249
- const { prefix } = options;
250
- this.prefix = prefix;
251
- this.raw = prefix ? new _Logger({ ...options, prefix: void 0 }) : this;
252
- }
253
- logWithLevel(level, ...messages) {
254
- if (this.prefix) {
255
- console[level](this.prefix, ...messages);
256
- } else {
257
- console[level](...messages);
258
- }
259
- }
260
- info(...messages) {
261
- this.logWithLevel("log", ...messages);
262
- }
263
- warn(...messages) {
264
- this.logWithLevel("warn", ...messages);
265
- }
266
- error(...messages) {
267
- this.logWithLevel("error", ...messages);
268
- }
269
- table(headers, rows) {
270
- const columnLengths = headers.map((header) => {
271
- let maxValueLength = header.title.length;
272
- for (const row of rows) {
273
- const value = row[header.property];
274
- if (value.length > maxValueLength) {
275
- maxValueLength = value.length;
276
- }
277
- }
278
- return maxValueLength;
279
- });
280
- const formattedRows = [];
281
- const horizontalLine = columnLengths.map((length) => "\u2500".repeat(length));
282
- formattedRows.push(horizontalLine, []);
283
- for (let headerIndex = 0; headerIndex < headers.length; headerIndex++) {
284
- const header = headers[headerIndex];
285
- const columnLength = columnLengths[headerIndex];
286
- const value = header.title;
287
- formattedRows.at(-1)?.push(value.padEnd(columnLength, " "));
288
- }
289
- formattedRows.push(horizontalLine);
290
- for (const row of rows) {
291
- formattedRows.push([]);
292
- for (let headerIndex = 0; headerIndex < headers.length; headerIndex++) {
293
- const header = headers[headerIndex];
294
- const columnLength = columnLengths[headerIndex];
295
- const value = row[header.property];
296
- formattedRows.at(-1)?.push(value.padEnd(columnLength, " "));
297
- }
298
- }
299
- formattedRows.push(horizontalLine);
300
- const formattedTable = formattedRows.map((row, index) => {
301
- const isFirstLine = index === 0;
302
- if (isFirstLine) {
303
- return `\u250C\u2500${row.join("\u2500\u252C\u2500")}\u2500\u2510`;
304
- }
305
- const isLineAfterHeaders = index === 2;
306
- if (isLineAfterHeaders) {
307
- return `\u251C\u2500${row.join("\u2500\u253C\u2500")}\u2500\u2524`;
308
- }
309
- const isLastLine = index === formattedRows.length - 1;
310
- if (isLastLine) {
311
- return `\u2514\u2500${row.join("\u2500\u2534\u2500")}\u2500\u2518`;
312
- }
313
- return `\u2502 ${row.join(" \u2502 ")} \u2502`;
314
- }).join("\n");
315
- this.logWithLevel("log", formattedTable);
316
- }
317
- };
318
- var Logger_default = Logger;
319
-
320
- // src/utils/environment.ts
321
- function isServerSide() {
322
- return typeof process !== "undefined" && typeof process.versions !== "undefined";
323
- }
324
- function isClientSide() {
325
- return typeof window !== "undefined" && typeof document !== "undefined";
326
- }
327
-
328
- // src/utils/logging.ts
329
- var logger = new Logger_default({
330
- prefix: color2.cyan("[@zimic/interceptor]")
331
- });
332
- function stringifyJSONToLog(value) {
250
+ function stringifyHttpJSONToLog(value) {
333
251
  return JSON.stringify(
334
252
  value,
335
253
  (_key, value2) => {
336
- return stringifyValueToLog(value2, {
254
+ return stringifyHttpValueToLog(value2, {
337
255
  fallback: (value3) => value3
338
256
  });
339
257
  },
340
258
  2
341
259
  ).replace(/\n\s*/g, " ").replace(/"(File { name: '.*?', type: '.*?', size: \d*? })"/g, "$1").replace(/"(Blob { type: '.*?', size: \d*? })"/g, "$1");
342
260
  }
343
- function stringifyValueToLog(value, options = {}) {
344
- const { fallback = stringifyJSONToLog, includeClassName } = options;
261
+ function stringifyHttpValueToLog(value, options = {}) {
262
+ const { fallback = stringifyHttpJSONToLog, includeClassName } = options;
345
263
  if (value === null || value === void 0 || typeof value !== "object") {
346
264
  return String(value);
347
265
  }
348
266
  if (value instanceof HttpHeaders) {
349
- return stringifyValueToLog(value.toObject());
267
+ return stringifyHttpValueToLog(value.toObject());
350
268
  }
351
- if (value instanceof HttpHeaders || value instanceof HttpSearchParams) {
269
+ if (value instanceof HttpSearchParams) {
352
270
  const prefix = includeClassName?.searchParams ?? false ? "URLSearchParams " : "";
353
- return `${prefix}${stringifyValueToLog(value.toObject())}`;
271
+ return `${prefix}${stringifyHttpValueToLog(value.toObject())}`;
354
272
  }
355
273
  if (value instanceof HttpFormData) {
356
- return `FormData ${stringifyValueToLog(value.toObject())}`;
274
+ return `FormData ${stringifyHttpValueToLog(value.toObject())}`;
357
275
  }
358
276
  if (value instanceof File) {
359
277
  return `File { name: '${value.name}', type: '${value.type}', size: ${value.size} }`;
@@ -363,23 +281,6 @@ function stringifyValueToLog(value, options = {}) {
363
281
  }
364
282
  return fallback(value);
365
283
  }
366
- var importUtil = createCachedDynamicImport_default(() => import('util'));
367
- async function formatValueToLog(value, options = {}) {
368
- if (isClientSide()) {
369
- return value;
370
- }
371
- const { colors = true } = options;
372
- const util = await importUtil();
373
- return util.inspect(value, {
374
- colors,
375
- compact: true,
376
- depth: Infinity,
377
- maxArrayLength: Infinity,
378
- maxStringLength: Infinity,
379
- breakLength: Infinity,
380
- sorted: true
381
- });
382
- }
383
284
 
384
285
  // src/http/errors/HttpTimesCheckError.ts
385
286
  function createMessageHeader({
@@ -403,8 +304,8 @@ function createMessageHeader({
403
304
 
404
305
  Requests evaluated by this handler:
405
306
 
406
- ${color2.green("- Expected")}
407
- ${color2.red("+ Received")}`
307
+ ${color.green("- Expected")}
308
+ ${color.red("+ Received")}`
408
309
  ].filter((part) => part !== false).join("");
409
310
  }
410
311
  function createMessageDiffs({ requestSaving, unmatchedRequestGroups }) {
@@ -416,35 +317,35 @@ function createMessageDiffs({ requestSaving, unmatchedRequestGroups }) {
416
317
  const messageParts = [`${requestNumber}: ${request.method} ${request.url}`];
417
318
  if (diff.computed) {
418
319
  messageParts.push("Computed restriction:");
419
- const stringifiedExpected = stringifyValueToLog(diff.computed.expected);
420
- const stringifiedReceived = stringifyValueToLog(diff.computed.received);
421
- messageParts.push(` ${color2.green(`- return ${stringifiedExpected}`)}`);
422
- messageParts.push(` ${color2.red(`+ return ${stringifiedReceived}`)}`);
320
+ const stringifiedExpected = stringifyHttpValueToLog(diff.computed.expected);
321
+ const stringifiedReceived = stringifyHttpValueToLog(diff.computed.received);
322
+ messageParts.push(` ${color.green(`- return ${stringifiedExpected}`)}`);
323
+ messageParts.push(` ${color.red(`+ return ${stringifiedReceived}`)}`);
423
324
  }
424
325
  if (diff.headers) {
425
326
  messageParts.push("Headers:");
426
- const stringifiedExpected = stringifyValueToLog(diff.headers.expected);
427
- const stringifiedReceived = stringifyValueToLog(diff.headers.received);
428
- messageParts.push(` ${color2.green(`- ${stringifiedExpected}`)}`);
429
- messageParts.push(` ${color2.red(`+ ${stringifiedReceived}`)}`);
327
+ const stringifiedExpected = stringifyHttpValueToLog(diff.headers.expected);
328
+ const stringifiedReceived = stringifyHttpValueToLog(diff.headers.received);
329
+ messageParts.push(` ${color.green(`- ${stringifiedExpected}`)}`);
330
+ messageParts.push(` ${color.red(`+ ${stringifiedReceived}`)}`);
430
331
  }
431
332
  if (diff.searchParams) {
432
333
  messageParts.push("Search params:");
433
- const stringifiedExpected = stringifyValueToLog(diff.searchParams.expected);
434
- const stringifiedReceived = stringifyValueToLog(diff.searchParams.received);
435
- messageParts.push(` ${color2.green(`- ${stringifiedExpected}`)}`);
436
- messageParts.push(` ${color2.red(`+ ${stringifiedReceived}`)}`);
334
+ const stringifiedExpected = stringifyHttpValueToLog(diff.searchParams.expected);
335
+ const stringifiedReceived = stringifyHttpValueToLog(diff.searchParams.received);
336
+ messageParts.push(` ${color.green(`- ${stringifiedExpected}`)}`);
337
+ messageParts.push(` ${color.red(`+ ${stringifiedReceived}`)}`);
437
338
  }
438
339
  if (diff.body) {
439
340
  messageParts.push("Body:");
440
- const stringifiedExpected = stringifyValueToLog(diff.body.expected, {
341
+ const stringifiedExpected = stringifyHttpValueToLog(diff.body.expected, {
441
342
  includeClassName: { searchParams: true }
442
343
  });
443
- const stringifiedReceived = stringifyValueToLog(diff.body.received, {
344
+ const stringifiedReceived = stringifyHttpValueToLog(diff.body.received, {
444
345
  includeClassName: { searchParams: true }
445
346
  });
446
- messageParts.push(` ${color2.green(`- ${stringifiedExpected}`)}`);
447
- messageParts.push(` ${color2.red(`+ ${stringifiedReceived}`)}`);
347
+ messageParts.push(` ${color.green(`- ${stringifiedExpected}`)}`);
348
+ messageParts.push(` ${color.red(`+ ${stringifiedReceived}`)}`);
448
349
  }
449
350
  return messageParts.join("\n ");
450
351
  }).join("\n\n");
@@ -474,6 +375,16 @@ var HttpTimesCheckError = class extends TimesCheckError {
474
375
  };
475
376
  var HttpTimesCheckError_default = HttpTimesCheckError;
476
377
 
378
+ // ../zimic-utils/dist/chunk-W66SQPEM.mjs
379
+ function createCachedDynamicImport(importModuleDynamically) {
380
+ let cachedImportResult;
381
+ return async function importModuleDynamicallyWithCache() {
382
+ cachedImportResult ??= await importModuleDynamically();
383
+ return cachedImportResult;
384
+ };
385
+ }
386
+ var createCachedDynamicImport_default = createCachedDynamicImport;
387
+
477
388
  // ../zimic-utils/dist/time.mjs
478
389
  function waitForDelay(milliseconds) {
479
390
  return new Promise((resolve) => {
@@ -482,6 +393,14 @@ function waitForDelay(milliseconds) {
482
393
  }
483
394
  var waitForDelay_default = waitForDelay;
484
395
 
396
+ // src/utils/environment.ts
397
+ function isServerSide() {
398
+ return typeof process !== "undefined" && typeof process.versions !== "undefined";
399
+ }
400
+ function isClientSide() {
401
+ return typeof window !== "undefined" && typeof document !== "undefined";
402
+ }
403
+
485
404
  // src/utils/data.ts
486
405
  async function convertReadableStreamToBlob(stream, options) {
487
406
  const chunks = [];
@@ -1025,6 +944,102 @@ function methodCanHaveResponseBody(method) {
1025
944
  return HTTP_METHODS_WITH_RESPONSE_BODY.has(method);
1026
945
  }
1027
946
 
947
+ // ../zimic-utils/dist/logging.mjs
948
+ var Logger = class _Logger {
949
+ prefix;
950
+ raw;
951
+ constructor(options = {}) {
952
+ const { prefix } = options;
953
+ this.prefix = prefix;
954
+ this.raw = prefix ? new _Logger({ ...options, prefix: void 0 }) : this;
955
+ }
956
+ logWithLevel(level, ...messages) {
957
+ if (this.prefix) {
958
+ console[level](this.prefix, ...messages);
959
+ } else {
960
+ console[level](...messages);
961
+ }
962
+ }
963
+ info(...messages) {
964
+ this.logWithLevel("log", ...messages);
965
+ }
966
+ warn(...messages) {
967
+ this.logWithLevel("warn", ...messages);
968
+ }
969
+ error(...messages) {
970
+ this.logWithLevel("error", ...messages);
971
+ }
972
+ table(headers, rows) {
973
+ const columnLengths = headers.map((header) => {
974
+ let maxValueLength = header.title.length;
975
+ for (const row of rows) {
976
+ const value = row[header.property];
977
+ if (value.length > maxValueLength) {
978
+ maxValueLength = value.length;
979
+ }
980
+ }
981
+ return maxValueLength;
982
+ });
983
+ const formattedRows = [];
984
+ const horizontalLine = columnLengths.map((length) => "\u2500".repeat(length));
985
+ formattedRows.push(horizontalLine, []);
986
+ for (let headerIndex = 0; headerIndex < headers.length; headerIndex++) {
987
+ const header = headers[headerIndex];
988
+ const columnLength = columnLengths[headerIndex];
989
+ const value = header.title;
990
+ formattedRows.at(-1)?.push(value.padEnd(columnLength, " "));
991
+ }
992
+ formattedRows.push(horizontalLine);
993
+ for (const row of rows) {
994
+ formattedRows.push([]);
995
+ for (let headerIndex = 0; headerIndex < headers.length; headerIndex++) {
996
+ const header = headers[headerIndex];
997
+ const columnLength = columnLengths[headerIndex];
998
+ const value = row[header.property];
999
+ formattedRows.at(-1)?.push(value.padEnd(columnLength, " "));
1000
+ }
1001
+ }
1002
+ formattedRows.push(horizontalLine);
1003
+ const formattedTable = formattedRows.map((row, index) => {
1004
+ const isFirstLine = index === 0;
1005
+ if (isFirstLine) {
1006
+ return `\u250C\u2500${row.join("\u2500\u252C\u2500")}\u2500\u2510`;
1007
+ }
1008
+ const isLineAfterHeaders = index === 2;
1009
+ if (isLineAfterHeaders) {
1010
+ return `\u251C\u2500${row.join("\u2500\u253C\u2500")}\u2500\u2524`;
1011
+ }
1012
+ const isLastLine = index === formattedRows.length - 1;
1013
+ if (isLastLine) {
1014
+ return `\u2514\u2500${row.join("\u2500\u2534\u2500")}\u2500\u2518`;
1015
+ }
1016
+ return `\u2502 ${row.join(" \u2502 ")} \u2502`;
1017
+ }).join("\n");
1018
+ this.logWithLevel("log", formattedTable);
1019
+ }
1020
+ };
1021
+ var Logger_default = Logger;
1022
+ var logger = new Logger_default({
1023
+ prefix: color.cyan("[@zimic/interceptor]")
1024
+ });
1025
+ var importUtil = createCachedDynamicImport_default(() => import('util'));
1026
+ async function formatValueToLog(value, options = {}) {
1027
+ if (isClientSide()) {
1028
+ return value;
1029
+ }
1030
+ const { colors = true } = options;
1031
+ const util = await importUtil();
1032
+ return util.inspect(value, {
1033
+ colors,
1034
+ compact: true,
1035
+ depth: Infinity,
1036
+ maxArrayLength: Infinity,
1037
+ maxStringLength: Infinity,
1038
+ breakLength: Infinity,
1039
+ sorted: true
1040
+ });
1041
+ }
1042
+
1028
1043
  // src/http/requestHandler/types/requests.ts
1029
1044
  var HTTP_INTERCEPTOR_REQUEST_HIDDEN_PROPERTIES = Object.freeze(
1030
1045
  /* @__PURE__ */ new Set([
@@ -1063,7 +1078,13 @@ var HttpInterceptorWorker = class _HttpInterceptorWorker {
1063
1078
  startingPromise;
1064
1079
  stoppingPromise;
1065
1080
  runningInterceptors = [];
1081
+ get numberOfRunningInterceptors() {
1082
+ return this.runningInterceptors.length;
1083
+ }
1066
1084
  async sharedStart(internalStart) {
1085
+ if (this.stoppingPromise) {
1086
+ await this.stoppingPromise;
1087
+ }
1067
1088
  if (this.isRunning) {
1068
1089
  return;
1069
1090
  }
@@ -1092,9 +1113,12 @@ var HttpInterceptorWorker = class _HttpInterceptorWorker {
1092
1113
  const stoppingResult = internalStop();
1093
1114
  if (stoppingResult instanceof Promise) {
1094
1115
  this.stoppingPromise = stoppingResult;
1095
- await this.stoppingPromise;
1116
+ try {
1117
+ await this.stoppingPromise;
1118
+ } finally {
1119
+ this.stoppingPromise = void 0;
1120
+ }
1096
1121
  }
1097
- this.stoppingPromise = void 0;
1098
1122
  }
1099
1123
  async logUnhandledRequestIfNecessary(request, strategy) {
1100
1124
  if (strategy?.log) {
@@ -1332,7 +1356,7 @@ var HttpInterceptorWorker = class _HttpInterceptorWorker {
1332
1356
  formatValueToLog(request.body)
1333
1357
  ]);
1334
1358
  logger[action === "bypass" ? "warn" : "error"](
1335
- `${action === "bypass" ? "Warning:" : "Error:"} Request was not handled and was ${action === "bypass" ? color2.yellow("bypassed") : color2.red("rejected")}.
1359
+ `${action === "bypass" ? "Warning:" : "Error:"} Request was not handled and was ${action === "bypass" ? color.yellow("bypassed") : color.red("rejected")}.
1336
1360
 
1337
1361
  `,
1338
1362
  `${request.method} ${request.url}`,
@@ -1349,16 +1373,16 @@ var HttpInterceptorWorker = class _HttpInterceptorWorker {
1349
1373
  var HttpInterceptorWorker_default = HttpInterceptorWorker;
1350
1374
 
1351
1375
  // src/http/requestHandler/RemoteHttpRequestHandler.ts
1352
- var UNSYNCED_PROPERTIES = /* @__PURE__ */ new Set(["then"]);
1376
+ var PENDING_PROPERTIES = /* @__PURE__ */ new Set(["then"]);
1353
1377
  var RemoteHttpRequestHandler = class {
1354
1378
  type = "remote";
1355
1379
  implementation;
1356
1380
  syncPromises = [];
1357
- unsynced;
1381
+ pending;
1358
1382
  synced;
1359
1383
  constructor(interceptor, method, path) {
1360
1384
  this.implementation = new HttpRequestHandlerImplementation_default(interceptor, method, path, this);
1361
- this.unsynced = this;
1385
+ this.pending = this;
1362
1386
  this.synced = this.createSyncedProxy();
1363
1387
  }
1364
1388
  createSyncedProxy() {
@@ -1378,7 +1402,7 @@ var RemoteHttpRequestHandler = class {
1378
1402
  });
1379
1403
  }
1380
1404
  shouldBeHiddenPropertyWhenSynced(property) {
1381
- return UNSYNCED_PROPERTIES.has(property);
1405
+ return PENDING_PROPERTIES.has(property);
1382
1406
  }
1383
1407
  get method() {
1384
1408
  return this.implementation.method;
@@ -1388,16 +1412,16 @@ var RemoteHttpRequestHandler = class {
1388
1412
  }
1389
1413
  with(restriction) {
1390
1414
  this.implementation.with(restriction);
1391
- return this.unsynced;
1415
+ return this.pending;
1392
1416
  }
1393
1417
  delay(minMilliseconds, maxMilliseconds) {
1394
1418
  this.implementation.delay(minMilliseconds, maxMilliseconds);
1395
- return this.unsynced;
1419
+ return this.pending;
1396
1420
  }
1397
1421
  respond(declaration) {
1398
- const newUnsyncedThis = this.unsynced;
1399
- newUnsyncedThis.implementation.respond(declaration);
1400
- return newUnsyncedThis;
1422
+ const pending = this.pending;
1423
+ pending.implementation.respond(declaration);
1424
+ return pending;
1401
1425
  }
1402
1426
  times(minNumberOfRequests, maxNumberOfRequests) {
1403
1427
  this.implementation.times(minNumberOfRequests, maxNumberOfRequests);
@@ -1415,7 +1439,7 @@ var RemoteHttpRequestHandler = class {
1415
1439
  }
1416
1440
  clear() {
1417
1441
  this.implementation.clear();
1418
- return this.unsynced;
1442
+ return this.pending;
1419
1443
  }
1420
1444
  get requests() {
1421
1445
  return this.implementation.requests;
@@ -1447,7 +1471,7 @@ var RemoteHttpRequestHandler = class {
1447
1471
  const promisesToWait = new Set(this.syncPromises);
1448
1472
  return Promise.all(promisesToWait).then(() => {
1449
1473
  this.syncPromises = this.syncPromises.filter((promise) => !promisesToWait.has(promise));
1450
- return this.isSynced ? this.synced : this.unsynced;
1474
+ return this.isSynced ? this.synced : this.pending;
1451
1475
  }).then(onFulfilled, onRejected);
1452
1476
  }
1453
1477
  catch(onRejected) {
@@ -1468,6 +1492,9 @@ var HttpInterceptorImplementation = class {
1468
1492
  createWorker;
1469
1493
  deleteWorker;
1470
1494
  worker;
1495
+ startPromise;
1496
+ numberOfPendingStarts = 0;
1497
+ lifecycleQueue = Promise.resolve();
1471
1498
  requestSaving;
1472
1499
  numberOfSavedRequests = 0;
1473
1500
  onUnhandledRequest;
@@ -1501,7 +1528,7 @@ var HttpInterceptorImplementation = class {
1501
1528
  return this.#baseURL;
1502
1529
  }
1503
1530
  set baseURL(newBaseURL) {
1504
- if (this.isRunning) {
1531
+ if (this.isRunning || this.isStarting) {
1505
1532
  throw new RunningHttpInterceptorError_default(
1506
1533
  "Did you forget to call `await interceptor.stop()` before changing the base URL?"
1507
1534
  );
@@ -1525,27 +1552,67 @@ var HttpInterceptorImplementation = class {
1525
1552
  get platform() {
1526
1553
  return this.worker?.platform ?? null;
1527
1554
  }
1528
- async start() {
1555
+ start() {
1556
+ if (this.startPromise) {
1557
+ return this.startPromise;
1558
+ }
1559
+ this.numberOfPendingStarts++;
1560
+ const startPromise = this.enqueueLifecycleOperation(() => this.startOnce()).finally(() => {
1561
+ this.numberOfPendingStarts--;
1562
+ const isLastStartPromise = this.startPromise === startPromise;
1563
+ if (isLastStartPromise) {
1564
+ this.startPromise = void 0;
1565
+ }
1566
+ });
1567
+ this.startPromise = startPromise;
1568
+ return startPromise;
1569
+ }
1570
+ async startOnce() {
1571
+ if (this.isRunning) {
1572
+ return;
1573
+ }
1529
1574
  try {
1530
1575
  this.worker = this.createWorker();
1531
- await this.worker.start();
1532
1576
  this.worker.registerRunningInterceptor(this);
1577
+ await this.worker.start();
1533
1578
  this.markAsRunning(true);
1534
1579
  } catch (error) {
1535
- await this.stop();
1580
+ await this.stopWorker();
1536
1581
  throw error;
1537
1582
  }
1538
1583
  }
1539
- async stop() {
1584
+ get isStarting() {
1585
+ return this.numberOfPendingStarts > 0;
1586
+ }
1587
+ async stop(options) {
1588
+ this.startPromise = void 0;
1589
+ await this.enqueueLifecycleOperation(() => this.stopOnce(options));
1590
+ }
1591
+ async stopOnce(options) {
1592
+ if (!this.isRunning) {
1593
+ return;
1594
+ }
1595
+ await options.beforeStop?.();
1596
+ await this.stopWorker();
1597
+ }
1598
+ async stopWorker() {
1540
1599
  this.worker?.unregisterRunningInterceptor(this);
1541
- const isLastRunningInterceptor = this.numberOfRunningInterceptors === 0 || this.numberOfRunningInterceptors === 1;
1600
+ const isLastRunningInterceptor = this.worker?.numberOfRunningInterceptors === 0;
1542
1601
  if (isLastRunningInterceptor) {
1543
1602
  await this.worker?.stop();
1544
- this.deleteWorker();
1603
+ const isStillLastRunningInterceptor = this.worker?.numberOfRunningInterceptors === 0;
1604
+ if (isStillLastRunningInterceptor) {
1605
+ this.deleteWorker();
1606
+ }
1545
1607
  }
1546
1608
  this.markAsRunning(false);
1547
1609
  this.worker = void 0;
1548
1610
  }
1611
+ enqueueLifecycleOperation(operation) {
1612
+ const operationPromise = this.lifecycleQueue.then(operation);
1613
+ this.lifecycleQueue = operationPromise.catch(() => void 0);
1614
+ return operationPromise;
1615
+ }
1549
1616
  markAsRunning(isRunning) {
1550
1617
  if (this.workerOrThrow.type === "local") {
1551
1618
  this.store.markLocalInterceptorAsRunning(this, isRunning);
@@ -1554,16 +1621,6 @@ var HttpInterceptorImplementation = class {
1554
1621
  }
1555
1622
  this.isRunning = isRunning;
1556
1623
  }
1557
- get numberOfRunningInterceptors() {
1558
- if (!this.isRunning) {
1559
- return 0;
1560
- }
1561
- if (this.workerOrThrow.type === "local") {
1562
- return this.store.numberOfRunningLocalInterceptors;
1563
- } else {
1564
- return this.store.numberOfRunningRemoteInterceptors(this.baseURL);
1565
- }
1566
- }
1567
1624
  get(path) {
1568
1625
  return this.createHttpRequestHandler("GET", path);
1569
1626
  }
@@ -1712,13 +1769,91 @@ var HttpInterceptorImplementation = class {
1712
1769
  }
1713
1770
  };
1714
1771
  var HttpInterceptorImplementation_default = HttpInterceptorImplementation;
1772
+
1773
+ // src/interceptor/LocalMSWWorkerStore.ts
1715
1774
  var importMSWNode = createCachedDynamicImport_default(() => import('msw/node'));
1716
1775
  var importMSWBrowser = createCachedDynamicImport_default(() => import('msw/browser'));
1717
- var LocalHttpInterceptorWorker = class _LocalHttpInterceptorWorker extends HttpInterceptorWorker_default {
1718
- // Re-creating MSW workers may cause issues, so we should keep a single worker instance, even if all interceptor
1719
- // workers are stopped. See https://github.com/mswjs/msw/issues/2597.
1776
+ var LocalMSWWorkerStore = class _LocalMSWWorkerStore {
1720
1777
  static mswWorker;
1778
+ static creatingMSWWorkerPromise;
1779
+ static startingMSWWorkerPromise;
1780
+ static numberOfRunningWorkers = 0;
1721
1781
  static isMSWWorkerRunning = false;
1782
+ class = _LocalMSWWorkerStore;
1783
+ get mswWorker() {
1784
+ return this.class.mswWorker;
1785
+ }
1786
+ async getMSWWorkerOrCreate(options) {
1787
+ if (this.class.mswWorker) {
1788
+ return this.class.mswWorker;
1789
+ }
1790
+ this.class.creatingMSWWorkerPromise ??= this.createMSWWorker(options).then((mswWorker) => {
1791
+ this.class.mswWorker = mswWorker;
1792
+ return mswWorker;
1793
+ }).finally(() => {
1794
+ this.class.creatingMSWWorkerPromise = void 0;
1795
+ });
1796
+ return this.class.creatingMSWWorkerPromise;
1797
+ }
1798
+ async createMSWWorker(options) {
1799
+ if (isServerSide()) {
1800
+ const mswNode = await importMSWNode();
1801
+ if ("setupServer" in mswNode) {
1802
+ return mswNode.setupServer();
1803
+ }
1804
+ }
1805
+ if (isClientSide()) {
1806
+ const mswBrowser = await importMSWBrowser();
1807
+ if ("setupWorker" in mswBrowser) {
1808
+ return mswBrowser.setupWorker();
1809
+ }
1810
+ }
1811
+ throw options.createUnknownPlatformError();
1812
+ }
1813
+ async startMSWWorker(mswWorker, sharedOptions) {
1814
+ if (!this.class.isMSWWorkerRunning) {
1815
+ this.class.startingMSWWorkerPromise ??= this.startMSWWorkerOnce(mswWorker, sharedOptions).then(() => {
1816
+ this.class.isMSWWorkerRunning = true;
1817
+ }).finally(() => {
1818
+ this.class.startingMSWWorkerPromise = void 0;
1819
+ });
1820
+ await this.class.startingMSWWorkerPromise;
1821
+ }
1822
+ this.class.numberOfRunningWorkers++;
1823
+ }
1824
+ async startMSWWorkerOnce(mswWorker, sharedOptions) {
1825
+ if (this.isInternalBrowserWorker(mswWorker)) {
1826
+ try {
1827
+ await mswWorker.start({ ...sharedOptions, quiet: true });
1828
+ } catch (error) {
1829
+ if (UnregisteredBrowserServiceWorkerError_default.matchesRawError(error)) {
1830
+ throw new UnregisteredBrowserServiceWorkerError_default();
1831
+ } else {
1832
+ throw error;
1833
+ }
1834
+ }
1835
+ } else {
1836
+ mswWorker.listen(sharedOptions);
1837
+ }
1838
+ }
1839
+ stopMSWWorker(mswWorker) {
1840
+ this.class.numberOfRunningWorkers = Math.max(this.class.numberOfRunningWorkers - 1, 0);
1841
+ if (this.class.numberOfRunningWorkers > 0) {
1842
+ return;
1843
+ }
1844
+ if (this.isInternalBrowserWorker(mswWorker)) ; else {
1845
+ mswWorker.close();
1846
+ this.class.isMSWWorkerRunning = false;
1847
+ }
1848
+ }
1849
+ isInternalBrowserWorker(worker) {
1850
+ return "start" in worker && "stop" in worker;
1851
+ }
1852
+ };
1853
+ var LocalMSWWorkerStore_default = LocalMSWWorkerStore;
1854
+
1855
+ // src/http/interceptorWorker/LocalHttpInterceptorWorker.ts
1856
+ var LocalHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
1722
1857
  mswHttpHandler;
1723
1858
  httpHandlersByMethod = {
1724
1859
  GET: [],
@@ -1729,39 +1864,28 @@ var LocalHttpInterceptorWorker = class _LocalHttpInterceptorWorker extends HttpI
1729
1864
  HEAD: [],
1730
1865
  OPTIONS: []
1731
1866
  };
1867
+ store = new LocalMSWWorkerStore_default();
1732
1868
  constructor(_options) {
1733
1869
  super();
1734
1870
  }
1735
- get class() {
1736
- return _LocalHttpInterceptorWorker;
1737
- }
1738
1871
  get type() {
1739
1872
  return "local";
1740
1873
  }
1741
1874
  get mswWorkerOrThrow() {
1742
- if (!this.class.mswWorker) {
1875
+ if (!this.store.mswWorker) {
1743
1876
  throw new NotRunningHttpInterceptorError_default();
1744
1877
  }
1745
- return this.class.mswWorker;
1878
+ return this.store.mswWorker;
1746
1879
  }
1747
1880
  async getMSWWorkerOrCreate() {
1748
- this.class.mswWorker ??= await this.createMSWWorker();
1749
- return this.class.mswWorker;
1750
- }
1751
- async createMSWWorker() {
1752
- if (isServerSide()) {
1753
- const mswNode = await importMSWNode();
1754
- if ("setupServer" in mswNode) {
1755
- return mswNode.setupServer();
1756
- }
1757
- }
1758
- if (isClientSide()) {
1759
- const mswBrowser = await importMSWBrowser();
1760
- if ("setupWorker" in mswBrowser) {
1761
- return mswBrowser.setupWorker();
1762
- }
1763
- }
1764
- throw new UnknownHttpInterceptorPlatformError_default();
1881
+ return this.store.getMSWWorkerOrCreate({
1882
+ createUnknownPlatformError: (
1883
+ // The unknown platform error is created here to prevent the store from relying on HTTP-specific resources.
1884
+ /* istanbul ignore next -- @preserve
1885
+ * Unknown runtime platforms are not part of the package test matrix. */
1886
+ () => new UnknownHttpInterceptorPlatformError_default()
1887
+ )
1888
+ });
1765
1889
  }
1766
1890
  async start() {
1767
1891
  await super.sharedStart(async () => {
@@ -1777,54 +1901,33 @@ var LocalHttpInterceptorWorker = class _LocalHttpInterceptorWorker extends HttpI
1777
1901
  mswWorker.use(this.mswHttpHandler);
1778
1902
  if (this.isInternalBrowserWorker(mswWorker)) {
1779
1903
  this.platform = "browser";
1780
- if (!this.class.isMSWWorkerRunning) {
1781
- await this.startInBrowser(mswWorker, sharedOptions);
1782
- this.class.isMSWWorkerRunning = true;
1783
- }
1784
1904
  } else {
1785
1905
  this.platform = "node";
1786
- this.startInNode(mswWorker, sharedOptions);
1787
- this.class.isMSWWorkerRunning = true;
1906
+ }
1907
+ try {
1908
+ await this.store.startMSWWorker(mswWorker, sharedOptions);
1909
+ } catch (error) {
1910
+ const newMSWHandlers = mswWorker.listHandlers().filter((handler) => handler !== this.mswHttpHandler);
1911
+ mswWorker.resetHandlers(...newMSWHandlers);
1912
+ this.mswHttpHandler = void 0;
1913
+ throw error;
1788
1914
  }
1789
1915
  this.isRunning = true;
1790
1916
  });
1791
1917
  }
1792
- async startInBrowser(mswWorker, sharedOptions) {
1793
- try {
1794
- await mswWorker.start({ ...sharedOptions, quiet: true });
1795
- } catch (error) {
1796
- this.handleBrowserWorkerStartError(error);
1797
- }
1798
- }
1799
- handleBrowserWorkerStartError(error) {
1800
- if (UnregisteredBrowserServiceWorkerError_default.matchesRawError(error)) {
1801
- throw new UnregisteredBrowserServiceWorkerError_default();
1802
- } else {
1803
- throw error;
1804
- }
1805
- }
1806
- startInNode(mswWorker, sharedOptions) {
1807
- mswWorker.listen(sharedOptions);
1808
- }
1809
1918
  async stop() {
1810
1919
  await super.sharedStop(async () => {
1811
1920
  const mswWorker = await this.getMSWWorkerOrCreate();
1812
1921
  this.clearHandlers();
1813
1922
  const newMSWHandlers = mswWorker.listHandlers().filter((handler) => handler !== this.mswHttpHandler);
1814
1923
  mswWorker.resetHandlers(...newMSWHandlers);
1815
- if (this.isInternalBrowserWorker(mswWorker)) ; else {
1816
- this.stopInNode(mswWorker);
1817
- this.class.isMSWWorkerRunning = false;
1818
- }
1924
+ this.store.stopMSWWorker(mswWorker);
1819
1925
  this.mswHttpHandler = void 0;
1820
1926
  this.isRunning = false;
1821
1927
  });
1822
1928
  }
1823
- stopInNode(mswWorker) {
1824
- mswWorker.close();
1825
- }
1826
1929
  isInternalBrowserWorker(worker) {
1827
- return "start" in worker && "stop" in worker;
1930
+ return this.store.isInternalBrowserWorker(worker);
1828
1931
  }
1829
1932
  hasInternalBrowserWorker() {
1830
1933
  return this.isInternalBrowserWorker(this.mswWorkerOrThrow);
@@ -2555,24 +2658,15 @@ var RemoteHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
2555
2658
  };
2556
2659
  var RemoteHttpInterceptorWorker_default = RemoteHttpInterceptorWorker;
2557
2660
 
2558
- // src/http/interceptorWorker/factory.ts
2559
- function createHttpInterceptorWorker(options) {
2560
- if (options.type === "local") {
2561
- return new LocalHttpInterceptorWorker_default(options);
2562
- } else {
2563
- return new RemoteHttpInterceptorWorker_default(options);
2564
- }
2565
- }
2566
-
2567
2661
  // src/http/interceptor/HttpInterceptorStore.ts
2568
2662
  var HttpInterceptorStore = class _HttpInterceptorStore {
2569
- static _localWorker;
2570
- static runningLocalInterceptors = /* @__PURE__ */ new Set();
2663
+ static localWorker;
2571
2664
  static remoteWorkers = /* @__PURE__ */ new Map();
2665
+ static runningLocalInterceptors = /* @__PURE__ */ new Set();
2572
2666
  static runningRemoteInterceptors = /* @__PURE__ */ new Map();
2573
2667
  class = _HttpInterceptorStore;
2574
2668
  get localWorker() {
2575
- return this.class._localWorker;
2669
+ return this.class.localWorker;
2576
2670
  }
2577
2671
  getRemoteWorkerKey(baseURL, options) {
2578
2672
  const key = [`${baseURL.origin}${baseURL.pathname}`];
@@ -2581,7 +2675,7 @@ var HttpInterceptorStore = class _HttpInterceptorStore {
2581
2675
  }
2582
2676
  return key.join(":");
2583
2677
  }
2584
- remoteWorker(baseURL, options) {
2678
+ getRemoteWorker(baseURL, options) {
2585
2679
  const remoteWorkerKey = this.getRemoteWorkerKey(baseURL, options);
2586
2680
  return this.class.remoteWorkers.get(remoteWorkerKey);
2587
2681
  }
@@ -2613,16 +2707,16 @@ var HttpInterceptorStore = class _HttpInterceptorStore {
2613
2707
  return runningInterceptors;
2614
2708
  }
2615
2709
  getOrCreateLocalWorker(workerOptions) {
2616
- const existingWorker = this.class._localWorker;
2710
+ const existingWorker = this.class.localWorker;
2617
2711
  if (existingWorker) {
2618
2712
  return existingWorker;
2619
2713
  }
2620
- const createdWorker = createHttpInterceptorWorker({ ...workerOptions, type: "local" });
2621
- this.class._localWorker = createdWorker;
2714
+ const createdWorker = new LocalHttpInterceptorWorker_default({ ...workerOptions, type: "local" });
2715
+ this.class.localWorker = createdWorker;
2622
2716
  return createdWorker;
2623
2717
  }
2624
2718
  deleteLocalWorker() {
2625
- this.class._localWorker = void 0;
2719
+ this.class.localWorker = void 0;
2626
2720
  }
2627
2721
  getOrCreateRemoteWorker(workerOptions) {
2628
2722
  const remoteWorkerKey = this.getRemoteWorkerKey(workerOptions.serverURL, { auth: workerOptions.auth });
@@ -2630,7 +2724,7 @@ var HttpInterceptorStore = class _HttpInterceptorStore {
2630
2724
  if (existingWorker) {
2631
2725
  return existingWorker;
2632
2726
  }
2633
- const createdWorker = createHttpInterceptorWorker({ ...workerOptions, type: "remote" });
2727
+ const createdWorker = new RemoteHttpInterceptorWorker_default({ ...workerOptions, type: "remote" });
2634
2728
  this.class.remoteWorkers.set(remoteWorkerKey, createdWorker);
2635
2729
  return createdWorker;
2636
2730
  }
@@ -2685,17 +2779,10 @@ var LocalHttpInterceptor = class {
2685
2779
  return this.implementation.isRunning;
2686
2780
  }
2687
2781
  async start() {
2688
- if (this.isRunning) {
2689
- return;
2690
- }
2691
2782
  await this.implementation.start();
2692
2783
  }
2693
2784
  async stop() {
2694
- if (!this.isRunning) {
2695
- return;
2696
- }
2697
- this.clear();
2698
- await this.implementation.stop();
2785
+ await this.implementation.stop({ beforeStop: () => this.clear() });
2699
2786
  }
2700
2787
  get = ((path) => {
2701
2788
  return this.implementation.get(path);
@@ -2733,24 +2820,24 @@ var RemoteHttpInterceptor = class {
2733
2820
  implementation;
2734
2821
  #auth;
2735
2822
  constructor(options) {
2736
- this.#auth = options.auth;
2737
2823
  const baseURL = new URL(options.baseURL);
2738
2824
  this.implementation = new HttpInterceptorImplementation_default({
2739
2825
  store: this.store,
2740
2826
  baseURL,
2741
2827
  createWorker: () => {
2742
2828
  return this.store.getOrCreateRemoteWorker({
2743
- serverURL: baseURL,
2829
+ serverURL: this.implementation.baseURL,
2744
2830
  auth: this.#auth
2745
2831
  });
2746
2832
  },
2747
2833
  deleteWorker: () => {
2748
- this.store.deleteRemoteWorker(baseURL, { auth: options.auth });
2834
+ this.store.deleteRemoteWorker(this.implementation.baseURL, { auth: this.#auth });
2749
2835
  },
2750
2836
  Handler: RemoteHttpRequestHandler_default,
2751
2837
  onUnhandledRequest: options.onUnhandledRequest,
2752
2838
  requestSaving: options.requestSaving
2753
2839
  });
2840
+ this.auth = options.auth;
2754
2841
  }
2755
2842
  get type() {
2756
2843
  return "remote";
@@ -2772,21 +2859,25 @@ var RemoteHttpInterceptor = class {
2772
2859
  }
2773
2860
  set auth(auth) {
2774
2861
  const cannotChangeAuthWhileRunningMessage = "Did you forget to call `await interceptor.stop()` before changing the authentication parameters?";
2775
- if (this.isRunning) {
2862
+ if (this.isRunning || this.implementation.isStarting) {
2776
2863
  throw new RunningHttpInterceptorError_default(cannotChangeAuthWhileRunningMessage);
2777
2864
  }
2778
2865
  if (!auth) {
2779
2866
  this.#auth = void 0;
2780
2867
  return;
2781
2868
  }
2782
- this.#auth = new Proxy(auth, {
2783
- set: (target, property, value) => {
2784
- if (this.isRunning) {
2785
- throw new RunningHttpInterceptorError_default(cannotChangeAuthWhileRunningMessage);
2869
+ this.#auth = new Proxy(
2870
+ { ...auth },
2871
+ // Copy object to ensure it's not mutated later without going though the proxy.
2872
+ {
2873
+ set: (target, property, value) => {
2874
+ if (this.isRunning || this.implementation.isStarting) {
2875
+ throw new RunningHttpInterceptorError_default(cannotChangeAuthWhileRunningMessage);
2876
+ }
2877
+ return Reflect.set(target, property, value);
2786
2878
  }
2787
- return Reflect.set(target, property, value);
2788
2879
  }
2789
- });
2880
+ );
2790
2881
  }
2791
2882
  get onUnhandledRequest() {
2792
2883
  return this.implementation.onUnhandledRequest;
@@ -2801,17 +2892,10 @@ var RemoteHttpInterceptor = class {
2801
2892
  return this.implementation.isRunning;
2802
2893
  }
2803
2894
  async start() {
2804
- if (this.isRunning) {
2805
- return;
2806
- }
2807
2895
  await this.implementation.start();
2808
2896
  }
2809
2897
  async stop() {
2810
- if (!this.isRunning) {
2811
- return;
2812
- }
2813
- await this.clear();
2814
- await this.implementation.stop();
2898
+ await this.implementation.stop({ beforeStop: () => this.clear() });
2815
2899
  }
2816
2900
  get = ((path) => {
2817
2901
  return this.implementation.get(path);
@@ -2858,6 +2942,7 @@ function isRemoteHttpInterceptorOptions(options) {
2858
2942
  return options.type === "remote";
2859
2943
  }
2860
2944
  function createHttpInterceptor(options) {
2945
+ assertTypeOf_default("options.baseURL", options.baseURL, "string");
2861
2946
  const type = options.type;
2862
2947
  if (isLocalHttpInterceptorOptions(options)) {
2863
2948
  return new LocalHttpInterceptor_default(options);
@@ -2881,19 +2966,12 @@ var InvalidJSONError = class extends InvalidJSONError$1 {
2881
2966
  * This is just a type guard to ensure the value is valid. In practice, this condition should never be true. */
2882
2967
  /* istanbul ignore next -- @preserve
2883
2968
  * Ignoring because there will always be a handler for the given method and path at this point. */
2884
- /* istanbul ignore if -- @preserve
2885
- * Trying to access the internal worker when it does not exist should not happen. */
2886
- /* istanbul ignore else -- @preserve
2887
- * We still check if we actually imported the server module in case our `isServerSide()` check returns true, but
2888
- * the environment actually resolves the browser module. */
2889
2969
  /* istanbul ignore else -- @preserve */
2970
+ /* istanbul ignore next -- @preserve */
2890
2971
  /* istanbul ignore else -- @preserve
2891
- * We still check if we actually imported the browser module in case our `isClientSide()` check returns true, but
2892
- * the environment actually resolves the server module. */
2893
- /* istanbul ignore next -- @preserve
2894
- * Ignoring because checking unknown platforms is not configured in our test setup. */
2895
- /* istanbul ignore else -- @preserve
2896
- * Since we start the internal worker once and do not stop it, tests may not be able exercise this branch. */
2972
+ * Browser worker start errors other than unregistered service workers come from MSW internals. */
2973
+ /* istanbul ignore if -- @preserve
2974
+ * Trying to access the internal worker when it does not exist should not happen. */
2897
2975
  /* istanbul ignore else -- @preserve
2898
2976
  * An unauthorized close event is the only one we expect to happen here. */
2899
2977
  /* istanbul ignore else -- @preserve
@@ -2907,6 +2985,8 @@ var InvalidJSONError = class extends InvalidJSONError$1 {
2907
2985
  * would reach a timeout and not be responded. The empty set serves as a fallback. */
2908
2986
  /* istanbul ignore if -- @preserve
2909
2987
  * Aborting requests is highly non-deterministic because it depends on specific timing of socket events. */
2988
+ /* istanbul ignore next -- @preserve
2989
+ * Ignoring because checking unknown platforms is not configured in our test setup. */
2910
2990
  /* istanbul ignore next -- @preserve
2911
2991
  *
2912
2992
  * If the socket is closed before receiving a response, the message is aborted with an error. This can happen if
@@ -2915,7 +2995,6 @@ var InvalidJSONError = class extends InvalidJSONError$1 {
2915
2995
  * necessary.
2916
2996
  *
2917
2997
  * Due to the rare nature of this edge case, we can't reliably reproduce it in tests. */
2918
- /* istanbul ignore next -- @preserve */
2919
2998
 
2920
2999
  export { DisabledRequestSavingError_default as DisabledRequestSavingError, HttpTimesCheckError_default as HttpTimesCheckError, InvalidFormDataError, InvalidJSONError, NotRunningHttpInterceptorError_default as NotRunningHttpInterceptorError, RequestSavingSafeLimitExceededError_default as RequestSavingSafeLimitExceededError, RunningHttpInterceptorError_default as RunningHttpInterceptorError, TimesCheckError, UnknownHttpInterceptorPlatformError_default as UnknownHttpInterceptorPlatformError, UnknownHttpInterceptorTypeError_default as UnknownHttpInterceptorTypeError, UnregisteredBrowserServiceWorkerError_default as UnregisteredBrowserServiceWorkerError, createHttpInterceptor };
2921
3000
  //# sourceMappingURL=http.mjs.map