@rangojs/router 0.0.0-experimental.b9cb8739 → 0.0.0-experimental.bdaf10aa
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 +730 -184
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +4344 -1335
- 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 +251 -24
- package/skills/caching/SKILL.md +375 -17
- 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 +249 -17
- package/skills/loader/SKILL.md +302 -54
- package/skills/middleware/SKILL.md +59 -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 +225 -10
- package/skills/ppr/SKILL.md +622 -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 +172 -9
- package/skills/router-setup/SKILL.md +131 -11
- 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 -616
- 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/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 +257 -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 +132 -33
- package/src/browser/navigation-client.ts +218 -68
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +203 -80
- package/src/browser/navigation-transaction.ts +18 -66
- package/src/browser/network-error-handler.ts +34 -7
- package/src/browser/partial-update.ts +241 -127
- package/src/browser/prefetch/cache.ts +271 -44
- package/src/browser/prefetch/fetch.ts +367 -40
- package/src/browser/prefetch/queue.ts +144 -23
- package/src/browser/prefetch/resource-ready.ts +77 -0
- package/src/browser/rango-state.ts +158 -76
- package/src/browser/react/Link.tsx +121 -16
- package/src/browser/react/NavigationProvider.tsx +240 -122
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/context.ts +7 -2
- 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 +46 -11
- 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 +272 -80
- package/src/browser/scroll-restoration.ts +56 -22
- package/src/browser/segment-reconciler.ts +44 -7
- package/src/browser/segment-structure-assert.ts +2 -2
- package/src/browser/server-action-bridge.ts +244 -71
- package/src/browser/types.ts +136 -12
- package/src/browser/validate-redirect-origin.ts +43 -16
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +207 -158
- package/src/build/generate-route-types.ts +6 -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 +464 -63
- 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 +336 -110
- 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 -97
- package/src/cache/cache-scope.ts +235 -103
- 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 +2446 -170
- 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 +11 -17
- package/src/cache/document-cache.ts +144 -49
- package/src/cache/handle-snapshot.ts +70 -0
- package/src/cache/index.ts +24 -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/taint.ts +55 -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 +84 -2
- package/src/debug.ts +2 -2
- 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 +485 -303
- package/src/route-definition/helper-factories.ts +28 -140
- package/src/route-definition/helpers-types.ts +153 -77
- package/src/route-definition/index.ts +4 -2
- package/src/route-definition/redirect.ts +53 -12
- 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 +48 -21
- 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 +130 -29
- package/src/router/handler-context.ts +83 -39
- package/src/router/instrument.ts +355 -0
- package/src/router/intercept-resolution.ts +50 -24
- package/src/router/lazy-includes.ts +89 -63
- package/src/router/loader-resolution.ts +286 -56
- package/src/router/logging.ts +5 -8
- package/src/router/manifest.ts +105 -56
- 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 +66 -22
- package/src/router/match-middleware/cache-lookup.ts +214 -263
- package/src/router/match-middleware/cache-store.ts +105 -50
- package/src/router/match-middleware/intercept-resolution.ts +8 -28
- package/src/router/match-middleware/segment-resolution.ts +52 -18
- package/src/router/match-pipelines.ts +1 -42
- package/src/router/match-result.ts +128 -44
- package/src/router/metrics.ts +5 -34
- package/src/router/middleware-types.ts +13 -142
- package/src/router/middleware.ts +301 -177
- 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 +203 -58
- 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 +11 -29
- package/src/router/router-interfaces.ts +146 -35
- package/src/router/router-options.ts +202 -15
- package/src/router/router-registry.ts +2 -5
- package/src/router/segment-resolution/fresh.ts +301 -78
- package/src/router/segment-resolution/helpers.ts +115 -30
- package/src/router/segment-resolution/loader-cache.ts +156 -39
- package/src/router/segment-resolution/loader-mask.ts +60 -0
- package/src/router/segment-resolution/loader-snapshot.ts +259 -0
- package/src/router/segment-resolution/mask-nested.ts +83 -0
- package/src/router/segment-resolution/revalidation.ts +477 -385
- 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 +8 -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 +10 -63
- package/src/router/url-params.ts +57 -0
- package/src/router.ts +210 -71
- package/src/rsc/full-payload.ts +70 -0
- package/src/rsc/handler-context.ts +3 -2
- package/src/rsc/handler.ts +682 -508
- 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 +33 -42
- package/src/rsc/nonce.ts +10 -1
- package/src/rsc/origin-guard.ts +39 -25
- package/src/rsc/progressive-enhancement.ts +138 -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 +509 -73
- package/src/rsc/runtime-warnings.ts +23 -10
- package/src/rsc/server-action.ts +287 -113
- package/src/rsc/shell-capture.ts +1190 -0
- package/src/rsc/shell-serve.ts +181 -0
- package/src/rsc/ssr-setup.ts +18 -2
- package/src/rsc/transition-gate.ts +89 -0
- package/src/rsc/types.ts +62 -6
- 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 +449 -132
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +367 -61
- 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 +38 -46
- package/src/server/request-context.ts +558 -173
- package/src/ssr/index.tsx +491 -174
- 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 +17 -8
- package/src/types/error-types.ts +30 -90
- package/src/types/global-namespace.ts +54 -41
- package/src/types/handler-context.ts +234 -82
- package/src/types/index.ts +3 -10
- package/src/types/loader-types.ts +44 -15
- package/src/types/request-scope.ts +112 -0
- package/src/types/route-config.ts +20 -52
- package/src/types/route-entry.ts +19 -7
- package/src/types/segments.ts +137 -14
- 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 +84 -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 +130 -85
- 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 -6
- 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 +234 -62
- 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 +49 -98
- 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 +89 -0
- 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 +46 -37
- package/src/vite/plugins/virtual-entries.ts +138 -27
- package/src/vite/rango.ts +353 -303
- package/src/vite/router-discovery.ts +1090 -166
- package/src/vite/utils/ast-handler-extract.ts +26 -35
- package/src/vite/utils/banner.ts +4 -4
- 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 +144 -44
- 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
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Route Snapshot
|
|
3
|
+
*
|
|
4
|
+
* Pure data type representing the fully-resolved state of a single route match.
|
|
5
|
+
* Consolidates the duplicated findMatch + loadManifest + collectRouteMiddleware +
|
|
6
|
+
* cacheScope derivation that previously lived separately in preview-match.ts
|
|
7
|
+
* and match-api.ts.
|
|
8
|
+
*
|
|
9
|
+
* resolveRoute() is the factory: given a pathname and dependencies, it returns
|
|
10
|
+
* a RouteSnapshot (or redirect/null). Consumers (createMatchContextForFull,
|
|
11
|
+
* createMatchContextForPartial, previewMatch) read snapshot fields instead of
|
|
12
|
+
* re-deriving them.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import type { CacheScope } from "../cache/cache-scope.js";
|
|
16
|
+
import { createCacheScope } from "../cache/cache-scope.js";
|
|
17
|
+
import type { EntryData, MetricsStore } from "../server/context.js";
|
|
18
|
+
import { loadManifest } from "./manifest.js";
|
|
19
|
+
import { collectRouteMiddleware } from "./middleware.js";
|
|
20
|
+
import type { CollectedMiddleware } from "./middleware-types.js";
|
|
21
|
+
import { traverseBack } from "./pattern-matching.js";
|
|
22
|
+
import type { RouteMatchResult } from "./pattern-matching.js";
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Immutable snapshot of a resolved route match.
|
|
26
|
+
*
|
|
27
|
+
* Contains everything derivable from (pathname, findMatch, loadManifest)
|
|
28
|
+
* without request context, navigation state, or intercept logic.
|
|
29
|
+
*/
|
|
30
|
+
export interface RouteSnapshot<TEnv = any> {
|
|
31
|
+
/** Raw match result from the trie/pattern matcher */
|
|
32
|
+
matched: RouteMatchResult<TEnv>;
|
|
33
|
+
/** Resolved manifest entry (with loaded handler, loader, etc.) */
|
|
34
|
+
manifestEntry: EntryData;
|
|
35
|
+
/** All entries in the route chain (from traverseBack) */
|
|
36
|
+
entries: EntryData[];
|
|
37
|
+
/** Canonical route key (e.g. "blog.detail") */
|
|
38
|
+
routeKey: string;
|
|
39
|
+
/** Last segment of a dotted route key (e.g. "detail" from "blog.detail") */
|
|
40
|
+
localRouteName: string;
|
|
41
|
+
/** Extracted route params */
|
|
42
|
+
params: Record<string, string>;
|
|
43
|
+
/** Collected route-level middleware from the entry tree */
|
|
44
|
+
routeMiddleware: CollectedMiddleware[];
|
|
45
|
+
/** Merged cache scope from the entry chain */
|
|
46
|
+
cacheScope: CacheScope | null;
|
|
47
|
+
/** Whether the matched route is a passthrough route */
|
|
48
|
+
isPassthrough: boolean;
|
|
49
|
+
/** Response type for non-RSC routes (e.g. "application/json") */
|
|
50
|
+
responseType?: string;
|
|
51
|
+
/**
|
|
52
|
+
* The isSSR flag the manifest was resolved with. Recorded so consumers can
|
|
53
|
+
* decide whether the snapshot is reusable: a snapshot resolved with isSSR
|
|
54
|
+
* differs (loading({ ssr: false }) entries) and is cached under a different
|
|
55
|
+
* manifest partition, so the full (document) path only reuses an isSSR:true
|
|
56
|
+
* snapshot and the partial path only reuses a non-isSSR one. Undefined on
|
|
57
|
+
* inline snapshots (redirect / not-found) that are never reused.
|
|
58
|
+
*/
|
|
59
|
+
isSSR?: boolean;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export type ResolveRouteResult<TEnv = any> =
|
|
63
|
+
| { type: "match"; snapshot: RouteSnapshot<TEnv> }
|
|
64
|
+
| { type: "redirect"; redirectTo: string }
|
|
65
|
+
| null;
|
|
66
|
+
|
|
67
|
+
export interface ResolveRouteDeps<TEnv = any> {
|
|
68
|
+
findMatch: (
|
|
69
|
+
pathname: string,
|
|
70
|
+
) => RouteMatchResult<TEnv> | null | Promise<RouteMatchResult<TEnv> | null>;
|
|
71
|
+
metricsStore?: MetricsStore;
|
|
72
|
+
isSSR?: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* When true, skip entries array and cacheScope chain construction.
|
|
75
|
+
* Used by previewMatch which only needs matched, manifestEntry,
|
|
76
|
+
* routeMiddleware, and responseType — avoids an extra traverseBack
|
|
77
|
+
* allocation and cacheScope composition on the hot classification path.
|
|
78
|
+
*/
|
|
79
|
+
lite?: boolean;
|
|
80
|
+
/**
|
|
81
|
+
* When true, skip pushing the "route-matching" metric internally.
|
|
82
|
+
* Used by createMatchContextForPartial on the fresh path (no snapshot
|
|
83
|
+
* reuse) so it can measure current + prev + intercept-source findMatch
|
|
84
|
+
* calls under one combined "route-matching" metric. On the reuse path,
|
|
85
|
+
* the partial path emits "route-matching:nav" for the prev +
|
|
86
|
+
* intercept-source lookups only (current-route resolution was done
|
|
87
|
+
* during classification without metrics).
|
|
88
|
+
*/
|
|
89
|
+
skipRouteMatchMetric?: boolean;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Resolve a pathname into a RouteSnapshot.
|
|
94
|
+
*
|
|
95
|
+
* This is the single source of truth for route derivation. It performs:
|
|
96
|
+
* 1. findMatch(pathname)
|
|
97
|
+
* 2. Redirect check
|
|
98
|
+
* 3. loadManifest
|
|
99
|
+
* 4. Passthrough detection
|
|
100
|
+
* 5. collectRouteMiddleware
|
|
101
|
+
* 6. Cache scope chain
|
|
102
|
+
* 7. responseType + localRouteName extraction
|
|
103
|
+
*
|
|
104
|
+
* Metrics timing is preserved identically to the previous inline code.
|
|
105
|
+
*/
|
|
106
|
+
export async function resolveRoute<TEnv = any>(
|
|
107
|
+
pathname: string,
|
|
108
|
+
deps: ResolveRouteDeps<TEnv>,
|
|
109
|
+
): Promise<ResolveRouteResult<TEnv>> {
|
|
110
|
+
const {
|
|
111
|
+
metricsStore,
|
|
112
|
+
isSSR = false,
|
|
113
|
+
lite = false,
|
|
114
|
+
skipRouteMatchMetric = false,
|
|
115
|
+
} = deps;
|
|
116
|
+
|
|
117
|
+
const routeMatchStart =
|
|
118
|
+
metricsStore && !skipRouteMatchMetric ? performance.now() : 0;
|
|
119
|
+
const matched = await deps.findMatch(pathname);
|
|
120
|
+
if (metricsStore && !skipRouteMatchMetric) {
|
|
121
|
+
metricsStore.metrics.push({
|
|
122
|
+
label: "route-matching",
|
|
123
|
+
duration: performance.now() - routeMatchStart,
|
|
124
|
+
startTime: routeMatchStart - metricsStore.requestStart,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (!matched) {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (matched.redirectTo) {
|
|
133
|
+
return { type: "redirect", redirectTo: matched.redirectTo };
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const manifestStart = metricsStore ? performance.now() : 0;
|
|
137
|
+
const manifestEntry = await loadManifest(
|
|
138
|
+
matched.entry,
|
|
139
|
+
matched.routeKey,
|
|
140
|
+
pathname,
|
|
141
|
+
metricsStore,
|
|
142
|
+
isSSR,
|
|
143
|
+
);
|
|
144
|
+
if (metricsStore) {
|
|
145
|
+
metricsStore.metrics.push({
|
|
146
|
+
label: "manifest-loading",
|
|
147
|
+
duration: performance.now() - manifestStart,
|
|
148
|
+
startTime: manifestStart - metricsStore.requestStart,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const isPassthrough =
|
|
153
|
+
manifestEntry.type === "route" && manifestEntry.isPassthrough === true;
|
|
154
|
+
|
|
155
|
+
let entries: EntryData[];
|
|
156
|
+
let cacheScope: CacheScope | null = null;
|
|
157
|
+
if (lite) {
|
|
158
|
+
entries = [];
|
|
159
|
+
} else {
|
|
160
|
+
({ entries, cacheScope } = buildEntriesAndCacheScope(manifestEntry));
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const routeMiddleware = collectRouteMiddleware(
|
|
164
|
+
lite ? traverseBack(manifestEntry) : entries,
|
|
165
|
+
matched.params,
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
const responseType =
|
|
169
|
+
matched.responseType ||
|
|
170
|
+
(manifestEntry.type === "route" ? manifestEntry.responseType : undefined);
|
|
171
|
+
|
|
172
|
+
const localRouteName = matched.routeKey.includes(".")
|
|
173
|
+
? matched.routeKey.split(".").pop()!
|
|
174
|
+
: matched.routeKey;
|
|
175
|
+
|
|
176
|
+
return {
|
|
177
|
+
type: "match",
|
|
178
|
+
snapshot: {
|
|
179
|
+
matched,
|
|
180
|
+
manifestEntry,
|
|
181
|
+
entries,
|
|
182
|
+
routeKey: matched.routeKey,
|
|
183
|
+
localRouteName,
|
|
184
|
+
params: matched.params,
|
|
185
|
+
routeMiddleware,
|
|
186
|
+
cacheScope,
|
|
187
|
+
isPassthrough,
|
|
188
|
+
responseType,
|
|
189
|
+
isSSR,
|
|
190
|
+
},
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Fill in the entries and cacheScope fields on a lite snapshot.
|
|
196
|
+
*
|
|
197
|
+
* When classifyRequest produces a lite snapshot (entries=[], cacheScope=null),
|
|
198
|
+
* this function computes the missing fields from manifestEntry without
|
|
199
|
+
* re-running findMatch, loadManifest, or collectRouteMiddleware.
|
|
200
|
+
*
|
|
201
|
+
* If the snapshot already has entries, returns it as-is.
|
|
202
|
+
*/
|
|
203
|
+
export function ensureFullRouteSnapshot<TEnv = any>(
|
|
204
|
+
snapshot: RouteSnapshot<TEnv>,
|
|
205
|
+
): RouteSnapshot<TEnv> {
|
|
206
|
+
if (snapshot.entries.length > 0) {
|
|
207
|
+
return snapshot;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const { entries, cacheScope } = buildEntriesAndCacheScope(
|
|
211
|
+
snapshot.manifestEntry,
|
|
212
|
+
);
|
|
213
|
+
return { ...snapshot, entries, cacheScope };
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Materialize the entry chain and derive the merged cache scope.
|
|
218
|
+
* Shared by resolveRoute (non-lite) and ensureFullRouteSnapshot.
|
|
219
|
+
*/
|
|
220
|
+
function buildEntriesAndCacheScope(manifestEntry: EntryData): {
|
|
221
|
+
entries: EntryData[];
|
|
222
|
+
cacheScope: CacheScope | null;
|
|
223
|
+
} {
|
|
224
|
+
const entries = [...traverseBack(manifestEntry)];
|
|
225
|
+
let cacheScope: CacheScope | null = null;
|
|
226
|
+
for (const entry of entries) {
|
|
227
|
+
if (entry.cache) {
|
|
228
|
+
cacheScope = createCacheScope(entry.cache, cacheScope);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return { entries, cacheScope };
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Test helper: create a RouteSnapshot with sensible defaults and overrides.
|
|
236
|
+
*/
|
|
237
|
+
export function createRouteSnapshot<TEnv = any>(
|
|
238
|
+
overrides?: Partial<RouteSnapshot<TEnv>>,
|
|
239
|
+
): RouteSnapshot<TEnv> {
|
|
240
|
+
return {
|
|
241
|
+
matched: {
|
|
242
|
+
entry: {} as any,
|
|
243
|
+
routeKey: "test",
|
|
244
|
+
params: {},
|
|
245
|
+
} as RouteMatchResult<TEnv>,
|
|
246
|
+
manifestEntry: { type: "route", shortCode: "R0", parent: null } as any,
|
|
247
|
+
entries: [],
|
|
248
|
+
routeKey: "test",
|
|
249
|
+
localRouteName: "test",
|
|
250
|
+
params: {},
|
|
251
|
+
routeMiddleware: [],
|
|
252
|
+
cacheScope: null,
|
|
253
|
+
isPassthrough: false,
|
|
254
|
+
...overrides,
|
|
255
|
+
};
|
|
256
|
+
}
|
|
@@ -19,6 +19,7 @@ import type {
|
|
|
19
19
|
} from "../types.js";
|
|
20
20
|
import type { RouteMatchResult } from "./pattern-matching.js";
|
|
21
21
|
import type { TelemetrySink } from "./telemetry.js";
|
|
22
|
+
import type { ResolveSegmentOptions } from "./segment-resolution.js";
|
|
22
23
|
|
|
23
24
|
/**
|
|
24
25
|
* Revalidation context passed to segment resolution
|
|
@@ -54,10 +55,10 @@ export interface InterceptResult {
|
|
|
54
55
|
* Instead of passing 20+ parameters, middleware calls getRouterContext() to access them.
|
|
55
56
|
*/
|
|
56
57
|
export interface RouterContext<TEnv = any> {
|
|
57
|
-
|
|
58
|
-
|
|
58
|
+
findMatch: (
|
|
59
|
+
pathname: string,
|
|
60
|
+
) => RouteMatchResult | null | Promise<RouteMatchResult | null>;
|
|
59
61
|
|
|
60
|
-
// Manifest loading
|
|
61
62
|
loadManifest: (
|
|
62
63
|
entry: any,
|
|
63
64
|
routeKey: string,
|
|
@@ -66,10 +67,8 @@ export interface RouterContext<TEnv = any> {
|
|
|
66
67
|
isSSR?: boolean,
|
|
67
68
|
) => Promise<EntryData>;
|
|
68
69
|
|
|
69
|
-
// Entry traversal
|
|
70
70
|
traverseBack: (entry: EntryData) => Generator<EntryData>;
|
|
71
71
|
|
|
72
|
-
// Handler context creation
|
|
73
72
|
createHandlerContext: (
|
|
74
73
|
params: Record<string, string>,
|
|
75
74
|
request: Request,
|
|
@@ -83,7 +82,6 @@ export interface RouterContext<TEnv = any> {
|
|
|
83
82
|
isPassthroughRoute?: boolean,
|
|
84
83
|
) => HandlerContext<any, TEnv>;
|
|
85
84
|
|
|
86
|
-
// Loader setup
|
|
87
85
|
setupLoaderAccess: (
|
|
88
86
|
ctx: HandlerContext<any, TEnv>,
|
|
89
87
|
loaderPromises: Map<string, Promise<any>>,
|
|
@@ -94,7 +92,6 @@ export interface RouterContext<TEnv = any> {
|
|
|
94
92
|
loaderPromises: Map<string, Promise<any>>,
|
|
95
93
|
) => void;
|
|
96
94
|
|
|
97
|
-
// Context access
|
|
98
95
|
getContext: () => {
|
|
99
96
|
getOrCreateStore: (key: string) => any;
|
|
100
97
|
runWithStore: <T>(
|
|
@@ -105,16 +102,13 @@ export interface RouterContext<TEnv = any> {
|
|
|
105
102
|
) => T;
|
|
106
103
|
};
|
|
107
104
|
|
|
108
|
-
// Metrics
|
|
109
105
|
getMetricsStore: () => MetricsStore | undefined;
|
|
110
106
|
|
|
111
|
-
// Cache
|
|
112
107
|
createCacheScope: (
|
|
113
108
|
cacheConfig: any,
|
|
114
109
|
parent: CacheScope | null,
|
|
115
110
|
) => CacheScope | null;
|
|
116
111
|
|
|
117
|
-
// Intercept detection
|
|
118
112
|
findInterceptForRoute: (
|
|
119
113
|
routeKey: string,
|
|
120
114
|
parentEntry: EntryData | null,
|
|
@@ -122,7 +116,6 @@ export interface RouterContext<TEnv = any> {
|
|
|
122
116
|
isAction: boolean,
|
|
123
117
|
) => InterceptResult | null;
|
|
124
118
|
|
|
125
|
-
// Segment resolution (with revalidation)
|
|
126
119
|
resolveAllSegmentsWithRevalidation: (
|
|
127
120
|
entries: EntryData[],
|
|
128
121
|
routeKey: string,
|
|
@@ -133,11 +126,11 @@ export interface RouterContext<TEnv = any> {
|
|
|
133
126
|
request: Request,
|
|
134
127
|
prevUrl: URL,
|
|
135
128
|
nextUrl: URL,
|
|
136
|
-
loaderPromises: Map<string, Promise<any>>,
|
|
137
129
|
actionContext: any | undefined,
|
|
138
130
|
interceptResult: InterceptResult | null,
|
|
139
131
|
localRouteName: string,
|
|
140
132
|
pathname: string,
|
|
133
|
+
stale?: boolean,
|
|
141
134
|
) => Promise<{ segments: ResolvedSegment[]; matchedIds: string[] }>;
|
|
142
135
|
|
|
143
136
|
// Generator-based segment resolution (for pipeline)
|
|
@@ -163,14 +156,13 @@ export interface RouterContext<TEnv = any> {
|
|
|
163
156
|
handlerContext: HandlerContext<any, TEnv>,
|
|
164
157
|
belongsToRoute: boolean,
|
|
165
158
|
revalidationContext?: RevalidationContext,
|
|
159
|
+
options?: { skipMiddleware?: boolean },
|
|
166
160
|
) => Promise<ResolvedSegment[]>;
|
|
167
161
|
|
|
168
|
-
// Collect with markers
|
|
169
162
|
collectWithMarkers?: <T>(
|
|
170
163
|
gen: AsyncGenerator<T | { __type: "id"; id: string }>,
|
|
171
164
|
) => Promise<{ items: T[]; matchedIds: string[] }>;
|
|
172
165
|
|
|
173
|
-
// Revalidation evaluation
|
|
174
166
|
evaluateRevalidation: (params: {
|
|
175
167
|
segment: ResolvedSegment;
|
|
176
168
|
prevParams: Record<string, string>;
|
|
@@ -188,10 +180,12 @@ export interface RouterContext<TEnv = any> {
|
|
|
188
180
|
| "cache-hit"
|
|
189
181
|
| "loader"
|
|
190
182
|
| "parallel"
|
|
191
|
-
| "orphan-layout"
|
|
183
|
+
| "orphan-layout"
|
|
184
|
+
| "route-handler"
|
|
185
|
+
| "layout-handler"
|
|
186
|
+
| "intercept-loader";
|
|
192
187
|
}) => Promise<boolean>;
|
|
193
188
|
|
|
194
|
-
// Request context
|
|
195
189
|
getRequestContext: () =>
|
|
196
190
|
| {
|
|
197
191
|
waitUntil: (fn: () => Promise<void>) => void;
|
|
@@ -199,16 +193,15 @@ export interface RouterContext<TEnv = any> {
|
|
|
199
193
|
}
|
|
200
194
|
| undefined;
|
|
201
195
|
|
|
202
|
-
// Simple segment resolution (without revalidation - for full match)
|
|
203
196
|
resolveAllSegments: (
|
|
204
197
|
entries: EntryData[],
|
|
205
198
|
routeKey: string,
|
|
206
199
|
params: Record<string, string>,
|
|
207
200
|
handlerContext: HandlerContext<any, TEnv>,
|
|
208
201
|
loaderPromises: Map<string, Promise<any>>,
|
|
202
|
+
options?: ResolveSegmentOptions,
|
|
209
203
|
) => Promise<ResolvedSegment[]>;
|
|
210
204
|
|
|
211
|
-
// Generator-based simple resolution
|
|
212
205
|
resolveAllSegmentsGenerator?: (
|
|
213
206
|
entries: EntryData[],
|
|
214
207
|
routeKey: string,
|
|
@@ -217,21 +210,17 @@ export interface RouterContext<TEnv = any> {
|
|
|
217
210
|
loaderPromises: Map<string, Promise<any>>,
|
|
218
211
|
) => AsyncGenerator<ResolvedSegment | { __type: "id"; id: string }>;
|
|
219
212
|
|
|
220
|
-
// Collect segments from generator
|
|
221
213
|
collectSegmentsFromGenerator?: <T>(
|
|
222
214
|
gen: AsyncGenerator<T | { __type: "id"; id: string }>,
|
|
223
215
|
) => Promise<T[]>;
|
|
224
216
|
|
|
225
|
-
// Handle store
|
|
226
217
|
createHandleStore: () => any;
|
|
227
218
|
|
|
228
|
-
// Loaders-only resolution (for full match cache hit - no revalidation)
|
|
229
219
|
resolveLoadersOnly?: (
|
|
230
220
|
entries: EntryData[],
|
|
231
221
|
handlerContext: HandlerContext<any, TEnv>,
|
|
232
222
|
) => Promise<ResolvedSegment[]>;
|
|
233
223
|
|
|
234
|
-
// Loaders-only resolution (for cache hit scenarios)
|
|
235
224
|
resolveLoadersOnlyWithRevalidation?: (
|
|
236
225
|
entries: EntryData[],
|
|
237
226
|
handlerContext: HandlerContext<any, TEnv>,
|
|
@@ -253,10 +242,8 @@ export interface RouterContext<TEnv = any> {
|
|
|
253
242
|
// Telemetry sink (optional, no-op when undefined)
|
|
254
243
|
telemetry?: TelemetrySink;
|
|
255
244
|
|
|
256
|
-
// Request ID for telemetry span correlation (set per-request in match handlers)
|
|
257
245
|
requestId?: string;
|
|
258
246
|
|
|
259
|
-
// Intercept loaders only (for cache hit + intercept scenarios)
|
|
260
247
|
resolveInterceptLoadersOnly?: (
|
|
261
248
|
intercept: InterceptEntry,
|
|
262
249
|
entry: EntryData,
|
|
@@ -279,7 +266,6 @@ export interface RouterContext<TEnv = any> {
|
|
|
279
266
|
} | null>;
|
|
280
267
|
}
|
|
281
268
|
|
|
282
|
-
// AsyncLocalStorage instance for router context
|
|
283
269
|
const routerContext = new AsyncLocalStorage<RouterContext<any>>();
|
|
284
270
|
|
|
285
271
|
/**
|
|
@@ -303,10 +289,6 @@ export function getRouterContext<TEnv = any>(): RouterContext<TEnv> {
|
|
|
303
289
|
*
|
|
304
290
|
* All async code within fn() can call getRouterContext() to access router closures.
|
|
305
291
|
* This works across async boundaries thanks to AsyncLocalStorage.
|
|
306
|
-
*
|
|
307
|
-
* @param deps Router dependencies to make available
|
|
308
|
-
* @param fn Function to run with dependencies available
|
|
309
|
-
* @returns Result of fn()
|
|
310
292
|
*/
|
|
311
293
|
export function runWithRouterContext<T, TEnv = any>(
|
|
312
294
|
deps: RouterContext<TEnv>,
|