@rangojs/router 0.17.0 → 0.19.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 +3 -2
- package/dist/types/browser/cookie-name.d.ts +6 -0
- package/dist/types/browser/event-controller.d.ts +3 -3
- package/dist/types/browser/history-state.d.ts +18 -0
- package/dist/types/browser/navigation-transaction.d.ts +20 -2
- package/dist/types/browser/partial-update.d.ts +16 -1
- package/dist/types/browser/prefetch/cache.d.ts +6 -6
- package/dist/types/browser/react/Link.d.ts +19 -9
- package/dist/types/browser/react/context.d.ts +2 -2
- package/dist/types/browser/react/location-state-shared.d.ts +95 -56
- package/dist/types/browser/react/location-state.d.ts +1 -1
- package/dist/types/browser/transition-when.d.ts +80 -0
- package/dist/types/browser/types.d.ts +104 -9
- package/dist/types/build/generate-manifest.d.ts +8 -0
- package/dist/types/cache/background-task.d.ts +24 -2
- package/dist/types/cache/cache-exec-scope.d.ts +31 -0
- package/dist/types/cache/cache-key-utils.d.ts +48 -2
- package/dist/types/cache/cache-policy.d.ts +18 -1
- package/dist/types/cache/cache-runtime.d.ts +7 -0
- package/dist/types/cache/cache-scope.d.ts +192 -26
- package/dist/types/cache/cache-tag.d.ts +116 -11
- package/dist/types/cache/cf/cf-base64.d.ts +6 -0
- package/dist/types/cache/cf/cf-cache-constants.d.ts +11 -0
- package/dist/types/cache/cf/cf-cache-store.d.ts +224 -72
- package/dist/types/cache/cf/cf-cache-types.d.ts +31 -4
- package/dist/types/cache/cf/cf-shell-frame.d.ts +95 -0
- package/dist/types/cache/cf/cf-tag-marker-memo.d.ts +19 -0
- package/dist/types/cache/document-cache.d.ts +10 -0
- package/dist/types/cache/handle-snapshot.d.ts +41 -8
- package/dist/types/cache/index.d.ts +1 -0
- package/dist/types/cache/invalidation-order.d.ts +23 -0
- package/dist/types/cache/isolate-tag-memo.d.ts +149 -0
- package/dist/types/cache/request-tag-mask.d.ts +54 -0
- package/dist/types/cache/shell-memo.d.ts +178 -0
- package/dist/types/cache/shell-snapshot.d.ts +141 -105
- package/dist/types/cache/tag-invalidation.d.ts +54 -3
- package/dist/types/cache/types.d.ts +267 -96
- package/dist/types/cache/vercel/vercel-cache-store.d.ts +123 -18
- package/dist/types/client-urls/navigation.d.ts +28 -2
- package/dist/types/client-urls/server-projection.d.ts +5 -2
- package/dist/types/client-urls/types.d.ts +5 -5
- package/dist/types/client.d.ts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.rsc.d.ts +1 -1
- package/dist/types/prerender/build-shell-capture.d.ts +11 -4
- package/dist/types/route-definition/helpers-types.d.ts +11 -11
- package/dist/types/route-name.d.ts +7 -0
- package/dist/types/router/error-handling.d.ts +1 -1
- package/dist/types/router/instrument.d.ts +8 -0
- package/dist/types/router/intercept-resolution.d.ts +2 -0
- package/dist/types/router/match-context.d.ts +5 -0
- package/dist/types/router/match-middleware/background-revalidation.d.ts +0 -4
- package/dist/types/router/middleware-types.d.ts +6 -1
- package/dist/types/router/router-options.d.ts +4 -1
- package/dist/types/router/segment-resolution/loader-cache.d.ts +58 -12
- package/dist/types/router/segment-resolution/loader-mask.d.ts +3 -4
- package/dist/types/router/segment-resolution/loader-snapshot.d.ts +33 -48
- package/dist/types/router/segment-resolution/mask-nested.d.ts +73 -24
- package/dist/types/router/segment-resolution/view-transition-default.d.ts +7 -5
- package/dist/types/router/transition-when.d.ts +24 -10
- package/dist/types/rsc/attach-transition-when.d.ts +18 -0
- package/dist/types/rsc/full-payload.d.ts +21 -0
- package/dist/types/rsc/handler.d.ts +1 -1
- package/dist/types/rsc/response-cache-serve.d.ts +15 -12
- package/dist/types/rsc/shell-build-manifest.d.ts +12 -3
- package/dist/types/rsc/shell-capture-constants.d.ts +116 -12
- package/dist/types/rsc/shell-capture.d.ts +202 -74
- package/dist/types/rsc/shell-serve.d.ts +144 -50
- package/dist/types/rsc/types.d.ts +9 -0
- package/dist/types/segment-system.d.ts +7 -0
- package/dist/types/server/context.d.ts +155 -33
- package/dist/types/server/cookie-store.d.ts +33 -0
- package/dist/types/server/handle-store.d.ts +52 -1
- package/dist/types/server/request-context.d.ts +210 -63
- package/dist/types/server/request-headers.d.ts +44 -0
- package/dist/types/server.d.ts +1 -0
- package/dist/types/ssr/index.d.ts +9 -0
- package/dist/types/ssr/ssr-root.d.ts +9 -8
- package/dist/types/testing/e2e/index.d.ts +1 -1
- package/dist/types/testing/flight.entry.d.ts +7 -0
- package/dist/types/testing/index.d.ts +3 -2
- package/dist/types/testing/internal/action-id.d.ts +7 -0
- package/dist/types/testing/location-state-key.d.ts +24 -0
- package/dist/types/testing/render-route.d.ts +17 -1
- package/dist/types/testing/run-loader.d.ts +18 -3
- package/dist/types/testing/run-transition-when.d.ts +44 -69
- package/dist/types/testing/serve-shell-request.d.ts +133 -0
- package/dist/types/testing/shell-status.d.ts +44 -19
- package/dist/types/transition-when-ref.d.ts +79 -0
- package/dist/types/types/cache-types.d.ts +15 -3
- package/dist/types/types/handler-context.d.ts +14 -1
- package/dist/types/types/index.d.ts +1 -1
- package/dist/types/types/segments.d.ts +86 -71
- package/dist/types/urls/path-helper-types.d.ts +3 -4
- package/dist/types/urls/pattern-types.d.ts +21 -18
- package/dist/types/vite/plugins/transition-when-hoist.d.ts +45 -0
- package/dist/types/vite/router-discovery.d.ts +29 -2
- package/dist/vite/index.js +1005 -105
- package/package.json +1 -1
- package/skills/breadcrumbs/SKILL.md +17 -7
- package/skills/cache-guide/SKILL.md +175 -76
- package/skills/caching/SKILL.md +361 -33
- package/skills/catalog.json +1 -1
- package/skills/client-urls/SKILL.md +12 -7
- package/skills/cloudflare/SKILL.md +15 -0
- package/skills/comparison/references/framework-comparison.md +52 -37
- package/skills/defer-hydration/SKILL.md +50 -30
- package/skills/deployment-caching/SKILL.md +5 -2
- package/skills/document-cache/SKILL.md +32 -2
- package/skills/handler-use/SKILL.md +2 -0
- package/skills/hooks/SKILL.md +3 -1
- package/skills/hooks/handle-and-actions.md +3 -1
- package/skills/hooks/navigation.md +23 -2
- package/skills/hooks/state.md +101 -7
- package/skills/intercept/SKILL.md +29 -12
- package/skills/loader/SKILL.md +197 -44
- package/skills/middleware/SKILL.md +34 -9
- package/skills/migrate-nextjs/SKILL.md +68 -37
- package/skills/migrate-react-router/SKILL.md +2 -1
- package/skills/migrate-react-router/component-migration.md +3 -1
- package/skills/migrate-react-router/data-and-actions.md +3 -1
- package/skills/migrate-react-router/route-mapping.md +7 -4
- package/skills/observability/SKILL.md +65 -0
- package/skills/parallel/SKILL.md +13 -8
- package/skills/ppr/SKILL.md +715 -371
- package/skills/prerender/SKILL.md +30 -17
- package/skills/rango/SKILL.md +72 -34
- package/skills/route/SKILL.md +14 -7
- package/skills/router-setup/SKILL.md +4 -2
- package/skills/scripts/SKILL.md +8 -1
- package/skills/server-actions/SKILL.md +11 -0
- package/skills/shell-manifest/SKILL.md +21 -12
- package/skills/testing/SKILL.md +49 -43
- package/skills/testing/cache-prerender.md +15 -14
- package/skills/testing/client-components.md +45 -3
- package/skills/testing/loader.md +19 -1
- package/skills/testing/middleware.md +1 -0
- package/skills/testing/predicates.md +49 -49
- package/skills/testing/render-handler.md +1 -0
- package/skills/testing/serve-shell-request.md +202 -0
- package/skills/testing/server-actions.md +9 -3
- package/skills/theme/SKILL.md +56 -4
- package/skills/typesafety/env-and-bindings.md +18 -2
- package/skills/use-cache/SKILL.md +91 -23
- package/skills/vercel/SKILL.md +14 -2
- package/skills/view-transitions/SKILL.md +150 -29
- package/src/__augment-tests__/augmented.check.ts +23 -0
- package/src/browser/cookie-name.ts +23 -0
- package/src/browser/event-controller.ts +4 -4
- package/src/browser/history-state.ts +75 -1
- package/src/browser/link-interceptor.ts +4 -0
- package/src/browser/navigation-bridge.ts +77 -18
- package/src/browser/navigation-client.ts +4 -3
- package/src/browser/navigation-store.ts +43 -1
- package/src/browser/navigation-transaction.ts +31 -11
- package/src/browser/partial-update.ts +146 -35
- package/src/browser/prefetch/cache.ts +6 -6
- package/src/browser/prefetch/fetch.ts +2 -2
- package/src/browser/react/Link.tsx +38 -33
- package/src/browser/react/NavigationProvider.tsx +2 -2
- package/src/browser/react/context.ts +2 -2
- package/src/browser/react/location-state-shared.ts +241 -49
- package/src/browser/react/location-state.ts +5 -2
- package/src/browser/rsc-router.tsx +9 -0
- package/src/browser/server-action-bridge.ts +84 -15
- package/src/browser/transition-when.ts +205 -0
- package/src/browser/types.ts +124 -10
- package/src/build/generate-manifest.ts +77 -1
- package/src/cache/background-task.ts +55 -2
- package/src/cache/cache-exec-scope.ts +48 -1
- package/src/cache/cache-key-utils.ts +62 -2
- package/src/cache/cache-policy.ts +31 -4
- package/src/cache/cache-runtime.ts +209 -129
- package/src/cache/cache-scope.ts +573 -69
- package/src/cache/cache-tag.ts +475 -19
- package/src/cache/cf/cf-base64.ts +36 -4
- package/src/cache/cf/cf-cache-constants.ts +12 -0
- package/src/cache/cf/cf-cache-store.ts +1094 -376
- package/src/cache/cf/cf-cache-types.ts +32 -4
- package/src/cache/cf/cf-shell-frame.ts +258 -0
- package/src/cache/cf/cf-tag-marker-memo.ts +55 -40
- package/src/cache/document-cache.ts +53 -7
- package/src/cache/handle-snapshot.ts +53 -9
- package/src/cache/index.ts +2 -0
- package/src/cache/invalidation-order.ts +84 -0
- package/src/cache/isolate-tag-memo.ts +308 -0
- package/src/cache/request-tag-mask.ts +147 -0
- package/src/cache/shell-memo.ts +341 -0
- package/src/cache/shell-snapshot.ts +249 -277
- package/src/cache/tag-invalidation.ts +109 -18
- package/src/cache/types.ts +274 -102
- package/src/cache/vercel/vercel-cache-store.ts +561 -74
- package/src/client-urls/client-root.tsx +8 -4
- package/src/client-urls/client-urls.ts +8 -6
- package/src/client-urls/navigation.ts +55 -4
- package/src/client-urls/server-projection.ts +31 -10
- package/src/client-urls/types.ts +12 -5
- package/src/client.tsx +2 -0
- package/src/host/cookie-handler.ts +2 -1
- package/src/index.rsc.ts +3 -0
- package/src/index.ts +3 -0
- package/src/loader-redirect.tsx +7 -3
- package/src/prerender/build-shell-capture.ts +173 -110
- package/src/route-definition/dsl-helpers.ts +6 -3
- package/src/route-definition/helpers-types.ts +11 -11
- package/src/route-name.ts +12 -0
- package/src/router/content-negotiation.ts +4 -1
- package/src/router/error-handling.ts +5 -2
- package/src/router/handler-context.ts +42 -5
- package/src/router/instrument.ts +54 -2
- package/src/router/intercept-resolution.ts +30 -8
- package/src/router/loader-resolution.ts +89 -33
- package/src/router/logging.ts +5 -3
- package/src/router/match-api.ts +89 -42
- package/src/router/match-context.ts +5 -0
- package/src/router/match-handlers.ts +14 -29
- package/src/router/match-middleware/background-revalidation.ts +3 -5
- package/src/router/match-middleware/cache-lookup.ts +52 -19
- package/src/router/match-middleware/cache-store.ts +36 -10
- package/src/router/match-result.ts +1 -0
- package/src/router/middleware-types.ts +6 -1
- package/src/router/middleware.ts +20 -4
- package/src/router/navigation-snapshot.ts +6 -5
- package/src/router/prerender-match.ts +10 -0
- package/src/router/request-classification.ts +7 -4
- package/src/router/router-options.ts +4 -1
- package/src/router/segment-resolution/fresh.ts +18 -13
- package/src/router/segment-resolution/helpers.ts +4 -2
- package/src/router/segment-resolution/loader-cache.ts +366 -70
- package/src/router/segment-resolution/loader-mask.ts +3 -4
- package/src/router/segment-resolution/loader-snapshot.ts +215 -126
- package/src/router/segment-resolution/mask-nested.ts +161 -42
- package/src/router/segment-resolution/revalidation.ts +27 -13
- package/src/router/segment-resolution/view-transition-default.ts +6 -21
- package/src/router/telemetry.ts +6 -3
- package/src/router/transition-when.ts +34 -52
- package/src/router.ts +2 -1
- package/src/rsc/attach-transition-when.ts +47 -0
- package/src/rsc/full-payload.ts +47 -3
- package/src/rsc/handler.ts +24 -10
- package/src/rsc/loader-fetch.ts +2 -1
- package/src/rsc/manifest-init.ts +4 -0
- package/src/rsc/origin-guard.ts +8 -5
- package/src/rsc/progressive-enhancement.ts +10 -32
- package/src/rsc/response-cache-serve.ts +69 -78
- package/src/rsc/response-route-handler.ts +2 -2
- package/src/rsc/rsc-rendering.ts +712 -338
- package/src/rsc/server-action.ts +8 -20
- package/src/rsc/shell-build-manifest.ts +49 -29
- package/src/rsc/shell-capture-constants.ts +182 -12
- package/src/rsc/shell-capture.ts +1126 -612
- package/src/rsc/shell-serve.ts +331 -85
- package/src/rsc/ssr-setup.ts +3 -2
- package/src/rsc/types.ts +9 -0
- package/src/segment-system.tsx +40 -7
- package/src/server/context.ts +328 -72
- package/src/server/cookie-store.ts +184 -133
- package/src/server/handle-store.ts +245 -27
- package/src/server/request-context.ts +364 -100
- package/src/server/request-headers.ts +134 -0
- package/src/server.ts +4 -0
- package/src/ssr/index.tsx +96 -37
- package/src/ssr/ssr-root.tsx +9 -8
- package/src/testing/dispatch.ts +4 -7
- package/src/testing/e2e/index.ts +1 -0
- package/src/testing/flight.entry.ts +14 -0
- package/src/testing/index.ts +5 -0
- package/src/testing/internal/action-id.ts +25 -0
- package/src/testing/internal/context.ts +1 -1
- package/src/testing/location-state-key.ts +45 -0
- package/src/testing/render-handler.ts +1 -1
- package/src/testing/render-route.tsx +109 -16
- package/src/testing/run-client-revalidate.ts +3 -19
- package/src/testing/run-loader.ts +67 -5
- package/src/testing/run-transition-when.ts +109 -172
- package/src/testing/serve-shell-request.ts +381 -0
- package/src/testing/shell-status.ts +73 -47
- package/src/theme/ThemeProvider.tsx +7 -6
- package/src/transition-when-ref.ts +220 -0
- package/src/types/cache-types.ts +15 -3
- package/src/types/handler-context.ts +14 -1
- package/src/types/index.ts +3 -0
- package/src/types/segments.ts +94 -91
- package/src/urls/path-helper-types.ts +3 -4
- package/src/urls/pattern-types.ts +21 -18
- package/src/vite/discovery/discover-routers.ts +3 -0
- package/src/vite/discovery/shell-prerender-phase.ts +9 -2
- package/src/vite/discovery/virtual-module-codegen.ts +16 -6
- package/src/vite/plugins/transition-when-hoist.ts +1064 -0
- package/src/vite/rango.ts +2 -0
- package/src/vite/router-discovery.ts +89 -9
- package/dist/types/rsc/transition-gate.d.ts +0 -23
- package/src/rsc/transition-gate.ts +0 -86
package/dist/vite/index.js
CHANGED
|
@@ -1587,10 +1587,10 @@ import path4 from "node:path";
|
|
|
1587
1587
|
function isDirectivePrologueStatement(node) {
|
|
1588
1588
|
return node?.type === "ExpressionStatement" && typeof node.directive === "string";
|
|
1589
1589
|
}
|
|
1590
|
-
function findImportInsertionPos(code,
|
|
1590
|
+
function findImportInsertionPos(code, parseAst7) {
|
|
1591
1591
|
let program;
|
|
1592
1592
|
try {
|
|
1593
|
-
program =
|
|
1593
|
+
program = parseAst7(code, { lang: "tsx" });
|
|
1594
1594
|
} catch {
|
|
1595
1595
|
return 0;
|
|
1596
1596
|
}
|
|
@@ -1627,10 +1627,10 @@ function walkNode(node, parent, ancestors, enter) {
|
|
|
1627
1627
|
}
|
|
1628
1628
|
ancestors.pop();
|
|
1629
1629
|
}
|
|
1630
|
-
function findHandlerCalls(code, fnName,
|
|
1630
|
+
function findHandlerCalls(code, fnName, parseAst7) {
|
|
1631
1631
|
let program;
|
|
1632
1632
|
try {
|
|
1633
|
-
program =
|
|
1633
|
+
program = parseAst7(code, { lang: "tsx" });
|
|
1634
1634
|
} catch {
|
|
1635
1635
|
return [];
|
|
1636
1636
|
}
|
|
@@ -1702,18 +1702,18 @@ function getImportedLocalNamesFromProgram(program, importedName) {
|
|
|
1702
1702
|
}
|
|
1703
1703
|
return localNames;
|
|
1704
1704
|
}
|
|
1705
|
-
function getImportedLocalNames(code, importedName,
|
|
1705
|
+
function getImportedLocalNames(code, importedName, parseAst7) {
|
|
1706
1706
|
try {
|
|
1707
|
-
const program =
|
|
1707
|
+
const program = parseAst7(code, { lang: "tsx" });
|
|
1708
1708
|
return getImportedLocalNamesFromProgram(program, importedName);
|
|
1709
1709
|
} catch {
|
|
1710
1710
|
return /* @__PURE__ */ new Set();
|
|
1711
1711
|
}
|
|
1712
1712
|
}
|
|
1713
|
-
function extractImportDeclarations(code,
|
|
1713
|
+
function extractImportDeclarations(code, parseAst7) {
|
|
1714
1714
|
let program;
|
|
1715
1715
|
try {
|
|
1716
|
-
program =
|
|
1716
|
+
program = parseAst7(code, { lang: "tsx" });
|
|
1717
1717
|
} catch {
|
|
1718
1718
|
return [];
|
|
1719
1719
|
}
|
|
@@ -1770,10 +1770,10 @@ function isSafeVariableDeclaration(node, handlerNames) {
|
|
|
1770
1770
|
(d) => isSafeDeclaratorInit(d.init) && !(d.init?.type === "CallExpression" && d.init.callee?.type === "Identifier" && handlerNames.has(d.init.callee.name))
|
|
1771
1771
|
);
|
|
1772
1772
|
}
|
|
1773
|
-
function extractModuleLevelDeclarations(code,
|
|
1773
|
+
function extractModuleLevelDeclarations(code, parseAst7, handlerNames) {
|
|
1774
1774
|
let program;
|
|
1775
1775
|
try {
|
|
1776
|
-
program =
|
|
1776
|
+
program = parseAst7(code, { lang: "tsx" });
|
|
1777
1777
|
} catch {
|
|
1778
1778
|
return [];
|
|
1779
1779
|
}
|
|
@@ -1804,17 +1804,17 @@ function extractModuleLevelDeclarations(code, parseAst6, handlerNames) {
|
|
|
1804
1804
|
}
|
|
1805
1805
|
return declarations;
|
|
1806
1806
|
}
|
|
1807
|
-
function transformInlineHandlers(fnName, virtualPrefix, s, code, filePath, virtualRegistry, moduleId,
|
|
1808
|
-
const sites = findHandlerCalls(code, fnName,
|
|
1807
|
+
function transformInlineHandlers(fnName, virtualPrefix, s, code, filePath, virtualRegistry, moduleId, parseAst7) {
|
|
1808
|
+
const sites = findHandlerCalls(code, fnName, parseAst7);
|
|
1809
1809
|
const inlineSites = sites.filter((site) => site.exportInfo === null);
|
|
1810
1810
|
if (inlineSites.length === 0) return false;
|
|
1811
|
-
const imports = extractImportDeclarations(code,
|
|
1812
|
-
const staticNames = getImportedLocalNames(code, "Static",
|
|
1813
|
-
const prerenderNames = getImportedLocalNames(code, "Prerender",
|
|
1811
|
+
const imports = extractImportDeclarations(code, parseAst7);
|
|
1812
|
+
const staticNames = getImportedLocalNames(code, "Static", parseAst7);
|
|
1813
|
+
const prerenderNames = getImportedLocalNames(code, "Prerender", parseAst7);
|
|
1814
1814
|
const handlerNames = /* @__PURE__ */ new Set([...staticNames, ...prerenderNames]);
|
|
1815
1815
|
const declarations = extractModuleLevelDeclarations(
|
|
1816
1816
|
code,
|
|
1817
|
-
|
|
1817
|
+
parseAst7,
|
|
1818
1818
|
handlerNames
|
|
1819
1819
|
);
|
|
1820
1820
|
const importStatements = [];
|
|
@@ -1837,7 +1837,7 @@ function transformInlineHandlers(fnName, virtualPrefix, s, code, filePath, virtu
|
|
|
1837
1837
|
}
|
|
1838
1838
|
if (importStatements.length > 0) {
|
|
1839
1839
|
const importBlock = importStatements.join("\n") + "\n";
|
|
1840
|
-
const insertionPos = findImportInsertionPos(code,
|
|
1840
|
+
const insertionPos = findImportInsertionPos(code, parseAst7);
|
|
1841
1841
|
if (insertionPos === 0) {
|
|
1842
1842
|
s.prepend(importBlock);
|
|
1843
1843
|
} else {
|
|
@@ -3103,8 +3103,8 @@ async function transformUseCache(code, id, options) {
|
|
|
3103
3103
|
const { hasDirective: hasDirective2, transformWrapExport, transformHoistInlineDirective } = rscTransforms;
|
|
3104
3104
|
let ast;
|
|
3105
3105
|
try {
|
|
3106
|
-
const { parseAst:
|
|
3107
|
-
ast =
|
|
3106
|
+
const { parseAst: parseAst7 } = await import("vite");
|
|
3107
|
+
ast = parseAst7(code, { lang: "tsx" });
|
|
3108
3108
|
} catch {
|
|
3109
3109
|
return;
|
|
3110
3110
|
}
|
|
@@ -3163,8 +3163,8 @@ async function transformFileLevelUseCache(code, ast, filePath, sourceId, isBuild
|
|
|
3163
3163
|
);
|
|
3164
3164
|
}
|
|
3165
3165
|
if (exportNames.length === 0) {
|
|
3166
|
-
const { default:
|
|
3167
|
-
const s = new
|
|
3166
|
+
const { default: MagicString5 } = await import("magic-string");
|
|
3167
|
+
const s = new MagicString5(code);
|
|
3168
3168
|
const directive2 = findFileLevelDirective(ast);
|
|
3169
3169
|
if (directive2) {
|
|
3170
3170
|
s.overwrite(
|
|
@@ -3288,6 +3288,782 @@ function warnOnNearMissDirectives(ast, fileId, warn) {
|
|
|
3288
3288
|
}
|
|
3289
3289
|
}
|
|
3290
3290
|
|
|
3291
|
+
// src/vite/plugins/transition-when-hoist.ts
|
|
3292
|
+
import { normalizePath as normalizePath2, parseAst as parseAst3 } from "vite";
|
|
3293
|
+
import MagicString4 from "magic-string";
|
|
3294
|
+
import { builtinModules } from "node:module";
|
|
3295
|
+
import { readFile } from "node:fs/promises";
|
|
3296
|
+
|
|
3297
|
+
// src/route-name.ts
|
|
3298
|
+
var AUTO_GENERATED_ROUTE_PREFIX = "$path_";
|
|
3299
|
+
var INTERNAL_INCLUDE_SCOPE_PREFIX = "$prefix_";
|
|
3300
|
+
function isAutoGeneratedRouteName(name) {
|
|
3301
|
+
return name.split(".").some((segment) => {
|
|
3302
|
+
return segment.startsWith(AUTO_GENERATED_ROUTE_PREFIX) || segment.startsWith(INTERNAL_INCLUDE_SCOPE_PREFIX);
|
|
3303
|
+
});
|
|
3304
|
+
}
|
|
3305
|
+
|
|
3306
|
+
// src/transition-when-ref.ts
|
|
3307
|
+
var TransitionWhenError = class extends Error {
|
|
3308
|
+
constructor() {
|
|
3309
|
+
super(...arguments);
|
|
3310
|
+
this.name = "TransitionWhenError";
|
|
3311
|
+
}
|
|
3312
|
+
};
|
|
3313
|
+
function findTransitionWhenError(error) {
|
|
3314
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3315
|
+
let current = error;
|
|
3316
|
+
while (typeof current === "object" && current !== null && !seen.has(current)) {
|
|
3317
|
+
seen.add(current);
|
|
3318
|
+
if (current.name === "TransitionWhenError") {
|
|
3319
|
+
return current;
|
|
3320
|
+
}
|
|
3321
|
+
current = current.cause;
|
|
3322
|
+
}
|
|
3323
|
+
return void 0;
|
|
3324
|
+
}
|
|
3325
|
+
|
|
3326
|
+
// src/vite/plugins/transition-when-hoist.ts
|
|
3327
|
+
var TRANSITION_WHEN_QUERY = "rango-when";
|
|
3328
|
+
var EXPORT_NAME = "__rango_when";
|
|
3329
|
+
var LOCAL_PREFIX = "__rango_when_";
|
|
3330
|
+
var Scope = class {
|
|
3331
|
+
constructor(parent, isFunction, node) {
|
|
3332
|
+
this.parent = parent;
|
|
3333
|
+
this.isFunction = isFunction;
|
|
3334
|
+
this.node = node;
|
|
3335
|
+
this.declarations = /* @__PURE__ */ new Set();
|
|
3336
|
+
}
|
|
3337
|
+
nearestFunction() {
|
|
3338
|
+
return this.isFunction || !this.parent ? this : this.parent.nearestFunction();
|
|
3339
|
+
}
|
|
3340
|
+
lookup(name) {
|
|
3341
|
+
if (this.declarations.has(name)) return this;
|
|
3342
|
+
return this.parent ? this.parent.lookup(name) : null;
|
|
3343
|
+
}
|
|
3344
|
+
};
|
|
3345
|
+
var TYPE_KEYS = /* @__PURE__ */ new Set([
|
|
3346
|
+
"typeAnnotation",
|
|
3347
|
+
"returnType",
|
|
3348
|
+
"typeParameters",
|
|
3349
|
+
"typeArguments",
|
|
3350
|
+
"superTypeArguments",
|
|
3351
|
+
"implements"
|
|
3352
|
+
]);
|
|
3353
|
+
function jsxNameReference(name) {
|
|
3354
|
+
if (name?.type === "JSXIdentifier") {
|
|
3355
|
+
return /^[a-z]/.test(name.name) || name.name.includes("-") ? null : name;
|
|
3356
|
+
}
|
|
3357
|
+
let root = name;
|
|
3358
|
+
while (root?.type === "JSXMemberExpression") root = root.object;
|
|
3359
|
+
return root?.type === "JSXIdentifier" && root.name !== "this" ? root : null;
|
|
3360
|
+
}
|
|
3361
|
+
function patternNames(pattern, names = []) {
|
|
3362
|
+
if (!pattern) return names;
|
|
3363
|
+
switch (pattern.type) {
|
|
3364
|
+
case "Identifier":
|
|
3365
|
+
names.push(pattern.name);
|
|
3366
|
+
break;
|
|
3367
|
+
case "ObjectPattern":
|
|
3368
|
+
for (const prop of pattern.properties) {
|
|
3369
|
+
patternNames(prop.type === "RestElement" ? prop : prop.value, names);
|
|
3370
|
+
}
|
|
3371
|
+
break;
|
|
3372
|
+
case "ArrayPattern":
|
|
3373
|
+
for (const element of pattern.elements) patternNames(element, names);
|
|
3374
|
+
break;
|
|
3375
|
+
case "RestElement":
|
|
3376
|
+
patternNames(pattern.argument, names);
|
|
3377
|
+
break;
|
|
3378
|
+
case "AssignmentPattern":
|
|
3379
|
+
patternNames(pattern.left, names);
|
|
3380
|
+
break;
|
|
3381
|
+
case "TSParameterProperty":
|
|
3382
|
+
patternNames(pattern.parameter, names);
|
|
3383
|
+
break;
|
|
3384
|
+
}
|
|
3385
|
+
return names;
|
|
3386
|
+
}
|
|
3387
|
+
function analyzeScopes(program) {
|
|
3388
|
+
const moduleScope = new Scope(null, true, program);
|
|
3389
|
+
const scopeOf = /* @__PURE__ */ new Map([[program, moduleScope]]);
|
|
3390
|
+
const references = [];
|
|
3391
|
+
const declarePattern = (pattern, scope) => {
|
|
3392
|
+
for (const name of patternNames(pattern)) scope.declarations.add(name);
|
|
3393
|
+
};
|
|
3394
|
+
const walkPattern = (pattern, scope, typeOnly) => {
|
|
3395
|
+
if (!pattern) return;
|
|
3396
|
+
switch (pattern.type) {
|
|
3397
|
+
case "Identifier":
|
|
3398
|
+
if (pattern.typeAnnotation) walk2(pattern.typeAnnotation, scope, true);
|
|
3399
|
+
return;
|
|
3400
|
+
case "ObjectPattern":
|
|
3401
|
+
for (const prop of pattern.properties) {
|
|
3402
|
+
if (prop.type === "RestElement") {
|
|
3403
|
+
walkPattern(prop.argument, scope, typeOnly);
|
|
3404
|
+
} else {
|
|
3405
|
+
if (prop.computed) walk2(prop.key, scope, typeOnly);
|
|
3406
|
+
walkPattern(prop.value, scope, typeOnly);
|
|
3407
|
+
}
|
|
3408
|
+
}
|
|
3409
|
+
if (pattern.typeAnnotation) walk2(pattern.typeAnnotation, scope, true);
|
|
3410
|
+
return;
|
|
3411
|
+
case "ArrayPattern":
|
|
3412
|
+
for (const element of pattern.elements) {
|
|
3413
|
+
walkPattern(element, scope, typeOnly);
|
|
3414
|
+
}
|
|
3415
|
+
if (pattern.typeAnnotation) walk2(pattern.typeAnnotation, scope, true);
|
|
3416
|
+
return;
|
|
3417
|
+
case "RestElement":
|
|
3418
|
+
walkPattern(pattern.argument, scope, typeOnly);
|
|
3419
|
+
return;
|
|
3420
|
+
case "AssignmentPattern":
|
|
3421
|
+
walkPattern(pattern.left, scope, typeOnly);
|
|
3422
|
+
walk2(pattern.right, scope, typeOnly);
|
|
3423
|
+
return;
|
|
3424
|
+
case "TSParameterProperty":
|
|
3425
|
+
walkPattern(pattern.parameter, scope, typeOnly);
|
|
3426
|
+
return;
|
|
3427
|
+
default:
|
|
3428
|
+
walk2(pattern, scope, typeOnly);
|
|
3429
|
+
}
|
|
3430
|
+
};
|
|
3431
|
+
const hoistDeclarations = (statements, scope) => {
|
|
3432
|
+
for (const statement of statements) {
|
|
3433
|
+
const node = statement.type === "ExportNamedDeclaration" || statement.type === "ExportDefaultDeclaration" ? statement.declaration : statement;
|
|
3434
|
+
if (!node) continue;
|
|
3435
|
+
switch (node.type) {
|
|
3436
|
+
case "ImportDeclaration":
|
|
3437
|
+
for (const spec of node.specifiers) {
|
|
3438
|
+
scope.declarations.add(spec.local.name);
|
|
3439
|
+
}
|
|
3440
|
+
break;
|
|
3441
|
+
case "FunctionDeclaration":
|
|
3442
|
+
case "ClassDeclaration":
|
|
3443
|
+
case "TSEnumDeclaration":
|
|
3444
|
+
case "TSTypeAliasDeclaration":
|
|
3445
|
+
case "TSInterfaceDeclaration":
|
|
3446
|
+
case "TSModuleDeclaration":
|
|
3447
|
+
if (node.id?.type === "Identifier") {
|
|
3448
|
+
scope.declarations.add(node.id.name);
|
|
3449
|
+
}
|
|
3450
|
+
break;
|
|
3451
|
+
case "VariableDeclaration":
|
|
3452
|
+
for (const declarator of node.declarations) {
|
|
3453
|
+
declarePattern(
|
|
3454
|
+
declarator.id,
|
|
3455
|
+
node.kind === "var" ? scope.nearestFunction() : scope
|
|
3456
|
+
);
|
|
3457
|
+
}
|
|
3458
|
+
break;
|
|
3459
|
+
}
|
|
3460
|
+
}
|
|
3461
|
+
};
|
|
3462
|
+
const walk2 = (node, scope, typeOnly) => {
|
|
3463
|
+
if (!node || typeof node !== "object") return;
|
|
3464
|
+
if (Array.isArray(node)) {
|
|
3465
|
+
for (const item of node) walk2(item, scope, typeOnly);
|
|
3466
|
+
return;
|
|
3467
|
+
}
|
|
3468
|
+
if (typeof node.type !== "string") return;
|
|
3469
|
+
switch (node.type) {
|
|
3470
|
+
case "Identifier":
|
|
3471
|
+
references.push({ node, scope, typeOnly });
|
|
3472
|
+
if (node.typeAnnotation) walk2(node.typeAnnotation, scope, true);
|
|
3473
|
+
return;
|
|
3474
|
+
case "ImportDeclaration":
|
|
3475
|
+
case "ExportAllDeclaration":
|
|
3476
|
+
return;
|
|
3477
|
+
case "ExportNamedDeclaration":
|
|
3478
|
+
if (node.declaration) walk2(node.declaration, scope, typeOnly);
|
|
3479
|
+
else if (!node.source) {
|
|
3480
|
+
for (const spec of node.specifiers) {
|
|
3481
|
+
walk2(spec.local, scope, typeOnly || node.exportKind === "type");
|
|
3482
|
+
}
|
|
3483
|
+
}
|
|
3484
|
+
return;
|
|
3485
|
+
case "MemberExpression":
|
|
3486
|
+
walk2(node.object, scope, typeOnly);
|
|
3487
|
+
if (node.computed) walk2(node.property, scope, typeOnly);
|
|
3488
|
+
return;
|
|
3489
|
+
case "Property":
|
|
3490
|
+
case "MethodDefinition":
|
|
3491
|
+
case "PropertyDefinition":
|
|
3492
|
+
case "TSPropertySignature":
|
|
3493
|
+
case "TSMethodSignature":
|
|
3494
|
+
if (node.computed) walk2(node.key, scope, typeOnly);
|
|
3495
|
+
walk2(node.value, scope, typeOnly);
|
|
3496
|
+
if (node.typeAnnotation) walk2(node.typeAnnotation, scope, true);
|
|
3497
|
+
return;
|
|
3498
|
+
case "LabeledStatement":
|
|
3499
|
+
walk2(node.body, scope, typeOnly);
|
|
3500
|
+
return;
|
|
3501
|
+
case "BreakStatement":
|
|
3502
|
+
case "ContinueStatement":
|
|
3503
|
+
case "MetaProperty":
|
|
3504
|
+
return;
|
|
3505
|
+
case "JSXOpeningElement":
|
|
3506
|
+
case "JSXClosingElement": {
|
|
3507
|
+
const ref = jsxNameReference(node.name);
|
|
3508
|
+
if (ref) references.push({ node: ref, scope, typeOnly });
|
|
3509
|
+
walk2(node.typeArguments, scope, true);
|
|
3510
|
+
walk2(node.attributes, scope, typeOnly);
|
|
3511
|
+
return;
|
|
3512
|
+
}
|
|
3513
|
+
case "TSQualifiedName":
|
|
3514
|
+
walk2(node.left, scope, typeOnly);
|
|
3515
|
+
return;
|
|
3516
|
+
case "TSEnumMember":
|
|
3517
|
+
walk2(node.initializer, scope, typeOnly);
|
|
3518
|
+
return;
|
|
3519
|
+
case "TSTypeAliasDeclaration":
|
|
3520
|
+
case "TSInterfaceDeclaration":
|
|
3521
|
+
walk2(node.typeParameters, scope, true);
|
|
3522
|
+
walk2(node.typeAnnotation ?? node.body, scope, true);
|
|
3523
|
+
walk2(node.extends, scope, true);
|
|
3524
|
+
return;
|
|
3525
|
+
case "VariableDeclarator":
|
|
3526
|
+
walkPattern(node.id, scope, typeOnly);
|
|
3527
|
+
walk2(node.init, scope, typeOnly);
|
|
3528
|
+
return;
|
|
3529
|
+
case "FunctionDeclaration":
|
|
3530
|
+
case "FunctionExpression":
|
|
3531
|
+
case "ArrowFunctionExpression": {
|
|
3532
|
+
const fnScope = new Scope(scope, true, node);
|
|
3533
|
+
scopeOf.set(node, fnScope);
|
|
3534
|
+
if (node.type === "FunctionExpression" && node.id) {
|
|
3535
|
+
fnScope.declarations.add(node.id.name);
|
|
3536
|
+
}
|
|
3537
|
+
for (const param of node.params) declarePattern(param, fnScope);
|
|
3538
|
+
walk2(node.typeParameters, fnScope, true);
|
|
3539
|
+
for (const param of node.params) walkPattern(param, fnScope, typeOnly);
|
|
3540
|
+
walk2(node.returnType, fnScope, true);
|
|
3541
|
+
if (node.body?.type === "BlockStatement") {
|
|
3542
|
+
hoistDeclarations(node.body.body, fnScope);
|
|
3543
|
+
walk2(node.body.body, fnScope, typeOnly);
|
|
3544
|
+
} else {
|
|
3545
|
+
walk2(node.body, fnScope, typeOnly);
|
|
3546
|
+
}
|
|
3547
|
+
return;
|
|
3548
|
+
}
|
|
3549
|
+
case "ClassDeclaration":
|
|
3550
|
+
case "ClassExpression": {
|
|
3551
|
+
let classScope = scope;
|
|
3552
|
+
if (node.type === "ClassExpression" && node.id) {
|
|
3553
|
+
classScope = new Scope(scope, false, node);
|
|
3554
|
+
classScope.declarations.add(node.id.name);
|
|
3555
|
+
scopeOf.set(node, classScope);
|
|
3556
|
+
}
|
|
3557
|
+
walk2(node.superClass, classScope, typeOnly);
|
|
3558
|
+
walk2(node.superTypeArguments, classScope, true);
|
|
3559
|
+
walk2(node.typeParameters, classScope, true);
|
|
3560
|
+
walk2(node.implements, classScope, true);
|
|
3561
|
+
walk2(node.body, classScope, typeOnly);
|
|
3562
|
+
return;
|
|
3563
|
+
}
|
|
3564
|
+
case "BlockStatement":
|
|
3565
|
+
case "StaticBlock": {
|
|
3566
|
+
const blockScope = new Scope(scope, false, node);
|
|
3567
|
+
scopeOf.set(node, blockScope);
|
|
3568
|
+
hoistDeclarations(node.body, blockScope);
|
|
3569
|
+
walk2(node.body, blockScope, typeOnly);
|
|
3570
|
+
return;
|
|
3571
|
+
}
|
|
3572
|
+
case "ForStatement":
|
|
3573
|
+
case "ForInStatement":
|
|
3574
|
+
case "ForOfStatement": {
|
|
3575
|
+
const loopScope = new Scope(scope, false, node);
|
|
3576
|
+
scopeOf.set(node, loopScope);
|
|
3577
|
+
const head = node.type === "ForStatement" ? node.init : node.left;
|
|
3578
|
+
if (head?.type === "VariableDeclaration") {
|
|
3579
|
+
hoistDeclarations([head], loopScope);
|
|
3580
|
+
}
|
|
3581
|
+
for (const key of ["init", "left", "right", "test", "update", "body"]) {
|
|
3582
|
+
walk2(node[key], loopScope, typeOnly);
|
|
3583
|
+
}
|
|
3584
|
+
return;
|
|
3585
|
+
}
|
|
3586
|
+
case "SwitchStatement": {
|
|
3587
|
+
walk2(node.discriminant, scope, typeOnly);
|
|
3588
|
+
const switchScope = new Scope(scope, false, node);
|
|
3589
|
+
scopeOf.set(node, switchScope);
|
|
3590
|
+
hoistDeclarations(
|
|
3591
|
+
node.cases.flatMap((c) => c.consequent),
|
|
3592
|
+
switchScope
|
|
3593
|
+
);
|
|
3594
|
+
for (const c of node.cases) {
|
|
3595
|
+
walk2(c.test, switchScope, typeOnly);
|
|
3596
|
+
walk2(c.consequent, switchScope, typeOnly);
|
|
3597
|
+
}
|
|
3598
|
+
return;
|
|
3599
|
+
}
|
|
3600
|
+
case "CatchClause": {
|
|
3601
|
+
const catchScope = new Scope(scope, false, node);
|
|
3602
|
+
scopeOf.set(node, catchScope);
|
|
3603
|
+
if (node.param) {
|
|
3604
|
+
declarePattern(node.param, catchScope);
|
|
3605
|
+
walkPattern(node.param, catchScope, typeOnly);
|
|
3606
|
+
}
|
|
3607
|
+
walk2(node.body, catchScope, typeOnly);
|
|
3608
|
+
return;
|
|
3609
|
+
}
|
|
3610
|
+
}
|
|
3611
|
+
for (const key of Object.keys(node)) {
|
|
3612
|
+
if (key === "type" || key === "start" || key === "end") continue;
|
|
3613
|
+
walk2(node[key], scope, typeOnly || TYPE_KEYS.has(key));
|
|
3614
|
+
}
|
|
3615
|
+
};
|
|
3616
|
+
hoistDeclarations(program.body, moduleScope);
|
|
3617
|
+
walk2(program.body, moduleScope, false);
|
|
3618
|
+
return { moduleScope, references, scopeOf };
|
|
3619
|
+
}
|
|
3620
|
+
function collectImports(program) {
|
|
3621
|
+
const imports = /* @__PURE__ */ new Map();
|
|
3622
|
+
for (const statement of program.body) {
|
|
3623
|
+
if (statement.type !== "ImportDeclaration") continue;
|
|
3624
|
+
const declTypeOnly = statement.importKind === "type";
|
|
3625
|
+
for (const spec of statement.specifiers) {
|
|
3626
|
+
imports.set(spec.local.name, {
|
|
3627
|
+
source: statement.source.value,
|
|
3628
|
+
imported: spec.type === "ImportDefaultSpecifier" ? "default" : spec.type === "ImportNamespaceSpecifier" ? "*" : spec.imported.type === "Identifier" ? spec.imported.name : String(spec.imported.value),
|
|
3629
|
+
typeOnly: declTypeOnly || spec.importKind === "type"
|
|
3630
|
+
});
|
|
3631
|
+
}
|
|
3632
|
+
}
|
|
3633
|
+
return imports;
|
|
3634
|
+
}
|
|
3635
|
+
function hasUseClientDirective(program) {
|
|
3636
|
+
for (const statement of program.body) {
|
|
3637
|
+
if (statement.type !== "ExpressionStatement" || typeof statement.directive !== "string") {
|
|
3638
|
+
return false;
|
|
3639
|
+
}
|
|
3640
|
+
if (statement.directive === "use client") return true;
|
|
3641
|
+
}
|
|
3642
|
+
return false;
|
|
3643
|
+
}
|
|
3644
|
+
function lineColumn(code, offset) {
|
|
3645
|
+
let line = 1;
|
|
3646
|
+
let column = 1;
|
|
3647
|
+
for (let i = 0; i < offset && i < code.length; i++) {
|
|
3648
|
+
if (code[i] === "\n") {
|
|
3649
|
+
line++;
|
|
3650
|
+
column = 1;
|
|
3651
|
+
} else {
|
|
3652
|
+
column++;
|
|
3653
|
+
}
|
|
3654
|
+
}
|
|
3655
|
+
return `${line}:${column}`;
|
|
3656
|
+
}
|
|
3657
|
+
var ROUTER_SOURCE = "@rangojs/router";
|
|
3658
|
+
var EXPRESSION_WRAPPERS = /* @__PURE__ */ new Set([
|
|
3659
|
+
"TSAsExpression",
|
|
3660
|
+
"TSSatisfiesExpression",
|
|
3661
|
+
"TSNonNullExpression",
|
|
3662
|
+
"TSTypeAssertion",
|
|
3663
|
+
"ParenthesizedExpression"
|
|
3664
|
+
]);
|
|
3665
|
+
function unwrapExpression(node) {
|
|
3666
|
+
while (node && EXPRESSION_WRAPPERS.has(node.type)) node = node.expression;
|
|
3667
|
+
return node;
|
|
3668
|
+
}
|
|
3669
|
+
function isFunctionLiteral(node) {
|
|
3670
|
+
return node?.type === "ArrowFunctionExpression" || node?.type === "FunctionExpression";
|
|
3671
|
+
}
|
|
3672
|
+
function propertyKeyIs(prop, name) {
|
|
3673
|
+
return prop?.type === "Property" && !prop.computed && (prop.key.type === "Identifier" && prop.key.name === name || prop.key.type === "Literal" && prop.key.value === name);
|
|
3674
|
+
}
|
|
3675
|
+
function findWhenSites(program, scopeOf, moduleScope, imports) {
|
|
3676
|
+
const sites = [];
|
|
3677
|
+
const helpers = /* @__PURE__ */ new Map();
|
|
3678
|
+
const routerExport = (callee, scope) => {
|
|
3679
|
+
const routerImport = (id) => {
|
|
3680
|
+
if (id?.type !== "Identifier") return null;
|
|
3681
|
+
if (scope.lookup(id.name) !== moduleScope) return null;
|
|
3682
|
+
const binding = imports.get(id.name);
|
|
3683
|
+
return binding?.source === ROUTER_SOURCE && !binding.typeOnly ? binding : null;
|
|
3684
|
+
};
|
|
3685
|
+
if (callee.type === "Identifier") {
|
|
3686
|
+
const imported = routerImport(callee)?.imported;
|
|
3687
|
+
return imported && imported !== "*" && imported !== "default" ? imported : null;
|
|
3688
|
+
}
|
|
3689
|
+
if (callee.type === "MemberExpression" && !callee.computed && callee.property.type === "Identifier" && routerImport(callee.object)?.imported === "*") {
|
|
3690
|
+
return callee.property.name;
|
|
3691
|
+
}
|
|
3692
|
+
return null;
|
|
3693
|
+
};
|
|
3694
|
+
const registerUrlsCallback = (callback) => {
|
|
3695
|
+
const fnScope = scopeOf.get(callback);
|
|
3696
|
+
let param = callback.params[0];
|
|
3697
|
+
if (param?.type === "AssignmentPattern") param = param.left;
|
|
3698
|
+
if (!fnScope || !param) return;
|
|
3699
|
+
const bindings = {
|
|
3700
|
+
transitions: /* @__PURE__ */ new Set(),
|
|
3701
|
+
objects: /* @__PURE__ */ new Set()
|
|
3702
|
+
};
|
|
3703
|
+
if (param.type === "Identifier") bindings.objects.add(param.name);
|
|
3704
|
+
if (param.type === "ObjectPattern") {
|
|
3705
|
+
for (const prop of param.properties) {
|
|
3706
|
+
if (!propertyKeyIs(prop, "transition")) continue;
|
|
3707
|
+
const target = prop.value.type === "AssignmentPattern" ? prop.value.left : prop.value;
|
|
3708
|
+
if (target.type === "Identifier") bindings.transitions.add(target.name);
|
|
3709
|
+
}
|
|
3710
|
+
}
|
|
3711
|
+
helpers.set(fnScope, bindings);
|
|
3712
|
+
};
|
|
3713
|
+
const isRouterTransition = (callee, scope) => {
|
|
3714
|
+
if (routerExport(callee, scope) === "transition") return true;
|
|
3715
|
+
if (callee.type === "Identifier") {
|
|
3716
|
+
const decl = scope.lookup(callee.name);
|
|
3717
|
+
return !!decl && !!helpers.get(decl)?.transitions.has(callee.name);
|
|
3718
|
+
}
|
|
3719
|
+
if (callee.type === "MemberExpression" && !callee.computed && callee.property.type === "Identifier" && callee.property.name === "transition" && callee.object.type === "Identifier") {
|
|
3720
|
+
const decl = scope.lookup(callee.object.name);
|
|
3721
|
+
return !!decl && !!helpers.get(decl)?.objects.has(callee.object.name);
|
|
3722
|
+
}
|
|
3723
|
+
return false;
|
|
3724
|
+
};
|
|
3725
|
+
const visit = (node, scope) => {
|
|
3726
|
+
if (!node || typeof node !== "object") return;
|
|
3727
|
+
if (Array.isArray(node)) {
|
|
3728
|
+
for (const item of node) visit(item, scope);
|
|
3729
|
+
return;
|
|
3730
|
+
}
|
|
3731
|
+
if (typeof node.type !== "string") return;
|
|
3732
|
+
const own = scopeOf.get(node) ?? scope;
|
|
3733
|
+
if (node.type === "CallExpression") {
|
|
3734
|
+
const callback = node.arguments[0];
|
|
3735
|
+
if (isFunctionLiteral(callback) && routerExport(node.callee, own) === "urls") {
|
|
3736
|
+
registerUrlsCallback(callback);
|
|
3737
|
+
}
|
|
3738
|
+
if (node.arguments[0]?.type === "ObjectExpression" && isRouterTransition(node.callee, own)) {
|
|
3739
|
+
for (const prop of node.arguments[0].properties) {
|
|
3740
|
+
if (propertyKeyIs(prop, "when")) {
|
|
3741
|
+
sites.push({
|
|
3742
|
+
prop,
|
|
3743
|
+
value: unwrapExpression(prop.value),
|
|
3744
|
+
scope: own
|
|
3745
|
+
});
|
|
3746
|
+
}
|
|
3747
|
+
}
|
|
3748
|
+
}
|
|
3749
|
+
}
|
|
3750
|
+
for (const key of Object.keys(node)) {
|
|
3751
|
+
if (key === "type" || key === "start" || key === "end") continue;
|
|
3752
|
+
visit(node[key], own);
|
|
3753
|
+
}
|
|
3754
|
+
};
|
|
3755
|
+
visit(program.body, moduleScope);
|
|
3756
|
+
return sites;
|
|
3757
|
+
}
|
|
3758
|
+
var LEXICAL_CAPTURE = {
|
|
3759
|
+
this: "`this` in an arrow is the enclosing server function's `this`.",
|
|
3760
|
+
arguments: "`arguments` in an arrow is the enclosing server function's `arguments`.",
|
|
3761
|
+
super: "`super` refers to the enclosing server object.",
|
|
3762
|
+
"new.target": "`new.target` in an arrow is the enclosing server function's."
|
|
3763
|
+
};
|
|
3764
|
+
function findLexicalCapture(literal, references, code) {
|
|
3765
|
+
const ownArguments = [];
|
|
3766
|
+
let found = null;
|
|
3767
|
+
const capture = (node, what) => {
|
|
3768
|
+
found = {
|
|
3769
|
+
node,
|
|
3770
|
+
detail: `${LEXICAL_CAPTURE[what]} Read what you need from \`to.params\`/\`to.state\`, or export the predicate from a "use client" module.`
|
|
3771
|
+
};
|
|
3772
|
+
};
|
|
3773
|
+
const loads = (node, expression, why) => {
|
|
3774
|
+
found = {
|
|
3775
|
+
node,
|
|
3776
|
+
detail: `\`${expression}\` ${why} Import client-safe modules statically, or export the predicate from a "use client" module.`
|
|
3777
|
+
};
|
|
3778
|
+
};
|
|
3779
|
+
const visit = (node, boundary) => {
|
|
3780
|
+
if (found || !node || typeof node !== "object") return;
|
|
3781
|
+
if (Array.isArray(node)) {
|
|
3782
|
+
for (const item of node) visit(item, boundary);
|
|
3783
|
+
return;
|
|
3784
|
+
}
|
|
3785
|
+
if (typeof node.type !== "string") return;
|
|
3786
|
+
switch (node.type) {
|
|
3787
|
+
case "FunctionExpression":
|
|
3788
|
+
case "FunctionDeclaration":
|
|
3789
|
+
ownArguments.push(node);
|
|
3790
|
+
boundary = node;
|
|
3791
|
+
break;
|
|
3792
|
+
case "ClassBody":
|
|
3793
|
+
boundary = node;
|
|
3794
|
+
break;
|
|
3795
|
+
case "ThisExpression":
|
|
3796
|
+
if (!boundary) capture(node, "this");
|
|
3797
|
+
return;
|
|
3798
|
+
case "Super":
|
|
3799
|
+
if (!boundary || boundary === literal) capture(node, "super");
|
|
3800
|
+
return;
|
|
3801
|
+
case "JSXMemberExpression": {
|
|
3802
|
+
let root = node;
|
|
3803
|
+
while (root.type === "JSXMemberExpression") root = root.object;
|
|
3804
|
+
if (root.name === "this" && !boundary) capture(root, "this");
|
|
3805
|
+
return;
|
|
3806
|
+
}
|
|
3807
|
+
case "MetaProperty":
|
|
3808
|
+
if (node.meta.name === "import") {
|
|
3809
|
+
loads(node, "import.meta", "is the server module's.");
|
|
3810
|
+
} else if (!boundary) {
|
|
3811
|
+
capture(node, "new.target");
|
|
3812
|
+
}
|
|
3813
|
+
return;
|
|
3814
|
+
case "MemberExpression":
|
|
3815
|
+
if (node.object?.type === "MetaProperty") {
|
|
3816
|
+
if (node.object.meta.name !== "import") break;
|
|
3817
|
+
if (!node.computed && node.property.name === "env") return;
|
|
3818
|
+
loads(
|
|
3819
|
+
node,
|
|
3820
|
+
node.computed ? "import.meta[...]" : `import.meta.${node.property.name}`,
|
|
3821
|
+
"is resolved against the server module; only `import.meta.env` is available to an inline predicate."
|
|
3822
|
+
);
|
|
3823
|
+
return;
|
|
3824
|
+
}
|
|
3825
|
+
break;
|
|
3826
|
+
case "ImportExpression":
|
|
3827
|
+
loads(
|
|
3828
|
+
node,
|
|
3829
|
+
`import(${code.slice(node.source.start, node.source.end)})`,
|
|
3830
|
+
"loads a module at run time, which the build cannot check is client-safe."
|
|
3831
|
+
);
|
|
3832
|
+
return;
|
|
3833
|
+
}
|
|
3834
|
+
for (const key of Object.keys(node)) {
|
|
3835
|
+
if (key === "type" || key === "start" || key === "end") continue;
|
|
3836
|
+
if (TYPE_KEYS.has(key)) continue;
|
|
3837
|
+
visit(node[key], boundary);
|
|
3838
|
+
}
|
|
3839
|
+
};
|
|
3840
|
+
visit(literal, null);
|
|
3841
|
+
if (found) return found;
|
|
3842
|
+
for (const ref of references) {
|
|
3843
|
+
if (ref.typeOnly || ref.node.name !== "arguments") continue;
|
|
3844
|
+
if (ref.node.start < literal.start || ref.node.end > literal.end) continue;
|
|
3845
|
+
const owned = ownArguments.some(
|
|
3846
|
+
(fn) => fn.start <= ref.node.start && ref.node.end <= fn.end
|
|
3847
|
+
);
|
|
3848
|
+
if (!owned) {
|
|
3849
|
+
capture(ref.node, "arguments");
|
|
3850
|
+
return found;
|
|
3851
|
+
}
|
|
3852
|
+
}
|
|
3853
|
+
return null;
|
|
3854
|
+
}
|
|
3855
|
+
var NODE_BUILTINS = new Set(builtinModules);
|
|
3856
|
+
function isServerOnlySpecifier(source) {
|
|
3857
|
+
return source === "server-only" || source.startsWith("node:") || source.startsWith("cloudflare:") || NODE_BUILTINS.has(source);
|
|
3858
|
+
}
|
|
3859
|
+
var ROUTER_IMPORT_RE = /["']@rangojs\/router["']/;
|
|
3860
|
+
var WHEN_RE = /\bwhen\b/;
|
|
3861
|
+
function parseLang(file) {
|
|
3862
|
+
if (/\.[cm]?ts$/.test(file)) return "ts";
|
|
3863
|
+
if (/\.[cm]?jsx?$/.test(file)) return "jsx";
|
|
3864
|
+
return "tsx";
|
|
3865
|
+
}
|
|
3866
|
+
function whenError(file, code, node, detail) {
|
|
3867
|
+
return new TransitionWhenError(
|
|
3868
|
+
`[rango] transition({ when }) at ${file}:${lineColumn(code, node.start)}: \`when\` runs in the browser; ${detail}`
|
|
3869
|
+
);
|
|
3870
|
+
}
|
|
3871
|
+
async function hoistTransitionWhens(code, id, deps = {}) {
|
|
3872
|
+
if (!ROUTER_IMPORT_RE.test(code) || !WHEN_RE.test(code)) return null;
|
|
3873
|
+
const file = normalizePath2(id.split("?", 1)[0]);
|
|
3874
|
+
let program;
|
|
3875
|
+
try {
|
|
3876
|
+
program = parseAst3(code, { lang: parseLang(file) });
|
|
3877
|
+
} catch {
|
|
3878
|
+
return null;
|
|
3879
|
+
}
|
|
3880
|
+
if (hasUseClientDirective(program)) return null;
|
|
3881
|
+
const { moduleScope, references, scopeOf } = analyzeScopes(program);
|
|
3882
|
+
const imports = collectImports(program);
|
|
3883
|
+
const sites = findWhenSites(program, scopeOf, moduleScope, imports);
|
|
3884
|
+
if (sites.length === 0) return null;
|
|
3885
|
+
const s = new MagicString4(code);
|
|
3886
|
+
const modules = [];
|
|
3887
|
+
const header = [];
|
|
3888
|
+
for (const site of sites) {
|
|
3889
|
+
const { prop, value } = site;
|
|
3890
|
+
if (prop.kind === "get" || prop.kind === "set") {
|
|
3891
|
+
throw whenError(
|
|
3892
|
+
file,
|
|
3893
|
+
code,
|
|
3894
|
+
prop,
|
|
3895
|
+
`\`${prop.kind} when()\` is an accessor; \`when\` must be the predicate itself: \`when: (ctx) => ...\` or \`when(ctx) { ... }\`.`
|
|
3896
|
+
);
|
|
3897
|
+
}
|
|
3898
|
+
if (value.type === "Identifier") {
|
|
3899
|
+
const decl = site.scope.lookup(value.name);
|
|
3900
|
+
if (decl && !(decl === moduleScope && imports.has(value.name))) {
|
|
3901
|
+
throw whenError(
|
|
3902
|
+
file,
|
|
3903
|
+
code,
|
|
3904
|
+
value,
|
|
3905
|
+
`\`${value.name}\` is a server-module binding. Export the predicate from a "use client" module and import it, or write it inline.`
|
|
3906
|
+
);
|
|
3907
|
+
}
|
|
3908
|
+
continue;
|
|
3909
|
+
}
|
|
3910
|
+
if (!isFunctionLiteral(value)) continue;
|
|
3911
|
+
const lexical = findLexicalCapture(value, references, code);
|
|
3912
|
+
if (lexical) throw whenError(file, code, lexical.node, lexical.detail);
|
|
3913
|
+
const used = /* @__PURE__ */ new Map();
|
|
3914
|
+
for (const ref of references) {
|
|
3915
|
+
if (ref.node.start < value.start || ref.node.end > value.end) continue;
|
|
3916
|
+
const decl = ref.scope.lookup(ref.node.name);
|
|
3917
|
+
if (!decl) continue;
|
|
3918
|
+
if (decl.node.start >= value.start && decl.node.end <= value.end && decl !== moduleScope) {
|
|
3919
|
+
continue;
|
|
3920
|
+
}
|
|
3921
|
+
if (decl === moduleScope && imports.has(ref.node.name)) {
|
|
3922
|
+
const valueUse = !ref.typeOnly && !imports.get(ref.node.name).typeOnly;
|
|
3923
|
+
used.set(ref.node.name, (used.get(ref.node.name) ?? false) || valueUse);
|
|
3924
|
+
continue;
|
|
3925
|
+
}
|
|
3926
|
+
if (ref.typeOnly) continue;
|
|
3927
|
+
throw whenError(
|
|
3928
|
+
file,
|
|
3929
|
+
code,
|
|
3930
|
+
ref.node,
|
|
3931
|
+
`\`${ref.node.name}\` is a server-module binding. Read it from \`to.params\`/\`to.state\`, or export the predicate from a "use client" module.`
|
|
3932
|
+
);
|
|
3933
|
+
}
|
|
3934
|
+
const bySource = /* @__PURE__ */ new Map();
|
|
3935
|
+
for (const [local2, valueUse] of used) {
|
|
3936
|
+
const binding = imports.get(local2);
|
|
3937
|
+
if (valueUse) {
|
|
3938
|
+
if (isServerOnlySpecifier(binding.source) || await deps.isServerOnlyImport?.(binding.source)) {
|
|
3939
|
+
throw whenError(
|
|
3940
|
+
file,
|
|
3941
|
+
code,
|
|
3942
|
+
value,
|
|
3943
|
+
`\`${local2}\` is imported from "${binding.source}", a server-only module. Import only client-safe modules into an inline predicate, or export it from a "use client" module.`
|
|
3944
|
+
);
|
|
3945
|
+
}
|
|
3946
|
+
}
|
|
3947
|
+
const lines = bySource.get(binding.source) ?? [];
|
|
3948
|
+
const typePrefix = valueUse ? "" : "type ";
|
|
3949
|
+
if (binding.imported === "*") {
|
|
3950
|
+
lines.push(
|
|
3951
|
+
`import ${typePrefix}* as ${local2} from ${JSON.stringify(binding.source)};`
|
|
3952
|
+
);
|
|
3953
|
+
} else if (binding.imported === "default") {
|
|
3954
|
+
lines.push(
|
|
3955
|
+
`import ${typePrefix}${local2} from ${JSON.stringify(binding.source)};`
|
|
3956
|
+
);
|
|
3957
|
+
} else {
|
|
3958
|
+
const spec = binding.imported === local2 ? local2 : `${JSON.stringify(binding.imported)} as ${local2}`;
|
|
3959
|
+
lines.push(
|
|
3960
|
+
`import ${typePrefix}{ ${spec} } from ${JSON.stringify(binding.source)};`
|
|
3961
|
+
);
|
|
3962
|
+
}
|
|
3963
|
+
bySource.set(binding.source, lines);
|
|
3964
|
+
}
|
|
3965
|
+
const source = prop.method ? `${value.async ? "async " : ""}function${value.generator ? "*" : ""} ` + code.slice(value.start, value.end) : code.slice(value.start, value.end);
|
|
3966
|
+
const index = modules.length;
|
|
3967
|
+
modules.push(
|
|
3968
|
+
[
|
|
3969
|
+
`"use client";`,
|
|
3970
|
+
...[...bySource.values()].flat(),
|
|
3971
|
+
`export const ${EXPORT_NAME} = ${source};`,
|
|
3972
|
+
""
|
|
3973
|
+
].join("\n")
|
|
3974
|
+
);
|
|
3975
|
+
const local = `${LOCAL_PREFIX}${index}`;
|
|
3976
|
+
s.overwrite(
|
|
3977
|
+
prop.start,
|
|
3978
|
+
prop.end,
|
|
3979
|
+
`${code.slice(prop.key.start, prop.key.end)}: ${local}`
|
|
3980
|
+
);
|
|
3981
|
+
header.push(
|
|
3982
|
+
`import { ${EXPORT_NAME} as ${local} } from ${JSON.stringify(
|
|
3983
|
+
`${file}?${TRANSITION_WHEN_QUERY}=${index}`
|
|
3984
|
+
)};`
|
|
3985
|
+
);
|
|
3986
|
+
}
|
|
3987
|
+
if (modules.length === 0) return null;
|
|
3988
|
+
let insertAt = 0;
|
|
3989
|
+
for (const statement of program.body) {
|
|
3990
|
+
if (statement.type !== "ExpressionStatement" || typeof statement.directive !== "string") {
|
|
3991
|
+
break;
|
|
3992
|
+
}
|
|
3993
|
+
insertAt = statement.end;
|
|
3994
|
+
}
|
|
3995
|
+
s.appendLeft(insertAt, `${insertAt ? "\n" : ""}${header.join("\n")}
|
|
3996
|
+
`);
|
|
3997
|
+
return {
|
|
3998
|
+
code: s.toString(),
|
|
3999
|
+
map: s.generateMap({ hires: true, source: file }),
|
|
4000
|
+
modules
|
|
4001
|
+
};
|
|
4002
|
+
}
|
|
4003
|
+
function parseHoistedWhenId(id) {
|
|
4004
|
+
const q = id.indexOf("?");
|
|
4005
|
+
if (q === -1) return null;
|
|
4006
|
+
const params = new URLSearchParams(id.slice(q + 1));
|
|
4007
|
+
const raw = params.get(TRANSITION_WHEN_QUERY);
|
|
4008
|
+
if (raw === null || !/^\d+$/.test(raw)) return null;
|
|
4009
|
+
return { file: id.slice(0, q), index: Number(raw) };
|
|
4010
|
+
}
|
|
4011
|
+
var SERVER_ONLY_IMPORT_RE = /\bimport\s+["']server-only["']/;
|
|
4012
|
+
async function readSource(file) {
|
|
4013
|
+
try {
|
|
4014
|
+
return await readFile(file, "utf-8");
|
|
4015
|
+
} catch {
|
|
4016
|
+
return null;
|
|
4017
|
+
}
|
|
4018
|
+
}
|
|
4019
|
+
function transitionWhenHoistPlugin() {
|
|
4020
|
+
const emitted = /* @__PURE__ */ new Map();
|
|
4021
|
+
return {
|
|
4022
|
+
name: "@rangojs/router:transition-when-hoist",
|
|
4023
|
+
enforce: "pre",
|
|
4024
|
+
async load(id) {
|
|
4025
|
+
const hoisted = parseHoistedWhenId(id);
|
|
4026
|
+
if (!hoisted) return;
|
|
4027
|
+
const file = normalizePath2(hoisted.file);
|
|
4028
|
+
const disk = await readSource(hoisted.file);
|
|
4029
|
+
const entry = emitted.get(file);
|
|
4030
|
+
const modules = entry && (disk === null || entry.disk === disk) ? entry.modules : disk === null ? void 0 : (await hoistTransitionWhens(disk, hoisted.file))?.modules;
|
|
4031
|
+
const module = modules?.[hoisted.index];
|
|
4032
|
+
if (module === void 0) {
|
|
4033
|
+
throw new TransitionWhenError(
|
|
4034
|
+
`[rango] ${hoisted.file} has no inline transition({ when }) #${hoisted.index}.`
|
|
4035
|
+
);
|
|
4036
|
+
}
|
|
4037
|
+
return module;
|
|
4038
|
+
},
|
|
4039
|
+
async transform(code, id) {
|
|
4040
|
+
if (this.environment?.name !== "rsc") return;
|
|
4041
|
+
if (id.includes("/node_modules/") || parseHoistedWhenId(id)) return;
|
|
4042
|
+
const file = normalizePath2(id.split("?", 1)[0]);
|
|
4043
|
+
if (!/\.[cm]?[jt]sx?$/.test(file)) return;
|
|
4044
|
+
emitted.delete(file);
|
|
4045
|
+
const result = await hoistTransitionWhens(code, id, {
|
|
4046
|
+
isServerOnlyImport: async (source) => {
|
|
4047
|
+
const resolved = await this.resolve(source, id);
|
|
4048
|
+
if (!resolved || resolved.external) return false;
|
|
4049
|
+
const target = resolved.id.split("?", 1)[0];
|
|
4050
|
+
if (target.includes("/node_modules/") || target.startsWith("\0")) {
|
|
4051
|
+
return false;
|
|
4052
|
+
}
|
|
4053
|
+
const text = await readSource(target);
|
|
4054
|
+
return text !== null && SERVER_ONLY_IMPORT_RE.test(text);
|
|
4055
|
+
}
|
|
4056
|
+
});
|
|
4057
|
+
if (!result) return;
|
|
4058
|
+
emitted.set(file, {
|
|
4059
|
+
disk: await readSource(file),
|
|
4060
|
+
modules: result.modules
|
|
4061
|
+
});
|
|
4062
|
+
return { code: result.code, map: result.map };
|
|
4063
|
+
}
|
|
4064
|
+
};
|
|
4065
|
+
}
|
|
4066
|
+
|
|
3291
4067
|
// src/vite/plugins/client-ref-dedup.ts
|
|
3292
4068
|
init_debug();
|
|
3293
4069
|
import { existsSync, readFileSync } from "node:fs";
|
|
@@ -3802,7 +4578,7 @@ import { resolve } from "node:path";
|
|
|
3802
4578
|
// package.json
|
|
3803
4579
|
var package_default = {
|
|
3804
4580
|
name: "@rangojs/router",
|
|
3805
|
-
version: "0.
|
|
4581
|
+
version: "0.19.0",
|
|
3806
4582
|
description: "Django-inspired RSC router with composable URL patterns",
|
|
3807
4583
|
keywords: [
|
|
3808
4584
|
"react",
|
|
@@ -4220,15 +4996,6 @@ function extractRouteFromCallExpression(node) {
|
|
|
4220
4996
|
};
|
|
4221
4997
|
}
|
|
4222
4998
|
|
|
4223
|
-
// src/route-name.ts
|
|
4224
|
-
var AUTO_GENERATED_ROUTE_PREFIX = "$path_";
|
|
4225
|
-
var INTERNAL_INCLUDE_SCOPE_PREFIX = "$prefix_";
|
|
4226
|
-
function isAutoGeneratedRouteName(name) {
|
|
4227
|
-
return name.split(".").some((segment) => {
|
|
4228
|
-
return segment.startsWith(AUTO_GENERATED_ROUTE_PREFIX) || segment.startsWith(INTERNAL_INCLUDE_SCOPE_PREFIX);
|
|
4229
|
-
});
|
|
4230
|
-
}
|
|
4231
|
-
|
|
4232
4999
|
// src/build/route-types/codegen.ts
|
|
4233
5000
|
function generateRouteTypesSource(routeManifest, searchSchemas) {
|
|
4234
5001
|
const entries = Object.entries(routeManifest).filter(([name]) => !isAutoGeneratedRouteName(name)).sort(([a], [b]) => a.localeCompare(b));
|
|
@@ -5269,14 +6036,14 @@ function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
|
|
|
5269
6036
|
}
|
|
5270
6037
|
|
|
5271
6038
|
// src/vite/plugins/version-plugin.ts
|
|
5272
|
-
import { parseAst as
|
|
6039
|
+
import { parseAst as parseAst5 } from "vite";
|
|
5273
6040
|
|
|
5274
6041
|
// src/vite/utils/directive-prologue.ts
|
|
5275
|
-
import { parseAst as
|
|
5276
|
-
function
|
|
6042
|
+
import { parseAst as parseAst4 } from "vite";
|
|
6043
|
+
function hasUseClientDirective2(source) {
|
|
5277
6044
|
let program;
|
|
5278
6045
|
try {
|
|
5279
|
-
program =
|
|
6046
|
+
program = parseAst4(source, { lang: "tsx" });
|
|
5280
6047
|
} catch {
|
|
5281
6048
|
return false;
|
|
5282
6049
|
}
|
|
@@ -5298,10 +6065,10 @@ function normalizeModuleId(id) {
|
|
|
5298
6065
|
return id.split("?", 1)[0];
|
|
5299
6066
|
}
|
|
5300
6067
|
function getClientModuleSignature(source) {
|
|
5301
|
-
if (!
|
|
6068
|
+
if (!hasUseClientDirective2(source)) return void 0;
|
|
5302
6069
|
let program;
|
|
5303
6070
|
try {
|
|
5304
|
-
program =
|
|
6071
|
+
program = parseAst5(source, { lang: "tsx" });
|
|
5305
6072
|
} catch {
|
|
5306
6073
|
return void 0;
|
|
5307
6074
|
}
|
|
@@ -5488,7 +6255,7 @@ import { isAbsolute as isAbsolute2, resolve as resolve4 } from "node:path";
|
|
|
5488
6255
|
|
|
5489
6256
|
// src/vite/plugins/performance-tracks.ts
|
|
5490
6257
|
init_debug();
|
|
5491
|
-
import { readFile } from "node:fs/promises";
|
|
6258
|
+
import { readFile as readFile2 } from "node:fs/promises";
|
|
5492
6259
|
var debug5 = createRangoDebugger(NS.transform);
|
|
5493
6260
|
var RSDW_PATCH_RE = /((?:var|let|const)\s+\w+\s*=\s*root\._children\s*,\s*(\w+)\s*=\s*root\._debugInfo\s*[;,])/;
|
|
5494
6261
|
function buildPatchReplacement(match, debugInfoVar) {
|
|
@@ -5517,7 +6284,7 @@ function performanceTracksOptimizeDepsPlugin() {
|
|
|
5517
6284
|
async load(id) {
|
|
5518
6285
|
const cleanId = id.split("?")[0] ?? id;
|
|
5519
6286
|
if (!RSDW_CLIENT_RE.test(cleanId)) return null;
|
|
5520
|
-
const code = await
|
|
6287
|
+
const code = await readFile2(cleanId, "utf8");
|
|
5521
6288
|
const patched = patchRsdwClientDebugInfoRecovery(code);
|
|
5522
6289
|
return { code: patched.code };
|
|
5523
6290
|
}
|
|
@@ -6147,6 +6914,10 @@ import React from "react";
|
|
|
6147
6914
|
// src/server/context.ts
|
|
6148
6915
|
import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
|
|
6149
6916
|
|
|
6917
|
+
// src/rsc/shell-capture-constants.ts
|
|
6918
|
+
var SHELL_CAPTURE_MAX_WAIT_MS = 15e3;
|
|
6919
|
+
var PPR_LANE_HINT = 'Lane rule: only loader(Def, { ssr: false }) executes at capture and bakes its non-promise data; every other loader is live (masked at capture, fresh per request) and needs loading() or an inline <Suspense> above its reader. See the /ppr skill, "The loader lane rule" (node_modules/@rangojs/router/skills/ppr/SKILL.md).';
|
|
6920
|
+
|
|
6150
6921
|
// src/cache/cache-exec-scope.ts
|
|
6151
6922
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
6152
6923
|
|
|
@@ -6158,6 +6929,8 @@ function _setCacheExecScopeProbe(probe) {
|
|
|
6158
6929
|
|
|
6159
6930
|
// src/cache/cache-exec-scope.ts
|
|
6160
6931
|
var cacheExecStorage = new AsyncLocalStorage();
|
|
6932
|
+
var IDENTITY_EXEMPT_KEY = /* @__PURE__ */ Symbol.for("rangojs-router:identity-exempt");
|
|
6933
|
+
var identityExemptStorage = globalThis[IDENTITY_EXEMPT_KEY] ??= new AsyncLocalStorage();
|
|
6161
6934
|
function isInsideCacheExecScope() {
|
|
6162
6935
|
return cacheExecStorage.getStore() !== void 0;
|
|
6163
6936
|
}
|
|
@@ -6170,19 +6943,37 @@ var LOADER_SCOPE_KEY = /* @__PURE__ */ Symbol.for("rangojs-router:loader-scope")
|
|
|
6170
6943
|
var loaderScopeALS = globalThis[LOADER_SCOPE_KEY] ??= new AsyncLocalStorage2();
|
|
6171
6944
|
var LOADER_BODY_SCOPE_KEY = /* @__PURE__ */ Symbol.for("rangojs-router:loader-body-scope");
|
|
6172
6945
|
var loaderBodyScopeALS = globalThis[LOADER_BODY_SCOPE_KEY] ??= new AsyncLocalStorage2();
|
|
6946
|
+
function requestReadCaptureFix(what) {
|
|
6947
|
+
return {
|
|
6948
|
+
capture: `The captured shell is served to every user of this URL, so request-scoped data read here would leak one user's ${what} to others. Read it inside a loader without ssr: false and consume it with useLoader, e.g. createLoader(async () => getUser(cookies().get("session")?.value)). ${PPR_LANE_HINT}`,
|
|
6949
|
+
warning: "Read it in a loader without ssr: false and consume it with useLoader under loading() or an inline <Suspense> (a live hole). A promise the handler passes or pushes does not help: the capture waits for it."
|
|
6950
|
+
};
|
|
6951
|
+
}
|
|
6952
|
+
var NON_CACHEABLE_READ = {
|
|
6953
|
+
verb: "called",
|
|
6954
|
+
fix: {
|
|
6955
|
+
useCache: "The variable was created with { cache: false } or set with { cache: false }, and the cache key does not include its value, so the first caller's value would be served to later callers. Read it before calling the cached function and pass the value in as an argument so it becomes part of the cache key.",
|
|
6956
|
+
cacheScope: "The variable was created with { cache: false } or set with { cache: false }, and its value would be stale on cache hit. Move the read outside the cached scope.",
|
|
6957
|
+
...requestReadCaptureFix("per-request variables")
|
|
6958
|
+
}
|
|
6959
|
+
};
|
|
6960
|
+
function getLoaderBodyTags() {
|
|
6961
|
+
return loaderBodyScopeALS.getStore()?.tags;
|
|
6962
|
+
}
|
|
6963
|
+
function getCurrentLoaderBodyId() {
|
|
6964
|
+
return loaderBodyScopeALS.getStore()?.loaderId;
|
|
6965
|
+
}
|
|
6173
6966
|
var PUSH_CALLBACK_SCOPE_KEY = /* @__PURE__ */ Symbol.for(
|
|
6174
6967
|
"rangojs-router:push-callback-scope"
|
|
6175
6968
|
);
|
|
6176
6969
|
var pushCallbackScopeALS = globalThis[PUSH_CALLBACK_SCOPE_KEY] ??= new AsyncLocalStorage2();
|
|
6177
6970
|
|
|
6178
|
-
// src/rsc/shell-capture-constants.ts
|
|
6179
|
-
var SHELL_CAPTURE_MAX_WAIT_MS = 15e3;
|
|
6180
|
-
|
|
6181
6971
|
// src/rsc/shell-serve.ts
|
|
6182
6972
|
var DEV_SHELL_PROBE_TIMEOUT_MS = 1e4;
|
|
6183
6973
|
function normalizeCaptureTimeout(value) {
|
|
6184
6974
|
return typeof value === "number" && Number.isFinite(value) && value >= 1 ? Math.min(value, SHELL_CAPTURE_MAX_WAIT_MS) : void 0;
|
|
6185
6975
|
}
|
|
6976
|
+
var SHELL_PRELUDE_CHUNK_BYTES = 32 * 1024;
|
|
6186
6977
|
|
|
6187
6978
|
// src/vite/inject-client-debug.ts
|
|
6188
6979
|
function isRouterInternalDebugId(id) {
|
|
@@ -7713,7 +8504,7 @@ init_client_ref_hashing();
|
|
|
7713
8504
|
// src/vite/discovery/client-urls-projection.ts
|
|
7714
8505
|
import { existsSync as existsSync7, readFileSync as readFileSync5 } from "node:fs";
|
|
7715
8506
|
import { isAbsolute as isAbsolute3, relative as relative4, resolve as resolve8 } from "node:path";
|
|
7716
|
-
import { normalizePath as
|
|
8507
|
+
import { normalizePath as normalizePath5, parseAst as parseAst6 } from "vite";
|
|
7717
8508
|
|
|
7718
8509
|
// src/client-urls/server-projection.ts
|
|
7719
8510
|
import * as React5 from "react";
|
|
@@ -8567,6 +9358,11 @@ init_logging();
|
|
|
8567
9358
|
init_cache();
|
|
8568
9359
|
init_rango_state();
|
|
8569
9360
|
|
|
9361
|
+
// src/browser/react/location-state-shared.ts
|
|
9362
|
+
function isLocationStateDefinition(value) {
|
|
9363
|
+
return typeof value === "function" && "__rsc_ls_flash" in value;
|
|
9364
|
+
}
|
|
9365
|
+
|
|
8570
9366
|
// src/browser/react/NavigationProvider.tsx
|
|
8571
9367
|
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
8572
9368
|
|
|
@@ -8575,9 +9371,9 @@ import {
|
|
|
8575
9371
|
forwardRef,
|
|
8576
9372
|
useCallback as useCallback5,
|
|
8577
9373
|
useContext as useContext15,
|
|
8578
|
-
useEffect as
|
|
9374
|
+
useEffect as useEffect14,
|
|
8579
9375
|
useMemo as useMemo7,
|
|
8580
|
-
useRef as
|
|
9376
|
+
useRef as useRef12,
|
|
8581
9377
|
useSyncExternalStore
|
|
8582
9378
|
} from "react";
|
|
8583
9379
|
|
|
@@ -8817,21 +9613,6 @@ function isPrefetchScopeDisabled(element) {
|
|
|
8817
9613
|
return typeof element.closest === "function" && element.closest(PREFETCH_SCOPE_OPT_OUT_SELECTOR) !== null;
|
|
8818
9614
|
}
|
|
8819
9615
|
|
|
8820
|
-
// src/browser/react/location-state.ts
|
|
8821
|
-
import { useState as useState14, useEffect as useEffect14, useRef as useRef12 } from "react";
|
|
8822
|
-
|
|
8823
|
-
// src/browser/react/location-state-shared.ts
|
|
8824
|
-
function isLocationStateEntry(value) {
|
|
8825
|
-
return value !== null && typeof value === "object" && "__rsc_ls_key" in value && "__rsc_ls_value" in value && typeof value.__rsc_ls_key === "string";
|
|
8826
|
-
}
|
|
8827
|
-
function resolveLocationStateEntries(entries) {
|
|
8828
|
-
const result = {};
|
|
8829
|
-
for (const entry of entries) {
|
|
8830
|
-
result[entry.__rsc_ls_key] = entry.__rsc_ls_lazy ? entry.__rsc_ls_value() : entry.__rsc_ls_value;
|
|
8831
|
-
}
|
|
8832
|
-
return result;
|
|
8833
|
-
}
|
|
8834
|
-
|
|
8835
9616
|
// src/browser/react/Link.tsx
|
|
8836
9617
|
init_loader();
|
|
8837
9618
|
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
@@ -8858,6 +9639,7 @@ var Link = forwardRef(function Link2({
|
|
|
8858
9639
|
scroll = true,
|
|
8859
9640
|
reloadDocument = false,
|
|
8860
9641
|
revalidate: revalidate2,
|
|
9642
|
+
transition: transition2,
|
|
8861
9643
|
prefetch,
|
|
8862
9644
|
prefetchKey,
|
|
8863
9645
|
state,
|
|
@@ -8882,7 +9664,7 @@ var Link = forwardRef(function Link2({
|
|
|
8882
9664
|
() => resolveAdaptiveStrategy(configuredStrategy),
|
|
8883
9665
|
() => configuredStrategy === "adaptive" ? "hover" : configuredStrategy
|
|
8884
9666
|
);
|
|
8885
|
-
const internalRef =
|
|
9667
|
+
const internalRef = useRef12(null);
|
|
8886
9668
|
const setRef = useCallback5(
|
|
8887
9669
|
(node) => {
|
|
8888
9670
|
internalRef.current = node;
|
|
@@ -8894,7 +9676,7 @@ var Link = forwardRef(function Link2({
|
|
|
8894
9676
|
},
|
|
8895
9677
|
[ref]
|
|
8896
9678
|
);
|
|
8897
|
-
const stateRef =
|
|
9679
|
+
const stateRef = useRef12(state);
|
|
8898
9680
|
stateRef.current = state;
|
|
8899
9681
|
const handleClick = useCallback5(
|
|
8900
9682
|
(e) => {
|
|
@@ -8916,21 +9698,13 @@ var Link = forwardRef(function Link2({
|
|
|
8916
9698
|
e.preventDefault();
|
|
8917
9699
|
e.stopPropagation();
|
|
8918
9700
|
const currentState = stateRef.current;
|
|
8919
|
-
|
|
8920
|
-
if (Array.isArray(currentState) && currentState.length > 0 && isLocationStateEntry(currentState[0])) {
|
|
8921
|
-
resolvedState = resolveLocationStateEntries(
|
|
8922
|
-
currentState
|
|
8923
|
-
);
|
|
8924
|
-
} else if (typeof currentState === "function") {
|
|
8925
|
-
resolvedState = currentState();
|
|
8926
|
-
} else if (currentState != null) {
|
|
8927
|
-
resolvedState = currentState;
|
|
8928
|
-
}
|
|
9701
|
+
const state2 = typeof currentState === "function" && !(process.env.NODE_ENV !== "production" && isLocationStateDefinition(currentState)) ? currentState() : currentState ?? void 0;
|
|
8929
9702
|
ctx.navigate(resolvedTo, {
|
|
8930
9703
|
replace,
|
|
8931
9704
|
scroll,
|
|
8932
|
-
state:
|
|
8933
|
-
revalidate: revalidate2
|
|
9705
|
+
state: state2,
|
|
9706
|
+
revalidate: revalidate2,
|
|
9707
|
+
transition: transition2
|
|
8934
9708
|
});
|
|
8935
9709
|
},
|
|
8936
9710
|
[
|
|
@@ -8940,6 +9714,7 @@ var Link = forwardRef(function Link2({
|
|
|
8940
9714
|
replace,
|
|
8941
9715
|
scroll,
|
|
8942
9716
|
revalidate2,
|
|
9717
|
+
transition2,
|
|
8943
9718
|
ctx,
|
|
8944
9719
|
onClick
|
|
8945
9720
|
]
|
|
@@ -8957,7 +9732,7 @@ var Link = forwardRef(function Link2({
|
|
|
8957
9732
|
);
|
|
8958
9733
|
}
|
|
8959
9734
|
}, [resolvedStrategy, resolvedTo, isExternal, ctx, prefetchKey]);
|
|
8960
|
-
|
|
9735
|
+
useEffect14(() => {
|
|
8961
9736
|
if (isExternal || !ctx?.store) return;
|
|
8962
9737
|
const isViewport = resolvedStrategy === "viewport";
|
|
8963
9738
|
const isRender = resolvedStrategy === "render";
|
|
@@ -9037,6 +9812,7 @@ var Link = forwardRef(function Link2({
|
|
|
9037
9812
|
"data-scroll": scroll === false ? "false" : void 0,
|
|
9038
9813
|
"data-replace": replace ? "true" : void 0,
|
|
9039
9814
|
"data-revalidate": revalidate2 === false ? "false" : void 0,
|
|
9815
|
+
"data-transition": transition2 === false ? "false" : void 0,
|
|
9040
9816
|
...props,
|
|
9041
9817
|
children: /* @__PURE__ */ jsx8(LinkContext.Provider, { value: resolvedTo, children })
|
|
9042
9818
|
}
|
|
@@ -9070,6 +9846,9 @@ var Breadcrumbs = createHandle(
|
|
|
9070
9846
|
"__rsc_router_breadcrumbs__"
|
|
9071
9847
|
);
|
|
9072
9848
|
|
|
9849
|
+
// src/browser/react/location-state.ts
|
|
9850
|
+
import { useState as useState14, useEffect as useEffect15, useRef as useRef13 } from "react";
|
|
9851
|
+
|
|
9073
9852
|
// src/href-client.ts
|
|
9074
9853
|
function href(path6, mount) {
|
|
9075
9854
|
if (mount && mount !== "/") {
|
|
@@ -9133,18 +9912,75 @@ var ALL_USE_ITEM_TYPES = new Set(
|
|
|
9133
9912
|
);
|
|
9134
9913
|
|
|
9135
9914
|
// src/server/request-context.ts
|
|
9136
|
-
import { AsyncLocalStorage as
|
|
9915
|
+
import { AsyncLocalStorage as AsyncLocalStorage5 } from "node:async_hooks";
|
|
9137
9916
|
init_cookie_name();
|
|
9138
9917
|
|
|
9918
|
+
// src/router/segment-resolution/mask-nested.ts
|
|
9919
|
+
import { cloneElement, isValidElement as isValidElement2 } from "react";
|
|
9920
|
+
|
|
9139
9921
|
// src/server/handle-store.ts
|
|
9140
9922
|
var LOADER_SLOT = Object.freeze({ loader: true });
|
|
9141
9923
|
|
|
9924
|
+
// src/cache/cache-tag.ts
|
|
9925
|
+
import { AsyncLocalStorage as AsyncLocalStorage3 } from "node:async_hooks";
|
|
9926
|
+
var cacheTagStorage = new AsyncLocalStorage3();
|
|
9927
|
+
var segmentOwnerStorage = new AsyncLocalStorage3();
|
|
9928
|
+
var recordedTagCapture = globalThis[/* @__PURE__ */ Symbol.for("rangojs-router:recorded-tag-capture")] ??= new AsyncLocalStorage3();
|
|
9929
|
+
var identityReads = globalThis[/* @__PURE__ */ Symbol.for("rangojs-router:identity-reads")] ??= /* @__PURE__ */ new WeakMap();
|
|
9930
|
+
function activeTagSet() {
|
|
9931
|
+
const capture = recordedTagCapture.getStore();
|
|
9932
|
+
const body = getLoaderBodyTags();
|
|
9933
|
+
if (capture && capture.outer === body) return capture.into;
|
|
9934
|
+
return body ?? capture?.into;
|
|
9935
|
+
}
|
|
9936
|
+
globalThis[/* @__PURE__ */ Symbol.for("rangojs-router:identity-read-recorder")] = (surface, verb) => {
|
|
9937
|
+
const set = activeTagSet();
|
|
9938
|
+
if (set === void 0 || identityReads.has(set)) return;
|
|
9939
|
+
identityReads.set(set, { surface, verb, bodyId: getCurrentLoaderBodyId() });
|
|
9940
|
+
};
|
|
9941
|
+
|
|
9142
9942
|
// src/router/router-context.ts
|
|
9143
|
-
import { AsyncLocalStorage as
|
|
9144
|
-
var routerContext = new
|
|
9943
|
+
import { AsyncLocalStorage as AsyncLocalStorage4 } from "async_hooks";
|
|
9944
|
+
var routerContext = new AsyncLocalStorage4();
|
|
9945
|
+
|
|
9946
|
+
// src/server/cookie-store.ts
|
|
9947
|
+
var REQUEST_READ_CACHE_FIX = {
|
|
9948
|
+
useCache: 'Request-scoped data (cookies, headers) varies per request but is not reflected in the cache key, so cached results would be served to the wrong users. Extract the value before the cached function and pass it as an argument:\n\n const locale = cookies().get("locale")?.value ?? "en";\n const data = await getCachedData(locale); // locale is now in the cache key',
|
|
9949
|
+
cacheScope: 'A cache() scope caches everything except loaders, so request-scoped data (cookies, headers) read here would be frozen into the shared cached shell and served to other users. Read it inside a loader instead \u2014 loaders always run fresh on every request, even on a cache hit:\n\n loader("user", () => getUser(cookies().get("session")?.value));'
|
|
9950
|
+
};
|
|
9951
|
+
function requestReadWording(what) {
|
|
9952
|
+
return {
|
|
9953
|
+
verb: "called",
|
|
9954
|
+
fix: { ...REQUEST_READ_CACHE_FIX, ...requestReadCaptureFix(what) },
|
|
9955
|
+
record: false
|
|
9956
|
+
};
|
|
9957
|
+
}
|
|
9958
|
+
var COOKIES_READ = requestReadWording("cookies");
|
|
9959
|
+
var HEADERS_READ = requestReadWording("headers");
|
|
9960
|
+
var REQUEST_HEADERS_READ = {
|
|
9961
|
+
verb: "read",
|
|
9962
|
+
fix: HEADERS_READ.fix
|
|
9963
|
+
};
|
|
9964
|
+
var RAW_COOKIES_READ = {
|
|
9965
|
+
verb: "called",
|
|
9966
|
+
fix: COOKIES_READ.fix
|
|
9967
|
+
};
|
|
9968
|
+
var THEME_READ_FIX = "On ppr and cache() routes, read the theme with useTheme() in a client component, or in a live loader (no ssr: false) with cookies().get(<storageKey>). The <html> theme class needs neither: the theme script sets it before paint. See the /theme skill (node_modules/@rangojs/router/skills/theme/SKILL.md).";
|
|
9969
|
+
var THEME_READ = {
|
|
9970
|
+
verb: "read",
|
|
9971
|
+
fix: {
|
|
9972
|
+
useCache: "The theme comes from the visitor's cookie and is not in the cache key, so the first caller's theme would be served to later callers. Read it before the cached function and pass it in as an argument.",
|
|
9973
|
+
cacheScope: "The theme comes from the visitor's cookie, so the first visitor's theme would be stored in the shared entry and served to everyone. " + THEME_READ_FIX,
|
|
9974
|
+
capture: `The captured shell is served to every visitor of this URL, so the capturing visitor's theme would reach everyone. ${THEME_READ_FIX}`,
|
|
9975
|
+
warning: THEME_READ_FIX
|
|
9976
|
+
}
|
|
9977
|
+
};
|
|
9978
|
+
|
|
9979
|
+
// src/cache/invalidation-order.ts
|
|
9980
|
+
var order = globalThis[/* @__PURE__ */ Symbol.for("rangojs-router:tag-invalidation-order")] ??= { seq: 0, tags: /* @__PURE__ */ new Map(), forgotten: 0 };
|
|
9145
9981
|
|
|
9146
9982
|
// src/server/request-context.ts
|
|
9147
|
-
var requestContextStorage = new
|
|
9983
|
+
var requestContextStorage = new AsyncLocalStorage5();
|
|
9148
9984
|
|
|
9149
9985
|
// src/route-definition/redirect.ts
|
|
9150
9986
|
init_redirect_origin();
|
|
@@ -9281,7 +10117,7 @@ function serializeTransition(route2) {
|
|
|
9281
10117
|
if (!source) return void 0;
|
|
9282
10118
|
const config = {};
|
|
9283
10119
|
for (const [key, value] of Object.entries(source)) {
|
|
9284
|
-
if (value === void 0) continue;
|
|
10120
|
+
if (value === void 0 || key === "when") continue;
|
|
9285
10121
|
config[key] = typeof value === "object" && value !== null ? Object.freeze({ ...value }) : value;
|
|
9286
10122
|
}
|
|
9287
10123
|
return Object.freeze(config);
|
|
@@ -9306,7 +10142,8 @@ function serializeRoute(route2) {
|
|
|
9306
10142
|
loaderIds: Object.freeze(loaderIds),
|
|
9307
10143
|
hasLoading: route2.loading !== void 0,
|
|
9308
10144
|
...awaitedLoaderIndices.length > 0 ? { awaitedLoaderIndices: Object.freeze(awaitedLoaderIndices) } : {},
|
|
9309
|
-
...transition2 ? { transition: transition2 } : {}
|
|
10145
|
+
...transition2 ? { transition: transition2 } : {},
|
|
10146
|
+
...typeof route2.transition?.when === "function" ? { transitionWhen: true } : {}
|
|
9310
10147
|
});
|
|
9311
10148
|
}
|
|
9312
10149
|
function serializeIntercept(record, index) {
|
|
@@ -9342,7 +10179,7 @@ var debug10 = createRangoDebugger(NS.discovery);
|
|
|
9342
10179
|
function hasDefaultExport(code) {
|
|
9343
10180
|
let program;
|
|
9344
10181
|
try {
|
|
9345
|
-
program =
|
|
10182
|
+
program = parseAst6(code, { lang: "tsx" });
|
|
9346
10183
|
} catch {
|
|
9347
10184
|
return false;
|
|
9348
10185
|
}
|
|
@@ -9359,18 +10196,18 @@ function hasDefaultExport(code) {
|
|
|
9359
10196
|
function normalizeSource(state, id) {
|
|
9360
10197
|
const cleanId = id.split("?", 1)[0];
|
|
9361
10198
|
const absoluteId = isAbsolute3(cleanId) ? cleanId : resolve8(state.projectRoot, cleanId);
|
|
9362
|
-
return
|
|
10199
|
+
return normalizePath5(absoluteId);
|
|
9363
10200
|
}
|
|
9364
10201
|
function referenceId(referenceKey) {
|
|
9365
10202
|
return `${referenceKey}#default`;
|
|
9366
10203
|
}
|
|
9367
10204
|
function recordClientUrlsModule(state, code, id) {
|
|
9368
|
-
if (!code.includes("clientUrls(") || !
|
|
10205
|
+
if (!code.includes("clientUrls(") || !hasUseClientDirective2(code) || !hasDefaultExport(code)) {
|
|
9369
10206
|
return;
|
|
9370
10207
|
}
|
|
9371
10208
|
const source = normalizeSource(state, id);
|
|
9372
|
-
const projectRoot =
|
|
9373
|
-
const relativeId =
|
|
10209
|
+
const projectRoot = normalizePath5(resolve8(state.projectRoot));
|
|
10210
|
+
const relativeId = normalizePath5(relative4(projectRoot, source));
|
|
9374
10211
|
const outsideProject = relativeId === ".." || relativeId.startsWith("../") || isAbsolute3(relativeId);
|
|
9375
10212
|
const devReferenceKey = outsideProject ? `/@fs${source}` : `/${relativeId}`;
|
|
9376
10213
|
const sourceByReferenceId = state.clientUrlSourceByReferenceId ??= /* @__PURE__ */ new Map();
|
|
@@ -9606,7 +10443,10 @@ async function discoverRouters(state, rscEnv, ssrEnv) {
|
|
|
9606
10443
|
await generateManifestFull(mount.patterns, routerMountIndex, {
|
|
9607
10444
|
routerId: id,
|
|
9608
10445
|
...router.__basename ? { urlPrefix: router.__basename } : {},
|
|
9609
|
-
...collectClientFallbackRef ? { collectClientFallbackRef } : {}
|
|
10446
|
+
...collectClientFallbackRef ? { collectClientFallbackRef } : {},
|
|
10447
|
+
// Discovery evaluates the tree in the react-server graph, where a
|
|
10448
|
+
// "use client" import is a client reference: reject server `when`s.
|
|
10449
|
+
validateTransitionWhen: true
|
|
9610
10450
|
})
|
|
9611
10451
|
);
|
|
9612
10452
|
routerMountIndex++;
|
|
@@ -9727,6 +10567,8 @@ async function runShellPrerenderPhase(s, builder) {
|
|
|
9727
10567
|
const candidates = s.shellCandidates;
|
|
9728
10568
|
const startTotal = performance.now();
|
|
9729
10569
|
console.log(`[rango] Shell-prerendering ${candidates.length} URL(s)...`);
|
|
10570
|
+
const keepAlive = setInterval(() => {
|
|
10571
|
+
}, 6e4);
|
|
9730
10572
|
let restoreClientRequire;
|
|
9731
10573
|
try {
|
|
9732
10574
|
const rscEnv = tempServer.environments?.rsc;
|
|
@@ -9888,9 +10730,7 @@ async function runShellPrerenderPhase(s, builder) {
|
|
|
9888
10730
|
const value = {
|
|
9889
10731
|
entry: res.entry,
|
|
9890
10732
|
ttl: policy.ttl,
|
|
9891
|
-
|
|
9892
|
-
tags: res.tags,
|
|
9893
|
-
routeName: cand.routeName
|
|
10733
|
+
tags: res.tags
|
|
9894
10734
|
};
|
|
9895
10735
|
staged.push({
|
|
9896
10736
|
key: buildShellManifestKey(cand.urlPath),
|
|
@@ -9934,6 +10774,7 @@ async function runShellPrerenderPhase(s, builder) {
|
|
|
9934
10774
|
} finally {
|
|
9935
10775
|
delete globalThis.__loadPrerenderManifestModule;
|
|
9936
10776
|
restoreClientRequire?.();
|
|
10777
|
+
clearInterval(keepAlive);
|
|
9937
10778
|
}
|
|
9938
10779
|
}
|
|
9939
10780
|
function writeShellManifest(s, rscOutDir, staged) {
|
|
@@ -10131,6 +10972,7 @@ function supplementGenFilesWithRuntimeRoutes(state) {
|
|
|
10131
10972
|
import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync5 } from "node:fs";
|
|
10132
10973
|
import { dirname as dirname4, basename, join as join7 } from "node:path";
|
|
10133
10974
|
var MANIFEST_EXTERNALIZE_THRESHOLD = 512 * 1024;
|
|
10975
|
+
var TRANSITION_WHEN_VALIDATION = `enableTransitionWhenValidation();`;
|
|
10134
10976
|
function devDiscoveryBootstrap(state) {
|
|
10135
10977
|
if (state.isBuildMode || state.opts?.preset !== "cloudflare" || state.devDiscoveryEpoch === void 0) {
|
|
10136
10978
|
return [];
|
|
@@ -10166,6 +11008,7 @@ function generateRoutesManifestModule(state) {
|
|
|
10166
11008
|
}
|
|
10167
11009
|
}
|
|
10168
11010
|
const serverImports = [
|
|
11011
|
+
"enableTransitionWhenValidation",
|
|
10169
11012
|
"setCachedManifest",
|
|
10170
11013
|
"setRouterManifest",
|
|
10171
11014
|
...state.isBuildMode ? ["registerRouterManifestLoader"] : [],
|
|
@@ -10180,7 +11023,8 @@ function generateRoutesManifestModule(state) {
|
|
|
10180
11023
|
// this virtual module but the route-map-builder singleton retains old data
|
|
10181
11024
|
// because it's not in the HMR invalidation chain. Without this clear, the
|
|
10182
11025
|
// handler finds stale trie data and never rebuilds from updated urlpatterns.
|
|
10183
|
-
`clearAllRouterData()
|
|
11026
|
+
`clearAllRouterData();`,
|
|
11027
|
+
TRANSITION_WHEN_VALIDATION
|
|
10184
11028
|
];
|
|
10185
11029
|
if (hasClientUrlModules) {
|
|
10186
11030
|
lines2.push(`clearClientUrlProjections();`);
|
|
@@ -10230,12 +11074,12 @@ function generateRoutesManifestModule(state) {
|
|
|
10230
11074
|
lines2.push(...devDiscoveryBootstrap(state));
|
|
10231
11075
|
return lines2.join("\n");
|
|
10232
11076
|
}
|
|
10233
|
-
const lines = [
|
|
11077
|
+
const lines = [
|
|
11078
|
+
`import { ${hasClientUrlModules ? "clearClientUrlProjections, " : ""}enableTransitionWhenValidation } from "@rangojs/router/server";`,
|
|
11079
|
+
TRANSITION_WHEN_VALIDATION
|
|
11080
|
+
];
|
|
10234
11081
|
if (hasClientUrlModules) {
|
|
10235
|
-
lines.push(
|
|
10236
|
-
`import { clearClientUrlProjections } from "@rangojs/router/server";`,
|
|
10237
|
-
`clearClientUrlProjections();`
|
|
10238
|
-
);
|
|
11082
|
+
lines.push(`clearClientUrlProjections();`);
|
|
10239
11083
|
}
|
|
10240
11084
|
if (!state.isBuildMode) {
|
|
10241
11085
|
const origin = state.devServerOrigin || state.devServer?.resolvedUrls?.local?.[0]?.replace(/\/$/, "") || state.devServer && `http://localhost:${state.devServer.config.server.port || 5173}`;
|
|
@@ -10245,7 +11089,7 @@ function generateRoutesManifestModule(state) {
|
|
|
10245
11089
|
}
|
|
10246
11090
|
}
|
|
10247
11091
|
lines.push(...devDiscoveryBootstrap(state));
|
|
10248
|
-
return lines.join("\n")
|
|
11092
|
+
return lines.join("\n");
|
|
10249
11093
|
}
|
|
10250
11094
|
function shortHash(input) {
|
|
10251
11095
|
let h = 2166136261;
|
|
@@ -10603,7 +11447,16 @@ async function createTempRscServer(state, options = {}) {
|
|
|
10603
11447
|
return createViteServer({
|
|
10604
11448
|
root: state.projectRoot,
|
|
10605
11449
|
configFile: false,
|
|
10606
|
-
server: {
|
|
11450
|
+
server: {
|
|
11451
|
+
middlewareMode: true,
|
|
11452
|
+
// Build mode: no file watching. buildStart installs the per-router tries
|
|
11453
|
+
// into this realm and runShellPrerenderPhase reuses it after the bundles
|
|
11454
|
+
// are written. A watched write in between (writeRouteTypesFiles' own
|
|
11455
|
+
// <router>.named-routes.gen.ts, which every router file imports) can
|
|
11456
|
+
// make Vite full-reload the RSC runner; the shell phase then matches in
|
|
11457
|
+
// a fresh realm with no tries and a root path("/*") wins (#947).
|
|
11458
|
+
...options.forceBuild ? { watch: null } : {}
|
|
11459
|
+
},
|
|
10607
11460
|
appType: "custom",
|
|
10608
11461
|
logLevel: "silent",
|
|
10609
11462
|
resolve: resolveConfig,
|
|
@@ -10655,6 +11508,9 @@ async function createTempRscServer(state, options = {}) {
|
|
|
10655
11508
|
] : [],
|
|
10656
11509
|
createVirtualStubPlugin(),
|
|
10657
11510
|
createCloudflareProtocolStubPlugin(),
|
|
11511
|
+
// Inline transition({ when }) literals become client references here
|
|
11512
|
+
// too, or discovery would see (and reject) the plain function.
|
|
11513
|
+
transitionWhenHoistPlugin(),
|
|
10658
11514
|
// Dev prerender must use dev-mode IDs (path-based) to match the workerd
|
|
10659
11515
|
// runtime. forceBuild produces hashed IDs for production bundle consistency.
|
|
10660
11516
|
exposeInternalIds(options.forceBuild ? { forceBuild: true } : void 0),
|
|
@@ -10742,6 +11598,25 @@ function createRouterDiscoveryPlugin(entryPath, opts) {
|
|
|
10742
11598
|
const s = createDiscoveryState(entryPath, opts);
|
|
10743
11599
|
let viteCommand = "build";
|
|
10744
11600
|
let viteMode = "production";
|
|
11601
|
+
let transitionWhenOverlay = null;
|
|
11602
|
+
const sendTransitionWhenOverlay = () => {
|
|
11603
|
+
if (!transitionWhenOverlay) return;
|
|
11604
|
+
s.devServer?.environments?.client?.hot?.send({
|
|
11605
|
+
type: "error",
|
|
11606
|
+
err: transitionWhenOverlay
|
|
11607
|
+
});
|
|
11608
|
+
};
|
|
11609
|
+
const showTransitionWhenError = (err) => {
|
|
11610
|
+
const whenError2 = findTransitionWhenError(err);
|
|
11611
|
+
if (!whenError2) return void 0;
|
|
11612
|
+
transitionWhenOverlay = {
|
|
11613
|
+
message: whenError2.message,
|
|
11614
|
+
stack: whenError2.stack ?? "",
|
|
11615
|
+
plugin: "@rangojs/router"
|
|
11616
|
+
};
|
|
11617
|
+
sendTransitionWhenOverlay();
|
|
11618
|
+
return whenError2;
|
|
11619
|
+
};
|
|
10745
11620
|
return {
|
|
10746
11621
|
name: "@rangojs/router:discovery",
|
|
10747
11622
|
// Make INTERNAL_RANGO_DEBUG reach the CLIENT debug logs by just setting the
|
|
@@ -10792,6 +11667,25 @@ function createRouterDiscoveryPlugin(entryPath, opts) {
|
|
|
10792
11667
|
if (s.isBuildMode) return;
|
|
10793
11668
|
if (globalThis.__rscRouterDiscoveryActive) return;
|
|
10794
11669
|
s.devServer = server;
|
|
11670
|
+
server.environments?.client?.hot?.on?.(
|
|
11671
|
+
"vite:client:connect",
|
|
11672
|
+
(_payload, client) => {
|
|
11673
|
+
if (transitionWhenOverlay) {
|
|
11674
|
+
client?.send?.({ type: "error", err: transitionWhenOverlay });
|
|
11675
|
+
}
|
|
11676
|
+
}
|
|
11677
|
+
);
|
|
11678
|
+
let overlayResendQueued = false;
|
|
11679
|
+
server.httpServer?.on("request", (req, res) => {
|
|
11680
|
+
const isPage = req.url?.includes("_rsc") === true || req.headers.accept?.includes("text/html") === true;
|
|
11681
|
+
if (transitionWhenOverlay && isPage && !overlayResendQueued) {
|
|
11682
|
+
overlayResendQueued = true;
|
|
11683
|
+
res.once("close", () => {
|
|
11684
|
+
overlayResendQueued = false;
|
|
11685
|
+
sendTransitionWhenOverlay();
|
|
11686
|
+
});
|
|
11687
|
+
}
|
|
11688
|
+
});
|
|
10795
11689
|
let workerReadyEpoch;
|
|
10796
11690
|
const publishDevDiscoveryReady = (epoch) => {
|
|
10797
11691
|
if (epoch <= (workerReadyEpoch ?? -1)) return;
|
|
@@ -11010,6 +11904,7 @@ function createRouterDiscoveryPlugin(entryPath, opts) {
|
|
|
11010
11904
|
} else {
|
|
11011
11905
|
console.error(report.message);
|
|
11012
11906
|
}
|
|
11907
|
+
showTransitionWhenError(err);
|
|
11013
11908
|
};
|
|
11014
11909
|
const discover = async () => {
|
|
11015
11910
|
const discoverStart = performance.now();
|
|
@@ -11426,9 +12321,7 @@ function createRouterDiscoveryPlugin(entryPath, opts) {
|
|
|
11426
12321
|
const body = JSON.stringify({
|
|
11427
12322
|
entry: result.entry,
|
|
11428
12323
|
ttl,
|
|
11429
|
-
|
|
11430
|
-
tags: result.tags,
|
|
11431
|
-
routeName
|
|
12324
|
+
tags: result.tags
|
|
11432
12325
|
});
|
|
11433
12326
|
devPrerenderCache.set(routerInstance, cacheKey, body);
|
|
11434
12327
|
res.setHeader("content-type", "application/json");
|
|
@@ -11538,6 +12431,7 @@ function createRouterDiscoveryPlugin(entryPath, opts) {
|
|
|
11538
12431
|
);
|
|
11539
12432
|
s.lastDiscoveryError = null;
|
|
11540
12433
|
}
|
|
12434
|
+
transitionWhenOverlay = null;
|
|
11541
12435
|
if (rscEnv && !rscEnv.runner) {
|
|
11542
12436
|
const nextRouteShape = routeShapeSignature();
|
|
11543
12437
|
let expectedEpoch;
|
|
@@ -11556,9 +12450,14 @@ function createRouterDiscoveryPlugin(entryPath, opts) {
|
|
|
11556
12450
|
message: err?.message ?? String(err),
|
|
11557
12451
|
at: Date.now()
|
|
11558
12452
|
};
|
|
11559
|
-
|
|
11560
|
-
|
|
11561
|
-
|
|
12453
|
+
const whenError2 = showTransitionWhenError(err);
|
|
12454
|
+
if (whenError2) {
|
|
12455
|
+
console.error(whenError2.message);
|
|
12456
|
+
} else {
|
|
12457
|
+
console.warn(
|
|
12458
|
+
`[rango] Runtime re-discovery failed: ${err.message}`
|
|
12459
|
+
);
|
|
12460
|
+
}
|
|
11562
12461
|
debugDiscovery?.(
|
|
11563
12462
|
"hmr: lastDiscoveryError set (%s) \u2014 manifest preserved at last-good; recovery mode active (any in-scan source change will trigger rediscovery)",
|
|
11564
12463
|
err?.message
|
|
@@ -12458,7 +13357,7 @@ If this is a multi-app host router, export a createHostRouter() instance and set
|
|
|
12458
13357
|
return;
|
|
12459
13358
|
try {
|
|
12460
13359
|
const source = readFileSync10(file, "utf-8");
|
|
12461
|
-
if (
|
|
13360
|
+
if (hasUseClientDirective2(source)) {
|
|
12462
13361
|
return [];
|
|
12463
13362
|
}
|
|
12464
13363
|
} catch {
|
|
@@ -12466,6 +13365,7 @@ If this is a multi-app host router, export a createHostRouter() instance and set
|
|
|
12466
13365
|
}
|
|
12467
13366
|
});
|
|
12468
13367
|
plugins.push(createLoaderDirectiveGuardPlugin());
|
|
13368
|
+
plugins.push(transitionWhenHoistPlugin());
|
|
12469
13369
|
plugins.push(createLoaderScanStubPlugin());
|
|
12470
13370
|
plugins.push(exposeActionId());
|
|
12471
13371
|
plugins.push(
|