@rangojs/router 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -1
- package/dist/types/browser/event-controller.d.ts +4 -0
- package/dist/types/browser/link-interceptor.d.ts +17 -7
- package/dist/types/browser/navigation-bridge.d.ts +13 -1
- package/dist/types/browser/notify-listeners.d.ts +2 -0
- package/dist/types/browser/prefetch/cache.d.ts +1 -1
- package/dist/types/browser/prefetch/default-strategy.d.ts +12 -3
- package/dist/types/browser/prefetch/invalidation.d.ts +6 -0
- package/dist/types/browser/prefetch/loader.d.ts +3 -1
- package/dist/types/browser/prefetch/observer.d.ts +3 -6
- package/dist/types/browser/rango-state.d.ts +4 -0
- package/dist/types/browser/react/Link.d.ts +4 -9
- package/dist/types/browser/react/context.d.ts +3 -0
- package/dist/types/browser/rsc-router.d.ts +7 -2
- package/dist/types/browser/types.d.ts +1 -0
- package/dist/types/cache/cache-key-utils.d.ts +11 -3
- package/dist/types/cache/cache-scope.d.ts +82 -3
- package/dist/types/cache/cf/cf-cache-store.d.ts +2 -2
- package/dist/types/cache/index.d.ts +3 -1
- package/dist/types/cache/search-params-filter.d.ts +64 -0
- package/dist/types/cache/shell-snapshot.d.ts +4 -4
- package/dist/types/cache/types.d.ts +30 -2
- package/dist/types/cache/vercel/vercel-cache-store.d.ts +2 -2
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.rsc.d.ts +1 -0
- package/dist/types/router/match-middleware/cache-lookup.d.ts +13 -0
- package/dist/types/router/navigation-snapshot.d.ts +29 -0
- package/dist/types/router/router-options.d.ts +27 -3
- package/dist/types/rsc/shell-build-manifest.d.ts +7 -1
- package/dist/types/rsc/shell-serve.d.ts +7 -1
- package/dist/types/rsc/types.d.ts +17 -0
- package/dist/types/server/request-context.d.ts +57 -4
- package/dist/types/testing/render-route.d.ts +10 -1
- package/dist/types/testing/shell-status.d.ts +6 -3
- package/dist/types/vite/plugin-types.d.ts +1 -1
- package/dist/vite/index.js +5 -5
- package/package.json +23 -22
- package/skills/caching/SKILL.md +39 -0
- package/skills/comparison/references/framework-comparison.md +7 -1
- package/skills/links/SKILL.md +24 -0
- package/skills/ppr/SKILL.md +53 -4
- package/skills/router-setup/SKILL.md +7 -2
- package/skills/testing/client-components.md +15 -14
- package/skills/vercel/SKILL.md +1 -1
- package/src/browser/event-controller.ts +110 -11
- package/src/browser/link-interceptor.ts +469 -20
- package/src/browser/navigation-bridge.ts +71 -2
- package/src/browser/navigation-store.ts +24 -1
- package/src/browser/notify-listeners.ts +22 -0
- package/src/browser/prefetch/cache.ts +4 -2
- package/src/browser/prefetch/default-strategy.ts +43 -3
- package/src/browser/prefetch/invalidation.ts +30 -0
- package/src/browser/prefetch/loader.ts +19 -12
- package/src/browser/prefetch/observer.ts +50 -22
- package/src/browser/rango-state.ts +21 -0
- package/src/browser/react/Link.tsx +97 -88
- package/src/browser/react/NavigationProvider.tsx +1 -0
- package/src/browser/react/context.ts +4 -0
- package/src/browser/rsc-router.tsx +22 -9
- package/src/browser/types.ts +1 -0
- package/src/cache/cache-key-utils.ts +18 -4
- package/src/cache/cache-runtime.ts +7 -2
- package/src/cache/cache-scope.ts +152 -23
- package/src/cache/cf/cf-cache-store.ts +51 -16
- package/src/cache/document-cache.ts +7 -1
- package/src/cache/index.ts +7 -0
- package/src/cache/search-params-filter.ts +118 -0
- package/src/cache/shell-snapshot.ts +8 -4
- package/src/cache/types.ts +33 -2
- package/src/cache/vercel/vercel-cache-store.ts +17 -3
- package/src/index.rsc.ts +4 -0
- package/src/index.ts +6 -0
- package/src/router/match-middleware/cache-lookup.ts +146 -33
- package/src/router/match-middleware/cache-store.ts +70 -0
- package/src/router/navigation-snapshot.ts +46 -6
- package/src/router/router-options.ts +31 -4
- package/src/rsc/handler.ts +9 -0
- package/src/rsc/response-cache-serve.ts +1 -1
- package/src/rsc/rsc-rendering.ts +252 -27
- package/src/rsc/shell-build-manifest.ts +8 -1
- package/src/rsc/shell-capture.ts +5 -0
- package/src/rsc/shell-serve.ts +8 -2
- package/src/rsc/types.ts +17 -0
- package/src/server/request-context.ts +62 -3
- package/src/testing/dispatch.ts +21 -3
- package/src/testing/render-route.tsx +86 -17
- package/src/testing/shell-status.ts +20 -3
- package/src/vite/plugin-types.ts +1 -1
- package/src/vite/plugins/vercel-output.ts +2 -2
- package/dist/types.backup/__internal.d.ts +0 -127
- package/dist/types.backup/bin/rango.d.ts +0 -1
- package/dist/types.backup/browser/action-coordinator.d.ts +0 -57
- package/dist/types.backup/browser/action-fence.d.ts +0 -33
- package/dist/types.backup/browser/app-shell.d.ts +0 -34
- package/dist/types.backup/browser/app-version.d.ts +0 -6
- package/dist/types.backup/browser/connection-warmup.d.ts +0 -31
- package/dist/types.backup/browser/cookie-name.d.ts +0 -66
- package/dist/types.backup/browser/event-controller.d.ts +0 -221
- package/dist/types.backup/browser/history-state.d.ts +0 -26
- package/dist/types.backup/browser/index.d.ts +0 -1
- package/dist/types.backup/browser/intercept-utils.d.ts +0 -30
- package/dist/types.backup/browser/invalidate-client-cache.d.ts +0 -17
- package/dist/types.backup/browser/link-interceptor.d.ts +0 -43
- package/dist/types.backup/browser/logging.d.ts +0 -33
- package/dist/types.backup/browser/merge-segment-loaders.d.ts +0 -38
- package/dist/types.backup/browser/navigation-bridge.d.ts +0 -27
- package/dist/types.backup/browser/navigation-client.d.ts +0 -17
- package/dist/types.backup/browser/navigation-store-handle.d.ts +0 -25
- package/dist/types.backup/browser/navigation-store.d.ts +0 -95
- package/dist/types.backup/browser/navigation-transaction.d.ts +0 -75
- package/dist/types.backup/browser/network-error-handler.d.ts +0 -35
- package/dist/types.backup/browser/partial-update.d.ts +0 -61
- package/dist/types.backup/browser/prefetch/cache.d.ts +0 -183
- package/dist/types.backup/browser/prefetch/fetch.d.ts +0 -52
- package/dist/types.backup/browser/prefetch/observer.d.ts +0 -27
- package/dist/types.backup/browser/prefetch/policy.d.ts +0 -13
- package/dist/types.backup/browser/prefetch/queue.d.ts +0 -48
- package/dist/types.backup/browser/prefetch/resource-ready.d.ts +0 -28
- package/dist/types.backup/browser/rango-state.d.ts +0 -52
- package/dist/types.backup/browser/react/Link.d.ts +0 -140
- package/dist/types.backup/browser/react/NavigationProvider.d.ts +0 -88
- package/dist/types.backup/browser/react/ScrollRestoration.d.ts +0 -78
- package/dist/types.backup/browser/react/context.d.ts +0 -54
- package/dist/types.backup/browser/react/filter-segment-order.d.ts +0 -35
- package/dist/types.backup/browser/react/index.d.ts +0 -1
- package/dist/types.backup/browser/react/location-state-shared.d.ts +0 -162
- package/dist/types.backup/browser/react/location-state.d.ts +0 -29
- package/dist/types.backup/browser/react/mount-context.d.ts +0 -23
- package/dist/types.backup/browser/react/nonce-context.d.ts +0 -14
- package/dist/types.backup/browser/react/shallow-equal.d.ts +0 -5
- package/dist/types.backup/browser/react/use-action.d.ts +0 -61
- package/dist/types.backup/browser/react/use-handle.d.ts +0 -21
- package/dist/types.backup/browser/react/use-href.d.ts +0 -32
- package/dist/types.backup/browser/react/use-link-status.d.ts +0 -36
- package/dist/types.backup/browser/react/use-mount.d.ts +0 -24
- package/dist/types.backup/browser/react/use-navigation.d.ts +0 -15
- package/dist/types.backup/browser/react/use-params.d.ts +0 -21
- package/dist/types.backup/browser/react/use-pathname.d.ts +0 -13
- package/dist/types.backup/browser/react/use-reverse.d.ts +0 -40
- package/dist/types.backup/browser/react/use-router.d.ts +0 -23
- package/dist/types.backup/browser/react/use-search-params.d.ts +0 -19
- package/dist/types.backup/browser/react/use-segments.d.ts +0 -29
- package/dist/types.backup/browser/response-adapter.d.ts +0 -58
- package/dist/types.backup/browser/rsc-router.d.ts +0 -141
- package/dist/types.backup/browser/scroll-restoration.d.ts +0 -103
- package/dist/types.backup/browser/segment-reconciler.d.ts +0 -74
- package/dist/types.backup/browser/segment-structure-assert.d.ts +0 -16
- package/dist/types.backup/browser/server-action-bridge.d.ts +0 -29
- package/dist/types.backup/browser/types.d.ts +0 -530
- package/dist/types.backup/browser/validate-redirect-origin.d.ts +0 -28
- package/dist/types.backup/build/collect-fallback-refs.d.ts +0 -5
- package/dist/types.backup/build/generate-manifest.d.ts +0 -100
- package/dist/types.backup/build/generate-route-types.d.ts +0 -8
- package/dist/types.backup/build/index.d.ts +0 -21
- package/dist/types.backup/build/prefix-tree-utils.d.ts +0 -56
- package/dist/types.backup/build/route-trie.d.ts +0 -89
- package/dist/types.backup/build/route-types/ast-helpers.d.ts +0 -3
- package/dist/types.backup/build/route-types/ast-route-extraction.d.ts +0 -13
- package/dist/types.backup/build/route-types/codegen.d.ts +0 -16
- package/dist/types.backup/build/route-types/include-resolution.d.ts +0 -74
- package/dist/types.backup/build/route-types/param-extraction.d.ts +0 -13
- package/dist/types.backup/build/route-types/per-module-writer.d.ts +0 -18
- package/dist/types.backup/build/route-types/router-processing.d.ts +0 -82
- package/dist/types.backup/build/route-types/scan-filter.d.ts +0 -17
- package/dist/types.backup/build/route-types/source-scan.d.ts +0 -13
- package/dist/types.backup/build/runtime-discovery.d.ts +0 -24
- package/dist/types.backup/cache/background-task.d.ts +0 -21
- package/dist/types.backup/cache/cache-error.d.ts +0 -71
- package/dist/types.backup/cache/cache-key-utils.d.ts +0 -35
- package/dist/types.backup/cache/cache-policy.d.ts +0 -59
- package/dist/types.backup/cache/cache-runtime.d.ts +0 -51
- package/dist/types.backup/cache/cache-scope.d.ts +0 -134
- package/dist/types.backup/cache/cache-tag.d.ts +0 -79
- package/dist/types.backup/cache/cf/cf-base64.d.ts +0 -4
- package/dist/types.backup/cache/cf/cf-cache-constants.d.ts +0 -105
- package/dist/types.backup/cache/cf/cf-cache-store.d.ts +0 -481
- package/dist/types.backup/cache/cf/cf-cache-types.d.ts +0 -300
- package/dist/types.backup/cache/cf/cf-kv-utils.d.ts +0 -22
- package/dist/types.backup/cache/cf/cf-tag-marker-memo.d.ts +0 -15
- package/dist/types.backup/cache/cf/index.d.ts +0 -3
- package/dist/types.backup/cache/document-cache.d.ts +0 -69
- package/dist/types.backup/cache/handle-capture.d.ts +0 -23
- package/dist/types.backup/cache/handle-snapshot.d.ts +0 -39
- package/dist/types.backup/cache/index.d.ts +0 -7
- package/dist/types.backup/cache/memory-segment-store.d.ts +0 -163
- package/dist/types.backup/cache/profile-registry.d.ts +0 -40
- package/dist/types.backup/cache/read-through-swr.d.ts +0 -60
- package/dist/types.backup/cache/segment-codec.d.ts +0 -78
- package/dist/types.backup/cache/shell-snapshot.d.ts +0 -162
- package/dist/types.backup/cache/tag-invalidation.d.ts +0 -74
- package/dist/types.backup/cache/taint.d.ts +0 -71
- package/dist/types.backup/cache/types.d.ts +0 -407
- package/dist/types.backup/cache/vercel/index.d.ts +0 -1
- package/dist/types.backup/cache/vercel/vercel-cache-store.d.ts +0 -267
- package/dist/types.backup/client.d.ts +0 -184
- package/dist/types.backup/client.rsc.d.ts +0 -39
- package/dist/types.backup/cloudflare/index.d.ts +0 -7
- package/dist/types.backup/cloudflare/tracing.d.ts +0 -53
- package/dist/types.backup/component-utils.d.ts +0 -46
- package/dist/types.backup/components/DefaultDocument.d.ts +0 -13
- package/dist/types.backup/context-var.d.ts +0 -84
- package/dist/types.backup/debug.d.ts +0 -57
- package/dist/types.backup/decode-loader-results.d.ts +0 -5
- package/dist/types.backup/default-error-boundary.d.ts +0 -10
- package/dist/types.backup/defer.d.ts +0 -89
- package/dist/types.backup/deps/browser.d.ts +0 -1
- package/dist/types.backup/deps/html-stream-client.d.ts +0 -1
- package/dist/types.backup/deps/html-stream-server.d.ts +0 -1
- package/dist/types.backup/deps/rsc.d.ts +0 -1
- package/dist/types.backup/deps/ssr.d.ts +0 -1
- package/dist/types.backup/encode-kv.d.ts +0 -35
- package/dist/types.backup/errors.d.ts +0 -226
- package/dist/types.backup/escape-script.d.ts +0 -44
- package/dist/types.backup/handle.d.ts +0 -93
- package/dist/types.backup/handles/MetaTags.d.ts +0 -17
- package/dist/types.backup/handles/Scripts.d.ts +0 -38
- package/dist/types.backup/handles/breadcrumbs.d.ts +0 -43
- package/dist/types.backup/handles/deferred-resolution.d.ts +0 -53
- package/dist/types.backup/handles/is-thenable.d.ts +0 -12
- package/dist/types.backup/handles/meta.d.ts +0 -43
- package/dist/types.backup/handles/script.d.ts +0 -139
- package/dist/types.backup/host/cookie-handler.d.ts +0 -8
- package/dist/types.backup/host/errors.d.ts +0 -40
- package/dist/types.backup/host/index.d.ts +0 -33
- package/dist/types.backup/host/pattern-matcher.d.ts +0 -30
- package/dist/types.backup/host/router.d.ts +0 -12
- package/dist/types.backup/host/testing.d.ts +0 -41
- package/dist/types.backup/host/types.d.ts +0 -148
- package/dist/types.backup/host/utils.d.ts +0 -20
- package/dist/types.backup/href-client.d.ts +0 -214
- package/dist/types.backup/index.d.ts +0 -112
- package/dist/types.backup/index.rsc.d.ts +0 -51
- package/dist/types.backup/internal-debug.d.ts +0 -1
- package/dist/types.backup/loader-store.d.ts +0 -193
- package/dist/types.backup/loader.d.ts +0 -18
- package/dist/types.backup/loader.rsc.d.ts +0 -18
- package/dist/types.backup/missing-id-error.d.ts +0 -1
- package/dist/types.backup/outlet-context.d.ts +0 -12
- package/dist/types.backup/outlet-provider.d.ts +0 -12
- package/dist/types.backup/prerender/build-shell-capture.d.ts +0 -104
- package/dist/types.backup/prerender/param-hash.d.ts +0 -6
- package/dist/types.backup/prerender/shell-manifest-key.d.ts +0 -18
- package/dist/types.backup/prerender/store.d.ts +0 -62
- package/dist/types.backup/prerender.d.ts +0 -292
- package/dist/types.backup/redirect-origin.d.ts +0 -55
- package/dist/types.backup/regex-escape.d.ts +0 -6
- package/dist/types.backup/render-error-thrower.d.ts +0 -13
- package/dist/types.backup/response-utils.d.ts +0 -35
- package/dist/types.backup/reverse.d.ts +0 -206
- package/dist/types.backup/root-error-boundary.d.ts +0 -32
- package/dist/types.backup/route-content-wrapper.d.ts +0 -40
- package/dist/types.backup/route-definition/dsl-helpers.d.ts +0 -130
- package/dist/types.backup/route-definition/helper-factories.d.ts +0 -22
- package/dist/types.backup/route-definition/helpers-types.d.ts +0 -392
- package/dist/types.backup/route-definition/index.d.ts +0 -7
- package/dist/types.backup/route-definition/redirect.d.ts +0 -48
- package/dist/types.backup/route-definition/resolve-handler-use.d.ts +0 -19
- package/dist/types.backup/route-definition/use-item-types.d.ts +0 -1
- package/dist/types.backup/route-definition.d.ts +0 -1
- package/dist/types.backup/route-map-builder.d.ts +0 -127
- package/dist/types.backup/route-name.d.ts +0 -27
- package/dist/types.backup/route-types.d.ts +0 -172
- package/dist/types.backup/router/basename.d.ts +0 -10
- package/dist/types.backup/router/content-negotiation.d.ts +0 -91
- package/dist/types.backup/router/debug-manifest.d.ts +0 -7
- package/dist/types.backup/router/error-handling.d.ts +0 -76
- package/dist/types.backup/router/find-match.d.ts +0 -19
- package/dist/types.backup/router/handler-context.d.ts +0 -41
- package/dist/types.backup/router/instrument.d.ts +0 -161
- package/dist/types.backup/router/intercept-resolution.d.ts +0 -79
- package/dist/types.backup/router/lazy-includes.d.ts +0 -26
- package/dist/types.backup/router/loader-resolution.d.ts +0 -63
- package/dist/types.backup/router/logging.d.ts +0 -41
- package/dist/types.backup/router/manifest.d.ts +0 -8
- package/dist/types.backup/router/match-api.d.ts +0 -19
- package/dist/types.backup/router/match-context.d.ts +0 -184
- package/dist/types.backup/router/match-handlers.d.ts +0 -49
- package/dist/types.backup/router/match-middleware/background-revalidation.d.ts +0 -113
- package/dist/types.backup/router/match-middleware/cache-lookup.d.ts +0 -113
- package/dist/types.backup/router/match-middleware/cache-store.d.ts +0 -112
- package/dist/types.backup/router/match-middleware/index.d.ts +0 -80
- package/dist/types.backup/router/match-middleware/intercept-resolution.d.ts +0 -116
- package/dist/types.backup/router/match-middleware/segment-resolution.d.ts +0 -94
- package/dist/types.backup/router/match-pipelines.d.ts +0 -103
- package/dist/types.backup/router/match-result.d.ts +0 -114
- package/dist/types.backup/router/metrics.d.ts +0 -6
- package/dist/types.backup/router/middleware-types.d.ts +0 -74
- package/dist/types.backup/router/middleware.d.ts +0 -116
- package/dist/types.backup/router/navigation-snapshot.d.ts +0 -22
- package/dist/types.backup/router/params-util.d.ts +0 -8
- package/dist/types.backup/router/parse-pattern.d.ts +0 -38
- package/dist/types.backup/router/pattern-matching.d.ts +0 -169
- package/dist/types.backup/router/prefetch-cache-ttl.d.ts +0 -27
- package/dist/types.backup/router/prefetch-limits.d.ts +0 -20
- package/dist/types.backup/router/prerender-match.d.ts +0 -50
- package/dist/types.backup/router/preview-match.d.ts +0 -22
- package/dist/types.backup/router/request-classification.d.ts +0 -104
- package/dist/types.backup/router/revalidation.d.ts +0 -57
- package/dist/types.backup/router/route-snapshot.d.ts +0 -112
- package/dist/types.backup/router/router-context.d.ts +0 -137
- package/dist/types.backup/router/router-interfaces.d.ts +0 -432
- package/dist/types.backup/router/router-options.d.ts +0 -738
- package/dist/types.backup/router/router-registry.d.ts +0 -15
- package/dist/types.backup/router/segment-resolution/fresh.d.ts +0 -55
- package/dist/types.backup/router/segment-resolution/helpers.d.ts +0 -93
- package/dist/types.backup/router/segment-resolution/loader-cache.d.ts +0 -33
- package/dist/types.backup/router/segment-resolution/loader-mask.d.ts +0 -44
- package/dist/types.backup/router/segment-resolution/loader-snapshot.d.ts +0 -90
- package/dist/types.backup/router/segment-resolution/mask-nested.d.ts +0 -53
- package/dist/types.backup/router/segment-resolution/revalidation.d.ts +0 -85
- package/dist/types.backup/router/segment-resolution/static-store.d.ts +0 -17
- package/dist/types.backup/router/segment-resolution/streamed-handler-telemetry.d.ts +0 -16
- package/dist/types.backup/router/segment-resolution/view-transition-default.d.ts +0 -28
- package/dist/types.backup/router/segment-resolution.d.ts +0 -3
- package/dist/types.backup/router/segment-wrappers.d.ts +0 -53
- package/dist/types.backup/router/state-cookie-name.d.ts +0 -1
- package/dist/types.backup/router/substitute-pattern-params.d.ts +0 -23
- package/dist/types.backup/router/telemetry-otel.d.ts +0 -113
- package/dist/types.backup/router/telemetry.d.ts +0 -215
- package/dist/types.backup/router/timeout.d.ts +0 -68
- package/dist/types.backup/router/tracing.d.ts +0 -125
- package/dist/types.backup/router/trie-matching.d.ts +0 -32
- package/dist/types.backup/router/types.d.ts +0 -98
- package/dist/types.backup/router/url-params.d.ts +0 -26
- package/dist/types.backup/router.d.ts +0 -7
- package/dist/types.backup/rsc/capture-queue.d.ts +0 -6
- package/dist/types.backup/rsc/full-payload.d.ts +0 -22
- package/dist/types.backup/rsc/handler-context.d.ts +0 -31
- package/dist/types.backup/rsc/handler.d.ts +0 -9
- package/dist/types.backup/rsc/helpers.d.ts +0 -213
- package/dist/types.backup/rsc/index.d.ts +0 -17
- package/dist/types.backup/rsc/json-route-result.d.ts +0 -20
- package/dist/types.backup/rsc/loader-fetch.d.ts +0 -14
- package/dist/types.backup/rsc/manifest-init.d.ts +0 -18
- package/dist/types.backup/rsc/nonce.d.ts +0 -28
- package/dist/types.backup/rsc/origin-guard.d.ts +0 -50
- package/dist/types.backup/rsc/progressive-enhancement.d.ts +0 -19
- package/dist/types.backup/rsc/redirect-guard.d.ts +0 -35
- package/dist/types.backup/rsc/response-cache-serve.d.ts +0 -46
- package/dist/types.backup/rsc/response-error.d.ts +0 -19
- package/dist/types.backup/rsc/response-route-handler.d.ts +0 -29
- package/dist/types.backup/rsc/rsc-rendering.d.ts +0 -23
- package/dist/types.backup/rsc/runtime-warnings.d.ts +0 -22
- package/dist/types.backup/rsc/server-action.d.ts +0 -68
- package/dist/types.backup/rsc/shell-build-manifest.d.ts +0 -84
- package/dist/types.backup/rsc/shell-capture-constants.d.ts +0 -27
- package/dist/types.backup/rsc/shell-capture.d.ts +0 -374
- package/dist/types.backup/rsc/shell-serve.d.ts +0 -136
- package/dist/types.backup/rsc/ssr-setup.d.ts +0 -48
- package/dist/types.backup/rsc/transition-gate.d.ts +0 -27
- package/dist/types.backup/rsc/types.d.ts +0 -290
- package/dist/types.backup/runtime-env.d.ts +0 -1
- package/dist/types.backup/search-params.d.ts +0 -125
- package/dist/types.backup/segment-content-promise.d.ts +0 -13
- package/dist/types.backup/segment-fragments.d.ts +0 -56
- package/dist/types.backup/segment-loader-promise.d.ts +0 -22
- package/dist/types.backup/segment-system.d.ts +0 -84
- package/dist/types.backup/serialize.d.ts +0 -164
- package/dist/types.backup/server/context.d.ts +0 -494
- package/dist/types.backup/server/cookie-parse.d.ts +0 -10
- package/dist/types.backup/server/cookie-store.d.ts +0 -107
- package/dist/types.backup/server/fetchable-loader-store.d.ts +0 -20
- package/dist/types.backup/server/handle-store.d.ts +0 -100
- package/dist/types.backup/server/loader-registry.d.ts +0 -32
- package/dist/types.backup/server/request-context.d.ts +0 -596
- package/dist/types.backup/server/root-layout.d.ts +0 -3
- package/dist/types.backup/server.d.ts +0 -15
- package/dist/types.backup/ssr/index.d.ts +0 -233
- package/dist/types.backup/ssr/inject-rsc-eager.d.ts +0 -3
- package/dist/types.backup/ssr/preinit-client-references.d.ts +0 -71
- package/dist/types.backup/ssr/ssr-root.d.ts +0 -69
- package/dist/types.backup/static-handler.d.ts +0 -57
- package/dist/types.backup/testing/cache-status.d.ts +0 -63
- package/dist/types.backup/testing/collect-handle.d.ts +0 -20
- package/dist/types.backup/testing/dispatch.d.ts +0 -123
- package/dist/types.backup/testing/dom.entry.d.ts +0 -15
- package/dist/types.backup/testing/e2e/fixture.d.ts +0 -37
- package/dist/types.backup/testing/e2e/index.d.ts +0 -30
- package/dist/types.backup/testing/e2e/matchers.d.ts +0 -17
- package/dist/types.backup/testing/e2e/page-helpers.d.ts +0 -62
- package/dist/types.backup/testing/e2e/parity.d.ts +0 -111
- package/dist/types.backup/testing/e2e/server.d.ts +0 -35
- package/dist/types.backup/testing/flight-matchers.d.ts +0 -55
- package/dist/types.backup/testing/flight-normalize.d.ts +0 -1
- package/dist/types.backup/testing/flight-tree.d.ts +0 -192
- package/dist/types.backup/testing/flight.d.ts +0 -115
- package/dist/types.backup/testing/flight.entry.d.ts +0 -27
- package/dist/types.backup/testing/generated-routes.d.ts +0 -66
- package/dist/types.backup/testing/index.d.ts +0 -52
- package/dist/types.backup/testing/internal/context.d.ts +0 -225
- package/dist/types.backup/testing/internal/flight-client-globals.d.ts +0 -1
- package/dist/types.backup/testing/internal/seed-vars.d.ts +0 -30
- package/dist/types.backup/testing/render-handler.d.ts +0 -160
- package/dist/types.backup/testing/render-route.d.ts +0 -246
- package/dist/types.backup/testing/run-loader.d.ts +0 -186
- package/dist/types.backup/testing/run-middleware.d.ts +0 -132
- package/dist/types.backup/testing/run-transition-when.d.ts +0 -77
- package/dist/types.backup/testing/vitest-stubs/cloudflare-email.d.ts +0 -6
- package/dist/types.backup/testing/vitest-stubs/cloudflare-workers.d.ts +0 -13
- package/dist/types.backup/testing/vitest-stubs/plugin-rsc.d.ts +0 -7
- package/dist/types.backup/testing/vitest-stubs/version.d.ts +0 -1
- package/dist/types.backup/testing/vitest.d.ts +0 -205
- package/dist/types.backup/theme/ThemeProvider.d.ts +0 -13
- package/dist/types.backup/theme/ThemeScript.d.ts +0 -45
- package/dist/types.backup/theme/constants.d.ts +0 -39
- package/dist/types.backup/theme/index.d.ts +0 -29
- package/dist/types.backup/theme/theme-context.d.ts +0 -21
- package/dist/types.backup/theme/theme-script.d.ts +0 -26
- package/dist/types.backup/theme/types.d.ts +0 -162
- package/dist/types.backup/theme/use-theme.d.ts +0 -8
- package/dist/types.backup/types/boundaries.d.ts +0 -93
- package/dist/types.backup/types/cache-types.d.ts +0 -191
- package/dist/types.backup/types/error-types.d.ts +0 -114
- package/dist/types.backup/types/global-namespace.d.ts +0 -90
- package/dist/types.backup/types/handler-context.d.ts +0 -658
- package/dist/types.backup/types/index.d.ts +0 -11
- package/dist/types.backup/types/loader-types.d.ts +0 -182
- package/dist/types.backup/types/request-scope.d.ts +0 -93
- package/dist/types.backup/types/route-config.d.ts +0 -105
- package/dist/types.backup/types/route-entry.d.ts +0 -95
- package/dist/types.backup/types/segments.d.ts +0 -234
- package/dist/types.backup/types.d.ts +0 -1
- package/dist/types.backup/urls/include-helper.d.ts +0 -17
- package/dist/types.backup/urls/include-provider.d.ts +0 -27
- package/dist/types.backup/urls/index.d.ts +0 -6
- package/dist/types.backup/urls/path-helper-types.d.ts +0 -197
- package/dist/types.backup/urls/path-helper.d.ts +0 -12
- package/dist/types.backup/urls/pattern-types.d.ts +0 -166
- package/dist/types.backup/urls/response-types.d.ts +0 -67
- package/dist/types.backup/urls/type-extraction.d.ts +0 -157
- package/dist/types.backup/urls/urls-function.d.ts +0 -24
- package/dist/types.backup/urls.d.ts +0 -1
- package/dist/types.backup/use-loader.d.ts +0 -150
- package/dist/types.backup/vercel/index.d.ts +0 -10
- package/dist/types.backup/vercel/tracing.d.ts +0 -70
- package/dist/types.backup/vite/debug.d.ts +0 -80
- package/dist/types.backup/vite/discovery/bundle-postprocess.d.ts +0 -12
- package/dist/types.backup/vite/discovery/dev-prerender-cache.d.ts +0 -65
- package/dist/types.backup/vite/discovery/discover-routers.d.ts +0 -17
- package/dist/types.backup/vite/discovery/discovery-errors.d.ts +0 -113
- package/dist/types.backup/vite/discovery/gate-state.d.ts +0 -79
- package/dist/types.backup/vite/discovery/prerender-collection.d.ts +0 -24
- package/dist/types.backup/vite/discovery/route-types-writer.d.ts +0 -32
- package/dist/types.backup/vite/discovery/self-gen-tracking.d.ts +0 -22
- package/dist/types.backup/vite/discovery/shell-prerender-phase.d.ts +0 -40
- package/dist/types.backup/vite/discovery/state.d.ts +0 -162
- package/dist/types.backup/vite/discovery/virtual-module-codegen.d.ts +0 -15
- package/dist/types.backup/vite/index.d.ts +0 -11
- package/dist/types.backup/vite/inject-client-debug.d.ts +0 -56
- package/dist/types.backup/vite/plugin-types.d.ts +0 -298
- package/dist/types.backup/vite/plugins/cjs-to-esm.d.ts +0 -6
- package/dist/types.backup/vite/plugins/client-ref-dedup.d.ts +0 -40
- package/dist/types.backup/vite/plugins/client-ref-hashing.d.ts +0 -35
- package/dist/types.backup/vite/plugins/cloudflare-protocol-stub.d.ts +0 -64
- package/dist/types.backup/vite/plugins/expose-action-id.d.ts +0 -18
- package/dist/types.backup/vite/plugins/expose-id-utils.d.ts +0 -37
- package/dist/types.backup/vite/plugins/expose-ids/export-analysis.d.ts +0 -19
- package/dist/types.backup/vite/plugins/expose-ids/handler-transform.d.ts +0 -10
- package/dist/types.backup/vite/plugins/expose-ids/loader-transform.d.ts +0 -8
- package/dist/types.backup/vite/plugins/expose-ids/router-transform.d.ts +0 -13
- package/dist/types.backup/vite/plugins/expose-ids/types.d.ts +0 -29
- package/dist/types.backup/vite/plugins/expose-internal-ids.d.ts +0 -6
- package/dist/types.backup/vite/plugins/performance-tracks.d.ts +0 -25
- package/dist/types.backup/vite/plugins/refresh-cmd.d.ts +0 -20
- package/dist/types.backup/vite/plugins/use-cache-transform.d.ts +0 -20
- package/dist/types.backup/vite/plugins/vercel-output.d.ts +0 -85
- package/dist/types.backup/vite/plugins/version-injector.d.ts +0 -21
- package/dist/types.backup/vite/plugins/version-plugin.d.ts +0 -19
- package/dist/types.backup/vite/plugins/virtual-entries.d.ts +0 -36
- package/dist/types.backup/vite/plugins/virtual-stub-plugin.d.ts +0 -7
- package/dist/types.backup/vite/rango.d.ts +0 -29
- package/dist/types.backup/vite/router-discovery.d.ts +0 -23
- package/dist/types.backup/vite/utils/ast-handler-extract.d.ts +0 -64
- package/dist/types.backup/vite/utils/banner.d.ts +0 -2
- package/dist/types.backup/vite/utils/bundle-analysis.d.ts +0 -28
- package/dist/types.backup/vite/utils/client-chunks.d.ts +0 -55
- package/dist/types.backup/vite/utils/directive-prologue.d.ts +0 -16
- package/dist/types.backup/vite/utils/forward-user-plugins.d.ts +0 -37
- package/dist/types.backup/vite/utils/manifest-utils.d.ts +0 -7
- package/dist/types.backup/vite/utils/package-resolution.d.ts +0 -6
- package/dist/types.backup/vite/utils/prerender-utils.d.ts +0 -32
- package/dist/types.backup/vite/utils/shared-utils.d.ts +0 -55
|
@@ -106,6 +106,7 @@ import {
|
|
|
106
106
|
runWithRequestContext,
|
|
107
107
|
} from "../../server/request-context.js";
|
|
108
108
|
import type { MatchContext, MatchPipelineState } from "../match-context.js";
|
|
109
|
+
import { createShellImplicitDocScope } from "../../cache/cache-scope.js";
|
|
109
110
|
import { getRouterContext } from "../router-context.js";
|
|
110
111
|
import { debugLog, debugWarn, getOrCreateRequestId } from "../logging.js";
|
|
111
112
|
import { INTERNAL_RANGO_DEBUG } from "../../internal-debug.js";
|
|
@@ -134,6 +135,14 @@ export function withCacheStore<TEnv>(
|
|
|
134
135
|
|
|
135
136
|
const ownStart = performance.now();
|
|
136
137
|
|
|
138
|
+
// Shell capture composition (capture side): a route-derived cache() scope
|
|
139
|
+
// keeps its normal store write below, but the capture's shell entry still
|
|
140
|
+
// needs the CANONICAL doc segment record for navigation replay. Recorded
|
|
141
|
+
// before the skip check because it must run on the explicit tier's hit
|
|
142
|
+
// path too (state.cacheHit skips the normal write, yet the served
|
|
143
|
+
// segments were collected into allSegments either way).
|
|
144
|
+
recordShellCaptureDocRecord(ctx, state, allSegments);
|
|
145
|
+
|
|
137
146
|
if (
|
|
138
147
|
!ctx.cacheScope?.enabled ||
|
|
139
148
|
ctx.isAction ||
|
|
@@ -348,3 +357,64 @@ export function withCacheStore<TEnv>(
|
|
|
348
357
|
}
|
|
349
358
|
};
|
|
350
359
|
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* During a SHELL CAPTURE of a route with a route-derived cache() scope, write
|
|
363
|
+
* the matched non-loader segments as the canonical doc segment record through
|
|
364
|
+
* the capture marker's SnapshotOnlySegmentStore — IN ADDITION to the explicit
|
|
365
|
+
* scope's normal real-store write. The record rides only inside the shell
|
|
366
|
+
* entry (a real doc-keyed write would poison the next capture's lookup; see
|
|
367
|
+
* RecordingShellStore.recordSegmentWrite), so no real-store behavior changes.
|
|
368
|
+
* Without it, navigation replay was structurally dead for any ppr route under
|
|
369
|
+
* a cache() scope (including an app-wide one): the snapshot held only
|
|
370
|
+
* explicit-tier-keyed records a partial lookup can never resolve.
|
|
371
|
+
*
|
|
372
|
+
* Records nothing when:
|
|
373
|
+
* - not a capture render, or the route derived no scope (the implicit doc
|
|
374
|
+
* scope's own cacheRoute below already records the doc record);
|
|
375
|
+
* - the scope is STATICALLY disabled (cache(false)) — the replay gate
|
|
376
|
+
* pre-decides that shape as `cache-disabled` before any shell read, so a
|
|
377
|
+
* record would be dead weight;
|
|
378
|
+
* - the prerender store supplied the match: those partials are served from
|
|
379
|
+
* build-time segments and report `prerender-store`.
|
|
380
|
+
*
|
|
381
|
+
* A false condition() suppresses the record too — the consumer's write
|
|
382
|
+
* refusal is absolute. The prelude-already-bakes-it argument does NOT excuse
|
|
383
|
+
* recording: a NAVIGATION-ONLY capture's prelude is never served as a
|
|
384
|
+
* document, so for those entries the segment record would be the sole
|
|
385
|
+
* persisted copy of a render the consumer refused to cache — and a later
|
|
386
|
+
* request where condition() flips true could consume it through the seeded
|
|
387
|
+
* fallback. The lookup-time `cache-disabled` report stays reachable without
|
|
388
|
+
* the record: matchPartialWithPprReplay installs a REPORT-ONLY marker (no
|
|
389
|
+
* store) on the no-eligible-snapshot path, so the lookup's own refusal is
|
|
390
|
+
* still surfaced while the fallback has nothing to serve.
|
|
391
|
+
*
|
|
392
|
+
* Wrapped in requestCtx.waitUntil — during a capture that is the tracked-write
|
|
393
|
+
* override, so captureAndStoreShell's settleWrites awaits the record before
|
|
394
|
+
* draining the snapshot.
|
|
395
|
+
*/
|
|
396
|
+
function recordShellCaptureDocRecord<TEnv>(
|
|
397
|
+
ctx: MatchContext<TEnv>,
|
|
398
|
+
state: MatchPipelineState,
|
|
399
|
+
segments: ResolvedSegment[],
|
|
400
|
+
): void {
|
|
401
|
+
const requestCtx = getRequestContext();
|
|
402
|
+
if (!requestCtx?._shellCaptureRun) return;
|
|
403
|
+
const marker = requestCtx._shellImplicitCache;
|
|
404
|
+
if (!marker?.store) return;
|
|
405
|
+
const scope = ctx.cacheScope;
|
|
406
|
+
if (!scope || scope.isShellImplicitDocScope) return;
|
|
407
|
+
if (ctx.isAction || ctx.isIntercept || ctx.request.method !== "GET") return;
|
|
408
|
+
if (state.cacheSource === "prerender") return;
|
|
409
|
+
if (!scope.allowsCache("write")) return;
|
|
410
|
+
|
|
411
|
+
const docScope = createShellImplicitDocScope(marker);
|
|
412
|
+
requestCtx.waitUntil(() =>
|
|
413
|
+
docScope.cacheRoute(
|
|
414
|
+
ctx.pathname,
|
|
415
|
+
ctx.matched.params,
|
|
416
|
+
segments,
|
|
417
|
+
ctx.isIntercept,
|
|
418
|
+
),
|
|
419
|
+
);
|
|
420
|
+
}
|
|
@@ -30,6 +30,50 @@ export interface ResolveNavigationDeps {
|
|
|
30
30
|
) => RouteMatchResult | null | Promise<RouteMatchResult | null>;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
/**
|
|
34
|
+
* The raw navigation-context header for a partial request, or null when the
|
|
35
|
+
* request carries none. Single source of truth shared by resolveNavigation and
|
|
36
|
+
* the PPR replay gate (matchPartialWithPprReplay): a context-less partial can
|
|
37
|
+
* never produce a partial match, so the replay path must decide
|
|
38
|
+
* `no-navigation-context` BEFORE spending shell-store reads — the two
|
|
39
|
+
* predicates drifting apart would misattribute the bypass again.
|
|
40
|
+
*/
|
|
41
|
+
export function getNavigationContextHeader(request: Request): string | null {
|
|
42
|
+
return (
|
|
43
|
+
request.headers.get("X-RSC-Router-Client-Path") ||
|
|
44
|
+
request.headers.get("Referer")
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Whether withCacheLookup's prerender short-circuit will serve this partial
|
|
50
|
+
* from the build-time prerender store: a Prerender() match (`matched.pr`)
|
|
51
|
+
* outside dev HMR — the short-circuit is disabled on X-RSC-HMR so HMR
|
|
52
|
+
* navigations pick up edited modules. Shared by withCacheLookup and the PPR
|
|
53
|
+
* replay gate (matchPartialWithPprReplay) for the same drift reason as
|
|
54
|
+
* getNavigationContextHeader: the gate's `prerender-store` bypass must decide
|
|
55
|
+
* exactly what the middleware will actually do. (Both callers additionally
|
|
56
|
+
* exclude actions on their own paths — the gate via its GET-only check.)
|
|
57
|
+
*/
|
|
58
|
+
export function prerenderStoreShortCircuits(
|
|
59
|
+
pr: true | undefined,
|
|
60
|
+
request: Request,
|
|
61
|
+
): boolean {
|
|
62
|
+
return pr === true && !request.headers.get("X-RSC-HMR");
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* The intercept-source header for a partial request, or null when the request
|
|
67
|
+
* carries none. Shared by resolveNavigation and the PPR replay gate's
|
|
68
|
+
* prerender probe: intercept navigations consult the intercept-specific
|
|
69
|
+
* prerender artifact (`paramHash + "/i"`), so the probe must check the same
|
|
70
|
+
* variant the middleware will — probing the bare hash for an intercept
|
|
71
|
+
* request would report `prerender-store` for an artifact that cannot serve.
|
|
72
|
+
*/
|
|
73
|
+
export function getInterceptSourceHeader(request: Request): string | null {
|
|
74
|
+
return request.headers.get("X-RSC-Router-Intercept-Source");
|
|
75
|
+
}
|
|
76
|
+
|
|
33
77
|
export async function resolveNavigation(
|
|
34
78
|
request: Request,
|
|
35
79
|
url: URL,
|
|
@@ -39,12 +83,8 @@ export async function resolveNavigation(
|
|
|
39
83
|
const clientSegmentIds =
|
|
40
84
|
url.searchParams.get("_rsc_segments")?.split(",").filter(Boolean) || [];
|
|
41
85
|
const stale = url.searchParams.get("_rsc_stale") === "true";
|
|
42
|
-
const previousUrl =
|
|
43
|
-
|
|
44
|
-
request.headers.get("Referer");
|
|
45
|
-
const interceptSourceUrl = request.headers.get(
|
|
46
|
-
"X-RSC-Router-Intercept-Source",
|
|
47
|
-
);
|
|
86
|
+
const previousUrl = getNavigationContextHeader(request);
|
|
87
|
+
const interceptSourceUrl = getInterceptSourceHeader(request);
|
|
48
88
|
const isHmr = !!request.headers.get("X-RSC-HMR");
|
|
49
89
|
|
|
50
90
|
if (!previousUrl) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ComponentType, ReactNode } from "react";
|
|
2
2
|
import type { SegmentCacheStore } from "../cache/types.js";
|
|
3
|
+
import type { CacheSearchParams } from "../cache/search-params-filter.js";
|
|
3
4
|
import type {
|
|
4
5
|
ErrorBoundaryHandler,
|
|
5
6
|
NotFoundBoundaryHandler,
|
|
@@ -304,15 +305,37 @@ export interface RangoOptions<TEnv = any> {
|
|
|
304
305
|
* }),
|
|
305
306
|
* });
|
|
306
307
|
* ```
|
|
308
|
+
*
|
|
309
|
+
* `searchParams` controls which query params key the cache (default:
|
|
310
|
+
* `"all"`). Cache keys only -- handlers still see the full query string.
|
|
311
|
+
* Excluding a param is a promise that rendered output does not depend on
|
|
312
|
+
* it; if it does, the first variant is cached and served to everyone.
|
|
313
|
+
*
|
|
314
|
+
* @example Ignore tracking params for cache keys
|
|
315
|
+
* ```typescript
|
|
316
|
+
* import { TRACKING_SEARCH_PARAMS } from "@rangojs/router";
|
|
317
|
+
*
|
|
318
|
+
* const router = createRouter({
|
|
319
|
+
* cache: {
|
|
320
|
+
* store: cacheStore,
|
|
321
|
+
* searchParams: { exclude: TRACKING_SEARCH_PARAMS },
|
|
322
|
+
* },
|
|
323
|
+
* });
|
|
324
|
+
* ```
|
|
307
325
|
*/
|
|
308
326
|
cache?:
|
|
309
|
-
| {
|
|
327
|
+
| {
|
|
328
|
+
store: SegmentCacheStore;
|
|
329
|
+
enabled?: boolean;
|
|
330
|
+
searchParams?: CacheSearchParams;
|
|
331
|
+
}
|
|
310
332
|
| ((
|
|
311
333
|
env: TEnv,
|
|
312
334
|
ctx?: ExecutionContext,
|
|
313
335
|
) => {
|
|
314
336
|
store: SegmentCacheStore;
|
|
315
337
|
enabled?: boolean;
|
|
338
|
+
searchParams?: CacheSearchParams;
|
|
316
339
|
});
|
|
317
340
|
|
|
318
341
|
/**
|
|
@@ -535,9 +558,13 @@ export interface RangoOptions<TEnv = any> {
|
|
|
535
558
|
|
|
536
559
|
/**
|
|
537
560
|
* Default prefetch strategy for every `<Link>` that does not set its own
|
|
538
|
-
* `prefetch` prop
|
|
539
|
-
*
|
|
540
|
-
*
|
|
561
|
+
* `prefetch` prop and every eligible intercepted plain anchor. Plain anchors
|
|
562
|
+
* can opt out with `data-prefetch="false"` or `data-prefetch="none"`. Common
|
|
563
|
+
* static-resource suffixes are excluded unless `data-prefetch="true"` marks
|
|
564
|
+
* the URL as an application route. Mark side-effectful GET links such as
|
|
565
|
+
* `/logout` with an opt-out because the router cannot infer endpoint safety.
|
|
566
|
+
* A per-Link `prefetch` prop always wins in both directions (a Link can opt
|
|
567
|
+
* out with `prefetch="none"`, or opt in under `defaultPrefetch: "none"`).
|
|
541
568
|
*
|
|
542
569
|
* - `"viewport"` (production default): prefetch when the link enters the viewport —
|
|
543
570
|
* idle-gated and queued (see `prefetchConcurrency`), so prefetches never
|
package/src/rsc/handler.ts
CHANGED
|
@@ -64,6 +64,10 @@ import {
|
|
|
64
64
|
} from "../route-map-builder.js";
|
|
65
65
|
import type { HandlerContext } from "./handler-context.js";
|
|
66
66
|
import type { CacheErrorCategory } from "../cache/cache-error.js";
|
|
67
|
+
import {
|
|
68
|
+
compileSearchParamsFilter,
|
|
69
|
+
type SearchParamsFilter,
|
|
70
|
+
} from "../cache/search-params-filter.js";
|
|
67
71
|
import type { SegmentCacheStore } from "../cache/types.js";
|
|
68
72
|
import { buildRouterTrieFromUrlpatterns } from "./manifest-init.js";
|
|
69
73
|
import { handleProgressiveEnhancement } from "./progressive-enhancement.js";
|
|
@@ -460,6 +464,7 @@ export function createRSCHandler<
|
|
|
460
464
|
// Priority: options.cache (handler override) > router.cache (router default)
|
|
461
465
|
// Store is enabled only if: config provided, enabled, and no ?__no_cache query param
|
|
462
466
|
let cacheStore: SegmentCacheStore | undefined;
|
|
467
|
+
let searchParamsFilter: SearchParamsFilter | undefined;
|
|
463
468
|
const cacheOption = options.cache ?? router.cache;
|
|
464
469
|
if (cacheOption && !url.searchParams.has("__no_cache")) {
|
|
465
470
|
const cacheConfig =
|
|
@@ -469,6 +474,9 @@ export function createRSCHandler<
|
|
|
469
474
|
|
|
470
475
|
if (cacheConfig.enabled !== false) {
|
|
471
476
|
cacheStore = cacheConfig.store;
|
|
477
|
+
searchParamsFilter = compileSearchParamsFilter(
|
|
478
|
+
cacheConfig.searchParams,
|
|
479
|
+
);
|
|
472
480
|
}
|
|
473
481
|
}
|
|
474
482
|
|
|
@@ -526,6 +534,7 @@ export function createRSCHandler<
|
|
|
526
534
|
url,
|
|
527
535
|
variables,
|
|
528
536
|
cacheStore,
|
|
537
|
+
searchParamsFilter,
|
|
529
538
|
explicitTaggedStores,
|
|
530
539
|
cacheProfiles: router.cacheProfiles,
|
|
531
540
|
executionContext: executionCtx,
|
|
@@ -103,7 +103,7 @@ export async function serveResponseRouteWithCache(
|
|
|
103
103
|
// Default key: response:{type}: + host-namespaced base (sorted search, reserved
|
|
104
104
|
// _rsc*/__* params excluded). Same composition as document/segment tiers so
|
|
105
105
|
// the host-namespacing and search-normalization rules cannot drift.
|
|
106
|
-
let cacheKey = `response:${responseType}:${cacheKeyBase(url.host, url.pathname, url.searchParams)}`;
|
|
106
|
+
let cacheKey = `response:${responseType}:${cacheKeyBase(url.host, url.pathname, url.searchParams, undefined, reqCtx._searchParamsFilter)}`;
|
|
107
107
|
|
|
108
108
|
// Priority 1: route-level key() (full override). Priority 2: store-level
|
|
109
109
|
// keyGenerator (modifies the default key).
|
package/src/rsc/rsc-rendering.ts
CHANGED
|
@@ -61,12 +61,22 @@ import {
|
|
|
61
61
|
type DevShellLookup,
|
|
62
62
|
} from "./shell-build-manifest.js";
|
|
63
63
|
import { contextGet } from "../context-var.js";
|
|
64
|
+
import {
|
|
65
|
+
getNavigationContextHeader,
|
|
66
|
+
prerenderStoreShortCircuits,
|
|
67
|
+
} from "../router/navigation-snapshot.js";
|
|
68
|
+
import {
|
|
69
|
+
ensureFullRouteSnapshot,
|
|
70
|
+
type RouteSnapshot,
|
|
71
|
+
} from "../router/route-snapshot.js";
|
|
72
|
+
import { prerenderEntryExists } from "../router/match-middleware/cache-lookup.js";
|
|
64
73
|
import {
|
|
65
74
|
resolveSameOriginRedirect,
|
|
66
75
|
safeSameOriginLanding,
|
|
67
76
|
} from "../redirect-origin.js";
|
|
68
77
|
import { nonce as nonceToken } from "./nonce.js";
|
|
69
78
|
import { reportCacheError } from "../cache/cache-error.js";
|
|
79
|
+
import type { SearchParamsFilter } from "../cache/search-params-filter.js";
|
|
70
80
|
import { INTERNAL_RANGO_DEBUG } from "../internal-debug.js";
|
|
71
81
|
import type {
|
|
72
82
|
SegmentCacheStore,
|
|
@@ -80,6 +90,10 @@ type PprReplayBypassReason =
|
|
|
80
90
|
| "nonce"
|
|
81
91
|
| "store-unavailable"
|
|
82
92
|
| "passive-read-unsupported"
|
|
93
|
+
| "no-navigation-context"
|
|
94
|
+
| "prerender-store"
|
|
95
|
+
| "intercept"
|
|
96
|
+
| "cache-disabled"
|
|
83
97
|
| "read-error"
|
|
84
98
|
| "no-entry"
|
|
85
99
|
| "invalid-version"
|
|
@@ -88,6 +102,7 @@ type PprReplayBypassReason =
|
|
|
88
102
|
| "transition-when"
|
|
89
103
|
| "no-segment-snapshot"
|
|
90
104
|
| "snapshot-miss"
|
|
105
|
+
| "explicit-cache-hit"
|
|
91
106
|
| "stale-build-entry";
|
|
92
107
|
|
|
93
108
|
type PprReplayStatus =
|
|
@@ -110,8 +125,11 @@ function describePprReplayStatus(status: PprReplayStatus): string {
|
|
|
110
125
|
: `bypass:${status.reason}`;
|
|
111
126
|
}
|
|
112
127
|
|
|
113
|
-
function buildNavigationShellKey(
|
|
114
|
-
|
|
128
|
+
function buildNavigationShellKey(
|
|
129
|
+
url: URL,
|
|
130
|
+
filter?: SearchParamsFilter,
|
|
131
|
+
): string {
|
|
132
|
+
return `${buildShellKey(url, filter)}:navigation`;
|
|
115
133
|
}
|
|
116
134
|
|
|
117
135
|
function createShellCaptureDescriptor(
|
|
@@ -147,6 +165,26 @@ function shouldHealReplayMiss(
|
|
|
147
165
|
);
|
|
148
166
|
}
|
|
149
167
|
|
|
168
|
+
/**
|
|
169
|
+
* Post-match truth override for a pre-match BYPASS classification. The gate
|
|
170
|
+
* decides before matchPartial runs, but two facts only the match can settle:
|
|
171
|
+
* whether the prerender store ACTUALLY served (either artifact variant — the
|
|
172
|
+
* gate's probe reads only the non-intercept one), and whether the navigation
|
|
173
|
+
* resolved to an intercept (findInterceptForRoute runs during the match; the
|
|
174
|
+
* intercept-source header proves nothing in either direction). The resulting
|
|
175
|
+
* reason is stamped on the request context by withCacheLookup. A replay HIT is
|
|
176
|
+
* never overridden — the seeded record was demonstrably consumed, so neither
|
|
177
|
+
* fact can be true.
|
|
178
|
+
*/
|
|
179
|
+
function reclassifyReplayStatus(
|
|
180
|
+
reqCtx: RequestContext<any>,
|
|
181
|
+
status: PprReplayStatus,
|
|
182
|
+
): PprReplayStatus {
|
|
183
|
+
if (status.outcome === "HIT") return status;
|
|
184
|
+
const reason = reqCtx._pprReplayPostMatchReason;
|
|
185
|
+
return reason ? { outcome: "BYPASS", reason } : status;
|
|
186
|
+
}
|
|
187
|
+
|
|
150
188
|
function resolveDevShellLookup(
|
|
151
189
|
reqCtx: RequestContext<any>,
|
|
152
190
|
pprConfig: ResolvedPprConfig,
|
|
@@ -173,21 +211,32 @@ function replayableShellSnapshot(
|
|
|
173
211
|
if (!hasIntactShellPayload(entry)) return { reason: "corrupt-entry" };
|
|
174
212
|
if (entry.handlerLiveHoles) return { reason: "handler-live-holes" };
|
|
175
213
|
if (entry.transitionWhen) return { reason: "transition-when" };
|
|
214
|
+
// Eligibility requires the CANONICAL doc segment record (`docKey`), not just
|
|
215
|
+
// any segment record: captures under an explicit cache() scope also record
|
|
216
|
+
// that tier's reads/writes under keys a partial lookup can never resolve,
|
|
217
|
+
// and counting those declared entries "replayable" that then always missed
|
|
218
|
+
// (a timing-dependent snapshot-miss/no-segment-snapshot flip-flop). Entries
|
|
219
|
+
// captured before the field existed read as no-segment-snapshot and heal on
|
|
220
|
+
// recapture (pre-release, same treatment as the buildVersion field).
|
|
221
|
+
const docKey = entry.docKey;
|
|
176
222
|
const snapshot = entry.snapshot;
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
223
|
+
const hasDocRecord =
|
|
224
|
+
docKey !== undefined &&
|
|
225
|
+
snapshot?.some((record) => {
|
|
226
|
+
if (
|
|
227
|
+
!record ||
|
|
228
|
+
typeof record !== "object" ||
|
|
229
|
+
record.family !== "segment" ||
|
|
230
|
+
record.key !== docKey ||
|
|
231
|
+
typeof record.value !== "object" ||
|
|
232
|
+
record.value === null
|
|
233
|
+
) {
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
236
|
+
const segments = (record.value as { segments?: unknown }).segments;
|
|
237
|
+
return Array.isArray(segments) && segments.length > 0;
|
|
238
|
+
});
|
|
239
|
+
return hasDocRecord && snapshot
|
|
191
240
|
? { snapshot }
|
|
192
241
|
: { reason: "no-segment-snapshot" };
|
|
193
242
|
}
|
|
@@ -263,7 +312,7 @@ async function handleRscRenderingInner<TEnv>(
|
|
|
263
312
|
// the provider-only check missed the latter (issue #656).
|
|
264
313
|
const activeNonce = nonce ?? contextGet(reqCtx._variables, nonceToken);
|
|
265
314
|
const store = reqCtx._cacheStore;
|
|
266
|
-
const key = buildShellKey(url);
|
|
315
|
+
const key = buildShellKey(url, reqCtx._searchParamsFilter);
|
|
267
316
|
// Dev Server-Timing mirror (issue #651): a capture completes AFTER its
|
|
268
317
|
// triggering response committed, so its outcome can only ride a LATER
|
|
269
318
|
// response's header. Read-and-clear keeps one capture = one report;
|
|
@@ -417,6 +466,7 @@ async function handleRscRenderingInner<TEnv>(
|
|
|
417
466
|
// only (production's exact candidate set). Folded away in
|
|
418
467
|
// production builds (NODE_ENV is a compile-time constant).
|
|
419
468
|
resolveDevShellLookup(reqCtx, pprConfig),
|
|
469
|
+
reqCtx._searchParamsFilter,
|
|
420
470
|
);
|
|
421
471
|
if (buildHit) {
|
|
422
472
|
// Past ppr.ttl: still serve the baked entry, recapture upgrades it.
|
|
@@ -671,7 +721,7 @@ async function handleRscRenderingInner<TEnv>(
|
|
|
671
721
|
},
|
|
672
722
|
createShellCaptureDescriptor(
|
|
673
723
|
ctx,
|
|
674
|
-
buildNavigationShellKey(url),
|
|
724
|
+
buildNavigationShellKey(url, reqCtx._searchParamsFilter),
|
|
675
725
|
pprConfig,
|
|
676
726
|
store,
|
|
677
727
|
true,
|
|
@@ -710,10 +760,17 @@ async function matchPartialWithPprReplay<TEnv>(
|
|
|
710
760
|
describePprReplayStatus(status),
|
|
711
761
|
);
|
|
712
762
|
};
|
|
763
|
+
const finalizeReplayStatus = (status: PprReplayStatus): PprReplayStatus => {
|
|
764
|
+
const finalStatus = reclassifyReplayStatus(reqCtx, status);
|
|
765
|
+
recordReplayStatus(finalStatus);
|
|
766
|
+
return finalStatus;
|
|
767
|
+
};
|
|
713
768
|
const runMatch = async (status?: PprReplayStatus) => {
|
|
714
769
|
const result = await ctx.router.matchPartial(request, { env });
|
|
715
|
-
|
|
716
|
-
|
|
770
|
+
// The match may have settled a fact the pre-match gate could only guess
|
|
771
|
+
// at (prerender serve, intercept resolution) — report the truth.
|
|
772
|
+
const finalStatus = status ? finalizeReplayStatus(status) : undefined;
|
|
773
|
+
return { result, status: finalStatus };
|
|
717
774
|
};
|
|
718
775
|
const pprConfig = resolvePprConfig(reqCtx._classifiedRoute?.manifestEntry);
|
|
719
776
|
const activeNonce = nonce ?? contextGet(reqCtx._variables, nonceToken);
|
|
@@ -738,9 +795,64 @@ async function matchPartialWithPprReplay<TEnv>(
|
|
|
738
795
|
reason: "passive-read-unsupported",
|
|
739
796
|
});
|
|
740
797
|
}
|
|
798
|
+
// A partial without navigation context (curl probes, synthetic monitors)
|
|
799
|
+
// can never produce a partial match — createMatchContextForPartial returns
|
|
800
|
+
// null and the seeded record could not have been consulted, which used to
|
|
801
|
+
// read as a misleading `snapshot-miss` AFTER two wasted getShell reads.
|
|
802
|
+
// Same predicate as resolveNavigation, decided before any store I/O.
|
|
803
|
+
if (!getNavigationContextHeader(request)) {
|
|
804
|
+
return runMatch({ outcome: "BYPASS", reason: "no-navigation-context" });
|
|
805
|
+
}
|
|
806
|
+
// The prerender probe and the cache-opt-out gate below both need the
|
|
807
|
+
// classified snapshot; resolve (and persist) it once.
|
|
808
|
+
const routeSnapshot = classifiedRouteSnapshot(reqCtx);
|
|
809
|
+
// Prerender routes short-circuit in withCacheLookup and serve the partial
|
|
810
|
+
// from build-time segments — a better-than-HIT outcome. Their captures
|
|
811
|
+
// record no doc segment record (withCacheStore skips on the prerender hit),
|
|
812
|
+
// so seeding could never succeed; skip the reads and report the store that
|
|
813
|
+
// actually serves instead of blaming a "broken" capture. Bypass ONLY when
|
|
814
|
+
// the baked artifact actually exists — the trie's pr flag alone is not a
|
|
815
|
+
// serve guarantee: a Passthrough(Prerender()) route with an unbaked or
|
|
816
|
+
// ctx.passthrough()-skipped param misses the store and renders live, and
|
|
817
|
+
// replay (including its heal capture) must stay available for it. The
|
|
818
|
+
// probe goes through the same memoized store the middleware serves from.
|
|
819
|
+
// Shared predicate with the middleware (it declines on dev HMR — such
|
|
820
|
+
// partials fall through to the ordinary replay decision here too).
|
|
821
|
+
//
|
|
822
|
+
// The probe is a PRE-match fast path, not the truth: it reads only the
|
|
823
|
+
// non-intercept artifact, and whether the navigation IS an intercept (and
|
|
824
|
+
// therefore whether tryPrerenderLookup reads `paramHash` or
|
|
825
|
+
// `paramHash + "/i"`) is resolved during the match by match-api's
|
|
826
|
+
// findInterceptForRoute — an intercept-source header proves nothing in
|
|
827
|
+
// either direction. runMatch reclassifies every BYPASS from the stamped
|
|
828
|
+
// post-match facts (reclassifyReplayStatus), so a wrong guess here can
|
|
829
|
+
// skip the two getShell reads but never mis-report or mis-heal.
|
|
830
|
+
if (
|
|
831
|
+
prerenderStoreShortCircuits(routeSnapshot?.matched?.pr, request) &&
|
|
832
|
+
(await prerenderEntryExists(
|
|
833
|
+
routeSnapshot?.matched?.routeKey,
|
|
834
|
+
routeSnapshot?.params ?? {},
|
|
835
|
+
url.pathname,
|
|
836
|
+
routeSnapshot?.entries ?? [],
|
|
837
|
+
))
|
|
838
|
+
) {
|
|
839
|
+
return runMatch({ outcome: "BYPASS", reason: "prerender-store" });
|
|
840
|
+
}
|
|
841
|
+
// Consumer cache opt-outs are absolute: a STATICALLY disabled scope
|
|
842
|
+
// (cache(false)) bypasses before any shell read — no heal capture (its
|
|
843
|
+
// snapshot would be equally unusable). A `condition()` predicate is
|
|
844
|
+
// request-time state and must NOT be pre-decided here: evaluating it at the
|
|
845
|
+
// gate and again at the lookup lets a false-then-true flap report
|
|
846
|
+
// cache-disabled while the explicit tier serves. The lookup's own
|
|
847
|
+
// evaluation governs (withCacheLookup fires the marker's onExplicitBypass,
|
|
848
|
+
// reported as cache-disabled post-match).
|
|
849
|
+
const routeCacheScope = routeSnapshot?.cacheScope ?? null;
|
|
850
|
+
if (routeCacheScope && !routeCacheScope.enabled) {
|
|
851
|
+
return runMatch({ outcome: "BYPASS", reason: "cache-disabled" });
|
|
852
|
+
}
|
|
741
853
|
|
|
742
|
-
const key = buildShellKey(url);
|
|
743
|
-
const navigationKey =
|
|
854
|
+
const key = buildShellKey(url, reqCtx._searchParamsFilter);
|
|
855
|
+
const navigationKey = `${key}:navigation`;
|
|
744
856
|
let cached: Awaited<ReturnType<typeof store.getShell>> = null;
|
|
745
857
|
try {
|
|
746
858
|
cached = await store.getShell(key, { claimRevalidation: false });
|
|
@@ -794,7 +906,13 @@ async function matchPartialWithPprReplay<TEnv>(
|
|
|
794
906
|
// Production build manifests are local module data. In dev, resolving a
|
|
795
907
|
// missing build shell would foreground-fetch /__rsc_shell and block an
|
|
796
908
|
// otherwise ordinary navigation on capture, so replay remains runtime-only.
|
|
797
|
-
const buildHit = await lookupBuildShell(
|
|
909
|
+
const buildHit = await lookupBuildShell(
|
|
910
|
+
url,
|
|
911
|
+
ctx.version,
|
|
912
|
+
store,
|
|
913
|
+
undefined,
|
|
914
|
+
reqCtx._searchParamsFilter,
|
|
915
|
+
);
|
|
798
916
|
if (buildHit?.stale) {
|
|
799
917
|
bypassReason ??= "stale-build-entry";
|
|
800
918
|
} else if (buildHit) {
|
|
@@ -811,15 +929,78 @@ async function matchPartialWithPprReplay<TEnv>(
|
|
|
811
929
|
}
|
|
812
930
|
|
|
813
931
|
if (!snapshot) {
|
|
932
|
+
// Report-only marker for routes with an ENABLED route-derived scope: the
|
|
933
|
+
// lookup's own outcome must stay reportable even without a replayable
|
|
934
|
+
// snapshot. An always-false condition() route never produces a doc
|
|
935
|
+
// record (the consumer's write refusal is absolute — see
|
|
936
|
+
// recordShellCaptureDocRecord), so without this its lookup-time refusal
|
|
937
|
+
// would be misreported as the eligibility reason and heal captures would
|
|
938
|
+
// be scheduled for snapshots that can never become consumable. The
|
|
939
|
+
// marker carries NO store: the seeded fallback in withCacheLookup
|
|
940
|
+
// requires one, so nothing can be served through it — it only reports.
|
|
941
|
+
// Bare routes never see it (an installed marker would otherwise mint an
|
|
942
|
+
// implicit scope over the REAL doc: partition in
|
|
943
|
+
// resolveShellImplicitCacheScope).
|
|
944
|
+
if (routeCacheScope?.enabled) {
|
|
945
|
+
let explicitCacheHit = false;
|
|
946
|
+
let explicitCacheBypass = false;
|
|
947
|
+
const previousImplicitCache = reqCtx._shellImplicitCache;
|
|
948
|
+
reqCtx._shellImplicitCache = {
|
|
949
|
+
onExplicitHit: () => {
|
|
950
|
+
explicitCacheHit = true;
|
|
951
|
+
},
|
|
952
|
+
onExplicitBypass: () => {
|
|
953
|
+
explicitCacheBypass = true;
|
|
954
|
+
},
|
|
955
|
+
};
|
|
956
|
+
try {
|
|
957
|
+
const result = await ctx.router.matchPartial(request, { env });
|
|
958
|
+
const provisionalStatus: PprReplayStatus = explicitCacheBypass
|
|
959
|
+
? { outcome: "BYPASS", reason: "cache-disabled" }
|
|
960
|
+
: explicitCacheHit
|
|
961
|
+
? { outcome: "BYPASS", reason: "explicit-cache-hit" }
|
|
962
|
+
: { outcome: "BYPASS", reason: bypassReason ?? "no-entry" };
|
|
963
|
+
const status = finalizeReplayStatus(provisionalStatus);
|
|
964
|
+
return {
|
|
965
|
+
result,
|
|
966
|
+
status,
|
|
967
|
+
// A lookup-time opt-out makes every heal snapshot unusable
|
|
968
|
+
// (recordShellCaptureDocRecord refuses under the same predicate),
|
|
969
|
+
// and a prerender-served or intercept match never consults a heal
|
|
970
|
+
// snapshot at all. Otherwise heal the shouldHealReplayMiss set PLUS
|
|
971
|
+
// `no-segment-snapshot`: an entry captured while condition() was
|
|
972
|
+
// false legitimately lacks a snapshot, and a later request whose
|
|
973
|
+
// lookup did NOT refuse (condition true now) can heal it — the
|
|
974
|
+
// capture derives from THIS request's context, so its doc record
|
|
975
|
+
// records. Excluding it left replay dead until the document
|
|
976
|
+
// recaptured. The always-false route stays protected: its every
|
|
977
|
+
// lookup refuses, so explicitCacheBypass suppresses the heal.
|
|
978
|
+
captureNeeded:
|
|
979
|
+
!explicitCacheBypass &&
|
|
980
|
+
reqCtx._pprReplayPostMatchReason === undefined &&
|
|
981
|
+
(shouldHealReplayMiss(bypassReason) ||
|
|
982
|
+
bypassReason === "no-segment-snapshot"),
|
|
983
|
+
};
|
|
984
|
+
} finally {
|
|
985
|
+
reqCtx._shellImplicitCache = previousImplicitCache;
|
|
986
|
+
}
|
|
987
|
+
}
|
|
814
988
|
const match = await runMatch({
|
|
815
989
|
outcome: "BYPASS",
|
|
816
990
|
reason: bypassReason ?? "no-entry",
|
|
817
991
|
});
|
|
818
|
-
return {
|
|
992
|
+
return {
|
|
993
|
+
...match,
|
|
994
|
+
captureNeeded:
|
|
995
|
+
reqCtx._pprReplayPostMatchReason === undefined &&
|
|
996
|
+
shouldHealReplayMiss(bypassReason),
|
|
997
|
+
};
|
|
819
998
|
}
|
|
820
999
|
|
|
821
1000
|
const previousImplicitCache = reqCtx._shellImplicitCache;
|
|
822
1001
|
let segmentReplayHit = false;
|
|
1002
|
+
let explicitCacheHit = false;
|
|
1003
|
+
let explicitCacheBypass = false;
|
|
823
1004
|
reqCtx._shellImplicitCache = {
|
|
824
1005
|
ttl: pprConfig.ttl,
|
|
825
1006
|
swr: pprConfig.swr,
|
|
@@ -830,20 +1011,64 @@ async function matchPartialWithPprReplay<TEnv>(
|
|
|
830
1011
|
onHit: () => {
|
|
831
1012
|
segmentReplayHit = true;
|
|
832
1013
|
},
|
|
1014
|
+
// Arms the explicit-scope composition in withCacheLookup: a route-derived
|
|
1015
|
+
// cache() scope stays authoritative, the seeded doc record supplies the
|
|
1016
|
+
// match only on its miss. An explicit-tier hit must NOT report a replay
|
|
1017
|
+
// HIT — it served under the consumer's own semantics.
|
|
1018
|
+
onExplicitHit: () => {
|
|
1019
|
+
explicitCacheHit = true;
|
|
1020
|
+
},
|
|
1021
|
+
// Lookup-time condition() refusal (or a scope with no store): the gate
|
|
1022
|
+
// deliberately does not pre-decide predicates, so the truthful
|
|
1023
|
+
// cache-disabled report comes from the lookup that actually refused.
|
|
1024
|
+
onExplicitBypass: () => {
|
|
1025
|
+
explicitCacheBypass = true;
|
|
1026
|
+
},
|
|
833
1027
|
};
|
|
834
1028
|
|
|
835
1029
|
try {
|
|
836
1030
|
const result = await ctx.router.matchPartial(request, { env });
|
|
837
|
-
const
|
|
1031
|
+
const provisionalStatus: PprReplayStatus = segmentReplayHit
|
|
838
1032
|
? { outcome: "HIT", freshness }
|
|
839
|
-
:
|
|
840
|
-
|
|
1033
|
+
: explicitCacheHit
|
|
1034
|
+
? { outcome: "BYPASS", reason: "explicit-cache-hit" }
|
|
1035
|
+
: explicitCacheBypass
|
|
1036
|
+
? { outcome: "BYPASS", reason: "cache-disabled" }
|
|
1037
|
+
: { outcome: "BYPASS", reason: "snapshot-miss" };
|
|
1038
|
+
// A prerender serve or intercept resolution leaves the seeded record
|
|
1039
|
+
// unconsulted (prerender short-circuits before the scope; intercepts
|
|
1040
|
+
// keep snapshot.cacheScope) — the "snapshot-miss" guess would blame the
|
|
1041
|
+
// capture for a lane that was never in play.
|
|
1042
|
+
const status = finalizeReplayStatus(provisionalStatus);
|
|
841
1043
|
return { result, status };
|
|
842
1044
|
} finally {
|
|
843
1045
|
reqCtx._shellImplicitCache = previousImplicitCache;
|
|
844
1046
|
}
|
|
845
1047
|
}
|
|
846
1048
|
|
|
1049
|
+
/**
|
|
1050
|
+
* The full route snapshot for the classified route, or null when
|
|
1051
|
+
* classification is unavailable (the gates then fall open to the ordinary
|
|
1052
|
+
* replay decision). Persists the enriched snapshot back onto
|
|
1053
|
+
* `_classifiedRoute` so the manifest-chain walk runs once per request:
|
|
1054
|
+
* matchPartial's createMatchContextForPartial re-reads `_classifiedRoute` and
|
|
1055
|
+
* calls ensureFullRouteSnapshot again, and the write-back lets that call hit
|
|
1056
|
+
* the entries-already-built fast path and reuse this same scope chain instead
|
|
1057
|
+
* of rebuilding it.
|
|
1058
|
+
*/
|
|
1059
|
+
function classifiedRouteSnapshot(
|
|
1060
|
+
reqCtx: RequestContext<any>,
|
|
1061
|
+
): RouteSnapshot<any> | null {
|
|
1062
|
+
const classified = reqCtx._classifiedRoute;
|
|
1063
|
+
if (!classified?.manifestEntry) return null;
|
|
1064
|
+
const full = ensureFullRouteSnapshot({
|
|
1065
|
+
...classified,
|
|
1066
|
+
entries: classified.entries ?? [],
|
|
1067
|
+
});
|
|
1068
|
+
reqCtx._classifiedRoute = full;
|
|
1069
|
+
return full;
|
|
1070
|
+
}
|
|
1071
|
+
|
|
847
1072
|
/**
|
|
848
1073
|
* Neutralize the shell-HIT degradation redirect target. The inline
|
|
849
1074
|
* `location.replace` in a committed 200 body bypasses the 3xx chokepoint
|