@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
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* settleGrowing). When waitUntil is unavailable, falls back to blocking or
|
|
7
7
|
* skipping.
|
|
8
8
|
*/
|
|
9
|
+
import type { ExecutionContext } from "../types/request-scope.js";
|
|
9
10
|
interface WaitUntilHost {
|
|
10
11
|
waitUntil?: (fn: () => Promise<void>) => void;
|
|
11
12
|
}
|
|
@@ -40,4 +41,25 @@ export declare function raceDeadline<T>(work: Promise<T>, deadline: number): Pro
|
|
|
40
41
|
* mutates `list`: a later call waits for what is still pending.
|
|
41
42
|
*/
|
|
42
43
|
export declare function settleGrowing(list: readonly Promise<unknown>[], deadline: number): Promise<boolean>;
|
|
44
|
+
/** Macrotask turns `awaitLaterMillisecond` waits at most. */
|
|
45
|
+
export declare const LATER_MILLISECOND_MAX_TURNS = 10;
|
|
46
|
+
/**
|
|
47
|
+
* Yield until `Date.now()` passes `since`, so a store's whole-millisecond tag
|
|
48
|
+
* gate (putShell vs an invalidation made just before) sees a later
|
|
49
|
+
* millisecond. Bounded: on Cloudflare the clock stands still between I/O
|
|
50
|
+
* events, so an unbounded wait could hang. At the bound the caller proceeds
|
|
51
|
+
* and a store may refuse the write, which its result reports.
|
|
52
|
+
*/
|
|
53
|
+
export declare function awaitLaterMillisecond(since: number, maxTurns?: number): Promise<void>;
|
|
54
|
+
/** An ExecutionContext that keeps every promise handed to `waitUntil`. */
|
|
55
|
+
export interface CollectingExecutionContext extends ExecutionContext {
|
|
56
|
+
readonly tasks: Promise<unknown>[];
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Wrap the caller's ExecutionContext (or none) so a caller can wait for the
|
|
60
|
+
* request's background work: the deferred cache writes, the shell capture, a
|
|
61
|
+
* store's own writes. Every other member reads through to `inner`, bound to
|
|
62
|
+
* it (workerd's methods reject a foreign `this`).
|
|
63
|
+
*/
|
|
64
|
+
export declare function createCollectingExecutionContext(inner?: ExecutionContext): CollectingExecutionContext;
|
|
43
65
|
export {};
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* Used by cache-runtime, cache-scope, document-cache, and loader-cache.
|
|
7
7
|
*/
|
|
8
8
|
import type { SearchParamsFilter } from "./search-params-filter.js";
|
|
9
|
+
export declare function isReservedSearchParam(key: string): boolean;
|
|
9
10
|
/**
|
|
10
11
|
* Build a sorted, deterministic query string from URLSearchParams,
|
|
11
12
|
* excluding the router's reserved params (see isReservedSearchParam).
|
|
@@ -27,11 +28,40 @@ export declare function sortedSearchString(searchParams: URLSearchParams, filter
|
|
|
27
28
|
*/
|
|
28
29
|
export declare function sortedRouteParams(params: Record<string, string> | undefined): string;
|
|
29
30
|
/**
|
|
30
|
-
*
|
|
31
|
+
* THE ROUTER RULE (#1065). A key that names one router's output for a host
|
|
32
|
+
* and path starts with the router part, `{encodeURIComponent(routerId)}@`. A
|
|
33
|
+
* key that names a function and its arguments, or a tag, does not.
|
|
31
34
|
*
|
|
32
|
-
*
|
|
33
|
-
* (
|
|
34
|
-
*
|
|
35
|
+
* - With the part: PPR shells and the build-shell manifest (buildShellKey,
|
|
36
|
+
* buildShellManifestKey); route cache() records, the document cache and
|
|
37
|
+
* response routes (cacheKeyBase); a loader's own cache() entry; a
|
|
38
|
+
* `"use cache"` entry of a call that takes a ctx (a ctx is one router's:
|
|
39
|
+
* its variables, env and reverse() map).
|
|
40
|
+
* - Without: a `"use cache"` entry of plain arguments or a bare Request
|
|
41
|
+
* (requestArgKey); tag markers; a key the app builds itself
|
|
42
|
+
* (`cache({ key })`, a `keyGenerator`).
|
|
43
|
+
*
|
|
44
|
+
* Why: a host and path do not name a router. A `hostOverride` cookie picks
|
|
45
|
+
* the router and forwards the request unmodified, and a `router.prerender()`
|
|
46
|
+
* warm requests whatever origin it resolved, so two routers on one store
|
|
47
|
+
* built one key and read each other's entry.
|
|
48
|
+
*
|
|
49
|
+
* The id (router.ts) has to be the same in every isolate and in build-time
|
|
50
|
+
* discovery: an explicit `id` and the injected `$$id` are, the `router_{n}`
|
|
51
|
+
* fallback is for a single router only (discover-routers.ts warns about
|
|
52
|
+
* more). Encoded, the id holds no `@` or `/`, and a host holds no `@`, so a
|
|
53
|
+
* key has a router part exactly when its first `@` comes before its first
|
|
54
|
+
* `/`: no id can be chosen to spell another router's key.
|
|
55
|
+
*/
|
|
56
|
+
export declare function routerKeyPrefix(routerId: string): string;
|
|
57
|
+
/**
|
|
58
|
+
* Key base of one router's output (the router rule, routerKeyPrefix):
|
|
59
|
+
* `${routerId}@${host}${pathname}[:params][?search]`.
|
|
60
|
+
*
|
|
61
|
+
* The ONE composition of the namespacing rule, shared by the segment tier
|
|
62
|
+
* (cache-scope.ts), the document tier (document-cache.ts), the response tier
|
|
63
|
+
* (rsc/response-cache-serve.ts) and the loader cache so the rule cannot drift
|
|
64
|
+
* between them. Host prefixing matters because VercelCacheStore /
|
|
35
65
|
* MemorySegmentCacheStore key by the raw string (only CFCacheStore adds host
|
|
36
66
|
* internally) -- on a single function serving multiple domains an
|
|
37
67
|
* un-namespaced key bleeds tenant A's cached response to tenant B.
|
|
@@ -40,7 +70,22 @@ export declare function sortedRouteParams(params: Record<string, string> | undef
|
|
|
40
70
|
* invalidates every persisted cache entry on upgrade. Callers append their own
|
|
41
71
|
* tier-specific suffixes (`:rsc`/`:html`, segment hash) after this base.
|
|
42
72
|
*/
|
|
43
|
-
export declare function cacheKeyBase(host: string, pathname: string, searchParams?: URLSearchParams, params?: Record<string, string>, filter?: SearchParamsFilter): string;
|
|
73
|
+
export declare function cacheKeyBase(routerId: string, host: string, pathname: string, searchParams?: URLSearchParams, params?: Record<string, string>, filter?: SearchParamsFilter): string;
|
|
74
|
+
/**
|
|
75
|
+
* cacheKeyBase for the request context `ctx`. rsc/handler.ts sets `_routerId`
|
|
76
|
+
* before the request scope opens and derived contexts inherit it, so a served
|
|
77
|
+
* request always has one. Only a hand-built context has none (a unit test,
|
|
78
|
+
* the runLoader / renderHandler primitives): its key has no router part,
|
|
79
|
+
* which no router's key equals (routerKeyPrefix).
|
|
80
|
+
*/
|
|
81
|
+
export declare function requestKeyBase(ctx: {
|
|
82
|
+
readonly _routerId?: string;
|
|
83
|
+
} | null | undefined, host: string, pathname: string, searchParams?: URLSearchParams, params?: Record<string, string>, filter?: SearchParamsFilter): string;
|
|
84
|
+
/**
|
|
85
|
+
* The `"use cache"` key part of a bare Request argument: its URL, with no
|
|
86
|
+
* router part (the router rule, routerKeyPrefix).
|
|
87
|
+
*/
|
|
88
|
+
export declare function requestArgKey(url: URL, filter?: SearchParamsFilter): string;
|
|
44
89
|
/**
|
|
45
90
|
* The prefix of a `key()` result's part in a record key (#975), and of a
|
|
46
91
|
* loader's own `key()` result after its `loader:<id>:` namespace (#1009,
|
|
@@ -7,6 +7,14 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { CacheDefaults, SegmentCacheStore } from "./types.js";
|
|
9
9
|
import type { RequestContext } from "../server/request-context.js";
|
|
10
|
+
/**
|
|
11
|
+
* How long a follower trusts an in-flight leader before evicting it and
|
|
12
|
+
* running fresh. High enough that a slow-but-healthy upstream never triggers
|
|
13
|
+
* duplicate work (a legitimate cached call taking >15s is already pathological);
|
|
14
|
+
* low enough to bound the blast radius of a wedged leader to seconds, not the
|
|
15
|
+
* isolate lifetime. Aligned with SHELL_CAPTURE_MAX_WAIT_MS.
|
|
16
|
+
*/
|
|
17
|
+
export declare const IN_FLIGHT_LEADER_MAX_WAIT_MS = 15000;
|
|
10
18
|
/**
|
|
11
19
|
* Default TTL for route-level cache() DSL and loader cache.
|
|
12
20
|
* Applied when neither the cache options nor the store defaults specify a TTL.
|
|
@@ -73,4 +81,13 @@ export declare function computeExpiration(ttlSeconds: number, swrSeconds?: numbe
|
|
|
73
81
|
};
|
|
74
82
|
export declare function resolveCacheKey(keyFn: ((ctx: RequestContext) => string | Promise<string>) | undefined, store: SegmentCacheStore | null, defaultKey: string): Promise<string>;
|
|
75
83
|
export declare function resolveTagsOption<TEnv>(tags: string[] | ((ctx: RequestContext<TEnv>) => string[]) | undefined, ctx: RequestContext<TEnv> | undefined, label: string): string[] | undefined;
|
|
84
|
+
/**
|
|
85
|
+
* Normalize a resolved tags array so the WRITE path matches the invalidate path:
|
|
86
|
+
* updateTag()/revalidateTag()/cacheTag() all drop empty/whitespace-only tags via
|
|
87
|
+
* normalizeTag(). Without this, an empty tag attached at write time would enter
|
|
88
|
+
* the store index but could never be invalidated (the verbs normalize it away),
|
|
89
|
+
* and on CFCacheStore would also cost a wasted KV marker read per request.
|
|
90
|
+
* Returns undefined when nothing usable remains, keeping the entry header-free.
|
|
91
|
+
*/
|
|
92
|
+
export declare function normalizeTagList(tags: string[]): string[] | undefined;
|
|
76
93
|
export declare function resolveCacheStore(explicitStore: SegmentCacheStore | undefined): SegmentCacheStore | null;
|
|
@@ -286,11 +286,10 @@ export declare class CacheScope {
|
|
|
286
286
|
* @param pathname - URL pathname for cache key generation
|
|
287
287
|
* @param params - Route params for cache key generation
|
|
288
288
|
* @param isIntercept - Whether this is an intercept navigation (uses different cache key)
|
|
289
|
-
* @param ownedPushes -
|
|
290
|
-
* loader-
|
|
291
|
-
* _claimLoaderPushes, and on a document HIT tail the owners it restores)
|
|
289
|
+
* @param ownedPushes - What the record is to each loader's handle pushes
|
|
290
|
+
* (withCacheLookup: loader-cache.ts loaderPins), called on a hit
|
|
292
291
|
*/
|
|
293
|
-
lookupRoute(pathname: string, params: Record<string, string>, isIntercept?: boolean, ownedPushes?: OwnedPushDelivery): Promise<{
|
|
292
|
+
lookupRoute(pathname: string, params: Record<string, string>, isIntercept?: boolean, ownedPushes?: () => OwnedPushDelivery): Promise<{
|
|
294
293
|
segments: ResolvedSegment[];
|
|
295
294
|
shouldRevalidate: boolean;
|
|
296
295
|
} | null>;
|
|
@@ -312,7 +311,7 @@ export declare class CacheScope {
|
|
|
312
311
|
* A corrupt entry that was evicted reads as `miss`: the store was consulted
|
|
313
312
|
* and holds nothing servable, which is the post-eviction truth.
|
|
314
313
|
*/
|
|
315
|
-
lookupRouteDetailed(pathname: string, params: Record<string, string>, isIntercept?: boolean, ownedPushes?: OwnedPushDelivery): Promise<CacheRouteLookupOutcome>;
|
|
314
|
+
lookupRouteDetailed(pathname: string, params: Record<string, string>, isIntercept?: boolean, ownedPushes?: () => OwnedPushDelivery): Promise<CacheRouteLookupOutcome>;
|
|
316
315
|
/**
|
|
317
316
|
* Record this scope's segment-DSL cache({ tags }) into the request tag union
|
|
318
317
|
* synchronously, under the same gate cacheRoute() uses for a write.
|
|
@@ -357,7 +356,7 @@ export declare class CacheScope {
|
|
|
357
356
|
* enclosing scopes on another store (#974) and of a scope without its own
|
|
358
357
|
* `key()` (#970)); with none, the app store's keyGenerator result
|
|
359
358
|
* given the document default key. Undefined (synchronously, with no work)
|
|
360
|
-
* when neither applies: the shell key stays
|
|
359
|
+
* when neither applies: the shell key stays unpartitioned (buildShellKey).
|
|
361
360
|
* Resolves to null when the partition is the default key itself (a
|
|
362
361
|
* keyGenerator that returns it unchanged): that partitions nothing, so the
|
|
363
362
|
* shell stays unpartitioned and keeps its build shell. The shell's key, its
|
|
@@ -3,7 +3,7 @@ declare global {
|
|
|
3
3
|
readonly default: Cache;
|
|
4
4
|
}
|
|
5
5
|
}
|
|
6
|
-
import type { SegmentCacheStore, CachedEntryData, CacheDefaults, CacheGetResult, CacheItemResult, CacheItemOptions, ShellCacheEntry, ShellDocumentRead, ShellDocumentReadOptions, CacheReadError } from "../types.js";
|
|
6
|
+
import type { CacheStoreScope, SegmentCacheStore, CachedEntryData, CacheDefaults, CacheGetResult, CacheItemResult, CacheItemOptions, ShellCacheEntry, ShellDocumentRead, ShellDocumentReadOptions, CacheReadError } from "../types.js";
|
|
7
7
|
import { type RequestContext } from "../../server/request-context.js";
|
|
8
8
|
import { CACHE_STALE_AT_HEADER, CACHE_STATUS_HEADER, CACHE_TAGS_HEADER, CACHE_TAGGED_AT_HEADER, TAG_MARKER_PREFIX, CACHE_REVALIDATING_AT_HEADER, MAX_REVALIDATION_INTERVAL, EDGE_LOOKUP_TIMEOUT_MS, EDGE_READ_TIMEOUT_MS, KV_READ_TIMEOUT_MS } from "./cf-cache-constants.js";
|
|
9
9
|
export { CACHE_STALE_AT_HEADER, CACHE_STATUS_HEADER, CACHE_TAGS_HEADER, CACHE_TAGGED_AT_HEADER, TAG_MARKER_PREFIX, CACHE_REVALIDATING_AT_HEADER, MAX_REVALIDATION_INTERVAL, EDGE_LOOKUP_TIMEOUT_MS, EDGE_READ_TIMEOUT_MS, KV_READ_TIMEOUT_MS, };
|
|
@@ -21,7 +21,8 @@ export declare class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<T
|
|
|
21
21
|
private readonly namespace?;
|
|
22
22
|
private readonly explicitBaseUrl?;
|
|
23
23
|
private readonly waitUntil?;
|
|
24
|
-
|
|
24
|
+
/** The `version` option: used for every versioned family when set. */
|
|
25
|
+
private readonly explicitVersion?;
|
|
25
26
|
private readonly edgeLookupTimeoutMs;
|
|
26
27
|
private readonly edgeReadTimeoutMs;
|
|
27
28
|
private readonly kvReadTimeoutMs;
|
|
@@ -42,6 +43,12 @@ export declare class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<T
|
|
|
42
43
|
private readonly kv?;
|
|
43
44
|
/** True when constructed without KV: no durable tag history (see ctor). */
|
|
44
45
|
readonly tagHistoryInert?: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* SegmentCacheStore.scope: with KV every colo's L1 miss reads the same L2
|
|
48
|
+
* entry ("global"); without it entries live in one colo's Cache API
|
|
49
|
+
* ("local"), purge mode included (a purge evicts, it stores nothing).
|
|
50
|
+
*/
|
|
51
|
+
readonly scope: CacheStoreScope;
|
|
45
52
|
private readonly onRevalidateTag?;
|
|
46
53
|
private readonly tagPurge?;
|
|
47
54
|
private readonly tagInvalidationTtl?;
|
|
@@ -327,9 +334,12 @@ export declare class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<T
|
|
|
327
334
|
* on the same context) read their markers as before.
|
|
328
335
|
*/
|
|
329
336
|
private recordShellHit;
|
|
330
|
-
/**
|
|
337
|
+
/**
|
|
338
|
+
* The isolate marker memo's key for a tag: markers are per namespace, and
|
|
339
|
+
* shared by every version (tagMarkerKey).
|
|
340
|
+
*/
|
|
331
341
|
private markerMemoKey;
|
|
332
|
-
/** The memo key: one per namespace,
|
|
342
|
+
/** The memo key: one per namespace, document version, base URL, and shell key. */
|
|
333
343
|
private shellMemoKey;
|
|
334
344
|
/**
|
|
335
345
|
* Serve a memoized shell (shell-memo.ts). The tag-marker check is the only
|
|
@@ -400,9 +410,16 @@ export declare class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<T
|
|
|
400
410
|
private kvReadShellDocument;
|
|
401
411
|
/** Promote a valid KV shell into the per-colo Cache API tier. */
|
|
402
412
|
private promoteShellToL1;
|
|
413
|
+
private shellRequest;
|
|
414
|
+
private shellKVKey;
|
|
403
415
|
/**
|
|
404
416
|
* Convert string key to Request object for CF Cache API.
|
|
405
|
-
*
|
|
417
|
+
*
|
|
418
|
+
* `family` picks the version in the URL path, so a version change misses:
|
|
419
|
+
* `"data"` for segment entries and `fn:` items (cached RSC data, valid while
|
|
420
|
+
* the router's server code is unchanged), `"document"` for `doc:` responses
|
|
421
|
+
* and `shell2:` shells (their bytes carry asset URLs and the handler
|
|
422
|
+
* version), `null` for tag markers, which apply to every version.
|
|
406
423
|
* @internal
|
|
407
424
|
*/
|
|
408
425
|
private keyToRequest;
|
|
@@ -477,7 +494,13 @@ export declare class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<T
|
|
|
477
494
|
* @internal
|
|
478
495
|
*/
|
|
479
496
|
private kvGetOrEvict;
|
|
480
|
-
/**
|
|
497
|
+
/**
|
|
498
|
+
* KV key for a tag's invalidation marker. Unversioned: a content-hash
|
|
499
|
+
* version can come back (deploy A, deploy B, roll back to A), and a marker
|
|
500
|
+
* written while B was live has to be visible to A's entries. The staleness
|
|
501
|
+
* check compares the marker time with the entry's taggedAt and nothing else
|
|
502
|
+
* (isGloballyInvalidated), so one marker per tag serves every version.
|
|
503
|
+
*/
|
|
481
504
|
private tagMarkerKey;
|
|
482
505
|
/**
|
|
483
506
|
* Header entries carrying an entry's tags (JSON-encoded, comma-safe) and the
|
|
@@ -554,7 +577,11 @@ export declare class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<T
|
|
|
554
577
|
* @internal
|
|
555
578
|
*/
|
|
556
579
|
private isL1Invalidated;
|
|
557
|
-
/**
|
|
580
|
+
/**
|
|
581
|
+
* Synthetic Cache API request for a tag's L1-cached invalidation marker.
|
|
582
|
+
* Unversioned for the same reason as tagMarkerKey; the cache namespace
|
|
583
|
+
* (getCache) still scopes it.
|
|
584
|
+
*/
|
|
558
585
|
private tagMarkerRequest;
|
|
559
586
|
/**
|
|
560
587
|
* Read a tag's latest invalidation timestamp (or null if never invalidated)
|
|
@@ -276,11 +276,19 @@ export interface CFCacheStoreOptions<TEnv = unknown> {
|
|
|
276
276
|
*/
|
|
277
277
|
tagCacheTtl?: number;
|
|
278
278
|
/**
|
|
279
|
-
* Cache version string override. When this
|
|
280
|
-
*
|
|
279
|
+
* Cache version string override. When set, this exact value prefixes every
|
|
280
|
+
* versioned key the store writes (`v/{version}/...`), for cached data and
|
|
281
|
+
* stored HTML alike; changing it makes every earlier entry unreachable.
|
|
281
282
|
*
|
|
282
|
-
*
|
|
283
|
-
*
|
|
283
|
+
* Leave it unset for the default: the store keys with the versions of the
|
|
284
|
+
* router serving the request. Segment entries and `"use cache"` items use
|
|
285
|
+
* the router's data version; document responses and PPR shells use its
|
|
286
|
+
* document version (see `createRouter({ version })`). Those are computed
|
|
287
|
+
* from the router's built code, so a deploy that does not change the router
|
|
288
|
+
* keeps its entries.
|
|
289
|
+
*
|
|
290
|
+
* Tag invalidation markers are never versioned: an invalidation applies to
|
|
291
|
+
* the entries of every version, including one that comes back in a rollback.
|
|
284
292
|
*/
|
|
285
293
|
version?: string;
|
|
286
294
|
/**
|
|
@@ -31,11 +31,14 @@ export interface DocumentCacheOptions<TEnv = any> {
|
|
|
31
31
|
/**
|
|
32
32
|
* Custom cache key generator.
|
|
33
33
|
*
|
|
34
|
-
* Replaces the default `host + pathname + search` key entirely.
|
|
35
|
-
* multi-domain deployment served by one function you MUST include
|
|
36
|
-
* (or an equivalent tenant discriminator) yourself — the default
|
|
37
|
-
* host-namespaced, but a custom generator's output is used verbatim,
|
|
38
|
-
* omitting host bleeds one hostname's cached response to another.
|
|
34
|
+
* Replaces the default `router id + host + pathname + search` key entirely.
|
|
35
|
+
* On a multi-domain deployment served by one function you MUST include
|
|
36
|
+
* `url.host` (or an equivalent tenant discriminator) yourself — the default
|
|
37
|
+
* key is host-namespaced, but a custom generator's output is used verbatim,
|
|
38
|
+
* so omitting host bleeds one hostname's cached response to another. The
|
|
39
|
+
* same goes for the router: two routers that share a cache store and can
|
|
40
|
+
* serve one host and path (a `hostOverride` cookie) need a generator that
|
|
41
|
+
* tells them apart.
|
|
39
42
|
*/
|
|
40
43
|
keyGenerator?: (url: URL) => string;
|
|
41
44
|
/**
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* during segment resolution and stored alongside cached segments.
|
|
7
7
|
*/
|
|
8
8
|
import type { ResolvedSegment } from "../types.js";
|
|
9
|
-
import type { HandleStore } from "../server/handle-store.js";
|
|
9
|
+
import type { HandleStore, RecordAuthority } from "../server/handle-store.js";
|
|
10
10
|
import type { HandleOwners, SegmentHandleData } from "./types.js";
|
|
11
11
|
type HandleRecord = Record<string, SegmentHandleData>;
|
|
12
12
|
/**
|
|
@@ -44,54 +44,50 @@ export declare function decodeHandleValue<T>(encoded: string): Promise<T | null>
|
|
|
44
44
|
export declare function captureHandles(segments: ResolvedSegment[], handleStore: HandleStore): Record<string, SegmentHandleData>;
|
|
45
45
|
/** The owners of captureHandles' values; undefined when none is owned. */
|
|
46
46
|
export declare function captureHandleOwners(segments: ResolvedSegment[], handleStore: HandleStore): HandleOwners | undefined;
|
|
47
|
-
/**
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
*/
|
|
67
|
-
restore?: boolean;
|
|
68
|
-
}
|
|
47
|
+
/**
|
|
48
|
+
* captureHandles and captureHandleOwners cut down to the handle arrays that
|
|
49
|
+
* hold an owned value, each whole (its unowned values too, in place), so
|
|
50
|
+
* restoreHandles rebuilds exactly those arrays over a store that already
|
|
51
|
+
* holds the rest. A prerender-served shell capture stores this: the
|
|
52
|
+
* prerender store restores the handler pushes on a HIT, and the loader
|
|
53
|
+
* pushes have no other record (shell-capture.ts captureAndStoreShell).
|
|
54
|
+
*/
|
|
55
|
+
export declare function captureOwnedHandles(handleStore: HandleStore): {
|
|
56
|
+
handles: HandleRecord;
|
|
57
|
+
owners?: HandleOwners;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* What the record being restored is to each loader's handle pushes on this
|
|
61
|
+
* request (HandleStore RecordAuthority). Built by loaderPins (loader-cache.ts)
|
|
62
|
+
* over the pins resolveLoaderData serves a loader's value from, so a value
|
|
63
|
+
* and its record copies get one answer.
|
|
64
|
+
*/
|
|
65
|
+
export type OwnedPushDelivery = (loaderId: string) => RecordAuthority;
|
|
69
66
|
/**
|
|
70
67
|
* Restore handle data from a cached snapshot into the handle store.
|
|
71
68
|
* Used when serving cached segments to replay their handle data: a route
|
|
72
69
|
* cache() record owns its segments' arrays, so it REPLACES them.
|
|
73
70
|
*
|
|
74
71
|
* A segment with `owners` is replaced with empty arrays and re-pushed in
|
|
75
|
-
* recorded order
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
* restores as a plain replay.
|
|
82
|
-
*
|
|
83
|
-
* `owned.restore`: a document HIT tail restoring the shell's doc record
|
|
84
|
-
* (withCacheLookup). A bake-lane owner's values are the prelude's, so they go
|
|
85
|
-
* through pushRestored and stand: a run of that loader on the HIT (a
|
|
86
|
-
* promise-carrying `ssr: false` loader, one whose record asks for a run)
|
|
87
|
-
* reads the store, and its settled pushes are dropped, not swapped in.
|
|
88
|
-
* Nothing is claimed, so the loader's own cache() HIT still replays the
|
|
89
|
-
* pushes the record could not keep (the thenable ones pushRestored lets
|
|
90
|
-
* through). A loader the route also runs on the live lane is a hole: its
|
|
91
|
-
* values keep pushReplayed, unclaimed, and its live run replaces them
|
|
92
|
-
* (#936), even inside a restored loader's body (`owned.liveLane`).
|
|
72
|
+
* recorded order. A loader-owned value stands (pushRestored) where `owned`
|
|
73
|
+
* says the record supplies that loader's value too ("pin", "copies"), and is
|
|
74
|
+
* a placeholder (pushPlaceholder) everywhere else: without `owned`, every
|
|
75
|
+
* owner. Neither claims its loader, so the loader's own cache() HIT still
|
|
76
|
+
* delivers (the thenable pushes a restored copy lets through, or its entry's
|
|
77
|
+
* pushes in a placeholder's place).
|
|
93
78
|
*/
|
|
94
79
|
export declare function restoreHandles(handles: Record<string, SegmentHandleData>, handleStore: HandleStore, owners?: HandleOwners, owned?: OwnedPushDelivery): void;
|
|
80
|
+
/**
|
|
81
|
+
* Serve a doc record's handles: set its authority over the loaders' pushes
|
|
82
|
+
* (with or without a handles blob: a pinned loader whose capture pushed
|
|
83
|
+
* nothing has no copy, and its run must still add no settled push), then
|
|
84
|
+
* decode and restoreHandles. `keepIds` limits the restore to the segments a
|
|
85
|
+
* boundary-scoped scope serves. A decode failure skips the restore.
|
|
86
|
+
*/
|
|
87
|
+
export declare function restoreRecordHandles(handleStore: HandleStore, record: {
|
|
88
|
+
handles?: string;
|
|
89
|
+
handleOwners?: HandleOwners;
|
|
90
|
+
}, owned: OwnedPushDelivery | undefined, keepIds?: ReadonlySet<string>): Promise<void>;
|
|
95
91
|
/**
|
|
96
92
|
* Append recorded handle pushes to the store, in recorded order, via push()
|
|
97
93
|
* so active captures and loader-scope tagging see them like live pushes. For
|
|
@@ -99,14 +95,27 @@ export declare function restoreHandles(handles: Record<string, SegmentHandleData
|
|
|
99
95
|
* restoreHandles would wipe those. `segmentId` redirects every value to one
|
|
100
96
|
* segment (the caller's).
|
|
101
97
|
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
98
|
+
* The replay of every cached unit that records by owner: a "use cache"
|
|
99
|
+
* function (useCacheRecordKey) and a loader's own cache() (loader-cache.ts
|
|
100
|
+
* recordOwnerKey, with `unitLoader` the cached loader).
|
|
101
|
+
*
|
|
102
|
+
* A `${seq}:${loaderId}` group is that loader's pushes, which reach the page
|
|
103
|
+
* once per request: `claim` (setupLoaderAccess _claimLoaderPushes) is asked
|
|
104
|
+
* once per loader and skips one that already ran or was replayed in this
|
|
105
|
+
* request; a claimed loader that runs later replaces its replayed values
|
|
106
|
+
* (HandleStore.pushReplayed). A group without an owner (`${seq}:`, or a key
|
|
107
|
+
* without ":" from a record written before owner keys, which is a segment
|
|
108
|
+
* id) is the unit's own: `unitLoader`'s, or no loader's for a function,
|
|
109
|
+
* whose pushes are plain.
|
|
110
|
+
*
|
|
111
|
+
* The claimed loaders' placeholders give way to this delivery
|
|
112
|
+
* (HandleStore.replacePlaceholders), `unitLoader`'s even when the entry
|
|
113
|
+
* recorded no push for it: the entry stands for that loader's run.
|
|
114
|
+
*
|
|
115
|
+
* No `claim` means the caller's pushes are diverted off the page (a stale
|
|
116
|
+
* refresh: cache-runtime.ts refreshView, setupLoaderAccess
|
|
117
|
+
* _runLoaderIsolated): every group is delivered, into the diverting capture,
|
|
118
|
+
* and the page's placeholders stay, or the page would lose the push.
|
|
110
119
|
*/
|
|
111
|
-
export declare function appendHandles(handles: Record<string, SegmentHandleData>, handleStore: HandleStore, segmentId
|
|
120
|
+
export declare function appendHandles(handles: Record<string, SegmentHandleData>, handleStore: HandleStore, segmentId: string | undefined, claim: ((loaderId: string) => boolean) | undefined, unitLoader?: string): void;
|
|
112
121
|
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type { SegmentCacheStore, CachedEntryData, CacheGetResult, CacheItemResult, CacheItemOptions, ShellCacheEntry, SerializedSegmentData, SegmentHandleData, CacheReadError, } from "./types.js";
|
|
1
|
+
export type { SegmentCacheStore, CacheStoreScope, CachedEntryData, CacheGetResult, CacheItemResult, CacheItemOptions, ShellCacheEntry, SerializedSegmentData, SegmentHandleData, CacheReadError, } from "./types.js";
|
|
2
2
|
export { CACHE_READ_ERROR } from "./types.js";
|
|
3
3
|
export { MemorySegmentCacheStore } from "./memory-segment-store.js";
|
|
4
4
|
export type { StoreMemoOptions } from "./shell-memo.js";
|
|
@@ -8,3 +8,5 @@ export { TRACKING_SEARCH_PARAMS, type CacheSearchParams, } from "./search-params
|
|
|
8
8
|
export { CacheScope, createCacheScope } from "./cache-scope.js";
|
|
9
9
|
export { createDocumentCacheMiddleware, type DocumentCacheOptions, } from "./document-cache.js";
|
|
10
10
|
export type { CacheErrorCategory } from "./cache-error.js";
|
|
11
|
+
export { getCacheVersions } from "../server/build-version-table.js";
|
|
12
|
+
export type { RouterVersions } from "../router-versions.js";
|
|
@@ -8,6 +8,20 @@ export interface ExecutionStart {
|
|
|
8
8
|
readonly seq: number;
|
|
9
9
|
readonly at: number;
|
|
10
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* The `taggedAt` / `ta` stamp a store writes on a tagged data entry: the start
|
|
13
|
+
* of the execution that produced the value (`startedAt`), so a marker written
|
|
14
|
+
* while it ran rejects the entry on read (#1068). Write time when the writer
|
|
15
|
+
* knows no start. Never later than now: a start from a skewed clock must not
|
|
16
|
+
* stamp the future, which would make the entry look newer than every marker.
|
|
17
|
+
*/
|
|
18
|
+
export declare function entryStamp(startedAt: number | undefined): number;
|
|
19
|
+
/** The stamp of a data entry: `entryStamp` for a tagged entry, none otherwise. */
|
|
20
|
+
export declare function taggedStamp(tags: readonly string[] | undefined, startedAt: number | undefined): number | undefined;
|
|
21
|
+
/** Mark the execution start behind a Response handed to putResponse. */
|
|
22
|
+
export declare function markResponseStart(response: Response, start: ExecutionStart): Response;
|
|
23
|
+
/** The start a writer marked on `response`, if any. */
|
|
24
|
+
export declare function responseStartedAt(response: Response): number | undefined;
|
|
11
25
|
/** Record an execution's start, before it reads its data. */
|
|
12
26
|
export declare function executionStart(): ExecutionStart;
|
|
13
27
|
/**
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Simple in-memory implementation of SegmentCacheStore.
|
|
5
5
|
* Uses globalThis to survive HMR in development.
|
|
6
6
|
*/
|
|
7
|
-
import type { SegmentCacheStore, CachedEntryData, CacheDefaults, CacheGetResult, CacheItemResult, CacheItemOptions, ShellCacheEntry } from "./types.js";
|
|
7
|
+
import type { CacheStoreScope, SegmentCacheStore, CachedEntryData, CacheDefaults, CacheGetResult, CacheItemResult, CacheItemOptions, ShellCacheEntry } from "./types.js";
|
|
8
8
|
import type { RequestContext } from "../server/request-context.js";
|
|
9
9
|
/**
|
|
10
10
|
* Options for MemorySegmentCacheStore
|
|
@@ -70,6 +70,25 @@ export interface MemorySegmentCacheStoreOptions<TEnv = unknown> {
|
|
|
70
70
|
* ```
|
|
71
71
|
*/
|
|
72
72
|
maxEntries?: number;
|
|
73
|
+
/**
|
|
74
|
+
* Where an entry this store writes can be read; what `router.prerender()`
|
|
75
|
+
* checks before warming a route. Defaults to `"local"`: the maps live in one
|
|
76
|
+
* process, and the router cannot tell one long-running server from several
|
|
77
|
+
* replicas or serverless instances, so a warm into it is refused in
|
|
78
|
+
* production. Set `"global"` only when exactly one process serves the app
|
|
79
|
+
* (a single Node server); a warm then reports `warmed`. Under the Vite dev
|
|
80
|
+
* server a `"local"` instance already counts as shared.
|
|
81
|
+
*
|
|
82
|
+
* Like `defaults` and `keyGenerator`, the scope is per instance: two
|
|
83
|
+
* instances with the same `name` share their maps but each declares its own
|
|
84
|
+
* scope. Keep them identical.
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```typescript
|
|
88
|
+
* const store = new MemorySegmentCacheStore({ scope: "global" });
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
scope?: CacheStoreScope;
|
|
73
92
|
}
|
|
74
93
|
/**
|
|
75
94
|
* In-memory segment cache store.
|
|
@@ -106,6 +125,13 @@ export interface MemorySegmentCacheStoreOptions<TEnv = unknown> {
|
|
|
106
125
|
* ```
|
|
107
126
|
*/
|
|
108
127
|
export declare class MemorySegmentCacheStore<TEnv = unknown> implements SegmentCacheStore<TEnv> {
|
|
128
|
+
/**
|
|
129
|
+
* SegmentCacheStore.scope: "local" unless `options.scope` says otherwise, so
|
|
130
|
+
* router.prerender() refuses to warm into these maps in production. Under
|
|
131
|
+
* the Vite dev server the gate counts a "local" instance as shared
|
|
132
|
+
* (store-scope.ts resolveWarmStoreScope).
|
|
133
|
+
*/
|
|
134
|
+
readonly scope: CacheStoreScope;
|
|
109
135
|
readonly supportsPassiveShellReads: true;
|
|
110
136
|
private cache;
|
|
111
137
|
private responseCache;
|
|
@@ -151,6 +177,12 @@ export declare class MemorySegmentCacheStore<TEnv = unknown> implements SegmentC
|
|
|
151
177
|
} | null>;
|
|
152
178
|
putShell(key: string, entry: ShellCacheEntry, ttlSeconds?: number, swrSeconds?: number, tags?: string[]): Promise<"stored" | "invalidated">;
|
|
153
179
|
isTagsInvalidatedSince(tags: string[], sinceMs: number): Promise<boolean>;
|
|
180
|
+
/**
|
|
181
|
+
* A tag invalidated in a millisecond after the write's execution started
|
|
182
|
+
* (#1068). Strictly after: the start's own millisecond is ambiguous, and
|
|
183
|
+
* invalidation-order.ts orders those exactly.
|
|
184
|
+
*/
|
|
185
|
+
private invalidatedAfter;
|
|
154
186
|
private tagsInvalidatedSince;
|
|
155
187
|
invalidateTags(tags: string[]): Promise<void>;
|
|
156
188
|
private registerTags;
|
|
@@ -18,9 +18,11 @@
|
|
|
18
18
|
* the capture's copy of a value: it is dynamic or has its own cache. A
|
|
19
19
|
* bake-lane loader body that runs on a HIT reads the store too; its pinned
|
|
20
20
|
* container paths stay the pin's (overlayLoaderContainer), and its settled
|
|
21
|
-
* pushes stay the record's (HandleStore.pushRestored).
|
|
21
|
+
* pushes stay the record's (HandleStore.pushRestored). The two go together:
|
|
22
|
+
* a loader whose pin the entry lost runs fresh, and the record's copies of
|
|
23
|
+
* its pushes give way to that run's (restoreHandles).
|
|
22
24
|
*/
|
|
23
|
-
import type { SegmentCacheStore, CacheGetResult, CacheItemResult, CacheItemOptions, CachedEntryData, ShellCacheEntry, ShellSnapshotRecord, CacheReadError } from "./types.js";
|
|
25
|
+
import type { SegmentCacheStore, CacheGetResult, CacheItemResult, CacheItemOptions, CachedEntryData, ShellCacheEntry, ShellSnapshotRecord, ShellSnapshotHandlesValue, CacheReadError } from "./types.js";
|
|
24
26
|
/**
|
|
25
27
|
* A store wrapper the CAPTURE render reads through. Every call passes through
|
|
26
28
|
* to the underlying store unchanged; the one thing it records is the doc
|
|
@@ -172,22 +174,45 @@ export interface ShellLoaderSeedEntry {
|
|
|
172
174
|
* hole-free record: a hole-carrying one always runs.
|
|
173
175
|
*/
|
|
174
176
|
runs: boolean;
|
|
177
|
+
/**
|
|
178
|
+
* The capture that wrote the pin recorded every settled push of the
|
|
179
|
+
* loader's run in the doc record (CachedEntryData.handleOwners): the pin
|
|
180
|
+
* carries the `runs` bit, which captures write since they record those
|
|
181
|
+
* pushes (v0.18). A replay then drops any other settled push of the loader
|
|
182
|
+
* (HandleStore RecordAuthority "pin"). False for an older pin, whose record
|
|
183
|
+
* may hold none and leaves them to the run.
|
|
184
|
+
*/
|
|
185
|
+
complete: boolean;
|
|
175
186
|
}
|
|
176
187
|
/**
|
|
177
188
|
* Materialize the loader-family seed from a shell snapshot for a HIT's tail
|
|
178
189
|
* render: Flight-deserialize each recorded (promise-elided) bake-lane
|
|
179
|
-
* container into a
|
|
180
|
-
*
|
|
190
|
+
* container into a loader-id -> pin Map, which serveShellHit assigns to the
|
|
191
|
+
* tail context's `_shellLoaderSeed` (loader-cache.ts servedPins).
|
|
181
192
|
* Lives here so every snapshot family is decoded in this module (the segment
|
|
182
193
|
* family via {@link SeededShellStore}); the loader family is not a store
|
|
183
194
|
* read, so it seeds the context instead of a store.
|
|
184
195
|
*
|
|
196
|
+
* Keyed by loader, not by the segment a pin was stored under: a loader runs
|
|
197
|
+
* once per capture, so every segment that registers it pinned the same
|
|
198
|
+
* container, and the loader's value and its handle pushes are both looked up
|
|
199
|
+
* by loader. A key that does not parse pins nothing.
|
|
200
|
+
*
|
|
185
201
|
* Deserializations run in parallel; a record that fails to decode is skipped
|
|
186
202
|
* (that loader drifts — the pre-snapshot behavior — instead of failing the
|
|
187
203
|
* HIT). Returns undefined when the snapshot carries no loader records, without
|
|
188
204
|
* touching the Flight codec (kept lazy for cold paths and non-RSC configs).
|
|
189
205
|
*/
|
|
190
206
|
export declare function buildShellLoaderSeed(snapshot: ShellSnapshotRecord[]): Promise<Map<string, ShellLoaderSeedEntry> | undefined>;
|
|
207
|
+
/** The key of a snapshot's one `handles` record (ShellSnapshotHandlesValue). */
|
|
208
|
+
export declare const SHELL_HANDLES_RECORD_KEY = "handles";
|
|
209
|
+
/**
|
|
210
|
+
* The `handles` record of a prerender-served entry, which a HIT tail restores
|
|
211
|
+
* after the prerender store's handles (cache-lookup.ts yieldFromStore), or
|
|
212
|
+
* undefined: an entry with a doc record, or one written before the record
|
|
213
|
+
* existed (v0.21), which serves as it did.
|
|
214
|
+
*/
|
|
215
|
+
export declare function shellPrerenderHandles(snapshot: readonly ShellSnapshotRecord[]): ShellSnapshotHandlesValue | undefined;
|
|
191
216
|
/**
|
|
192
217
|
* The implicit doc scope's store on a HIT tail and on a partial replay: it
|
|
193
218
|
* serves the snapshot's segment records, the doc record among them, and
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The store scope `router.prerender()` gates a warm on
|
|
3
|
+
* (prerender/create-prerender-trigger.ts). See
|
|
4
|
+
* docs/design/prerender-every-route.md, "The store declaration".
|
|
5
|
+
*/
|
|
6
|
+
import type { CacheStoreScope, SegmentCacheStore } from "./types.js";
|
|
7
|
+
/**
|
|
8
|
+
* True under the Vite dev server: only its routes-manifest virtual module sets
|
|
9
|
+
* the dev origin (vite/discovery/virtual-module-codegen.ts). A build, a preview
|
|
10
|
+
* server and a test runner answer false.
|
|
11
|
+
*/
|
|
12
|
+
export declare function isViteDevServer(): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* The scope a warm treats `store` as having: its own declaration, with none
|
|
15
|
+
* or an unknown value being `"local"`.
|
|
16
|
+
*
|
|
17
|
+
* One exception: under the Vite dev server a MemorySegmentCacheStore answers
|
|
18
|
+
* `"global"`, because that one process serves every request. Production reads
|
|
19
|
+
* the class's own `scope` (`"local"`): changing that declaration is what
|
|
20
|
+
* would admit it there.
|
|
21
|
+
*/
|
|
22
|
+
export declare function resolveWarmStoreScope(store: SegmentCacheStore<any>, devServer?: boolean): CacheStoreScope;
|