@rangojs/router 0.0.0-experimental.c873df95 → 0.0.0-experimental.c9471f9b
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 +724 -183
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +4276 -1206
- 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 +338 -13
- 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 +166 -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 +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 +131 -30
- package/src/browser/navigation-client.ts +204 -87
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +203 -80
- package/src/browser/navigation-transaction.ts +9 -59
- package/src/browser/network-error-handler.ts +34 -7
- package/src/browser/partial-update.ts +198 -125
- package/src/browser/prefetch/cache.ts +246 -71
- package/src/browser/prefetch/fetch.ts +358 -40
- package/src/browser/prefetch/queue.ts +113 -32
- package/src/browser/prefetch/resource-ready.ts +77 -0
- package/src/browser/rango-state.ts +158 -76
- package/src/browser/react/Link.tsx +112 -15
- package/src/browser/react/NavigationProvider.tsx +213 -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 +168 -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 +244 -71
- package/src/browser/types.ts +127 -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 +333 -117
- 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 +233 -101
- 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/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/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 +153 -77
- package/src/route-definition/index.ts +4 -2
- package/src/route-definition/redirect.ts +51 -10
- 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 +83 -39
- package/src/router/instrument.ts +355 -0
- package/src/router/intercept-resolution.ts +48 -24
- package/src/router/lazy-includes.ts +85 -62
- package/src/router/loader-resolution.ts +286 -56
- package/src/router/logging.ts +0 -6
- package/src/router/manifest.ts +96 -53
- 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 +48 -21
- package/src/router/match-middleware/cache-lookup.ts +178 -277
- package/src/router/match-middleware/cache-store.ts +74 -45
- 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 +124 -50
- package/src/router/metrics.ts +0 -34
- package/src/router/middleware-types.ts +13 -142
- package/src/router/middleware.ts +300 -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 +6 -28
- 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 +204 -88
- package/src/router/segment-resolution/helpers.ts +115 -30
- package/src/router/segment-resolution/loader-cache.ts +155 -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 +354 -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 +10 -63
- package/src/router/url-params.ts +57 -0
- package/src/router.ts +205 -70
- 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 +386 -205
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +280 -51
- 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 +550 -171
- package/src/ssr/index.tsx +467 -175
- 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 +145 -79
- 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 +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 +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 -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 +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 +37 -40
- package/src/vite/plugins/virtual-entries.ts +138 -27
- package/src/vite/rango.ts +247 -132
- 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 +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
package/src/router/match-api.ts
CHANGED
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Match API
|
|
3
|
-
*
|
|
4
|
-
* Extracted from createRouter closure. Contains match context creation functions
|
|
5
|
-
* and the matchError function for error boundary resolution.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
1
|
import { CacheScope, createCacheScope } from "../cache/cache-scope.js";
|
|
9
2
|
import { RouteNotFoundError } from "../errors";
|
|
10
3
|
import {
|
|
@@ -22,10 +15,10 @@ import { collectRouteMiddleware } from "./middleware.js";
|
|
|
22
15
|
import { traverseBack } from "./pattern-matching.js";
|
|
23
16
|
import { DefaultErrorFallback } from "../default-error-boundary.js";
|
|
24
17
|
import {
|
|
25
|
-
EntryData,
|
|
26
|
-
LoaderEntry,
|
|
18
|
+
type EntryData,
|
|
19
|
+
type LoaderEntry,
|
|
27
20
|
getContext,
|
|
28
|
-
InterceptSelectorContext,
|
|
21
|
+
type InterceptSelectorContext,
|
|
29
22
|
} from "../server/context";
|
|
30
23
|
import type { ErrorBoundaryHandler, ErrorInfo, MatchResult } from "../types";
|
|
31
24
|
import type { ReactNode } from "react";
|
|
@@ -33,10 +26,18 @@ import type { MatchContext } from "./match-context.js";
|
|
|
33
26
|
import type { MatchApiDeps, ActionContext } from "./types.js";
|
|
34
27
|
import {
|
|
35
28
|
getRequestContext,
|
|
29
|
+
_getRequestContext,
|
|
36
30
|
setRequestContextPrevRouteKey,
|
|
37
31
|
} from "../server/request-context.js";
|
|
38
32
|
import { isAutoGeneratedRouteName } from "../route-name.js";
|
|
33
|
+
import type { DefaultRouteName } from "../types/global-namespace.js";
|
|
39
34
|
import { debugLog, debugWarn } from "./logging.js";
|
|
35
|
+
import {
|
|
36
|
+
resolveRoute,
|
|
37
|
+
ensureFullRouteSnapshot,
|
|
38
|
+
type RouteSnapshot,
|
|
39
|
+
} from "./route-snapshot.js";
|
|
40
|
+
import { resolveNavigation } from "./navigation-snapshot.js";
|
|
40
41
|
|
|
41
42
|
/**
|
|
42
43
|
* Create match context for full requests (document/SSR).
|
|
@@ -47,64 +48,73 @@ export async function createMatchContextForFull<TEnv>(
|
|
|
47
48
|
deps: MatchApiDeps<TEnv>,
|
|
48
49
|
findInterceptForRoute: MatchApiDeps<TEnv>["findInterceptForRoute"],
|
|
49
50
|
): Promise<MatchContext<TEnv> | { type: "redirect"; redirectUrl: string }> {
|
|
50
|
-
const
|
|
51
|
-
const
|
|
51
|
+
const reqCtx = _getRequestContext();
|
|
52
|
+
const cleanUrl = reqCtx?.url ?? stripInternalParams(new URL(request.url));
|
|
53
|
+
const pathname = cleanUrl.pathname;
|
|
52
54
|
|
|
53
55
|
const metricsStore = deps.getMetricsStore();
|
|
54
56
|
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
if (
|
|
58
|
-
|
|
59
|
-
label: "route-matching",
|
|
60
|
-
duration: performance.now() - routeMatchStart,
|
|
61
|
-
startTime: routeMatchStart - metricsStore.requestStart,
|
|
62
|
-
});
|
|
57
|
+
const isHmr = !!request.headers.get("X-RSC-HMR");
|
|
58
|
+
// HMR: clear the manifest cache so stale handler references are discarded.
|
|
59
|
+
if (isHmr) {
|
|
60
|
+
clearManifestCache();
|
|
63
61
|
}
|
|
64
62
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
63
|
+
// Reuse the snapshot classifyRequest already resolved when it is a full-render
|
|
64
|
+
// snapshot (isSSR:true) and HMR has not invalidated it — mirrors the partial
|
|
65
|
+
// path. A partial-mode snapshot (isSSR:false) carries the wrong loading()
|
|
66
|
+
// entries and lives in a different manifest partition, so it is NOT reusable.
|
|
67
|
+
const classified = reqCtx?._classifiedRoute;
|
|
68
|
+
const classifiedRoute =
|
|
69
|
+
!isHmr && classified?.isSSR === true ? classified : undefined;
|
|
70
|
+
|
|
71
|
+
// On the reuse path, findMatch + manifest-loading already ran during
|
|
72
|
+
// classifyRequest (which carries no metricsStore), so only the cheap
|
|
73
|
+
// entries/cacheScope materialization is timed here under a distinct label. On
|
|
74
|
+
// the fresh path, resolveRoute emits route-matching + manifest-loading as usual.
|
|
75
|
+
const routeMatchStart = metricsStore ? performance.now() : 0;
|
|
76
|
+
|
|
77
|
+
let snapshot: RouteSnapshot<TEnv>;
|
|
78
|
+
if (classifiedRoute && classifiedRoute.manifestEntry) {
|
|
79
|
+
snapshot = ensureFullRouteSnapshot(classifiedRoute);
|
|
80
|
+
if (metricsStore) {
|
|
81
|
+
metricsStore.metrics.push({
|
|
82
|
+
label: "route-matching:reuse",
|
|
83
|
+
duration: performance.now() - routeMatchStart,
|
|
84
|
+
startTime: routeMatchStart - metricsStore.requestStart,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
} else {
|
|
88
|
+
const result = await resolveRoute<TEnv>(pathname, {
|
|
89
|
+
findMatch: (p) => deps.findMatch(p, metricsStore),
|
|
90
|
+
metricsStore,
|
|
91
|
+
isSSR: true,
|
|
68
92
|
});
|
|
69
|
-
}
|
|
70
93
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
}
|
|
94
|
+
if (!result) {
|
|
95
|
+
throw new RouteNotFoundError(`No route matched for ${pathname}`, {
|
|
96
|
+
cause: { pathname, method: request.method },
|
|
97
|
+
});
|
|
98
|
+
}
|
|
77
99
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
metricsStore.metrics.push({
|
|
88
|
-
label: "manifest-loading",
|
|
89
|
-
duration: performance.now() - manifestStart,
|
|
90
|
-
startTime: manifestStart - metricsStore.requestStart,
|
|
91
|
-
});
|
|
92
|
-
}
|
|
100
|
+
if (result.type === "redirect") {
|
|
101
|
+
// Preserve the raw query string (including internal _rsc* params) on the
|
|
102
|
+
// redirect target, matching the pre-reuse behavior of `url.search`.
|
|
103
|
+
const rawSearch = (reqCtx?.originalUrl ?? new URL(request.url)).search;
|
|
104
|
+
return {
|
|
105
|
+
type: "redirect",
|
|
106
|
+
redirectUrl: result.redirectTo + rawSearch,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
93
109
|
|
|
94
|
-
|
|
95
|
-
manifestEntry.type === "route" &&
|
|
96
|
-
manifestEntry.prerenderDef?.options?.passthrough === true
|
|
97
|
-
) {
|
|
98
|
-
matched.pt = true;
|
|
110
|
+
snapshot = result.snapshot;
|
|
99
111
|
}
|
|
100
112
|
|
|
101
|
-
const
|
|
102
|
-
traverseBack(manifestEntry),
|
|
103
|
-
matched.params,
|
|
104
|
-
);
|
|
113
|
+
const { matched } = snapshot;
|
|
105
114
|
|
|
106
|
-
|
|
107
|
-
|
|
115
|
+
if (snapshot.isPassthrough) {
|
|
116
|
+
matched.pt = true;
|
|
117
|
+
}
|
|
108
118
|
|
|
109
119
|
const handlerContext = createHandlerContext(
|
|
110
120
|
matched.params,
|
|
@@ -134,14 +144,6 @@ export async function createMatchContextForFull<TEnv>(
|
|
|
134
144
|
Store.metrics = metricsStore;
|
|
135
145
|
}
|
|
136
146
|
|
|
137
|
-
const entries = [...traverseBack(manifestEntry)];
|
|
138
|
-
let cacheScope: CacheScope | null = null;
|
|
139
|
-
for (const entry of entries) {
|
|
140
|
-
if (entry.cache) {
|
|
141
|
-
cacheScope = createCacheScope(entry.cache, cacheScope);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
147
|
return {
|
|
146
148
|
request,
|
|
147
149
|
url: cleanUrl,
|
|
@@ -154,12 +156,10 @@ export async function createMatchContextForFull<TEnv>(
|
|
|
154
156
|
prevParams: {},
|
|
155
157
|
prevMatch: null,
|
|
156
158
|
matched,
|
|
157
|
-
manifestEntry,
|
|
158
|
-
entries,
|
|
159
|
+
manifestEntry: snapshot.manifestEntry,
|
|
160
|
+
entries: snapshot.entries,
|
|
159
161
|
routeKey: matched.routeKey,
|
|
160
|
-
localRouteName:
|
|
161
|
-
? matched.routeKey.split(".").pop()!
|
|
162
|
-
: matched.routeKey,
|
|
162
|
+
localRouteName: snapshot.localRouteName,
|
|
163
163
|
handlerContext,
|
|
164
164
|
loaderPromises,
|
|
165
165
|
routeMap: deps.getRouteMap(),
|
|
@@ -175,16 +175,16 @@ export async function createMatchContextForFull<TEnv>(
|
|
|
175
175
|
segments: { path: [], ids: [] },
|
|
176
176
|
toRouteName:
|
|
177
177
|
matched.routeKey && !isAutoGeneratedRouteName(matched.routeKey)
|
|
178
|
-
? matched.routeKey
|
|
178
|
+
? (matched.routeKey as DefaultRouteName)
|
|
179
179
|
: undefined,
|
|
180
180
|
},
|
|
181
181
|
isSameRouteNavigation: false,
|
|
182
182
|
interceptResult: null,
|
|
183
|
-
cacheScope,
|
|
183
|
+
cacheScope: snapshot.cacheScope,
|
|
184
184
|
isIntercept: false,
|
|
185
185
|
actionContext: undefined,
|
|
186
186
|
isAction: false,
|
|
187
|
-
routeMiddleware,
|
|
187
|
+
routeMiddleware: snapshot.routeMiddleware,
|
|
188
188
|
isFullMatch: true,
|
|
189
189
|
};
|
|
190
190
|
}
|
|
@@ -199,111 +199,92 @@ export async function createMatchContextForPartial<TEnv>(
|
|
|
199
199
|
findInterceptForRoute: MatchApiDeps<TEnv>["findInterceptForRoute"],
|
|
200
200
|
actionContext?: ActionContext,
|
|
201
201
|
): Promise<MatchContext<TEnv> | null> {
|
|
202
|
-
const
|
|
203
|
-
|
|
202
|
+
const reqCtx = _getRequestContext();
|
|
203
|
+
// resolveNavigation needs the raw URL (reads internal _rsc_segments /
|
|
204
|
+
// _rsc_stale params that stripInternalParams removes); the clean URL feeds the
|
|
205
|
+
// handler context. Both come off the request context when present.
|
|
206
|
+
const rawUrl = reqCtx?.originalUrl ?? new URL(request.url);
|
|
207
|
+
const cleanUrl = reqCtx?.url ?? stripInternalParams(rawUrl);
|
|
208
|
+
const pathname = cleanUrl.pathname;
|
|
204
209
|
|
|
205
210
|
const metricsStore = deps.getMetricsStore();
|
|
206
211
|
|
|
207
|
-
const
|
|
208
|
-
url.searchParams.get("_rsc_segments")?.split(",").filter(Boolean) || [];
|
|
209
|
-
const stale = url.searchParams.get("_rsc_stale") === "true";
|
|
210
|
-
const previousUrl =
|
|
211
|
-
request.headers.get("X-RSC-Router-Client-Path") ||
|
|
212
|
-
request.headers.get("Referer");
|
|
213
|
-
const interceptSourceUrl = request.headers.get(
|
|
214
|
-
"X-RSC-Router-Intercept-Source",
|
|
215
|
-
);
|
|
212
|
+
const isHmr = !!request.headers.get("X-RSC-HMR");
|
|
216
213
|
|
|
217
214
|
// HMR: clear manifest cache so stale handler references are discarded
|
|
218
|
-
if (
|
|
215
|
+
if (isHmr) {
|
|
219
216
|
clearManifestCache();
|
|
220
217
|
}
|
|
221
218
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
219
|
+
// Reuse the classified snapshot when available and not invalidated by HMR.
|
|
220
|
+
// classifyRequest resolves a partial request with isSSR=false, matching this
|
|
221
|
+
// path. Never reuse an isSSR:true (full-render) snapshot — its loading()
|
|
222
|
+
// entries and manifest partition are wrong here. On HMR, discard to pick up
|
|
223
|
+
// manifest changes.
|
|
224
|
+
const classified = reqCtx?._classifiedRoute;
|
|
225
|
+
const classifiedRoute =
|
|
226
|
+
!isHmr && classified?.isSSR !== true ? classified : undefined;
|
|
227
|
+
|
|
228
|
+
// Time route matching. On the reuse path, only nav findMatch calls are new
|
|
229
|
+
// (current-route findMatch and manifest-loading were already timed during
|
|
230
|
+
// classifyRequest via its metricsStore). On the fresh path, all findMatch
|
|
231
|
+
// calls are measured together.
|
|
232
|
+
const routeMatchStart = metricsStore ? performance.now() : 0;
|
|
232
233
|
|
|
233
|
-
let
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
234
|
+
let snapshot: RouteSnapshot<TEnv>;
|
|
235
|
+
if (classifiedRoute && classifiedRoute.manifestEntry) {
|
|
236
|
+
snapshot = ensureFullRouteSnapshot(classifiedRoute);
|
|
237
|
+
} else {
|
|
238
|
+
const result = await resolveRoute<TEnv>(pathname, {
|
|
239
|
+
findMatch: (p) => deps.findMatch(p, metricsStore),
|
|
240
|
+
metricsStore,
|
|
241
|
+
isSSR: false,
|
|
242
|
+
skipRouteMatchMetric: true,
|
|
243
|
+
});
|
|
241
244
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
: prevMatch;
|
|
245
|
+
if (!result) {
|
|
246
|
+
throw new RouteNotFoundError(`No route matched for ${pathname}`, {
|
|
247
|
+
cause: { pathname, method: request.method },
|
|
248
|
+
});
|
|
249
|
+
}
|
|
248
250
|
|
|
249
|
-
|
|
251
|
+
if (result.type === "redirect") {
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
250
254
|
|
|
251
|
-
|
|
252
|
-
metricsStore.metrics.push({
|
|
253
|
-
label: "route-matching",
|
|
254
|
-
duration: performance.now() - routeMatchStart,
|
|
255
|
-
startTime: routeMatchStart - metricsStore.requestStart,
|
|
256
|
-
});
|
|
255
|
+
snapshot = result.snapshot;
|
|
257
256
|
}
|
|
258
257
|
|
|
259
|
-
|
|
260
|
-
throw new RouteNotFoundError(`No route matched for ${pathname}`, {
|
|
261
|
-
cause: { pathname, method: request.method, previousUrl },
|
|
262
|
-
});
|
|
263
|
-
}
|
|
258
|
+
const { matched } = snapshot;
|
|
264
259
|
|
|
265
|
-
|
|
266
|
-
|
|
260
|
+
// Backward compat: downstream middleware reads matched.pt
|
|
261
|
+
if (snapshot.isPassthrough) {
|
|
262
|
+
matched.pt = true;
|
|
267
263
|
}
|
|
268
264
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
265
|
+
const nav = await resolveNavigation(request, rawUrl, matched.routeKey, {
|
|
266
|
+
findMatch: deps.findMatch,
|
|
267
|
+
});
|
|
268
|
+
if (!nav) {
|
|
269
|
+
return null;
|
|
274
270
|
}
|
|
275
271
|
|
|
276
|
-
const manifestStart = metricsStore ? performance.now() : 0;
|
|
277
|
-
const manifestEntry = await loadManifest(
|
|
278
|
-
matched.entry,
|
|
279
|
-
matched.routeKey,
|
|
280
|
-
pathname,
|
|
281
|
-
metricsStore,
|
|
282
|
-
false,
|
|
283
|
-
);
|
|
284
272
|
if (metricsStore) {
|
|
273
|
+
const isReuse = !!classifiedRoute;
|
|
285
274
|
metricsStore.metrics.push({
|
|
286
|
-
label: "
|
|
287
|
-
duration: performance.now() -
|
|
288
|
-
startTime:
|
|
275
|
+
label: isReuse ? "route-matching:nav" : "route-matching",
|
|
276
|
+
duration: performance.now() - routeMatchStart,
|
|
277
|
+
startTime: routeMatchStart - metricsStore.requestStart,
|
|
289
278
|
});
|
|
290
279
|
}
|
|
291
280
|
|
|
292
|
-
if (
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
281
|
+
if (nav.prevMatch && nav.prevMatch.entry !== matched.entry && !matched.pr) {
|
|
282
|
+
debugLog("matchPartial", "route group changed", {
|
|
283
|
+
from: nav.prevMatch.routeKey,
|
|
284
|
+
to: matched.routeKey,
|
|
285
|
+
});
|
|
297
286
|
}
|
|
298
287
|
|
|
299
|
-
const routeMiddleware = collectRouteMiddleware(
|
|
300
|
-
traverseBack(manifestEntry),
|
|
301
|
-
matched.params,
|
|
302
|
-
);
|
|
303
|
-
|
|
304
|
-
// Clean URL without internal _rsc* params for userland access
|
|
305
|
-
const cleanUrl = stripInternalParams(url);
|
|
306
|
-
|
|
307
288
|
const handlerContext = createHandlerContext(
|
|
308
289
|
matched.params,
|
|
309
290
|
request,
|
|
@@ -317,9 +298,8 @@ export async function createMatchContextForPartial<TEnv>(
|
|
|
317
298
|
matched.pt === true,
|
|
318
299
|
);
|
|
319
300
|
|
|
320
|
-
const clientSegmentSet = new Set(clientSegmentIds);
|
|
321
301
|
debugLog("matchPartial", "client segments", {
|
|
322
|
-
segments: Array.from(clientSegmentSet),
|
|
302
|
+
segments: Array.from(nav.clientSegmentSet),
|
|
323
303
|
});
|
|
324
304
|
|
|
325
305
|
const loaderPromises = new Map<string, Promise<any>>();
|
|
@@ -337,100 +317,79 @@ export async function createMatchContextForPartial<TEnv>(
|
|
|
337
317
|
Store.metrics = metricsStore;
|
|
338
318
|
}
|
|
339
319
|
|
|
340
|
-
|
|
341
|
-
interceptContextMatch && interceptContextMatch.routeKey === matched.routeKey
|
|
342
|
-
);
|
|
343
|
-
|
|
344
|
-
if (interceptSourceUrl) {
|
|
320
|
+
if (nav.hasInterceptSource) {
|
|
345
321
|
debugLog("matchPartial.intercept", "intercept context detected", {
|
|
346
322
|
currentUrl: pathname,
|
|
347
|
-
interceptSource:
|
|
348
|
-
contextRoute: interceptContextMatch?.routeKey,
|
|
323
|
+
interceptSource: nav.interceptContextUrl.href,
|
|
324
|
+
contextRoute: nav.interceptContextMatch?.routeKey,
|
|
349
325
|
currentRoute: matched.routeKey,
|
|
350
|
-
sameRouteNavigation: isSameRouteNavigation,
|
|
326
|
+
sameRouteNavigation: nav.isSameRouteNavigation,
|
|
351
327
|
});
|
|
352
328
|
}
|
|
353
329
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
if (id.includes(".@")) return false;
|
|
360
|
-
if (/D\d+\./.test(id)) return false;
|
|
361
|
-
return true;
|
|
362
|
-
});
|
|
363
|
-
const effectiveFromUrl = interceptSourceUrl ? interceptContextUrl : prevUrl;
|
|
364
|
-
const effectiveFromMatch = interceptSourceUrl
|
|
365
|
-
? interceptContextMatch
|
|
366
|
-
: prevMatch;
|
|
367
|
-
|
|
368
|
-
// Store previous route key on the request context for revalidation
|
|
369
|
-
// fromRouteName. Uses effectiveFromMatch so intercept-source navigations
|
|
370
|
-
// see the intercept origin route, not the plain previous URL route.
|
|
371
|
-
setRequestContextPrevRouteKey(effectiveFromMatch?.routeKey);
|
|
330
|
+
setRequestContextPrevRouteKey(
|
|
331
|
+
nav.effectiveFromMatch?.routeKey,
|
|
332
|
+
nav.effectiveFromUrl,
|
|
333
|
+
nav.effectiveFromMatch?.params ?? nav.prevParams,
|
|
334
|
+
);
|
|
372
335
|
|
|
373
336
|
const interceptSelectorContext: InterceptSelectorContext = {
|
|
374
|
-
from: effectiveFromUrl,
|
|
337
|
+
from: nav.effectiveFromUrl,
|
|
375
338
|
to: cleanUrl,
|
|
376
339
|
params: matched.params,
|
|
377
340
|
request,
|
|
378
341
|
env,
|
|
379
342
|
segments: {
|
|
380
|
-
path: effectiveFromUrl.pathname.split("/").filter(Boolean),
|
|
381
|
-
ids: filteredSegmentIds,
|
|
343
|
+
path: nav.effectiveFromUrl.pathname.split("/").filter(Boolean),
|
|
344
|
+
ids: nav.filteredSegmentIds,
|
|
382
345
|
},
|
|
383
346
|
fromRouteName:
|
|
384
|
-
effectiveFromMatch?.routeKey &&
|
|
385
|
-
!isAutoGeneratedRouteName(effectiveFromMatch.routeKey)
|
|
386
|
-
? effectiveFromMatch.routeKey
|
|
347
|
+
nav.effectiveFromMatch?.routeKey &&
|
|
348
|
+
!isAutoGeneratedRouteName(nav.effectiveFromMatch.routeKey)
|
|
349
|
+
? (nav.effectiveFromMatch.routeKey as DefaultRouteName)
|
|
387
350
|
: undefined,
|
|
388
351
|
toRouteName:
|
|
389
352
|
matched.routeKey && !isAutoGeneratedRouteName(matched.routeKey)
|
|
390
|
-
? matched.routeKey
|
|
353
|
+
? (matched.routeKey as DefaultRouteName)
|
|
391
354
|
: undefined,
|
|
392
355
|
};
|
|
393
356
|
const isAction = !!actionContext;
|
|
394
357
|
|
|
395
|
-
const clientHasInterceptSegments = [...clientSegmentSet].some((id) =>
|
|
358
|
+
const clientHasInterceptSegments = [...nav.clientSegmentSet].some((id) =>
|
|
396
359
|
id.includes(".@"),
|
|
397
360
|
);
|
|
398
361
|
const skipInterceptForAction = isAction && !clientHasInterceptSegments;
|
|
399
362
|
const interceptResult =
|
|
400
|
-
isSameRouteNavigation || skipInterceptForAction
|
|
363
|
+
nav.isSameRouteNavigation || skipInterceptForAction
|
|
401
364
|
? null
|
|
402
365
|
: findInterceptForRoute(
|
|
403
366
|
matched.routeKey,
|
|
404
|
-
manifestEntry.parent,
|
|
367
|
+
snapshot.manifestEntry.parent,
|
|
405
368
|
interceptSelectorContext,
|
|
406
369
|
isAction,
|
|
407
370
|
) ||
|
|
408
|
-
(localRouteName !== matched.routeKey
|
|
371
|
+
(snapshot.localRouteName !== matched.routeKey
|
|
409
372
|
? findInterceptForRoute(
|
|
410
|
-
localRouteName,
|
|
411
|
-
manifestEntry.parent,
|
|
373
|
+
snapshot.localRouteName,
|
|
374
|
+
snapshot.manifestEntry.parent,
|
|
412
375
|
interceptSelectorContext,
|
|
413
376
|
isAction,
|
|
414
377
|
)
|
|
415
378
|
: null);
|
|
416
379
|
|
|
380
|
+
// Make a mutable copy of clientSegmentSet so we can delete entries
|
|
381
|
+
// for same-route navigation forcing
|
|
382
|
+
const clientSegmentSet = new Set(nav.clientSegmentSet);
|
|
383
|
+
|
|
417
384
|
if (
|
|
418
|
-
isSameRouteNavigation &&
|
|
419
|
-
manifestEntry.type === "route" &&
|
|
420
|
-
|
|
385
|
+
nav.isSameRouteNavigation &&
|
|
386
|
+
snapshot.manifestEntry.type === "route" &&
|
|
387
|
+
nav.hasInterceptSource
|
|
421
388
|
) {
|
|
422
389
|
debugLog("matchPartial.intercept", "forcing route segment render", {
|
|
423
|
-
segmentId: manifestEntry.shortCode,
|
|
390
|
+
segmentId: snapshot.manifestEntry.shortCode,
|
|
424
391
|
});
|
|
425
|
-
clientSegmentSet.delete(manifestEntry.shortCode);
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
const entries = [...traverseBack(manifestEntry)];
|
|
429
|
-
let cacheScope: CacheScope | null = null;
|
|
430
|
-
for (const entry of entries) {
|
|
431
|
-
if (entry.cache) {
|
|
432
|
-
cacheScope = createCacheScope(entry.cache, cacheScope);
|
|
433
|
-
}
|
|
392
|
+
clientSegmentSet.delete(snapshot.manifestEntry.shortCode);
|
|
434
393
|
}
|
|
435
394
|
|
|
436
395
|
const isIntercept = !!interceptResult;
|
|
@@ -440,31 +399,31 @@ export async function createMatchContextForPartial<TEnv>(
|
|
|
440
399
|
url: cleanUrl,
|
|
441
400
|
pathname,
|
|
442
401
|
env,
|
|
443
|
-
clientSegmentIds,
|
|
402
|
+
clientSegmentIds: nav.clientSegmentIds,
|
|
444
403
|
clientSegmentSet,
|
|
445
|
-
stale,
|
|
446
|
-
prevUrl,
|
|
447
|
-
prevParams,
|
|
448
|
-
prevMatch,
|
|
404
|
+
stale: nav.stale,
|
|
405
|
+
prevUrl: nav.prevUrl,
|
|
406
|
+
prevParams: nav.prevParams,
|
|
407
|
+
prevMatch: nav.prevMatch,
|
|
449
408
|
matched,
|
|
450
|
-
manifestEntry,
|
|
451
|
-
entries,
|
|
409
|
+
manifestEntry: snapshot.manifestEntry,
|
|
410
|
+
entries: snapshot.entries,
|
|
452
411
|
routeKey: matched.routeKey,
|
|
453
|
-
localRouteName,
|
|
412
|
+
localRouteName: snapshot.localRouteName,
|
|
454
413
|
handlerContext,
|
|
455
414
|
loaderPromises,
|
|
456
415
|
routeMap: deps.getRouteMap(),
|
|
457
416
|
metricsStore,
|
|
458
417
|
Store,
|
|
459
|
-
interceptContextMatch,
|
|
418
|
+
interceptContextMatch: nav.interceptContextMatch,
|
|
460
419
|
interceptSelectorContext,
|
|
461
|
-
isSameRouteNavigation,
|
|
420
|
+
isSameRouteNavigation: nav.isSameRouteNavigation,
|
|
462
421
|
interceptResult,
|
|
463
|
-
cacheScope,
|
|
422
|
+
cacheScope: snapshot.cacheScope,
|
|
464
423
|
isIntercept,
|
|
465
424
|
actionContext,
|
|
466
425
|
isAction,
|
|
467
|
-
routeMiddleware,
|
|
426
|
+
routeMiddleware: snapshot.routeMiddleware,
|
|
468
427
|
isFullMatch: false,
|
|
469
428
|
};
|
|
470
429
|
}
|
|
@@ -485,7 +444,7 @@ export async function matchError<TEnv>(
|
|
|
485
444
|
|
|
486
445
|
debugLog("matchError", "matching error", { pathname });
|
|
487
446
|
|
|
488
|
-
const matched = deps.findMatch(pathname);
|
|
447
|
+
const matched = await deps.findMatch(pathname);
|
|
489
448
|
if (!matched) {
|
|
490
449
|
debugWarn("matchError", "no route matched", { pathname });
|
|
491
450
|
return null;
|
|
@@ -615,6 +574,7 @@ export async function matchError<TEnv>(
|
|
|
615
574
|
segments: [errorSegment],
|
|
616
575
|
matched: matchedIds,
|
|
617
576
|
diff: [errorSegment.id],
|
|
577
|
+
resolvedIds: [errorSegment.id],
|
|
618
578
|
params: matched.params,
|
|
619
579
|
};
|
|
620
580
|
}
|
|
@@ -242,25 +242,3 @@ export function createPipelineState(): MatchPipelineState {
|
|
|
242
242
|
slots: {},
|
|
243
243
|
};
|
|
244
244
|
}
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* Input parameters for createMatchContext
|
|
248
|
-
*/
|
|
249
|
-
export interface CreateMatchContextInput<TEnv = any> {
|
|
250
|
-
request: Request;
|
|
251
|
-
env: TEnv;
|
|
252
|
-
actionContext?: ActionContext;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* Result from createMatchContext - either a context or null (fall back to full match)
|
|
257
|
-
*/
|
|
258
|
-
export type CreateMatchContextResult<TEnv = any> =
|
|
259
|
-
| { type: "context"; ctx: MatchContext<TEnv> }
|
|
260
|
-
| { type: "fallback"; reason: string }
|
|
261
|
-
| { type: "error"; error: Error };
|
|
262
|
-
|
|
263
|
-
// Note: createMatchContext() will be implemented in Step J10 when we wire everything together.
|
|
264
|
-
// It requires access to RouterContext (findMatch, loadManifest, etc.) which are closure
|
|
265
|
-
// functions from createRouter(). The implementation will live in router.ts initially
|
|
266
|
-
// and call getRouterContext() to access these dependencies.
|