@rangojs/router 0.0.0-experimental.14 → 0.0.0-experimental.140
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/AGENTS.md +17 -0
- package/README.md +432 -7
- package/dist/bin/rango.js +2073 -213
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +7258 -2714
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/package.json +140 -67
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +329 -0
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +487 -0
- package/skills/caching/SKILL.md +357 -25
- package/skills/comparison/SKILL.md +50 -0
- package/skills/comparison/agents/openai.yaml +4 -0
- package/skills/comparison/references/framework-comparison.md +837 -0
- package/skills/composability/SKILL.md +246 -0
- package/skills/css/SKILL.md +76 -0
- package/skills/debug-manifest/SKILL.md +16 -10
- package/skills/document-cache/SKILL.md +87 -62
- package/skills/fonts/SKILL.md +6 -4
- package/skills/handler-use/SKILL.md +364 -0
- package/skills/hooks/SKILL.md +557 -79
- package/skills/host-router/SKILL.md +320 -0
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +207 -15
- package/skills/layout/SKILL.md +146 -6
- package/skills/links/SKILL.md +304 -25
- package/skills/loader/SKILL.md +616 -54
- package/skills/middleware/SKILL.md +217 -37
- package/skills/migrate-nextjs/SKILL.md +611 -0
- package/skills/migrate-react-router/SKILL.md +927 -0
- package/skills/mime-routes/SKILL.md +42 -11
- package/skills/observability/SKILL.md +194 -0
- package/skills/parallel/SKILL.md +284 -3
- package/skills/ppr/SKILL.md +426 -0
- package/skills/prerender/SKILL.md +437 -52
- package/skills/rango/SKILL.md +369 -22
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +263 -121
- package/skills/route/SKILL.md +350 -21
- package/skills/router-setup/SKILL.md +246 -33
- package/skills/scripts/SKILL.md +179 -0
- package/skills/server-actions/SKILL.md +775 -0
- package/skills/shell-manifest/SKILL.md +185 -0
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/tailwind/SKILL.md +27 -3
- package/skills/testing/SKILL.md +126 -222
- package/skills/testing/bindings.md +103 -0
- package/skills/testing/cache-prerender.md +127 -0
- package/skills/testing/client-components.md +124 -0
- package/skills/testing/e2e-parity.md +125 -0
- package/skills/testing/flight.md +91 -0
- package/skills/testing/handles.md +131 -0
- package/skills/testing/loader.md +128 -0
- package/skills/testing/middleware.md +99 -0
- package/skills/testing/render-handler.md +122 -0
- package/skills/testing/response-routes.md +95 -0
- package/skills/testing/reverse-and-types.md +85 -0
- package/skills/testing/server-actions.md +107 -0
- package/skills/testing/server-tree.md +128 -0
- package/skills/testing/setup.md +123 -0
- package/skills/theme/SKILL.md +9 -8
- package/skills/typesafety/SKILL.md +532 -103
- package/skills/use-cache/SKILL.md +367 -0
- package/skills/vercel/SKILL.md +128 -0
- package/skills/view-transitions/SKILL.md +337 -0
- package/src/__augment-tests__/augment.ts +81 -0
- package/src/__augment-tests__/augmented.check.ts +116 -0
- package/src/__internal.ts +77 -44
- package/src/bin/rango.ts +312 -15
- package/src/browser/action-coordinator.ts +114 -0
- package/src/browser/action-fence.ts +47 -0
- package/src/browser/app-shell.ts +39 -0
- package/src/browser/app-version.ts +14 -0
- package/src/browser/connection-warmup.ts +134 -0
- package/src/browser/cookie-name.ts +140 -0
- package/src/browser/event-controller.ts +293 -202
- package/src/browser/history-state.ts +101 -0
- package/src/browser/index.ts +3 -3
- package/src/browser/intercept-utils.ts +52 -0
- package/src/browser/invalidate-client-cache.ts +52 -0
- package/src/browser/link-interceptor.ts +24 -4
- package/src/browser/logging.ts +11 -0
- package/src/browser/merge-segment-loaders.ts +20 -12
- package/src/browser/navigation-bridge.ts +385 -576
- package/src/browser/navigation-client.ts +245 -75
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +184 -118
- package/src/browser/navigation-transaction.ts +247 -0
- package/src/browser/network-error-handler.ts +88 -0
- package/src/browser/partial-update.ts +412 -364
- package/src/browser/prefetch/cache.ts +359 -0
- package/src/browser/prefetch/fetch.ts +452 -0
- package/src/browser/prefetch/observer.ts +65 -0
- package/src/browser/prefetch/policy.ts +48 -0
- package/src/browser/prefetch/queue.ts +209 -0
- package/src/browser/prefetch/resource-ready.ts +77 -0
- package/src/browser/rango-state.ts +194 -0
- package/src/browser/react/Link.tsx +275 -68
- package/src/browser/react/NavigationProvider.tsx +265 -109
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/context.ts +11 -0
- package/src/browser/react/filter-segment-order.ts +70 -0
- package/src/browser/react/index.ts +0 -48
- package/src/browser/react/location-state-shared.ts +272 -60
- package/src/browser/react/location-state.ts +90 -20
- package/src/browser/react/mount-context.ts +6 -1
- package/src/browser/react/nonce-context.ts +23 -0
- package/src/browser/react/shallow-equal.ts +27 -0
- package/src/browser/react/use-action.ts +35 -66
- package/src/browser/react/use-handle.ts +39 -126
- package/src/browser/react/use-href.tsx +8 -1
- package/src/browser/react/use-link-status.ts +39 -13
- package/src/browser/react/use-navigation.ts +53 -69
- package/src/browser/react/use-params.ts +75 -0
- package/src/browser/react/use-pathname.ts +47 -0
- package/src/browser/react/use-reverse.ts +106 -0
- package/src/browser/react/use-router.ts +98 -0
- package/src/browser/react/use-search-params.ts +51 -0
- package/src/browser/react/use-segments.ts +72 -99
- package/src/browser/response-adapter.ts +164 -0
- package/src/browser/rsc-router.tsx +300 -72
- package/src/browser/scroll-restoration.ts +138 -50
- package/src/browser/segment-reconciler.ts +243 -0
- package/src/browser/segment-structure-assert.ts +17 -1
- package/src/browser/server-action-bridge.ts +668 -613
- package/src/browser/types.ts +223 -51
- package/src/browser/validate-redirect-origin.ts +56 -0
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +252 -161
- package/src/build/generate-route-types.ts +41 -1038
- package/src/build/index.ts +12 -7
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +225 -42
- package/src/build/route-types/ast-helpers.ts +25 -0
- package/src/build/route-types/ast-route-extraction.ts +105 -0
- package/src/build/route-types/codegen.ts +113 -0
- package/src/build/route-types/include-resolution.ts +812 -0
- package/src/build/route-types/param-extraction.ts +51 -0
- package/src/build/route-types/per-module-writer.ts +144 -0
- package/src/build/route-types/router-processing.ts +695 -0
- package/src/build/route-types/scan-filter.ts +85 -0
- package/src/build/route-types/source-scan.ts +216 -0
- package/src/build/runtime-discovery.ts +223 -0
- package/src/cache/background-task.ts +34 -0
- package/src/cache/cache-error.ts +104 -0
- package/src/cache/cache-key-utils.ts +60 -0
- package/src/cache/cache-policy.ts +199 -0
- package/src/cache/cache-runtime.ts +525 -0
- package/src/cache/cache-scope.ts +298 -332
- package/src/cache/cache-tag.ts +103 -0
- package/src/cache/cf/cf-base64.ts +33 -0
- package/src/cache/cf/cf-cache-constants.ts +127 -0
- package/src/cache/cf/cf-cache-store.ts +2500 -158
- package/src/cache/cf/cf-cache-types.ts +349 -0
- package/src/cache/cf/cf-kv-utils.ts +46 -0
- package/src/cache/cf/cf-tag-marker-memo.ts +105 -0
- package/src/cache/cf/index.ts +17 -17
- package/src/cache/document-cache.ts +199 -92
- package/src/cache/handle-capture.ts +81 -0
- package/src/cache/handle-snapshot.ts +111 -0
- package/src/cache/index.ts +29 -35
- package/src/cache/memory-segment-store.ts +363 -30
- package/src/cache/profile-registry.ts +88 -0
- package/src/cache/read-through-swr.ts +178 -0
- package/src/cache/segment-codec.ts +248 -0
- package/src/cache/shell-cache.ts +386 -0
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/taint.ts +153 -0
- package/src/cache/types.ts +156 -211
- package/src/cache/vercel/index.ts +11 -0
- package/src/cache/vercel/vercel-cache-store.ts +1102 -0
- package/src/client.rsc.tsx +43 -21
- package/src/client.tsx +131 -347
- package/src/cloudflare/index.ts +11 -0
- package/src/cloudflare/tracing.ts +109 -0
- package/src/component-utils.ts +23 -4
- package/src/components/DefaultDocument.tsx +13 -3
- package/src/context-var.ts +168 -0
- package/src/debug.ts +19 -9
- package/src/decode-loader-results.ts +52 -0
- package/src/defer.ts +185 -0
- package/src/deps/ssr.ts +0 -1
- package/src/encode-kv.ts +49 -0
- package/src/errors.ts +106 -10
- package/src/escape-script.ts +52 -0
- package/src/handle.ts +110 -35
- package/src/handles/MetaTags.tsx +83 -59
- package/src/handles/Scripts.tsx +183 -0
- package/src/handles/breadcrumbs.ts +93 -0
- package/src/handles/deferred-resolution.ts +127 -0
- package/src/handles/is-thenable.ts +18 -0
- package/src/handles/meta.ts +44 -53
- package/src/handles/script.ts +244 -0
- package/src/host/cookie-handler.ts +20 -65
- package/src/host/errors.ts +21 -30
- package/src/host/index.ts +13 -9
- package/src/host/pattern-matcher.ts +50 -79
- package/src/host/router.ts +151 -121
- package/src/host/testing.ts +45 -32
- package/src/host/types.ts +52 -11
- package/src/host/utils.ts +2 -2
- package/src/href-client.ts +192 -57
- package/src/index.rsc.ts +177 -35
- package/src/index.ts +255 -71
- package/src/internal-debug.ts +9 -2
- package/src/loader-store.ts +500 -0
- package/src/loader.rsc.ts +31 -99
- package/src/loader.ts +30 -12
- package/src/missing-id-error.ts +68 -0
- package/src/outlet-context.ts +1 -1
- package/src/outlet-provider.tsx +41 -0
- package/src/prerender/param-hash.ts +16 -14
- package/src/prerender/store.ts +121 -21
- package/src/prerender.ts +460 -26
- package/src/redirect-origin.ts +100 -0
- package/src/regex-escape.ts +8 -0
- package/src/render-error-thrower.tsx +20 -0
- package/src/response-utils.ts +62 -0
- package/src/reverse.ts +198 -128
- package/src/root-error-boundary.tsx +42 -48
- package/src/route-content-wrapper.tsx +22 -77
- package/src/route-definition/dsl-helpers.ts +1116 -0
- package/src/route-definition/helper-factories.ts +88 -0
- package/src/route-definition/helpers-types.ts +505 -0
- package/src/route-definition/index.ts +54 -0
- package/src/route-definition/redirect.ts +134 -0
- package/src/route-definition/resolve-handler-use.ts +160 -0
- package/src/route-definition/use-item-types.ts +29 -0
- package/src/route-definition.ts +1 -1481
- package/src/route-map-builder.ts +82 -144
- package/src/route-name.ts +53 -0
- package/src/route-types.ts +71 -45
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +263 -0
- package/src/router/debug-manifest.ts +72 -0
- package/src/router/error-handling.ts +54 -27
- package/src/router/find-match.ts +245 -0
- package/src/router/handler-context.ts +377 -125
- package/src/router/instrument.ts +350 -0
- package/src/router/intercept-resolution.ts +59 -28
- package/src/router/lazy-includes.ts +254 -0
- package/src/router/loader-resolution.ts +421 -157
- package/src/router/logging.ts +106 -6
- package/src/router/manifest.ts +131 -57
- package/src/router/match-api.ts +167 -246
- package/src/router/match-context.ts +4 -24
- package/src/router/match-handlers.ts +440 -0
- package/src/router/match-middleware/background-revalidation.ts +117 -93
- package/src/router/match-middleware/cache-lookup.ts +297 -150
- package/src/router/match-middleware/cache-store.ts +123 -51
- package/src/router/match-middleware/intercept-resolution.ts +44 -43
- package/src/router/match-middleware/segment-resolution.ts +64 -22
- package/src/router/match-pipelines.ts +11 -87
- package/src/router/match-result.ts +121 -50
- package/src/router/metrics.ts +219 -28
- package/src/router/middleware-types.ts +93 -0
- package/src/router/middleware.ts +505 -441
- package/src/router/navigation-snapshot.ts +133 -0
- package/src/router/params-util.ts +23 -0
- package/src/router/parse-pattern.ts +115 -0
- package/src/router/pattern-matching.ts +311 -142
- package/src/router/prefetch-cache-ttl.ts +51 -0
- package/src/router/prefetch-limits.ts +37 -0
- package/src/router/prerender-match.ts +547 -0
- package/src/router/preview-match.ts +102 -0
- package/src/router/request-classification.ts +278 -0
- package/src/router/revalidation.ts +203 -62
- package/src/router/route-snapshot.ts +246 -0
- package/src/router/router-context.ts +45 -48
- package/src/router/router-interfaces.ts +554 -0
- package/src/router/router-options.ts +779 -0
- package/src/router/router-registry.ts +21 -0
- package/src/router/segment-resolution/fresh.ts +772 -0
- package/src/router/segment-resolution/helpers.ts +348 -0
- package/src/router/segment-resolution/loader-cache.ts +250 -0
- package/src/router/segment-resolution/loader-mask.ts +44 -0
- package/src/router/segment-resolution/revalidation.ts +1331 -0
- package/src/router/segment-resolution/static-store.ts +81 -0
- package/src/router/segment-resolution/streamed-handler-telemetry.ts +52 -0
- package/src/router/segment-resolution/view-transition-default.ts +56 -0
- package/src/router/segment-resolution.ts +25 -1354
- package/src/router/segment-wrappers.ts +292 -0
- package/src/router/state-cookie-name.ts +33 -0
- package/src/router/substitute-pattern-params.ts +75 -0
- package/src/router/telemetry-otel.ts +261 -0
- package/src/router/telemetry.ts +377 -0
- package/src/router/timeout.ts +128 -0
- package/src/router/tracing.ts +206 -0
- package/src/router/trie-matching.ts +240 -61
- package/src/router/types.ts +23 -70
- package/src/router/url-params.ts +57 -0
- package/src/router.ts +781 -2378
- package/src/rsc/full-payload.ts +70 -0
- package/src/rsc/handler-context.ts +46 -0
- package/src/rsc/handler.ts +905 -1142
- package/src/rsc/helpers.ts +275 -19
- package/src/rsc/index.ts +2 -25
- package/src/rsc/json-route-result.ts +38 -0
- package/src/rsc/loader-fetch.ts +305 -0
- package/src/rsc/manifest-init.ts +77 -0
- package/src/rsc/nonce.ts +14 -0
- package/src/rsc/origin-guard.ts +155 -0
- package/src/rsc/progressive-enhancement.ts +502 -0
- package/src/rsc/redirect-guard.ts +99 -0
- package/src/rsc/response-cache-serve.ts +238 -0
- package/src/rsc/response-error.ts +104 -0
- package/src/rsc/response-route-handler.ts +257 -0
- package/src/rsc/rsc-rendering.ts +337 -0
- package/src/rsc/runtime-warnings.ts +55 -0
- package/src/rsc/server-action.ts +522 -0
- package/src/rsc/shell-capture.ts +439 -0
- package/src/rsc/ssr-setup.ts +144 -0
- package/src/rsc/transition-gate.ts +89 -0
- package/src/rsc/types.ts +95 -12
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +99 -82
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-loader-promise.ts +149 -0
- package/src/segment-system.tsx +349 -134
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +452 -85
- package/src/server/cookie-parse.ts +32 -0
- package/src/server/cookie-store.ts +310 -0
- package/src/server/fetchable-loader-store.ts +11 -6
- package/src/server/handle-store.ts +123 -42
- package/src/server/live.ts +130 -0
- package/src/server/loader-registry.ts +51 -100
- package/src/server/request-context.ts +842 -157
- package/src/server.ts +15 -8
- package/src/ssr/index.tsx +412 -136
- package/src/ssr/ssr-root.tsx +228 -0
- package/src/static-handler.ts +45 -18
- package/src/testing/cache-status.ts +162 -0
- package/src/testing/collect-handle.ts +46 -0
- package/src/testing/dispatch.ts +701 -0
- package/src/testing/dom.entry.ts +22 -0
- package/src/testing/e2e/fixture.ts +188 -0
- package/src/testing/e2e/index.ts +128 -0
- package/src/testing/e2e/matchers.ts +35 -0
- package/src/testing/e2e/page-helpers.ts +272 -0
- package/src/testing/e2e/parity.ts +387 -0
- package/src/testing/e2e/server.ts +195 -0
- package/src/testing/flight-matchers.ts +97 -0
- package/src/testing/flight-normalize.ts +11 -0
- package/src/testing/flight-runtime.d.ts +57 -0
- package/src/testing/flight-tree.ts +682 -0
- package/src/testing/flight.entry.ts +52 -0
- package/src/testing/flight.ts +257 -0
- package/src/testing/generated-routes.ts +199 -0
- package/src/testing/index.ts +105 -0
- package/src/testing/internal/context.ts +371 -0
- package/src/testing/internal/flight-client-globals.ts +30 -0
- package/src/testing/internal/seed-vars.ts +54 -0
- package/src/testing/render-handler.ts +357 -0
- package/src/testing/render-route.tsx +584 -0
- package/src/testing/run-loader.ts +385 -0
- package/src/testing/run-middleware.ts +205 -0
- package/src/testing/run-transition-when.ts +164 -0
- package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
- package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
- package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
- package/src/testing/vitest-stubs/version.ts +5 -0
- package/src/testing/vitest.ts +305 -0
- package/src/theme/ThemeProvider.tsx +40 -72
- package/src/theme/ThemeScript.tsx +12 -14
- package/src/theme/constants.ts +57 -15
- package/src/theme/index.ts +3 -20
- package/src/theme/theme-context.ts +5 -35
- package/src/theme/theme-script.ts +43 -39
- package/src/theme/use-theme.ts +0 -3
- package/src/types/boundaries.ts +123 -0
- package/src/types/cache-types.ts +207 -0
- package/src/types/error-types.ts +132 -0
- package/src/types/global-namespace.ts +113 -0
- package/src/types/handler-context.ts +839 -0
- package/src/types/index.ts +81 -0
- package/src/types/loader-types.ts +212 -0
- package/src/types/request-scope.ts +112 -0
- package/src/types/route-config.ts +138 -0
- package/src/types/route-entry.ts +114 -0
- package/src/types/segments.ts +271 -0
- package/src/types.ts +1 -1795
- package/src/urls/include-helper.ts +162 -0
- package/src/urls/include-provider.ts +71 -0
- package/src/urls/index.ts +43 -0
- package/src/urls/path-helper-types.ts +413 -0
- package/src/urls/path-helper.ts +275 -0
- package/src/urls/pattern-types.ts +124 -0
- package/src/urls/response-types.ts +109 -0
- package/src/urls/type-extraction.ts +316 -0
- package/src/urls/urls-function.ts +80 -0
- package/src/urls.ts +1 -1341
- package/src/use-loader.tsx +406 -141
- package/src/vercel/index.ts +11 -0
- package/src/vercel/tracing.ts +88 -0
- package/src/vite/debug.ts +185 -0
- package/src/vite/discovery/bundle-postprocess.ts +182 -0
- package/src/vite/discovery/discover-routers.ts +389 -0
- package/src/vite/discovery/discovery-errors.ts +255 -0
- package/src/vite/discovery/gate-state.ts +171 -0
- package/src/vite/discovery/prerender-collection.ts +467 -0
- package/src/vite/discovery/route-types-writer.ts +214 -0
- package/src/vite/discovery/self-gen-tracking.ts +73 -0
- package/src/vite/discovery/state.ts +161 -0
- package/src/vite/discovery/virtual-module-codegen.ts +183 -0
- package/src/vite/index.ts +23 -2255
- package/src/vite/inject-client-debug.ts +36 -0
- package/src/vite/plugin-types.ts +303 -0
- package/src/vite/plugins/cjs-to-esm.ts +90 -0
- package/src/vite/plugins/client-ref-dedup.ts +120 -0
- package/src/vite/plugins/client-ref-hashing.ts +118 -0
- package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
- package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/src/vite/plugins/cloudflare-protocol-stub.ts +194 -0
- package/src/vite/{expose-action-id.ts → plugins/expose-action-id.ts} +88 -110
- package/src/vite/{expose-id-utils.ts → plugins/expose-id-utils.ts} +89 -79
- package/src/vite/plugins/expose-ids/export-analysis.ts +363 -0
- package/src/vite/plugins/expose-ids/handler-transform.ts +130 -0
- package/src/vite/plugins/expose-ids/loader-transform.ts +64 -0
- package/src/vite/plugins/expose-ids/router-transform.ts +199 -0
- package/src/vite/plugins/expose-ids/types.ts +45 -0
- package/src/vite/plugins/expose-internal-ids.ts +805 -0
- package/src/vite/plugins/performance-tracks.ts +89 -0
- package/src/vite/plugins/refresh-cmd.ts +127 -0
- package/src/vite/plugins/use-cache-transform.ts +313 -0
- package/src/vite/plugins/vercel-output.ts +384 -0
- package/src/vite/plugins/version-injector.ts +94 -0
- package/src/vite/plugins/version-plugin.ts +263 -0
- package/src/vite/plugins/virtual-entries.ts +234 -0
- package/src/vite/plugins/virtual-stub-plugin.ts +29 -0
- package/src/vite/rango.ts +560 -0
- package/src/vite/router-discovery.ts +1638 -0
- package/src/vite/{ast-handler-extract.ts → utils/ast-handler-extract.ts} +200 -37
- package/src/vite/utils/banner.ts +36 -0
- package/src/vite/utils/bundle-analysis.ts +132 -0
- package/src/vite/utils/client-chunks.ts +184 -0
- package/src/vite/utils/directive-prologue.ts +40 -0
- package/src/vite/utils/forward-user-plugins.ts +171 -0
- package/src/vite/utils/manifest-utils.ts +15 -0
- package/src/vite/utils/package-resolution.ts +89 -0
- package/src/vite/utils/prerender-utils.ts +249 -0
- package/src/vite/utils/shared-utils.ts +269 -0
- package/CLAUDE.md +0 -43
- package/dist/vite/index.named-routes.gen.ts +0 -103
- package/src/browser/lru-cache.ts +0 -69
- package/src/browser/react/use-client-cache.ts +0 -56
- package/src/browser/request-controller.ts +0 -164
- package/src/browser/shallow.ts +0 -35
- package/src/cache/memory-store.ts +0 -253
- package/src/handles/index.ts +0 -6
- package/src/href-context.ts +0 -33
- package/src/network-error-thrower.tsx +0 -21
- package/src/router.gen.ts +0 -6
- package/src/static-handler.gen.ts +0 -5
- package/src/urls.gen.ts +0 -8
- package/src/vite/expose-internal-ids.ts +0 -1167
- package/src/vite/package-resolution.ts +0 -125
- package/src/vite/virtual-entries.ts +0 -114
- /package/src/vite/{version.d.ts → plugins/version.d.ts} +0 -0
package/src/router/logging.ts
CHANGED
|
@@ -1,10 +1,44 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
2
|
import { INTERNAL_RANGO_DEBUG } from "../internal-debug.js";
|
|
3
3
|
|
|
4
|
+
export interface RevalidationTraceEntry {
|
|
5
|
+
segmentId: string;
|
|
6
|
+
segmentType: string;
|
|
7
|
+
belongsToRoute: boolean;
|
|
8
|
+
source:
|
|
9
|
+
| "segment-resolution"
|
|
10
|
+
| "cache-hit"
|
|
11
|
+
| "loader"
|
|
12
|
+
| "parallel"
|
|
13
|
+
| "orphan-layout"
|
|
14
|
+
| "route-handler"
|
|
15
|
+
| "layout-handler"
|
|
16
|
+
| "intercept-loader";
|
|
17
|
+
defaultShouldRevalidate: boolean;
|
|
18
|
+
finalShouldRevalidate: boolean;
|
|
19
|
+
reason: string;
|
|
20
|
+
customRevalidators?: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface RevalidationTraceMeta {
|
|
24
|
+
method: string;
|
|
25
|
+
prevUrl: string;
|
|
26
|
+
nextUrl: string;
|
|
27
|
+
routeKey: string;
|
|
28
|
+
isAction: boolean;
|
|
29
|
+
stale?: boolean;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface RevalidationTrace {
|
|
33
|
+
meta: RevalidationTraceMeta;
|
|
34
|
+
entries: RevalidationTraceEntry[];
|
|
35
|
+
}
|
|
36
|
+
|
|
4
37
|
interface RouterLogContext {
|
|
5
38
|
requestId: string;
|
|
6
39
|
transactionId: string;
|
|
7
40
|
depth: number;
|
|
41
|
+
revalidationTrace?: RevalidationTrace;
|
|
8
42
|
}
|
|
9
43
|
|
|
10
44
|
interface RouterLogOptions {
|
|
@@ -36,7 +70,7 @@ function getHeaderRequestId(request: Request): string | null {
|
|
|
36
70
|
return trimmed.length > 0 ? trimmed : null;
|
|
37
71
|
}
|
|
38
72
|
|
|
39
|
-
function getOrCreateRequestId(request: Request): string {
|
|
73
|
+
export function getOrCreateRequestId(request: Request): string {
|
|
40
74
|
const existing = requestIds.get(request);
|
|
41
75
|
if (existing) return existing;
|
|
42
76
|
|
|
@@ -74,9 +108,15 @@ export function runWithRouterLogContext<T>(
|
|
|
74
108
|
);
|
|
75
109
|
}
|
|
76
110
|
|
|
77
|
-
export function withRouterLogScope<T>(
|
|
111
|
+
export function withRouterLogScope<T>(
|
|
112
|
+
label: string,
|
|
113
|
+
fn: () => Promise<T>,
|
|
114
|
+
): Promise<T>;
|
|
78
115
|
export function withRouterLogScope<T>(label: string, fn: () => T): T;
|
|
79
|
-
export function withRouterLogScope<T>(
|
|
116
|
+
export function withRouterLogScope<T>(
|
|
117
|
+
label: string,
|
|
118
|
+
fn: () => Promise<T> | T,
|
|
119
|
+
): Promise<T> | T {
|
|
80
120
|
const ctx = routerLogContext.getStore();
|
|
81
121
|
if (!INTERNAL_RANGO_DEBUG || !ctx) {
|
|
82
122
|
return fn();
|
|
@@ -88,9 +128,16 @@ export function withRouterLogScope<T>(label: string, fn: () => Promise<T> | T):
|
|
|
88
128
|
try {
|
|
89
129
|
const result = fn();
|
|
90
130
|
if (result && typeof (result as Promise<T>).then === "function") {
|
|
91
|
-
return (result as Promise<T>).
|
|
92
|
-
|
|
93
|
-
|
|
131
|
+
return (result as Promise<T>).then(
|
|
132
|
+
(value) => {
|
|
133
|
+
debugLog(label, "end");
|
|
134
|
+
return value;
|
|
135
|
+
},
|
|
136
|
+
(error) => {
|
|
137
|
+
debugLog(label, "error", { error: String(error) });
|
|
138
|
+
throw error;
|
|
139
|
+
},
|
|
140
|
+
);
|
|
94
141
|
}
|
|
95
142
|
debugLog(label, "end");
|
|
96
143
|
return result;
|
|
@@ -143,3 +190,56 @@ export function debugWarn(
|
|
|
143
190
|
|
|
144
191
|
console.warn(`${prefix} ${message}`);
|
|
145
192
|
}
|
|
193
|
+
|
|
194
|
+
export function isTraceActive(): boolean {
|
|
195
|
+
if (!INTERNAL_RANGO_DEBUG) return false;
|
|
196
|
+
const ctx = routerLogContext.getStore();
|
|
197
|
+
return !!ctx?.revalidationTrace;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export function startRevalidationTrace(meta: RevalidationTraceMeta): void {
|
|
201
|
+
const ctx = routerLogContext.getStore();
|
|
202
|
+
if (!ctx || !INTERNAL_RANGO_DEBUG) return;
|
|
203
|
+
ctx.revalidationTrace = { meta, entries: [] };
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export function pushRevalidationTraceEntry(
|
|
207
|
+
entry: RevalidationTraceEntry,
|
|
208
|
+
): void {
|
|
209
|
+
const ctx = routerLogContext.getStore();
|
|
210
|
+
if (!ctx?.revalidationTrace) return;
|
|
211
|
+
ctx.revalidationTrace.entries.push(entry);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export function flushRevalidationTrace(): RevalidationTrace | null {
|
|
215
|
+
const ctx = routerLogContext.getStore();
|
|
216
|
+
if (!ctx?.revalidationTrace) return null;
|
|
217
|
+
const trace = ctx.revalidationTrace;
|
|
218
|
+
ctx.revalidationTrace = undefined;
|
|
219
|
+
|
|
220
|
+
if (trace.entries.length === 0) return trace;
|
|
221
|
+
|
|
222
|
+
const revalidated = trace.entries.filter((e) => e.finalShouldRevalidate);
|
|
223
|
+
const skipped = trace.entries.filter((e) => !e.finalShouldRevalidate);
|
|
224
|
+
|
|
225
|
+
debugLog("revalidation-trace", "flush", {
|
|
226
|
+
method: trace.meta.method,
|
|
227
|
+
routeKey: trace.meta.routeKey,
|
|
228
|
+
isAction: trace.meta.isAction,
|
|
229
|
+
stale: trace.meta.stale,
|
|
230
|
+
prevUrl: trace.meta.prevUrl,
|
|
231
|
+
nextUrl: trace.meta.nextUrl,
|
|
232
|
+
total: trace.entries.length,
|
|
233
|
+
revalidated: revalidated.length,
|
|
234
|
+
skipped: skipped.length,
|
|
235
|
+
entries: trace.entries.map((e) => ({
|
|
236
|
+
segmentId: e.segmentId,
|
|
237
|
+
type: e.segmentType,
|
|
238
|
+
source: e.source,
|
|
239
|
+
revalidate: e.finalShouldRevalidate,
|
|
240
|
+
reason: e.reason,
|
|
241
|
+
})),
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
return trace;
|
|
245
|
+
}
|
package/src/router/manifest.ts
CHANGED
|
@@ -1,36 +1,45 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Router Manifest Loading
|
|
3
|
-
*
|
|
4
|
-
* Handles lazy loading and validation of route manifests.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
1
|
import { invariant, RouteNotFoundError } from "../errors";
|
|
8
2
|
import { createRouteHelpers } from "../route-definition";
|
|
9
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
getContext,
|
|
5
|
+
runWithPrefixes,
|
|
6
|
+
getIsolatedLazyParent,
|
|
7
|
+
type EntryData,
|
|
8
|
+
type MetricsStore,
|
|
9
|
+
} from "../server/context";
|
|
10
10
|
import MapRootLayout from "../server/root-layout";
|
|
11
|
+
import { joinPrefix } from "./pattern-matching.js";
|
|
11
12
|
import type { RouteEntry } from "../types";
|
|
12
13
|
import type { UrlPatterns } from "../urls";
|
|
14
|
+
import {
|
|
15
|
+
isIncludeProvider,
|
|
16
|
+
resolveIncludeModule,
|
|
17
|
+
} from "../urls/include-provider.js";
|
|
13
18
|
import { VERSION } from "@rangojs/router:version";
|
|
14
19
|
|
|
20
|
+
// Tags an error thrown while dynamically importing an async include's module
|
|
21
|
+
// (`() => import("./routes")`) so loadManifest's outer catch re-raises it as a
|
|
22
|
+
// server error rather than masking it as a RouteNotFoundError (404).
|
|
23
|
+
const MODULE_LOAD_FAILURE = Symbol.for("rango.moduleLoadFailure");
|
|
24
|
+
|
|
15
25
|
// Module-level manifest cache: avoids re-executing DSL handler on every request.
|
|
16
26
|
// Handler execution is deterministic (components, loaders, middleware are module-level
|
|
17
27
|
// stable references), so the resulting EntryData tree can be safely cached and reused
|
|
18
28
|
// across requests within the same isolate.
|
|
19
29
|
//
|
|
20
|
-
// Cache is keyed by (VERSION, mountIndex, routeKey, isSSR).
|
|
30
|
+
// Cache is keyed by (VERSION, routerId, mountIndex, routeKey, isSSR). routeKey is
|
|
31
|
+
// REQUIRED in the key: loadManifest() runs the handler with forRoute=routeKey, and
|
|
32
|
+
// path-helper.ts prunes (skips registering) every route except forRoute, so the
|
|
33
|
+
// resulting Store.manifest is pruned to the requested route — NOT the full include.
|
|
34
|
+
// Dropping routeKey would make a sibling route miss and overwrite this entry with its
|
|
35
|
+
// own pruned manifest, so alternating sibling requests would thrash (re-run the
|
|
36
|
+
// handler every time). Running the include handler once per isolate instead of once
|
|
37
|
+
// per route is possible but needs an unpruned manifest cache with prune-on-read — see
|
|
38
|
+
// LP1 in docs/internal/matching-and-lazy-discovery.md. VERSION comes from the
|
|
21
39
|
// @rangojs/router:version virtual module which Vite invalidates on RSC module HMR.
|
|
22
40
|
// When VERSION changes, this module re-evaluates and the cache is recreated empty.
|
|
23
|
-
// Including VERSION in the key is additional defense against stale entries.
|
|
24
41
|
const manifestModuleCache = new Map<string, Map<string, EntryData>>();
|
|
25
42
|
|
|
26
|
-
/**
|
|
27
|
-
* Load manifest from route entry with AsyncLocalStorage context
|
|
28
|
-
* Handles lazy imports, unwrapping, and validation
|
|
29
|
-
*
|
|
30
|
-
* Results are cached at module level after first execution. Subsequent calls
|
|
31
|
-
* for the same (routeKey, isSSR) within the same isolate return cached data
|
|
32
|
-
* without re-executing the DSL handler.
|
|
33
|
-
*/
|
|
34
43
|
/**
|
|
35
44
|
* Clear the module-level manifest cache.
|
|
36
45
|
* Called on HMR to ensure stale handler references are discarded.
|
|
@@ -59,8 +68,12 @@ export async function loadManifest(
|
|
|
59
68
|
|
|
60
69
|
const mountIndex = entry.mountIndex;
|
|
61
70
|
|
|
62
|
-
// Check module-level cache (persists across requests within same isolate)
|
|
63
|
-
|
|
71
|
+
// Check module-level cache (persists across requests within same isolate).
|
|
72
|
+
// Include routerId so multi-router setups (host routing) don't share cached
|
|
73
|
+
// EntryData across routers with overlapping mountIndex + routeKey combinations.
|
|
74
|
+
// routeKey is in the key because loadManifest() builds a manifest pruned to
|
|
75
|
+
// forRoute=routeKey (see path-helper.ts) — see the cache comment above.
|
|
76
|
+
const cacheKey = `${VERSION}:${entry.routerId ?? ""}:${mountIndex ?? ""}:${routeKey}:${isSSR ? 1 : 0}`;
|
|
64
77
|
const cached = manifestModuleCache.get(cacheKey);
|
|
65
78
|
if (cached) {
|
|
66
79
|
const cacheStart = performance.now();
|
|
@@ -80,47 +93,71 @@ export async function loadManifest(
|
|
|
80
93
|
const storeSetupStart = performance.now();
|
|
81
94
|
const Store = getContext().getOrCreateStore(routeKey);
|
|
82
95
|
|
|
83
|
-
// Set mount index in store for unique shortCode prefixes
|
|
84
96
|
Store.mountIndex = mountIndex;
|
|
85
|
-
|
|
86
|
-
// Set isSSR flag so loading() can check if we're in SSR
|
|
87
97
|
Store.isSSR = isSSR;
|
|
88
98
|
|
|
89
|
-
// Attach metrics store to context if provided
|
|
90
99
|
if (metricsStore) {
|
|
91
100
|
Store.metrics = metricsStore;
|
|
92
101
|
}
|
|
93
102
|
|
|
94
103
|
pushMetric?.("manifest:store-setup", storeSetupStart);
|
|
95
104
|
|
|
96
|
-
// Clear manifest before rebuilding to prevent stale entry mutations
|
|
97
105
|
const clearStart = performance.now();
|
|
98
106
|
Store.manifest.clear();
|
|
99
107
|
pushMetric?.("manifest:clear", clearStart);
|
|
100
108
|
|
|
101
109
|
try {
|
|
102
110
|
// Include mountIndex in namespace to ensure unique cache keys per mount
|
|
103
|
-
const namespaceWithMount =
|
|
104
|
-
? `#router.M${mountIndex}`
|
|
105
|
-
: "#router";
|
|
111
|
+
const namespaceWithMount =
|
|
112
|
+
mountIndex !== undefined ? `#router.M${mountIndex}` : "#router";
|
|
106
113
|
|
|
107
114
|
// For lazy entries, use the captured parent from include() context
|
|
108
115
|
// This ensures routes are registered under the correct layout hierarchy
|
|
109
|
-
const lazyContext =
|
|
110
|
-
|
|
116
|
+
const lazyContext =
|
|
117
|
+
entry.lazy && entry.lazyPatterns ? entry.lazyContext : null;
|
|
118
|
+
const parentForContext = lazyContext
|
|
119
|
+
? getIsolatedLazyParent(
|
|
120
|
+
(lazyContext.parent as EntryData | null) ?? Store.parent,
|
|
121
|
+
)
|
|
122
|
+
: Store.parent;
|
|
111
123
|
|
|
112
124
|
// For lazy entries, merge captured counters from include() so the
|
|
113
125
|
// handler's entries get shortCode indices after sibling entries that
|
|
114
126
|
// were created during pattern extraction. This prevents shortCode
|
|
115
127
|
// collisions between lazy and non-lazy entries under the same parent
|
|
116
128
|
// (e.g., ArticlesLayout and BlogLayout both under NavLayout).
|
|
117
|
-
if (lazyContext
|
|
118
|
-
const
|
|
119
|
-
for (const [key, value] of Object.entries(captured)) {
|
|
129
|
+
if (lazyContext?.counters) {
|
|
130
|
+
for (const [key, value] of Object.entries(lazyContext.counters)) {
|
|
120
131
|
Store.counters[key] = Math.max(Store.counters[key] ?? 0, value);
|
|
121
132
|
}
|
|
122
133
|
}
|
|
123
134
|
|
|
135
|
+
// Propagate cache profiles for DSL-time cache("profileName") resolution.
|
|
136
|
+
// Non-lazy entries carry profiles directly; lazy entries carry them
|
|
137
|
+
// in the captured lazyContext from include() time. Always write
|
|
138
|
+
// (including clearing to undefined) so a prior lazy build's profile
|
|
139
|
+
// map cannot leak into a later non-lazy build on the same ALS-backed
|
|
140
|
+
// Store — which would otherwise let cache("name") resolve a profile
|
|
141
|
+
// from an unrelated entry.
|
|
142
|
+
Store.cacheProfiles = entry.cacheProfiles ?? lazyContext?.cacheProfiles;
|
|
143
|
+
|
|
144
|
+
// Propagate rootScoped from lazyContext so that routes inside
|
|
145
|
+
// nested { name: "sub" } under { name: "" } keep inherited root scope
|
|
146
|
+
// when the manifest is rebuilt on each request. Always write
|
|
147
|
+
// (including clearing to undefined, which makes getRootScoped()
|
|
148
|
+
// return its true default) so a prior lazy build's scope cannot leak
|
|
149
|
+
// into a later non-lazy build on the same ALS-backed Store — which
|
|
150
|
+
// would otherwise mis-register plain routes as non-root-scoped and
|
|
151
|
+
// break dot-local reverse resolution.
|
|
152
|
+
Store.rootScoped = lazyContext?.rootScoped;
|
|
153
|
+
|
|
154
|
+
// Propagate includeScope from lazyContext so that direct-descendant
|
|
155
|
+
// shortCodes of this include use the correct scoped counter namespace
|
|
156
|
+
// on every manifest rebuild. Always write (including clearing to
|
|
157
|
+
// undefined) so a prior lazy build's scope cannot leak into a later
|
|
158
|
+
// non-lazy build on the same ALS-backed Store.
|
|
159
|
+
Store.includeScope = lazyContext?.includeScope;
|
|
160
|
+
|
|
124
161
|
const handlerExecStart = performance.now();
|
|
125
162
|
const useItems = await getContext().runWithStore(
|
|
126
163
|
Store,
|
|
@@ -137,64 +174,91 @@ export async function loadManifest(
|
|
|
137
174
|
// not exist in the non-lazy (root handler) path and would produce
|
|
138
175
|
// mismatched shortCodes.
|
|
139
176
|
if (entry.lazy && entry.lazyPatterns) {
|
|
177
|
+
// Resolve an async include provider (`() => import("./routes")`) before
|
|
178
|
+
// running its handler. The match-time precomputed shortcut can skip
|
|
179
|
+
// evaluateLazyEntry's resolution, so render-time must resolve it here;
|
|
180
|
+
// cache the resolved patterns on the entry so later renders reuse them.
|
|
181
|
+
if (isIncludeProvider(entry.lazyPatterns)) {
|
|
182
|
+
try {
|
|
183
|
+
entry.lazyPatterns = resolveIncludeModule(
|
|
184
|
+
await entry.lazyPatterns(),
|
|
185
|
+
entry.staticPrefix,
|
|
186
|
+
) as unknown as UrlPatterns<any>;
|
|
187
|
+
} catch (err) {
|
|
188
|
+
// A failed dynamic import of a REAL, matched route's module is a
|
|
189
|
+
// server error, not a missing route. Tag it so the outer catch
|
|
190
|
+
// surfaces it as a 5xx instead of masking it as a
|
|
191
|
+
// RouteNotFoundError — which renders the 404 page (monitoring
|
|
192
|
+
// misses the failure and a CDN could cache the 404).
|
|
193
|
+
if (err && typeof err === "object") {
|
|
194
|
+
(err as Record<PropertyKey, unknown>)[MODULE_LOAD_FAILURE] =
|
|
195
|
+
true;
|
|
196
|
+
}
|
|
197
|
+
throw err;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
140
200
|
const lazyPatterns = entry.lazyPatterns as UrlPatterns<any>;
|
|
141
201
|
const includePrefix = (entry as any)._lazyPrefix || "";
|
|
142
|
-
|
|
202
|
+
// Slash-collapsing join so a trailing-slash parent prefix does not
|
|
203
|
+
// bake a double slash into the registered route patterns (must match
|
|
204
|
+
// the same join in evaluateLazyEntry / the build-time runWithPrefixes).
|
|
205
|
+
const fullPrefix = joinPrefix(lazyContext?.urlPrefix, includePrefix);
|
|
143
206
|
|
|
144
207
|
if (fullPrefix || lazyContext?.namePrefix) {
|
|
145
|
-
return runWithPrefixes(
|
|
146
|
-
|
|
147
|
-
lazyContext?.namePrefix,
|
|
148
|
-
() => lazyPatterns.handler()
|
|
208
|
+
return runWithPrefixes(fullPrefix, lazyContext?.namePrefix, () =>
|
|
209
|
+
lazyPatterns.handler(),
|
|
149
210
|
);
|
|
150
211
|
}
|
|
151
212
|
return lazyPatterns.handler();
|
|
152
213
|
}
|
|
153
214
|
|
|
154
|
-
// Wrap handler execution in root layout so routes get correct parent
|
|
155
|
-
// This ensures all routes are registered with the layout as their parent
|
|
156
215
|
let promiseResult: Promise<any> | null = null;
|
|
157
216
|
const wrappedItems = helpers.layout(MapRootLayout, () => {
|
|
158
217
|
const result = entry.handler();
|
|
159
218
|
if (result instanceof Promise) {
|
|
160
|
-
// Lazy handler detected - capture promise for async handling
|
|
161
219
|
promiseResult = result;
|
|
162
|
-
return [];
|
|
220
|
+
return [];
|
|
163
221
|
}
|
|
164
222
|
return result;
|
|
165
223
|
});
|
|
166
224
|
|
|
167
|
-
// Handle lazy (Promise-based) handlers
|
|
168
225
|
if (promiseResult !== null) {
|
|
169
226
|
const load = await (promiseResult as Promise<any>);
|
|
170
|
-
if (
|
|
171
|
-
load &&
|
|
172
|
-
load !== null &&
|
|
173
|
-
typeof load === "object" &&
|
|
174
|
-
"default" in load
|
|
175
|
-
) {
|
|
227
|
+
if (load && typeof load === "object" && "default" in load) {
|
|
176
228
|
// Promise<{ default: () => Array }> - e.g., dynamic import
|
|
177
|
-
|
|
229
|
+
if (typeof load.default !== "function") {
|
|
230
|
+
throw new Error(
|
|
231
|
+
`[@rangojs/router] Unsupported async handler: { default } must be a function, ` +
|
|
232
|
+
`got ${typeof load.default}. Use () => import('./urls') for lazy loading.`,
|
|
233
|
+
);
|
|
234
|
+
}
|
|
178
235
|
return (load.default as (h?: any) => any)(helpers);
|
|
179
236
|
}
|
|
180
237
|
if (typeof load === "function") {
|
|
181
238
|
// Promise<() => Array>
|
|
182
239
|
return (load as (h?: any) => any)(helpers);
|
|
183
240
|
}
|
|
184
|
-
//
|
|
185
|
-
|
|
241
|
+
// Reject unsupported async handler results. Supported shapes are:
|
|
242
|
+
// Promise<{ default: fn }> — dynamic import
|
|
243
|
+
// Promise<fn> — lazy function
|
|
244
|
+
// Direct Promise<Array> is not supported; use a function wrapper.
|
|
245
|
+
throw new Error(
|
|
246
|
+
`[@rangojs/router] Unsupported async handler result (${typeof load}). ` +
|
|
247
|
+
`Lazy route handlers must resolve to a function or { default: fn }, ` +
|
|
248
|
+
`not a direct array. Wrap your handler: () => import('./urls') or ` +
|
|
249
|
+
`() => Promise.resolve((h) => [...])`,
|
|
250
|
+
);
|
|
186
251
|
}
|
|
187
252
|
|
|
188
|
-
// Inline handler - routes were registered with correct parent inside layout
|
|
189
253
|
return [wrappedItems].flat(3);
|
|
190
|
-
}
|
|
254
|
+
},
|
|
191
255
|
);
|
|
192
256
|
pushMetric?.("manifest:handler-exec", handlerExecStart);
|
|
193
257
|
|
|
194
258
|
const validationStart = performance.now();
|
|
195
259
|
invariant(
|
|
196
260
|
useItems && useItems.length > 0,
|
|
197
|
-
"Did not receive any handler from router.map()"
|
|
261
|
+
"Did not receive any handler from router.map()",
|
|
198
262
|
);
|
|
199
263
|
// For non-lazy entries the root handler is wrapped in MapRootLayout,
|
|
200
264
|
// so the result always contains a layout item. Lazy entries run the
|
|
@@ -203,13 +267,13 @@ export async function loadManifest(
|
|
|
203
267
|
if (!lazyContext) {
|
|
204
268
|
invariant(
|
|
205
269
|
useItems.some((item: { type: string }) => item.type === "layout"),
|
|
206
|
-
"Top-level handler must be a layout"
|
|
270
|
+
"Top-level handler must be a layout",
|
|
207
271
|
);
|
|
208
272
|
}
|
|
209
273
|
|
|
210
274
|
invariant(
|
|
211
275
|
Store.manifest.has(routeKey),
|
|
212
|
-
`Route must be registered for ${routeKey}
|
|
276
|
+
`Route must be registered for ${routeKey}`,
|
|
213
277
|
);
|
|
214
278
|
pushMetric?.("manifest:validation", validationStart);
|
|
215
279
|
|
|
@@ -218,6 +282,16 @@ export async function loadManifest(
|
|
|
218
282
|
|
|
219
283
|
return Store.manifest.get(routeKey)!;
|
|
220
284
|
} catch (e) {
|
|
285
|
+
// A tagged async-include module-load failure is a server error for a REAL
|
|
286
|
+
// matched route — re-raise it unchanged (becomes a 5xx) instead of masking
|
|
287
|
+
// it as a RouteNotFoundError (which renders/caches a 404).
|
|
288
|
+
if (
|
|
289
|
+
e &&
|
|
290
|
+
typeof e === "object" &&
|
|
291
|
+
(e as Record<PropertyKey, unknown>)[MODULE_LOAD_FAILURE]
|
|
292
|
+
) {
|
|
293
|
+
throw e;
|
|
294
|
+
}
|
|
221
295
|
throw new RouteNotFoundError(
|
|
222
296
|
`Failed to load route handlers for ${path}: ${(e as Error).message}`,
|
|
223
297
|
{
|
|
@@ -228,7 +302,7 @@ export async function loadManifest(
|
|
|
228
302
|
routeKey,
|
|
229
303
|
},
|
|
230
304
|
},
|
|
231
|
-
}
|
|
305
|
+
},
|
|
232
306
|
);
|
|
233
307
|
}
|
|
234
308
|
}
|