@depup/msw 3.0.1-depup.0 → 3.0.3-depup.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -4
- package/changes.json +7 -3
- package/lib/_chunks/cookie-store.js +3 -2
- package/lib/_chunks/cookie-store.js.map +1 -1
- package/lib/_chunks/interceptor-source.d.ts +5 -1
- package/lib/_chunks/interceptor-source.js +18 -5
- package/lib/_chunks/interceptor-source.js.map +1 -1
- package/lib/_chunks/request-handler.d.ts +3 -2
- package/lib/browser/index.d.ts +4 -9
- package/lib/browser/index.js +21 -14
- package/lib/browser/index.js.map +1 -1
- package/lib/graphql/index.d.ts +19 -4
- package/lib/graphql/index.js +24 -12
- package/lib/graphql/index.js.map +1 -1
- package/lib/iife/index.js +66 -33
- package/lib/iife/index.js.map +1 -1
- package/lib/mockServiceWorker.js +1 -1
- package/lib/vite/index.js +10 -7
- package/lib/vite/index.js.map +1 -1
- package/lib/vite/runtime.d.ts +2 -3
- package/lib/vite/runtime.js +70 -68
- package/lib/vite/runtime.js.map +1 -1
- package/package.json +12 -9
- package/src/browser/default-network-options.ts +1 -1
- package/src/browser/setup-worker.ts +1 -4
- package/src/browser/sources/fallback-http-source.ts +11 -8
- package/src/browser/sources/service-worker-source.ts +12 -5
- package/src/browser/utils/should-invalidate-worker.test.ts +0 -16
- package/src/core/experimental/define-network.ts +1 -1
- package/src/core/experimental/handlers-controller.test.ts +61 -0
- package/src/core/experimental/handlers-controller.ts +39 -6
- package/src/core/experimental/sources/network-source.ts +8 -1
- package/src/core/handlers/handler.ts +3 -2
- package/src/graphql/graphql-subscription.ts +30 -12
- package/src/vite/plugin.test.ts +1 -1
- package/src/vite/plugin.ts +13 -10
- package/src/vite/runtime.ts +85 -85
- package/src/vite/tsconfig.build.json +1 -1
- package/src/vite/options.d.ts +0 -5
package/lib/mockServiceWorker.js
CHANGED
package/lib/vite/index.js
CHANGED
|
@@ -4,7 +4,6 @@ import { fileURLToPath } from "node:url";
|
|
|
4
4
|
const WORKER_FILENAME = "mockServiceWorker.js";
|
|
5
5
|
const WORKER_SCRIPT_PATH = new URL("../mockServiceWorker.js", import.meta.url);
|
|
6
6
|
const VIRTUAL_MODULE_ID = "virtual:msw";
|
|
7
|
-
const VIRTUAL_OPTIONS_ID = "virtual:msw/options";
|
|
8
7
|
const RUNTIME_PATH = fileURLToPath(new URL("./runtime.js", import.meta.url));
|
|
9
8
|
/**
|
|
10
9
|
* A Vite plugin for Mock Service Worker.
|
|
@@ -41,18 +40,22 @@ function msw(options = {}) {
|
|
|
41
40
|
const environmentsUsingNetwork = /* @__PURE__ */ new Set();
|
|
42
41
|
return {
|
|
43
42
|
name: "msw",
|
|
44
|
-
|
|
43
|
+
resolveId(id) {
|
|
45
44
|
if (mode === "worker-only") return;
|
|
46
|
-
if (id ===
|
|
47
|
-
if (id === VIRTUAL_MODULE_ID) return this.resolve(RUNTIME_PATH);
|
|
45
|
+
if (id === VIRTUAL_MODULE_ID) return `\0${VIRTUAL_MODULE_ID}`;
|
|
48
46
|
},
|
|
49
47
|
load(id) {
|
|
50
|
-
if (mode === "worker-only" || id !== `\0${
|
|
51
|
-
if (this.environment.config.consumer === "server") return `
|
|
48
|
+
if (mode === "worker-only" || id !== `\0${VIRTUAL_MODULE_ID}`) return;
|
|
49
|
+
if (this.environment.config.consumer === "server") return `
|
|
50
|
+
import { defaultNetworkOptions } from 'msw/node'
|
|
51
|
+
import { createNetwork } from ${JSON.stringify(RUNTIME_PATH)}
|
|
52
|
+
export const network = await createNetwork(defaultNetworkOptions)
|
|
53
|
+
`;
|
|
52
54
|
environmentsUsingNetwork.add(this.environment.name);
|
|
53
55
|
return `
|
|
54
56
|
import { createDefaultNetworkOptions } from 'msw/browser'
|
|
55
|
-
|
|
57
|
+
import { createNetwork } from ${JSON.stringify(RUNTIME_PATH)}
|
|
58
|
+
export const network = await createNetwork(createDefaultNetworkOptions(${JSON.stringify(workerUrl)}))
|
|
56
59
|
`;
|
|
57
60
|
},
|
|
58
61
|
configResolved(config) {
|
package/lib/vite/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/vite/plugin.ts"],"sourcesContent":["import * as fs from 'node:fs'\nimport { fileURLToPath } from 'node:url'\nimport type { Plugin } from 'vite'\n\nconst WORKER_FILENAME = 'mockServiceWorker.js'\nconst WORKER_SCRIPT_PATH = new URL('../mockServiceWorker.js', import.meta.url)\nconst VIRTUAL_MODULE_ID = 'virtual:msw'\nconst
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/vite/plugin.ts"],"sourcesContent":["import * as fs from 'node:fs'\nimport { fileURLToPath } from 'node:url'\nimport type { Plugin } from 'vite'\n\nconst WORKER_FILENAME = 'mockServiceWorker.js'\nconst WORKER_SCRIPT_PATH = new URL('../mockServiceWorker.js', import.meta.url)\nconst VIRTUAL_MODULE_ID = 'virtual:msw'\nconst RUNTIME_PATH = fileURLToPath(new URL('./runtime.js', import.meta.url))\n\nexport interface MswPluginOptions {\n /**\n * Use automatic integration or only provide the worker script for manual setup.\n * In worker-only mode, virtual modules are disabled.\n * @default \"auto\"\n */\n mode?: 'auto' | 'worker-only'\n}\n\n/**\n * A Vite plugin for Mock Service Worker.\n *\n * @example\n * // vite.config.ts\n * import { msw } from 'msw/vite'\n *\n * export default defineConfig({\n * plugins: [msw()]\n * })\n *\n * @example\n * // src/{client,server}.ts\n * if (import.meta.env.DEV) {\n * const { network } = await import('virtual:msw')\n * const { handlers } = await import('./mocks/handlers')\n *\n * network.configure({ handlers })\n * await network.enable()\n * }\n *\n * @remarks\n * The worker script is served during development and emitted next to any\n * client bundle that imports `virtual:msw`. Guard mocking setup with\n * `import.meta.env.DEV` to exclude both from production builds.\n *\n * For application TypeScript projects that do not include the Vite config,\n * add `/// <reference types=\"msw/vite/client\" />` to an included declaration file.\n */\nexport function msw(options: MswPluginOptions = {}): Plugin {\n const mode = options.mode ?? 'auto'\n let workerUrl = `/${WORKER_FILENAME}`\n const environmentsUsingNetwork = new Set<string>()\n\n return {\n name: 'msw',\n resolveId(id) {\n if (mode === 'worker-only') {\n return\n }\n\n if (id === VIRTUAL_MODULE_ID) {\n return `\\0${VIRTUAL_MODULE_ID}`\n }\n },\n load(id) {\n if (mode === 'worker-only' || id !== `\\0${VIRTUAL_MODULE_ID}`) {\n return\n }\n\n // Tools like Vitest import the runtime natively when it's installed\n // in \"node_modules\". Provide it with the environment's options from here\n // so it never has to import a virtual module that only Vite can resolve.\n if (this.environment.config.consumer === 'server') {\n return `\nimport { defaultNetworkOptions } from 'msw/node'\nimport { createNetwork } from ${JSON.stringify(RUNTIME_PATH)}\nexport const network = await createNetwork(defaultNetworkOptions)\n`\n }\n\n environmentsUsingNetwork.add(this.environment.name)\n\n return `\nimport { createDefaultNetworkOptions } from 'msw/browser'\nimport { createNetwork } from ${JSON.stringify(RUNTIME_PATH)}\nexport const network = await createNetwork(createDefaultNetworkOptions(${JSON.stringify(workerUrl)}))\n`\n },\n configResolved(config) {\n // Keep relative build bases relative and service workers on the app's origin.\n const base =\n config.base === './'\n ? config.base\n : new URL(config.base, 'http://localhost').pathname\n workerUrl = `${base}${WORKER_FILENAME}`\n },\n generateBundle() {\n if (this.environment.config.consumer !== 'client') {\n return\n }\n\n // In \"auto\" mode, the worker is only useful to bundles that contain the\n // network. A user guard (e.g. `import.meta.env.DEV`) that drops the\n // `virtual:msw` import drops the worker too.\n if (\n mode === 'auto' &&\n !environmentsUsingNetwork.has(this.environment.name)\n ) {\n return\n }\n\n this.emitFile({\n type: 'asset',\n fileName: WORKER_FILENAME,\n source: fs.readFileSync(WORKER_SCRIPT_PATH, 'utf8'),\n })\n },\n configureServer(server) {\n const workerScript = fs.readFileSync(WORKER_SCRIPT_PATH, 'utf8')\n server.middlewares.use((request, response, next) => {\n const requestUrl = new URL(request.url ?? '/', 'http://localhost')\n\n if (requestUrl.pathname !== workerUrl) {\n next()\n return\n }\n\n response.writeHead(200, {\n 'cache-control': 'no-cache',\n 'content-type': 'application/javascript; charset=utf-8',\n 'service-worker-allowed': '/',\n })\n response.end(workerScript)\n })\n },\n }\n}\n"],"mappings":";;;AAIA,MAAM,kBAAkB;AACxB,MAAM,qBAAqB,IAAI,IAAI,2BAA2B,YAAY,GAAG;AAC7E,MAAM,oBAAoB;AAC1B,MAAM,eAAe,cAAc,IAAI,IAAI,gBAAgB,YAAY,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwC3E,SAAgB,IAAI,UAA4B,CAAC,GAAW;CAC1D,MAAM,OAAO,QAAQ,QAAQ;CAC7B,IAAI,YAAY,IAAI;CACpB,MAAM,2CAA2B,IAAI,IAAY;CAEjD,OAAO;EACL,MAAM;EACN,UAAU,IAAI;GACZ,IAAI,SAAS,eACX;GAGF,IAAI,OAAO,mBACT,OAAO,KAAK;EAEhB;EACA,KAAK,IAAI;GACP,IAAI,SAAS,iBAAiB,OAAO,KAAK,qBACxC;GAMF,IAAI,KAAK,YAAY,OAAO,aAAa,UACvC,OAAO;;gCAEiB,KAAK,UAAU,YAAY,EAAE;;;GAKvD,yBAAyB,IAAI,KAAK,YAAY,IAAI;GAElD,OAAO;;gCAEmB,KAAK,UAAU,YAAY,EAAE;yEACY,KAAK,UAAU,SAAS,EAAE;;EAE/F;EACA,eAAe,QAAQ;GAMrB,YAAY,GAHV,OAAO,SAAS,OACZ,OAAO,OACP,IAAI,IAAI,OAAO,MAAM,kBAAkB,CAAC,CAAC,WACzB;EACxB;EACA,iBAAiB;GACf,IAAI,KAAK,YAAY,OAAO,aAAa,UACvC;GAMF,IACE,SAAS,UACT,CAAC,yBAAyB,IAAI,KAAK,YAAY,IAAI,GAEnD;GAGF,KAAK,SAAS;IACZ,MAAM;IACN,UAAU;IACV,QAAQ,GAAG,aAAa,oBAAoB,MAAM;GACpD,CAAC;EACH;EACA,gBAAgB,QAAQ;GACtB,MAAM,eAAe,GAAG,aAAa,oBAAoB,MAAM;GAC/D,OAAO,YAAY,KAAK,SAAS,UAAU,SAAS;IAGlD,IAAI,IAFmB,IAAI,QAAQ,OAAO,KAAK,kBAElC,CAAC,CAAC,aAAa,WAAW;KACrC,KAAK;KACL;IACF;IAEA,SAAS,UAAU,KAAK;KACtB,iBAAiB;KACjB,gBAAgB;KAChB,0BAA0B;IAC5B,CAAC;IACD,SAAS,IAAI,YAAY;GAC3B,CAAC;EACH;CACF;AACF"}
|
package/lib/vite/runtime.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { defaultNetworkOptions } from "virtual:msw/options";
|
|
1
|
+
import { defineNetwork } from "msw/experimental";
|
|
3
2
|
//#region src/vite/runtime.d.ts
|
|
4
|
-
export declare
|
|
3
|
+
export declare function createNetwork(options: Parameters<typeof defineNetwork>[0]): Promise<ReturnType<typeof defineNetwork>>;
|
|
5
4
|
//#endregion
|
|
6
5
|
//# sourceMappingURL=runtime.d.ts.map
|
package/lib/vite/runtime.js
CHANGED
|
@@ -1,77 +1,79 @@
|
|
|
1
1
|
import { NetworkReadyState, defineNetwork } from "msw/experimental";
|
|
2
|
-
import { defaultNetworkOptions } from "virtual:msw/options";
|
|
3
2
|
//#region src/vite/runtime.ts
|
|
4
3
|
const hot = import.meta.hot;
|
|
5
4
|
const hotData = hot?.data;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
5
|
+
async function createNetwork(options) {
|
|
6
|
+
while (hotData?.disposeNetwork) {
|
|
7
|
+
const disposePrevious = hotData.disposeNetwork;
|
|
8
|
+
await disposePrevious();
|
|
9
|
+
if (hotData.disposeNetwork === disposePrevious) break;
|
|
10
|
+
}
|
|
11
|
+
const network = defineNetwork(options);
|
|
12
|
+
if (hot && hotData) {
|
|
13
|
+
let resumeAfterUpdate = false;
|
|
14
|
+
let retired = false;
|
|
15
|
+
let pendingOperation;
|
|
16
|
+
const configure = network.configure;
|
|
17
|
+
const enable = network.enable;
|
|
18
|
+
const disable = network.disable;
|
|
19
|
+
const runOperation = (action) => {
|
|
20
|
+
const result = pendingOperation ? pendingOperation.then(action) : action();
|
|
21
|
+
if (result instanceof Promise) {
|
|
22
|
+
const operation = result.finally(() => {
|
|
23
|
+
if (pendingOperation === operation) pendingOperation = void 0;
|
|
24
|
+
});
|
|
25
|
+
pendingOperation = operation;
|
|
26
|
+
return operation;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
const stop = () => {
|
|
30
|
+
if (network.readyState === NetworkReadyState.ENABLED) return disable();
|
|
31
|
+
};
|
|
32
|
+
network.configure = (options) => {
|
|
33
|
+
runOperation(() => {
|
|
34
|
+
if (retired) return;
|
|
35
|
+
const stopped = stop();
|
|
36
|
+
if (stopped instanceof Promise) return stopped.then(() => configure(options));
|
|
37
|
+
configure(options);
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
network.enable = async () => {
|
|
41
|
+
await runOperation(() => {
|
|
42
|
+
if (!retired && network.readyState === NetworkReadyState.DISABLED) return enable();
|
|
24
43
|
});
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const shouldResume = resumeAfterUpdate;
|
|
57
|
-
resumeAfterUpdate = false;
|
|
58
|
-
if (shouldResume && network.readyState === NetworkReadyState.DISABLED) await network.enable();
|
|
59
|
-
};
|
|
60
|
-
hot.on("vite:beforeUpdate", beforeUpdate);
|
|
61
|
-
hot.on("vite:afterUpdate", afterUpdate);
|
|
62
|
-
hot.on("vite:beforeFullReload", disableNetwork);
|
|
63
|
-
const disposeNetwork = async () => {
|
|
64
|
-
retired = true;
|
|
65
|
-
resumeAfterUpdate = false;
|
|
66
|
-
hot.off("vite:beforeUpdate", beforeUpdate);
|
|
67
|
-
hot.off("vite:afterUpdate", afterUpdate);
|
|
68
|
-
hot.off("vite:beforeFullReload", disableNetwork);
|
|
69
|
-
await disableNetwork();
|
|
70
|
-
};
|
|
71
|
-
hotData.disposeNetwork = disposeNetwork;
|
|
72
|
-
hot.dispose(disposeNetwork);
|
|
44
|
+
};
|
|
45
|
+
network.disable = async () => {
|
|
46
|
+
await runOperation(stop);
|
|
47
|
+
};
|
|
48
|
+
const disableNetwork = async () => {
|
|
49
|
+
await network.disable();
|
|
50
|
+
};
|
|
51
|
+
const beforeUpdate = async () => {
|
|
52
|
+
resumeAfterUpdate = network.readyState === NetworkReadyState.ENABLED;
|
|
53
|
+
await disableNetwork();
|
|
54
|
+
};
|
|
55
|
+
const afterUpdate = async () => {
|
|
56
|
+
const shouldResume = resumeAfterUpdate;
|
|
57
|
+
resumeAfterUpdate = false;
|
|
58
|
+
if (shouldResume && network.readyState === NetworkReadyState.DISABLED) await network.enable();
|
|
59
|
+
};
|
|
60
|
+
hot.on("vite:beforeUpdate", beforeUpdate);
|
|
61
|
+
hot.on("vite:afterUpdate", afterUpdate);
|
|
62
|
+
hot.on("vite:beforeFullReload", disableNetwork);
|
|
63
|
+
const disposeNetwork = async () => {
|
|
64
|
+
retired = true;
|
|
65
|
+
resumeAfterUpdate = false;
|
|
66
|
+
hot.off("vite:beforeUpdate", beforeUpdate);
|
|
67
|
+
hot.off("vite:afterUpdate", afterUpdate);
|
|
68
|
+
hot.off("vite:beforeFullReload", disableNetwork);
|
|
69
|
+
await disableNetwork();
|
|
70
|
+
};
|
|
71
|
+
hotData.disposeNetwork = disposeNetwork;
|
|
72
|
+
hot.dispose(disposeNetwork);
|
|
73
|
+
}
|
|
74
|
+
return network;
|
|
73
75
|
}
|
|
74
76
|
//#endregion
|
|
75
|
-
export {
|
|
77
|
+
export { createNetwork };
|
|
76
78
|
|
|
77
79
|
//# sourceMappingURL=runtime.js.map
|
package/lib/vite/runtime.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.js","names":[],"sources":["../../src/vite/runtime.ts"],"sourcesContent":["/// <reference types=\"vite/client\" />\n\nimport {
|
|
1
|
+
{"version":3,"file":"runtime.js","names":[],"sources":["../../src/vite/runtime.ts"],"sourcesContent":["/// <reference types=\"vite/client\" />\n\nimport { defineNetwork, NetworkReadyState } from 'msw/experimental'\n\nconst hot = import.meta.hot\nconst hotData: { disposeNetwork?: () => Promise<void> } | undefined = hot?.data\n\nexport async function createNetwork(\n options: Parameters<typeof defineNetwork>[0],\n): Promise<ReturnType<typeof defineNetwork>> {\n // SSR imports can re-evaluate the network before the old HMR listener runs.\n while (hotData?.disposeNetwork) {\n const disposePrevious = hotData.disposeNetwork\n await disposePrevious()\n\n if (hotData.disposeNetwork === disposePrevious) {\n break\n }\n }\n\n const network = defineNetwork(options)\n\n if (hot && hotData) {\n let resumeAfterUpdate = false\n let retired = false\n let pendingOperation: Promise<void> | undefined\n const configure = network.configure\n const enable = network.enable\n const disable = network.disable\n\n const runOperation = (action: () => void | Promise<void>) => {\n const result = pendingOperation ? pendingOperation.then(action) : action()\n\n if (result instanceof Promise) {\n const operation = result.finally(() => {\n if (pendingOperation === operation) {\n pendingOperation = undefined\n }\n })\n pendingOperation = operation\n\n return operation\n }\n }\n\n const stop = () => {\n if (network.readyState === NetworkReadyState.ENABLED) {\n return disable()\n }\n }\n\n // An SSR entry may be re-evaluated while this module remains cached.\n network.configure = (options) => {\n void runOperation(() => {\n if (retired) {\n return\n }\n\n const stopped = stop()\n\n if (stopped instanceof Promise) {\n return stopped.then(() => configure(options))\n }\n\n configure(options)\n })\n }\n network.enable = async () => {\n await runOperation(() => {\n if (!retired && network.readyState === NetworkReadyState.DISABLED) {\n return enable()\n }\n })\n }\n network.disable = async () => {\n await runOperation(stop)\n }\n\n const disableNetwork = async () => {\n await network.disable()\n }\n\n const beforeUpdate = async () => {\n resumeAfterUpdate = network.readyState === NetworkReadyState.ENABLED\n await disableNetwork()\n }\n\n const afterUpdate = async () => {\n const shouldResume = resumeAfterUpdate\n resumeAfterUpdate = false\n\n if (shouldResume && network.readyState === NetworkReadyState.DISABLED) {\n await network.enable()\n }\n }\n\n hot.on('vite:beforeUpdate', beforeUpdate)\n hot.on('vite:afterUpdate', afterUpdate)\n hot.on('vite:beforeFullReload', disableNetwork)\n\n const disposeNetwork = async () => {\n retired = true\n resumeAfterUpdate = false\n\n hot.off('vite:beforeUpdate', beforeUpdate)\n hot.off('vite:afterUpdate', afterUpdate)\n hot.off('vite:beforeFullReload', disableNetwork)\n\n await disableNetwork()\n }\n\n hotData.disposeNetwork = disposeNetwork\n hot.dispose(disposeNetwork)\n }\n\n return network\n}\n"],"mappings":";;AAIA,MAAM,MAAM,YAAY;AACxB,MAAM,UAAgE,KAAK;AAE3E,eAAsB,cACpB,SAC2C;CAE3C,OAAO,SAAS,gBAAgB;EAC9B,MAAM,kBAAkB,QAAQ;EAChC,MAAM,gBAAgB;EAEtB,IAAI,QAAQ,mBAAmB,iBAC7B;CAEJ;CAEA,MAAM,UAAU,cAAc,OAAO;CAErC,IAAI,OAAO,SAAS;EAClB,IAAI,oBAAoB;EACxB,IAAI,UAAU;EACd,IAAI;EACJ,MAAM,YAAY,QAAQ;EAC1B,MAAM,SAAS,QAAQ;EACvB,MAAM,UAAU,QAAQ;EAExB,MAAM,gBAAgB,WAAuC;GAC3D,MAAM,SAAS,mBAAmB,iBAAiB,KAAK,MAAM,IAAI,OAAO;GAEzE,IAAI,kBAAkB,SAAS;IAC7B,MAAM,YAAY,OAAO,cAAc;KACrC,IAAI,qBAAqB,WACvB,mBAAmB,KAAA;IAEvB,CAAC;IACD,mBAAmB;IAEnB,OAAO;GACT;EACF;EAEA,MAAM,aAAa;GACjB,IAAI,QAAQ,eAAe,kBAAkB,SAC3C,OAAO,QAAQ;EAEnB;EAGA,QAAQ,aAAa,YAAY;GAC/B,mBAAwB;IACtB,IAAI,SACF;IAGF,MAAM,UAAU,KAAK;IAErB,IAAI,mBAAmB,SACrB,OAAO,QAAQ,WAAW,UAAU,OAAO,CAAC;IAG9C,UAAU,OAAO;GACnB,CAAC;EACH;EACA,QAAQ,SAAS,YAAY;GAC3B,MAAM,mBAAmB;IACvB,IAAI,CAAC,WAAW,QAAQ,eAAe,kBAAkB,UACvD,OAAO,OAAO;GAElB,CAAC;EACH;EACA,QAAQ,UAAU,YAAY;GAC5B,MAAM,aAAa,IAAI;EACzB;EAEA,MAAM,iBAAiB,YAAY;GACjC,MAAM,QAAQ,QAAQ;EACxB;EAEA,MAAM,eAAe,YAAY;GAC/B,oBAAoB,QAAQ,eAAe,kBAAkB;GAC7D,MAAM,eAAe;EACvB;EAEA,MAAM,cAAc,YAAY;GAC9B,MAAM,eAAe;GACrB,oBAAoB;GAEpB,IAAI,gBAAgB,QAAQ,eAAe,kBAAkB,UAC3D,MAAM,QAAQ,OAAO;EAEzB;EAEA,IAAI,GAAG,qBAAqB,YAAY;EACxC,IAAI,GAAG,oBAAoB,WAAW;EACtC,IAAI,GAAG,yBAAyB,cAAc;EAE9C,MAAM,iBAAiB,YAAY;GACjC,UAAU;GACV,oBAAoB;GAEpB,IAAI,IAAI,qBAAqB,YAAY;GACzC,IAAI,IAAI,oBAAoB,WAAW;GACvC,IAAI,IAAI,yBAAyB,cAAc;GAE/C,MAAM,eAAe;EACvB;EAEA,QAAQ,iBAAiB;EACzB,IAAI,QAAQ,cAAc;CAC5B;CAEA,OAAO;AACT"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@depup/msw",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.3-depup.0",
|
|
4
4
|
"description": "The industry standard for API mocking in JavaScript. (with updated dependencies)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/core/index.js",
|
|
@@ -94,7 +94,6 @@
|
|
|
94
94
|
"funding": "https://github.com/sponsors/mswjs",
|
|
95
95
|
"files": [
|
|
96
96
|
"config/constants.js",
|
|
97
|
-
"config/scripts/postinstall.js",
|
|
98
97
|
"cli",
|
|
99
98
|
"lib",
|
|
100
99
|
"src",
|
|
@@ -123,9 +122,9 @@
|
|
|
123
122
|
],
|
|
124
123
|
"sideEffects": false,
|
|
125
124
|
"dependencies": {
|
|
126
|
-
"@inquirer/confirm": "^6.3.
|
|
125
|
+
"@inquirer/confirm": "^6.3.3",
|
|
127
126
|
"@msw/url": "^0.1.2",
|
|
128
|
-
"@mswjs/interceptors": "^0.45.
|
|
127
|
+
"@mswjs/interceptors": "^0.45.7",
|
|
129
128
|
"cookie": "^2.0.1",
|
|
130
129
|
"headers-polyfill": "^5.0.1",
|
|
131
130
|
"is-node-process": "^1.2.0",
|
|
@@ -167,7 +166,7 @@
|
|
|
167
166
|
"json-bigint": "^1.0.0",
|
|
168
167
|
"knip": "^6.34.0",
|
|
169
168
|
"lint-staged": "^17.1.1",
|
|
170
|
-
"msw": "^3.0.
|
|
169
|
+
"msw": "^3.0.3",
|
|
171
170
|
"oxlint": "^1.75.0",
|
|
172
171
|
"page-with": "^0.6.1",
|
|
173
172
|
"prettier": "^3.9.6",
|
|
@@ -229,17 +228,21 @@
|
|
|
229
228
|
"changes": {
|
|
230
229
|
"@inquirer/confirm": {
|
|
231
230
|
"from": "^6.0.11",
|
|
232
|
-
"to": "^6.3.
|
|
231
|
+
"to": "^6.3.3"
|
|
232
|
+
},
|
|
233
|
+
"@mswjs/interceptors": {
|
|
234
|
+
"from": "^0.45.6",
|
|
235
|
+
"to": "^0.45.7"
|
|
233
236
|
},
|
|
234
237
|
"type-fest": {
|
|
235
238
|
"from": "^5.5.0",
|
|
236
239
|
"to": "^5.10.0"
|
|
237
240
|
}
|
|
238
241
|
},
|
|
239
|
-
"depsUpdated":
|
|
242
|
+
"depsUpdated": 3,
|
|
240
243
|
"originalPackage": "msw",
|
|
241
|
-
"originalVersion": "3.0.
|
|
242
|
-
"processedAt": "2026-
|
|
244
|
+
"originalVersion": "3.0.3",
|
|
245
|
+
"processedAt": "2026-10-10T04:42:39.550Z",
|
|
243
246
|
"smokeTest": "passed"
|
|
244
247
|
}
|
|
245
248
|
}
|
|
@@ -17,7 +17,7 @@ export function createDefaultNetworkOptions(
|
|
|
17
17
|
sources: [
|
|
18
18
|
supportsServiceWorker()
|
|
19
19
|
? new ServiceWorkerSource({ serviceWorker: { url: workerUrl } })
|
|
20
|
-
: new FallbackHttpSource(
|
|
20
|
+
: new FallbackHttpSource(),
|
|
21
21
|
new InterceptorSource({
|
|
22
22
|
interceptors: [
|
|
23
23
|
new WebSocketInterceptor() as InterceptorSourceOptions['interceptors'][number],
|
|
@@ -56,11 +56,8 @@ export function setupWorker(...handlers: Array<AnyHandler>): SetupWorker {
|
|
|
56
56
|
options: options?.serviceWorker?.options,
|
|
57
57
|
},
|
|
58
58
|
findWorker: options?.findWorker,
|
|
59
|
-
quiet: options?.quiet,
|
|
60
|
-
})
|
|
61
|
-
: new FallbackHttpSource({
|
|
62
|
-
quiet: options?.quiet,
|
|
63
59
|
})
|
|
60
|
+
: new FallbackHttpSource()
|
|
64
61
|
|
|
65
62
|
network.configure({
|
|
66
63
|
sources: [
|
|
@@ -1,23 +1,26 @@
|
|
|
1
1
|
import { FetchInterceptor } from '@mswjs/interceptors/fetch'
|
|
2
2
|
import { XMLHttpRequestInterceptor } from '@mswjs/interceptors/XMLHttpRequest'
|
|
3
3
|
import { InterceptorSource } from '#core/experimental/sources/interceptor-source'
|
|
4
|
+
import type { NetworkFrameResolutionContext } from '#core/experimental/frames/network-frame'
|
|
4
5
|
import { devUtils } from '#core/utils/internal/dev-utils'
|
|
5
6
|
|
|
6
|
-
interface FallbackHttpSourceOptions {
|
|
7
|
-
quiet?: boolean
|
|
8
|
-
}
|
|
9
|
-
|
|
10
7
|
export class FallbackHttpSource extends InterceptorSource {
|
|
11
|
-
|
|
8
|
+
/**
|
|
9
|
+
* The resolved context of the network this source was last enabled with.
|
|
10
|
+
*/
|
|
11
|
+
#context?: NetworkFrameResolutionContext
|
|
12
|
+
|
|
13
|
+
constructor() {
|
|
12
14
|
super({
|
|
13
15
|
interceptors: [new XMLHttpRequestInterceptor(), new FetchInterceptor()],
|
|
14
16
|
})
|
|
15
17
|
}
|
|
16
18
|
|
|
17
|
-
public enable(): void {
|
|
19
|
+
public enable(context?: NetworkFrameResolutionContext): void {
|
|
20
|
+
this.#context = context
|
|
18
21
|
super.enable()
|
|
19
22
|
|
|
20
|
-
if (!this
|
|
23
|
+
if (!this.#context?.quiet) {
|
|
21
24
|
this.#printStartMessage()
|
|
22
25
|
}
|
|
23
26
|
}
|
|
@@ -25,7 +28,7 @@ export class FallbackHttpSource extends InterceptorSource {
|
|
|
25
28
|
public disable(): void {
|
|
26
29
|
super.disable()
|
|
27
30
|
|
|
28
|
-
if (!this
|
|
31
|
+
if (!this.#context?.quiet) {
|
|
29
32
|
this.#printStopMessage()
|
|
30
33
|
}
|
|
31
34
|
}
|
|
@@ -2,6 +2,7 @@ import { invariant } from 'outvariant'
|
|
|
2
2
|
import type { Emitter } from 'rettime'
|
|
3
3
|
import { FetchResponse } from '@mswjs/interceptors'
|
|
4
4
|
import { NetworkSource } from '#core/experimental/sources/network-source'
|
|
5
|
+
import type { NetworkFrameResolutionContext } from '#core/experimental/frames/network-frame'
|
|
5
6
|
import { RequestHandler } from '#core/handlers/request-handler'
|
|
6
7
|
import {
|
|
7
8
|
HttpNetworkFrame,
|
|
@@ -23,7 +24,6 @@ import { validateWorkerScope } from '../utils/validate-worker-scope'
|
|
|
23
24
|
import { shouldInvalidateWorker } from '../utils/should-invalidate-worker'
|
|
24
25
|
|
|
25
26
|
export interface ServiceWorkerSourceOptions {
|
|
26
|
-
quiet?: boolean
|
|
27
27
|
serviceWorker: {
|
|
28
28
|
url: string
|
|
29
29
|
options?: RegistrationOptions
|
|
@@ -75,6 +75,10 @@ export class ServiceWorkerSource extends NetworkSource<ServiceWorkerHttpNetworkF
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
#options: ServiceWorkerSourceOptions
|
|
78
|
+
/**
|
|
79
|
+
* The resolved context of the network this source was last enabled with.
|
|
80
|
+
*/
|
|
81
|
+
#context?: NetworkFrameResolutionContext
|
|
78
82
|
/**
|
|
79
83
|
* @note We cannot use `WeakMap` here as request/response
|
|
80
84
|
* identity cannot be preserved through the client-worker channel.
|
|
@@ -109,7 +113,10 @@ export class ServiceWorkerSource extends NetworkSource<ServiceWorkerHttpNetworkF
|
|
|
109
113
|
})
|
|
110
114
|
}
|
|
111
115
|
|
|
112
|
-
public async enable(
|
|
116
|
+
public async enable(
|
|
117
|
+
context?: NetworkFrameResolutionContext,
|
|
118
|
+
): Promise<ServiceWorkerRegistration> {
|
|
119
|
+
this.#context = context
|
|
113
120
|
this.#channel.removeAllListeners()
|
|
114
121
|
this.#frames.clear()
|
|
115
122
|
|
|
@@ -147,7 +154,7 @@ export class ServiceWorkerSource extends NetworkSource<ServiceWorkerHttpNetworkF
|
|
|
147
154
|
})
|
|
148
155
|
await clientConfirmationPromise.promise
|
|
149
156
|
|
|
150
|
-
if (!this.#
|
|
157
|
+
if (!this.#context?.quiet) {
|
|
151
158
|
this.#printStartMessage()
|
|
152
159
|
}
|
|
153
160
|
|
|
@@ -178,7 +185,7 @@ export class ServiceWorkerSource extends NetworkSource<ServiceWorkerHttpNetworkF
|
|
|
178
185
|
* `#handleRequest`. `#startWorker` swaps in a fresh deferred on re-enable.
|
|
179
186
|
*/
|
|
180
187
|
|
|
181
|
-
if (!this.#
|
|
188
|
+
if (!this.#context?.quiet) {
|
|
182
189
|
this.#printStopMessage()
|
|
183
190
|
}
|
|
184
191
|
}
|
|
@@ -294,7 +301,7 @@ Please consider using a custom "serviceWorker.url" option to point to the actual
|
|
|
294
301
|
this.#channel.postMessage('KEEPALIVE_REQUEST')
|
|
295
302
|
}, 5000)
|
|
296
303
|
|
|
297
|
-
if (!this.#
|
|
304
|
+
if (!this.#context?.quiet) {
|
|
298
305
|
validateWorkerScope(registration)
|
|
299
306
|
}
|
|
300
307
|
|
|
@@ -104,19 +104,3 @@ test('returns false when findWorker is the same reference', () => {
|
|
|
104
104
|
),
|
|
105
105
|
).toBe(false)
|
|
106
106
|
})
|
|
107
|
-
|
|
108
|
-
test('returns false regardless of the "quiet" option', () => {
|
|
109
|
-
expect(
|
|
110
|
-
shouldInvalidateWorker(
|
|
111
|
-
createOptions({ quiet: true }),
|
|
112
|
-
createOptions({ quiet: true }),
|
|
113
|
-
),
|
|
114
|
-
).toBe(false)
|
|
115
|
-
|
|
116
|
-
expect(
|
|
117
|
-
shouldInvalidateWorker(
|
|
118
|
-
createOptions({ quiet: false }),
|
|
119
|
-
createOptions({ quiet: true }),
|
|
120
|
-
),
|
|
121
|
-
).toBe(false)
|
|
122
|
-
})
|
|
@@ -308,6 +308,67 @@ describe(InMemoryHandlersController.prototype.reset, () => {
|
|
|
308
308
|
expect(controller.getHandlersByKind('websocket')).toEqual([wsOne, wsTwo])
|
|
309
309
|
expect(controller.getHandlersByKind('request')).toEqual([upgradeHandler])
|
|
310
310
|
})
|
|
311
|
+
|
|
312
|
+
test('resets the kept handlers and disposes of the removed ones', () => {
|
|
313
|
+
const initialHandler = http.get('/initial', () => {})
|
|
314
|
+
initialHandler.reset = vi.fn()
|
|
315
|
+
initialHandler.dispose = vi.fn()
|
|
316
|
+
const runtimeHandler = http.get('/runtime', () => {})
|
|
317
|
+
runtimeHandler.reset = vi.fn()
|
|
318
|
+
runtimeHandler.dispose = vi.fn()
|
|
319
|
+
|
|
320
|
+
const controller = new InMemoryHandlersController([initialHandler])
|
|
321
|
+
controller.use([runtimeHandler])
|
|
322
|
+
controller.reset([])
|
|
323
|
+
|
|
324
|
+
expect.soft(initialHandler.reset).toHaveBeenCalledOnce()
|
|
325
|
+
expect.soft(initialHandler.dispose).not.toHaveBeenCalled()
|
|
326
|
+
expect.soft(runtimeHandler.reset).not.toHaveBeenCalled()
|
|
327
|
+
expect(runtimeHandler.dispose).toHaveBeenCalledOnce()
|
|
328
|
+
})
|
|
329
|
+
|
|
330
|
+
test('reports a rejected disposal of a removed handler', async () => {
|
|
331
|
+
vi.spyOn(console, 'error').mockImplementation(() => {})
|
|
332
|
+
onTestFinished(() => vi.restoreAllMocks())
|
|
333
|
+
|
|
334
|
+
const runtimeHandler = http.get('/runtime', () => {})
|
|
335
|
+
runtimeHandler.dispose = () =>
|
|
336
|
+
Promise.reject(new Error('Handler disposal error'))
|
|
337
|
+
|
|
338
|
+
const controller = new InMemoryHandlersController([])
|
|
339
|
+
controller.use([runtimeHandler])
|
|
340
|
+
controller.reset([])
|
|
341
|
+
|
|
342
|
+
await expect
|
|
343
|
+
.poll(() => console.error)
|
|
344
|
+
.toHaveBeenCalledWith(
|
|
345
|
+
`[MSW] Failed to dispose of "request" handler removed during reset. Please see the original error below.\nError: Handler disposal error`,
|
|
346
|
+
)
|
|
347
|
+
})
|
|
348
|
+
|
|
349
|
+
test('removes the remaining handlers when a disposal throws', () => {
|
|
350
|
+
vi.spyOn(console, 'error').mockImplementation(() => {})
|
|
351
|
+
onTestFinished(() => vi.restoreAllMocks())
|
|
352
|
+
|
|
353
|
+
const throwingHandler = http.get('/throwing', () => {})
|
|
354
|
+
throwingHandler.dispose = () => {
|
|
355
|
+
throw new Error('Handler disposal error')
|
|
356
|
+
}
|
|
357
|
+
const runtimeHandler = http.get('/runtime', () => {})
|
|
358
|
+
runtimeHandler.dispose = vi.fn()
|
|
359
|
+
|
|
360
|
+
const controller = new InMemoryHandlersController([])
|
|
361
|
+
controller.use([throwingHandler, runtimeHandler])
|
|
362
|
+
controller.reset([])
|
|
363
|
+
|
|
364
|
+
expect
|
|
365
|
+
.soft(console.error)
|
|
366
|
+
.toHaveBeenCalledWith(
|
|
367
|
+
`[MSW] Failed to dispose of "request" handler removed during reset. Please see the original error below.\nError: Handler disposal error`,
|
|
368
|
+
)
|
|
369
|
+
expect.soft(runtimeHandler.dispose).toHaveBeenCalledOnce()
|
|
370
|
+
expect(controller.currentHandlers()).toEqual([])
|
|
371
|
+
})
|
|
311
372
|
})
|
|
312
373
|
|
|
313
374
|
describe(InMemoryHandlersController.prototype.listHandlers, () => {
|
|
@@ -168,11 +168,38 @@ export abstract class HandlersController {
|
|
|
168
168
|
),
|
|
169
169
|
)
|
|
170
170
|
|
|
171
|
-
|
|
171
|
+
const { initialHandlers } = this.getState()
|
|
172
|
+
const nextInitialHandlers =
|
|
173
|
+
nextHandlers.length > 0
|
|
174
|
+
? groupHandlersByKind(nextHandlers)
|
|
175
|
+
: initialHandlers
|
|
176
|
+
const currentHandlers = new Set(this.currentHandlers())
|
|
177
|
+
const nextHandlersSet = new Set(
|
|
178
|
+
Object.values(nextInitialHandlers).flat().filter(Boolean),
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
for (const handler of currentHandlers.intersection(nextHandlersSet)) {
|
|
172
182
|
handler.reset()
|
|
173
183
|
}
|
|
174
184
|
|
|
175
|
-
|
|
185
|
+
// The handlers that leave the network with this reset release
|
|
186
|
+
// whatever they hold (e.g. live connection bindings).
|
|
187
|
+
// Resetting is synchronous, so their disposal is not awaited.
|
|
188
|
+
for (const handler of currentHandlers.difference(nextHandlersSet)) {
|
|
189
|
+
try {
|
|
190
|
+
const disposal = handler.dispose()
|
|
191
|
+
|
|
192
|
+
if (disposal instanceof Promise) {
|
|
193
|
+
disposal.catch((error) => {
|
|
194
|
+
this.#printDisposalError(handler, error)
|
|
195
|
+
})
|
|
196
|
+
}
|
|
197
|
+
} catch (error) {
|
|
198
|
+
// A failing disposal must not prevent the remaining handlers
|
|
199
|
+
// from being disposed of, nor the removed handlers from being cleared.
|
|
200
|
+
this.#printDisposalError(handler, error)
|
|
201
|
+
}
|
|
202
|
+
}
|
|
176
203
|
|
|
177
204
|
if (nextHandlers.length === 0) {
|
|
178
205
|
this.setState({
|
|
@@ -182,11 +209,9 @@ export abstract class HandlersController {
|
|
|
182
209
|
return
|
|
183
210
|
}
|
|
184
211
|
|
|
185
|
-
const normalizedNextHandlers = groupHandlersByKind(nextHandlers)
|
|
186
|
-
|
|
187
212
|
this.setState({
|
|
188
|
-
initialHandlers:
|
|
189
|
-
handlers: { ...
|
|
213
|
+
initialHandlers: nextInitialHandlers,
|
|
214
|
+
handlers: { ...nextInitialHandlers },
|
|
190
215
|
})
|
|
191
216
|
}
|
|
192
217
|
|
|
@@ -217,6 +242,14 @@ export abstract class HandlersController {
|
|
|
217
242
|
#validateHandlers(handlers: Array<AnyHandler>): boolean {
|
|
218
243
|
return handlers.every((handler) => !Array.isArray(handler))
|
|
219
244
|
}
|
|
245
|
+
|
|
246
|
+
#printDisposalError(handler: AnyHandler, error: unknown): void {
|
|
247
|
+
devUtils.error(
|
|
248
|
+
'Failed to dispose of "%s" handler removed during reset. Please see the original error below.\n%s',
|
|
249
|
+
handler.kind,
|
|
250
|
+
error,
|
|
251
|
+
)
|
|
252
|
+
}
|
|
220
253
|
}
|
|
221
254
|
|
|
222
255
|
export class InMemoryHandlersController extends HandlersController {
|
|
@@ -2,6 +2,7 @@ import { Emitter, TypedEvent, type TypedListenerOptions } from 'rettime'
|
|
|
2
2
|
import type {
|
|
3
3
|
AnyNetworkFrame,
|
|
4
4
|
ExtractFrameEvents,
|
|
5
|
+
NetworkFrameResolutionContext,
|
|
5
6
|
} from '../frames/network-frame'
|
|
6
7
|
|
|
7
8
|
class NetworkFrameEvent<
|
|
@@ -33,7 +34,13 @@ export abstract class NetworkSource<
|
|
|
33
34
|
this.emitter = new Emitter()
|
|
34
35
|
}
|
|
35
36
|
|
|
36
|
-
|
|
37
|
+
/**
|
|
38
|
+
* Enable this network source.
|
|
39
|
+
* @param context The resolved context of the network this source belongs to.
|
|
40
|
+
*/
|
|
41
|
+
public abstract enable(
|
|
42
|
+
context?: NetworkFrameResolutionContext,
|
|
43
|
+
): unknown | Promise<unknown>
|
|
37
44
|
|
|
38
45
|
public async queue(frame: Frame): Promise<void> {
|
|
39
46
|
await this.emitter.emitAsPromise(
|