@nifrajs/web 3.5.0 → 4.0.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.
- package/dist/backend-only.d.ts +15 -0
- package/dist/backend-only.d.ts.map +1 -0
- package/dist/backend-only.js +16 -0
- package/dist/backend-only.js.map +1 -0
- package/dist/boundary.d.ts +5 -0
- package/dist/boundary.d.ts.map +1 -1
- package/dist/boundary.js +11 -2
- package/dist/boundary.js.map +1 -1
- package/dist/build-plan.d.ts +18 -6
- package/dist/build-plan.d.ts.map +1 -1
- package/dist/build-plan.js +82 -34
- package/dist/build-plan.js.map +1 -1
- package/dist/build-vite.d.ts +4 -0
- package/dist/build-vite.d.ts.map +1 -1
- package/dist/build-vite.js +68 -13
- package/dist/build-vite.js.map +1 -1
- package/dist/build.d.ts +57 -23
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +356 -85
- package/dist/build.js.map +1 -1
- package/dist/bun-dev-entry.d.ts +1 -1
- package/dist/bun-dev-entry.js +1 -1
- package/dist/cdn.d.ts +74 -0
- package/dist/cdn.d.ts.map +1 -0
- package/dist/cdn.js +132 -0
- package/dist/cdn.js.map +1 -0
- package/dist/client.d.ts +3 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +136 -35
- package/dist/client.js.map +1 -1
- package/dist/conformance.d.ts +4 -3
- package/dist/conformance.d.ts.map +1 -1
- package/dist/conformance.js +12 -3
- package/dist/conformance.js.map +1 -1
- package/dist/csp.d.ts +93 -0
- package/dist/csp.d.ts.map +1 -0
- package/dist/csp.js +122 -0
- package/dist/csp.js.map +1 -0
- package/dist/dev-client.d.ts +76 -0
- package/dist/dev-client.d.ts.map +1 -0
- package/dist/dev-client.js +280 -0
- package/dist/dev-client.js.map +1 -0
- package/dist/dev-diagnostics.d.ts +26 -2
- package/dist/dev-diagnostics.d.ts.map +1 -1
- package/dist/dev-diagnostics.js +38 -7
- package/dist/dev-diagnostics.js.map +1 -1
- package/dist/dev-error.d.ts +4 -13
- package/dist/dev-error.d.ts.map +1 -1
- package/dist/dev-error.js +46 -4
- package/dist/dev-error.js.map +1 -1
- package/dist/dev-feed.d.ts +298 -0
- package/dist/dev-feed.d.ts.map +1 -0
- package/dist/dev-feed.js +797 -0
- package/dist/dev-feed.js.map +1 -0
- package/dist/dev-indicator.d.ts +38 -0
- package/dist/dev-indicator.d.ts.map +1 -0
- package/dist/dev-indicator.js +93 -0
- package/dist/dev-indicator.js.map +1 -0
- package/dist/dev-session.d.ts +77 -0
- package/dist/dev-session.d.ts.map +1 -0
- package/dist/dev-session.js +580 -0
- package/dist/dev-session.js.map +1 -0
- package/dist/dev-sourcemap.d.ts +27 -0
- package/dist/dev-sourcemap.d.ts.map +1 -0
- package/dist/dev-sourcemap.js +235 -0
- package/dist/dev-sourcemap.js.map +1 -0
- package/dist/dev-ssr-graph.d.ts.map +1 -1
- package/dist/dev-ssr-graph.js +13 -5
- package/dist/dev-ssr-graph.js.map +1 -1
- package/dist/dev.d.ts +15 -2
- package/dist/dev.d.ts.map +1 -1
- package/dist/dev.js +69 -44
- package/dist/dev.js.map +1 -1
- package/dist/diagnostic-catalog.d.ts +35 -0
- package/dist/diagnostic-catalog.d.ts.map +1 -0
- package/dist/diagnostic-catalog.js +203 -0
- package/dist/diagnostic-catalog.js.map +1 -0
- package/dist/diagnostic-prompt.d.ts +49 -0
- package/dist/diagnostic-prompt.d.ts.map +1 -0
- package/dist/diagnostic-prompt.js +303 -0
- package/dist/diagnostic-prompt.js.map +1 -0
- package/dist/diagnostic.d.ts +17 -23
- package/dist/diagnostic.d.ts.map +1 -1
- package/dist/diagnostic.js +31 -39
- package/dist/diagnostic.js.map +1 -1
- package/dist/draft.d.ts.map +1 -1
- package/dist/draft.js +4 -1
- package/dist/draft.js.map +1 -1
- package/dist/fn.d.ts +5 -0
- package/dist/fn.d.ts.map +1 -1
- package/dist/fn.js +13 -3
- package/dist/fn.js.map +1 -1
- package/dist/fs.d.ts.map +1 -1
- package/dist/fs.js +4 -2
- package/dist/fs.js.map +1 -1
- package/dist/index.d.ts +13 -15
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -12
- package/dist/index.js.map +1 -1
- package/dist/internal/cdn/cloudflare.d.ts +48 -0
- package/dist/internal/cdn/cloudflare.d.ts.map +1 -0
- package/dist/internal/cdn/cloudflare.js +94 -0
- package/dist/internal/cdn/cloudflare.js.map +1 -0
- package/dist/internal/cdn/core.d.ts +91 -0
- package/dist/internal/cdn/core.d.ts.map +1 -0
- package/dist/internal/cdn/core.js +220 -0
- package/dist/internal/cdn/core.js.map +1 -0
- package/dist/internal/cdn/fastly.d.ts +17 -0
- package/dist/internal/cdn/fastly.d.ts.map +1 -0
- package/dist/internal/cdn/fastly.js +43 -0
- package/dist/internal/cdn/fastly.js.map +1 -0
- package/dist/internal/cdn/vercel.d.ts +31 -0
- package/dist/internal/cdn/vercel.d.ts.map +1 -0
- package/dist/internal/cdn/vercel.js +56 -0
- package/dist/internal/cdn/vercel.js.map +1 -0
- package/dist/internal/code-unit-order.d.ts +4 -0
- package/dist/internal/code-unit-order.d.ts.map +1 -0
- package/dist/internal/code-unit-order.js +6 -0
- package/dist/internal/code-unit-order.js.map +1 -0
- package/dist/internal/codegen.d.ts.map +1 -1
- package/dist/internal/codegen.js +141 -25
- package/dist/internal/codegen.js.map +1 -1
- package/dist/internal/dev-csp.d.ts +24 -0
- package/dist/internal/dev-csp.d.ts.map +1 -0
- package/dist/internal/dev-csp.js +160 -0
- package/dist/internal/dev-csp.js.map +1 -0
- package/dist/internal/dev-reserved.d.ts +25 -0
- package/dist/internal/dev-reserved.d.ts.map +1 -0
- package/dist/internal/dev-reserved.js +39 -0
- package/dist/internal/dev-reserved.js.map +1 -0
- package/dist/internal/html-spans.d.ts +10 -0
- package/dist/internal/html-spans.d.ts.map +1 -0
- package/dist/internal/html-spans.js +46 -0
- package/dist/internal/html-spans.js.map +1 -0
- package/dist/internal/loading-runtime.d.ts +44 -0
- package/dist/internal/loading-runtime.d.ts.map +1 -0
- package/dist/internal/loading-runtime.js +206 -0
- package/dist/internal/loading-runtime.js.map +1 -0
- package/dist/internal/matches-runtime.d.ts +8 -0
- package/dist/internal/matches-runtime.d.ts.map +1 -0
- package/dist/internal/matches-runtime.js +61 -0
- package/dist/internal/matches-runtime.js.map +1 -0
- package/dist/internal/mount-shadow.d.ts +36 -0
- package/dist/internal/mount-shadow.d.ts.map +1 -0
- package/dist/internal/mount-shadow.js +65 -0
- package/dist/internal/mount-shadow.js.map +1 -0
- package/dist/internal/node-builtins.d.ts +3 -0
- package/dist/internal/node-builtins.d.ts.map +1 -0
- package/dist/internal/node-builtins.js +79 -0
- package/dist/internal/node-builtins.js.map +1 -0
- package/dist/internal/output-guard.d.ts +65 -0
- package/dist/internal/output-guard.d.ts.map +1 -0
- package/dist/internal/output-guard.js +630 -0
- package/dist/internal/output-guard.js.map +1 -0
- package/dist/internal/page-execution.d.ts +20 -8
- package/dist/internal/page-execution.d.ts.map +1 -1
- package/dist/internal/page-execution.js +571 -105
- package/dist/internal/page-execution.js.map +1 -1
- package/dist/internal/parity.d.ts +21 -0
- package/dist/internal/parity.d.ts.map +1 -1
- package/dist/internal/parity.js +104 -22
- package/dist/internal/parity.js.map +1 -1
- package/dist/internal/private-env.d.ts +12 -0
- package/dist/internal/private-env.d.ts.map +1 -0
- package/dist/internal/private-env.js +335 -0
- package/dist/internal/private-env.js.map +1 -0
- package/dist/internal/public-url.d.ts +3 -0
- package/dist/internal/public-url.d.ts.map +1 -0
- package/dist/internal/public-url.js +18 -0
- package/dist/internal/public-url.js.map +1 -0
- package/dist/internal/render-document.d.ts +25 -19
- package/dist/internal/render-document.d.ts.map +1 -1
- package/dist/internal/render-document.js +77 -61
- package/dist/internal/render-document.js.map +1 -1
- package/dist/internal/response-controls.d.ts +75 -0
- package/dist/internal/response-controls.d.ts.map +1 -0
- package/dist/internal/response-controls.js +256 -0
- package/dist/internal/response-controls.js.map +1 -0
- package/dist/internal/runtime-contract.d.ts +11 -16
- package/dist/internal/runtime-contract.d.ts.map +1 -1
- package/dist/internal/runtime-contract.js.map +1 -1
- package/dist/internal/secret-scan.d.ts +104 -0
- package/dist/internal/secret-scan.d.ts.map +1 -0
- package/dist/internal/secret-scan.js +503 -0
- package/dist/internal/secret-scan.js.map +1 -0
- package/dist/internal/server-boundary.d.ts +6 -29
- package/dist/internal/server-boundary.d.ts.map +1 -1
- package/dist/internal/server-boundary.js +6 -66
- package/dist/internal/server-boundary.js.map +1 -1
- package/dist/internal/source-map.d.ts +47 -0
- package/dist/internal/source-map.d.ts.map +1 -0
- package/dist/internal/source-map.js +225 -0
- package/dist/internal/source-map.js.map +1 -0
- package/dist/internal/target-compat.d.ts +27 -0
- package/dist/internal/target-compat.d.ts.map +1 -0
- package/dist/internal/target-compat.js +77 -0
- package/dist/internal/target-compat.js.map +1 -0
- package/dist/internal/timing-safe-equal.d.ts +6 -0
- package/dist/internal/timing-safe-equal.d.ts.map +1 -1
- package/dist/internal/timing-safe-equal.js +10 -0
- package/dist/internal/timing-safe-equal.js.map +1 -1
- package/dist/internal/vitals-runtime.d.ts +18 -0
- package/dist/internal/vitals-runtime.d.ts.map +1 -0
- package/dist/internal/vitals-runtime.js +38 -0
- package/dist/internal/vitals-runtime.js.map +1 -0
- package/dist/internal/web-app.d.ts +38 -9
- package/dist/internal/web-app.d.ts.map +1 -1
- package/dist/internal/web-app.js +199 -59
- package/dist/internal/web-app.js.map +1 -1
- package/dist/internal/zone-graph.d.ts +89 -0
- package/dist/internal/zone-graph.d.ts.map +1 -0
- package/dist/internal/zone-graph.js +492 -0
- package/dist/internal/zone-graph.js.map +1 -0
- package/dist/isr.d.ts +83 -6
- package/dist/isr.d.ts.map +1 -1
- package/dist/isr.js +263 -36
- package/dist/isr.js.map +1 -1
- package/dist/llms-txt.d.ts.map +1 -1
- package/dist/llms-txt.js +31 -6
- package/dist/llms-txt.js.map +1 -1
- package/dist/manifest.d.ts +220 -13
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +394 -9
- package/dist/manifest.js.map +1 -1
- package/dist/module-graph.d.ts +26 -5
- package/dist/module-graph.d.ts.map +1 -1
- package/dist/module-graph.js +17 -7
- package/dist/module-graph.js.map +1 -1
- package/dist/navigation.d.ts +17 -3
- package/dist/navigation.d.ts.map +1 -1
- package/dist/navigation.js +11 -5
- package/dist/navigation.js.map +1 -1
- package/dist/nonce.d.ts +47 -0
- package/dist/nonce.d.ts.map +1 -0
- package/dist/nonce.js +63 -0
- package/dist/nonce.js.map +1 -0
- package/dist/plugins/css-modules.d.ts.map +1 -1
- package/dist/plugins/css-modules.js +4 -3
- package/dist/plugins/css-modules.js.map +1 -1
- package/dist/plugins/kit.d.ts +9 -0
- package/dist/plugins/kit.d.ts.map +1 -1
- package/dist/plugins/kit.js +18 -0
- package/dist/plugins/kit.js.map +1 -1
- package/dist/plugins/svg.d.ts +22 -3
- package/dist/plugins/svg.d.ts.map +1 -1
- package/dist/plugins/svg.js +112 -1
- package/dist/plugins/svg.js.map +1 -1
- package/dist/plugins/vite-leak-guard.d.ts +107 -3
- package/dist/plugins/vite-leak-guard.d.ts.map +1 -1
- package/dist/plugins/vite-leak-guard.js +378 -17
- package/dist/plugins/vite-leak-guard.js.map +1 -1
- package/dist/plugins/vite-zone-guard.d.ts +61 -0
- package/dist/plugins/vite-zone-guard.d.ts.map +1 -0
- package/dist/plugins/vite-zone-guard.js +208 -0
- package/dist/plugins/vite-zone-guard.js.map +1 -0
- package/dist/plugins/zone-guard.d.ts +27 -0
- package/dist/plugins/zone-guard.d.ts.map +1 -0
- package/dist/plugins/zone-guard.js +80 -0
- package/dist/plugins/zone-guard.js.map +1 -0
- package/dist/prerender.d.ts +10 -0
- package/dist/prerender.d.ts.map +1 -1
- package/dist/prerender.js +35 -3
- package/dist/prerender.js.map +1 -1
- package/dist/public-dir.d.ts +9 -0
- package/dist/public-dir.d.ts.map +1 -1
- package/dist/public-dir.js +67 -9
- package/dist/public-dir.js.map +1 -1
- package/dist/pwa-manifest.d.ts +68 -0
- package/dist/pwa-manifest.d.ts.map +1 -0
- package/dist/pwa-manifest.js +178 -0
- package/dist/pwa-manifest.js.map +1 -0
- package/dist/query.js +4 -4
- package/dist/query.js.map +1 -1
- package/dist/render-seam.d.ts +42 -2
- package/dist/render-seam.d.ts.map +1 -1
- package/dist/render-seam.js +6 -0
- package/dist/render-seam.js.map +1 -1
- package/dist/route-manifest.d.ts +3 -0
- package/dist/route-manifest.d.ts.map +1 -1
- package/dist/route-manifest.js +26 -3
- package/dist/route-manifest.js.map +1 -1
- package/dist/route-types.d.ts +24 -0
- package/dist/route-types.d.ts.map +1 -0
- package/dist/route-types.js +195 -0
- package/dist/route-types.js.map +1 -0
- package/dist/router.d.ts +28 -6
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +129 -40
- package/dist/router.js.map +1 -1
- package/dist/vitals.d.ts +33 -0
- package/dist/vitals.d.ts.map +1 -0
- package/dist/vitals.js +16 -0
- package/dist/vitals.js.map +1 -0
- package/dist/vite.d.ts +16 -1
- package/dist/vite.d.ts.map +1 -1
- package/dist/vite.js +248 -43
- package/dist/vite.js.map +1 -1
- package/dist/zones.d.ts +70 -0
- package/dist/zones.d.ts.map +1 -0
- package/dist/zones.js +365 -0
- package/dist/zones.js.map +1 -0
- package/package.json +67 -14
- package/src/backend-only.ts +16 -0
- package/src/boundary.ts +18 -5
- package/src/build-plan.ts +90 -35
- package/src/build-vite.ts +77 -11
- package/src/build.ts +466 -96
- package/src/bun-dev-entry.ts +1 -1
- package/src/cdn.ts +216 -0
- package/src/client.ts +135 -36
- package/src/conformance.ts +16 -3
- package/src/csp.ts +194 -0
- package/src/dev-client.ts +349 -0
- package/src/dev-diagnostics.ts +60 -7
- package/src/dev-error.ts +49 -5
- package/src/dev-feed.ts +1140 -0
- package/src/dev-indicator.ts +113 -0
- package/src/dev-session.ts +729 -0
- package/src/dev-sourcemap.ts +281 -0
- package/src/dev-ssr-graph.ts +16 -5
- package/src/dev.ts +86 -43
- package/src/diagnostic-catalog.ts +243 -0
- package/src/diagnostic-prompt.ts +355 -0
- package/src/diagnostic.ts +63 -66
- package/src/draft.ts +4 -1
- package/src/fn.ts +19 -3
- package/src/fs.ts +13 -2
- package/src/index.ts +42 -10
- package/src/internal/cdn/cloudflare.ts +146 -0
- package/src/internal/cdn/core.ts +316 -0
- package/src/internal/cdn/fastly.ts +62 -0
- package/src/internal/cdn/vercel.ts +95 -0
- package/src/internal/code-unit-order.ts +5 -0
- package/src/internal/codegen.ts +161 -24
- package/src/internal/dev-csp.ts +176 -0
- package/src/internal/dev-reserved.ts +52 -0
- package/src/internal/html-spans.ts +50 -0
- package/src/internal/loading-runtime.ts +244 -0
- package/src/internal/matches-runtime.ts +62 -0
- package/src/internal/mount-shadow.ts +88 -0
- package/src/internal/node-builtins.ts +79 -0
- package/src/internal/output-guard.ts +701 -0
- package/src/internal/page-execution.ts +795 -185
- package/src/internal/parity.ts +150 -36
- package/src/internal/private-env.ts +334 -0
- package/src/internal/public-url.ts +22 -0
- package/src/internal/render-document.ts +114 -67
- package/src/internal/response-controls.ts +284 -0
- package/src/internal/runtime-contract.ts +10 -15
- package/src/internal/secret-scan.ts +638 -0
- package/src/internal/server-boundary.ts +6 -69
- package/src/internal/source-map.ts +256 -0
- package/src/internal/target-compat.ts +92 -0
- package/src/internal/timing-safe-equal.ts +13 -0
- package/src/internal/vitals-runtime.ts +53 -0
- package/src/internal/web-app.ts +262 -84
- package/src/internal/zone-graph.ts +593 -0
- package/src/isr.ts +325 -37
- package/src/llms-txt.ts +28 -4
- package/src/manifest.ts +682 -16
- package/src/module-graph.ts +53 -9
- package/src/navigation.ts +29 -6
- package/src/nonce.ts +104 -0
- package/src/plugins/css-modules.ts +5 -3
- package/src/plugins/kit.ts +24 -0
- package/src/plugins/svg.ts +135 -4
- package/src/plugins/vite-leak-guard.ts +529 -16
- package/src/plugins/vite-zone-guard.ts +263 -0
- package/src/plugins/zone-guard.ts +119 -0
- package/src/prerender.ts +49 -3
- package/src/public-dir.ts +69 -8
- package/src/pwa-manifest.ts +226 -0
- package/src/query.ts +4 -4
- package/src/render-seam.ts +46 -1
- package/src/route-manifest.ts +15 -3
- package/src/route-types.ts +264 -0
- package/src/router.ts +163 -63
- package/src/vitals.ts +44 -0
- package/src/vite.ts +257 -42
- package/src/zones.ts +430 -0
- package/dist/plugins/vite-server-only.d.ts +0 -49
- package/dist/plugins/vite-server-only.d.ts.map +0 -1
- package/dist/plugins/vite-server-only.js +0 -57
- package/dist/plugins/vite-server-only.js.map +0 -1
- package/dist/server-only.d.ts +0 -21
- package/dist/server-only.d.ts.map +0 -1
- package/dist/server-only.js +0 -25
- package/dist/server-only.js.map +0 -1
- package/src/plugins/vite-server-only.ts +0 -75
- package/src/server-only.ts +0 -25
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Maps a browser stack trace back to source files, using the source maps the dev server itself
|
|
3
|
+
* serves (Bun links `/_bun/client/<gen>.js.map`; Vite inlines a data URL per module).
|
|
4
|
+
*
|
|
5
|
+
* Every fetch goes to the dev server's own origin, whatever host a frame names, so a crafted frame
|
|
6
|
+
* cannot make the server request anything else. Browser stacks in any engine's format come out as
|
|
7
|
+
* V8 `at` frames, which is what {@link parseFrames} reads.
|
|
8
|
+
*/
|
|
9
|
+
import { isAbsolute, resolve } from "node:path";
|
|
10
|
+
import { fileURLToPath } from "node:url";
|
|
11
|
+
import { decodeMappings, inlineSourceMap, lookupPosition, originalPosition, } from "./internal/source-map.js";
|
|
12
|
+
// V8: ` at fn (url:1:2)` / ` at url:1:2` / ` at async fn (url:1:2)`.
|
|
13
|
+
const V8_FRAME = /^\s*at\s+(?:(.*?)\s+\()?(.+?):(\d+):(\d+)\)?\s*$/;
|
|
14
|
+
// SpiderMonkey / JavaScriptCore: `fn@url:1:2` / `@url:1:2`.
|
|
15
|
+
const AT_FRAME = /^\s*(.*?)@(.+?):(\d+):(\d+)\s*$/;
|
|
16
|
+
const MAX_FRAMES = 50;
|
|
17
|
+
const SCRIPT_PATH = /\.(?:[cm]?[jt]sx?|vue|svelte|astro|mdx)$/i;
|
|
18
|
+
const MAX_SCRIPT_BYTES = 64 * 1024 * 1024;
|
|
19
|
+
const FETCH_TIMEOUT_MS = 5_000;
|
|
20
|
+
function parseFrame(line) {
|
|
21
|
+
const match = V8_FRAME.exec(line) ?? AT_FRAME.exec(line);
|
|
22
|
+
if (match === null)
|
|
23
|
+
return undefined;
|
|
24
|
+
const [, name, url = "", lineText = "", columnText = ""] = match;
|
|
25
|
+
return {
|
|
26
|
+
name: name === undefined || name === "" ? undefined : name.replace(/^async\s+/, ""),
|
|
27
|
+
url,
|
|
28
|
+
line: Number(lineText),
|
|
29
|
+
column: Number(columnText),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
// ---------------------------------------------------------------------------------------------------
|
|
33
|
+
// Lookup
|
|
34
|
+
// ---------------------------------------------------------------------------------------------------
|
|
35
|
+
export { decodeMappings } from "./internal/source-map.js";
|
|
36
|
+
/**
|
|
37
|
+
* The source position for a 0-based generated line/column. When the source is a plugin's output that
|
|
38
|
+
* carries its own map inline (a compiled `.svelte` or `.vue` file), that map is followed too: Bun's
|
|
39
|
+
* bundler keeps the plugin's output as the source, not the file it compiled.
|
|
40
|
+
*/
|
|
41
|
+
function lookup(map, line, column) {
|
|
42
|
+
const found = lookupPosition(map.lines, line, column);
|
|
43
|
+
if (found === undefined)
|
|
44
|
+
return undefined;
|
|
45
|
+
const source = map.sources[found.source];
|
|
46
|
+
if (source === undefined)
|
|
47
|
+
return undefined;
|
|
48
|
+
if (!map.inner.has(found.source)) {
|
|
49
|
+
const content = map.sourcesContent[found.source];
|
|
50
|
+
map.inner.set(found.source, typeof content === "string" ? inlineSourceMap(content) : undefined);
|
|
51
|
+
}
|
|
52
|
+
const inner = map.inner.get(found.source);
|
|
53
|
+
const original = inner === undefined ? undefined : originalPosition(inner, found.line, found.column);
|
|
54
|
+
return original === undefined
|
|
55
|
+
? { source, line: found.line, column: found.column }
|
|
56
|
+
: { source, line: original.line, column: original.column };
|
|
57
|
+
}
|
|
58
|
+
// ---------------------------------------------------------------------------------------------------
|
|
59
|
+
// Fetching
|
|
60
|
+
// ---------------------------------------------------------------------------------------------------
|
|
61
|
+
function isRecord(value) {
|
|
62
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
63
|
+
}
|
|
64
|
+
const SOURCE_MAPPING_URL = /[#@]\s*sourceMappingURL=([^\s'"]+)\s*$/;
|
|
65
|
+
function sourceMappingUrl(script) {
|
|
66
|
+
// The comment is the last one in the file; a data URL can be megabytes, so look from the end.
|
|
67
|
+
const at = script.lastIndexOf("sourceMappingURL=");
|
|
68
|
+
if (at === -1)
|
|
69
|
+
return undefined;
|
|
70
|
+
const lineStart = script.lastIndexOf("\n", at) + 1;
|
|
71
|
+
return SOURCE_MAPPING_URL.exec(script.slice(lineStart))?.[1];
|
|
72
|
+
}
|
|
73
|
+
function decodeDataUrl(url) {
|
|
74
|
+
const comma = url.indexOf(",");
|
|
75
|
+
if (comma === -1)
|
|
76
|
+
return undefined;
|
|
77
|
+
const meta = url.slice(5, comma);
|
|
78
|
+
const payload = url.slice(comma + 1);
|
|
79
|
+
return meta.endsWith(";base64")
|
|
80
|
+
? Buffer.from(payload, "base64").toString("utf8")
|
|
81
|
+
: decodeURIComponent(payload);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* The directory a served script lives in on disk. Vite serves files outside the root as
|
|
85
|
+
* `/@fs/<absolute path>`; everything else maps onto the project root.
|
|
86
|
+
*/
|
|
87
|
+
function scriptDirectory(scriptPath, root) {
|
|
88
|
+
const dir = decodeURIComponent(scriptPath.replace(/[^/]*$/, ""));
|
|
89
|
+
// `/@fs/C:/x/` names `C:/x/` on Windows: the slash before a drive letter is URL syntax only.
|
|
90
|
+
return dir.startsWith("/@fs/")
|
|
91
|
+
? dir.slice("/@fs".length).replace(/^\/([a-zA-Z]:)/, "$1")
|
|
92
|
+
: resolve(root, `.${dir}`);
|
|
93
|
+
}
|
|
94
|
+
/** The filesystem path a map's source names, when it is a file. */
|
|
95
|
+
function sourcePath(source, sourceRoot, scriptPath, root) {
|
|
96
|
+
const joined = sourceRoot === "" ? source : `${sourceRoot.replace(/\/?$/, "/")}${source}`;
|
|
97
|
+
if (joined.startsWith("file://")) {
|
|
98
|
+
try {
|
|
99
|
+
return fileURLToPath(joined);
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
return joined;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (/^[a-z][a-z\d+.-]*:/i.test(joined))
|
|
106
|
+
return joined;
|
|
107
|
+
if (isAbsolute(joined))
|
|
108
|
+
return joined;
|
|
109
|
+
// Relative to the script's own location, as a map's sources always are.
|
|
110
|
+
return resolve(scriptDirectory(scriptPath, root), joined);
|
|
111
|
+
}
|
|
112
|
+
export function createSourceMapper(options) {
|
|
113
|
+
const root = resolve(options.root);
|
|
114
|
+
const fetchImpl = options.fetch ?? ((url, init) => fetch(url, init));
|
|
115
|
+
const maxMaps = options.maxMaps ?? 8;
|
|
116
|
+
const maps = new Map();
|
|
117
|
+
const fetchText = async (url) => {
|
|
118
|
+
const response = await fetchImpl(url, { signal: AbortSignal.timeout(FETCH_TIMEOUT_MS) });
|
|
119
|
+
if (!response.ok)
|
|
120
|
+
return undefined;
|
|
121
|
+
const length = Number(response.headers.get("content-length") ?? "0");
|
|
122
|
+
if (length > MAX_SCRIPT_BYTES)
|
|
123
|
+
return undefined;
|
|
124
|
+
const text = await response.text();
|
|
125
|
+
return text.length > MAX_SCRIPT_BYTES ? undefined : text;
|
|
126
|
+
};
|
|
127
|
+
const load = async (origin, pathAndQuery) => {
|
|
128
|
+
const scriptUrl = new URL(pathAndQuery, origin);
|
|
129
|
+
const script = await fetchText(scriptUrl.href);
|
|
130
|
+
if (script === undefined)
|
|
131
|
+
return undefined;
|
|
132
|
+
const reference = sourceMappingUrl(script);
|
|
133
|
+
if (reference === undefined)
|
|
134
|
+
return undefined;
|
|
135
|
+
let text;
|
|
136
|
+
if (reference.startsWith("data:"))
|
|
137
|
+
text = decodeDataUrl(reference);
|
|
138
|
+
else {
|
|
139
|
+
const mapUrl = new URL(reference, scriptUrl);
|
|
140
|
+
// Same server only: the map's URL comes from a script body, and a body is data.
|
|
141
|
+
if (mapUrl.origin !== scriptUrl.origin)
|
|
142
|
+
return undefined;
|
|
143
|
+
text = await fetchText(mapUrl.href);
|
|
144
|
+
}
|
|
145
|
+
if (text === undefined)
|
|
146
|
+
return undefined;
|
|
147
|
+
const raw = JSON.parse(text);
|
|
148
|
+
if (!isRecord(raw) || typeof raw.mappings !== "string" || !Array.isArray(raw.sources))
|
|
149
|
+
return undefined;
|
|
150
|
+
const sourceRoot = typeof raw.sourceRoot === "string" ? raw.sourceRoot : "";
|
|
151
|
+
return {
|
|
152
|
+
sources: raw.sources.map((source) => typeof source === "string" ? sourcePath(source, sourceRoot, scriptUrl.pathname, root) : ""),
|
|
153
|
+
lines: decodeMappings(raw.mappings),
|
|
154
|
+
sourcesContent: Array.isArray(raw.sourcesContent) ? raw.sourcesContent : [],
|
|
155
|
+
inner: new Map(),
|
|
156
|
+
};
|
|
157
|
+
};
|
|
158
|
+
const mapFor = (origin, pathAndQuery) => {
|
|
159
|
+
const cached = maps.get(pathAndQuery);
|
|
160
|
+
if (cached !== undefined) {
|
|
161
|
+
maps.delete(pathAndQuery);
|
|
162
|
+
maps.set(pathAndQuery, cached);
|
|
163
|
+
return cached;
|
|
164
|
+
}
|
|
165
|
+
const loading = load(origin, pathAndQuery).catch(() => undefined);
|
|
166
|
+
maps.set(pathAndQuery, loading);
|
|
167
|
+
while (maps.size > maxMaps) {
|
|
168
|
+
const oldest = maps.keys().next().value;
|
|
169
|
+
if (oldest === undefined)
|
|
170
|
+
break;
|
|
171
|
+
maps.delete(oldest);
|
|
172
|
+
}
|
|
173
|
+
return loading;
|
|
174
|
+
};
|
|
175
|
+
/** The script's path on this server, when a frame names this server at all. */
|
|
176
|
+
const ownPath = (url, origin) => {
|
|
177
|
+
let parsed;
|
|
178
|
+
try {
|
|
179
|
+
parsed = new URL(url);
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
return undefined;
|
|
183
|
+
}
|
|
184
|
+
const own = new URL(origin);
|
|
185
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:")
|
|
186
|
+
return undefined;
|
|
187
|
+
// `localhost:<port>` and `127.0.0.1:<port>` both reach this server; another port is another server.
|
|
188
|
+
if (parsed.port !== own.port)
|
|
189
|
+
return undefined;
|
|
190
|
+
const host = parsed.hostname;
|
|
191
|
+
if (host !== "localhost" &&
|
|
192
|
+
host !== "127.0.0.1" &&
|
|
193
|
+
host !== "[::1]" &&
|
|
194
|
+
!host.endsWith(".localhost"))
|
|
195
|
+
return undefined;
|
|
196
|
+
// Scripts only: fetching a page URL (an inline script's frame) would render it, loaders and all.
|
|
197
|
+
if (!SCRIPT_PATH.test(parsed.pathname))
|
|
198
|
+
return undefined;
|
|
199
|
+
return `${parsed.pathname}${parsed.search}`;
|
|
200
|
+
};
|
|
201
|
+
return {
|
|
202
|
+
async mapStack(stack) {
|
|
203
|
+
const origin = options.origin();
|
|
204
|
+
const lines = stack.split("\n");
|
|
205
|
+
const out = [];
|
|
206
|
+
let frames = 0;
|
|
207
|
+
for (const line of lines) {
|
|
208
|
+
const frame = parseFrame(line);
|
|
209
|
+
if (frame === undefined) {
|
|
210
|
+
// The message block (and engine noise between frames) stays as it was.
|
|
211
|
+
if (frames === 0)
|
|
212
|
+
out.push(line);
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
if (frames >= MAX_FRAMES)
|
|
216
|
+
break;
|
|
217
|
+
frames += 1;
|
|
218
|
+
let location = `${frame.url}:${frame.line}:${frame.column}`;
|
|
219
|
+
const path = origin === undefined ? undefined : ownPath(frame.url, origin);
|
|
220
|
+
if (origin !== undefined && path !== undefined) {
|
|
221
|
+
const map = await mapFor(origin, path);
|
|
222
|
+
const position = map === undefined ? undefined : lookup(map, frame.line - 1, frame.column - 1);
|
|
223
|
+
if (position !== undefined && position.source !== "")
|
|
224
|
+
location = `${position.source}:${position.line}:${position.column}`;
|
|
225
|
+
}
|
|
226
|
+
out.push(frame.name === undefined ? ` at ${location}` : ` at ${frame.name} (${location})`);
|
|
227
|
+
}
|
|
228
|
+
return out.join("\n");
|
|
229
|
+
},
|
|
230
|
+
clear() {
|
|
231
|
+
maps.clear();
|
|
232
|
+
},
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
//# sourceMappingURL=dev-sourcemap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-sourcemap.js","sourceRoot":"","sources":["../src/dev-sourcemap.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EACL,cAAc,EACd,eAAe,EACf,cAAc,EAEd,gBAAgB,GAEjB,MAAM,0BAA0B,CAAA;AAyBjC,8EAA8E;AAC9E,MAAM,QAAQ,GAAG,kDAAkD,CAAA;AACnE,4DAA4D;AAC5D,MAAM,QAAQ,GAAG,iCAAiC,CAAA;AAClD,MAAM,UAAU,GAAG,EAAE,CAAA;AACrB,MAAM,WAAW,GAAG,2CAA2C,CAAA;AAC/D,MAAM,gBAAgB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAA;AACzC,MAAM,gBAAgB,GAAG,KAAK,CAAA;AAE9B,SAAS,UAAU,CAAC,IAAY;IAC9B,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACxD,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,SAAS,CAAA;IACpC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,GAAG,EAAE,EAAE,QAAQ,GAAG,EAAE,EAAE,UAAU,GAAG,EAAE,CAAC,GAAG,KAAK,CAAA;IAChE,OAAO;QACL,IAAI,EAAE,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;QACnF,GAAG;QACH,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC;QACtB,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC;KAC3B,CAAA;AACH,CAAC;AAED,sGAAsG;AACtG,SAAS;AACT,sGAAsG;AAEtG,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAUzD;;;;GAIG;AACH,SAAS,MAAM,CACb,GAAe,EACf,IAAY,EACZ,MAAc;IAEd,MAAM,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;IACrD,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IACzC,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IACxC,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IAC1C,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;QACjC,MAAM,OAAO,GAAG,GAAG,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QAChD,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;IACjG,CAAC;IACD,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IACzC,MAAM,QAAQ,GACZ,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;IACrF,OAAO,QAAQ,KAAK,SAAS;QAC3B,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE;QACpD,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAA;AAC9D,CAAC;AAED,sGAAsG;AACtG,WAAW;AACX,sGAAsG;AAEtG,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;AAC7E,CAAC;AAED,MAAM,kBAAkB,GAAG,wCAAwC,CAAA;AAEnE,SAAS,gBAAgB,CAAC,MAAc;IACtC,8FAA8F;IAC9F,MAAM,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAA;IAClD,IAAI,EAAE,KAAK,CAAC,CAAC;QAAE,OAAO,SAAS,CAAA;IAC/B,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,CAAA;IAClD,OAAO,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;AAC9D,CAAC;AAED,SAAS,aAAa,CAAC,GAAW;IAChC,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAC9B,IAAI,KAAK,KAAK,CAAC,CAAC;QAAE,OAAO,SAAS,CAAA;IAClC,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;IAChC,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAA;IACpC,OAAO,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC7B,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;QACjD,CAAC,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAA;AACjC,CAAC;AAED;;;GAGG;AACH,SAAS,eAAe,CAAC,UAAkB,EAAE,IAAY;IACvD,MAAM,GAAG,GAAG,kBAAkB,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAA;IAChE,6FAA6F;IAC7F,OAAO,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC;QAC5B,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,gBAAgB,EAAE,IAAI,CAAC;QAC1D,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,EAAE,CAAC,CAAA;AAC9B,CAAC;AAED,mEAAmE;AACnE,SAAS,UAAU,CAAC,MAAc,EAAE,UAAkB,EAAE,UAAkB,EAAE,IAAY;IACtF,MAAM,MAAM,GAAG,UAAU,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,EAAE,CAAA;IACzF,IAAI,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QACjC,IAAI,CAAC;YACH,OAAO,aAAa,CAAC,MAAM,CAAC,CAAA;QAC9B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,MAAM,CAAA;QACf,CAAC;IACH,CAAC;IACD,IAAI,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAA;IACrD,IAAI,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAA;IACrC,wEAAwE;IACxE,OAAO,OAAO,CAAC,eAAe,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAA;AAC3D,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAA4B;IAC7D,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IAClC,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAA;IACpE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,CAAC,CAAA;IACpC,MAAM,IAAI,GAAG,IAAI,GAAG,EAA2C,CAAA;IAE/D,MAAM,SAAS,GAAG,KAAK,EAAE,GAAW,EAA+B,EAAE;QACnE,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAA;QACxF,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,OAAO,SAAS,CAAA;QAClC,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,GAAG,CAAC,CAAA;QACpE,IAAI,MAAM,GAAG,gBAAgB;YAAE,OAAO,SAAS,CAAA;QAC/C,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;QAClC,OAAO,IAAI,CAAC,MAAM,GAAG,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAA;IAC1D,CAAC,CAAA;IAED,MAAM,IAAI,GAAG,KAAK,EAAE,MAAc,EAAE,YAAoB,EAAmC,EAAE;QAC3F,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,CAAA;QAC/C,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QAC9C,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,SAAS,CAAA;QAC1C,MAAM,SAAS,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAA;QAC1C,IAAI,SAAS,KAAK,SAAS;YAAE,OAAO,SAAS,CAAA;QAC7C,IAAI,IAAwB,CAAA;QAC5B,IAAI,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC;YAAE,IAAI,GAAG,aAAa,CAAC,SAAS,CAAC,CAAA;aAC7D,CAAC;YACJ,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;YAC5C,gFAAgF;YAChF,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM;gBAAE,OAAO,SAAS,CAAA;YACxD,IAAI,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QACrC,CAAC;QACD,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,SAAS,CAAA;QACxC,MAAM,GAAG,GAAY,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QACrC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;YACnF,OAAO,SAAS,CAAA;QAClB,MAAM,UAAU,GAAG,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAA;QAC3E,OAAO;YACL,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAClC,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAC3F;YACD,KAAK,EAAE,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC;YACnC,cAAc,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE;YAC3E,KAAK,EAAE,IAAI,GAAG,EAAE;SACjB,CAAA;IACH,CAAC,CAAA;IAED,MAAM,MAAM,GAAG,CAAC,MAAc,EAAE,YAAoB,EAAmC,EAAE;QACvF,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;QACrC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;YACzB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,CAAA;YAC9B,OAAO,MAAM,CAAA;QACf,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;QACjE,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,OAAO,CAAC,CAAA;QAC/B,OAAO,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,CAAC;YAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAA;YACvC,IAAI,MAAM,KAAK,SAAS;gBAAE,MAAK;YAC/B,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QACrB,CAAC;QACD,OAAO,OAAO,CAAA;IAChB,CAAC,CAAA;IAED,+EAA+E;IAC/E,MAAM,OAAO,GAAG,CAAC,GAAW,EAAE,MAAc,EAAsB,EAAE;QAClE,IAAI,MAAW,CAAA;QACf,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;QACvB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAA;QAClB,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAA;QAC3B,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ;YAAE,OAAO,SAAS,CAAA;QACjF,oGAAoG;QACpG,IAAI,MAAM,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI;YAAE,OAAO,SAAS,CAAA;QAC9C,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAA;QAC5B,IACE,IAAI,KAAK,WAAW;YACpB,IAAI,KAAK,WAAW;YACpB,IAAI,KAAK,OAAO;YAChB,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;YAE5B,OAAO,SAAS,CAAA;QAClB,iGAAiG;QACjG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;YAAE,OAAO,SAAS,CAAA;QACxD,OAAO,GAAG,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,CAAA;IAC7C,CAAC,CAAA;IAED,OAAO;QACL,KAAK,CAAC,QAAQ,CAAC,KAAK;YAClB,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAA;YAC/B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;YAC/B,MAAM,GAAG,GAAa,EAAE,CAAA;YACxB,IAAI,MAAM,GAAG,CAAC,CAAA;YACd,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,CAAA;gBAC9B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;oBACxB,uEAAuE;oBACvE,IAAI,MAAM,KAAK,CAAC;wBAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;oBAChC,SAAQ;gBACV,CAAC;gBACD,IAAI,MAAM,IAAI,UAAU;oBAAE,MAAK;gBAC/B,MAAM,IAAI,CAAC,CAAA;gBACX,IAAI,QAAQ,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,MAAM,EAAE,CAAA;gBAC3D,MAAM,IAAI,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;gBAC1E,IAAI,MAAM,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;oBAC/C,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;oBACtC,MAAM,QAAQ,GACZ,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,GAAG,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;oBAC/E,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,KAAK,EAAE;wBAClD,QAAQ,GAAG,GAAG,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAA;gBACvE,CAAC;gBACD,GAAG,CAAC,IAAI,CACN,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,UAAU,QAAQ,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,CAAC,IAAI,KAAK,QAAQ,GAAG,CACvF,CAAA;YACH,CAAC;YACD,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACvB,CAAC;QACD,KAAK;YACH,IAAI,CAAC,KAAK,EAAE,CAAA;QACd,CAAC;KACF,CAAA;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev-ssr-graph.d.ts","sourceRoot":"","sources":["../src/dev-ssr-graph.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dev-ssr-graph.d.ts","sourceRoot":"","sources":["../src/dev-ssr-graph.ts"],"names":[],"mappings":"AA4DA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,KAAK,CAAA;AAuDpC,MAAM,WAAW,eAAe;IAC9B,kFAAkF;IAClF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,QAAQ;IACvB;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAA;IAC1B;;;OAGG;IACH,KAAK,IAAI,OAAO,CAAA;IAChB,0GAA0G;IAC1G,UAAU,IAAI,MAAM,CAAA;IACpB,qEAAqE;IACrE,OAAO,IAAI,IAAI,CAAA;CAChB;AA6CD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAGjG;AAED,yGAAyG;AACzG,wBAAgB,cAAc,CAAC,OAAO,EAAE,eAAe,GAAG,QAAQ,CAkKjE"}
|
package/dist/dev-ssr-graph.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Bun's runtime caches every module it has evaluated, and nothing invalidates that cache on a file
|
|
5
5
|
* change. The dev server's answer used to stop at the route module: `discoverRoutes({ importQuery })`
|
|
6
6
|
* appends a changing query to each route's own dynamic import, so the route re-evaluates. Its imports
|
|
7
|
-
* do not - a component, a helper, a
|
|
7
|
+
* do not - a component, a helper, a backend module all keep resolving to the same cached specifier,
|
|
8
8
|
* so SSR kept rendering the code that was on disk when the server started while the client, which Bun
|
|
9
9
|
* rebuilds properly, rendered the edit. Every framework on this pipeline had it; the Vite pipeline does
|
|
10
10
|
* not, because Vite owns its own SSR module graph.
|
|
@@ -46,8 +46,9 @@
|
|
|
46
46
|
*
|
|
47
47
|
* So the version is applied one level earlier, in the importer's own source: on load, each app-owned
|
|
48
48
|
* module has its relative specifiers rewritten to absolute paths carrying the current version of the
|
|
49
|
-
* file they point at
|
|
50
|
-
* a third-party plugin
|
|
49
|
+
* file they point at - an alias such as `@/components/Button` too, resolved the way Bun resolves it.
|
|
50
|
+
* `onResolve` stays as well, because it is the only hook that sees modules loaded by a third-party plugin
|
|
51
|
+
* this one does not wrap.
|
|
51
52
|
*
|
|
52
53
|
* Old versions stay in Bun's registry - a bounded dev-only leak, one entry per edit, which is what the
|
|
53
54
|
* route-level query already did.
|
|
@@ -95,6 +96,13 @@ const appSourceFilter = (root) => {
|
|
|
95
96
|
* transpiler's own scan reported the same specifier, which is what keeps a lookalike string literal out.
|
|
96
97
|
*/
|
|
97
98
|
const SPECIFIER = /\b(from|import|require)((?:\s*\()?\s*)(["'])([^"'\n]+)\3/g;
|
|
99
|
+
/**
|
|
100
|
+
* A specifier that can name an app file: relative, absolute, or an alias an npm package name cannot be
|
|
101
|
+
* (`@/x`, `~/x`, `#x`, `$lib/x`). A bare package name is left alone - resolving one here would pin it
|
|
102
|
+
* for the life of the dev server, and a package is never app source anyway. An alias shaped like a
|
|
103
|
+
* package (`@app/x`, `src/x`) is not recognized.
|
|
104
|
+
*/
|
|
105
|
+
const APP_SPECIFIER = /^(?:[^a-z0-9@]|@[^a-z0-9])/i;
|
|
98
106
|
/** `/abs/path.ts?v=2` and `file:///abs/path.ts` both name `/abs/path.ts`. */
|
|
99
107
|
function plainPath(path) {
|
|
100
108
|
const withoutQuery = path.split("?", 1)[0] ?? path;
|
|
@@ -228,7 +236,7 @@ export function createSsrGraph(options) {
|
|
|
228
236
|
// through untouched rather than adding a second, worse one.
|
|
229
237
|
return contents;
|
|
230
238
|
}
|
|
231
|
-
const candidates = new Set(scanned.map((entry) => entry.path).filter((
|
|
239
|
+
const candidates = new Set(scanned.map((entry) => entry.path).filter((path) => APP_SPECIFIER.test(path)));
|
|
232
240
|
if (candidates.size === 0)
|
|
233
241
|
return contents;
|
|
234
242
|
const keys = new Map();
|
|
@@ -255,7 +263,7 @@ export function createSsrGraph(options) {
|
|
|
255
263
|
});
|
|
256
264
|
// The resolver half covers what the loader half cannot see: a module compiled by a plugin that
|
|
257
265
|
// does not call `rewriteSsrImports`. Extension-bearing specifiers only, which is all Bun offers.
|
|
258
|
-
build.onResolve({ filter:
|
|
266
|
+
build.onResolve({ filter: APP_SPECIFIER }, (args) => {
|
|
259
267
|
if (resolving)
|
|
260
268
|
return undefined;
|
|
261
269
|
// A specifier that already carries a query is either this module's own rewrite or a plugin's
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev-ssr-graph.js","sourceRoot":"","sources":["../src/dev-ssr-graph.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"dev-ssr-graph.js","sourceRoot":"","sources":["../src/dev-ssr-graph.ts"],"names":[],"mappings":"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"}
|
package/dist/dev.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { type BuildClientOptions } from "./build.js";
|
|
2
|
+
import { type DevAppHooks } from "./dev-session.js";
|
|
3
|
+
export type { DevAppHooks } from "./dev-session.js";
|
|
2
4
|
export { LAST_ERROR_PATH } from "./diagnostic.js";
|
|
3
5
|
/** Minimal app surface the dev server needs - `createWebApp(...)` satisfies it. */
|
|
4
6
|
interface FetchApp {
|
|
@@ -8,9 +10,10 @@ export interface DevServerOptions extends Omit<BuildClientOptions, "minify"> {
|
|
|
8
10
|
/**
|
|
9
11
|
* Build the nifra app for the current client entry. `importQuery` changes on every reload - pass it to
|
|
10
12
|
* `discoverRoutes(routesDir, { importQuery })` so SSR re-imports edited route modules instead of Bun's
|
|
11
|
-
* cached copies.
|
|
13
|
+
* cached copies. Pass `dev.onLoaderError` to `createWebApp` so failures an `_error` boundary renders
|
|
14
|
+
* still reach the dev feed (`nifra errors`).
|
|
12
15
|
*/
|
|
13
|
-
readonly createApp: (clientEntry: string, importQuery: string) => FetchApp | Promise<FetchApp>;
|
|
16
|
+
readonly createApp: (clientEntry: string, importQuery: string, dev: DevAppHooks) => FetchApp | Promise<FetchApp>;
|
|
14
17
|
/** Directories to watch (default: `[routesDir]`). */
|
|
15
18
|
readonly watch?: readonly string[];
|
|
16
19
|
/** Port to listen on (default {@link DEFAULT_DEV_PORT}). */
|
|
@@ -27,6 +30,16 @@ export interface DevServerOptions extends Omit<BuildClientOptions, "minify"> {
|
|
|
27
30
|
* pass runs in the background off the hot path, so HMR is never waiting on it, and only reports.
|
|
28
31
|
*/
|
|
29
32
|
readonly guardLeaks?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Write `.nifra/dev-server.json` (how `nifra errors`/`nifra logs` and the MCP tools find this server)
|
|
35
|
+
* and the persisted dev log beside it (default `true`).
|
|
36
|
+
*/
|
|
37
|
+
readonly record?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Show the browser errors a dev page reports in a badge on that page, with a Copy prompt button per
|
|
40
|
+
* fix (default `true`). Off, the errors still reach the feed.
|
|
41
|
+
*/
|
|
42
|
+
readonly indicator?: boolean;
|
|
30
43
|
}
|
|
31
44
|
export interface DevServer {
|
|
32
45
|
readonly port: number;
|
package/dist/dev.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../src/dev.ts"],"names":[],"mappings":"AAyDA,OAAO,EAAE,KAAK,kBAAkB,EAAe,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../src/dev.ts"],"names":[],"mappings":"AAyDA,OAAO,EAAE,KAAK,kBAAkB,EAAe,MAAM,YAAY,CAAA;AAGjE,OAAO,EAAoB,KAAK,WAAW,EAAmB,MAAM,kBAAkB,CAAA;AAQtF,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEjD,mFAAmF;AACnF,UAAU,QAAQ;IAChB,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;CACtD;AAED,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,kBAAkB,EAAE,QAAQ,CAAC;IAC1E;;;;;OAKG;IACH,QAAQ,CAAC,SAAS,EAAE,CAClB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,WAAW,KACb,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;IACjC,qDAAqD;IACrD,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAClC,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB;sFACkF;IAClF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;IACnC;;;;;;;OAOG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAA;IAC7B;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;IACzB;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAC7B;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB;;;;OAIG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,IAAI,IAAI,IAAI,CAAA;CACb;AAaD;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,uBAAuB,CAAA;AAyCrD;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAMjD;AAED,UAAU,oBAAoB;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAC1B;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAsBjE;AAED,wGAAwG;AACxG,wBAAgB,SAAS,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAQ3D;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAM5E;AAED,0FAA0F;AAC1F,wBAAsB,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,SAAS,CAAC,CAkVnF;AAED;;;;;;;;;;;GAWG;AACH;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAIvD"}
|
package/dist/dev.js
CHANGED
|
@@ -22,7 +22,7 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
|
|
|
22
22
|
* not, and saving it does a clean full reload. Plus no Vite dependency and ONE bundler across dev and
|
|
23
23
|
* production, which is the real prize - the dev/prod seam disappears.
|
|
24
24
|
*
|
|
25
|
-
* CSS Modules, server functions, and
|
|
25
|
+
* CSS Modules, server functions, and the zone guard use the same production transforms through the
|
|
26
26
|
* generated Bun config. The CLI owns that config because Bun's HTML dev server accepts plugins only from
|
|
27
27
|
* `[serve.static] plugins`; direct callers should pass the equivalent plugin through their Bun config.
|
|
28
28
|
*
|
|
@@ -47,7 +47,7 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
|
|
|
47
47
|
*
|
|
48
48
|
* SSR invalidation is Bun's import cache rather than Vite's module graph, so route modules are re-imported
|
|
49
49
|
* under a changing query on each change - which is what `discoverRoutes({ importQuery })` exists for. That
|
|
50
|
-
* query stops at the route file, so everything BELOW it - components, helpers,
|
|
50
|
+
* query stops at the route file, so everything BELOW it - components, helpers, backend modules - is
|
|
51
51
|
* tracked and re-keyed per module by `./dev-ssr-graph.ts`, or SSR would render the code that was on disk
|
|
52
52
|
* when the server started.
|
|
53
53
|
*
|
|
@@ -57,11 +57,12 @@ import { mkdirSync, readdirSync, readFileSync, rmSync, unwatchFile, watchFile, w
|
|
|
57
57
|
import { dirname, relative, resolve } from "node:path";
|
|
58
58
|
import { buildClient } from "./build.js";
|
|
59
59
|
import { resolveDevEntry } from "./bun-dev-entry.js";
|
|
60
|
-
import { createDevDiagnostics } from "./dev-diagnostics.js";
|
|
61
60
|
import { explainBindFailure } from "./dev-port.js";
|
|
61
|
+
import { createDevSession } from "./dev-session.js";
|
|
62
62
|
import { createSsrGraph } from "./dev-ssr-graph.js";
|
|
63
63
|
import { discoverRoutes } from "./fs.js";
|
|
64
64
|
import { DEFAULT_DEV_PORT, generateClientEntry } from "./index.js";
|
|
65
|
+
import { DEV_ENTRY_FILE } from "./internal/dev-reserved.js";
|
|
65
66
|
import { DEV_HMR_ENV, DEV_ROOT_ENV, DEV_ROUTES_ENV } from "./plugins/kit.js";
|
|
66
67
|
import { servePublicDir } from "./public-dir.js";
|
|
67
68
|
export { LAST_ERROR_PATH } from "./diagnostic.js";
|
|
@@ -216,10 +217,17 @@ export async function createDevServer(options) {
|
|
|
216
217
|
// (`devHotComponent`). Announced here rather than passed, for the same reason the flag above is.
|
|
217
218
|
process.env[DEV_ROOT_ENV] = root;
|
|
218
219
|
process.env[DEV_ROUTES_ENV] = resolve(routesDir);
|
|
219
|
-
//
|
|
220
|
-
// LAST_ERROR_PATH
|
|
221
|
-
//
|
|
222
|
-
const
|
|
220
|
+
// Everything this server sees, for the agent driving it: failures (with the overlay's Diagnostic and
|
|
221
|
+
// LAST_ERROR_PATH riding on the same capture), console output, request traces and the discovery
|
|
222
|
+
// record. Shared with the Vite adapter so the two servers report identically.
|
|
223
|
+
const session = createDevSession({
|
|
224
|
+
root,
|
|
225
|
+
pipeline: "bun",
|
|
226
|
+
publicEnvPrefix: options.publicEnvPrefix,
|
|
227
|
+
record: options.record,
|
|
228
|
+
indicator: options.indicator,
|
|
229
|
+
});
|
|
230
|
+
const devHooks = { onLoaderError: session.onLoaderError };
|
|
223
231
|
// SSR freshness BELOW the route module. The route-level `importQuery` only ever reloaded the route
|
|
224
232
|
// itself; everything it imports is tracked here and re-keyed when it changes. Registered now because a
|
|
225
233
|
// Bun runtime plugin only affects modules loaded after it, and the first route import is `appFor`
|
|
@@ -230,7 +238,7 @@ export async function createDevServer(options) {
|
|
|
230
238
|
const ssrGraph = createSsrGraph({ root });
|
|
231
239
|
(await import("bun")).plugin(ssrGraph.plugin);
|
|
232
240
|
const devDir = resolve(root, DEV_DIR);
|
|
233
|
-
const entryPath = resolve(devDir,
|
|
241
|
+
const entryPath = resolve(devDir, DEV_ENTRY_FILE);
|
|
234
242
|
const htmlPath = resolve(devDir, "entry.html");
|
|
235
243
|
const publicDir = options.publicDir === false ? undefined : (options.publicDir ?? "public");
|
|
236
244
|
// Route dev's `public/` through the SAME handler production uses. Dev previously inherited this
|
|
@@ -297,7 +305,7 @@ export async function createDevServer(options) {
|
|
|
297
305
|
* client leaks. It is no longer what keeps SSR correct.
|
|
298
306
|
*
|
|
299
307
|
* The entry hash is not the whole marker, though, because it only covers the CLIENT graph. A module
|
|
300
|
-
* the browser never receives - a
|
|
308
|
+
* the browser never receives - a backend module, a loader's helper - can change without moving it, so
|
|
301
309
|
* the key also carries {@link SsrGraph} generation, which counts changes on the SERVER side. Either
|
|
302
310
|
* one moving rebuilds the app, which is what re-imports the route modules under a fresh query.
|
|
303
311
|
*/
|
|
@@ -306,8 +314,11 @@ export async function createDevServer(options) {
|
|
|
306
314
|
return Promise.resolve(built.app);
|
|
307
315
|
if (building?.key === key)
|
|
308
316
|
return building.promise;
|
|
317
|
+
// A new key means the code moved since the last build: what the feed recorded before is stale.
|
|
318
|
+
if (version > 0)
|
|
319
|
+
session.markChange();
|
|
309
320
|
version += 1;
|
|
310
|
-
const promise = Promise.resolve(createApp(CLIENT_ENTRY_PATH, `v=${version}
|
|
321
|
+
const promise = Promise.resolve(createApp(CLIENT_ENTRY_PATH, `v=${version}`, devHooks));
|
|
311
322
|
building = { key, promise };
|
|
312
323
|
void promise
|
|
313
324
|
.then((next) => {
|
|
@@ -328,6 +339,36 @@ export async function createDevServer(options) {
|
|
|
328
339
|
ssrGraph.sweep();
|
|
329
340
|
return appFor(`${entrySrc}#${ssrGraph.generation()}`);
|
|
330
341
|
};
|
|
342
|
+
const renderApp = async (req, url) => {
|
|
343
|
+
try {
|
|
344
|
+
// One fresh probe per request: it is both the freshness check for SSR and the stylesheet list,
|
|
345
|
+
// so the page cannot be rendered against a build the browser is not about to load.
|
|
346
|
+
const entry = await currentEntry(true);
|
|
347
|
+
const res = await (await appForRequest(entry.src)).fetch(req);
|
|
348
|
+
if (!(res.headers.get("content-type") ?? "").includes("text/html"))
|
|
349
|
+
return res;
|
|
350
|
+
if (entry.styles.length === 0)
|
|
351
|
+
return session.decoratePage(req, res);
|
|
352
|
+
const headers = new Headers(res.headers);
|
|
353
|
+
headers.delete("content-length"); // the body grows with the injected stylesheet links
|
|
354
|
+
return session.decoratePage(req, new Response(injectStyles(await res.text(), entry.styles), {
|
|
355
|
+
status: res.status,
|
|
356
|
+
headers,
|
|
357
|
+
}));
|
|
358
|
+
}
|
|
359
|
+
catch (err) {
|
|
360
|
+
// One Diagnostic drives every surface: the overlay returned here, the JSON at LAST_ERROR_PATH and
|
|
361
|
+
// the feed's `ssr` entry.
|
|
362
|
+
const html = session.failure(err, {
|
|
363
|
+
method: req.method,
|
|
364
|
+
url: `${url.pathname}${url.search}`,
|
|
365
|
+
});
|
|
366
|
+
return new Response(html, {
|
|
367
|
+
status: 500,
|
|
368
|
+
headers: { "content-type": "text/html; charset=utf-8" },
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
};
|
|
331
372
|
try {
|
|
332
373
|
server = serve({
|
|
333
374
|
port,
|
|
@@ -347,11 +388,10 @@ export async function createDevServer(options) {
|
|
|
347
388
|
const entry = await currentEntry();
|
|
348
389
|
return new Response(null, { status: 307, headers: { location: entry.src } });
|
|
349
390
|
}
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
return
|
|
354
|
-
}
|
|
391
|
+
// The agent endpoints (errors, logs, requests, identity, last-error): shared surface.
|
|
392
|
+
const agent = await session.handle(req);
|
|
393
|
+
if (agent !== undefined)
|
|
394
|
+
return agent;
|
|
355
395
|
// Static probe before routing; a miss returns undefined and falls through, so no route is
|
|
356
396
|
// shadowed. Every GET/HEAD pays the probe, including page renders and API routes: the handler
|
|
357
397
|
// serves extension-less files too (an ACME challenge token is the reason), so there is no
|
|
@@ -360,37 +400,12 @@ export async function createDevServer(options) {
|
|
|
360
400
|
const staticFile = await servePublic(req);
|
|
361
401
|
if (staticFile !== undefined)
|
|
362
402
|
return staticFile;
|
|
363
|
-
|
|
364
|
-
// One fresh probe per request: it is both the freshness check for SSR and the stylesheet list,
|
|
365
|
-
// so the page cannot be rendered against a build the browser is not about to load.
|
|
366
|
-
const entry = await currentEntry(true);
|
|
367
|
-
const res = await (await appForRequest(entry.src)).fetch(req);
|
|
368
|
-
if (!(res.headers.get("content-type") ?? "").includes("text/html"))
|
|
369
|
-
return res;
|
|
370
|
-
if (entry.styles.length === 0)
|
|
371
|
-
return res;
|
|
372
|
-
const headers = new Headers(res.headers);
|
|
373
|
-
headers.delete("content-length"); // the body grows with the injected stylesheet links
|
|
374
|
-
return new Response(injectStyles(await res.text(), entry.styles), {
|
|
375
|
-
status: res.status,
|
|
376
|
-
headers,
|
|
377
|
-
});
|
|
378
|
-
}
|
|
379
|
-
catch (err) {
|
|
380
|
-
// One Diagnostic drives both surfaces: the overlay returned here and the JSON at LAST_ERROR_PATH.
|
|
381
|
-
const html = devDiagnostics.capture(err, {
|
|
382
|
-
method: req.method,
|
|
383
|
-
url: `${url.pathname}${url.search}`,
|
|
384
|
-
});
|
|
385
|
-
return new Response(html, {
|
|
386
|
-
status: 500,
|
|
387
|
-
headers: { "content-type": "text/html; charset=utf-8" },
|
|
388
|
-
});
|
|
389
|
-
}
|
|
403
|
+
return session.track(req, () => renderApp(req, url));
|
|
390
404
|
},
|
|
391
405
|
});
|
|
392
406
|
}
|
|
393
407
|
catch (err) {
|
|
408
|
+
session.stop();
|
|
394
409
|
// `Bun.serve` throws synchronously on a bind failure; the Vite path's equivalent arrives as an async
|
|
395
410
|
// `error` event. Same explanation either way - see ./dev-port.ts for why it is worth spelling out.
|
|
396
411
|
throw explainBindFailure(err, port);
|
|
@@ -404,9 +419,11 @@ export async function createDevServer(options) {
|
|
|
404
419
|
// Leaving the server up would answer 500s forever, which presents as a running server rather than as
|
|
405
420
|
// the startup failure it is.
|
|
406
421
|
server.stop(true);
|
|
422
|
+
session.stop();
|
|
407
423
|
throw err;
|
|
408
424
|
}
|
|
409
|
-
|
|
425
|
+
session.listening(server.port ?? port);
|
|
426
|
+
const guard = options.guardLeaks !== false ? leakGuard(options, session) : undefined;
|
|
410
427
|
guard?.();
|
|
411
428
|
// What is left for the watcher, now that request ordering keeps SSR fresh: regenerate the client entry
|
|
412
429
|
// when routes are ADDED or REMOVED (a scan result the request path never re-derives), and re-run the
|
|
@@ -418,12 +435,17 @@ export async function createDevServer(options) {
|
|
|
418
435
|
if (timer)
|
|
419
436
|
clearTimeout(timer);
|
|
420
437
|
timer = setTimeout(() => {
|
|
438
|
+
// A deletion its own watcher reported is unwatched now, or the next topology poll reports it
|
|
439
|
+
// again as a second change: another regeneration and another leak-guard build.
|
|
440
|
+
syncWatchedFiles(false);
|
|
441
|
+
session.markChange();
|
|
421
442
|
try {
|
|
422
443
|
writeDevFiles({ routesDir, clientModule, entryPath, htmlPath });
|
|
423
444
|
}
|
|
424
445
|
catch (err) {
|
|
425
446
|
// A half-saved file can fail the scan mid-edit; the next change re-runs this.
|
|
426
447
|
console.error("[nifra/web/dev] client entry regeneration failed:", err);
|
|
448
|
+
session.buildFailed(err, "client entry regeneration failed");
|
|
427
449
|
}
|
|
428
450
|
guard?.();
|
|
429
451
|
}, 60);
|
|
@@ -483,6 +505,7 @@ export async function createDevServer(options) {
|
|
|
483
505
|
unwatchFile(file);
|
|
484
506
|
ssrGraph.dispose();
|
|
485
507
|
server.stop(true);
|
|
508
|
+
session.stop();
|
|
486
509
|
rmSync(devDir, { recursive: true, force: true });
|
|
487
510
|
// Put the dev-phase env flags back the way this server found them (see `priorDevEnv`).
|
|
488
511
|
for (const [key, prior] of Object.entries(priorDevEnv)) {
|
|
@@ -516,7 +539,7 @@ export function buildFailureDetail(err) {
|
|
|
516
539
|
? err.errors.map((e) => ` ${e instanceof Error ? e.message : String(e)}`).join("\n")
|
|
517
540
|
: ` ${err instanceof Error ? err.message : String(err)}`;
|
|
518
541
|
}
|
|
519
|
-
function leakGuard(options) {
|
|
542
|
+
function leakGuard(options, session) {
|
|
520
543
|
let running = false;
|
|
521
544
|
let queued = false;
|
|
522
545
|
const run = () => {
|
|
@@ -526,9 +549,11 @@ function leakGuard(options) {
|
|
|
526
549
|
}
|
|
527
550
|
running = true;
|
|
528
551
|
buildClient({ ...options, minify: false })
|
|
552
|
+
.then(() => session.buildPassed())
|
|
529
553
|
.catch((err) => {
|
|
530
554
|
console.error(`\n[nifra/web/dev] client-leak guard failed:\n${buildFailureDetail(err)}\n` +
|
|
531
555
|
" The dev server is still running. This will fail `nifra build`.\n");
|
|
556
|
+
session.buildFailed(err, "client build failed (this will fail `nifra build`)");
|
|
532
557
|
})
|
|
533
558
|
.finally(() => {
|
|
534
559
|
running = false;
|