@rangojs/router 0.20.0 → 0.22.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/dist/bin/rango.js +39 -15
- package/dist/types/browser/event-controller.d.ts +49 -0
- package/dist/types/browser/history-state.d.ts +16 -4
- package/dist/types/browser/navigation-store.d.ts +9 -0
- package/dist/types/browser/navigation-transaction.d.ts +7 -0
- package/dist/types/browser/partial-update.d.ts +2 -1
- package/dist/types/browser/prefetch/default-strategy.d.ts +16 -20
- package/dist/types/browser/rango-state.d.ts +3 -1
- package/dist/types/browser/react/NavigationProvider.d.ts +14 -1
- package/dist/types/browser/react/context.d.ts +25 -0
- package/dist/types/browser/react/location-state-shared.d.ts +84 -10
- package/dist/types/browser/react/location-state.d.ts +7 -2
- package/dist/types/browser/rsc-router.d.ts +13 -2
- package/dist/types/browser/types.d.ts +10 -0
- package/dist/types/build/generate-manifest.d.ts +2 -0
- package/dist/types/cache/background-task.d.ts +22 -0
- package/dist/types/cache/cache-key-utils.d.ts +50 -5
- package/dist/types/cache/cache-policy.d.ts +17 -0
- package/dist/types/cache/cache-scope.d.ts +5 -6
- package/dist/types/cache/cf/cf-cache-store.d.ts +34 -7
- package/dist/types/cache/cf/cf-cache-types.d.ts +12 -4
- package/dist/types/cache/document-cache.d.ts +8 -5
- package/dist/types/cache/handle-snapshot.d.ts +59 -50
- package/dist/types/cache/index.d.ts +3 -1
- package/dist/types/cache/invalidation-order.d.ts +14 -0
- package/dist/types/cache/memory-segment-store.d.ts +33 -1
- package/dist/types/cache/shell-snapshot.d.ts +29 -4
- package/dist/types/cache/store-scope.d.ts +22 -0
- package/dist/types/cache/tag-invalidation.d.ts +7 -6
- package/dist/types/cache/types.d.ts +84 -24
- package/dist/types/cache/vercel/vercel-cache-store.d.ts +35 -17
- package/dist/types/client-urls/navigation.d.ts +7 -1
- package/dist/types/client-urls/optimistic-location.d.ts +10 -4
- package/dist/types/errors.d.ts +6 -0
- package/dist/types/handles/deferred-resolution.d.ts +18 -1
- package/dist/types/internal-suspense-audit.d.ts +1 -0
- package/dist/types/loader-store.d.ts +4 -8
- package/dist/types/outlet-provider.d.ts +2 -1
- package/dist/types/prerender/build-shell-capture.d.ts +8 -6
- package/dist/types/prerender/cloudflare.d.ts +49 -0
- package/dist/types/prerender/create-prerender-trigger.d.ts +121 -0
- package/dist/types/prerender/index.d.ts +12 -0
- package/dist/types/prerender/memory-prerender-store.d.ts +29 -0
- package/dist/types/prerender/on-demand.d.ts +272 -0
- package/dist/types/prerender/producer-guard.d.ts +33 -0
- package/dist/types/prerender/shell-manifest-key.d.ts +1 -18
- package/dist/types/prerender/warm-request.d.ts +65 -0
- package/dist/types/prerender/warm.d.ts +65 -0
- package/dist/types/prerender/writable-store.d.ts +170 -0
- package/dist/types/prerender.d.ts +27 -0
- package/dist/types/reverse.d.ts +1 -1
- package/dist/types/route-content-wrapper.d.ts +3 -1
- package/dist/types/router/error-handling.d.ts +2 -0
- package/dist/types/router/handler-context.d.ts +1 -1
- package/dist/types/router/match-middleware/cache-lookup.d.ts +15 -1
- package/dist/types/router/navigation-snapshot.d.ts +8 -1
- package/dist/types/router/pattern-matching.d.ts +2 -0
- package/dist/types/router/prefetch-default.d.ts +4 -4
- package/dist/types/router/prerender-match.d.ts +23 -1
- package/dist/types/router/route-trie-builder.d.ts +8 -1
- package/dist/types/router/router-context.d.ts +1 -0
- package/dist/types/router/router-interfaces.d.ts +32 -1
- package/dist/types/router/router-options.d.ts +39 -5
- package/dist/types/router/segment-resolution/fresh.d.ts +7 -0
- package/dist/types/router/segment-resolution/loader-cache.d.ts +23 -10
- package/dist/types/router/segment-resolution/revalidation.d.ts +5 -1
- package/dist/types/router/segment-resolution/streamed-handler-boundary.d.ts +43 -0
- package/dist/types/router/trie-matching.d.ts +2 -0
- package/dist/types/router-versions.d.ts +39 -0
- package/dist/types/rsc/handler-context.d.ts +5 -0
- package/dist/types/rsc/shell-build-manifest.d.ts +9 -6
- package/dist/types/rsc/shell-capture-constants.d.ts +20 -5
- package/dist/types/rsc/shell-capture.d.ts +14 -1
- package/dist/types/rsc/shell-serve.d.ts +2 -2
- package/dist/types/rsc/ssr-module-loader.d.ts +15 -0
- package/dist/types/rsc/types.d.ts +12 -6
- package/dist/types/segment-boundary-content.d.ts +17 -0
- package/dist/types/segment-loader-promise.d.ts +2 -6
- package/dist/types/server/build-version-table.d.ts +53 -0
- package/dist/types/server/context.d.ts +12 -4
- package/dist/types/server/handle-store.d.ts +89 -46
- package/dist/types/server/request-context.d.ts +84 -9
- package/dist/types/suspense-audit-react.d.ts +26 -0
- package/dist/types/suspense-audit.d.ts +157 -0
- package/dist/types/testing/action-form.d.ts +34 -0
- package/dist/types/testing/build-versions.d.ts +32 -0
- package/dist/types/testing/dom.entry.d.ts +1 -1
- package/dist/types/testing/flight.entry.d.ts +3 -1
- package/dist/types/testing/index.d.ts +6 -0
- package/dist/types/testing/internal/seed-vars.d.ts +7 -2
- package/dist/types/testing/internal/server-modules.d.ts +8 -0
- package/dist/types/testing/location-state-key.d.ts +5 -1
- package/dist/types/testing/render-route.d.ts +77 -6
- package/dist/types/testing/serve-shell-request.d.ts +55 -4
- package/dist/types/testing/shell-status.d.ts +14 -6
- package/dist/types/testing/vitest-stubs/plugin-rsc.d.ts +9 -6
- package/dist/types/testing/vitest-stubs/version.d.ts +1 -0
- package/dist/types/thenable-status.d.ts +6 -0
- package/dist/types/types/handler-context.d.ts +15 -5
- package/dist/types/types/route-entry.d.ts +5 -0
- package/dist/types/urls/path-helper.d.ts +18 -0
- package/dist/types/vite/discovery/build-versions.d.ts +393 -0
- package/dist/types/vite/discovery/installed-packages.d.ts +26 -0
- package/dist/types/vite/discovery/router-versions-phase.d.ts +52 -0
- package/dist/types/vite/discovery/shell-prerender-phase.d.ts +7 -17
- package/dist/types/vite/discovery/state.d.ts +25 -0
- package/dist/types/vite/encryption-key.d.ts +18 -0
- package/dist/types/vite/inject-client-debug.d.ts +6 -25
- package/dist/types/vite/plugin-types.d.ts +27 -0
- package/dist/types/vite/plugins/{version-injector.d.ts → entry-bootstrap-injector.d.ts} +4 -6
- package/dist/types/vite/plugins/expose-ids/export-analysis.d.ts +1 -0
- package/dist/types/vite/plugins/expose-ids/router-transform.d.ts +14 -0
- package/dist/types/vite/plugins/stable-rsc-output.d.ts +51 -0
- package/dist/types/vite/plugins/version-plugin.d.ts +9 -11
- package/dist/types/vite/plugins/virtual-entries.d.ts +18 -1
- package/dist/types/vite/router-discovery.d.ts +6 -0
- package/dist/types/vite/utils/bundle-analysis.d.ts +6 -2
- package/dist/types/vite/utils/client-chunks.d.ts +2 -0
- package/dist/types/vite/utils/compare-strings.d.ts +7 -0
- package/dist/types/vite/utils/package-resolution.d.ts +8 -0
- package/dist/types/vite/utils/prerender-utils.d.ts +2 -0
- package/dist/vite/index.js +1707 -931
- package/package.json +12 -3
- package/skills/cache-guide/SKILL.md +102 -37
- package/skills/caching/SKILL.md +56 -9
- package/skills/catalog.json +1 -1
- package/skills/client-urls/SKILL.md +16 -0
- package/skills/cloudflare/SKILL.md +133 -1
- package/skills/comparison/references/framework-comparison.md +17 -13
- package/skills/deployment-caching/SKILL.md +33 -12
- package/skills/document-cache/SKILL.md +16 -14
- package/skills/hooks/SKILL.md +25 -0
- package/skills/hooks/handle-and-actions.md +5 -0
- package/skills/hooks/navigation.md +38 -0
- package/skills/hooks/state.md +213 -11
- package/skills/hooks/urls.md +40 -1
- package/skills/host-router/SKILL.md +31 -0
- package/skills/intercept/SKILL.md +6 -0
- package/skills/loader/SKILL.md +25 -5
- package/skills/middleware/SKILL.md +2 -0
- package/skills/migrate-nextjs/SKILL.md +82 -9
- package/skills/ppr/SKILL.md +150 -48
- package/skills/prerender/SKILL.md +651 -10
- package/skills/rango/SKILL.md +9 -7
- package/skills/response-routes/SKILL.md +5 -5
- package/skills/route/SKILL.md +29 -0
- package/skills/router-setup/SKILL.md +15 -1
- package/skills/testing/SKILL.md +32 -27
- package/skills/testing/cache-prerender.md +18 -17
- package/skills/testing/client-components.md +193 -8
- package/skills/testing/handles.md +2 -0
- package/skills/testing/loader.md +1 -1
- package/skills/testing/middleware.md +1 -1
- package/skills/testing/render-handler.md +18 -18
- package/skills/testing/serve-shell-request.md +167 -22
- package/skills/testing/server-actions.md +17 -17
- package/skills/testing/server-tree.md +1 -1
- package/skills/typesafety/generated-files-and-cli.md +1 -1
- package/skills/use-cache/SKILL.md +25 -10
- package/skills/vercel/SKILL.md +5 -3
- package/skills/view-transitions/SKILL.md +9 -4
- package/src/bin/rango.ts +1 -1
- package/src/browser/event-controller.ts +119 -2
- package/src/browser/history-state.ts +39 -17
- package/src/browser/link-interceptor.ts +2 -2
- package/src/browser/navigation-bridge.ts +104 -41
- package/src/browser/navigation-store.ts +26 -0
- package/src/browser/navigation-transaction.ts +24 -12
- package/src/browser/network-error-handler.ts +2 -0
- package/src/browser/partial-update.ts +58 -14
- package/src/browser/prefetch/default-strategy.ts +22 -42
- package/src/browser/rango-state.ts +3 -1
- package/src/browser/react/Link.tsx +37 -43
- package/src/browser/react/NavigationProvider.tsx +85 -1
- package/src/browser/react/context.ts +30 -0
- package/src/browser/react/location-state-shared.ts +200 -34
- package/src/browser/react/location-state.ts +28 -77
- package/src/browser/react/use-action.ts +4 -1
- package/src/browser/react/use-handle.ts +3 -0
- package/src/browser/react/use-link-status.ts +4 -3
- package/src/browser/react/use-navigation.ts +4 -1
- package/src/browser/react/use-params.ts +4 -1
- package/src/browser/react/use-pathname.ts +4 -1
- package/src/browser/react/use-search-params.ts +5 -3
- package/src/browser/react/use-segments.ts +36 -54
- package/src/browser/rsc-router.tsx +93 -31
- package/src/browser/segment-reconciler.ts +3 -3
- package/src/browser/server-action-bridge.ts +43 -7
- package/src/browser/types.ts +11 -0
- package/src/build/generate-manifest.ts +17 -0
- package/src/build/merge-full-manifests.ts +5 -0
- package/src/build/route-trie.ts +1 -0
- package/src/cache/background-task.ts +61 -0
- package/src/cache/cache-key-utils.ts +91 -12
- package/src/cache/cache-policy.ts +11 -2
- package/src/cache/cache-runtime.ts +23 -23
- package/src/cache/cache-scope.ts +48 -36
- package/src/cache/cf/cf-cache-store.ts +91 -66
- package/src/cache/cf/cf-cache-types.ts +12 -4
- package/src/cache/document-cache.ts +35 -14
- package/src/cache/handle-snapshot.ts +118 -86
- package/src/cache/index.ts +5 -0
- package/src/cache/invalidation-order.ts +53 -0
- package/src/cache/memory-segment-store.ts +52 -1
- package/src/cache/shell-snapshot.ts +52 -5
- package/src/cache/store-scope.ts +36 -0
- package/src/cache/tag-invalidation.ts +7 -5
- package/src/cache/types.ts +90 -24
- package/src/cache/vercel/vercel-cache-store.ts +68 -26
- package/src/client-urls/client-root.tsx +1 -0
- package/src/client-urls/navigation.ts +10 -0
- package/src/client-urls/optimistic-location.ts +10 -4
- package/src/client.tsx +40 -3
- package/src/errors.ts +13 -6
- package/src/handles/deferred-resolution.ts +36 -0
- package/src/internal-suspense-audit.ts +12 -0
- package/src/loader-store.ts +4 -9
- package/src/outlet-provider.tsx +25 -1
- package/src/prerender/build-shell-capture.ts +11 -9
- package/src/prerender/cloudflare.ts +130 -0
- package/src/prerender/create-prerender-trigger.ts +780 -0
- package/src/prerender/index.ts +39 -0
- package/src/prerender/memory-prerender-store.ts +115 -0
- package/src/prerender/on-demand.ts +339 -0
- package/src/prerender/producer-guard.ts +66 -0
- package/src/prerender/shell-manifest-key.ts +12 -17
- package/src/prerender/warm-request.ts +154 -0
- package/src/prerender/warm.ts +193 -0
- package/src/prerender/writable-store.ts +278 -0
- package/src/prerender.ts +29 -0
- package/src/reverse.ts +1 -1
- package/src/route-content-wrapper.tsx +107 -13
- package/src/router/error-handling.ts +12 -12
- package/src/router/find-match.ts +1 -0
- package/src/router/handler-context.ts +2 -0
- package/src/router/intercept-resolution.ts +15 -8
- package/src/router/loader-resolution.ts +2 -10
- package/src/router/manifest.ts +2 -0
- package/src/router/match-middleware/background-revalidation.ts +2 -0
- package/src/router/match-middleware/cache-lookup.ts +239 -54
- package/src/router/navigation-snapshot.ts +25 -6
- package/src/router/pattern-matching.ts +14 -0
- package/src/router/prefetch-default.ts +4 -4
- package/src/router/prerender-match.ts +460 -352
- package/src/router/request-classification.ts +15 -12
- package/src/router/route-trie-builder.ts +9 -0
- package/src/router/router-context.ts +1 -0
- package/src/router/router-interfaces.ts +35 -1
- package/src/router/router-options.ts +45 -5
- package/src/router/segment-resolution/fresh.ts +20 -19
- package/src/router/segment-resolution/loader-cache.ts +110 -77
- package/src/router/segment-resolution/revalidation.ts +34 -24
- package/src/router/segment-resolution/streamed-handler-boundary.ts +133 -0
- package/src/router/trie-matching.ts +3 -0
- package/src/router-versions.ts +60 -0
- package/src/router.ts +107 -1
- package/src/rsc/full-payload.ts +6 -2
- package/src/rsc/handler-context.ts +5 -0
- package/src/rsc/handler.ts +64 -7
- package/src/rsc/progressive-enhancement.ts +5 -1
- package/src/rsc/response-cache-serve.ts +10 -4
- package/src/rsc/rsc-rendering.ts +65 -12
- package/src/rsc/shell-build-manifest.ts +17 -12
- package/src/rsc/shell-capture-constants.ts +39 -7
- package/src/rsc/shell-capture.ts +144 -45
- package/src/rsc/shell-serve.ts +12 -6
- package/src/rsc/ssr-module-loader.ts +26 -0
- package/src/rsc/types.ts +12 -6
- package/src/segment-boundary-content.ts +25 -0
- package/src/segment-loader-promise.ts +28 -38
- package/src/segment-system.tsx +117 -57
- package/src/server/build-version-table.ts +130 -0
- package/src/server/context.ts +40 -17
- package/src/server/cookie-store.ts +5 -0
- package/src/server/handle-store.ts +357 -127
- package/src/server/request-context.ts +149 -12
- package/src/ssr/ssr-root.tsx +32 -13
- package/src/suspense-audit-react.tsx +98 -0
- package/src/suspense-audit.ts +1030 -0
- package/src/testing/action-form.ts +66 -0
- package/src/testing/build-versions.ts +64 -0
- package/src/testing/dispatch.ts +6 -0
- package/src/testing/dom.entry.ts +1 -0
- package/src/testing/flight-runtime.d.ts +27 -0
- package/src/testing/flight.entry.ts +4 -0
- package/src/testing/index.ts +22 -0
- package/src/testing/internal/context.ts +2 -1
- package/src/testing/internal/seed-vars.ts +14 -2
- package/src/testing/internal/server-modules.ts +32 -0
- package/src/testing/location-state-key.ts +18 -8
- package/src/testing/render-handler.ts +2 -1
- package/src/testing/render-route.tsx +293 -46
- package/src/testing/serve-shell-request.ts +262 -37
- package/src/testing/shell-status.ts +17 -6
- package/src/testing/vitest-stubs/plugin-rsc.ts +37 -11
- package/src/testing/vitest-stubs/version.ts +4 -1
- package/src/thenable-status.ts +10 -0
- package/src/types/handler-context.ts +15 -5
- package/src/types/route-entry.ts +6 -0
- package/src/urls/path-helper.ts +69 -9
- package/src/use-loader.tsx +57 -30
- package/src/vite/discovery/build-versions.ts +1281 -0
- package/src/vite/discovery/bundle-postprocess.ts +4 -0
- package/src/vite/discovery/discover-routers.ts +15 -0
- package/src/vite/discovery/installed-packages.ts +159 -0
- package/src/vite/discovery/prerender-collection.ts +38 -1
- package/src/vite/discovery/router-versions-phase.ts +336 -0
- package/src/vite/discovery/shell-prerender-phase.ts +33 -43
- package/src/vite/discovery/state.ts +36 -1
- package/src/vite/discovery/virtual-module-codegen.ts +7 -2
- package/src/vite/encryption-key.ts +101 -9
- package/src/vite/inject-client-debug.ts +42 -20
- package/src/vite/plugin-types.ts +28 -0
- package/src/vite/plugins/{version-injector.ts → entry-bootstrap-injector.ts} +7 -22
- package/src/vite/plugins/expose-ids/export-analysis.ts +1 -1
- package/src/vite/plugins/expose-ids/router-transform.ts +36 -15
- package/src/vite/plugins/expose-internal-ids.ts +12 -3
- package/src/vite/plugins/stable-rsc-output.ts +147 -0
- package/src/vite/plugins/version-plugin.ts +19 -24
- package/src/vite/plugins/version.d.ts +17 -2
- package/src/vite/plugins/virtual-entries.ts +39 -6
- package/src/vite/rango.ts +28 -3
- package/src/vite/router-discovery.ts +96 -13
- package/src/vite/utils/bundle-analysis.ts +39 -7
- package/src/vite/utils/client-chunks.ts +5 -1
- package/src/vite/utils/compare-strings.ts +9 -0
- package/src/vite/utils/package-resolution.ts +9 -0
- package/src/vite/utils/prerender-utils.ts +4 -1
- package/src/vite/utils/shared-utils.ts +1 -1
- package/dist/types/segment-content-promise.d.ts +0 -13
- package/src/segment-content-promise.ts +0 -67
|
@@ -17,6 +17,25 @@ export type HandleData = Record<string, Record<string, unknown[]>>;
|
|
|
17
17
|
* Reads data directly from the store for each segment in order.
|
|
18
18
|
*/
|
|
19
19
|
export declare function buildHandleSnapshot(handleStore: HandleStore, segmentOrder: string[]): HandleData;
|
|
20
|
+
/**
|
|
21
|
+
* What a restored record is to one loader's handle pushes on this request
|
|
22
|
+
* (loader-cache.ts loaderPins; docs/design/handle-push-ownership.md). Two
|
|
23
|
+
* answers let the record's copies stand, two make them placeholders, and in
|
|
24
|
+
* each pair one also speaks for the loader's other pushes:
|
|
25
|
+
* - "pin": the request serves the loader's value from the pin stored with
|
|
26
|
+
* the record, and the record lists every settled push of that run. Its
|
|
27
|
+
* copies stand, and any other settled push of the loader is dropped.
|
|
28
|
+
* - "copies": its copies stand and nothing else is known: a dependency of
|
|
29
|
+
* pinned loaders, or a pin written before captures recorded every push.
|
|
30
|
+
* - "hole": the route runs the loader on this request (it registers it and
|
|
31
|
+
* the record does not pin it). Its copies are placeholders and a push made
|
|
32
|
+
* in its body is its own, with or without copies.
|
|
33
|
+
* - "placeholders": its copies are placeholders and nothing else is known: a
|
|
34
|
+
* dependency the route does not register while a pin is missing (the
|
|
35
|
+
* record does not name the loader that ran it). Without copies its push
|
|
36
|
+
* counts for the loader that awaits it.
|
|
37
|
+
*/
|
|
38
|
+
export type RecordAuthority = "pin" | "copies" | "hole" | "placeholders";
|
|
20
39
|
/**
|
|
21
40
|
* HandleStore tracks pending handler promises and stores handle data.
|
|
22
41
|
*
|
|
@@ -81,69 +100,86 @@ export interface HandleStore {
|
|
|
81
100
|
*/
|
|
82
101
|
push(handleName: string, segmentId: string, data: unknown, loaderPush?: boolean, owner?: string): void;
|
|
83
102
|
/**
|
|
84
|
-
* push() a
|
|
85
|
-
*
|
|
86
|
-
* in this request, its first push removes every
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
103
|
+
* push() a cached unit's copy of a value `loaderId`'s body pushed
|
|
104
|
+
* (handle-snapshot.ts appendHandles: a loader-cache or "use cache" HIT). If
|
|
105
|
+
* that loader then runs live in this request, its first push removes every
|
|
106
|
+
* copy pushed for it (replays and placeholders) and takes the first one's
|
|
107
|
+
* position, and the pushes of that run follow in push order, a dependency's
|
|
108
|
+
* included, so the handle output stays live without a duplicate. A push
|
|
109
|
+
* counts as that loader's when it is made in its body, or in a body it
|
|
110
|
+
* entered that has no copies of its own (the capture credits a dependency's
|
|
111
|
+
* push under a live-lane loader to that loader). A run that ends without a
|
|
112
|
+
* push leaves a replay in place, unless the loader is a hole
|
|
113
|
+
* (settleLoaderRun).
|
|
93
114
|
*/
|
|
94
115
|
pushReplayed(handleName: string, segmentId: string, data: unknown, loaderId: string): void;
|
|
95
116
|
/**
|
|
96
|
-
* push() a
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
*
|
|
117
|
+
* push() a record's copy of `loaderId`'s push as a placeholder
|
|
118
|
+
* (handle-snapshot.ts restoreHandles): the record does not supply that
|
|
119
|
+
* loader's value on this request, so its own source decides its pushes. A
|
|
120
|
+
* live run replaces it as it does a replay; a run that ends without a push
|
|
121
|
+
* drops it (settleLoaderRun); a cached unit that claims the loader delivers
|
|
122
|
+
* in its place (replacePlaceholders).
|
|
123
|
+
*/
|
|
124
|
+
pushPlaceholder(handleName: string, segmentId: string, data: unknown, loaderId: string): void;
|
|
125
|
+
/**
|
|
126
|
+
* push() a record's copy of `loaderId`'s settled push that stands
|
|
127
|
+
* (restoreHandles): the record supplies the loader's value too. From then
|
|
128
|
+
* on this request drops every settled, thenable-free push the loader makes
|
|
129
|
+
* (live, or replayed from a cache entry, anywhere inside its body), and
|
|
130
|
+
* keeps the ones holding a thenable (holdsThenable: what the record could
|
|
131
|
+
* not keep), placed among the restored copies in the loader's push order.
|
|
106
132
|
*/
|
|
107
133
|
pushRestored(handleName: string, segmentId: string, data: unknown, loaderId: string): void;
|
|
108
134
|
/**
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
* never takes a push made inside a hole it awaited, while a body inside the
|
|
116
|
-
* hole that restored copies of its own (a dependency the capture ran under
|
|
117
|
-
* a bake-lane loader) still takes its pushes.
|
|
135
|
+
* What the record this request restored is to each loader (RecordAuthority;
|
|
136
|
+
* CacheScope.lookupRouteDetailed sets it on a hit). A "pin" loader counts
|
|
137
|
+
* as restored with or without copies. A hole is a "hole" loader or one with
|
|
138
|
+
* placeholders: the walk out through enclosing loader bodies that finds the
|
|
139
|
+
* loader a push counts for stops at its body, so a pinned loader never
|
|
140
|
+
* takes a push made inside a hole it awaited.
|
|
118
141
|
*/
|
|
119
|
-
|
|
142
|
+
setRecordAuthority(authority: (loaderId: string) => RecordAuthority): void;
|
|
120
143
|
/**
|
|
121
144
|
* `loaderId`'s run in this request settled (resolved or rejected), its
|
|
122
|
-
* pushes made (loader-resolution.ts createLoaderExecutor).
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
* its settled pushes, as its pin is for its data. Restored copies are not
|
|
128
|
-
* replays and stand.
|
|
145
|
+
* pushes made (loader-resolution.ts createLoaderExecutor). Its placeholders
|
|
146
|
+
* that no push of the run replaced are dropped: the run's output decides,
|
|
147
|
+
* so a loader that throws or skips its push shows none rather than the
|
|
148
|
+
* record's. A hole's replays go with them. Any other loader's replays stay
|
|
149
|
+
* (a dependency another entry's HIT replayed), and so do restored copies.
|
|
129
150
|
*/
|
|
130
151
|
settleLoaderRun(loaderId: string): void;
|
|
131
152
|
/**
|
|
132
|
-
* A
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
* place in each array. Any other loader, or a hole with nothing replayed,
|
|
139
|
-
* delivers as a plain replay.
|
|
153
|
+
* A cached unit's HIT delivering the pushes it recorded for `loaderIds`,
|
|
154
|
+
* the loaders it claimed (appendHandles). Their placeholders give way to
|
|
155
|
+
* what `deliver` pushes for them, nothing when it pushes nothing, so the
|
|
156
|
+
* page shows the pushes of the run that produced the unit's value. The
|
|
157
|
+
* pushReplayed calls `deliver` makes take the removed values' place in each
|
|
158
|
+
* array, in order. Without placeholders it is a plain replay.
|
|
140
159
|
*/
|
|
141
|
-
|
|
160
|
+
replacePlaceholders(loaderIds: readonly string[], deliver: () => void): void;
|
|
142
161
|
/**
|
|
143
162
|
* Get all collected handle data after all handlers have settled.
|
|
144
163
|
* Waits for `settled` (handler lane), then returns the data at that point.
|
|
145
164
|
*/
|
|
146
165
|
getData(): Promise<HandleData>;
|
|
166
|
+
/**
|
|
167
|
+
* Fix the document lane at the store's current state. From then on
|
|
168
|
+
* `stream("settled")` yields this state and nothing newer, and
|
|
169
|
+
* `streamLate()` delivers every change made after it, whether or not it
|
|
170
|
+
* beat the handler barrier. The first call wins. It must run before the
|
|
171
|
+
* document stream is first read: a stream that started on the live state
|
|
172
|
+
* stays on it (reported through `onError` in development).
|
|
173
|
+
*
|
|
174
|
+
* A PPR shell HIT calls it once its record is replayed and before a loader
|
|
175
|
+
* runs (rsc-rendering.ts serveShellHit). The prelude was rendered from the
|
|
176
|
+
* record's handle data (resolvedHandleStream `recordedOnly`), so that is
|
|
177
|
+
* what the client must hydrate with. What the request's loaders then push,
|
|
178
|
+
* replace or drop is theirs, not the shell's: in the document snapshot it
|
|
179
|
+
* rendered elements the prelude never had, or left out ones it has (issue
|
|
180
|
+
* #1035), and it got there or not by a race with the lane's first read.
|
|
181
|
+
*/
|
|
182
|
+
freezeDocumentSnapshot(): void;
|
|
147
183
|
/**
|
|
148
184
|
* Get an async iterator that yields handle data on each push.
|
|
149
185
|
* Completes at the chosen settlement barrier: "fullySettled" (default —
|
|
@@ -152,6 +188,9 @@ export interface HandleStore {
|
|
|
152
188
|
* blocking positions and must not wait on loader bodies).
|
|
153
189
|
* Each yield contains the full accumulated state (not just the delta).
|
|
154
190
|
* Safe for concurrent consumers (per-consumer version cursor).
|
|
191
|
+
* The "settled" lane of a frozen store (freezeDocumentSnapshot) yields the
|
|
192
|
+
* frozen state once, at once, and ends. That yield is the store's own
|
|
193
|
+
* frozen object: a consumer must not write to it.
|
|
155
194
|
*/
|
|
156
195
|
stream(until?: "settled" | "fullySettled"): AsyncGenerator<HandleData, void, unknown>;
|
|
157
196
|
/**
|
|
@@ -160,7 +199,9 @@ export interface HandleStore {
|
|
|
160
199
|
* fullySettled. Returns without yielding when the auxiliary lane is empty
|
|
161
200
|
* by the time `settled` resolves. The client consumes this post-hydration
|
|
162
201
|
* (rsc-router.tsx) and merges via the same application path as nav-lane
|
|
163
|
-
* progressive handle updates.
|
|
202
|
+
* progressive handle updates. On a frozen store (freezeDocumentSnapshot)
|
|
203
|
+
* it starts from the frozen state instead: a change made before the
|
|
204
|
+
* handler barrier is late too.
|
|
164
205
|
*/
|
|
165
206
|
streamLate(): AsyncGenerator<HandleData, void, unknown>;
|
|
166
207
|
/**
|
|
@@ -177,6 +218,8 @@ export interface HandleStore {
|
|
|
177
218
|
* value are omitted; undefined when none has one.
|
|
178
219
|
*/
|
|
179
220
|
getRecordOwners(segmentId: string): Record<string, (string | null)[]> | undefined;
|
|
221
|
+
/** The segment ids for which getRecordOwners returns an entry. */
|
|
222
|
+
getOwnedSegmentIds(): string[];
|
|
180
223
|
/**
|
|
181
224
|
* Replay cached handle data back into the store (for cache hits).
|
|
182
225
|
* Used to restore handle data when serving cached segments.
|
|
@@ -19,7 +19,8 @@ import type { Handle } from "../handle.js";
|
|
|
19
19
|
import { type ContextVar } from "../context-var.js";
|
|
20
20
|
import { type HandleStore, type HandleData } from "./handle-store.js";
|
|
21
21
|
import { type MetricsStore } from "./context.js";
|
|
22
|
-
import type { SegmentCacheStore } from "../cache/types.js";
|
|
22
|
+
import type { SegmentCacheStore, ShellSnapshotHandlesValue } from "../cache/types.js";
|
|
23
|
+
import type { RouterVersions } from "../router-versions.js";
|
|
23
24
|
import type { Theme, ResolvedThemeConfig } from "../theme/types.js";
|
|
24
25
|
import type { ExecutionContext, RequestScope } from "../types/request-scope.js";
|
|
25
26
|
import type { TransitionWhenRecord } from "../router/transition-when.js";
|
|
@@ -203,6 +204,25 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
|
|
|
203
204
|
_pprReplayPostMatchReason?: "prerender-store" | "intercept";
|
|
204
205
|
/** @internal Cache store for segment caching (optional, used by CacheScope) */
|
|
205
206
|
_cacheStore?: SegmentCacheStore;
|
|
207
|
+
/**
|
|
208
|
+
* @internal Env-scoped writable prerender store (the durable overlay) plus the
|
|
209
|
+
* deployment identity for build-scoped keys, resolved per request from the
|
|
210
|
+
* `prerender` router option. Read by the serve-path overlay lookup before the
|
|
211
|
+
* bundled build manifest. Absent when no prerender store is configured.
|
|
212
|
+
*/
|
|
213
|
+
_prerender?: import("../prerender/on-demand.js").ResolvedPrerender<any>;
|
|
214
|
+
/**
|
|
215
|
+
* @internal Set only on the requestless on-demand producer's context. When
|
|
216
|
+
* present, the standalone request-scoped READS — `cookies()`, `headers()`,
|
|
217
|
+
* `invalidateClientCache()`, `keepClientCache()` — throw a
|
|
218
|
+
* PrerenderPersonalizationError so a personalized render is skipped rather than
|
|
219
|
+
* baked into a shared payload. Response MUTATIONS on the producer context
|
|
220
|
+
* (`ctx.setStatus`/`header`/`setCookie`) stay silent no-op stubs, matching
|
|
221
|
+
* build-time prerender (the design's "throw or skip" contract permits skip):
|
|
222
|
+
* they write to a discarded synthetic response, so there is nothing to leak.
|
|
223
|
+
* Never set on the live request path.
|
|
224
|
+
*/
|
|
225
|
+
_onDemandProducer?: true;
|
|
206
226
|
/**
|
|
207
227
|
* @internal Compiled `cache.searchParams` filter for default cache-key
|
|
208
228
|
* generation (undefined = "all", the byte-stable unfiltered format). Set
|
|
@@ -271,6 +291,20 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
|
|
|
271
291
|
* cache miss.
|
|
272
292
|
*/
|
|
273
293
|
_shellForcedMiss?: true;
|
|
294
|
+
/**
|
|
295
|
+
* @internal This request is a router.prerender() warm
|
|
296
|
+
* (prerender/warm-request.ts). In `replace` mode every runtime cache read
|
|
297
|
+
* misses (isWarmReplace); the layers report into the record. A capture's
|
|
298
|
+
* derived context inherits it through the prototype.
|
|
299
|
+
*/
|
|
300
|
+
_prerenderWarm?: import("../prerender/warm-request.js").PrerenderWarmRecord;
|
|
301
|
+
/**
|
|
302
|
+
* @internal Runs a callback in the async context this request entered the
|
|
303
|
+
* handler with (captureRequestEntryContext). router.prerender() dispatches
|
|
304
|
+
* a warm through it when called from inside a request. Absent where the
|
|
305
|
+
* runtime has no AsyncLocalStorage.snapshot.
|
|
306
|
+
*/
|
|
307
|
+
_runAtRequestEntry?: <T>(fn: () => T) => T;
|
|
274
308
|
/**
|
|
275
309
|
* @internal The freshness window of the route cache() records this
|
|
276
310
|
* request read or wrote (cache-scope.ts noteRouteRecordWindow), as ms
|
|
@@ -283,7 +317,7 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
|
|
|
283
317
|
_routeRecordWindow?: RouteRecordWindow;
|
|
284
318
|
/**
|
|
285
319
|
* @internal Loader-family snapshot seed for a shell HIT's tail render:
|
|
286
|
-
*
|
|
320
|
+
* loader id -> the capture's elided container (already Flight-deserialized
|
|
287
321
|
* by serveShellHit) plus its capture-computed hole bit. resolveLoaderData
|
|
288
322
|
* overlays it onto the fresh run's container (recorded paths pinned,
|
|
289
323
|
* hole-marker paths keep the fresh nested promises) so the payload's baked
|
|
@@ -291,7 +325,9 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
|
|
|
291
325
|
* and does not run the loader. Two owners: serveShellHit sets it on the
|
|
292
326
|
* HIT tail's derived context, and matchPartialWithPprReplay sets it on the
|
|
293
327
|
* request context of a PPR partial replay once its doc record hits, and
|
|
294
|
-
* restores the previous value after the match.
|
|
328
|
+
* restores the previous value after the match. Read through servedPins
|
|
329
|
+
* (loader-cache.ts) only: it also decides which of the record's
|
|
330
|
+
* loader-owned handle pushes stand (loaderPins).
|
|
295
331
|
*/
|
|
296
332
|
_shellLoaderSeed?: Map<string, import("../cache/shell-snapshot.js").ShellLoaderSeedEntry>;
|
|
297
333
|
/**
|
|
@@ -348,9 +384,7 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
|
|
|
348
384
|
* scope replaces any route-derived cache() scope for the tail's match
|
|
349
385
|
* (resolveShellImplicitCacheScope), and a lookup that does not hit throws
|
|
350
386
|
* ShellRecordUnavailableError instead of resolving segments
|
|
351
|
-
* (withCacheLookup): a HIT never runs a handler.
|
|
352
|
-
* loader-owned handle pushes restore as authoritative
|
|
353
|
-
* (HandleStore.pushRestored): the prelude rendered them.
|
|
387
|
+
* (withCacheLookup): a HIT never runs a handler.
|
|
354
388
|
*/
|
|
355
389
|
docTail?: true;
|
|
356
390
|
/**
|
|
@@ -360,6 +394,8 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
|
|
|
360
394
|
* host) and miss the record.
|
|
361
395
|
*/
|
|
362
396
|
fixedDocKey?: string;
|
|
397
|
+
/** @internal The snapshot's `handles` record (ShellSnapshotHandlesValue). */
|
|
398
|
+
prerenderHandles?: ShellSnapshotHandlesValue;
|
|
363
399
|
/**
|
|
364
400
|
* @internal Set ONLY by matchPartialWithPprReplay on the navigation-replay
|
|
365
401
|
* serve path. Its presence arms the explicit-scope composition in
|
|
@@ -671,6 +707,17 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
|
|
|
671
707
|
* deriveShellCaptureContext gives the capture its own.
|
|
672
708
|
*/
|
|
673
709
|
_renderErrors?: unknown[];
|
|
710
|
+
/**
|
|
711
|
+
* @internal Rejections of streamed (loading()) handlers that were recovered
|
|
712
|
+
* into a declared errorBoundary()/notFoundBoundary() fallback, by segment id.
|
|
713
|
+
* The recovered promise resolves, so Flight reports nothing; cacheRoute
|
|
714
|
+
* (cache-scope.ts) refuses a write only when one of ITS segments is listed,
|
|
715
|
+
* the granularity a Flight error row has. The same errors are also pushed to
|
|
716
|
+
* `_renderErrors` for the document cache and PPR shell capture. A render
|
|
717
|
+
* under a derived context (shell capture, SWR re-render) owns its own map.
|
|
718
|
+
* Allocated on the first recovery.
|
|
719
|
+
*/
|
|
720
|
+
_recoveredHandlerErrors?: Map<string, unknown>;
|
|
674
721
|
/**
|
|
675
722
|
* @internal Report a non-fatal background error through the router's
|
|
676
723
|
* onError callback. Wired by the RSC handler / router during request
|
|
@@ -708,6 +755,14 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
|
|
|
708
755
|
/** @internal Owning router id; scopes the search-schema/root-scope registry
|
|
709
756
|
* lookups per router (route-map-builder.ts) */
|
|
710
757
|
_routerId?: string;
|
|
758
|
+
/**
|
|
759
|
+
* @internal Cache versions of the router serving this request. The cache
|
|
760
|
+
* factory builds a store per request without knowing the router, so a store
|
|
761
|
+
* reads its key versions from here, lazily, the same way CFCacheStore
|
|
762
|
+
* resolves its base URL (getCacheVersions, server/build-version-table.ts).
|
|
763
|
+
* Unset on a context no router created; a store then uses the build version.
|
|
764
|
+
*/
|
|
765
|
+
_versions?: RouterVersions;
|
|
711
766
|
/**
|
|
712
767
|
* @internal RouteSnapshot from classifyRequest, reused by match/matchPartial
|
|
713
768
|
* to avoid a second resolveRoute call. Cleared on HMR invalidation.
|
|
@@ -748,7 +803,7 @@ export interface RouteRecordWindow {
|
|
|
748
803
|
* This is the type exported to library consumers. Internal code should
|
|
749
804
|
* use the full RequestContext interface directly.
|
|
750
805
|
*/
|
|
751
|
-
export type PublicRequestContext<TEnv = DefaultEnv, TParams = Record<string, string>> = Omit<RequestContext<TEnv, TParams>, "cookie" | "cookies" | "_readCookie" | "_readCookies" | "setCookie" | "deleteCookie" | "_handleStore" | "_transitionWhenRefs" | "_pprReplayPostMatchReason" | "_cacheStore" | "_searchParamsFilter" | "_shellCaptureRun" | "_shellImplicitCache" | "_shellLoaderSeed" | "_shellCaptureLoaderRecords" | "_shellCaptureUnrecordedLoaderPush" | "_shellCaptureLoaderLanes" | "_resolvedCacheKeys" | "_shellKey" | "_shellForcedMiss" | "_routeRecordWindow" | "_shellFragmentPayload" | "_shellCaptureGuardTripped" | "_shellCaptureGuardTrippedLoaderId" | "_explicitTaggedStores" | "_requestTags" | "_recordTagOwners" | "_recordLoaderTags" | "_cacheProfiles" | "_onResponseCallbacks" | "_pendingBackgroundTasks" | "_themeConfig" | "_readTheme" | "_documentCacheRender" | "_payloadVisitorTheme" | "_locationState" | "_routeName" | "_prevRouteKey" | "_inActionRevalidation" | "_reportedErrors" | "_renderErrors" | "_renderBarrier" | "_resolveRenderBarrier" | "_renderBarrierSegmentOrder" | "_treeHasStreaming" | "_renderBarrierWaiters" | "_handlerLoaderDeps" | "_awaitBeforeFlushLoaderIds" | "_renderBarrierHandleSnapshot" | "_renderBarrierGuardClosed" | "_reportBackgroundError" | "_debugPerformance" | "_metricsStore" | "_renderForeground" | "_activeRoutine" | "_renderDiagnosticsEnabled" | "_handlerStart" | "_tracing" | "_basename" | "_routerId" | "_setStatus" | "_rotateStateCookie" | "_setKeepCacheDirective" | "_freshReads" | "_setFreshReadsCookie" | "_requestRoot" | "_requestStart" | "_responseSent" | "_variables" | "_classifiedRoute" | "_requestMode" | "_cacheSignal" | "_dynamic" | "res">;
|
|
806
|
+
export type PublicRequestContext<TEnv = DefaultEnv, TParams = Record<string, string>> = Omit<RequestContext<TEnv, TParams>, "cookie" | "cookies" | "_readCookie" | "_readCookies" | "setCookie" | "deleteCookie" | "_handleStore" | "_transitionWhenRefs" | "_pprReplayPostMatchReason" | "_cacheStore" | "_prerender" | "_onDemandProducer" | "_searchParamsFilter" | "_shellCaptureRun" | "_shellImplicitCache" | "_shellLoaderSeed" | "_shellCaptureLoaderRecords" | "_shellCaptureUnrecordedLoaderPush" | "_shellCaptureLoaderLanes" | "_resolvedCacheKeys" | "_shellKey" | "_shellForcedMiss" | "_prerenderWarm" | "_runAtRequestEntry" | "_routeRecordWindow" | "_shellFragmentPayload" | "_shellCaptureGuardTripped" | "_shellCaptureGuardTrippedLoaderId" | "_explicitTaggedStores" | "_requestTags" | "_recordTagOwners" | "_recordLoaderTags" | "_cacheProfiles" | "_onResponseCallbacks" | "_pendingBackgroundTasks" | "_themeConfig" | "_readTheme" | "_documentCacheRender" | "_payloadVisitorTheme" | "_locationState" | "_routeName" | "_prevRouteKey" | "_inActionRevalidation" | "_reportedErrors" | "_renderErrors" | "_recoveredHandlerErrors" | "_renderBarrier" | "_resolveRenderBarrier" | "_renderBarrierSegmentOrder" | "_treeHasStreaming" | "_renderBarrierWaiters" | "_handlerLoaderDeps" | "_awaitBeforeFlushLoaderIds" | "_renderBarrierHandleSnapshot" | "_renderBarrierGuardClosed" | "_reportBackgroundError" | "_debugPerformance" | "_metricsStore" | "_renderForeground" | "_activeRoutine" | "_renderDiagnosticsEnabled" | "_handlerStart" | "_tracing" | "_basename" | "_routerId" | "_versions" | "_setStatus" | "_rotateStateCookie" | "_setKeepCacheDirective" | "_freshReads" | "_setFreshReadsCookie" | "_requestRoot" | "_requestStart" | "_responseSent" | "_variables" | "_classifiedRoute" | "_requestMode" | "_cacheSignal" | "_dynamic" | "res">;
|
|
752
807
|
/**
|
|
753
808
|
* Marker for a waitUntil-scheduled fn whose task promise must NOT enter
|
|
754
809
|
* _pendingBackgroundTasks. Used by the PPR shell capture for its own task:
|
|
@@ -757,6 +812,15 @@ export type PublicRequestContext<TEnv = DefaultEnv, TParams = Record<string, str
|
|
|
757
812
|
* @internal
|
|
758
813
|
*/
|
|
759
814
|
export declare const UNTRACKED_BACKGROUND_TASK: unique symbol;
|
|
815
|
+
/**
|
|
816
|
+
* Capture the current async context (RequestContext._runAtRequestEntry), taken
|
|
817
|
+
* on handler entry before any router scope, so a nested dispatch (a
|
|
818
|
+
* router.prerender() warm called from a handler, loader or action) does not
|
|
819
|
+
* inherit the caller's route-definition, loader and cache-scope state. Per
|
|
820
|
+
* request: workerd refuses a snapshot outside the request that created it.
|
|
821
|
+
* See docs/design/prerender-every-route.md.
|
|
822
|
+
*/
|
|
823
|
+
export declare function captureRequestEntryContext(): (<T>(fn: () => T) => T) | undefined;
|
|
760
824
|
/**
|
|
761
825
|
* Run a function within a request context
|
|
762
826
|
* Used by the RSC handler to provide context to server actions
|
|
@@ -804,6 +868,12 @@ export interface CreateRequestContextOptions<TEnv> {
|
|
|
804
868
|
initialResponse?: Response;
|
|
805
869
|
/** Optional cache store for segment caching (used by CacheScope) */
|
|
806
870
|
cacheStore?: SegmentCacheStore;
|
|
871
|
+
/**
|
|
872
|
+
* Optional env-scoped writable prerender store + deployment identity (the
|
|
873
|
+
* durable overlay), resolved per request by the RSC handler from the
|
|
874
|
+
* `prerender` router option.
|
|
875
|
+
*/
|
|
876
|
+
prerender?: import("../prerender/on-demand.js").ResolvedPrerender<any>;
|
|
807
877
|
/**
|
|
808
878
|
* Compiled `cache.searchParams` filter from the resolved handler cache
|
|
809
879
|
* config (handler.ts). Stored as _searchParamsFilter.
|
|
@@ -824,8 +894,13 @@ export interface CreateRequestContextOptions<TEnv> {
|
|
|
824
894
|
themeConfig?: ResolvedThemeConfig | null;
|
|
825
895
|
/** Resolved rango state cookie name, for the server seat of invalidateClientCache(). */
|
|
826
896
|
stateCookieName?: string;
|
|
827
|
-
/**
|
|
828
|
-
|
|
897
|
+
/**
|
|
898
|
+
* The versions of the router serving this request (resolveRouterVersions).
|
|
899
|
+
* Stored as `_versions` for the cache stores; `document` is also the prefix
|
|
900
|
+
* of a server-rotated rango state value, which the browser compares with the
|
|
901
|
+
* payload's `metadata.version`.
|
|
902
|
+
*/
|
|
903
|
+
versions?: RouterVersions;
|
|
829
904
|
}
|
|
830
905
|
/**
|
|
831
906
|
* Create a full request context with all methods implemented
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import { type BoundaryAudit } from "./suspense-audit.js";
|
|
3
|
+
/**
|
|
4
|
+
* One boundary: what each render hands it, what each commit carries, and its
|
|
5
|
+
* mount. Called above the Suspense, which commits while the content waits.
|
|
6
|
+
* `streams` and `nodes` are what else its content waits for (I3 only).
|
|
7
|
+
*/
|
|
8
|
+
export declare function useBoundaryAudit(boundary: string, segmentId: string, value: unknown, streams?: Record<string, unknown>, nodes?: unknown): BoundaryAudit;
|
|
9
|
+
/** The boundary's content is on screen. */
|
|
10
|
+
export declare function useRevealAudit(rec: BoundaryAudit): void;
|
|
11
|
+
/**
|
|
12
|
+
* One `useLoader` read of a per-loader stream (I1, I2 at the read site). A
|
|
13
|
+
* read that suspends while mounting keeps no record: only a reader on screen
|
|
14
|
+
* is audited.
|
|
15
|
+
*/
|
|
16
|
+
export declare function useReadAudit(loaderId: string, stream: unknown): void;
|
|
17
|
+
/** Wraps a boundary's fallback: mounted means the fallback is on screen. */
|
|
18
|
+
export declare function AuditedFallback({ audit, children, }: {
|
|
19
|
+
audit: BoundaryAudit;
|
|
20
|
+
children: ReactNode;
|
|
21
|
+
}): ReactNode;
|
|
22
|
+
/** Wraps a segment's outlet children: the segment's mount (I4). */
|
|
23
|
+
export declare function AuditedOutlet({ segmentId, children, }: {
|
|
24
|
+
segmentId: string;
|
|
25
|
+
children: ReactNode;
|
|
26
|
+
}): ReactNode;
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
export type SuspenseAuditKind = "swap" | "untracked" | "idle-fallback" | "resuspended" | "remount" | "drift" | "uncaused" | "mutated";
|
|
2
|
+
/** What may hand React a tree (I6). */
|
|
3
|
+
export type TreeUpdateCause = "navigation" | "popstate" | "stale-revalidation" | "action" | "error" | "hmr";
|
|
4
|
+
export interface SuspenseAuditEvent {
|
|
5
|
+
/** I1 swap, I2 untracked, I3 idle-fallback and resuspended, I4 remount, I5 drift, I6 uncaused, I7 mutated. */
|
|
6
|
+
kind: SuspenseAuditKind;
|
|
7
|
+
/** `content:<segment id>`, `loaders:<outlet key>`, `outlet:<segment id>`, `read:<loader id>`, `segment:<segment id>`. */
|
|
8
|
+
boundary: string;
|
|
9
|
+
detail: string;
|
|
10
|
+
url: string;
|
|
11
|
+
at: number;
|
|
12
|
+
}
|
|
13
|
+
export interface SuspenseAuditReport {
|
|
14
|
+
swaps: number;
|
|
15
|
+
untracked: number;
|
|
16
|
+
idleFallbacks: number;
|
|
17
|
+
resuspended: number;
|
|
18
|
+
remounts: number;
|
|
19
|
+
drifts: number;
|
|
20
|
+
uncaused: number;
|
|
21
|
+
mutations: number;
|
|
22
|
+
/**
|
|
23
|
+
* Not a violation: fallbacks the router cannot attribute. Nothing it handed
|
|
24
|
+
* the boundary was a promise React read, so the content's own suspension
|
|
25
|
+
* put the fallback up: an app's use(), a React.lazy, a client reference.
|
|
26
|
+
*/
|
|
27
|
+
unattributedFallbacks: number;
|
|
28
|
+
/** Not a violation: tree updates React was handed, by cause ("none" without one). */
|
|
29
|
+
treeUpdates: Record<string, number>;
|
|
30
|
+
/**
|
|
31
|
+
* Not a violation: the distinct thenables each boundary or read was handed.
|
|
32
|
+
* One per value it waited for; two for one navigation is a gate replaced
|
|
33
|
+
* by the real promise.
|
|
34
|
+
*/
|
|
35
|
+
readonly handed: Record<string, number>;
|
|
36
|
+
/**
|
|
37
|
+
* Not a violation: fallbacks shown over content on screen while what the
|
|
38
|
+
* boundary waits for was pending. An urgent commit does that by design.
|
|
39
|
+
*/
|
|
40
|
+
shownWhilePending: number;
|
|
41
|
+
/** Mounts per boundary since the document loaded. */
|
|
42
|
+
readonly mounts: Record<string, number>;
|
|
43
|
+
/** The last events, oldest first. */
|
|
44
|
+
events: SuspenseAuditEvent[];
|
|
45
|
+
reset(): void;
|
|
46
|
+
}
|
|
47
|
+
/** One boundary, or one `useLoader` read. Lives as long as its fiber. */
|
|
48
|
+
export interface BoundaryAudit {
|
|
49
|
+
boundary: string;
|
|
50
|
+
/** Segment id, for the place in the tree. */
|
|
51
|
+
segmentId: string;
|
|
52
|
+
/** The React key the segment was mounted under (I4 identity). */
|
|
53
|
+
key: string;
|
|
54
|
+
/** 0 until the boundary is on screen. */
|
|
55
|
+
mountId: number;
|
|
56
|
+
/** Last value a render ran with, and the URL it ran under. */
|
|
57
|
+
seen: unknown;
|
|
58
|
+
hasSeen: boolean;
|
|
59
|
+
seenUrl: string;
|
|
60
|
+
/** Last value a commit carried. */
|
|
61
|
+
committed: unknown;
|
|
62
|
+
hasCommitted: boolean;
|
|
63
|
+
/** What else the boundary's content waits for: per-loader streams, nodes. */
|
|
64
|
+
streams: Record<string, unknown> | undefined;
|
|
65
|
+
nodes: unknown;
|
|
66
|
+
/** The content has been on screen. */
|
|
67
|
+
revealed: boolean;
|
|
68
|
+
/** The fallback's effect was cleaned up in this task (auditFallback). */
|
|
69
|
+
fallbackGone: boolean;
|
|
70
|
+
}
|
|
71
|
+
export declare function createBoundaryAudit(boundary: string, segmentId: string): BoundaryAudit;
|
|
72
|
+
/**
|
|
73
|
+
* Render phase: the value this render hands the boundary.
|
|
74
|
+
*
|
|
75
|
+
* I1: a boundary on screen was handed a thenable that is still pending, and
|
|
76
|
+
* is handed another one that is not already settled, for the same URL. React
|
|
77
|
+
* starts waiting again. A settled replacement is read at once, and another
|
|
78
|
+
* URL is another navigation: both are exempt.
|
|
79
|
+
* I2: a boundary whose content has been on screen is handed a native promise
|
|
80
|
+
* React has not read, and React finds it settled when it reads it. A render
|
|
81
|
+
* that cannot wait suspends on it and commits the fallback over the content,
|
|
82
|
+
* which React keeps up for 300 ms. Judged from the status React leaves on
|
|
83
|
+
* the promise when it reads it in the same task.
|
|
84
|
+
*/
|
|
85
|
+
export declare function auditHandover(rec: BoundaryAudit, value: unknown): void;
|
|
86
|
+
/** Commit phase: what the boundary on screen now reads. */
|
|
87
|
+
export declare function auditCommit(rec: BoundaryAudit, value: unknown, streams?: Record<string, unknown>, nodes?: unknown): void;
|
|
88
|
+
export declare function auditReveal(rec: BoundaryAudit): void;
|
|
89
|
+
/** One `useLoader` read on screen: it has a mount and reveals with it. */
|
|
90
|
+
export declare function auditRead(rec: BoundaryAudit, stream: unknown): void;
|
|
91
|
+
/**
|
|
92
|
+
* How the audit learns that a payload is still streaming: the event
|
|
93
|
+
* controller, set at boot (browser/rsc-router.tsx). Not read from
|
|
94
|
+
* NavigationStoreContext in AuditedFallback: see the header.
|
|
95
|
+
*/
|
|
96
|
+
export declare function setSuspenseAuditStreamProbe(probe: () => boolean): void;
|
|
97
|
+
/**
|
|
98
|
+
* I3: the boundary's fallback is on screen with nothing to wait for: nothing
|
|
99
|
+
* the router handed the boundary is pending, no payload is streaming and no
|
|
100
|
+
* client reference is loading. `idle-fallback` on a boundary new to the page,
|
|
101
|
+
* `resuspended` when the fallback replaced content that had been on screen.
|
|
102
|
+
*
|
|
103
|
+
* Reported only when the router owns the fallback: React suspended on a
|
|
104
|
+
* promise the router handed unread that was already settled (`needless`).
|
|
105
|
+
* Any other fallback is the content's own (an app's use(), a React.lazy, a
|
|
106
|
+
* client reference) and is counted as `unattributedFallbacks`, not reported,
|
|
107
|
+
* also when the boundary holds a promise React has read.
|
|
108
|
+
*
|
|
109
|
+
* A fallback over content on screen while something is pending is counted
|
|
110
|
+
* (`shownWhilePending`) and not reported: an urgent commit does that by
|
|
111
|
+
* design (transition({ when }) gated off, #995), and so does dev while a
|
|
112
|
+
* client reference loads.
|
|
113
|
+
*/
|
|
114
|
+
export declare function auditFallback(rec: BoundaryAudit): () => void;
|
|
115
|
+
/** One renderSegments call, collected while it builds. */
|
|
116
|
+
export interface TreeAudit {
|
|
117
|
+
/** Segment ids, leaf first while building, root first once finished. */
|
|
118
|
+
order: string[];
|
|
119
|
+
keys: Map<string, string>;
|
|
120
|
+
types: Map<string, string>;
|
|
121
|
+
chains: Map<string, string[]>;
|
|
122
|
+
/** Segments this tree remounts by the documented rules. */
|
|
123
|
+
replaced: Set<string>;
|
|
124
|
+
/** The segment objects the tree is built from (I7), until it is held. */
|
|
125
|
+
segments: object[];
|
|
126
|
+
}
|
|
127
|
+
export declare function startTreeAudit(): TreeAudit | undefined;
|
|
128
|
+
/** The element renderSegments built for one segment, leaf first. */
|
|
129
|
+
export declare function auditSegmentElement(tree: TreeAudit | undefined, id: string, type: string, key: string, element: unknown, outletTransition: boolean, slots: readonly string[], segments: readonly object[]): void;
|
|
130
|
+
/**
|
|
131
|
+
* A finished tree. The first is the document's, which React holds from
|
|
132
|
+
* hydration; any later one is held when an emit hands its root to React
|
|
133
|
+
* (auditTreeUpdate).
|
|
134
|
+
*/
|
|
135
|
+
export declare function finishTreeAudit(tree: TreeAudit | undefined, root: unknown): void;
|
|
136
|
+
/**
|
|
137
|
+
* I4: a boundary that stays on the page under the same React key is
|
|
138
|
+
* unmounted and mounted again. A different key is the documented remount.
|
|
139
|
+
*/
|
|
140
|
+
export declare function auditMount(rec: BoundaryAudit): void;
|
|
141
|
+
export declare function auditUnmount(rec: BoundaryAudit): void;
|
|
142
|
+
/**
|
|
143
|
+
* I6: the cause of the tree update the caller emits next, in the same task.
|
|
144
|
+
* It does not outlive the task: an emit after an await names its cause again,
|
|
145
|
+
* or a cause left behind would cover an emitter that names none.
|
|
146
|
+
*/
|
|
147
|
+
export declare function auditTreeCause(cause: TreeUpdateCause): void;
|
|
148
|
+
/**
|
|
149
|
+
* I6: a tree update reached React (the store.onUpdate subscriber in
|
|
150
|
+
* browser/react/NavigationProvider.tsx), with the root it hands React. Only a
|
|
151
|
+
* navigation, a back/forward, its stale revalidation, an action, an error and
|
|
152
|
+
* HMR hand React a tree; anything else updates in place through a store its
|
|
153
|
+
* readers subscribe to, or through a pending promise read with use().
|
|
154
|
+
*/
|
|
155
|
+
export declare function auditTreeUpdate(root?: unknown): void;
|
|
156
|
+
/** Forget every tree and mount seen so far. For tests of the audit itself. */
|
|
157
|
+
export declare function forgetSuspenseAudit(): void;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createActionForm: the FormData a browser posts when a form is submitted
|
|
3
|
+
* before hydration (no JavaScript), for a server action.
|
|
4
|
+
*
|
|
5
|
+
* React's server render writes hidden fields on the form so the POST names its
|
|
6
|
+
* action and carries the bound state; decodeAction / decodeFormState read them
|
|
7
|
+
* back. A test cannot render those fields (react-dom/server does not load under
|
|
8
|
+
* the react-server condition), so this builds the same wire format and
|
|
9
|
+
* registers the action where the plugin-rsc stub's decodeAction resolves it,
|
|
10
|
+
* tagged as a server reference like a built "use server" export so the bound
|
|
11
|
+
* action keeps its `$$id` (onError's actionId, the action phase label).
|
|
12
|
+
* Post the result with `serveShellRequest(router, url, { form })`.
|
|
13
|
+
*/
|
|
14
|
+
/** Options for {@link createActionForm}. */
|
|
15
|
+
export interface CreateActionFormOptions {
|
|
16
|
+
/**
|
|
17
|
+
* The action's reference id, `<module id>#<export name>`, as the build gives
|
|
18
|
+
* a "use server" export. Any unique string of that shape in a test.
|
|
19
|
+
*/
|
|
20
|
+
id: string;
|
|
21
|
+
/**
|
|
22
|
+
* A `useActionState` form (default): the action runs as `(prevState, formData)`
|
|
23
|
+
* and the POST carries the state key. false: a plain `<form action={fn}>`
|
|
24
|
+
* ($ACTION_ID_), the action runs as `(formData)`.
|
|
25
|
+
*/
|
|
26
|
+
useActionState?: boolean;
|
|
27
|
+
/** The form's own fields, as the person filled them. */
|
|
28
|
+
fields?: Record<string, string>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Build a no-JS form POST body for `action` and register it so a handler
|
|
32
|
+
* decodes it back to `action`.
|
|
33
|
+
*/
|
|
34
|
+
export declare function createActionForm(action: (...args: any[]) => unknown, options: CreateActionFormOptions): FormData;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type RouterVersions } from "../router-versions.js";
|
|
2
|
+
export type { RouterVersions };
|
|
3
|
+
/**
|
|
4
|
+
* The versions a simulated build ships.
|
|
5
|
+
*
|
|
6
|
+
* - `data` and `document`: the versions of every router the test does not list
|
|
7
|
+
* under `routers` (the build's whole-build pair).
|
|
8
|
+
* - `routers`: versions per router id (`router.id`), as a host-router build
|
|
9
|
+
* computes them.
|
|
10
|
+
*/
|
|
11
|
+
export interface BuildVersions extends RouterVersions {
|
|
12
|
+
routers?: Record<string, RouterVersions>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Install the cache versions of a simulated build, or remove them with no
|
|
16
|
+
* argument (routers serve unversioned again, the default in tests).
|
|
17
|
+
*
|
|
18
|
+
* A router that sets `createRouter({ version })` keeps that value for both
|
|
19
|
+
* versions, exactly as in production.
|
|
20
|
+
*
|
|
21
|
+
* @example A deploy that changes the client only keeps cached data
|
|
22
|
+
* ```ts
|
|
23
|
+
* setBuildVersions({ data: "d1", document: "h1" });
|
|
24
|
+
* await serveShellRequest(router, "/product/1", { cacheStore });
|
|
25
|
+
* setBuildVersions({ data: "d1", document: "h2" });
|
|
26
|
+
* const { shellStatus } = await serveShellRequest(router, "/product/1", {
|
|
27
|
+
* cacheStore,
|
|
28
|
+
* });
|
|
29
|
+
* // shellStatus is "MISS": the stored HTML was keyed by document version h1.
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export declare function setBuildVersions(versions?: BuildVersions): void;
|
|
@@ -12,4 +12,4 @@
|
|
|
12
12
|
* (`happy-dom` or `jsdom`).
|
|
13
13
|
*/
|
|
14
14
|
export { renderRoute } from "./render-route.js";
|
|
15
|
-
export type { RenderRouteSpec, RenderRouteOptions, TestRouterHandle, RenderRouteResult, HandleDataSeed, } from "./render-route.js";
|
|
15
|
+
export type { RenderRouteSpec, RenderRouteOptions, TestRouterHandle, RenderRouteResult, RenderRouteHydrateResult, HandleDataSeed, } from "./render-route.js";
|