@rangojs/router 0.5.1 → 0.6.0
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 +5 -1
- package/dist/bin/rango.js +343 -125
- package/dist/types/browser/event-controller.d.ts +6 -0
- package/dist/types/browser/react/use-router.d.ts +10 -3
- package/dist/types/browser/react/use-search-params.d.ts +57 -10
- package/dist/types/browser/types.d.ts +22 -0
- package/dist/types/build/merge-full-manifests.d.ts +3 -0
- package/dist/types/build/route-trie.d.ts +4 -73
- package/dist/types/build/route-types/per-module-writer.d.ts +6 -4
- package/dist/types/build/route-types/router-processing.d.ts +2 -3
- package/dist/types/cache/cache-exec-scope.d.ts +31 -0
- package/dist/types/cache/cf/cf-cache-constants.d.ts +8 -1
- package/dist/types/cache/cf/cf-cache-store.d.ts +15 -1
- package/dist/types/cache/cf/cf-cache-types.d.ts +1 -1
- package/dist/types/cache/cf/cf-kv-utils.d.ts +21 -0
- package/dist/types/cache/taint.d.ts +12 -6
- package/dist/types/client-urls/client-root.d.ts +38 -0
- package/dist/types/client-urls/client-urls.d.ts +5 -0
- package/dist/types/client-urls/navigation.d.ts +38 -0
- package/dist/types/client-urls/revalidation-protocol.d.ts +25 -0
- package/dist/types/client-urls/server-projection.d.ts +62 -0
- package/dist/types/client-urls/types.d.ts +144 -0
- package/dist/types/client.d.ts +12 -4
- package/dist/types/client.rsc.d.ts +4 -1
- package/dist/types/decode-loader-results.d.ts +37 -0
- package/dist/types/errors.d.ts +1 -0
- package/dist/types/handles/is-thenable.d.ts +2 -4
- package/dist/types/index.d.ts +1 -1
- package/dist/types/loader-redirect.d.ts +27 -0
- package/dist/types/outlet-context.d.ts +12 -0
- package/dist/types/outlet-provider.d.ts +3 -1
- package/dist/types/redirect-origin.d.ts +4 -0
- package/dist/types/route-content-wrapper.d.ts +42 -1
- package/dist/types/route-definition/helpers-types.d.ts +13 -2
- package/dist/types/router/error-handling.d.ts +35 -1
- package/dist/types/router/intercept-resolution.d.ts +12 -0
- package/dist/types/router/loader-resolution.d.ts +24 -2
- package/dist/types/router/revalidation.d.ts +7 -0
- package/dist/{types.backup/build/route-trie.d.ts → types/router/route-trie-builder.d.ts} +4 -16
- package/dist/types/router/router-interfaces.d.ts +20 -0
- package/dist/types/router/segment-resolution/helpers.d.ts +1 -1
- package/dist/types/router/trie-matching.d.ts +1 -1
- package/dist/types/rsc/helpers.d.ts +3 -0
- package/dist/types/rsc/manifest-init.d.ts +5 -5
- package/dist/types/rsc/render-pipeline.d.ts +9 -0
- package/dist/types/rsc/routine-plan.d.ts +124 -0
- package/dist/types/rsc/shell-capture-constants.d.ts +17 -0
- package/dist/types/rsc/shell-capture.d.ts +9 -0
- package/dist/types/rsc/shell-serve.d.ts +11 -0
- package/dist/types/rsc/types.d.ts +30 -0
- package/dist/types/segment-system.d.ts +2 -0
- package/dist/types/server/context.d.ts +10 -0
- package/dist/types/server/handle-store.d.ts +34 -3
- package/dist/types/server/request-context.d.ts +14 -1
- package/dist/types/server.d.ts +1 -0
- package/dist/types/ssr/index.d.ts +22 -0
- package/dist/types/ssr/ssr-root.d.ts +10 -0
- package/dist/types/testing/dom.entry.d.ts +1 -1
- package/dist/types/testing/render-route.d.ts +16 -6
- package/dist/types/testing/run-loader.d.ts +9 -0
- package/dist/types/types/boundaries.d.ts +22 -0
- package/dist/types/types/index.d.ts +1 -1
- package/dist/types/types/loader-types.d.ts +57 -5
- package/dist/types/types/segments.d.ts +7 -0
- package/dist/types/urls/path-helper-types.d.ts +10 -4
- package/dist/types/vite/discovery/client-urls-projection.d.ts +53 -0
- package/dist/types/vite/discovery/discover-routers.d.ts +1 -1
- package/dist/types/vite/discovery/state.d.ts +8 -1
- package/dist/types/vite/encryption-key.d.ts +2 -0
- package/dist/types/vite/plugins/expose-internal-ids.d.ts +10 -0
- package/dist/types/vite/plugins/server-ref-hashing.d.ts +24 -0
- package/dist/types/vite/plugins/server-reference-pattern.d.ts +1 -0
- package/dist/types/vite/utils/shared-utils.d.ts +12 -0
- package/dist/vite/index.js +5101 -2056
- package/package.json +3 -3
- package/skills/breadcrumbs/SKILL.md +39 -9
- package/skills/caching/SKILL.md +1 -1
- package/skills/catalog.json +7 -1
- package/skills/client-urls/SKILL.md +338 -0
- package/skills/comparison/references/framework-comparison.md +23 -9
- package/skills/hooks/SKILL.md +2 -2
- package/skills/hooks/data.md +11 -2
- package/skills/hooks/handle-and-actions.md +7 -0
- package/skills/hooks/outlets.md +26 -5
- package/skills/hooks/urls.md +40 -3
- package/skills/loader/SKILL.md +132 -20
- package/skills/migrate-nextjs/SKILL.md +70 -10
- package/skills/migrate-react-router/SKILL.md +49 -13
- package/skills/migrate-react-router/component-migration.md +18 -13
- package/skills/migrate-react-router/data-and-actions.md +14 -3
- package/skills/migrate-react-router/route-mapping.md +15 -2
- package/skills/mime-routes/SKILL.md +3 -1
- package/skills/parallel/SKILL.md +32 -1
- package/skills/ppr/SKILL.md +16 -6
- package/skills/prerender/SKILL.md +8 -4
- package/skills/rango/SKILL.md +21 -17
- package/skills/react-compiler/SKILL.md +3 -3
- package/skills/response-routes/SKILL.md +4 -2
- package/skills/route/SKILL.md +5 -2
- package/skills/router-setup/SKILL.md +16 -2
- package/skills/scripts/SKILL.md +16 -6
- package/skills/shell-manifest/SKILL.md +16 -7
- package/skills/testing/SKILL.md +2 -2
- package/skills/testing/client-components.md +6 -0
- package/skills/testing/handles.md +30 -8
- package/skills/testing/loader.md +51 -49
- package/skills/testing/middleware.md +1 -1
- package/skills/theme/SKILL.md +8 -5
- package/skills/typesafety/generated-files-and-cli.md +16 -9
- package/skills/typesafety/route-types.md +5 -1
- package/skills/use-cache/SKILL.md +47 -0
- package/src/bin/rango.ts +7 -3
- package/src/browser/event-controller.ts +40 -15
- package/src/browser/navigation-bridge.ts +6 -0
- package/src/browser/navigation-client.ts +5 -0
- package/src/browser/partial-update.ts +77 -10
- package/src/browser/react/NavigationProvider.tsx +7 -0
- package/src/browser/react/use-router.ts +40 -11
- package/src/browser/react/use-search-params.ts +140 -17
- package/src/browser/rsc-router.tsx +59 -0
- package/src/browser/server-action-bridge.ts +26 -0
- package/src/browser/types.ts +22 -0
- package/src/build/merge-full-manifests.ts +161 -0
- package/src/build/route-trie.ts +9 -332
- package/src/build/route-types/include-resolution.ts +66 -11
- package/src/build/route-types/per-module-writer.ts +11 -6
- package/src/build/route-types/router-processing.ts +184 -153
- package/src/build/runtime-discovery.ts +23 -12
- package/src/cache/cache-exec-scope.ts +47 -0
- package/src/cache/cache-runtime.ts +113 -40
- package/src/cache/cf/cf-cache-constants.ts +8 -1
- package/src/cache/cf/cf-cache-store.ts +41 -64
- package/src/cache/cf/cf-cache-types.ts +1 -1
- package/src/cache/cf/cf-kv-utils.ts +38 -0
- package/src/cache/segment-codec.ts +21 -5
- package/src/cache/taint.ts +28 -9
- package/src/client-urls/client-root.tsx +168 -0
- package/src/client-urls/client-urls.ts +698 -0
- package/src/client-urls/navigation.ts +237 -0
- package/src/client-urls/revalidation-protocol.ts +56 -0
- package/src/client-urls/server-projection.ts +579 -0
- package/src/client-urls/types.ts +195 -0
- package/src/client.rsc.tsx +12 -0
- package/src/client.tsx +49 -6
- package/src/decode-loader-results.ts +113 -0
- package/src/errors.ts +14 -0
- package/src/handles/deferred-resolution.ts +14 -7
- package/src/handles/is-thenable.ts +2 -4
- package/src/index.ts +1 -0
- package/src/loader-redirect.tsx +64 -0
- package/src/outlet-context.ts +12 -0
- package/src/outlet-provider.tsx +15 -1
- package/src/redirect-origin.ts +29 -0
- package/src/route-content-wrapper.tsx +96 -3
- package/src/route-definition/dsl-helpers.ts +28 -3
- package/src/route-definition/helpers-types.ts +13 -0
- package/src/route-definition/redirect.ts +17 -18
- package/src/router/error-handling.ts +65 -11
- package/src/router/intercept-resolution.ts +29 -0
- package/src/router/loader-resolution.ts +261 -28
- package/src/router/match-middleware/cache-lookup.ts +24 -15
- package/src/router/match-result.ts +7 -0
- package/src/router/revalidation.ts +24 -11
- package/src/router/route-trie-builder.ts +334 -0
- package/src/router/router-interfaces.ts +38 -0
- package/src/router/segment-resolution/fresh.ts +47 -0
- package/src/router/segment-resolution/helpers.ts +9 -11
- package/src/router/segment-resolution/loader-cache.ts +14 -24
- package/src/router/segment-resolution/revalidation.ts +20 -1
- package/src/router/trie-matching.ts +3 -3
- package/src/router.ts +46 -1
- package/src/rsc/full-payload.ts +6 -0
- package/src/rsc/handler.ts +36 -12
- package/src/rsc/helpers.ts +13 -0
- package/src/rsc/loader-fetch.ts +2 -2
- package/src/rsc/manifest-init.ts +28 -9
- package/src/rsc/progressive-enhancement.ts +247 -70
- package/src/rsc/render-pipeline.ts +68 -24
- package/src/rsc/routine-plan.ts +359 -0
- package/src/rsc/rsc-rendering.ts +569 -302
- package/src/rsc/server-action.ts +180 -71
- package/src/rsc/shell-capture-constants.ts +18 -0
- package/src/rsc/shell-capture.ts +104 -21
- package/src/rsc/shell-serve.ts +15 -2
- package/src/rsc/ssr-setup.ts +10 -1
- package/src/rsc/types.ts +31 -2
- package/src/segment-system.tsx +83 -26
- package/src/server/context.ts +10 -0
- package/src/server/cookie-store.ts +19 -19
- package/src/server/handle-store.ts +185 -48
- package/src/server/request-context.ts +36 -6
- package/src/server.ts +7 -0
- package/src/ssr/index.tsx +37 -2
- package/src/ssr/ssr-root.tsx +30 -2
- package/src/testing/dom.entry.ts +1 -1
- package/src/testing/render-route.tsx +22 -8
- package/src/testing/run-loader.ts +51 -13
- package/src/types/boundaries.ts +19 -0
- package/src/types/index.ts +1 -0
- package/src/types/loader-types.ts +60 -5
- package/src/types/segments.ts +7 -0
- package/src/urls/include-helper.ts +22 -4
- package/src/urls/path-helper-types.ts +14 -1
- package/src/use-loader.tsx +67 -6
- package/src/vite/discovery/client-urls-projection.ts +322 -0
- package/src/vite/discovery/discover-routers.ts +43 -17
- package/src/vite/discovery/state.ts +11 -1
- package/src/vite/discovery/virtual-module-codegen.ts +20 -0
- package/src/vite/encryption-key.ts +29 -0
- package/src/vite/plugins/expose-action-id.ts +2 -2
- package/src/vite/plugins/expose-internal-ids.ts +46 -0
- package/src/vite/plugins/server-ref-hashing.ts +74 -0
- package/src/vite/plugins/server-reference-pattern.ts +10 -0
- package/src/vite/plugins/virtual-entries.ts +12 -3
- package/src/vite/rango.ts +9 -0
- package/src/vite/router-discovery.ts +184 -14
- package/src/vite/utils/shared-utils.ts +12 -7
- 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-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
package/src/rsc/rsc-rendering.ts
CHANGED
|
@@ -27,8 +27,21 @@ import {
|
|
|
27
27
|
createResponseWithMergedHeaders,
|
|
28
28
|
createSimpleRedirectResponse,
|
|
29
29
|
attachLocationStateIfPresent,
|
|
30
|
+
matchAndRecordParams,
|
|
30
31
|
} from "./helpers.js";
|
|
31
|
-
import {
|
|
32
|
+
import {
|
|
33
|
+
createRenderStageTraceBridge,
|
|
34
|
+
renderRscFlightStage,
|
|
35
|
+
renderRscResponse,
|
|
36
|
+
} from "./render-pipeline.js";
|
|
37
|
+
import {
|
|
38
|
+
createRoutineTrace,
|
|
39
|
+
handoff,
|
|
40
|
+
runRoutine,
|
|
41
|
+
scope,
|
|
42
|
+
step,
|
|
43
|
+
type RoutinePlan,
|
|
44
|
+
} from "./routine-plan.js";
|
|
32
45
|
import type { HandlerContext } from "./handler-context.js";
|
|
33
46
|
import { gateTransitions } from "./transition-gate.js";
|
|
34
47
|
import { buildFullPayload } from "./full-payload.js";
|
|
@@ -44,6 +57,7 @@ import {
|
|
|
44
57
|
SHELL_STATUS_HEADER,
|
|
45
58
|
resolvePprConfig,
|
|
46
59
|
buildShellKey,
|
|
60
|
+
shellSearchSeed,
|
|
47
61
|
isValidShellHit,
|
|
48
62
|
hasIntactShellPayload,
|
|
49
63
|
base64ToBytes,
|
|
@@ -140,12 +154,14 @@ function buildNavigationShellKey(
|
|
|
140
154
|
function createShellCaptureDescriptor(
|
|
141
155
|
ctx: HandlerContext<any>,
|
|
142
156
|
key: string,
|
|
157
|
+
searchSeed: string,
|
|
143
158
|
pprConfig: ResolvedPprConfig,
|
|
144
159
|
store: SegmentCacheStore<any>,
|
|
145
160
|
navigationOnly?: true,
|
|
146
161
|
): ShellCaptureDescriptor {
|
|
147
162
|
return {
|
|
148
163
|
key,
|
|
164
|
+
searchSeed,
|
|
149
165
|
buildVersion: ctx.version,
|
|
150
166
|
ttl: pprConfig.ttl,
|
|
151
167
|
swr: pprConfig.swr,
|
|
@@ -281,6 +297,34 @@ export function handleRscRendering<TEnv>(
|
|
|
281
297
|
);
|
|
282
298
|
}
|
|
283
299
|
|
|
300
|
+
interface RequestRenderInput<TEnv> {
|
|
301
|
+
ctx: HandlerContext<TEnv>;
|
|
302
|
+
request: Request;
|
|
303
|
+
env: TEnv;
|
|
304
|
+
url: URL;
|
|
305
|
+
isPartial: boolean;
|
|
306
|
+
handleStore: ReturnType<typeof getRequestContext>["_handleStore"];
|
|
307
|
+
nonce: string | undefined;
|
|
308
|
+
renderSpan: TraceSpan;
|
|
309
|
+
reqCtx: ReturnType<typeof getRequestContext>;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
type ShellServeOutcome =
|
|
313
|
+
| { kind: "serve"; response: Response }
|
|
314
|
+
| { kind: "miss"; descriptor: ShellCaptureDescriptor; ssrModule: SSRModule }
|
|
315
|
+
| { kind: "pass" };
|
|
316
|
+
|
|
317
|
+
type PreparedRender =
|
|
318
|
+
| { kind: "control"; response: Response }
|
|
319
|
+
| {
|
|
320
|
+
kind: "payload";
|
|
321
|
+
payload: RscPayload;
|
|
322
|
+
hasInterceptSlots: boolean;
|
|
323
|
+
pprReplayStatus?: PprReplayStatus;
|
|
324
|
+
partialCaptureNeeded: boolean;
|
|
325
|
+
partialCaptureKey?: string;
|
|
326
|
+
};
|
|
327
|
+
|
|
284
328
|
async function handleRscRenderingInner<TEnv>(
|
|
285
329
|
ctx: HandlerContext<TEnv>,
|
|
286
330
|
request: Request,
|
|
@@ -291,13 +335,49 @@ async function handleRscRenderingInner<TEnv>(
|
|
|
291
335
|
nonce: string | undefined,
|
|
292
336
|
renderSpan: TraceSpan,
|
|
293
337
|
): Promise<Response> {
|
|
338
|
+
// Flow trace rides the internal debug surface (INTERNAL_RANGO_DEBUG=1): the
|
|
339
|
+
// Vite pipeline bakes the flag at build/dev-server start (inject-client-debug),
|
|
340
|
+
// so trace allocation and output fold out of ordinary production builds while
|
|
341
|
+
// an explicit debug build keeps them. The routine itself remains the executor.
|
|
342
|
+
const mode = isPartial ? "partial" : "document";
|
|
343
|
+
const trace = INTERNAL_RANGO_DEBUG ? createRoutineTrace(mode) : undefined;
|
|
294
344
|
const reqCtx = getRequestContext();
|
|
345
|
+
const input: RequestRenderInput<TEnv> = {
|
|
346
|
+
ctx,
|
|
347
|
+
request,
|
|
348
|
+
env,
|
|
349
|
+
url,
|
|
350
|
+
isPartial,
|
|
351
|
+
handleStore,
|
|
352
|
+
nonce,
|
|
353
|
+
renderSpan,
|
|
354
|
+
reqCtx,
|
|
355
|
+
};
|
|
356
|
+
try {
|
|
357
|
+
return await runRoutine(requestRenderPlan(input), {
|
|
358
|
+
trace,
|
|
359
|
+
owner: reqCtx,
|
|
360
|
+
});
|
|
361
|
+
} finally {
|
|
362
|
+
if (trace) {
|
|
363
|
+
console.log(
|
|
364
|
+
`[routine] ${request.method} ${url.pathname} (${trace.name})\n${trace.format()}`,
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
295
369
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
370
|
+
/**
|
|
371
|
+
* The request-level render plan. Reads top to bottom as the request executes:
|
|
372
|
+
* serve a stored PPR shell if one commits, otherwise match and build the
|
|
373
|
+
* payload, render it through the stage driver, then hand off background
|
|
374
|
+
* captures. Effects run through the routine runner (yield-before-execute,
|
|
375
|
+
* exact result/error identity — see routine-plan.ts).
|
|
376
|
+
*/
|
|
377
|
+
function* requestRenderPlan<TEnv>(
|
|
378
|
+
input: RequestRenderInput<TEnv>,
|
|
379
|
+
): RoutinePlan<Response> {
|
|
380
|
+
const { isPartial, reqCtx } = input;
|
|
301
381
|
|
|
302
382
|
// --- Axis 2: integrated PPR shell serve (docs/design/ppr-shell-resume.md) ---
|
|
303
383
|
//
|
|
@@ -305,214 +385,278 @@ async function handleRscRenderingInner<TEnv>(
|
|
|
305
385
|
// chain (executeRender wraps it), so no shell byte can precede a guard
|
|
306
386
|
// decision — that ordering is what makes a shared shell safe. Routes
|
|
307
387
|
// without the `ppr` option stay pure axis 1 at zero cost.
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
388
|
+
const shell = yield* scope("shell-serve", shellServePlan(input));
|
|
389
|
+
if (shell.kind === "serve") return shell.response;
|
|
390
|
+
|
|
391
|
+
// Match + payload. A control response (redirect, prerender collection)
|
|
392
|
+
// ends the plan before any rendering.
|
|
393
|
+
const prepared = yield* scope(
|
|
394
|
+
isPartial ? "prepare:partial" : "prepare:full",
|
|
395
|
+
preparePayloadPlan(input),
|
|
396
|
+
);
|
|
397
|
+
if (prepared.kind === "control") return prepared.response;
|
|
398
|
+
|
|
399
|
+
// For partial requests, include any server-set location state in the payload.
|
|
400
|
+
// SSR (full page) requests ignore location state since there's no history.state
|
|
401
|
+
// to write to on a fresh page load.
|
|
402
|
+
if (isPartial && prepared.payload.metadata) {
|
|
403
|
+
attachLocationStateIfPresent(prepared.payload);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
const response = yield* step("render", () =>
|
|
407
|
+
renderPreparedRscResponse(input, prepared),
|
|
408
|
+
);
|
|
409
|
+
|
|
410
|
+
// --- Axis 2: PPR shell CAPTURE on MISS (background task; see design doc) ---
|
|
411
|
+
// Capture only a 200 HTML document (a 404/error render is not a cacheable
|
|
412
|
+
// shell). Capture does not flow through the HTTP pipeline — middleware never
|
|
413
|
+
// re-runs (it already ran for this request; guarding is serve-time).
|
|
414
|
+
// reqCtx._dynamic is re-read here on purpose: a loader may have marked the
|
|
415
|
+
// request dynamic while rendering.
|
|
416
|
+
if (shell.kind === "miss" && !reqCtx._dynamic) {
|
|
417
|
+
if (
|
|
418
|
+
response.status === 200 &&
|
|
419
|
+
(response.headers.get("content-type") ?? "").includes("text/html")
|
|
420
|
+
) {
|
|
421
|
+
const { descriptor, ssrModule } = shell;
|
|
422
|
+
yield* handoff("shell-capture", () =>
|
|
423
|
+
scheduleShellCapture(
|
|
424
|
+
input.ctx,
|
|
425
|
+
input.request,
|
|
426
|
+
input.env,
|
|
427
|
+
input.url,
|
|
428
|
+
reqCtx,
|
|
429
|
+
ssrModule,
|
|
430
|
+
descriptor,
|
|
431
|
+
),
|
|
432
|
+
);
|
|
433
|
+
}
|
|
434
|
+
response.headers.set(SHELL_STATUS_HEADER, "MISS");
|
|
435
|
+
}
|
|
436
|
+
|
|
312
437
|
if (
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
!
|
|
316
|
-
|
|
317
|
-
!reqCtx._dynamic
|
|
438
|
+
isPartial &&
|
|
439
|
+
prepared.partialCaptureNeeded &&
|
|
440
|
+
!reqCtx._dynamic &&
|
|
441
|
+
response.status === 200
|
|
318
442
|
) {
|
|
319
|
-
const
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
443
|
+
const captureKey = prepared.partialCaptureKey;
|
|
444
|
+
yield* handoff("navigation-shell-capture", () =>
|
|
445
|
+
scheduleNavigationShellCapture(input, captureKey),
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
return response;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* Axis 2 shell serve. Sync gates stay plan code; store and SSR effects run as
|
|
454
|
+
* named steps. Outcomes: serve a composed shell response, report a MISS (the
|
|
455
|
+
* top-level plan schedules the capture after the response commits), or pass
|
|
456
|
+
* (route not eligible — pure axis 1).
|
|
457
|
+
*/
|
|
458
|
+
function* shellServePlan<TEnv>(
|
|
459
|
+
input: RequestRenderInput<TEnv>,
|
|
460
|
+
): RoutinePlan<ShellServeOutcome> {
|
|
461
|
+
const { ctx, request, env, url, isPartial, handleStore, nonce, reqCtx } =
|
|
462
|
+
input;
|
|
463
|
+
|
|
464
|
+
if (
|
|
465
|
+
isPartial ||
|
|
466
|
+
request.method !== "GET" ||
|
|
467
|
+
url.searchParams.has("__prerender_collect") ||
|
|
468
|
+
isRscRequest(request, url, false) ||
|
|
469
|
+
reqCtx._dynamic
|
|
470
|
+
) {
|
|
471
|
+
return { kind: "pass" };
|
|
472
|
+
}
|
|
473
|
+
const pprConfig = resolvePprConfig(reqCtx._classifiedRoute?.manifestEntry);
|
|
474
|
+
if (!pprConfig) return { kind: "pass" };
|
|
475
|
+
|
|
476
|
+
// A per-request CSP nonce pins the route to axis 1: a shared shell would
|
|
477
|
+
// freeze the capture request's nonce and CSP would reject it for every
|
|
478
|
+
// other visitor. BOTH nonce sources must gate — the createRouter({ nonce })
|
|
479
|
+
// provider (`nonce` param) and a middleware ctx.set(nonce, …) token write;
|
|
480
|
+
// the provider-only check missed the latter (issue #656).
|
|
481
|
+
const activeNonce = nonce ?? contextGet(reqCtx._variables, nonceToken);
|
|
482
|
+
const store = reqCtx._cacheStore;
|
|
483
|
+
const key = buildShellKey(url, reqCtx._searchParamsFilter);
|
|
484
|
+
mirrorPprServerTimingsForDev(key, reqCtx);
|
|
485
|
+
if (activeNonce !== undefined) {
|
|
486
|
+
// Declared intent that cannot be honored deserves a diagnostic (unlike an
|
|
487
|
+
// undeclared route, which is silent): a ppr route gated off by an active
|
|
488
|
+
// per-request nonce warns once per key. Axis 1 after the warning.
|
|
489
|
+
warnPprNonceActiveOnce(key);
|
|
490
|
+
return { kind: "pass" };
|
|
491
|
+
}
|
|
492
|
+
if (!hasShellFamily(store)) {
|
|
493
|
+
// Declared intent that cannot be honored deserves a diagnostic (unlike an
|
|
494
|
+
// undeclared route, which is silent). Axis 1 after the warning.
|
|
495
|
+
warnShellStoreMissingOnce(key);
|
|
496
|
+
return { kind: "pass" };
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
// SSR setup starts before route handling, so read the shell before joining it
|
|
500
|
+
// to overlap the remaining setup work with cache I/O.
|
|
501
|
+
const cached = yield* step("shell-read", () =>
|
|
502
|
+
readShellEntry(store, key, reqCtx),
|
|
503
|
+
);
|
|
504
|
+
|
|
505
|
+
// allReady (ssr.resolveStreaming) bypasses PPR entirely: buffering defeats
|
|
506
|
+
// streaming, so bots/SEO crawlers get one complete axis-1 document. These
|
|
507
|
+
// routes pay one unnecessary shell read to keep the PPR hot path concurrent.
|
|
508
|
+
const [ssrModule, streamMode] = yield* step("ssr-setup", () =>
|
|
509
|
+
getSSRSetup(ctx, request, env, url, reqCtx._metricsStore),
|
|
510
|
+
);
|
|
511
|
+
if (
|
|
512
|
+
streamMode === "allReady" ||
|
|
513
|
+
!ssrModule.resumeShellHTML ||
|
|
514
|
+
!ssrModule.captureShellHTML
|
|
515
|
+
) {
|
|
516
|
+
return { kind: "pass" };
|
|
517
|
+
}
|
|
518
|
+
const descriptor = createShellCaptureDescriptor(
|
|
519
|
+
ctx,
|
|
520
|
+
key,
|
|
521
|
+
shellSearchSeed(url, reqCtx._searchParamsFilter),
|
|
522
|
+
pprConfig,
|
|
523
|
+
store,
|
|
524
|
+
);
|
|
525
|
+
|
|
526
|
+
if (
|
|
527
|
+
cached &&
|
|
528
|
+
!cached.entry.navigationOnly &&
|
|
529
|
+
isValidShellHit(cached.entry, ctx.version)
|
|
530
|
+
) {
|
|
531
|
+
if (!hasIntactShellPayload(cached.entry)) {
|
|
532
|
+
// Corrupt stored payload (undecodable prelude / unparseable
|
|
533
|
+
// postponed): a store-layer fault worth a diagnostic, unlike the
|
|
534
|
+
// silent version-mismatch lifecycle misses above. Degrade to MISS
|
|
535
|
+
// — the top-level plan schedules the recapture that overwrites it.
|
|
536
|
+
reportCacheError(
|
|
537
|
+
new Error(
|
|
538
|
+
`corrupt shell entry for "${key}": prelude/postponed failed ` +
|
|
539
|
+
"the integrity check; serving axis 1 and recapturing",
|
|
540
|
+
),
|
|
541
|
+
"cache-read",
|
|
542
|
+
"[ShellServe] getShell",
|
|
543
|
+
);
|
|
544
|
+
} else {
|
|
545
|
+
// Stale (SWR) hit: serve the stale shell now, recapture in the
|
|
546
|
+
// background (stampede-guarded + backoff inside scheduleShellCapture).
|
|
547
|
+
if (cached.shouldRevalidate) {
|
|
548
|
+
yield* handoff("shell-recapture", () =>
|
|
549
|
+
scheduleShellCapture(
|
|
550
|
+
ctx,
|
|
551
|
+
request,
|
|
552
|
+
env,
|
|
553
|
+
url,
|
|
554
|
+
reqCtx,
|
|
555
|
+
ssrModule,
|
|
556
|
+
descriptor,
|
|
557
|
+
),
|
|
558
|
+
);
|
|
362
559
|
}
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
// per-request nonce warns once per key. Axis 1 after the warning.
|
|
367
|
-
warnPprNonceActiveOnce(key);
|
|
368
|
-
} else if (!hasShellFamily(store)) {
|
|
369
|
-
// Declared intent that cannot be honored deserves a diagnostic (unlike an
|
|
370
|
-
// undeclared route, which is silent). Axis 1 after the warning.
|
|
371
|
-
warnShellStoreMissingOnce(key);
|
|
372
|
-
} else {
|
|
373
|
-
// allReady (ssr.resolveStreaming) bypasses PPR entirely: buffering defeats
|
|
374
|
-
// streaming, so bots/SEO crawlers get one complete axis-1 document.
|
|
375
|
-
const [ssrModule, streamMode] = await getSSRSetup(
|
|
560
|
+
const entry = cached.entry;
|
|
561
|
+
const response = yield* step("shell-hit", () =>
|
|
562
|
+
serveShellHit(
|
|
376
563
|
ctx,
|
|
377
564
|
request,
|
|
378
565
|
env,
|
|
379
566
|
url,
|
|
380
|
-
reqCtx
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
const shellReadStart = reqCtx._metricsStore ? performance.now() : 0;
|
|
425
|
-
try {
|
|
426
|
-
cached = await store.getShell(key);
|
|
427
|
-
} catch (error) {
|
|
428
|
-
// A failing store read degrades to axis 1 (MISS), never a 500.
|
|
429
|
-
reportCacheError(error, "cache-read", "[ShellServe] getShell");
|
|
430
|
-
}
|
|
431
|
-
if (reqCtx._metricsStore) {
|
|
432
|
-
// Raw store outcome (pre-validity-gates), so a version-mismatch
|
|
433
|
-
// lifecycle miss is still distinguishable from a store miss.
|
|
434
|
-
appendMetric(
|
|
435
|
-
reqCtx._metricsStore,
|
|
436
|
-
"ppr:shell-read",
|
|
437
|
-
shellReadStart,
|
|
438
|
-
performance.now() - shellReadStart,
|
|
439
|
-
undefined,
|
|
440
|
-
cached ? "hit" : "miss",
|
|
441
|
-
);
|
|
442
|
-
}
|
|
443
|
-
if (
|
|
444
|
-
cached &&
|
|
445
|
-
!cached.entry.navigationOnly &&
|
|
446
|
-
isValidShellHit(cached.entry, ctx.version)
|
|
447
|
-
) {
|
|
448
|
-
if (!hasIntactShellPayload(cached.entry)) {
|
|
449
|
-
// Corrupt stored payload (undecodable prelude / unparseable
|
|
450
|
-
// postponed): a store-layer fault worth a diagnostic, unlike the
|
|
451
|
-
// silent version-mismatch lifecycle misses above. Degrade to MISS
|
|
452
|
-
// — pprMiss below schedules the recapture that overwrites it.
|
|
453
|
-
reportCacheError(
|
|
454
|
-
new Error(
|
|
455
|
-
`corrupt shell entry for "${key}": prelude/postponed failed ` +
|
|
456
|
-
"the integrity check; serving axis 1 and recapturing",
|
|
457
|
-
),
|
|
458
|
-
"cache-read",
|
|
459
|
-
"[ShellServe] getShell",
|
|
460
|
-
);
|
|
461
|
-
} else {
|
|
462
|
-
// Stale (SWR) hit: serve the stale shell now, recapture in the
|
|
463
|
-
// background (stampede-guarded + backoff inside scheduleShellCapture).
|
|
464
|
-
return serveHit(cached.entry, cached.shouldRevalidate);
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
// Build-time shell read-through (producer B, #699): on a runtime
|
|
468
|
-
// store MISS a Prerender+ppr route serves its `vite build`-baked
|
|
469
|
-
// shell through the SAME serveShellHit. lookupBuildShell owns every
|
|
470
|
-
// gate and fails to null (ordinary MISS path takes over); past
|
|
471
|
-
// ppr.ttl the baked entry still serves while SWR recaptures — the
|
|
472
|
-
// upgrade path from build entry to runtime entry.
|
|
473
|
-
const buildHit = await lookupBuildShell(
|
|
474
|
-
url,
|
|
475
|
-
ctx.version,
|
|
476
|
-
store,
|
|
477
|
-
// Dev: no build manifest exists; producer B runs on demand via
|
|
478
|
-
// the dev server's /__rsc_shell endpoint for PRERENDERED routes
|
|
479
|
-
// only (production's exact candidate set). Folded away in
|
|
480
|
-
// production builds (NODE_ENV is a compile-time constant).
|
|
481
|
-
resolveDevShellLookup(reqCtx, pprConfig),
|
|
482
|
-
reqCtx._searchParamsFilter,
|
|
483
|
-
);
|
|
484
|
-
if (buildHit) {
|
|
485
|
-
// Past ppr.ttl: still serve the baked entry, recapture upgrades it.
|
|
486
|
-
return serveHit(buildHit.entry, buildHit.stale);
|
|
487
|
-
}
|
|
488
|
-
// MISS (no entry, invalid reactVersion, or store read failure): axis 1
|
|
489
|
-
// + a background capture scheduled once the response is known servable.
|
|
490
|
-
pprMiss = { descriptor, ssrModule };
|
|
491
|
-
}
|
|
492
|
-
}
|
|
567
|
+
reqCtx,
|
|
568
|
+
handleStore,
|
|
569
|
+
ssrModule,
|
|
570
|
+
entry,
|
|
571
|
+
descriptor,
|
|
572
|
+
),
|
|
573
|
+
);
|
|
574
|
+
return { kind: "serve", response };
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
// Build-time shell read-through (producer B, #699): on a runtime
|
|
579
|
+
// store MISS a Prerender+ppr route serves its `vite build`-baked
|
|
580
|
+
// shell through the SAME serve path. lookupBuildShell owns every
|
|
581
|
+
// gate and fails to null (ordinary MISS path takes over); past
|
|
582
|
+
// ppr.ttl the baked entry still serves while SWR recaptures — the
|
|
583
|
+
// upgrade path from build entry to runtime entry.
|
|
584
|
+
const buildHit = yield* step("build-shell-lookup", () =>
|
|
585
|
+
lookupBuildShell(
|
|
586
|
+
url,
|
|
587
|
+
ctx.version,
|
|
588
|
+
store,
|
|
589
|
+
// Dev: no build manifest exists; producer B runs on demand via
|
|
590
|
+
// the dev server's /__rsc_shell endpoint for PRERENDERED routes
|
|
591
|
+
// only (production's exact candidate set). Folded away in
|
|
592
|
+
// production builds (NODE_ENV is a compile-time constant).
|
|
593
|
+
resolveDevShellLookup(reqCtx, pprConfig),
|
|
594
|
+
reqCtx._searchParamsFilter,
|
|
595
|
+
),
|
|
596
|
+
);
|
|
597
|
+
if (buildHit) {
|
|
598
|
+
// Past ppr.ttl: still serve the baked entry, recapture upgrades it.
|
|
599
|
+
if (buildHit.stale) {
|
|
600
|
+
yield* handoff("shell-recapture", () =>
|
|
601
|
+
scheduleShellCapture(
|
|
602
|
+
ctx,
|
|
603
|
+
request,
|
|
604
|
+
env,
|
|
605
|
+
url,
|
|
606
|
+
reqCtx,
|
|
607
|
+
ssrModule,
|
|
608
|
+
descriptor,
|
|
609
|
+
),
|
|
610
|
+
);
|
|
493
611
|
}
|
|
612
|
+
const response = yield* step("shell-hit", () =>
|
|
613
|
+
serveShellHit(
|
|
614
|
+
ctx,
|
|
615
|
+
request,
|
|
616
|
+
env,
|
|
617
|
+
url,
|
|
618
|
+
reqCtx,
|
|
619
|
+
handleStore,
|
|
620
|
+
ssrModule,
|
|
621
|
+
buildHit.entry,
|
|
622
|
+
descriptor,
|
|
623
|
+
),
|
|
624
|
+
);
|
|
625
|
+
return { kind: "serve", response };
|
|
494
626
|
}
|
|
495
627
|
|
|
628
|
+
// MISS (no entry, invalid reactVersion, or store read failure): axis 1
|
|
629
|
+
// + a background capture scheduled once the response is known servable.
|
|
630
|
+
return { kind: "miss", descriptor, ssrModule };
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
/**
|
|
634
|
+
* Match the request and assemble the RSC payload, or produce a control
|
|
635
|
+
* response (redirect, prerender collection) that ends the request plan.
|
|
636
|
+
*/
|
|
637
|
+
function* preparePayloadPlan<TEnv>(
|
|
638
|
+
input: RequestRenderInput<TEnv>,
|
|
639
|
+
): RoutinePlan<PreparedRender> {
|
|
640
|
+
const { ctx, request, env, url, isPartial, handleStore, nonce, reqCtx } =
|
|
641
|
+
input;
|
|
642
|
+
|
|
496
643
|
if (isPartial) {
|
|
497
644
|
// Partial render (navigation)
|
|
498
|
-
const replay =
|
|
499
|
-
ctx,
|
|
500
|
-
request,
|
|
501
|
-
env,
|
|
502
|
-
url,
|
|
503
|
-
reqCtx,
|
|
504
|
-
nonce,
|
|
645
|
+
const replay = yield* step("match:ppr-replay", () =>
|
|
646
|
+
matchPartialAndRecordParams(ctx, request, env, url, reqCtx, nonce),
|
|
505
647
|
);
|
|
506
648
|
const result = replay.result;
|
|
507
|
-
pprReplayStatus = replay.status;
|
|
508
|
-
partialCaptureNeeded =
|
|
649
|
+
const pprReplayStatus = replay.status;
|
|
650
|
+
const partialCaptureNeeded =
|
|
509
651
|
"captureNeeded" in replay && replay.captureNeeded === true;
|
|
510
|
-
partialCaptureKey =
|
|
652
|
+
const partialCaptureKey =
|
|
653
|
+
"captureKey" in replay ? replay.captureKey : undefined;
|
|
511
654
|
|
|
512
655
|
if (!result) {
|
|
513
656
|
// Fall back to full render
|
|
514
|
-
const match =
|
|
515
|
-
|
|
657
|
+
const match = yield* step("match:fallback", () =>
|
|
658
|
+
matchAndRecordParams(ctx, request, env),
|
|
659
|
+
);
|
|
516
660
|
|
|
517
661
|
if (match.redirect) {
|
|
518
662
|
// Partial request: use X-RSC-Redirect header so the client can
|
|
@@ -529,16 +673,22 @@ async function handleRscRenderingInner<TEnv>(
|
|
|
529
673
|
serializePprReplayStatus(pprReplayStatus),
|
|
530
674
|
);
|
|
531
675
|
}
|
|
532
|
-
return redirectResponse;
|
|
676
|
+
return { kind: "control", response: redirectResponse };
|
|
533
677
|
}
|
|
534
678
|
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
679
|
+
return {
|
|
680
|
+
kind: "payload",
|
|
681
|
+
payload: buildFullPayload(match, ctx, url, reqCtx, handleStore),
|
|
682
|
+
hasInterceptSlots: false,
|
|
683
|
+
pprReplayStatus,
|
|
684
|
+
partialCaptureNeeded,
|
|
685
|
+
partialCaptureKey,
|
|
686
|
+
};
|
|
687
|
+
}
|
|
540
688
|
|
|
541
|
-
|
|
689
|
+
return {
|
|
690
|
+
kind: "payload",
|
|
691
|
+
payload: {
|
|
542
692
|
metadata: {
|
|
543
693
|
pathname: url.pathname,
|
|
544
694
|
// routerId is serialized on every payload (including within-session
|
|
@@ -558,6 +708,7 @@ async function handleRscRenderingInner<TEnv>(
|
|
|
558
708
|
params: result.params,
|
|
559
709
|
isPartial: true,
|
|
560
710
|
slots: result.slots,
|
|
711
|
+
interceptTargets: result.interceptTargets,
|
|
561
712
|
handles: handleStore.stream(),
|
|
562
713
|
version: ctx.version,
|
|
563
714
|
prefetchCacheTTL: ctx.router.prefetchCacheTTL,
|
|
@@ -566,62 +717,191 @@ async function handleRscRenderingInner<TEnv>(
|
|
|
566
717
|
defaultPrefetch: ctx.router.defaultPrefetch,
|
|
567
718
|
stateCookieName: ctx.router.resolvedStateCookieName,
|
|
568
719
|
},
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
720
|
+
},
|
|
721
|
+
hasInterceptSlots: !!result.slots,
|
|
722
|
+
pprReplayStatus,
|
|
723
|
+
partialCaptureNeeded,
|
|
724
|
+
partialCaptureKey,
|
|
725
|
+
};
|
|
726
|
+
}
|
|
575
727
|
|
|
576
|
-
|
|
577
|
-
|
|
728
|
+
// Full render (initial page load)
|
|
729
|
+
const match = yield* step("match", () =>
|
|
730
|
+
matchAndRecordParams(ctx, request, env),
|
|
731
|
+
);
|
|
732
|
+
|
|
733
|
+
if (match.redirect) {
|
|
734
|
+
return {
|
|
735
|
+
kind: "control",
|
|
736
|
+
response: createResponseWithMergedHeaders(null, {
|
|
578
737
|
status: 308,
|
|
579
738
|
headers: { Location: match.redirect },
|
|
580
|
-
})
|
|
581
|
-
}
|
|
739
|
+
}),
|
|
740
|
+
};
|
|
741
|
+
}
|
|
582
742
|
|
|
583
|
-
|
|
584
|
-
|
|
743
|
+
// Caching is now handled in router.match() via cache provider in request context
|
|
744
|
+
// match.segments already contains cached or fresh segments as appropriate
|
|
745
|
+
|
|
746
|
+
if (url.searchParams.has("__prerender_collect")) {
|
|
747
|
+
const response = yield* step("prerender-collect", () =>
|
|
748
|
+
collectPrerenderArtifacts(match, handleStore),
|
|
749
|
+
);
|
|
750
|
+
return { kind: "control", response };
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
return {
|
|
754
|
+
kind: "payload",
|
|
755
|
+
payload: buildFullPayload(match, ctx, url, reqCtx, handleStore),
|
|
756
|
+
hasInterceptSlots: false,
|
|
757
|
+
partialCaptureNeeded: false,
|
|
758
|
+
};
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
/**
|
|
762
|
+
* PPR replay match that stamps params/routeName when a replay result exists.
|
|
763
|
+
* A null result records nothing — the fallback match records its own.
|
|
764
|
+
*/
|
|
765
|
+
async function matchPartialAndRecordParams<TEnv>(
|
|
766
|
+
ctx: HandlerContext<TEnv>,
|
|
767
|
+
request: Request,
|
|
768
|
+
env: TEnv,
|
|
769
|
+
url: URL,
|
|
770
|
+
reqCtx: RequestContext<any>,
|
|
771
|
+
nonce: string | undefined,
|
|
772
|
+
): Promise<Awaited<ReturnType<typeof matchPartialWithPprReplay<TEnv>>>> {
|
|
773
|
+
const replay = await matchPartialWithPprReplay(
|
|
774
|
+
ctx,
|
|
775
|
+
request,
|
|
776
|
+
env,
|
|
777
|
+
url,
|
|
778
|
+
reqCtx,
|
|
779
|
+
nonce,
|
|
780
|
+
);
|
|
781
|
+
if (replay.result) {
|
|
782
|
+
setRequestContextParams(replay.result.params, replay.result.routeName);
|
|
783
|
+
}
|
|
784
|
+
return replay;
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
/**
|
|
788
|
+
* Shell store read that degrades to null on failure (axis 1 MISS, never a 500)
|
|
789
|
+
* and records the raw `ppr:shell-read` outcome (pre-validity-gates, so a
|
|
790
|
+
* version-mismatch lifecycle miss stays distinguishable from a store miss).
|
|
791
|
+
*/
|
|
792
|
+
async function readShellEntry<
|
|
793
|
+
TStore extends { getShell(key: string): Promise<unknown> },
|
|
794
|
+
>(
|
|
795
|
+
store: TStore,
|
|
796
|
+
key: string,
|
|
797
|
+
reqCtx: ReturnType<typeof getRequestContext>,
|
|
798
|
+
): Promise<Awaited<ReturnType<TStore["getShell"]>> | null> {
|
|
799
|
+
let cached: Awaited<ReturnType<TStore["getShell"]>> | null = null;
|
|
800
|
+
const shellReadStart = reqCtx._metricsStore ? performance.now() : 0;
|
|
801
|
+
try {
|
|
802
|
+
// The constraint types the call as Promise<unknown>; the instantiated
|
|
803
|
+
// TStore carries the real entry type, so the assertion restores it.
|
|
804
|
+
cached = (await store.getShell(key)) as Awaited<
|
|
805
|
+
ReturnType<TStore["getShell"]>
|
|
806
|
+
>;
|
|
807
|
+
} catch (error) {
|
|
808
|
+
reportCacheError(error, "cache-read", "[ShellServe] getShell");
|
|
809
|
+
}
|
|
810
|
+
if (reqCtx._metricsStore) {
|
|
811
|
+
appendMetric(
|
|
812
|
+
reqCtx._metricsStore,
|
|
813
|
+
"ppr:shell-read",
|
|
814
|
+
shellReadStart,
|
|
815
|
+
performance.now() - shellReadStart,
|
|
816
|
+
undefined,
|
|
817
|
+
cached ? "hit" : "miss",
|
|
818
|
+
);
|
|
819
|
+
}
|
|
820
|
+
return cached;
|
|
821
|
+
}
|
|
585
822
|
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
823
|
+
/**
|
|
824
|
+
* Dev Server-Timing mirror (issue #651): a capture completes AFTER its
|
|
825
|
+
* triggering response committed, so its outcome can only ride a LATER
|
|
826
|
+
* response's header. Read-and-clear keeps one capture = one report;
|
|
827
|
+
* dev-only (see takeCaptureDebugEventForTiming).
|
|
828
|
+
*/
|
|
829
|
+
function mirrorPprServerTimingsForDev(
|
|
830
|
+
key: string,
|
|
831
|
+
reqCtx: ReturnType<typeof getRequestContext>,
|
|
832
|
+
): void {
|
|
833
|
+
if (process.env.NODE_ENV !== "production" && reqCtx._metricsStore) {
|
|
834
|
+
const lastCapture = takeCaptureDebugEventForTiming(key);
|
|
835
|
+
if (lastCapture) {
|
|
836
|
+
appendMetric(
|
|
837
|
+
reqCtx._metricsStore,
|
|
838
|
+
"ppr:capture",
|
|
839
|
+
performance.now(),
|
|
840
|
+
lastCapture.attemptMs ?? 0,
|
|
841
|
+
undefined,
|
|
842
|
+
// attemptMs already rides as this entry's dur — drop it from desc.
|
|
843
|
+
describeShellCaptureEvent({ ...lastCapture, attemptMs: undefined }),
|
|
592
844
|
);
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
routeName: match.routeName,
|
|
609
|
-
params: match.params,
|
|
610
|
-
}),
|
|
611
|
-
{ headers: { "Content-Type": "application/json" } },
|
|
845
|
+
}
|
|
846
|
+
// Same mirror for the previous HIT's tail: its per-stage numbers
|
|
847
|
+
// (seed/match/handover/first-html/complete) finished after that
|
|
848
|
+
// response's headers were committed, so they ride THIS request's
|
|
849
|
+
// Server-Timing as `ppr:tail;dur=<complete ms>`.
|
|
850
|
+
const lastTail = takeShellTailTimingForServerTiming(key);
|
|
851
|
+
if (lastTail) {
|
|
852
|
+
appendMetric(
|
|
853
|
+
reqCtx._metricsStore,
|
|
854
|
+
"ppr:tail",
|
|
855
|
+
performance.now(),
|
|
856
|
+
lastTail.completeMs ?? 0,
|
|
857
|
+
undefined,
|
|
858
|
+
// completeMs already rides as this entry's dur — drop it from desc.
|
|
859
|
+
describeShellTailTiming({ ...lastTail, completeMs: undefined }),
|
|
612
860
|
);
|
|
613
|
-
} else {
|
|
614
|
-
payload = buildFullPayload(match, ctx, url, reqCtx, handleStore);
|
|
615
861
|
}
|
|
616
862
|
}
|
|
863
|
+
}
|
|
617
864
|
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
865
|
+
/**
|
|
866
|
+
* Build-time prerender collection: serialize segments and handle data
|
|
867
|
+
* to JSON for storage as build artifacts. At runtime the worker
|
|
868
|
+
* deserializes these and feeds them through the normal segment pipeline.
|
|
869
|
+
*/
|
|
870
|
+
async function collectPrerenderArtifacts<TEnv>(
|
|
871
|
+
match: Awaited<ReturnType<HandlerContext<TEnv>["router"]["match"]>>,
|
|
872
|
+
handleStore: ReturnType<typeof getRequestContext>["_handleStore"],
|
|
873
|
+
): Promise<Response> {
|
|
874
|
+
const nonLoaderSegments = match.segments.filter((s) => s.type !== "loader");
|
|
875
|
+
handleStore.seal();
|
|
876
|
+
await handleStore.settled;
|
|
877
|
+
const { serializeSegments } = await import("../cache/segment-codec.js");
|
|
878
|
+
const serializedSegments = await serializeSegments(nonLoaderSegments);
|
|
879
|
+
const handles: Record<string, Record<string, unknown[]>> = {};
|
|
880
|
+
for (const seg of nonLoaderSegments) {
|
|
881
|
+
const segHandles = handleStore.getDataForSegment(seg.id);
|
|
882
|
+
if (Object.keys(segHandles).length > 0) {
|
|
883
|
+
handles[seg.id] = segHandles;
|
|
884
|
+
}
|
|
623
885
|
}
|
|
886
|
+
return new Response(
|
|
887
|
+
JSON.stringify({
|
|
888
|
+
segments: serializedSegments,
|
|
889
|
+
handles,
|
|
890
|
+
routeName: match.routeName,
|
|
891
|
+
params: match.params,
|
|
892
|
+
}),
|
|
893
|
+
{ headers: { "Content-Type": "application/json" } },
|
|
894
|
+
);
|
|
895
|
+
}
|
|
624
896
|
|
|
897
|
+
/** Assemble headers + tracking and run the foreground stage-driver render. */
|
|
898
|
+
function renderPreparedRscResponse<TEnv>(
|
|
899
|
+
input: RequestRenderInput<TEnv>,
|
|
900
|
+
prepared: Extract<PreparedRender, { kind: "payload" }>,
|
|
901
|
+
): Promise<Response> {
|
|
902
|
+
const { ctx, request, env, url, isPartial, nonce, reqCtx, renderSpan } =
|
|
903
|
+
input;
|
|
904
|
+
const { payload, pprReplayStatus, hasInterceptSlots } = prepared;
|
|
625
905
|
const metricsStore = reqCtx._metricsStore;
|
|
626
906
|
|
|
627
907
|
const rscHeaders: Record<string, string> = {
|
|
@@ -661,8 +941,11 @@ async function handleRscRenderingInner<TEnv>(
|
|
|
661
941
|
mode: isPartial ? ("partial" as const) : ("full" as const),
|
|
662
942
|
routeKey: reqCtx._routeName,
|
|
663
943
|
span: renderSpan,
|
|
944
|
+
onEvent:
|
|
945
|
+
reqCtx._activeRoutine &&
|
|
946
|
+
createRenderStageTraceBridge(reqCtx._activeRoutine),
|
|
664
947
|
};
|
|
665
|
-
|
|
948
|
+
return renderRscResponse(
|
|
666
949
|
{
|
|
667
950
|
ctx,
|
|
668
951
|
request,
|
|
@@ -686,65 +969,46 @@ async function handleRscRenderingInner<TEnv>(
|
|
|
686
969
|
}),
|
|
687
970
|
},
|
|
688
971
|
);
|
|
972
|
+
}
|
|
689
973
|
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
974
|
+
/**
|
|
975
|
+
* Background capture for a navigation-only shell (partial replay reported
|
|
976
|
+
* captureNeeded). SSR setup is resolved lazily inside the capture because the
|
|
977
|
+
* partial request itself never touched HTML rendering.
|
|
978
|
+
*/
|
|
979
|
+
function scheduleNavigationShellCapture<TEnv>(
|
|
980
|
+
input: RequestRenderInput<TEnv>,
|
|
981
|
+
partialCaptureKey: string | undefined,
|
|
982
|
+
): void {
|
|
983
|
+
const { ctx, request, env, url, reqCtx } = input;
|
|
984
|
+
const pprConfig = resolvePprConfig(reqCtx._classifiedRoute?.manifestEntry)!;
|
|
985
|
+
const store = reqCtx._cacheStore!;
|
|
986
|
+
scheduleShellCapture(
|
|
987
|
+
ctx,
|
|
988
|
+
request,
|
|
989
|
+
env,
|
|
990
|
+
url,
|
|
991
|
+
reqCtx,
|
|
992
|
+
async (captureRequest, captureUrl) => {
|
|
993
|
+
const [ssrModule, streamMode] = await getSSRSetup(
|
|
700
994
|
ctx,
|
|
701
|
-
|
|
995
|
+
captureRequest,
|
|
702
996
|
env,
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
pprMiss.ssrModule,
|
|
706
|
-
pprMiss.descriptor,
|
|
997
|
+
captureUrl,
|
|
998
|
+
undefined,
|
|
707
999
|
);
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
if (
|
|
713
|
-
isPartial &&
|
|
714
|
-
partialCaptureNeeded &&
|
|
715
|
-
!reqCtx._dynamic &&
|
|
716
|
-
response.status === 200
|
|
717
|
-
) {
|
|
718
|
-
const pprConfig = resolvePprConfig(reqCtx._classifiedRoute?.manifestEntry)!;
|
|
719
|
-
const store = reqCtx._cacheStore!;
|
|
720
|
-
scheduleShellCapture(
|
|
1000
|
+
return streamMode === "allReady" ? null : ssrModule;
|
|
1001
|
+
},
|
|
1002
|
+
createShellCaptureDescriptor(
|
|
721
1003
|
ctx,
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
url,
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
env,
|
|
731
|
-
captureUrl,
|
|
732
|
-
undefined,
|
|
733
|
-
);
|
|
734
|
-
return streamMode === "allReady" ? null : ssrModule;
|
|
735
|
-
},
|
|
736
|
-
createShellCaptureDescriptor(
|
|
737
|
-
ctx,
|
|
738
|
-
partialCaptureKey ??
|
|
739
|
-
buildNavigationShellKey(url, reqCtx._searchParamsFilter),
|
|
740
|
-
pprConfig,
|
|
741
|
-
store,
|
|
742
|
-
true,
|
|
743
|
-
),
|
|
744
|
-
);
|
|
745
|
-
}
|
|
746
|
-
|
|
747
|
-
return response;
|
|
1004
|
+
partialCaptureKey ??
|
|
1005
|
+
buildNavigationShellKey(url, reqCtx._searchParamsFilter),
|
|
1006
|
+
shellSearchSeed(url, reqCtx._searchParamsFilter),
|
|
1007
|
+
pprConfig,
|
|
1008
|
+
store,
|
|
1009
|
+
true,
|
|
1010
|
+
),
|
|
1011
|
+
);
|
|
748
1012
|
}
|
|
749
1013
|
|
|
750
1014
|
/**
|
|
@@ -1257,6 +1521,9 @@ function serveShellHit(
|
|
|
1257
1521
|
ssrModule.resumeShellHTML!(rscStream, {
|
|
1258
1522
|
postponed: entry.postponed,
|
|
1259
1523
|
nonce: undefined,
|
|
1524
|
+
// The shell key's own search — identical to the capture seed for
|
|
1525
|
+
// this key, so the resume tree matches the captured tree.
|
|
1526
|
+
search: shellSearchSeed(url, reqCtx._searchParamsFilter),
|
|
1260
1527
|
}),
|
|
1261
1528
|
);
|
|
1262
1529
|
};
|