@rangojs/router 0.27.0 → 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/event-controller.d.ts +2 -1
- package/dist/types/browser/history-state.d.ts +3 -9
- 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/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 +5 -14
- 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 +4 -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 +34 -86
- 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/router-context.d.ts +7 -46
- 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 +1 -1
- 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/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 +9 -1
- 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/document-cache/SKILL.md +13 -1
- package/skills/handler-use/SKILL.md +1 -1
- package/skills/intercept/SKILL.md +17 -7
- package/skills/middleware/SKILL.md +18 -0
- package/skills/ppr/SKILL.md +18 -3
- package/skills/prerender/SKILL.md +39 -15
- package/skills/rango/SKILL.md +5 -1
- package/skills/server-actions/SKILL.md +8 -1
- package/skills/testing/response-routes.md +6 -4
- package/skills/use-cache/SKILL.md +46 -8
- package/src/__internal.ts +7 -1
- package/src/browser/connection-warmup.ts +3 -1
- package/src/browser/event-controller.ts +5 -3
- package/src/browser/history-state.ts +6 -12
- package/src/browser/navigation-bridge.ts +14 -13
- package/src/browser/navigation-client.ts +18 -25
- package/src/browser/navigation-store.ts +25 -27
- package/src/browser/navigation-transaction.ts +4 -1
- 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 +1 -0
- package/src/browser/segment-reconciler.ts +66 -53
- package/src/browser/server-action-bridge.ts +50 -57
- 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 +34 -13
- 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 +5 -16
- 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 +20 -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 +675 -726
- package/src/router/match-middleware/cache-store.ts +4 -8
- package/src/router/match-middleware/intercept-resolution.ts +3 -23
- package/src/router/match-middleware/segment-resolution.ts +34 -61
- package/src/router/middleware.ts +69 -11
- package/src/router/navigation-snapshot.ts +4 -4
- 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/route-snapshot.ts +2 -5
- package/src/router/router-context.ts +10 -95
- 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 +164 -349
- package/src/rsc/server-action.ts +87 -113
- package/src/rsc/shell-capture-constants.ts +1 -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/testing/dispatch.ts +223 -710
- package/src/testing/e2e/page-helpers.ts +2 -2
- package/src/testing/serve-shell-request.ts +23 -36
- package/src/types/cache-types.ts +6 -3
- package/src/types/error-types.ts +9 -1
- package/src/types/handler-context.ts +12 -1
- 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
|
@@ -86,10 +86,14 @@ export interface SegmentCacheStore<TEnv = unknown> {
|
|
|
86
86
|
* Return value becomes the final cache key (unless route overrides with `key` option).
|
|
87
87
|
*
|
|
88
88
|
* Resolution priority:
|
|
89
|
-
* 1. Route-level `key` function (
|
|
89
|
+
* 1. Route-level `key` function (replaces the URL part; the request kind stays)
|
|
90
90
|
* 2. Store-level `keyGenerator` (modifies default key)
|
|
91
91
|
* 3. Default key generation (prefix:pathname:params)
|
|
92
92
|
*
|
|
93
|
+
* Keep `defaultKey` in the result: its prefix names the request kind (a
|
|
94
|
+
* document, a navigation or an intercept navigation), whose records hold
|
|
95
|
+
* different segments. A result without it gives every kind one record.
|
|
96
|
+
*
|
|
93
97
|
* Return `defaultKey` unchanged to leave a request unpartitioned. An empty
|
|
94
98
|
* string is not a key: where the result partitions a nested cache() on
|
|
95
99
|
* another store, or a ppr shell, it fails key resolution, so the request
|
|
@@ -250,7 +254,7 @@ export interface SegmentCacheStore<TEnv = unknown> {
|
|
|
250
254
|
/**
|
|
251
255
|
* Declares the shell family present-but-inert: getShell/putShell exist but
|
|
252
256
|
* no-op (a custom store whose backing tier is conditionally unavailable).
|
|
253
|
-
*
|
|
257
|
+
* planShellCapture skips captures whose only write target is inert —
|
|
254
258
|
* the background render would be dead work that still occupies the
|
|
255
259
|
* per-isolate serialized capture queue (a promise-heavy route bakes for
|
|
256
260
|
* seconds per MISS with nothing stored). Absent/false means the family,
|
|
@@ -602,7 +606,7 @@ export type ShellSnapshotFamily = "segment" | "loader" | "handles";
|
|
|
602
606
|
* format (CachedEntryData `handles` + `handleOwners`). A Prerender + ppr
|
|
603
607
|
* route's handler layer comes from the prerender store, whose build-time
|
|
604
608
|
* entry has no loader push, so the entry keeps these for the HIT to restore
|
|
605
|
-
* as a doc record's (issue #1057,
|
|
609
|
+
* as a doc record's (issue #1057, decodeStoredEntry in cache-lookup.ts). An
|
|
606
610
|
* entry written before it (v0.21) has none and serves as it did.
|
|
607
611
|
*/
|
|
608
612
|
export type ShellSnapshotHandlesValue = Pick<CachedEntryData, "handles" | "handleOwners">;
|
|
@@ -326,8 +326,14 @@ export declare class VercelCacheStore<TEnv = unknown> implements SegmentCacheSto
|
|
|
326
326
|
* `taggedAt`. An entry without a stamp counts as older than any mask.
|
|
327
327
|
*/
|
|
328
328
|
private maskedForRequest;
|
|
329
|
-
/**
|
|
330
|
-
|
|
329
|
+
/**
|
|
330
|
+
* The read of a data family (get, getItem, getResponse): a failed read is
|
|
331
|
+
* the family's `readError`; a missing, corrupt, expired or masked entry is a
|
|
332
|
+
* miss, and a corrupt or expired one is evicted. The hit is built before the
|
|
333
|
+
* stale claim, so an entry that does not rebuild is evicted as corrupt with
|
|
334
|
+
* no revalidation lock written for it.
|
|
335
|
+
*/
|
|
336
|
+
private readRecord;
|
|
331
337
|
private toStoreKey;
|
|
332
338
|
private write;
|
|
333
339
|
/**
|
|
@@ -370,8 +376,4 @@ export declare class VercelCacheStore<TEnv = unknown> implements SegmentCacheSto
|
|
|
370
376
|
private clampTagsForWrite;
|
|
371
377
|
private safeDelete;
|
|
372
378
|
private emitDebug;
|
|
373
|
-
private asSegmentEnvelope;
|
|
374
|
-
private asItemEnvelope;
|
|
375
|
-
private asShellEnvelope;
|
|
376
|
-
private asResponseEnvelope;
|
|
377
379
|
}
|
|
@@ -1,21 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The wire markers of prefetches
|
|
3
|
-
* (
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* like segment-fragments.ts: the browser must not import the server modules
|
|
8
|
-
* that use them.
|
|
2
|
+
* The wire markers of prefetches: shared by the browser and the server
|
|
3
|
+
* (router/segment-resolution/prefetch-deferral.ts requestKind,
|
|
4
|
+
* rsc/prefetch-render-error.ts, rsc/rsc-rendering.ts). Dependency free, like
|
|
5
|
+
* segment-fragments.ts: the browser must not import the server modules that
|
|
6
|
+
* use them.
|
|
9
7
|
*/
|
|
10
8
|
/** Request header of a `<Link>` prefetch (browser/prefetch/fetch.ts). */
|
|
11
9
|
export declare const PREFETCH_HEADER = "X-Rango-Prefetch";
|
|
12
|
-
/** Query param of a fill request (browser/navigation-client.ts). */
|
|
13
|
-
export declare const FILL_PARAM = "_rsc_fill";
|
|
14
|
-
/**
|
|
15
|
-
* Query param of a stale request (browser/navigation-client.ts): `revalidate()`
|
|
16
|
-
* sees `stale: true` (router/navigation-snapshot.ts).
|
|
17
|
-
*/
|
|
18
|
-
export declare const STALE_PARAM = "_rsc_stale";
|
|
19
10
|
/**
|
|
20
11
|
* The last row of a prefetch whose render reported an error
|
|
21
12
|
* (rsc/prefetch-render-error.ts): a Flight hint with a code React does not
|
|
@@ -54,6 +54,37 @@ export declare function createDevPrerenderStore(devUrl: string): PrerenderStore;
|
|
|
54
54
|
* Returns null if no prerender data is available.
|
|
55
55
|
*/
|
|
56
56
|
export declare function createPrerenderStore(): PrerenderStore | null;
|
|
57
|
+
/**
|
|
58
|
+
* The segments of a prerendered URL's intercept variant (`/i`): the main
|
|
59
|
+
* variant's without the intercepted route's own (`belongsToRoute`: its
|
|
60
|
+
* handler, layouts and slots), then the intercept's. A render under an
|
|
61
|
+
* intercept skips the route's entry (resolveAllSegments), so the variant
|
|
62
|
+
* holds what a cache() intercept record holds. The producer
|
|
63
|
+
* (matchForPrerender) encodes `interceptHandles` for exactly these segments.
|
|
64
|
+
*/
|
|
65
|
+
export declare function interceptVariantSegments(segments: SerializedSegmentData[], interceptSegments: SerializedSegmentData[]): SerializedSegmentData[];
|
|
66
|
+
/**
|
|
67
|
+
* The intercept variant as served under the intercept the match selected
|
|
68
|
+
* (findInterceptForRoute): its main segments and that intercept's slot,
|
|
69
|
+
* `slotId` in `intercept:<routeName>`. The build bakes every intercept that
|
|
70
|
+
* can target the route, since it cannot evaluate when(). Null when the
|
|
71
|
+
* variant does not hold that slot: the request renders live. The handles
|
|
72
|
+
* string is kept whole; decodeStoredEntry (cache-lookup.ts) replays only the
|
|
73
|
+
* served segments' pushes.
|
|
74
|
+
*/
|
|
75
|
+
export declare function selectInterceptVariant(entry: PrerenderEntry, slotId: string, routeName: string): PrerenderEntry | null;
|
|
76
|
+
/**
|
|
77
|
+
* The manifest entries ([key, PrerenderEntry JSON]) one prerendered URL
|
|
78
|
+
* bakes, keyed as the production store's get() reads them. The intercept
|
|
79
|
+
* variant (`/i`) holds interceptVariantSegments with the handle string the
|
|
80
|
+
* producer encoded for it. Written by the build
|
|
81
|
+
* (vite/discovery/prerender-collection.ts) and serveShellRequest.
|
|
82
|
+
*/
|
|
83
|
+
export declare function prerenderManifestEntries(result: PrerenderEntry & {
|
|
84
|
+
routeName: string;
|
|
85
|
+
interceptSegments?: SerializedSegmentData[];
|
|
86
|
+
interceptHandles?: string;
|
|
87
|
+
}, paramHash: string): Array<[key: string, value: string]>;
|
|
57
88
|
/**
|
|
58
89
|
* Create a static segment store.
|
|
59
90
|
* Production only: backed by globalThis.__STATIC_MANIFEST injected at build time.
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* layers import this without pulling the trigger.
|
|
8
8
|
*/
|
|
9
9
|
import type { HandlerCacheConfig } from "../rsc/types.js";
|
|
10
|
-
import type { ShellCaptureDebugEvent } from "../rsc/shell-capture.js";
|
|
10
|
+
import type { ShellCaptureDebugEvent, ShellCaptureState } from "../rsc/shell-capture.js";
|
|
11
11
|
import type { PrerenderWarmCaches } from "./on-demand.js";
|
|
12
12
|
/** What one warm request did: written by the layers, read by the trigger. */
|
|
13
13
|
export interface PrerenderWarmRecord extends PrerenderWarmCaches {
|
|
@@ -33,7 +33,7 @@ export interface PrerenderWarmRecord extends PrerenderWarmCaches {
|
|
|
33
33
|
/** What the helpers read; a derived capture context inherits the record. */
|
|
34
34
|
export interface WarmContext {
|
|
35
35
|
_prerenderWarm?: PrerenderWarmRecord;
|
|
36
|
-
|
|
36
|
+
_shellCaptureState?: Pick<ShellCaptureState, "run">;
|
|
37
37
|
}
|
|
38
38
|
export declare function createWarmRecord(mode: PrerenderWarmRecord["mode"], cacheConfig: HandlerCacheConfig): PrerenderWarmRecord;
|
|
39
39
|
/** The mark is the object: a clone or a rebuilt request carries none. */
|
|
@@ -46,7 +46,7 @@ export declare function readWarmMark(request: Request): PrerenderWarmRecord | un
|
|
|
46
46
|
* "use cache" in-flight dedup lives outside the store, so a wrapper would
|
|
47
47
|
* miss both.
|
|
48
48
|
*
|
|
49
|
-
* False in the warm's own shell capture (`
|
|
49
|
+
* False in the warm's own shell capture (`_shellCaptureState`): it runs after
|
|
50
50
|
* the warm's writes settled and must replay them, or it would render every
|
|
51
51
|
* handler a second time and could bake another generation than the one just
|
|
52
52
|
* written.
|
|
@@ -264,8 +264,8 @@ export declare function isPrerenderPassthrough(value: unknown): value is Prerend
|
|
|
264
264
|
* A build handler signals passthrough by returning `ctx.passthrough()` (the
|
|
265
265
|
* PRERENDER_PASSTHROUGH sentinel), which lands on the segment's `component`.
|
|
266
266
|
* But when the route declares `loading()`, the handler result is deferred
|
|
267
|
-
* upstream (
|
|
268
|
-
* to the sentinel rather than the sentinel itself — a synchronous
|
|
267
|
+
* upstream (resolveEntryHandler), so `component` is a thenable
|
|
268
|
+
* resolving to the sentinel rather than the sentinel itself — a synchronous
|
|
269
269
|
* `isPrerenderPassthrough(component)` on the Promise returns false and the build
|
|
270
270
|
* bakes a corrupt artifact instead of deferring. Resolve thenables first.
|
|
271
271
|
*
|
|
@@ -32,3 +32,8 @@ export declare function publicRouteName(routeKey: string | undefined): string |
|
|
|
32
32
|
* Throws with a clear message when a reserved prefix is detected.
|
|
33
33
|
*/
|
|
34
34
|
export declare function validateUserRouteName(name: string): void;
|
|
35
|
+
/**
|
|
36
|
+
* The route key's last name segment ("item" for "shop.item"). An intercept
|
|
37
|
+
* that targets it is selected when none targets the full key (match-api.ts).
|
|
38
|
+
*/
|
|
39
|
+
export declare function localRouteName(routeKey: string): string;
|
|
@@ -45,10 +45,10 @@ export declare function invokeOnError<TEnv = any>(onError: OnErrorCallback<TEnv>
|
|
|
45
45
|
/**
|
|
46
46
|
* First non-undefined `pick(orphan)` over the routeless entries in
|
|
47
47
|
* `entry.layout` and, recursively, in theirs: depth-first in render order
|
|
48
|
-
* (resolveOrphanLayout in segment-resolution/
|
|
49
|
-
* entry nested in another renders (a layout() after a
|
|
50
|
-
* layout() in a routeless wrapper); a one-level scan
|
|
51
|
-
* intercepts it declares (#926).
|
|
48
|
+
* (resolveOrphanLayout in segment-resolution/revalidation.ts).
|
|
49
|
+
* Since #922 a routeless entry nested in another renders (a layout() after a
|
|
50
|
+
* bare cache() marker, a layout() in a routeless wrapper); a one-level scan
|
|
51
|
+
* missed the boundaries and intercepts it declares (#926).
|
|
52
52
|
*
|
|
53
53
|
* `skip` is the entry an upward walk came from. Only a bare cache() marker is
|
|
54
54
|
* both in its layout's layout[] and in the chain, and its subtree was already
|
|
@@ -190,9 +190,10 @@ export declare function observeSegmentHandler<C, R>(segmentId: string, spanId: s
|
|
|
190
190
|
* loop (request.start/end/error, cache.decision, ...).
|
|
191
191
|
* - segment-resolution/helpers.ts emits via a caller-provided report.telemetry
|
|
192
192
|
* sink rather than the ALS router context.
|
|
193
|
-
* - rsc/
|
|
194
|
-
* (request.origin-rejected), and
|
|
195
|
-
* handler.error) emit via
|
|
193
|
+
* - rsc/request-stages.ts timeoutResponse (request.timeout) and
|
|
194
|
+
* originRejectedResponse (request.origin-rejected), and rsc/handler.ts
|
|
195
|
+
* handleStore.onError (late-handle handler.error) emit via
|
|
196
|
+
* router.telemetry directly — they run outside the
|
|
196
197
|
* RouterContext ALS (only match()/matchPartial() enter it), so a
|
|
197
198
|
* getRouterContext() read there throws and the event would vanish.
|
|
198
199
|
*/
|
|
@@ -5,9 +5,8 @@
|
|
|
5
5
|
* functions for soft navigation (modals).
|
|
6
6
|
*/
|
|
7
7
|
import type { EntryData, InterceptEntry, InterceptSelectorContext } from "../server/context";
|
|
8
|
-
import type {
|
|
9
|
-
import type {
|
|
10
|
-
import type { RevalidationContext } from "./router-context.js";
|
|
8
|
+
import type { ResolvedSegment } from "../types";
|
|
9
|
+
import type { ResolutionPass } from "./segment-resolution/resolution-pass.js";
|
|
11
10
|
/**
|
|
12
11
|
* Check if an intercept's when conditions are satisfied.
|
|
13
12
|
* All when() functions must return true for the intercept to activate.
|
|
@@ -40,6 +39,19 @@ export declare function findInterceptForRoute(targetRouteKey: string, fromEntry:
|
|
|
40
39
|
} | null;
|
|
41
40
|
/** The segment id of `intercept`'s slot on `parentEntry`. */
|
|
42
41
|
export declare function interceptSlotId(parentEntry: EntryData, intercept: InterceptEntry): string;
|
|
42
|
+
/**
|
|
43
|
+
* The intercept a match selected (findInterceptForRoute), as its cache()
|
|
44
|
+
* record names it (CacheScope): the slot id, then `~` and its position among
|
|
45
|
+
* the intercepts its entry declares for the same slot and target route. Two
|
|
46
|
+
* such intercepts share the slot id, and the position tells them apart; one
|
|
47
|
+
* for another slot or route does not renumber it. `~` is unreserved in a
|
|
48
|
+
* URL, so a store that maps the key onto one unencoded keeps the whole key.
|
|
49
|
+
* Undefined when the match selected none.
|
|
50
|
+
*/
|
|
51
|
+
export declare function interceptRecordKey(selected: {
|
|
52
|
+
intercept: InterceptEntry;
|
|
53
|
+
entry: EntryData;
|
|
54
|
+
} | null): string | undefined;
|
|
43
55
|
/**
|
|
44
56
|
* Every segment id an intercept's slot owns, in order: the slot, then one
|
|
45
57
|
* loader segment per loader in declaration order, run or not. A request that
|
|
@@ -47,15 +59,19 @@ export declare function interceptSlotId(parentEntry: EntryData, intercept: Inter
|
|
|
47
59
|
*/
|
|
48
60
|
export declare function interceptSegmentIds(parentEntry: EntryData, intercept: InterceptEntry): string[];
|
|
49
61
|
/**
|
|
50
|
-
* Resolve an intercept entry: its slot segment, then its loader segments.
|
|
62
|
+
* Resolve an intercept entry: its slot segment, then its loader segments. The
|
|
63
|
+
* background re-render resolves with a pass that holds nothing
|
|
64
|
+
* (heldNothingPassInput, resolution-pass.ts): every segment renders fresh, and
|
|
65
|
+
* its loaders are skipped (skipLoaders), each registered for the handler's
|
|
66
|
+
* read.
|
|
51
67
|
*/
|
|
52
|
-
export declare function resolveInterceptEntry<TEnv>(interceptEntry: InterceptEntry, parentEntry: EntryData,
|
|
68
|
+
export declare function resolveInterceptEntry<TEnv>(pass: ResolutionPass<TEnv>, interceptEntry: InterceptEntry, parentEntry: EntryData, belongsToRoute: boolean, options?: {
|
|
53
69
|
/**
|
|
54
70
|
* Set ONLY by the post-response background re-render (stale background
|
|
55
71
|
* revalidation), whose sole purpose is to re-render the segment tree to
|
|
56
|
-
* populate the cache: a handler error
|
|
57
|
-
* error boundary, so a failure is never cached. Never
|
|
58
|
-
* foreground path.
|
|
72
|
+
* populate the cache: a handler error is reported, then rejects instead
|
|
73
|
+
* of rendering the error boundary, so a failure is never cached. Never
|
|
74
|
+
* set on the foreground path.
|
|
59
75
|
*/
|
|
60
76
|
background?: boolean;
|
|
61
77
|
}): Promise<ResolvedSegment[]>;
|
|
@@ -63,4 +79,4 @@ export declare function resolveInterceptEntry<TEnv>(interceptEntry: InterceptEnt
|
|
|
63
79
|
* The loader segments of a cached intercept slot, on a cache hit: the slot
|
|
64
80
|
* keeps its cached component and layout, its loaders are never cached.
|
|
65
81
|
*/
|
|
66
|
-
export declare function resolveInterceptLoadersOnly<TEnv>(interceptEntry: InterceptEntry, parentEntry: EntryData,
|
|
82
|
+
export declare function resolveInterceptLoadersOnly<TEnv>(pass: ResolutionPass<TEnv>, interceptEntry: InterceptEntry, parentEntry: EntryData, belongsToRoute: boolean): Promise<ResolvedSegment[]>;
|
|
@@ -63,7 +63,6 @@
|
|
|
63
63
|
*
|
|
64
64
|
* Handler Context:
|
|
65
65
|
* - handlerContext: Context passed to loaders
|
|
66
|
-
* - loaderPromises: Memoized loader promises
|
|
67
66
|
*
|
|
68
67
|
* Intercepts:
|
|
69
68
|
* - interceptResult: Detected intercept (if soft navigation)
|
|
@@ -114,15 +113,8 @@ import type { EntryData, InterceptSelectorContext, MetricsStore } from "../serve
|
|
|
114
113
|
import type { HandlerContext, ResolvedSegment } from "../types.js";
|
|
115
114
|
import type { RouteMatchResult } from "./pattern-matching.js";
|
|
116
115
|
import type { InterceptResult } from "./router-context.js";
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
*/
|
|
120
|
-
export interface ActionContext {
|
|
121
|
-
actionId?: string;
|
|
122
|
-
actionUrl?: URL;
|
|
123
|
-
actionResult?: any;
|
|
124
|
-
formData?: FormData;
|
|
125
|
-
}
|
|
116
|
+
import type { ResolutionPassInput } from "./segment-resolution/resolution-pass.js";
|
|
117
|
+
import type { ActionContext } from "./types.js";
|
|
126
118
|
/**
|
|
127
119
|
* Match context containing all state for the match pipeline
|
|
128
120
|
*/
|
|
@@ -143,7 +135,6 @@ export interface MatchContext<TEnv = any> {
|
|
|
143
135
|
routeKey: string;
|
|
144
136
|
localRouteName: string;
|
|
145
137
|
handlerContext: HandlerContext<any, TEnv>;
|
|
146
|
-
loaderPromises: Map<string, Promise<any>>;
|
|
147
138
|
routeMap: Record<string, string>;
|
|
148
139
|
metricsStore: MetricsStore | undefined;
|
|
149
140
|
Store: any;
|
|
@@ -174,6 +165,8 @@ export interface MatchContext<TEnv = any> {
|
|
|
174
165
|
* stored, so a record can be older than the copy the client holds after it.
|
|
175
166
|
*/
|
|
176
167
|
export declare function rendersLive(ctx: Pick<MatchContext, "isAction" | "stale">): boolean;
|
|
168
|
+
/** This match as the input of a revalidating resolution pass (resolution-pass.ts). */
|
|
169
|
+
export declare function resolutionPassInput<TEnv>(ctx: MatchContext<TEnv>): ResolutionPassInput<TEnv>;
|
|
177
170
|
/**
|
|
178
171
|
* Mutable state that flows through the pipeline
|
|
179
172
|
*/
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
2
|
import type { ErrorBoundaryHandler, ErrorInfo, ErrorPhase, MatchResult } from "../types";
|
|
3
3
|
import { type EntryData, type InterceptEntry, type InterceptSelectorContext } from "../server/context.js";
|
|
4
|
-
import type { MatchApiDeps } from "./types.js";
|
|
4
|
+
import type { ActionContext, MatchApiDeps } from "./types.js";
|
|
5
5
|
import type { RouterContext } from "./router-context.js";
|
|
6
|
-
import { type ActionContext } from "./match-context.js";
|
|
7
6
|
import type { MiddlewareFn } from "./middleware.js";
|
|
8
7
|
import { type TelemetrySink } from "./telemetry.js";
|
|
9
8
|
export interface MatchHandlerDeps<TEnv = any> {
|
|
@@ -33,11 +32,8 @@ export interface MatchHandlers<TEnv = any> {
|
|
|
33
32
|
handler: MiddlewareFn;
|
|
34
33
|
params: Record<string, string>;
|
|
35
34
|
}>;
|
|
36
|
-
responseType?: string;
|
|
37
|
-
handler?: Function;
|
|
38
35
|
params?: Record<string, string>;
|
|
39
|
-
|
|
40
|
-
manifestEntry?: EntryData;
|
|
36
|
+
routeKey?: string;
|
|
41
37
|
} | null>;
|
|
42
38
|
}
|
|
43
39
|
/**
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
* |
|
|
37
37
|
* v
|
|
38
38
|
* +---------------------------+
|
|
39
|
-
* |
|
|
39
|
+
* | FRESH segment pass | Fresh resolution (no revalidation)
|
|
40
40
|
* | + resolveIntercepts() | Ensures complete components
|
|
41
41
|
* +---------------------------+
|
|
42
42
|
* |
|
|
@@ -94,10 +94,12 @@
|
|
|
94
94
|
* FRESH RESOLUTION (NO REVALIDATION)
|
|
95
95
|
* ===================================
|
|
96
96
|
*
|
|
97
|
-
* Both full and partial requests
|
|
97
|
+
* Both full and partial requests resolve with a FRESH pass (without
|
|
98
98
|
* revalidation logic) to ensure all segments have complete components.
|
|
99
99
|
* Using revalidation-aware resolution would produce null components
|
|
100
|
-
* for skipped segments, which would corrupt the cache entry.
|
|
100
|
+
* for skipped segments, which would corrupt the cache entry. Under an
|
|
101
|
+
* intercept the walk still skips the intercepted route's entry, as the MISS
|
|
102
|
+
* does: an intercept: record never holds the route's page.
|
|
101
103
|
*/
|
|
102
104
|
import type { ResolvedSegment } from "../../types.js";
|
|
103
105
|
import type { MatchContext, MatchPipelineState } from "../match-context.js";
|
|
@@ -118,23 +120,11 @@ import { type RequestContext } from "../../server/request-context.js";
|
|
|
118
120
|
* MAX_REVALIDATION_INTERVAL, as after a refresh that throws.
|
|
119
121
|
*
|
|
120
122
|
* Runs on a DERIVED request context that owns the per-render state the
|
|
121
|
-
* foreground reads while it is still producing the page
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
* cache-scope.ts), so a swap sent live pushes into this render.
|
|
127
|
-
* setupLoaderAccess binds the store at setup, so it runs inside the
|
|
128
|
-
* derived context too.
|
|
129
|
-
* - _metricsStore: undefined, and the DSL store below has `metrics` unset
|
|
130
|
-
* (track() reads that one), so nothing lands on the foreground's perf
|
|
131
|
-
* timeline. ctx.Store.run closes over ctx.Store, so the derived store
|
|
132
|
-
* needs its own run.
|
|
133
|
-
* - response writes (headers, cookies, status, onResponse callbacks) go to
|
|
134
|
-
* a throwaway context (whose status gates the write, above) and are
|
|
135
|
-
* dropped: a layout above the cache() boundary is outside the header
|
|
136
|
-
* guard and an error boundary sets a status, so they would otherwise
|
|
137
|
-
* reach the live response.
|
|
123
|
+
* foreground reads while it is still producing the page:
|
|
124
|
+
* RENDER_PASS_FIELDS["background-revalidation"] (server/render-pass.ts) lists
|
|
125
|
+
* each field and why. The DSL store below has `metrics` unset too (track()
|
|
126
|
+
* reads that one), so nothing lands on the foreground's perf timeline;
|
|
127
|
+
* ctx.Store.run closes over ctx.Store, so the derived store needs its own run.
|
|
138
128
|
* runWithRequestContext also re-establishes the request ALS, which a waitUntil
|
|
139
129
|
* task on workerd loses; the DSL store is a different ALS (build context).
|
|
140
130
|
*/
|
|
@@ -1,95 +1,44 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Cache Lookup Middleware
|
|
3
3
|
*
|
|
4
|
-
* First middleware in the pipeline.
|
|
4
|
+
* First middleware in the pipeline. Before segment resolution runs, it serves
|
|
5
|
+
* a stored match from the first source that answers:
|
|
5
6
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* +---------------------+
|
|
13
|
-
* | Is action request? |──yes──> yield* source (pass through)
|
|
14
|
-
* +---------------------+
|
|
15
|
-
* | no
|
|
16
|
-
* v
|
|
17
|
-
* +---------------------+
|
|
18
|
-
* | Cache enabled? |──no───> yield* source (pass through)
|
|
19
|
-
* +---------------------+
|
|
20
|
-
* | yes
|
|
21
|
-
* v
|
|
22
|
-
* +---------------------+
|
|
23
|
-
* | Lookup cache |
|
|
24
|
-
* | (pathname, params) |
|
|
25
|
-
* +---------------------+
|
|
26
|
-
* |
|
|
27
|
-
* +-----+-----+
|
|
28
|
-
* | |
|
|
29
|
-
* miss hit
|
|
30
|
-
* | |
|
|
31
|
-
* v v
|
|
32
|
-
* yield* Set state.cacheHit = true
|
|
33
|
-
* source Set state.shouldRevalidate
|
|
34
|
-
* | |
|
|
35
|
-
* | v
|
|
36
|
-
* | +---------------------------+
|
|
37
|
-
* | | For each cached segment: |
|
|
38
|
-
* | | - Apply revalidation |
|
|
39
|
-
* | | - Set component = null |
|
|
40
|
-
* | | if client has it |
|
|
41
|
-
* | +---------------------------+
|
|
42
|
-
* | |
|
|
43
|
-
* | v
|
|
44
|
-
* | +---------------------------+
|
|
45
|
-
* | | Resolve fresh loaders | <-- Loaders are NEVER cached
|
|
46
|
-
* | | (always fresh data) |
|
|
47
|
-
* | +---------------------------+
|
|
48
|
-
* | |
|
|
49
|
-
* | v
|
|
50
|
-
* | yield cached segments
|
|
51
|
-
* | yield fresh loader segments
|
|
52
|
-
* | |
|
|
53
|
-
* +-----------+
|
|
54
|
-
* |
|
|
55
|
-
* v
|
|
56
|
-
* next middleware
|
|
7
|
+
* 1. Prerender: the writable on-demand overlay, then the bundled build
|
|
8
|
+
* manifest. A live render (an action or a stale partial) reads them too
|
|
9
|
+
* when the route has no live handler (not a Passthrough).
|
|
10
|
+
* 2. The dev Static store (`__PRERENDER_DEV_URL`, isStaticPrerender entries).
|
|
11
|
+
* 3. The route's cache() record (the segment cache). An action or a stale
|
|
12
|
+
* partial renders live (rendersLive) and reads no record.
|
|
57
13
|
*
|
|
14
|
+
* Every source serves through serveStoredSegments: pre-rendering is caching
|
|
15
|
+
* at build time, so a prerender entry is a cache hit through the same segment
|
|
16
|
+
* path. When no source answers, the request passes through to
|
|
17
|
+
* segment-resolution.
|
|
58
18
|
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
19
|
+
* A STORED HIT
|
|
20
|
+
* ============
|
|
61
21
|
*
|
|
62
|
-
* Cache HIT:
|
|
63
22
|
* - state.cacheHit = true signals downstream middleware to skip
|
|
64
|
-
* -
|
|
65
|
-
* - Loaders are always re-resolved
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
* Cache MISS:
|
|
69
|
-
* - Passes through to segment-resolution middleware
|
|
70
|
-
* - No segments yielded from this middleware
|
|
71
|
-
*
|
|
72
|
-
* Loaders:
|
|
73
|
-
* - NEVER cached in the segment cache
|
|
74
|
-
* - Always resolved fresh on every request
|
|
75
|
-
* - Ensures data freshness even with cached UI components
|
|
76
|
-
* - Segment cache staleness does NOT propagate to loader revalidation;
|
|
23
|
+
* - A segment the client already holds and keeps has its component nullified
|
|
24
|
+
* - Loaders are always re-resolved fresh: never cached or pre-rendered.
|
|
25
|
+
* Segment cache staleness does NOT propagate to loader revalidation;
|
|
77
26
|
* loaders use their own revalidation rules (actionId, user-defined)
|
|
27
|
+
* - A cache() record sets state.shouldRevalidate, which triggers background
|
|
28
|
+
* SWR when the record was stale
|
|
78
29
|
*
|
|
30
|
+
* REVALIDATION RULES (cache() record)
|
|
31
|
+
* ===================================
|
|
79
32
|
*
|
|
80
|
-
*
|
|
81
|
-
* ==================
|
|
82
|
-
*
|
|
83
|
-
* Each cached segment is evaluated against its revalidation rules:
|
|
33
|
+
* Each record segment the client holds is evaluated against its rules:
|
|
84
34
|
*
|
|
85
|
-
* 1. No rules defined ->
|
|
35
|
+
* 1. No rules defined -> re-render the route's own segments when the search
|
|
36
|
+
* or the route params changed; otherwise skip (nullify component)
|
|
86
37
|
* 2. Rules return false -> skip re-render (nullify component)
|
|
87
38
|
* 3. Rules return true -> re-render (keep component)
|
|
88
39
|
*
|
|
89
|
-
* Revalidation context includes
|
|
90
|
-
*
|
|
91
|
-
* - Request object
|
|
92
|
-
* - Action context (if POST)
|
|
40
|
+
* Revalidation context includes the previous/next URL and params, the request
|
|
41
|
+
* and the action context (if POST).
|
|
93
42
|
*/
|
|
94
43
|
import type { ResolvedSegment } from "../../types.js";
|
|
95
44
|
import { type EntryData } from "../../server/context.js";
|
|
@@ -112,7 +61,7 @@ export declare function setPrerenderStoreForTests(store: PrerenderStore | null |
|
|
|
112
61
|
* misses the store and renders live, and replay — including its heal
|
|
113
62
|
* capture — must stay available for it (withCacheStore records the doc
|
|
114
63
|
* record on that path; state.cacheSource is not "prerender"). The store
|
|
115
|
-
* memoizes per routeKey/paramHash, so this probe and
|
|
64
|
+
* memoizes per routeKey/paramHash, so this probe and readPrerenderSource's
|
|
116
65
|
* subsequent get() share one underlying load.
|
|
117
66
|
*/
|
|
118
67
|
export declare function prerenderEntryExists(routeKey: string | undefined, params: Record<string, string>, pathname: string, entries: EntryData[]): Promise<boolean>;
|
|
@@ -127,14 +76,13 @@ export type GeneratorMiddleware<T> = (source: AsyncGenerator<T>) => AsyncGenerat
|
|
|
127
76
|
/**
|
|
128
77
|
* Creates cache lookup middleware
|
|
129
78
|
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
* -
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
79
|
+
* The middleware is serveStoredSegments. It serves a stored match when one
|
|
80
|
+
* answers, in this order: the prerender overlay and build store (Prerender
|
|
81
|
+
* and on-demand routes), the dev Static store, then the route's cache()
|
|
82
|
+
* record. It yields the stored segments and the loaders resolved fresh and
|
|
83
|
+
* sets state.cacheHit (and state.shouldRevalidate for a cache() record, for
|
|
84
|
+
* background SWR).
|
|
136
85
|
*
|
|
137
|
-
* If
|
|
138
|
-
* - Passes through to next middleware
|
|
86
|
+
* If nothing answers, passes through to the next middleware.
|
|
139
87
|
*/
|
|
140
88
|
export declare function withCacheLookup<TEnv>(ctx: MatchContext<TEnv>, state: MatchPipelineState): GeneratorMiddleware<ResolvedSegment>;
|
|
@@ -29,15 +29,16 @@
|
|
|
29
29
|
* yes no
|
|
30
30
|
* | |
|
|
31
31
|
* v v
|
|
32
|
-
*
|
|
33
|
-
* Segments Segments
|
|
34
|
-
* | |
|
|
32
|
+
* FRESH pass partial pass
|
|
35
33
|
* | | (compares with prev state)
|
|
36
34
|
* | | (handles null components)
|
|
37
35
|
* | |
|
|
38
36
|
* +-----------+
|
|
39
37
|
* |
|
|
40
38
|
* v
|
|
39
|
+
* resolveAllSegments()
|
|
40
|
+
* |
|
|
41
|
+
* v
|
|
41
42
|
* +---------------------------+
|
|
42
43
|
* | Update state: |
|
|
43
44
|
* | - state.segments |
|
|
@@ -54,13 +55,14 @@
|
|
|
54
55
|
* RESOLUTION MODES
|
|
55
56
|
* ================
|
|
56
57
|
*
|
|
58
|
+
* Both use resolveAllSegments().
|
|
59
|
+
*
|
|
57
60
|
* Full Match (document request):
|
|
58
|
-
* -
|
|
59
|
-
*
|
|
61
|
+
* - A FRESH pass (freshPassInput): no revalidation logic (nothing to
|
|
62
|
+
* compare against)
|
|
60
63
|
* - Simple resolution of all route entries
|
|
61
64
|
*
|
|
62
65
|
* Partial Match (navigation):
|
|
63
|
-
* - Uses resolveAllSegmentsWithRevalidation()
|
|
64
66
|
* - Compares current vs previous params/URL
|
|
65
67
|
* - Sets component = null for segments client already has
|
|
66
68
|
* - Respects custom revalidation rules
|
|
@@ -1,12 +1,23 @@
|
|
|
1
1
|
import type { RouterContext } from "./router-context.js";
|
|
2
|
-
import type { ResolveSegmentOptions } from "./segment-resolution.js";
|
|
3
|
-
import type { EntryData } from "../server/context";
|
|
4
2
|
import type { PartialPrerenderProps } from "../urls/pattern-types.js";
|
|
5
|
-
import type { HandlerContext, ResolvedSegment } from "../types";
|
|
6
3
|
import type { SerializedSegmentData } from "../cache/types.js";
|
|
7
4
|
import type { RouteMatchResult } from "./pattern-matching.js";
|
|
8
5
|
import type { RouterVersions } from "../router-versions.js";
|
|
9
6
|
import type { OnDemandRouteConfig } from "../prerender/on-demand.js";
|
|
7
|
+
/**
|
|
8
|
+
* An intercept a navigation can select over the route that the build does
|
|
9
|
+
* not bake: its HIT misses (selectInterceptVariant) and it renders live,
|
|
10
|
+
* with the request instead of BuildContext.
|
|
11
|
+
* - `same-slot`: another intercept on its layout fills the same slot.
|
|
12
|
+
* - `handler-response` / `layout-response`: its handler or layout returned a
|
|
13
|
+
* Response for this URL.
|
|
14
|
+
* - `local-name`: it targets the route's localRouteName, which the build
|
|
15
|
+
* never bakes.
|
|
16
|
+
*/
|
|
17
|
+
export interface LiveIntercept {
|
|
18
|
+
slot: string;
|
|
19
|
+
reason: "same-slot" | "handler-response" | "layout-response" | "local-name";
|
|
20
|
+
}
|
|
10
21
|
export interface PrerenderMatchDeps<TEnv = any> {
|
|
11
22
|
/** Owning router id; scopes bake-time root-scope/search-schema lookups the
|
|
12
23
|
* same way reqCtx._routerId does at runtime (issue #762). */
|
|
@@ -21,7 +32,7 @@ export interface PrerenderMatchDeps<TEnv = any> {
|
|
|
21
32
|
findMatch: (pathname: string) => RouteMatchResult<TEnv> | null | Promise<RouteMatchResult<TEnv> | null>;
|
|
22
33
|
buildRouterContext: () => RouterContext<TEnv>;
|
|
23
34
|
mergedRouteMap: Record<string, string>;
|
|
24
|
-
resolveAllSegments:
|
|
35
|
+
resolveAllSegments: RouterContext<TEnv>["resolveAllSegments"];
|
|
25
36
|
}
|
|
26
37
|
/**
|
|
27
38
|
* Build-time pre-render match. Resolves segments with a BuildContext
|
|
@@ -46,9 +57,13 @@ onDemand?: boolean): Promise<{
|
|
|
46
57
|
routeName: string;
|
|
47
58
|
params: Record<string, string>;
|
|
48
59
|
interceptSegments?: SerializedSegmentData[];
|
|
49
|
-
/** RSC-encoded
|
|
50
|
-
*
|
|
60
|
+
/** RSC-encoded handle map for the intercept artifact: the intercept's
|
|
61
|
+
* pushes and those of the main segments the intercepted route does not
|
|
62
|
+
* own; the sinks store it as-is. */
|
|
51
63
|
interceptHandles?: string;
|
|
64
|
+
/** The intercepts the intercept variant does not hold, for the build's
|
|
65
|
+
* warning (warnLiveIntercepts). */
|
|
66
|
+
liveIntercepts?: LiveIntercept[];
|
|
52
67
|
passthrough?: true;
|
|
53
68
|
/** On-demand only: the render hit `notFound()` and nothing else failed. */
|
|
54
69
|
notFound?: true;
|