@rangojs/router 0.0.0-experimental.1878aa49 → 0.0.0-experimental.190fb30d
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 +8 -4
- package/README.md +303 -741
- package/dist/bin/rango.js +605 -146
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +4117 -1211
- package/dist/vite/index.js.bak +5448 -0
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/package.json +86 -15
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +85 -6
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +228 -33
- package/skills/caching/SKILL.md +336 -19
- package/skills/catalog.json +271 -0
- 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 +110 -4
- package/skills/css/SKILL.md +76 -0
- package/skills/debug-manifest/SKILL.md +5 -3
- package/skills/defer-hydration/SKILL.md +235 -0
- package/skills/document-cache/SKILL.md +87 -56
- package/skills/fonts/SKILL.md +1 -1
- package/skills/handler-use/SKILL.md +364 -0
- package/skills/hooks/SKILL.md +73 -691
- package/skills/hooks/data.md +273 -0
- package/skills/hooks/handle-and-actions.md +103 -0
- package/skills/hooks/navigation.md +110 -0
- package/skills/hooks/outlets.md +41 -0
- package/skills/hooks/state.md +228 -0
- package/skills/hooks/urls.md +135 -0
- package/skills/host-router/SKILL.md +129 -27
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +94 -18
- package/skills/layout/SKILL.md +62 -19
- package/skills/links/SKILL.md +247 -17
- package/skills/loader/SKILL.md +248 -10
- package/skills/middleware/SKILL.md +57 -16
- package/skills/migrate-nextjs/SKILL.md +745 -0
- package/skills/migrate-react-router/SKILL.md +153 -0
- package/skills/migrate-react-router/cloudflare-workers.md +129 -0
- package/skills/migrate-react-router/component-migration.md +196 -0
- package/skills/migrate-react-router/data-and-actions.md +225 -0
- package/skills/migrate-react-router/route-mapping.md +271 -0
- package/skills/mime-routes/SKILL.md +29 -2
- package/skills/observability/SKILL.md +202 -0
- package/skills/parallel/SKILL.md +99 -10
- package/skills/ppr/SKILL.md +618 -0
- package/skills/prerender/SKILL.md +178 -124
- package/skills/rango/SKILL.md +318 -24
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +138 -49
- package/skills/route/SKILL.md +141 -9
- package/skills/router-setup/SKILL.md +44 -9
- package/skills/scripts/SKILL.md +179 -0
- package/skills/server-actions/SKILL.md +776 -0
- package/skills/shell-manifest/SKILL.md +185 -0
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/tailwind/SKILL.md +28 -4
- package/skills/testing/SKILL.md +130 -0
- 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 +1 -1
- package/skills/typesafety/SKILL.md +45 -626
- package/skills/typesafety/env-and-bindings.md +254 -0
- package/skills/typesafety/generated-files-and-cli.md +335 -0
- package/skills/typesafety/params-and-search.md +153 -0
- package/skills/typesafety/route-types.md +209 -0
- package/skills/use-cache/SKILL.md +74 -15
- 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 +1 -66
- package/src/browser/action-coordinator.ts +53 -36
- package/src/browser/action-fence.ts +47 -0
- package/src/browser/app-shell.ts +39 -0
- package/src/browser/connection-warmup.ts +134 -0
- package/src/browser/cookie-name.ts +140 -0
- package/src/browser/event-controller.ts +252 -158
- package/src/browser/history-state.ts +21 -0
- package/src/browser/index.ts +3 -3
- package/src/browser/invalidate-client-cache.ts +52 -0
- package/src/browser/logging.ts +28 -0
- package/src/browser/merge-segment-loaders.ts +6 -4
- package/src/browser/navigation-bridge.ts +115 -27
- package/src/browser/navigation-client.ts +163 -70
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +161 -73
- package/src/browser/navigation-transaction.ts +9 -59
- package/src/browser/network-error-handler.ts +34 -7
- package/src/browser/partial-update.ts +186 -135
- package/src/browser/prefetch/cache.ts +246 -71
- package/src/browser/prefetch/fetch.ts +350 -38
- package/src/browser/prefetch/queue.ts +61 -12
- package/src/browser/rango-state.ts +158 -76
- package/src/browser/react/Link.tsx +70 -9
- package/src/browser/react/NavigationProvider.tsx +202 -120
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/filter-segment-order.ts +66 -7
- package/src/browser/react/index.ts +0 -48
- package/src/browser/react/location-state-shared.ts +178 -8
- package/src/browser/react/location-state.ts +39 -14
- package/src/browser/react/use-action.ts +6 -15
- package/src/browser/react/use-handle.ts +23 -69
- package/src/browser/react/use-href.tsx +8 -1
- package/src/browser/react/use-link-status.ts +33 -8
- package/src/browser/react/use-navigation.ts +32 -7
- package/src/browser/react/use-params.ts +20 -10
- package/src/browser/react/use-reverse.ts +106 -0
- package/src/browser/react/use-router.ts +25 -3
- package/src/browser/react/use-search-params.ts +0 -5
- package/src/browser/react/use-segments.ts +11 -21
- package/src/browser/response-adapter.ts +99 -8
- package/src/browser/rsc-router.tsx +145 -28
- package/src/browser/scroll-restoration.ts +44 -27
- package/src/browser/segment-reconciler.ts +44 -12
- package/src/browser/segment-structure-assert.ts +2 -2
- package/src/browser/server-action-bridge.ts +236 -65
- package/src/browser/types.ts +102 -9
- package/src/browser/validate-redirect-origin.ts +43 -16
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +205 -159
- package/src/build/generate-route-types.ts +3 -1
- package/src/build/index.ts +11 -3
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +198 -41
- package/src/build/route-types/ast-route-extraction.ts +15 -8
- package/src/build/route-types/codegen.ts +16 -5
- package/src/build/route-types/include-resolution.ts +456 -62
- package/src/build/route-types/param-extraction.ts +6 -3
- package/src/build/route-types/per-module-writer.ts +22 -6
- package/src/build/route-types/router-processing.ts +128 -51
- package/src/build/route-types/scan-filter.ts +9 -2
- package/src/build/route-types/source-scan.ts +216 -0
- package/src/build/runtime-discovery.ts +13 -21
- package/src/cache/cache-error.ts +104 -0
- package/src/cache/cache-key-utils.ts +58 -13
- package/src/cache/cache-policy.ts +108 -34
- package/src/cache/cache-runtime.ts +454 -101
- package/src/cache/cache-scope.ts +187 -96
- package/src/cache/cache-tag.ts +149 -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 +2206 -372
- 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 +6 -16
- package/src/cache/document-cache.ts +126 -41
- package/src/cache/handle-snapshot.ts +70 -0
- package/src/cache/index.ts +23 -20
- package/src/cache/memory-segment-store.ts +243 -37
- package/src/cache/profile-registry.ts +46 -31
- package/src/cache/read-through-swr.ts +56 -12
- package/src/cache/segment-codec.ts +13 -21
- package/src/cache/shell-snapshot.ts +417 -0
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/types.ts +194 -99
- package/src/cache/vercel/index.ts +11 -0
- package/src/cache/vercel/vercel-cache-store.ts +1132 -0
- package/src/client.rsc.tsx +41 -21
- package/src/client.tsx +116 -290
- package/src/cloudflare/index.ts +11 -0
- package/src/cloudflare/tracing.ts +108 -0
- package/src/component-utils.ts +19 -0
- package/src/components/DefaultDocument.tsx +8 -2
- package/src/context-var.ts +18 -6
- 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 +30 -4
- package/src/escape-script.ts +52 -0
- package/src/handle.ts +104 -34
- package/src/handles/MetaTags.tsx +24 -53
- package/src/handles/Scripts.tsx +183 -0
- package/src/handles/breadcrumbs.ts +35 -8
- package/src/handles/deferred-resolution.ts +127 -0
- package/src/handles/is-thenable.ts +18 -0
- package/src/handles/meta.ts +14 -40
- package/src/handles/script.ts +244 -0
- package/src/host/cookie-handler.ts +9 -60
- package/src/host/errors.ts +13 -22
- package/src/host/index.ts +9 -2
- package/src/host/pattern-matcher.ts +23 -52
- package/src/host/router.ts +107 -99
- package/src/host/testing.ts +40 -27
- package/src/host/types.ts +37 -4
- package/src/host/utils.ts +1 -1
- package/src/href-client.ts +137 -22
- package/src/index.rsc.ts +100 -13
- package/src/index.ts +143 -19
- package/src/internal-debug.ts +11 -10
- package/src/loader-store.ts +500 -0
- package/src/loader.rsc.ts +20 -13
- package/src/loader.ts +12 -11
- package/src/missing-id-error.ts +68 -0
- package/src/outlet-context.ts +1 -1
- package/src/outlet-provider.tsx +1 -5
- package/src/prerender/param-hash.ts +16 -16
- package/src/prerender/store.ts +37 -41
- package/src/prerender.ts +215 -86
- package/src/redirect-origin.ts +114 -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 +65 -15
- package/src/root-error-boundary.tsx +1 -19
- package/src/route-content-wrapper.tsx +19 -77
- package/src/route-definition/dsl-helpers.ts +461 -304
- package/src/route-definition/helper-factories.ts +28 -140
- package/src/route-definition/helpers-types.ts +147 -72
- package/src/route-definition/index.ts +4 -2
- package/src/route-definition/redirect.ts +44 -11
- package/src/route-definition/resolve-handler-use.ts +160 -0
- package/src/route-definition/use-item-types.ts +29 -0
- package/src/route-map-builder.ts +41 -20
- package/src/route-types.ts +37 -46
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +164 -17
- package/src/router/error-handling.ts +45 -18
- package/src/router/find-match.ts +129 -30
- package/src/router/handler-context.ts +47 -22
- package/src/router/instrument.ts +355 -0
- package/src/router/intercept-resolution.ts +39 -20
- package/src/router/lazy-includes.ts +85 -62
- package/src/router/loader-resolution.ts +277 -54
- package/src/router/logging.ts +0 -6
- package/src/router/manifest.ts +97 -57
- package/src/router/match-api.ts +178 -218
- package/src/router/match-context.ts +0 -22
- package/src/router/match-handlers.ts +211 -165
- package/src/router/match-middleware/background-revalidation.ts +40 -24
- package/src/router/match-middleware/cache-lookup.ts +168 -277
- package/src/router/match-middleware/cache-store.ts +64 -52
- package/src/router/match-middleware/intercept-resolution.ts +0 -22
- package/src/router/match-middleware/segment-resolution.ts +45 -14
- package/src/router/match-pipelines.ts +1 -42
- package/src/router/match-result.ts +113 -45
- package/src/router/metrics.ts +0 -34
- package/src/router/middleware-types.ts +7 -134
- package/src/router/middleware.ts +298 -172
- 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 +181 -150
- package/src/router/prefetch-cache-ttl.ts +51 -0
- package/src/router/prefetch-limits.ts +37 -0
- package/src/router/prerender-match.ts +201 -56
- package/src/router/preview-match.ts +35 -103
- package/src/router/request-classification.ts +291 -0
- package/src/router/revalidation.ts +123 -73
- package/src/router/route-snapshot.ts +256 -0
- package/src/router/router-context.ts +6 -29
- package/src/router/router-interfaces.ts +125 -35
- package/src/router/router-options.ts +166 -5
- package/src/router/router-registry.ts +2 -5
- package/src/router/segment-resolution/fresh.ts +188 -86
- package/src/router/segment-resolution/helpers.ts +86 -6
- package/src/router/segment-resolution/loader-cache.ts +155 -39
- package/src/router/segment-resolution/loader-mask.ts +67 -0
- package/src/router/segment-resolution/loader-snapshot.ts +308 -0
- package/src/router/segment-resolution/revalidation.ts +344 -319
- package/src/router/segment-resolution/static-store.ts +19 -5
- 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 +5 -1
- package/src/router/segment-wrappers.ts +6 -5
- package/src/router/state-cookie-name.ts +33 -0
- package/src/router/substitute-pattern-params.ts +75 -0
- package/src/router/telemetry-otel.ts +160 -200
- package/src/router/telemetry.ts +105 -20
- package/src/router/timeout.ts +0 -20
- package/src/router/tracing.ts +215 -0
- package/src/router/trie-matching.ts +171 -59
- package/src/router/types.ts +9 -63
- package/src/router/url-params.ts +57 -0
- package/src/router.ts +170 -72
- package/src/rsc/full-payload.ts +70 -0
- package/src/rsc/handler-context.ts +3 -2
- package/src/rsc/handler.ts +678 -513
- package/src/rsc/helpers.ts +168 -46
- package/src/rsc/index.ts +2 -5
- package/src/rsc/json-route-result.ts +38 -0
- package/src/rsc/loader-fetch.ts +127 -31
- package/src/rsc/manifest-init.ts +29 -42
- package/src/rsc/nonce.ts +10 -1
- package/src/rsc/origin-guard.ts +39 -25
- package/src/rsc/progressive-enhancement.ts +134 -15
- package/src/rsc/redirect-guard.ts +100 -0
- package/src/rsc/response-cache-serve.ts +238 -0
- package/src/rsc/response-error.ts +79 -12
- package/src/rsc/response-route-handler.ts +99 -189
- package/src/rsc/rsc-rendering.ts +497 -77
- package/src/rsc/runtime-warnings.ts +23 -10
- package/src/rsc/server-action.ts +286 -114
- package/src/rsc/shell-capture.ts +1166 -0
- package/src/rsc/shell-serve.ts +181 -0
- package/src/rsc/ssr-setup.ts +17 -1
- package/src/rsc/transition-gate.ts +89 -0
- package/src/rsc/types.ts +54 -5
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +35 -30
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-loader-promise.ts +167 -0
- package/src/segment-system.tsx +355 -204
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +247 -54
- package/src/server/cookie-parse.ts +32 -0
- package/src/server/cookie-store.ts +152 -5
- package/src/server/handle-store.ts +40 -38
- package/src/server/loader-registry.ts +33 -42
- package/src/server/request-context.ts +502 -161
- package/src/ssr/index.tsx +467 -178
- package/src/ssr/inject-rsc-eager.ts +167 -0
- package/src/ssr/ssr-root.tsx +228 -0
- package/src/static-handler.ts +27 -18
- package/src/testing/cache-status.ts +162 -0
- package/src/testing/collect-handle.ts +46 -0
- package/src/testing/dispatch.ts +813 -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 +56 -84
- package/src/theme/ThemeScript.tsx +7 -9
- package/src/theme/constants.ts +52 -13
- package/src/theme/index.ts +0 -7
- package/src/theme/theme-context.ts +1 -5
- package/src/theme/theme-script.ts +22 -21
- package/src/theme/use-theme.ts +0 -3
- package/src/types/boundaries.ts +0 -35
- package/src/types/cache-types.ts +13 -4
- package/src/types/error-types.ts +30 -90
- package/src/types/global-namespace.ts +54 -41
- package/src/types/handler-context.ts +120 -62
- package/src/types/index.ts +3 -10
- package/src/types/loader-types.ts +40 -10
- package/src/types/request-scope.ts +112 -0
- package/src/types/route-config.ts +20 -52
- package/src/types/route-entry.ts +12 -7
- package/src/types/segments.ts +136 -15
- package/src/urls/include-helper.ts +40 -75
- package/src/urls/include-provider.ts +71 -0
- package/src/urls/index.ts +2 -11
- package/src/urls/path-helper-types.ts +102 -23
- package/src/urls/path-helper.ts +62 -111
- package/src/urls/pattern-types.ts +72 -19
- package/src/urls/response-types.ts +25 -22
- package/src/urls/type-extraction.ts +98 -154
- package/src/urls/urls-function.ts +1 -19
- package/src/use-loader.tsx +346 -89
- 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 +36 -38
- package/src/vite/discovery/dev-prerender-cache.ts +117 -0
- package/src/vite/discovery/discover-routers.ts +127 -86
- 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 +214 -132
- package/src/vite/discovery/route-types-writer.ts +40 -84
- package/src/vite/discovery/self-gen-tracking.ts +27 -1
- package/src/vite/discovery/state.ts +57 -4
- package/src/vite/discovery/virtual-module-codegen.ts +14 -34
- package/src/vite/index.ts +15 -0
- package/src/vite/inject-client-debug.ts +88 -0
- package/src/vite/plugin-types.ts +261 -6
- package/src/vite/plugins/cjs-to-esm.ts +16 -19
- package/src/vite/plugins/client-ref-dedup.ts +16 -11
- package/src/vite/plugins/client-ref-hashing.ts +28 -15
- 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/plugins/expose-action-id.ts +48 -95
- package/src/vite/plugins/expose-id-utils.ts +96 -51
- package/src/vite/plugins/expose-ids/export-analysis.ts +101 -34
- package/src/vite/plugins/expose-ids/handler-transform.ts +15 -64
- package/src/vite/plugins/expose-ids/loader-transform.ts +14 -24
- package/src/vite/plugins/expose-ids/router-transform.ts +118 -29
- package/src/vite/plugins/expose-internal-ids.ts +553 -317
- package/src/vite/plugins/performance-tracks.ts +26 -25
- package/src/vite/plugins/refresh-cmd.ts +89 -27
- package/src/vite/plugins/use-cache-transform.ts +73 -83
- package/src/vite/plugins/vercel-output.ts +384 -0
- package/src/vite/plugins/version-injector.ts +40 -29
- package/src/vite/plugins/version-plugin.ts +37 -40
- package/src/vite/plugins/virtual-entries.ts +138 -27
- package/src/vite/rango.ts +238 -139
- package/src/vite/router-discovery.ts +1091 -159
- package/src/vite/utils/ast-handler-extract.ts +26 -35
- package/src/vite/utils/banner.ts +1 -1
- package/src/vite/utils/bundle-analysis.ts +10 -15
- 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 +4 -59
- package/src/vite/utils/package-resolution.ts +20 -52
- package/src/vite/utils/prerender-utils.ts +98 -38
- package/src/vite/utils/shared-utils.ts +142 -43
- package/src/browser/action-response-classifier.ts +0 -99
- package/src/browser/react/use-client-cache.ts +0 -58
- package/src/browser/shallow.ts +0 -40
- package/src/handles/index.ts +0 -7
- package/src/network-error-thrower.tsx +0 -23
- package/src/router/middleware-cookies.ts +0 -55
package/src/router/manifest.ts
CHANGED
|
@@ -1,9 +1,3 @@
|
|
|
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
3
|
import {
|
|
@@ -14,29 +8,38 @@ import {
|
|
|
14
8
|
type MetricsStore,
|
|
15
9
|
} from "../server/context";
|
|
16
10
|
import MapRootLayout from "../server/root-layout";
|
|
11
|
+
import { joinPrefix } from "./pattern-matching.js";
|
|
17
12
|
import type { RouteEntry } from "../types";
|
|
18
13
|
import type { UrlPatterns } from "../urls";
|
|
14
|
+
import {
|
|
15
|
+
isIncludeProvider,
|
|
16
|
+
resolveIncludeModule,
|
|
17
|
+
} from "../urls/include-provider.js";
|
|
19
18
|
import { VERSION } from "@rangojs/router:version";
|
|
20
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
|
+
|
|
21
25
|
// Module-level manifest cache: avoids re-executing DSL handler on every request.
|
|
22
26
|
// Handler execution is deterministic (components, loaders, middleware are module-level
|
|
23
27
|
// stable references), so the resulting EntryData tree can be safely cached and reused
|
|
24
28
|
// across requests within the same isolate.
|
|
25
29
|
//
|
|
26
|
-
// 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
|
|
27
39
|
// @rangojs/router:version virtual module which Vite invalidates on RSC module HMR.
|
|
28
40
|
// When VERSION changes, this module re-evaluates and the cache is recreated empty.
|
|
29
|
-
// Including VERSION in the key is additional defense against stale entries.
|
|
30
41
|
const manifestModuleCache = new Map<string, Map<string, EntryData>>();
|
|
31
42
|
|
|
32
|
-
/**
|
|
33
|
-
* Load manifest from route entry with AsyncLocalStorage context
|
|
34
|
-
* Handles lazy imports, unwrapping, and validation
|
|
35
|
-
*
|
|
36
|
-
* Results are cached at module level after first execution. Subsequent calls
|
|
37
|
-
* for the same (routeKey, isSSR) within the same isolate return cached data
|
|
38
|
-
* without re-executing the DSL handler.
|
|
39
|
-
*/
|
|
40
43
|
/**
|
|
41
44
|
* Clear the module-level manifest cache.
|
|
42
45
|
* Called on HMR to ensure stale handler references are discarded.
|
|
@@ -65,9 +68,11 @@ export async function loadManifest(
|
|
|
65
68
|
|
|
66
69
|
const mountIndex = entry.mountIndex;
|
|
67
70
|
|
|
68
|
-
// Check module-level cache (persists across requests within same isolate)
|
|
71
|
+
// Check module-level cache (persists across requests within same isolate).
|
|
69
72
|
// Include routerId so multi-router setups (host routing) don't share cached
|
|
70
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.
|
|
71
76
|
const cacheKey = `${VERSION}:${entry.routerId ?? ""}:${mountIndex ?? ""}:${routeKey}:${isSSR ? 1 : 0}`;
|
|
72
77
|
const cached = manifestModuleCache.get(cacheKey);
|
|
73
78
|
if (cached) {
|
|
@@ -77,10 +82,14 @@ export async function loadManifest(
|
|
|
77
82
|
Store.mountIndex = mountIndex;
|
|
78
83
|
Store.isSSR = isSSR;
|
|
79
84
|
if (metricsStore) Store.metrics = metricsStore;
|
|
80
|
-
//
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
85
|
+
// Alias the request-scoped Store to the cached Map instead of copying it
|
|
86
|
+
// entry-by-entry. At request time this Store is throwaway (no ambient
|
|
87
|
+
// RangoContext store spans classify->match->render, so getOrCreateStore
|
|
88
|
+
// returns a fresh detached store here), so nothing mutates it in place after
|
|
89
|
+
// loadManifest returns. The fresh path below REASSIGNS Store.manifest rather
|
|
90
|
+
// than clearing it in place, so a later fresh load sharing this Store cannot
|
|
91
|
+
// poison the cached Map.
|
|
92
|
+
Store.manifest = cached;
|
|
84
93
|
pushMetric?.("manifest:cache-hit", cacheStart);
|
|
85
94
|
return cached.get(routeKey)!;
|
|
86
95
|
}
|
|
@@ -88,22 +97,21 @@ export async function loadManifest(
|
|
|
88
97
|
const storeSetupStart = performance.now();
|
|
89
98
|
const Store = getContext().getOrCreateStore(routeKey);
|
|
90
99
|
|
|
91
|
-
// Set mount index in store for unique shortCode prefixes
|
|
92
100
|
Store.mountIndex = mountIndex;
|
|
93
|
-
|
|
94
|
-
// Set isSSR flag so loading() can check if we're in SSR
|
|
95
101
|
Store.isSSR = isSSR;
|
|
96
102
|
|
|
97
|
-
// Attach metrics store to context if provided
|
|
98
103
|
if (metricsStore) {
|
|
99
104
|
Store.metrics = metricsStore;
|
|
100
105
|
}
|
|
101
106
|
|
|
102
107
|
pushMetric?.("manifest:store-setup", storeSetupStart);
|
|
103
108
|
|
|
104
|
-
// Clear manifest before rebuilding to prevent stale entry mutations
|
|
105
109
|
const clearStart = performance.now();
|
|
106
|
-
|
|
110
|
+
// Reassign rather than clear() in place: a prior cache-hit may have aliased
|
|
111
|
+
// Store.manifest to a shared module-cache Map (see cache-hit branch above),
|
|
112
|
+
// and clearing it in place would poison that cache. A fresh Map isolates this
|
|
113
|
+
// build; the cache still receives an independent copy at the end.
|
|
114
|
+
Store.manifest = new Map();
|
|
107
115
|
pushMetric?.("manifest:clear", clearStart);
|
|
108
116
|
|
|
109
117
|
try {
|
|
@@ -126,28 +134,37 @@ export async function loadManifest(
|
|
|
126
134
|
// were created during pattern extraction. This prevents shortCode
|
|
127
135
|
// collisions between lazy and non-lazy entries under the same parent
|
|
128
136
|
// (e.g., ArticlesLayout and BlogLayout both under NavLayout).
|
|
129
|
-
if (lazyContext
|
|
130
|
-
const
|
|
131
|
-
for (const [key, value] of Object.entries(captured)) {
|
|
137
|
+
if (lazyContext?.counters) {
|
|
138
|
+
for (const [key, value] of Object.entries(lazyContext.counters)) {
|
|
132
139
|
Store.counters[key] = Math.max(Store.counters[key] ?? 0, value);
|
|
133
140
|
}
|
|
134
141
|
}
|
|
135
142
|
|
|
136
143
|
// Propagate cache profiles for DSL-time cache("profileName") resolution.
|
|
137
144
|
// Non-lazy entries carry profiles directly; lazy entries carry them
|
|
138
|
-
// in the captured lazyContext from include() time.
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
145
|
+
// in the captured lazyContext from include() time. Always write
|
|
146
|
+
// (including clearing to undefined) so a prior lazy build's profile
|
|
147
|
+
// map cannot leak into a later non-lazy build on the same ALS-backed
|
|
148
|
+
// Store — which would otherwise let cache("name") resolve a profile
|
|
149
|
+
// from an unrelated entry.
|
|
150
|
+
Store.cacheProfiles = entry.cacheProfiles ?? lazyContext?.cacheProfiles;
|
|
144
151
|
|
|
145
152
|
// Propagate rootScoped from lazyContext so that routes inside
|
|
146
153
|
// nested { name: "sub" } under { name: "" } keep inherited root scope
|
|
147
|
-
// when the manifest is rebuilt on each request.
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
154
|
+
// when the manifest is rebuilt on each request. Always write
|
|
155
|
+
// (including clearing to undefined, which makes getRootScoped()
|
|
156
|
+
// return its true default) so a prior lazy build's scope cannot leak
|
|
157
|
+
// into a later non-lazy build on the same ALS-backed Store — which
|
|
158
|
+
// would otherwise mis-register plain routes as non-root-scoped and
|
|
159
|
+
// break dot-local reverse resolution.
|
|
160
|
+
Store.rootScoped = lazyContext?.rootScoped;
|
|
161
|
+
|
|
162
|
+
// Propagate includeScope from lazyContext so that direct-descendant
|
|
163
|
+
// shortCodes of this include use the correct scoped counter namespace
|
|
164
|
+
// on every manifest rebuild. Always write (including clearing to
|
|
165
|
+
// undefined) so a prior lazy build's scope cannot leak into a later
|
|
166
|
+
// non-lazy build on the same ALS-backed Store.
|
|
167
|
+
Store.includeScope = lazyContext?.includeScope;
|
|
151
168
|
|
|
152
169
|
const handlerExecStart = performance.now();
|
|
153
170
|
const useItems = await getContext().runWithStore(
|
|
@@ -165,9 +182,35 @@ export async function loadManifest(
|
|
|
165
182
|
// not exist in the non-lazy (root handler) path and would produce
|
|
166
183
|
// mismatched shortCodes.
|
|
167
184
|
if (entry.lazy && entry.lazyPatterns) {
|
|
185
|
+
// Resolve an async include provider (`() => import("./routes")`) before
|
|
186
|
+
// running its handler. The match-time precomputed shortcut can skip
|
|
187
|
+
// evaluateLazyEntry's resolution, so render-time must resolve it here;
|
|
188
|
+
// cache the resolved patterns on the entry so later renders reuse them.
|
|
189
|
+
if (isIncludeProvider(entry.lazyPatterns)) {
|
|
190
|
+
try {
|
|
191
|
+
entry.lazyPatterns = resolveIncludeModule(
|
|
192
|
+
await entry.lazyPatterns(),
|
|
193
|
+
entry.staticPrefix,
|
|
194
|
+
) as unknown as UrlPatterns<any>;
|
|
195
|
+
} catch (err) {
|
|
196
|
+
// A failed dynamic import of a REAL, matched route's module is a
|
|
197
|
+
// server error, not a missing route. Tag it so the outer catch
|
|
198
|
+
// surfaces it as a 5xx instead of masking it as a
|
|
199
|
+
// RouteNotFoundError — which renders the 404 page (monitoring
|
|
200
|
+
// misses the failure and a CDN could cache the 404).
|
|
201
|
+
if (err && typeof err === "object") {
|
|
202
|
+
(err as Record<PropertyKey, unknown>)[MODULE_LOAD_FAILURE] =
|
|
203
|
+
true;
|
|
204
|
+
}
|
|
205
|
+
throw err;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
168
208
|
const lazyPatterns = entry.lazyPatterns as UrlPatterns<any>;
|
|
169
209
|
const includePrefix = (entry as any)._lazyPrefix || "";
|
|
170
|
-
|
|
210
|
+
// Slash-collapsing join so a trailing-slash parent prefix does not
|
|
211
|
+
// bake a double slash into the registered route patterns (must match
|
|
212
|
+
// the same join in evaluateLazyEntry / the build-time runWithPrefixes).
|
|
213
|
+
const fullPrefix = joinPrefix(lazyContext?.urlPrefix, includePrefix);
|
|
171
214
|
|
|
172
215
|
if (fullPrefix || lazyContext?.namePrefix) {
|
|
173
216
|
return runWithPrefixes(fullPrefix, lazyContext?.namePrefix, () =>
|
|
@@ -177,28 +220,19 @@ export async function loadManifest(
|
|
|
177
220
|
return lazyPatterns.handler();
|
|
178
221
|
}
|
|
179
222
|
|
|
180
|
-
// Wrap handler execution in root layout so routes get correct parent
|
|
181
|
-
// This ensures all routes are registered with the layout as their parent
|
|
182
223
|
let promiseResult: Promise<any> | null = null;
|
|
183
224
|
const wrappedItems = helpers.layout(MapRootLayout, () => {
|
|
184
225
|
const result = entry.handler();
|
|
185
226
|
if (result instanceof Promise) {
|
|
186
|
-
// Lazy handler detected - capture promise for async handling
|
|
187
227
|
promiseResult = result;
|
|
188
|
-
return [];
|
|
228
|
+
return [];
|
|
189
229
|
}
|
|
190
230
|
return result;
|
|
191
231
|
});
|
|
192
232
|
|
|
193
|
-
// Handle lazy (Promise-based) handlers
|
|
194
233
|
if (promiseResult !== null) {
|
|
195
234
|
const load = await (promiseResult as Promise<any>);
|
|
196
|
-
if (
|
|
197
|
-
load &&
|
|
198
|
-
load !== null &&
|
|
199
|
-
typeof load === "object" &&
|
|
200
|
-
"default" in load
|
|
201
|
-
) {
|
|
235
|
+
if (load && typeof load === "object" && "default" in load) {
|
|
202
236
|
// Promise<{ default: () => Array }> - e.g., dynamic import
|
|
203
237
|
if (typeof load.default !== "function") {
|
|
204
238
|
throw new Error(
|
|
@@ -224,7 +258,6 @@ export async function loadManifest(
|
|
|
224
258
|
);
|
|
225
259
|
}
|
|
226
260
|
|
|
227
|
-
// Inline handler - routes were registered with correct parent inside layout
|
|
228
261
|
return [wrappedItems].flat(3);
|
|
229
262
|
},
|
|
230
263
|
);
|
|
@@ -248,10 +281,7 @@ export async function loadManifest(
|
|
|
248
281
|
|
|
249
282
|
invariant(
|
|
250
283
|
Store.manifest.has(routeKey),
|
|
251
|
-
`Route must be registered for ${routeKey}
|
|
252
|
-
`Registered keys: [${[...Store.manifest.keys()].join(", ")}]. ` +
|
|
253
|
-
`Entry lazy=${!!entry.lazy}, lazyContext.namePrefix=${lazyContext?.namePrefix ?? "(none)"}, ` +
|
|
254
|
-
`lazyContext.urlPrefix=${(lazyContext as any)?.urlPrefix ?? "(none)"}`,
|
|
284
|
+
`Route must be registered for ${routeKey}`,
|
|
255
285
|
);
|
|
256
286
|
pushMetric?.("manifest:validation", validationStart);
|
|
257
287
|
|
|
@@ -260,6 +290,16 @@ export async function loadManifest(
|
|
|
260
290
|
|
|
261
291
|
return Store.manifest.get(routeKey)!;
|
|
262
292
|
} catch (e) {
|
|
293
|
+
// A tagged async-include module-load failure is a server error for a REAL
|
|
294
|
+
// matched route — re-raise it unchanged (becomes a 5xx) instead of masking
|
|
295
|
+
// it as a RouteNotFoundError (which renders/caches a 404).
|
|
296
|
+
if (
|
|
297
|
+
e &&
|
|
298
|
+
typeof e === "object" &&
|
|
299
|
+
(e as Record<PropertyKey, unknown>)[MODULE_LOAD_FAILURE]
|
|
300
|
+
) {
|
|
301
|
+
throw e;
|
|
302
|
+
}
|
|
263
303
|
throw new RouteNotFoundError(
|
|
264
304
|
`Failed to load route handlers for ${path}: ${(e as Error).message}`,
|
|
265
305
|
{
|