@rangojs/router 0.26.6 → 0.28.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 +1 -1
- package/dist/types/__internal.d.ts +7 -1
- package/dist/types/browser/action-coordinator.d.ts +0 -4
- package/dist/types/browser/action-fence.d.ts +11 -3
- package/dist/types/browser/event-controller.d.ts +20 -1
- package/dist/types/browser/history-state.d.ts +7 -9
- package/dist/types/browser/intercept-utils.d.ts +23 -0
- package/dist/types/browser/navigation-store.d.ts +8 -6
- package/dist/types/browser/react/filter-segment-order.d.ts +2 -2
- package/dist/types/browser/rsc-router.d.ts +1 -1
- package/dist/types/browser/segment-reconciler.d.ts +6 -4
- package/dist/types/browser/types.d.ts +2 -1
- package/dist/types/browser/wire-protocol.d.ts +25 -0
- package/dist/types/cache/cache-key-utils.d.ts +11 -5
- package/dist/types/cache/cache-scope.d.ts +34 -22
- package/dist/types/cache/cf/cf-cache-constants.d.ts +2 -2
- package/dist/types/cache/cf/cf-cache-store.d.ts +47 -65
- package/dist/types/cache/cf/cf-kv-utils.d.ts +1 -1
- package/dist/types/cache/handle-snapshot.d.ts +9 -4
- package/dist/types/cache/segment-codec.d.ts +14 -0
- package/dist/types/cache/shell-snapshot.d.ts +1 -1
- package/dist/types/cache/tag-invalidation.d.ts +10 -0
- package/dist/types/cache/taint.d.ts +5 -3
- package/dist/types/cache/types.d.ts +7 -3
- package/dist/types/cache/vercel/vercel-cache-store.d.ts +8 -6
- package/dist/types/prefetch-markers.d.ts +4 -6
- package/dist/types/prerender/store.d.ts +31 -0
- package/dist/types/prerender/warm-request.d.ts +3 -3
- package/dist/types/prerender.d.ts +2 -2
- package/dist/types/route-name.d.ts +5 -0
- package/dist/types/router/error-handling.d.ts +4 -4
- package/dist/types/router/instrument.d.ts +4 -3
- package/dist/types/router/intercept-resolution.d.ts +25 -9
- package/dist/types/router/match-context.d.ts +12 -11
- package/dist/types/router/match-handlers.d.ts +2 -6
- package/dist/types/router/match-middleware/background-revalidation.d.ts +10 -20
- package/dist/types/router/match-middleware/cache-lookup.d.ts +35 -87
- package/dist/types/router/match-middleware/cache-store.d.ts +2 -2
- package/dist/types/router/match-middleware/segment-resolution.d.ts +8 -6
- package/dist/types/router/prerender-match.d.ts +21 -6
- package/dist/types/router/preview-match.d.ts +2 -7
- package/dist/types/router/request-classification.d.ts +5 -0
- package/dist/types/router/revalidation.d.ts +6 -1
- package/dist/types/router/router-context.d.ts +9 -63
- package/dist/types/router/router-interfaces.d.ts +8 -14
- package/dist/types/router/segment-resolution/loader-cache.d.ts +3 -3
- package/dist/types/router/segment-resolution/loader-mask.d.ts +4 -4
- package/dist/types/router/segment-resolution/prefetch-deferral.d.ts +20 -18
- package/dist/types/router/segment-resolution/resolution-pass.d.ts +93 -0
- package/dist/types/router/segment-resolution/revalidation.d.ts +82 -31
- package/dist/types/router/segment-resolution.d.ts +1 -2
- package/dist/types/router/segment-wrappers.d.ts +11 -48
- package/dist/types/router/telemetry.d.ts +2 -0
- package/dist/types/router/types.d.ts +10 -0
- package/dist/types/rsc/full-payload.d.ts +2 -2
- package/dist/types/rsc/handler-context.d.ts +6 -6
- package/dist/types/rsc/json-route-result.d.ts +5 -9
- package/dist/types/rsc/request-stages.d.ts +203 -0
- package/dist/types/rsc/response-cache-serve.d.ts +7 -12
- package/dist/types/rsc/response-route-handler.d.ts +2 -2
- package/dist/types/rsc/routine-plan.d.ts +1 -1
- package/dist/types/rsc/server-action.d.ts +2 -2
- package/dist/types/rsc/shell-capture-constants.d.ts +2 -2
- package/dist/types/rsc/shell-capture.d.ts +132 -15
- package/dist/types/rsc/shell-serve.d.ts +37 -12
- package/dist/types/server/context.d.ts +9 -8
- package/dist/types/server/handle-store.d.ts +16 -0
- package/dist/types/server/render-pass.d.ts +72 -0
- package/dist/types/server/request-context.d.ts +24 -104
- package/dist/types/server/rewrite-trail.d.ts +2 -2
- package/dist/types/testing/dispatch.d.ts +35 -18
- package/dist/types/testing/serve-shell-request.d.ts +7 -0
- package/dist/types/types/cache-types.d.ts +6 -3
- package/dist/types/types/error-types.d.ts +9 -1
- package/dist/types/types/handler-context.d.ts +18 -7
- package/dist/types/types/segments.d.ts +1 -1
- package/dist/types/vite/discovery/build-discovery-phase.d.ts +40 -0
- package/dist/types/vite/discovery/build-env.d.ts +22 -0
- package/dist/types/vite/discovery/bundle-scan-phase.d.ts +12 -0
- package/dist/types/vite/discovery/dev-prerender-cache.d.ts +3 -2
- package/dist/types/vite/discovery/dev-server-phase.d.ts +26 -0
- package/dist/types/vite/discovery/discovery-errors.d.ts +1 -1
- package/dist/types/vite/discovery/state.d.ts +12 -0
- package/dist/types/vite/plugins/version-plugin.d.ts +1 -1
- package/dist/types/vite/plugins/virtual-entries.d.ts +1 -1
- package/dist/types/vite/router-discovery.d.ts +8 -47
- package/dist/types/vite/temp-rsc-server.d.ts +39 -0
- package/dist/types/vite/utils/prerender-utils.d.ts +9 -0
- package/dist/types/wire-params.d.ts +34 -0
- package/dist/vite/index.js +3809 -3710
- package/package.json +1 -1
- package/skills/cache-guide/SKILL.md +8 -5
- package/skills/caching/SKILL.md +37 -18
- package/skills/client-urls/SKILL.md +2 -1
- package/skills/document-cache/SKILL.md +18 -1
- package/skills/handler-use/SKILL.md +1 -1
- package/skills/intercept/SKILL.md +53 -13
- package/skills/layout/SKILL.md +11 -7
- package/skills/loader/SKILL.md +30 -13
- package/skills/middleware/SKILL.md +19 -1
- package/skills/migrate-nextjs/SKILL.md +5 -4
- package/skills/parallel/SKILL.md +5 -4
- package/skills/ppr/SKILL.md +19 -3
- package/skills/prerender/SKILL.md +39 -15
- package/skills/rango/SKILL.md +23 -11
- package/skills/server-actions/SKILL.md +51 -6
- package/skills/testing/predicates.md +1 -1
- package/skills/testing/response-routes.md +6 -4
- package/skills/testing/serve-shell-request.md +7 -7
- package/skills/use-cache/SKILL.md +46 -8
- package/skills/ux-architecture/SKILL.md +3 -2
- package/src/__internal.ts +7 -1
- package/src/browser/action-coordinator.ts +2 -13
- package/src/browser/action-fence.ts +11 -3
- package/src/browser/connection-warmup.ts +3 -1
- package/src/browser/event-controller.ts +42 -3
- package/src/browser/history-state.ts +15 -13
- package/src/browser/intercept-utils.ts +51 -0
- package/src/browser/navigation-bridge.ts +34 -30
- package/src/browser/navigation-client.ts +21 -33
- package/src/browser/navigation-store.ts +25 -27
- package/src/browser/navigation-transaction.ts +7 -11
- package/src/browser/partial-update.ts +8 -0
- package/src/browser/prefetch/cache.ts +2 -1
- package/src/browser/prefetch/fetch.ts +8 -16
- package/src/browser/prefetch/queue.ts +4 -4
- package/src/browser/react/NavigationProvider.tsx +2 -1
- package/src/browser/react/filter-segment-order.ts +2 -2
- package/src/browser/rsc-router.tsx +17 -2
- package/src/browser/segment-reconciler.ts +66 -53
- package/src/browser/server-action-bridge.ts +265 -127
- package/src/browser/types.ts +2 -1
- package/src/browser/wire-protocol.ts +41 -0
- package/src/cache/cache-key-utils.ts +11 -5
- package/src/cache/cache-runtime.ts +110 -50
- package/src/cache/cache-scope.ts +110 -64
- package/src/cache/cf/cf-cache-constants.ts +2 -2
- package/src/cache/cf/cf-cache-store.ts +486 -874
- package/src/cache/cf/cf-kv-utils.ts +1 -1
- package/src/cache/document-cache.ts +42 -15
- package/src/cache/handle-snapshot.ts +19 -7
- package/src/cache/segment-codec.ts +55 -0
- package/src/cache/shell-snapshot.ts +2 -2
- package/src/cache/tag-invalidation.ts +21 -2
- package/src/cache/taint.ts +5 -3
- package/src/cache/types.ts +7 -3
- package/src/cache/vercel/vercel-cache-store.ts +243 -310
- package/src/handles/pushed-by.ts +1 -1
- package/src/prefetch-markers.ts +4 -7
- package/src/prerender/store.ts +76 -0
- package/src/prerender/warm-request.ts +8 -4
- package/src/prerender.ts +2 -2
- package/src/route-name.ts +8 -0
- package/src/router/error-handling.ts +4 -4
- package/src/router/instrument.ts +4 -3
- package/src/router/intercept-resolution.ts +77 -75
- package/src/router/loader-resolution.ts +5 -4
- package/src/router/match-api.ts +4 -5
- package/src/router/match-context.ts +33 -12
- package/src/router/match-handlers.ts +8 -20
- package/src/router/match-middleware/background-revalidation.ts +41 -53
- package/src/router/match-middleware/cache-lookup.ts +680 -720
- package/src/router/match-middleware/cache-store.ts +14 -12
- package/src/router/match-middleware/intercept-resolution.ts +3 -23
- package/src/router/match-middleware/segment-resolution.ts +34 -61
- package/src/router/match-result.ts +1 -20
- package/src/router/middleware.ts +69 -11
- package/src/router/navigation-snapshot.ts +4 -3
- package/src/router/prerender-match.ts +100 -44
- package/src/router/preview-match.ts +6 -41
- package/src/router/request-classification.ts +13 -7
- package/src/router/revalidation.ts +33 -7
- package/src/router/route-snapshot.ts +2 -5
- package/src/router/router-context.ts +14 -117
- package/src/router/router-interfaces.ts +8 -14
- package/src/router/segment-resolution/loader-cache.ts +14 -9
- package/src/router/segment-resolution/loader-mask.ts +5 -5
- package/src/router/segment-resolution/prefetch-deferral.ts +30 -27
- package/src/router/segment-resolution/resolution-pass.ts +137 -0
- package/src/router/segment-resolution/revalidation.ts +897 -776
- package/src/router/segment-resolution.ts +4 -13
- package/src/router/segment-wrappers.ts +51 -269
- package/src/router/telemetry.ts +5 -0
- package/src/router/types.ts +10 -0
- package/src/router.ts +12 -13
- package/src/rsc/full-payload.ts +6 -5
- package/src/rsc/handler-context.ts +8 -14
- package/src/rsc/handler.ts +126 -507
- package/src/rsc/json-route-result.ts +5 -9
- package/src/rsc/loader-fetch.ts +6 -5
- package/src/rsc/progressive-enhancement.ts +5 -0
- package/src/rsc/request-stages.ts +757 -0
- package/src/rsc/response-cache-serve.ts +10 -14
- package/src/rsc/response-route-handler.ts +13 -5
- package/src/rsc/rewrite-passes.ts +2 -1
- package/src/rsc/routine-plan.ts +1 -1
- package/src/rsc/rsc-rendering.ts +172 -349
- package/src/rsc/server-action.ts +87 -113
- package/src/rsc/shell-capture-constants.ts +3 -1
- package/src/rsc/shell-capture.ts +212 -169
- package/src/rsc/shell-serve.ts +121 -18
- package/src/rsc/ssr-setup.ts +5 -4
- package/src/segment-system.tsx +3 -3
- package/src/server/context.ts +22 -25
- package/src/server/handle-store.ts +55 -0
- package/src/server/render-pass.ts +291 -0
- package/src/server/request-context.ts +26 -115
- package/src/server/rewrite-trail.ts +6 -4
- package/src/ssr/index.tsx +1 -1
- package/src/ssr/ssr-root.tsx +1 -0
- package/src/testing/dispatch.ts +223 -710
- package/src/testing/e2e/page-helpers.ts +2 -2
- package/src/testing/serve-shell-request.ts +37 -32
- package/src/types/cache-types.ts +6 -3
- package/src/types/error-types.ts +9 -1
- package/src/types/handler-context.ts +21 -7
- package/src/types/segments.ts +1 -1
- package/src/vite/discovery/build-discovery-phase.ts +204 -0
- package/src/vite/discovery/build-env.ts +148 -0
- package/src/vite/discovery/bundle-scan-phase.ts +128 -0
- package/src/vite/discovery/dev-prerender-cache.ts +8 -3
- package/src/vite/discovery/dev-server-phase.ts +1776 -0
- package/src/vite/discovery/discover-routers.ts +1 -1
- package/src/vite/discovery/discovery-errors.ts +1 -1
- package/src/vite/discovery/prerender-collection.ts +24 -39
- package/src/vite/discovery/state.ts +15 -0
- package/src/vite/plugins/version-plugin.ts +1 -1
- package/src/vite/plugins/virtual-entries.ts +1 -1
- package/src/vite/router-discovery.ts +29 -2428
- package/src/vite/temp-rsc-server.ts +223 -0
- package/src/vite/utils/prerender-utils.ts +47 -0
- package/src/wire-params.ts +35 -0
- package/dist/types/router/segment-resolution/fresh.d.ts +0 -72
- package/src/router/segment-resolution/fresh.ts +0 -945
package/dist/bin/rango.js
CHANGED
|
@@ -1644,7 +1644,7 @@ var init_package = __esm({
|
|
|
1644
1644
|
"package.json"() {
|
|
1645
1645
|
package_default = {
|
|
1646
1646
|
name: "@rangojs/router",
|
|
1647
|
-
version: "0.
|
|
1647
|
+
version: "0.28.0",
|
|
1648
1648
|
description: "Django-inspired RSC router with composable URL patterns",
|
|
1649
1649
|
keywords: [
|
|
1650
1650
|
"react",
|
|
@@ -53,7 +53,13 @@ export type { CachedEntryData, CacheGetResult, SerializedSegmentData, CacheDefau
|
|
|
53
53
|
* @internal
|
|
54
54
|
* Router context for AsyncLocalStorage.
|
|
55
55
|
*/
|
|
56
|
-
export type { RouterContext,
|
|
56
|
+
export type { RouterContext, InterceptResult, } from "./router/router-context.js";
|
|
57
|
+
/**
|
|
58
|
+
* @internal
|
|
59
|
+
* The request side of a revalidating resolution pass (RouterContext's
|
|
60
|
+
* revalidating resolvers take it).
|
|
61
|
+
*/
|
|
62
|
+
export type { ResolutionPassInput } from "./router/segment-resolution/resolution-pass.js";
|
|
57
63
|
/**
|
|
58
64
|
* @internal
|
|
59
65
|
* Route match context during pipeline processing.
|
|
@@ -6,8 +6,6 @@ import type { ActionEntry } from "./event-controller.js";
|
|
|
6
6
|
*/
|
|
7
7
|
type ActionScenario = {
|
|
8
8
|
type: "navigated-away";
|
|
9
|
-
historyKeyChanged: boolean;
|
|
10
|
-
onInterceptRoute: boolean;
|
|
11
9
|
} | {
|
|
12
10
|
type: "hmr-missing";
|
|
13
11
|
} | {
|
|
@@ -44,8 +42,6 @@ export interface ActionOutcomeInput {
|
|
|
44
42
|
reconciledSegmentCount: number;
|
|
45
43
|
/** Number of matched segment IDs from server */
|
|
46
44
|
matchedCount: number;
|
|
47
|
-
/** Current intercept source URL (null when not on intercept route) */
|
|
48
|
-
currentInterceptSource: string | null;
|
|
49
45
|
}
|
|
50
46
|
/**
|
|
51
47
|
* Classify a post-reconciliation action outcome. Ordered priority chain: each
|
|
@@ -6,9 +6,11 @@
|
|
|
6
6
|
* start. While the fence is up, the decision of whether the action invalidated
|
|
7
7
|
* anything is deferred to the response:
|
|
8
8
|
*
|
|
9
|
-
* -
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* - a navigation during the flight is an ordinary one: a prefetch is served,
|
|
10
|
+
* and the page it commits may hold pre-write data until the follow-up below,
|
|
11
|
+
* - a navigation without a prefetch, and a prefetch, fetch with
|
|
12
|
+
* `cache: "no-store"` so they cannot be served stale bytes from the
|
|
13
|
+
* browser's Vary-keyed HTTP cache,
|
|
12
14
|
* - popstate reads are treated as stale-while-revalidate.
|
|
13
15
|
*
|
|
14
16
|
* Nothing is wiped, rotated, or broadcast while the fence is up — that is what
|
|
@@ -16,6 +18,12 @@
|
|
|
16
18
|
* actions compose: each action raises and lowers its own reference, and the
|
|
17
19
|
* fence is down only when the count reaches zero.
|
|
18
20
|
*
|
|
21
|
+
* The drop runs the batch's follow-up: when an action of the batch did not
|
|
22
|
+
* land on the page on screen, the action bridge refetches that page once,
|
|
23
|
+
* whole, after the navigation the user started, unless an intercept is on
|
|
24
|
+
* screen (server-action-bridge.ts followUp; the rules are R1-R7 in
|
|
25
|
+
* docs/internal/execution-model.md).
|
|
26
|
+
*
|
|
19
27
|
* The refcount is a single module-level counter, not keyed by routerId.
|
|
20
28
|
* Consumers (navigation-client.ts, prefetch/fetch.ts, navigation-bridge.ts)
|
|
21
29
|
* read it unscoped, so an action in one router would suppress another router's
|
|
@@ -20,6 +20,18 @@ export interface NavigationEntry {
|
|
|
20
20
|
options?: NavigateOptionsInternal & {
|
|
21
21
|
skipLoadingState?: boolean;
|
|
22
22
|
};
|
|
23
|
+
/**
|
|
24
|
+
* Resolves once the navigation has ended: its transaction ended and every
|
|
25
|
+
* stream it opened closed. True when it committed, false when it ended
|
|
26
|
+
* without a commit (a failure) or was left (aborted, which settles it at
|
|
27
|
+
* once). A `prefetch: false` fill holds the transaction open
|
|
28
|
+
* (partial-update.ts awaits fillHoles before it resolves) and its stream
|
|
29
|
+
* until the fill's answer streamed, so a waiter never cuts a fill or a
|
|
30
|
+
* stream short. Only the action bridge's follow-up awaits it
|
|
31
|
+
* (server-action-bridge.ts followUp); no hook reads it, and settling it
|
|
32
|
+
* notifies nothing.
|
|
33
|
+
*/
|
|
34
|
+
settled: Promise<boolean>;
|
|
23
35
|
}
|
|
24
36
|
/**
|
|
25
37
|
* Entry tracking an in-flight action
|
|
@@ -195,7 +207,8 @@ export interface EventController {
|
|
|
195
207
|
startAction(actionId: string, args: unknown[],
|
|
196
208
|
/** Originating history entry key; scopes location-state arbitration. */
|
|
197
209
|
cohort?: string): ActionHandle;
|
|
198
|
-
|
|
210
|
+
/** Abort every action in flight except `except` (an ActionHandle id). */
|
|
211
|
+
abortAllActions(except?: string): void;
|
|
199
212
|
getState(): DerivedNavigationState;
|
|
200
213
|
getActionState(actionId: string): TrackedActionState;
|
|
201
214
|
getLocation(): NavigationLocation;
|
|
@@ -279,6 +292,12 @@ export interface EventController {
|
|
|
279
292
|
/** True once after a `treeless` commit. */
|
|
280
293
|
takeTreelessLocationState(): boolean;
|
|
281
294
|
getCurrentNavigation(): NavigationEntry | null;
|
|
295
|
+
/**
|
|
296
|
+
* The newest navigation until it settles (NavigationEntry.settled): before
|
|
297
|
+
* its commit, and after it while its transaction or a stream is still
|
|
298
|
+
* open. Null once it settled or was left.
|
|
299
|
+
*/
|
|
300
|
+
getUnsettledNavigation(): NavigationEntry | null;
|
|
282
301
|
getInflightActions(): Map<string, ActionEntry>;
|
|
283
302
|
/** Whether any concurrent actions have occurred (shared across all handles) */
|
|
284
303
|
hadAnyConcurrentActions(): boolean;
|
|
@@ -21,15 +21,9 @@ export declare function hasLocationState(state: unknown): boolean;
|
|
|
21
21
|
*/
|
|
22
22
|
export declare function pushHistoryWithIdx(state: Record<string, unknown> | null, url: string, replace: boolean): void;
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* cache miss.
|
|
28
|
-
*/
|
|
29
|
-
export declare const SHELL_MISS_MARKER: string;
|
|
30
|
-
/**
|
|
31
|
-
* Drop the forced-MISS marker from the address bar at boot, keeping the
|
|
32
|
-
* history entry's state (initBrowserApp calls it before any location read).
|
|
24
|
+
* Drop the forced-MISS marker (`WIRE.shellMiss`, rsc/shell-serve.ts) from the
|
|
25
|
+
* address bar at boot, keeping the history entry's state (initBrowserApp
|
|
26
|
+
* calls it before any location read).
|
|
33
27
|
* Left in place, a refresh or a shared link would stay off the shell and the
|
|
34
28
|
* app's search params would carry it. The server strips the same marker from
|
|
35
29
|
* the request before rendering (shell-serve.ts withoutShellMissMarker), so
|
|
@@ -46,6 +40,10 @@ export declare function stripShellMissMarker(): void;
|
|
|
46
40
|
*
|
|
47
41
|
* A slot is recognised by its key alone (the `~r` suffix): at start-up the
|
|
48
42
|
* module that defines it may not be loaded.
|
|
43
|
+
*
|
|
44
|
+
* The same pass drops the entry's intercept marks (`intercept`,
|
|
45
|
+
* `sourceUrl`): a document request never renders an intercept, so the entry
|
|
46
|
+
* is a full page for later Back/Forward.
|
|
49
47
|
*/
|
|
50
48
|
export declare function clearLocationStateOnDocumentLoad(): void;
|
|
51
49
|
/**
|
|
@@ -31,3 +31,26 @@ export declare function hasActiveIntercept(slots?: Record<string, SlotState>): b
|
|
|
31
31
|
* whether interception happens depends on the current page context.
|
|
32
32
|
*/
|
|
33
33
|
export declare function isInterceptOnlyCache(segments: ResolvedSegment[]): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* An intercept's `matched`: the client's ids without any of the slot's (its
|
|
36
|
+
* id and every loader segment on it, another intercept's into the same slot
|
|
37
|
+
* included), then the slot's (interceptSegmentIds). One order for the
|
|
38
|
+
* prefetch, its fill, an action and a revisit: a fill whose `matched` differs
|
|
39
|
+
* from its tree's is rendered as a new tree (browser/partial-update.ts
|
|
40
|
+
* fillHoles). Shared by router/match-result.ts and wholeInterceptMatched.
|
|
41
|
+
*/
|
|
42
|
+
export declare function interceptMatched(clientIds: readonly string[], slotIds: readonly string[]): string[];
|
|
43
|
+
/**
|
|
44
|
+
* The `matched` the browser keeps for an intercept answer to a request that
|
|
45
|
+
* held no segments (a followed redirect, a Back/Forward revalidation with
|
|
46
|
+
* handles pending, the dev HMR refetch), or undefined to keep the answer's.
|
|
47
|
+
* The server never renders the page under an intercept and lists it only
|
|
48
|
+
* from the ids a request held, so such an answer has an empty outlet under
|
|
49
|
+
* the slot. The page it lands over (`held`) stays, as the server lists it for
|
|
50
|
+
* a request that holds it.
|
|
51
|
+
*/
|
|
52
|
+
export declare function wholeInterceptMatched(held: readonly ResolvedSegment[], answer: {
|
|
53
|
+
matched?: string[];
|
|
54
|
+
segments?: ResolvedSegment[];
|
|
55
|
+
slots?: Record<string, SlotState>;
|
|
56
|
+
}): string[] | undefined;
|
|
@@ -24,16 +24,18 @@ export declare function liveHandleDataForCache(eventController: Pick<EventContro
|
|
|
24
24
|
* Options for generating a history key
|
|
25
25
|
*/
|
|
26
26
|
export interface HistoryKeyOptions {
|
|
27
|
-
/**
|
|
27
|
+
/** Key an intercept entry (apart from the plain entry for the URL). */
|
|
28
28
|
intercept?: boolean;
|
|
29
|
+
/** The page the intercept was opened over (history.state.sourceUrl). */
|
|
30
|
+
interceptSource?: string;
|
|
29
31
|
}
|
|
30
32
|
/**
|
|
31
|
-
* Generate a cache key from a URL.
|
|
32
|
-
*
|
|
33
|
-
* Hash fragments (#) are excluded since they don't affect server data.
|
|
33
|
+
* Generate a cache key from a URL: pathname + search. Hash fragments (#) are
|
|
34
|
+
* excluded since they don't affect server data.
|
|
34
35
|
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
36
|
+
* An intercept entry is keyed `<url>:intercept:<source>`: its cached tree
|
|
37
|
+
* includes the page under the intercept. hasInterceptCache relies on the
|
|
38
|
+
* `:intercept:` separator.
|
|
37
39
|
*/
|
|
38
40
|
export declare function generateHistoryKey(url?: string, options?: HistoryKeyOptions): string;
|
|
39
41
|
/**
|
|
@@ -26,8 +26,8 @@ export declare function loaderParentId(id: string): string;
|
|
|
26
26
|
* 2. Place each parallel slot id (contains ".@") immediately after its
|
|
27
27
|
* parent layout/route id. Raw segment-resolution emission order does NOT
|
|
28
28
|
* guarantee this: route-mounted parallels are resolved/pushed BEFORE the
|
|
29
|
-
* route handler's segment is appended (see
|
|
30
|
-
*
|
|
29
|
+
* route handler's segment is appended (see resolveSegment in
|
|
30
|
+
* segment-resolution/revalidation.ts), so matched can read
|
|
31
31
|
* `[..., R0.@panel, R0]`. collectHandleData consumes segmentOrder verbatim
|
|
32
32
|
* with later-wins semantics, so without normalization the route handler's
|
|
33
33
|
* Meta would override the slot's more-specific Meta — backwards.
|
|
@@ -62,10 +62,12 @@ export interface ReconcileResult {
|
|
|
62
62
|
*/
|
|
63
63
|
export declare function reconcileSegments(input: ReconcileInput): ReconcileResult;
|
|
64
64
|
/**
|
|
65
|
-
* Reconcile error
|
|
65
|
+
* Reconcile an error-boundary response with cached segments.
|
|
66
66
|
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* preserving sibling layouts that aren't in
|
|
67
|
+
* The server returns the error boundary segment and, above it, what the
|
|
68
|
+
* action's revalidation re-ran (rsc/server-action.ts). This function overlays
|
|
69
|
+
* them onto the full cached tree, preserving sibling layouts that aren't in
|
|
70
|
+
* the error parent chain. The error segment replaces its cached copy; every
|
|
71
|
+
* other segment merges as an action's does (mergeCached).
|
|
70
72
|
*/
|
|
71
73
|
export declare function reconcileErrorSegments(cachedSegments: ResolvedSegment[], errorSegments: ResolvedSegment[]): ReconcileResult;
|
|
@@ -558,7 +558,8 @@ export interface NavigationStore {
|
|
|
558
558
|
*/
|
|
559
559
|
handlesPending?: boolean;
|
|
560
560
|
} | undefined;
|
|
561
|
-
|
|
561
|
+
/** Whether an intercept entry is cached for the plain `historyKey`, from any source page. */
|
|
562
|
+
hasInterceptCache(historyKey: string): boolean;
|
|
562
563
|
/**
|
|
563
564
|
* Update only the handleData (and optionally the stale / handlesPending flags)
|
|
564
565
|
* of an existing cache entry. When a flag is omitted the entry's current value
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** The parameters of a partial request: a navigation, a prefetch or a JS server action. */
|
|
2
|
+
export interface PartialRequestInit {
|
|
3
|
+
/** A JS server action's id: written as `_rsc_action` in place of `_rsc_partial`. */
|
|
4
|
+
action?: string;
|
|
5
|
+
/** The mounted segment ids the server diffs against. */
|
|
6
|
+
segmentIds: readonly string[];
|
|
7
|
+
/**
|
|
8
|
+
* An empty `segmentIds`: "send" writes `_rsc_segments=` (navigation,
|
|
9
|
+
* action), "omit" leaves it out (prefetch). The prefetch cache keys carry
|
|
10
|
+
* the difference.
|
|
11
|
+
*/
|
|
12
|
+
emptySegments: "send" | "omit";
|
|
13
|
+
stale?: boolean;
|
|
14
|
+
version?: string;
|
|
15
|
+
routerId?: string;
|
|
16
|
+
rewriteTarget?: string;
|
|
17
|
+
fill?: boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Writes the partial-request parameters onto `url` in the one order every
|
|
21
|
+
* sender uses. Navigation and prefetch cache keys are built from the result
|
|
22
|
+
* (prefetch/cache.ts), so a navigation adopts a prefetch only while both
|
|
23
|
+
* write identically: browser/__tests__/wire-urls.test.ts pins the strings.
|
|
24
|
+
*/
|
|
25
|
+
export declare function writePartialParams(url: URL, init: PartialRequestInit): URL;
|
|
@@ -97,8 +97,10 @@ export declare const KEY_PART_PREFIX = "key:";
|
|
|
97
97
|
* (CacheScope.resolveKeyFrom, CacheScope.resolvePartition): the `key()`
|
|
98
98
|
* results of the scope's cache() chain, outermost first, then its default
|
|
99
99
|
* parts: the keyGenerator results of enclosing scopes on another store
|
|
100
|
-
* (#974) and, for a record key
|
|
101
|
-
* default key (or its store's keyGenerator result,
|
|
100
|
+
* (#974) and, for a route record key, the scope's own part: without a
|
|
101
|
+
* `key()` of its own, its default key (or its store's keyGenerator result,
|
|
102
|
+
* #970); with one, the default key's request kind (`doc`, `partial` or
|
|
103
|
+
* `intercept:<intercept>`, routeRecordKind in cache-scope.ts).
|
|
102
104
|
*
|
|
103
105
|
* Key scheme invariant (#975). A `key()` result is often request input,
|
|
104
106
|
* and a record key has no route or scope discriminator (the store reads
|
|
@@ -124,9 +126,13 @@ export declare const KEY_PART_PREFIX = "key:";
|
|
|
124
126
|
* A namespaced `key()` result starts with `key:` and holds no `|`. A
|
|
125
127
|
* composed key holds a `|` and either starts with `key:` or holds no `:`.
|
|
126
128
|
* Among composed keys, splitting on `|` recovers each part, a part's kind
|
|
127
|
-
* (a `key:` prefix, or no `:` at all) and its value.
|
|
128
|
-
*
|
|
129
|
-
*
|
|
129
|
+
* (a `key:` prefix, or no `:` at all) and its value. A request kind part is
|
|
130
|
+
* a default key's prefix without the URL after it, so it never equals a
|
|
131
|
+
* default key part; a keyGenerator part can equal it (`doc`) only when the
|
|
132
|
+
* keyGenerator returns a constant, which already gives every URL one record.
|
|
133
|
+
* Pinned by the collision probe in
|
|
134
|
+
* src/cache/__tests__/cache-scope-chain.test.ts. A keyGenerator result is
|
|
135
|
+
* the store's own namespace, as before.
|
|
130
136
|
*
|
|
131
137
|
* Shared with the testing helper `shellCacheKey`, so a test builds the
|
|
132
138
|
* production partition.
|
|
@@ -14,16 +14,23 @@ import { type ExecutionStart } from "./tag-invalidation.js";
|
|
|
14
14
|
import { type OwnedPushDelivery } from "./handle-snapshot.js";
|
|
15
15
|
import type { RequestContext } from "../server/request-context.js";
|
|
16
16
|
type CacheKeyFn = NonNullable<PartialCacheOptions["key"]>;
|
|
17
|
+
/**
|
|
18
|
+
* A route record that answered. `restoreHandles` is set when the lookup left
|
|
19
|
+
* the handle restore to its caller (lookupRouteDetailed `deferHandles`),
|
|
20
|
+
* which names the segments it sends (handle-snapshot.ts restoreHandles).
|
|
21
|
+
*/
|
|
22
|
+
export interface CachedRouteHit {
|
|
23
|
+
segments: ResolvedSegment[];
|
|
24
|
+
shouldRevalidate: boolean;
|
|
25
|
+
restoreHandles?: (sentIds: ReadonlySet<string>) => Promise<void>;
|
|
26
|
+
}
|
|
17
27
|
/**
|
|
18
28
|
* Discriminated outcome of a route cache lookup — see
|
|
19
29
|
* {@link CacheScope.lookupRouteDetailed} for what each status licenses.
|
|
20
30
|
*/
|
|
21
31
|
export type CacheRouteLookupOutcome = {
|
|
22
32
|
status: "hit";
|
|
23
|
-
result:
|
|
24
|
-
segments: ResolvedSegment[];
|
|
25
|
-
shouldRevalidate: boolean;
|
|
26
|
-
};
|
|
33
|
+
result: CachedRouteHit;
|
|
27
34
|
} | {
|
|
28
35
|
status: "miss" | "bypass" | "error";
|
|
29
36
|
};
|
|
@@ -187,14 +194,18 @@ export declare class CacheScope {
|
|
|
187
194
|
* enclosing partition (#970, #974). A scope whose own config sets no
|
|
188
195
|
* `key()` appends its own default key (resolveDefaultKey). Reusing the
|
|
189
196
|
* outer `key()` result alone would give every route under the inner
|
|
190
|
-
* cache() one record: a `key()` replaces the
|
|
191
|
-
* outer key that names no route (`tier:gold`) would make `/a` HIT
|
|
192
|
-
* record. A scope with its own `key()` adds no default key:
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
*
|
|
197
|
+
* cache() one record: a `key()` replaces the default key's URL part, so
|
|
198
|
+
* an outer key that names no route (`tier:gold`) would make `/a` HIT
|
|
199
|
+
* `/b`'s record. A scope with its own `key()` adds no default key: its `key()`
|
|
200
|
+
* replaces the URL part, and its store's keyGenerator does not run. It
|
|
201
|
+
* appends `kind` instead (routeRecordKind): the `key()` decides which
|
|
202
|
+
* requests of one kind share a record, never that a document, a
|
|
203
|
+
* navigation and an intercept navigation do. With no partition part it is
|
|
204
|
+
* resolveDefaultKey alone. With a `key()` on the chain but no request
|
|
205
|
+
* context it rejects (keyWithoutContextError). `partitionedPrefix`
|
|
206
|
+
* prefixes a key built from partition parts only (the response family's
|
|
207
|
+
* `response:`, which passes no `kind`: a response route answers every
|
|
208
|
+
* request alike).
|
|
198
209
|
*
|
|
199
210
|
* Each `key()` result lives on the request context (`_resolvedCacheKeys`),
|
|
200
211
|
* by function: it runs once per request whatever the default key
|
|
@@ -205,7 +216,7 @@ export declare class CacheScope {
|
|
|
205
216
|
* itself: a `key()` calling `cookies()` would trip the capture guard there,
|
|
206
217
|
* and a capture must store the partition its request resolved.
|
|
207
218
|
*/
|
|
208
|
-
resolveKeyFrom(defaultKey: string, partitionedPrefix?: string): Promise<string>;
|
|
219
|
+
resolveKeyFrom(defaultKey: string, partitionedPrefix?: string, kind?: string): Promise<string>;
|
|
209
220
|
/**
|
|
210
221
|
* @internal The request partition of a ppr route's shell under this scope
|
|
211
222
|
* (resolveShellPartition): its partition parts (resolvePartitionParts),
|
|
@@ -285,14 +296,14 @@ export declare class CacheScope {
|
|
|
285
296
|
*
|
|
286
297
|
* @param pathname - URL pathname for cache key generation
|
|
287
298
|
* @param params - Route params for cache key generation
|
|
288
|
-
* @param
|
|
299
|
+
* @param intercept - The intercept an intercept navigation selected
|
|
300
|
+
* (interceptRecordKey): its record has its own key
|
|
289
301
|
* @param ownedPushes - What the record is to each loader's handle pushes
|
|
290
302
|
* (withCacheLookup: loader-cache.ts loaderPins), called on a hit
|
|
303
|
+
* @param deferHandles - Restore no handle value here: the caller calls the
|
|
304
|
+
* hit's `restoreHandles` once it decided which segments it sends
|
|
291
305
|
*/
|
|
292
|
-
lookupRoute(pathname: string, params: Record<string, string>,
|
|
293
|
-
segments: ResolvedSegment[];
|
|
294
|
-
shouldRevalidate: boolean;
|
|
295
|
-
} | null>;
|
|
306
|
+
lookupRoute(pathname: string, params: Record<string, string>, intercept?: string, ownedPushes?: () => OwnedPushDelivery, deferHandles?: boolean): Promise<CachedRouteHit | null>;
|
|
296
307
|
/**
|
|
297
308
|
* @internal lookupRoute with a discriminated outcome. The PPR replay
|
|
298
309
|
* composition (withCacheLookup) may substitute the seeded doc record ONLY on
|
|
@@ -311,7 +322,7 @@ export declare class CacheScope {
|
|
|
311
322
|
* A corrupt entry that was evicted reads as `miss`: the store was consulted
|
|
312
323
|
* and holds nothing servable, which is the post-eviction truth.
|
|
313
324
|
*/
|
|
314
|
-
lookupRouteDetailed(pathname: string, params: Record<string, string>,
|
|
325
|
+
lookupRouteDetailed(pathname: string, params: Record<string, string>, intercept?: string, ownedPushes?: () => OwnedPushDelivery, deferHandles?: boolean): Promise<CacheRouteLookupOutcome>;
|
|
315
326
|
/**
|
|
316
327
|
* Record this scope's segment-DSL cache({ tags }) into the request tag union
|
|
317
328
|
* synchronously, under the same gate cacheRoute() uses for a write.
|
|
@@ -341,13 +352,14 @@ export declare class CacheScope {
|
|
|
341
352
|
* @param pathname - URL pathname for cache key generation
|
|
342
353
|
* @param params - Route params for cache key generation
|
|
343
354
|
* @param segments - All resolved segments to cache
|
|
344
|
-
* @param
|
|
355
|
+
* @param intercept - The intercept an intercept navigation selected
|
|
356
|
+
* (interceptRecordKey): its record has its own key
|
|
345
357
|
* @param start - Where the render of `segments` started: the record is not
|
|
346
358
|
* written when one of its tags was invalidated since (#977,
|
|
347
359
|
* predatesInvalidation). A shell capture's doc record passes none: it
|
|
348
360
|
* lives only in the shell entry, which putShell gates by its own start.
|
|
349
361
|
*/
|
|
350
|
-
cacheRoute(pathname: string, params: Record<string, string>, segments: ResolvedSegment[],
|
|
362
|
+
cacheRoute(pathname: string, params: Record<string, string>, segments: ResolvedSegment[], intercept?: string, start?: ExecutionStart): Promise<void>;
|
|
351
363
|
}
|
|
352
364
|
/**
|
|
353
365
|
* @internal The request partition of a ppr route's shell: with a route
|
|
@@ -392,7 +404,7 @@ export declare function createShellImplicitDocScope(marker: ShellImplicitCacheMa
|
|
|
392
404
|
* normal partial navigation replay), substitute an implicit doc-level scope
|
|
393
405
|
* so withCacheLookup/withCacheStore treat the WHOLE matched route as a
|
|
394
406
|
* cache() boundary — the shell entry IS a cache() of the handler layer, with
|
|
395
|
-
* loaders as the live carve-outs (
|
|
407
|
+
* loaders as the live carve-outs (serveStoredSegments).
|
|
396
408
|
*
|
|
397
409
|
* A document HIT tail (`docTail`) always gets the implicit scope: it replays
|
|
398
410
|
* the shell's own record and never consults a route-derived scope, whose
|
|
@@ -38,13 +38,13 @@ export declare const CACHE_REVALIDATING_AT_HEADER = "x-edge-cache-revalidating-a
|
|
|
38
38
|
* re-arm re-puts the full window and restarts CF's retention clock, pinning a
|
|
39
39
|
* perpetually-stale entry (one whose background revalidation keeps failing) past
|
|
40
40
|
* its intended hard-expiry indefinitely. Mirrors the KVSegmentEnvelope `e`
|
|
41
|
-
* field and the remaining-ttl math in
|
|
41
|
+
* field and the remaining-ttl math in promoteToL1.
|
|
42
42
|
* @internal
|
|
43
43
|
*/
|
|
44
44
|
export declare const CACHE_EXPIRES_AT_HEADER = "x-edge-cache-expires-at";
|
|
45
45
|
/**
|
|
46
46
|
* Header stashing the route author's original Cache-Control on L1 document
|
|
47
|
-
* entries. putResponse/
|
|
47
|
+
* entries. putResponse/promoteToL1 overwrite Cache-Control with a long
|
|
48
48
|
* `max-age` so the CF Cache API retains the entry across the whole SWR window;
|
|
49
49
|
* getResponse restores this original value before serving so the client and any
|
|
50
50
|
* upstream CDN see the author's intended directive, not the internal edge TTL.
|
|
@@ -145,7 +145,7 @@ export declare class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<T
|
|
|
145
145
|
* the faulty per-colo entry ONLY when that fall-through found no good copy.
|
|
146
146
|
*
|
|
147
147
|
* The conditional evict is the load-bearing detail: when KV DOES serve a copy,
|
|
148
|
-
*
|
|
148
|
+
* readKv has already scheduled a same-key promote (`cache.put`); an eager
|
|
149
149
|
* `cache.delete` here would race that put with no CF Cache API ordering
|
|
150
150
|
* guarantee and could clobber the freshly-restored entry. So in that case we
|
|
151
151
|
* lean on #558's heal-by-overwrite (the non-suppressed fall-through promotes /
|
|
@@ -164,7 +164,10 @@ export declare class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<T
|
|
|
164
164
|
private healCorruptL1;
|
|
165
165
|
/**
|
|
166
166
|
* Re-put a stale L1 entry marked REVALIDATING, so concurrent requests serve it
|
|
167
|
-
* without each triggering a revalidation.
|
|
167
|
+
* without each triggering a revalidation (readL1). A JSON family re-puts its
|
|
168
|
+
* parsed body as a string, without a status text as set() writes it; the
|
|
169
|
+
* document re-puts a clone (`source`) whose original body still streams to
|
|
170
|
+
* the client.
|
|
168
171
|
*
|
|
169
172
|
* The write is NON-BLOCKING (waitUntil) and best-effort by design:
|
|
170
173
|
* - It runs in waitUntil, so it never adds the put latency to the served stale
|
|
@@ -185,20 +188,6 @@ export declare class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<T
|
|
|
185
188
|
* @internal
|
|
186
189
|
*/
|
|
187
190
|
private markRevalidating;
|
|
188
|
-
/**
|
|
189
|
-
* Document-tier counterpart of markRevalidating for getResponse's herd guard.
|
|
190
|
-
* The segment/item tiers JSON-parse the body, so they re-put with a string
|
|
191
|
-
* body; document bodies are streamed verbatim, so we re-put with a CLONED
|
|
192
|
-
* response body (`response.clone()`) supplied by the caller -- the original
|
|
193
|
-
* body still streams to the client while the marker carries the clone. Same
|
|
194
|
-
* REVALIDATING status header, same revalidating-at stamp, same
|
|
195
|
-
* remainingCacheControl re-put math as markRevalidating, so the document tier
|
|
196
|
-
* suppresses concurrent revalidation for the identical MAX_REVALIDATION_INTERVAL
|
|
197
|
-
* window the segment tier does. Best-effort and non-blocking: a failed marker
|
|
198
|
-
* write must not affect the served stale read.
|
|
199
|
-
* @internal
|
|
200
|
-
*/
|
|
201
|
-
private markResponseRevalidating;
|
|
202
191
|
/**
|
|
203
192
|
* Guard the segment tier against a `keyGenerator` that returns a key colliding
|
|
204
193
|
* with a reserved tag-marker namespace: `__tag__/` (the KV marker key) or
|
|
@@ -212,17 +201,29 @@ export declare class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<T
|
|
|
212
201
|
*/
|
|
213
202
|
private isReservedSegmentKey;
|
|
214
203
|
/**
|
|
215
|
-
* Get cached entry data by key.
|
|
216
|
-
*
|
|
217
|
-
|
|
204
|
+
* Get cached entry data by key (readL1). On L1 miss, falls back to KV (L2)
|
|
205
|
+
* if configured; KV hits are promoted to L1 in the background.
|
|
206
|
+
*/
|
|
207
|
+
get(key: string): Promise<CacheGetResult | null | CacheReadError>;
|
|
208
|
+
/**
|
|
209
|
+
* The family's debug sink for one read; the document family is outside the
|
|
210
|
+
* debug surface (op is only get/getItem). Undefined when debug is off, so
|
|
211
|
+
* the hot path allocates no event.
|
|
212
|
+
* @internal
|
|
213
|
+
*/
|
|
214
|
+
private debugSink;
|
|
215
|
+
/**
|
|
216
|
+
* The L1 read of a family, which handles SWR atomically:
|
|
218
217
|
* - If stale and not already revalidating, marks as REVALIDATING and returns shouldRevalidate: true
|
|
219
218
|
* - If already REVALIDATING (and recent), returns shouldRevalidate: false
|
|
220
219
|
* - If fresh, returns shouldRevalidate: false
|
|
221
220
|
*
|
|
222
|
-
*
|
|
223
|
-
*
|
|
221
|
+
* Every degraded L1 read falls through to KV (readKv). The family methods
|
|
222
|
+
* return it unwrapped: an async wrapper adds two promises and two microtask
|
|
223
|
+
* ticks to every read.
|
|
224
|
+
* @internal
|
|
224
225
|
*/
|
|
225
|
-
|
|
226
|
+
private readL1;
|
|
226
227
|
/**
|
|
227
228
|
* Store entry data with TTL and optional SWR window.
|
|
228
229
|
* Resolves once the L1 write lands, per the SegmentCacheStore.set contract
|
|
@@ -236,9 +237,9 @@ export declare class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<T
|
|
|
236
237
|
*/
|
|
237
238
|
delete(key: string): Promise<boolean>;
|
|
238
239
|
/**
|
|
239
|
-
* Get a cached Response by key (for document-level caching).
|
|
240
|
-
*
|
|
241
|
-
*
|
|
240
|
+
* Get a cached Response by key (for document-level caching): see readL1.
|
|
241
|
+
* Its body streams to the client unread, outside the debug surface. Falls
|
|
242
|
+
* back to KV (L2) on L1 miss.
|
|
242
243
|
*/
|
|
243
244
|
getResponse(key: string): Promise<{
|
|
244
245
|
response: Response;
|
|
@@ -258,7 +259,7 @@ export declare class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<T
|
|
|
258
259
|
putResponse(key: string, response: Response, ttl: number, swr?: number, tags?: string[]): Promise<void>;
|
|
259
260
|
/**
|
|
260
261
|
* Get a cached function result by key.
|
|
261
|
-
* Follows the same SWR pattern as get() for segment caching.
|
|
262
|
+
* Follows the same SWR pattern as get() for segment caching (readL1).
|
|
262
263
|
* Falls back to KV (L2) on L1 miss.
|
|
263
264
|
*/
|
|
264
265
|
getItem(key: string): Promise<CacheItemResult | null>;
|
|
@@ -351,7 +352,7 @@ export declare class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<T
|
|
|
351
352
|
* caller's `tagHints`: cfTagHints may have evicted the key while the memo
|
|
352
353
|
* still holds it. A shell a tag marker rejects is dropped and read from
|
|
353
354
|
* the store too, which may hold a capture from after the marker (see
|
|
354
|
-
*
|
|
355
|
+
* readL1(), "Tag invalidation"), unless the request's own mask rejected it
|
|
355
356
|
* (declinesKvFallThrough).
|
|
356
357
|
*/
|
|
357
358
|
private readMemoizedShell;
|
|
@@ -538,15 +539,6 @@ export declare class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<T
|
|
|
538
539
|
* @internal
|
|
539
540
|
*/
|
|
540
541
|
private skipUncacheableTagSet;
|
|
541
|
-
/**
|
|
542
|
-
* Merge the internal tag headers onto an existing Headers instance. The
|
|
543
|
-
* from-scratch paths spread tagHeaderEntries() into an object-literal init;
|
|
544
|
-
* the document put/promote paths build a Headers first, so they .set() each
|
|
545
|
-
* entry instead — except `Cache-Tag`, which is APPENDED: a document author
|
|
546
|
-
* may have set their own Cache-Tag, and clobbering it would break their CDN
|
|
547
|
-
* purging. Append produces the comma-merged list CF expects.
|
|
548
|
-
*/
|
|
549
|
-
private setTagHeaders;
|
|
550
542
|
/** Read an entry's tags/taggedAt back from its headers. */
|
|
551
543
|
private readTagInfo;
|
|
552
544
|
/**
|
|
@@ -780,12 +772,27 @@ export declare class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<T
|
|
|
780
772
|
/** invalidateTags' marker writes, tag purge, and hooks. */
|
|
781
773
|
private writeTagInvalidation;
|
|
782
774
|
/**
|
|
783
|
-
* KV
|
|
784
|
-
*
|
|
785
|
-
*
|
|
775
|
+
* The KV (L2) read behind an L1 miss, for every family: a missing,
|
|
776
|
+
* timed-out, corrupt (kvGetOrEvict reports and evicts it), expired or
|
|
777
|
+
* tag-invalidated envelope is a miss, a read failure is the family's read
|
|
778
|
+
* error, and a hit is promoted to L1 in the background.
|
|
779
|
+
*
|
|
780
|
+
* A degraded L1 fall-through (body-timeout / non-200) passes
|
|
781
|
+
* `suppressRevalidate`: KV has no REVALIDATING herd guard, so N concurrent
|
|
782
|
+
* degraded reads would otherwise each spawn a render exactly when the colo
|
|
783
|
+
* is already struggling. The stale data is still served and promoted; only
|
|
784
|
+
* the revalidation is withheld.
|
|
785
|
+
* @internal
|
|
786
|
+
*/
|
|
787
|
+
private readKv;
|
|
788
|
+
/**
|
|
789
|
+
* Promote a KV hit to L1 in the background, under its remaining ttl, with
|
|
790
|
+
* its deadlines (so a promoted entry that later goes stale re-puts with the
|
|
791
|
+
* correct remaining ttl, see set()) and its tags (so it stays
|
|
792
|
+
* tag-invalidatable). The family builds the entry (toL1).
|
|
786
793
|
* @internal
|
|
787
794
|
*/
|
|
788
|
-
private
|
|
795
|
+
private promoteToL1;
|
|
789
796
|
/**
|
|
790
797
|
* Write segment data to KV.
|
|
791
798
|
*
|
|
@@ -794,29 +801,4 @@ export declare class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<T
|
|
|
794
801
|
* @internal
|
|
795
802
|
*/
|
|
796
803
|
private kvSetSegment;
|
|
797
|
-
/**
|
|
798
|
-
* Promote segment data from KV to L1 Cache API.
|
|
799
|
-
* @internal
|
|
800
|
-
*/
|
|
801
|
-
private promoteSegmentToL1;
|
|
802
|
-
/**
|
|
803
|
-
* KV fallback for function cache reads.
|
|
804
|
-
* @internal
|
|
805
|
-
*/
|
|
806
|
-
private kvGetItem;
|
|
807
|
-
/**
|
|
808
|
-
* Promote function cache data from KV to L1.
|
|
809
|
-
* @internal
|
|
810
|
-
*/
|
|
811
|
-
private promoteItemToL1;
|
|
812
|
-
/**
|
|
813
|
-
* KV fallback for document cache reads.
|
|
814
|
-
* @internal
|
|
815
|
-
*/
|
|
816
|
-
private kvGetResponse;
|
|
817
|
-
/**
|
|
818
|
-
* Promote document cache data from KV to L1.
|
|
819
|
-
* @internal
|
|
820
|
-
*/
|
|
821
|
-
private promoteResponseToL1;
|
|
822
804
|
}
|
|
@@ -37,7 +37,7 @@ export declare function kvKeyDigest(value: string): Promise<string>;
|
|
|
37
37
|
* of restarting it -- copying set()'s original full-window max-age would reset
|
|
38
38
|
* CF's retention clock on every re-arm and pin a perpetually-stale entry forever.
|
|
39
39
|
* An entry lacking a valid deadline (legacy/tampered) floors to max-age=1, so it
|
|
40
|
-
* hard-expires in ~1s and self-heals via KV. Mirrors
|
|
40
|
+
* hard-expires in ~1s and self-heals via KV. Mirrors promoteToL1's math.
|
|
41
41
|
* @internal
|
|
42
42
|
*/
|
|
43
43
|
export declare function remainingCacheControl(headers: Headers, now: number): string;
|