@rangojs/router 0.18.0 → 0.19.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/types/browser/event-controller.d.ts +3 -3
- package/dist/types/browser/history-state.d.ts +2 -0
- package/dist/types/browser/navigation-transaction.d.ts +20 -2
- package/dist/types/browser/partial-update.d.ts +16 -1
- package/dist/types/browser/prefetch/cache.d.ts +6 -6
- package/dist/types/browser/react/Link.d.ts +19 -9
- package/dist/types/browser/react/context.d.ts +2 -2
- package/dist/types/browser/react/location-state-shared.d.ts +95 -56
- package/dist/types/browser/react/location-state.d.ts +1 -1
- package/dist/types/browser/transition-when.d.ts +80 -0
- package/dist/types/browser/types.d.ts +104 -9
- package/dist/types/build/generate-manifest.d.ts +8 -0
- package/dist/types/cache/background-task.d.ts +24 -2
- package/dist/types/cache/cache-exec-scope.d.ts +31 -0
- package/dist/types/cache/cache-key-utils.d.ts +44 -13
- package/dist/types/cache/cache-policy.d.ts +1 -1
- package/dist/types/cache/cache-runtime.d.ts +7 -0
- package/dist/types/cache/cache-scope.d.ts +117 -35
- package/dist/types/cache/cache-tag.d.ts +24 -4
- package/dist/types/cache/cf/cf-cache-store.d.ts +55 -44
- package/dist/types/cache/cf/cf-shell-frame.d.ts +1 -1
- package/dist/types/cache/cf/cf-tag-marker-memo.d.ts +0 -15
- package/dist/types/cache/document-cache.d.ts +10 -0
- package/dist/types/cache/handle-snapshot.d.ts +40 -8
- package/dist/types/cache/invalidation-order.d.ts +23 -0
- package/dist/types/cache/request-tag-mask.d.ts +54 -0
- package/dist/types/cache/shell-snapshot.d.ts +88 -141
- package/dist/types/cache/tag-invalidation.d.ts +38 -14
- package/dist/types/cache/types.d.ts +68 -61
- package/dist/types/cache/vercel/vercel-cache-store.d.ts +23 -16
- package/dist/types/client-urls/navigation.d.ts +28 -2
- package/dist/types/client-urls/server-projection.d.ts +5 -2
- package/dist/types/client-urls/types.d.ts +5 -5
- package/dist/types/client.d.ts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.rsc.d.ts +1 -1
- package/dist/types/route-definition/helpers-types.d.ts +11 -11
- package/dist/types/route-name.d.ts +7 -0
- package/dist/types/router/error-handling.d.ts +1 -1
- package/dist/types/router/intercept-resolution.d.ts +2 -0
- package/dist/types/router/match-context.d.ts +5 -0
- package/dist/types/router/match-middleware/background-revalidation.d.ts +0 -4
- package/dist/types/router/router-options.d.ts +4 -1
- package/dist/types/router/segment-resolution/loader-cache.d.ts +18 -1
- package/dist/types/router/segment-resolution/loader-mask.d.ts +3 -4
- package/dist/types/router/segment-resolution/loader-snapshot.d.ts +14 -40
- package/dist/types/router/segment-resolution/mask-nested.d.ts +11 -3
- package/dist/types/router/segment-resolution/view-transition-default.d.ts +7 -5
- package/dist/types/router/transition-when.d.ts +24 -10
- package/dist/types/rsc/attach-transition-when.d.ts +18 -0
- package/dist/types/rsc/full-payload.d.ts +14 -7
- package/dist/types/rsc/response-cache-serve.d.ts +15 -12
- package/dist/types/rsc/shell-build-manifest.d.ts +4 -3
- package/dist/types/rsc/shell-capture-constants.d.ts +77 -20
- package/dist/types/rsc/shell-capture.d.ts +78 -81
- package/dist/types/rsc/shell-serve.d.ts +19 -48
- package/dist/types/rsc/types.d.ts +2 -0
- package/dist/types/segment-system.d.ts +7 -0
- package/dist/types/server/context.d.ts +89 -61
- package/dist/types/server/cookie-store.d.ts +30 -18
- package/dist/types/server/handle-store.d.ts +52 -1
- package/dist/types/server/request-context.d.ts +66 -45
- package/dist/types/server/request-headers.d.ts +44 -0
- package/dist/types/server.d.ts +1 -0
- package/dist/types/testing/e2e/index.d.ts +1 -1
- package/dist/types/testing/index.d.ts +3 -2
- package/dist/types/testing/internal/action-id.d.ts +7 -0
- package/dist/types/testing/location-state-key.d.ts +24 -0
- package/dist/types/testing/render-route.d.ts +17 -1
- package/dist/types/testing/run-transition-when.d.ts +44 -69
- package/dist/types/testing/serve-shell-request.d.ts +7 -6
- package/dist/types/testing/shell-status.d.ts +34 -22
- package/dist/types/transition-when-ref.d.ts +79 -0
- package/dist/types/types/cache-types.d.ts +15 -3
- package/dist/types/types/index.d.ts +1 -1
- package/dist/types/types/segments.d.ts +86 -71
- package/dist/types/urls/path-helper-types.d.ts +3 -4
- package/dist/types/urls/pattern-types.d.ts +3 -4
- package/dist/types/vite/plugins/transition-when-hoist.d.ts +45 -0
- package/dist/vite/index.js +960 -97
- package/package.json +1 -1
- package/skills/cache-guide/SKILL.md +76 -49
- package/skills/caching/SKILL.md +167 -69
- package/skills/client-urls/SKILL.md +1 -1
- package/skills/comparison/references/framework-comparison.md +8 -5
- package/skills/document-cache/SKILL.md +24 -0
- package/skills/hooks/SKILL.md +3 -1
- package/skills/hooks/navigation.md +23 -2
- package/skills/hooks/state.md +98 -6
- package/skills/intercept/SKILL.md +29 -12
- package/skills/loader/SKILL.md +52 -21
- package/skills/middleware/SKILL.md +18 -0
- package/skills/migrate-nextjs/SKILL.md +3 -3
- package/skills/observability/SKILL.md +6 -5
- package/skills/parallel/SKILL.md +1 -1
- package/skills/ppr/SKILL.md +129 -77
- package/skills/prerender/SKILL.md +3 -3
- package/skills/rango/SKILL.md +25 -6
- package/skills/route/SKILL.md +2 -0
- package/skills/testing/SKILL.md +27 -25
- package/skills/testing/cache-prerender.md +9 -9
- package/skills/testing/client-components.md +45 -3
- package/skills/testing/loader.md +3 -2
- package/skills/testing/middleware.md +1 -0
- package/skills/testing/predicates.md +49 -49
- package/skills/testing/render-handler.md +1 -0
- package/skills/testing/serve-shell-request.md +14 -0
- package/skills/testing/server-actions.md +9 -3
- package/skills/theme/SKILL.md +8 -4
- package/skills/typesafety/env-and-bindings.md +8 -0
- package/skills/use-cache/SKILL.md +64 -19
- package/skills/view-transitions/SKILL.md +150 -29
- package/src/__augment-tests__/augmented.check.ts +23 -0
- package/src/browser/event-controller.ts +4 -4
- package/src/browser/history-state.ts +52 -1
- package/src/browser/link-interceptor.ts +4 -0
- package/src/browser/navigation-bridge.ts +77 -18
- package/src/browser/navigation-client.ts +4 -3
- package/src/browser/navigation-store.ts +43 -1
- package/src/browser/navigation-transaction.ts +31 -11
- package/src/browser/partial-update.ts +146 -35
- package/src/browser/prefetch/cache.ts +6 -6
- package/src/browser/prefetch/fetch.ts +2 -2
- package/src/browser/react/Link.tsx +38 -33
- package/src/browser/react/NavigationProvider.tsx +2 -2
- package/src/browser/react/context.ts +2 -2
- package/src/browser/react/location-state-shared.ts +241 -49
- package/src/browser/react/location-state.ts +5 -2
- package/src/browser/rsc-router.tsx +4 -0
- package/src/browser/server-action-bridge.ts +84 -15
- package/src/browser/transition-when.ts +205 -0
- package/src/browser/types.ts +124 -10
- package/src/build/generate-manifest.ts +77 -1
- package/src/cache/background-task.ts +55 -2
- package/src/cache/cache-exec-scope.ts +48 -1
- package/src/cache/cache-key-utils.ts +56 -16
- package/src/cache/cache-policy.ts +9 -4
- package/src/cache/cache-runtime.ts +197 -144
- package/src/cache/cache-scope.ts +304 -112
- package/src/cache/cache-tag.ts +105 -13
- package/src/cache/cf/cf-cache-store.ts +152 -76
- package/src/cache/cf/cf-shell-frame.ts +2 -2
- package/src/cache/cf/cf-tag-marker-memo.ts +11 -100
- package/src/cache/document-cache.ts +53 -7
- package/src/cache/handle-snapshot.ts +52 -9
- package/src/cache/invalidation-order.ts +84 -0
- package/src/cache/request-tag-mask.ts +147 -0
- package/src/cache/shell-snapshot.ts +130 -348
- package/src/cache/tag-invalidation.ts +57 -51
- package/src/cache/types.ts +71 -67
- package/src/cache/vercel/vercel-cache-store.ts +61 -58
- package/src/client-urls/client-root.tsx +8 -4
- package/src/client-urls/client-urls.ts +8 -6
- package/src/client-urls/navigation.ts +55 -4
- package/src/client-urls/server-projection.ts +31 -10
- package/src/client-urls/types.ts +12 -5
- package/src/client.tsx +2 -0
- package/src/host/cookie-handler.ts +2 -1
- package/src/index.rsc.ts +3 -0
- package/src/index.ts +3 -0
- package/src/loader-redirect.tsx +7 -3
- package/src/prerender/build-shell-capture.ts +155 -146
- package/src/route-definition/dsl-helpers.ts +2 -0
- package/src/route-definition/helpers-types.ts +11 -11
- package/src/route-name.ts +12 -0
- package/src/router/content-negotiation.ts +4 -1
- package/src/router/error-handling.ts +5 -2
- package/src/router/handler-context.ts +10 -7
- package/src/router/intercept-resolution.ts +11 -1
- package/src/router/loader-resolution.ts +28 -3
- package/src/router/logging.ts +5 -3
- package/src/router/match-api.ts +62 -34
- package/src/router/match-context.ts +5 -0
- package/src/router/match-handlers.ts +9 -29
- package/src/router/match-middleware/background-revalidation.ts +3 -5
- package/src/router/match-middleware/cache-lookup.ts +35 -19
- package/src/router/match-middleware/cache-store.ts +15 -9
- package/src/router/match-result.ts +1 -0
- package/src/router/middleware.ts +2 -5
- package/src/router/navigation-snapshot.ts +6 -5
- package/src/router/prerender-match.ts +4 -0
- package/src/router/request-classification.ts +7 -4
- package/src/router/router-options.ts +4 -1
- package/src/router/segment-resolution/fresh.ts +0 -4
- package/src/router/segment-resolution/loader-cache.ts +150 -25
- package/src/router/segment-resolution/loader-mask.ts +3 -4
- package/src/router/segment-resolution/loader-snapshot.ts +15 -78
- package/src/router/segment-resolution/mask-nested.ts +47 -22
- package/src/router/segment-resolution/revalidation.ts +0 -3
- package/src/router/segment-resolution/view-transition-default.ts +6 -21
- package/src/router/telemetry.ts +6 -3
- package/src/router/transition-when.ts +34 -52
- package/src/router.ts +2 -1
- package/src/rsc/attach-transition-when.ts +47 -0
- package/src/rsc/full-payload.ts +30 -10
- package/src/rsc/handler.ts +12 -10
- package/src/rsc/loader-fetch.ts +2 -1
- package/src/rsc/manifest-init.ts +4 -0
- package/src/rsc/origin-guard.ts +8 -5
- package/src/rsc/progressive-enhancement.ts +7 -30
- package/src/rsc/response-cache-serve.ts +68 -80
- package/src/rsc/response-route-handler.ts +2 -2
- package/src/rsc/rsc-rendering.ts +206 -252
- package/src/rsc/server-action.ts +8 -20
- package/src/rsc/shell-build-manifest.ts +22 -20
- package/src/rsc/shell-capture-constants.ts +136 -20
- package/src/rsc/shell-capture.ts +352 -589
- package/src/rsc/shell-serve.ts +73 -109
- package/src/rsc/ssr-setup.ts +3 -2
- package/src/rsc/types.ts +2 -0
- package/src/segment-system.tsx +40 -7
- package/src/server/context.ts +189 -124
- package/src/server/cookie-store.ts +153 -127
- package/src/server/handle-store.ts +245 -27
- package/src/server/request-context.ts +123 -84
- package/src/server/request-headers.ts +134 -0
- package/src/server.ts +4 -0
- package/src/testing/dispatch.ts +4 -7
- package/src/testing/e2e/index.ts +1 -0
- package/src/testing/index.ts +5 -0
- package/src/testing/internal/action-id.ts +25 -0
- package/src/testing/internal/context.ts +1 -1
- package/src/testing/location-state-key.ts +45 -0
- package/src/testing/render-handler.ts +1 -1
- package/src/testing/render-route.tsx +109 -16
- package/src/testing/run-client-revalidate.ts +3 -19
- package/src/testing/run-loader.ts +5 -1
- package/src/testing/run-transition-when.ts +109 -172
- package/src/testing/serve-shell-request.ts +10 -7
- package/src/testing/shell-status.ts +60 -56
- package/src/transition-when-ref.ts +220 -0
- package/src/types/cache-types.ts +15 -3
- package/src/types/index.ts +3 -0
- package/src/types/segments.ts +94 -91
- package/src/urls/path-helper-types.ts +3 -4
- package/src/urls/pattern-types.ts +3 -4
- package/src/vite/discovery/discover-routers.ts +3 -0
- package/src/vite/discovery/shell-prerender-phase.ts +0 -2
- package/src/vite/discovery/virtual-module-codegen.ts +16 -6
- package/src/vite/plugins/transition-when-hoist.ts +1064 -0
- package/src/vite/rango.ts +2 -0
- package/src/vite/router-discovery.ts +75 -5
- package/dist/types/rsc/transition-gate.d.ts +0 -23
- package/src/rsc/transition-gate.ts +0 -86
|
@@ -41,6 +41,12 @@ export interface RscMetadata {
|
|
|
41
41
|
resolvedIds?: string[];
|
|
42
42
|
/** Merged route params from the matched route */
|
|
43
43
|
params?: Record<string, string>;
|
|
44
|
+
/**
|
|
45
|
+
* The matched route's name (include name prefix applied), when the route is
|
|
46
|
+
* named. The browser keeps it per history entry for transition({ when })'s
|
|
47
|
+
* `from.routeName` / `to.routeName` (browser/transition-when.ts).
|
|
48
|
+
*/
|
|
49
|
+
routeName?: string;
|
|
44
50
|
/**
|
|
45
51
|
* State of named slots for this route match
|
|
46
52
|
* Key is slot name (e.g., "@modal"), value is slot state
|
|
@@ -246,6 +252,17 @@ export interface SegmentState {
|
|
|
246
252
|
currentUrl: string;
|
|
247
253
|
currentSegmentIds: string[];
|
|
248
254
|
}
|
|
255
|
+
/**
|
|
256
|
+
* What the router remembers about one history entry for transition({ when })
|
|
257
|
+
* (NavigationStore.rememberDisplayedEntry).
|
|
258
|
+
*
|
|
259
|
+
* @internal This type is an implementation detail and may change without notice.
|
|
260
|
+
*/
|
|
261
|
+
export interface HistoryEntryMemory {
|
|
262
|
+
readonly routeName: string | undefined;
|
|
263
|
+
/** The entry's `history.state` as last recorded. */
|
|
264
|
+
readonly state: unknown;
|
|
265
|
+
}
|
|
249
266
|
/**
|
|
250
267
|
* Navigation update emitted when UI should re-render
|
|
251
268
|
*
|
|
@@ -265,11 +282,51 @@ export interface NavigationUpdate {
|
|
|
265
282
|
};
|
|
266
283
|
}
|
|
267
284
|
/**
|
|
268
|
-
*
|
|
269
|
-
* -
|
|
270
|
-
*
|
|
285
|
+
* Plain object accepted as {@link PlainHistoryState}. The `any` string index
|
|
286
|
+
* admits interface-typed values (an `unknown` index would reject interfaces,
|
|
287
|
+
* which carry no implicit index signature). The `never` members reject:
|
|
288
|
+
* - a single typed entry (`GridState(value)` without the array) — its
|
|
289
|
+
* `__rsc_ls_*` fields would be spread onto history.state and
|
|
290
|
+
* `useLocationState(GridState)` would read `undefined`;
|
|
291
|
+
* - functions, including a location-state definition passed uncalled
|
|
292
|
+
* (`Symbol.hasInstance` comes from `Function.prototype`), which throw
|
|
293
|
+
* `DataCloneError`;
|
|
294
|
+
* - arrays and other iterables (`Symbol.iterator`), so an array must match the
|
|
295
|
+
* typed-entry or plain-array member instead;
|
|
296
|
+
* - built-ins tagged with `Symbol.toStringTag` (`Promise`, `WeakMap`,
|
|
297
|
+
* `WeakSet`), which throw `DataCloneError`. The cloneable tagged ones
|
|
298
|
+
* (`Map`, `Set`, `ArrayBuffer`, typed arrays) have their own members.
|
|
299
|
+
*
|
|
300
|
+
* Members are not checked: a function, symbol, or React element inside a
|
|
301
|
+
* plain object still compiles, as does a top-level `ReactElement` or DOM node
|
|
302
|
+
* (an object with none of the keys above).
|
|
303
|
+
*/
|
|
304
|
+
export interface PlainHistoryObject {
|
|
305
|
+
readonly [key: string]: any;
|
|
306
|
+
readonly __rsc_ls_key?: never;
|
|
307
|
+
readonly __rsc_ls_value?: never;
|
|
308
|
+
readonly __rsc_ls_lazy?: never;
|
|
309
|
+
readonly [Symbol.iterator]?: never;
|
|
310
|
+
readonly [Symbol.hasInstance]?: never;
|
|
311
|
+
readonly [Symbol.toStringTag]?: never;
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Plain (untyped) navigation state, stored under `history.state.state` and
|
|
315
|
+
* read with `useLocationState<T>()`. A structured-clone-safe value: primitives,
|
|
316
|
+
* arrays, `Map`/`Set`, `ArrayBuffer`, typed arrays, and plain objects. Excludes
|
|
317
|
+
* functions, symbols, `Promise`/`WeakMap`/`WeakSet`, and objects carrying
|
|
318
|
+
* `__rsc_ls_*` keys (a typed entry passed without its array). Arrays, `Map`,
|
|
319
|
+
* and `Set` are checked element by element; plain object members are not
|
|
320
|
+
* checked (see {@link PlainHistoryObject}).
|
|
271
321
|
*/
|
|
272
|
-
export type
|
|
322
|
+
export type PlainHistoryState = string | number | boolean | bigint | null | undefined | readonly PlainHistoryState[] | ReadonlyMap<PlainHistoryState, PlainHistoryState> | ReadonlySet<PlainHistoryState> | ArrayBuffer | ArrayBufferView | PlainHistoryObject;
|
|
323
|
+
/**
|
|
324
|
+
* State value for `router.push()` / `router.replace()` / `<Link state>`.
|
|
325
|
+
* - `readonly LocationStateEntry[]`: typed entries from `createLocationState()`
|
|
326
|
+
* definitions, e.g. `[GridState({ count: 3 })]` (recommended)
|
|
327
|
+
* - {@link PlainHistoryState}: plain structured-clone-safe state
|
|
328
|
+
*/
|
|
329
|
+
export type HistoryState = readonly import("./react/location-state-shared.js").LocationStateEntry[] | PlainHistoryState;
|
|
273
330
|
/**
|
|
274
331
|
* Options for navigation operations
|
|
275
332
|
*/
|
|
@@ -295,6 +352,22 @@ export interface NavigateOptions {
|
|
|
295
352
|
* ```
|
|
296
353
|
*/
|
|
297
354
|
revalidate?: boolean;
|
|
355
|
+
/**
|
|
356
|
+
* Set to `false` to present this navigation without a transition: the
|
|
357
|
+
* commit is urgent and every `<ViewTransition>` class resolves to `"none"`,
|
|
358
|
+
* the same result as a `transition({ when })` predicate returning `false`.
|
|
359
|
+
* No `when` predicate is called. Back/forward, action and revalidation
|
|
360
|
+
* commits are unaffected (they are not started by this call).
|
|
361
|
+
*
|
|
362
|
+
* @default true (the route's transition config applies)
|
|
363
|
+
*
|
|
364
|
+
* @example
|
|
365
|
+
* ```tsx
|
|
366
|
+
* router.push("/photos/2", { transition: false });
|
|
367
|
+
* <Link to="/photos/2" transition={false}>Next</Link>
|
|
368
|
+
* ```
|
|
369
|
+
*/
|
|
370
|
+
transition?: boolean;
|
|
298
371
|
/**
|
|
299
372
|
* State to pass to history.pushState/replaceState
|
|
300
373
|
* Accessible via useLocationState() hook.
|
|
@@ -316,14 +389,21 @@ export interface NavigateOptions {
|
|
|
316
389
|
* // Plain static state
|
|
317
390
|
* navigate("/product", { state: { from: "list" } });
|
|
318
391
|
*
|
|
319
|
-
* //
|
|
320
|
-
* navigate("/product", { state: ()
|
|
392
|
+
* // Compile errors (and a dev-mode runtime error for untyped callers):
|
|
393
|
+
* navigate("/product", { state: ProductState(p) }); // entry without the array
|
|
394
|
+
* navigate("/product", { state: [ProductState] }); // definition not called
|
|
321
395
|
* ```
|
|
322
396
|
*/
|
|
323
397
|
state?: HistoryState;
|
|
324
398
|
}
|
|
325
|
-
/**
|
|
326
|
-
|
|
399
|
+
/**
|
|
400
|
+
* @internal Extended options used only within the navigation bridge. `state`
|
|
401
|
+
* is widened to `unknown`: the redirect lanes pass state already resolved to
|
|
402
|
+
* a flat `history.state` record, and in dev Link passes an uncalled
|
|
403
|
+
* definition through to resolveNavigationState's check.
|
|
404
|
+
*/
|
|
405
|
+
export interface NavigateOptionsInternal extends Omit<NavigateOptions, "state"> {
|
|
406
|
+
state?: unknown;
|
|
327
407
|
/** Skip segment cache (used by redirect-with-state to force re-render) */
|
|
328
408
|
_skipCache?: boolean;
|
|
329
409
|
}
|
|
@@ -402,6 +482,21 @@ export interface NavigationStore {
|
|
|
402
482
|
setSegmentIds(ids: string[]): void;
|
|
403
483
|
getHistoryKey(): string;
|
|
404
484
|
setHistoryKey(key: string): void;
|
|
485
|
+
/**
|
|
486
|
+
* Per-history-entry memory for transition({ when }) sources: record the
|
|
487
|
+
* entry on screen (keyed by its `history.state.key`) with its current
|
|
488
|
+
* `history.state` and, when given, its route name (kept from the last
|
|
489
|
+
* record otherwise; every push/replace creates a new key, so a stale name
|
|
490
|
+
* never carries to another entry). Called after every commit, restore and
|
|
491
|
+
* state merge.
|
|
492
|
+
*/
|
|
493
|
+
rememberDisplayedEntry(routeName?: string): void;
|
|
494
|
+
/**
|
|
495
|
+
* The memory of the entry on screen, or of `entryKey`. At popstate
|
|
496
|
+
* history.state already belongs to the destination, so back/forward reads
|
|
497
|
+
* the entry being LEFT from here. In-memory only: empty after a reload.
|
|
498
|
+
*/
|
|
499
|
+
getHistoryEntryMemory(entryKey?: string): HistoryEntryMemory | undefined;
|
|
405
500
|
/** Monotonic token of the most recently committed navigation. */
|
|
406
501
|
getNavInstance(): number;
|
|
407
502
|
cacheSegmentsForHistory(historyKey: string, segments: ResolvedSegment[], handleData?: HandleData): void;
|
|
@@ -517,7 +612,7 @@ export interface ServerActionBridgeConfig {
|
|
|
517
612
|
* Navigation bridge for handling client-side navigation
|
|
518
613
|
*/
|
|
519
614
|
export interface NavigationBridge {
|
|
520
|
-
navigate(url: string, options?:
|
|
615
|
+
navigate(url: string, options?: NavigateOptionsInternal): Promise<void>;
|
|
521
616
|
refresh(): Promise<void>;
|
|
522
617
|
handlePopstate(): Promise<void>;
|
|
523
618
|
registerLinkInterception(): () => void;
|
|
@@ -93,6 +93,14 @@ export declare function generateManifestFull<TEnv>(urlpatterns: UrlPatterns<TEnv
|
|
|
93
93
|
* EntryData map built below is local; this is the only seam that surfaces it.
|
|
94
94
|
*/
|
|
95
95
|
collectClientFallbackRef?: (refKey: string) => void;
|
|
96
|
+
/**
|
|
97
|
+
* Fail on an invalid transition({ when }): a non-function, or a plain
|
|
98
|
+
* (server) function where a client reference is required. Only the Vite
|
|
99
|
+
* plugin's discovery passes it: it evaluates the tree in the react-server
|
|
100
|
+
* graph, the one place a "use client" import is told apart from a server
|
|
101
|
+
* function (transition-when-ref.ts).
|
|
102
|
+
*/
|
|
103
|
+
validateTransitionWhen?: boolean;
|
|
96
104
|
}): Promise<FullManifest>;
|
|
97
105
|
/**
|
|
98
106
|
* Generate TypeScript code for the manifest
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Background Task Runner
|
|
3
3
|
*
|
|
4
|
-
* Unified helper for scheduling async work via waitUntil
|
|
5
|
-
*
|
|
4
|
+
* Unified helper for scheduling async work via waitUntil, and the two bounded
|
|
5
|
+
* waits the PPR shell capture puts on background work (raceDeadline,
|
|
6
|
+
* settleGrowing). When waitUntil is unavailable, falls back to blocking or
|
|
7
|
+
* skipping.
|
|
6
8
|
*/
|
|
7
9
|
interface WaitUntilHost {
|
|
8
10
|
waitUntil?: (fn: () => Promise<void>) => void;
|
|
@@ -18,4 +20,24 @@ interface WaitUntilHost {
|
|
|
18
20
|
* @returns A promise when blocking fallback is used, void otherwise.
|
|
19
21
|
*/
|
|
20
22
|
export declare function runBackground(host: WaitUntilHost | null | undefined, task: () => Promise<void>, blockWhenNoWaitUntil?: boolean): Promise<void> | void;
|
|
23
|
+
/**
|
|
24
|
+
* Race `work` against an absolute deadline (epoch ms), keeping its value. The
|
|
25
|
+
* losing work is not cancelled (a router match has no abort signal) and its
|
|
26
|
+
* late rejection is swallowed. The timer is unref'd, so a pending deadline
|
|
27
|
+
* never keeps a Node dev process alive.
|
|
28
|
+
*/
|
|
29
|
+
export declare function raceDeadline<T>(work: Promise<T>, deadline: number): Promise<{
|
|
30
|
+
done: true;
|
|
31
|
+
value: T;
|
|
32
|
+
} | {
|
|
33
|
+
done: false;
|
|
34
|
+
}>;
|
|
35
|
+
/**
|
|
36
|
+
* Wait until every promise in `list` has settled, including ones appended
|
|
37
|
+
* while waiting (a settled write can schedule a nested one: cacheRoute
|
|
38
|
+
* schedules its store.set in a second waitUntil), or until `deadline` (epoch
|
|
39
|
+
* ms). Resolves true when the list drained, false at the deadline. Never
|
|
40
|
+
* mutates `list`: a later call waits for what is still pending.
|
|
41
|
+
*/
|
|
42
|
+
export declare function settleGrowing(list: readonly Promise<unknown>[], deadline: number): Promise<boolean>;
|
|
21
43
|
export {};
|
|
@@ -31,6 +31,37 @@
|
|
|
31
31
|
export interface CacheExecScope {
|
|
32
32
|
readonly parent?: CacheExecScope;
|
|
33
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Run a callback whose identity reads never reach a shared entry, so
|
|
36
|
+
* guardIdentityRead (server/context.ts) lets them through and records
|
|
37
|
+
* nothing (#976):
|
|
38
|
+
*
|
|
39
|
+
* - a cache's own decisions and metadata: a `key()`, a store `keyGenerator`
|
|
40
|
+
* (cache-policy.ts resolveCacheKey), a `condition()` (cache-scope.ts
|
|
41
|
+
* conditionAllows, loader-cache.ts) and a `tags()` function
|
|
42
|
+
* (cache-policy.ts resolveTagsOption). The value picks the entry, whether
|
|
43
|
+
* one is used, or how it is invalidated; it is never rendered. Reading the
|
|
44
|
+
* request there is the documented way to partition an entry;
|
|
45
|
+
* - the router's `onError` (router/error-handling.ts invokeOnError): it
|
|
46
|
+
* observes, and a render error can reach it inside a capture or a cached
|
|
47
|
+
* scope.
|
|
48
|
+
*
|
|
49
|
+
* Scar: a ppr capture resolves its doc record key, and the record's tags,
|
|
50
|
+
* again under the capture context; once `ctx.request.headers` was guarded, a
|
|
51
|
+
* keyGenerator or tags() reading it refused every capture of the route.
|
|
52
|
+
*
|
|
53
|
+
* The exemption is async-local, so it would follow everything the callback
|
|
54
|
+
* starts. A "use cache" body (runWithCacheExecScope), a loader body
|
|
55
|
+
* (server/context.ts runInsideLoaderBodyScope) and a segment funnel
|
|
56
|
+
* (getContext().runWithStore) end it on entry (endIdentityExempt). Scar: a
|
|
57
|
+
* key() that awaited a "use cache" function reading cookies() stored the
|
|
58
|
+
* first visitor's cookie and served it to the next.
|
|
59
|
+
*/
|
|
60
|
+
export declare function runIdentityExempt<T>(fn: () => T): T;
|
|
61
|
+
/** True inside runIdentityExempt, and not in a scope started from it. */
|
|
62
|
+
export declare function isInsideIdentityExempt(): boolean;
|
|
63
|
+
/** Run `fn` with the identity exemption ended (see runIdentityExempt). */
|
|
64
|
+
export declare function endIdentityExempt<T>(fn: () => T): T;
|
|
34
65
|
/**
|
|
35
66
|
* Run fn with the "use cache" execution scope active. Continuations spawned
|
|
36
67
|
* from fn's synchronous kickoff inherit the scope; parallel chains do not.
|
|
@@ -42,17 +42,48 @@ export declare function sortedRouteParams(params: Record<string, string> | undef
|
|
|
42
42
|
*/
|
|
43
43
|
export declare function cacheKeyBase(host: string, pathname: string, searchParams?: URLSearchParams, params?: Record<string, string>, filter?: SearchParamsFilter): string;
|
|
44
44
|
/**
|
|
45
|
-
* The
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* (CacheScope.resolveKeyFrom). One part is returned raw, so a single keyed
|
|
49
|
-
* scope keeps its key byte for byte. Two or more are joined by `|`, each
|
|
50
|
-
* URI-encoded (like partitionShellKey, rsc/shell-capture-constants.ts): an
|
|
51
|
-
* encoded part holds no `|`, so every tuple maps to its own key, of any
|
|
52
|
-
* depth. Raw, `("a|b", "c")` and `("a", "b|c")` named one record. A composed
|
|
53
|
-
* key holds no `:` either, so a single raw result with one (a prefixed
|
|
54
|
-
* `tier:...`, a `doc:` default key) never equals it; an unprefixed raw result
|
|
55
|
-
* can. Shared with the testing helper `shellCacheKey`, which composes a
|
|
56
|
-
* nested partition the same way.
|
|
45
|
+
* The prefix of a `key()` result's part in a record key (#975), and of a
|
|
46
|
+
* loader's own `key()` result after its `loader:<id>:` namespace (#1009,
|
|
47
|
+
* loader-cache.ts loaderKeyFromResult).
|
|
57
48
|
*/
|
|
58
|
-
export declare
|
|
49
|
+
export declare const KEY_PART_PREFIX = "key:";
|
|
50
|
+
/**
|
|
51
|
+
* A cache() record key, or ppr shell partition, from its parts
|
|
52
|
+
* (CacheScope.resolveKeyFrom, CacheScope.resolvePartition): the `key()`
|
|
53
|
+
* results of the scope's cache() chain, outermost first, then its default
|
|
54
|
+
* parts: the keyGenerator results of enclosing scopes on another store
|
|
55
|
+
* (#974) and, for a record key under a scope without its own `key()`, its
|
|
56
|
+
* default key (or its store's keyGenerator result, #970).
|
|
57
|
+
*
|
|
58
|
+
* Key scheme invariant (#975). A `key()` result is often request input,
|
|
59
|
+
* and a record key has no route or scope discriminator (the store reads
|
|
60
|
+
* `store.get(key)`), so a result that equals another record's key writes
|
|
61
|
+
* one route's content under the other's entry. Before #975 a single
|
|
62
|
+
* `key()` result was stored raw: the header value `doc:localhost/pricing`
|
|
63
|
+
* named /pricing's default-keyed record, and `gold|doc%3Alocalhost%2Fpricing`
|
|
64
|
+
* named gold's nested /pricing record (#970). So every part is encoded:
|
|
65
|
+
*
|
|
66
|
+
* - a `key()` part is `key:` plus `encodeURIComponent(result)`: it starts
|
|
67
|
+
* with `key:` and holds no `|` and no other `:`;
|
|
68
|
+
* - a default part is `encodeURIComponent(value)`: it holds no `:` or `|`;
|
|
69
|
+
* an enclosing store's keyGenerator result equal to the default key is an
|
|
70
|
+
* empty part, so each store keeps its position (CacheScope
|
|
71
|
+
* positionalParts);
|
|
72
|
+
* - one `key()` part is the key; two or more parts are joined by `|`,
|
|
73
|
+
* `key()` parts first;
|
|
74
|
+
* - a lone default part stays raw: with no `key()` on the chain the record
|
|
75
|
+
* key is the default key or the store's keyGenerator result, unchanged.
|
|
76
|
+
*
|
|
77
|
+
* Why nothing collides: the router's default keys (`doc:`, `partial:`,
|
|
78
|
+
* `intercept:`, `response:<type>:`) never start with `key:` and hold a `:`.
|
|
79
|
+
* A namespaced `key()` result starts with `key:` and holds no `|`. A
|
|
80
|
+
* composed key holds a `|` and either starts with `key:` or holds no `:`.
|
|
81
|
+
* Among composed keys, splitting on `|` recovers each part, a part's kind
|
|
82
|
+
* (a `key:` prefix, or no `:` at all) and its value. Pinned by the collision
|
|
83
|
+
* probe in src/cache/__tests__/cache-scope-chain.test.ts. A keyGenerator
|
|
84
|
+
* result is the store's own namespace, as before.
|
|
85
|
+
*
|
|
86
|
+
* Shared with the testing helper `shellCacheKey`, so a test builds the
|
|
87
|
+
* production partition.
|
|
88
|
+
*/
|
|
89
|
+
export declare function composeCacheKeys(keyResults: readonly string[], defaultParts?: readonly string[]): string;
|
|
@@ -71,6 +71,6 @@ export declare function computeExpiration(ttlSeconds: number, swrSeconds?: numbe
|
|
|
71
71
|
staleAt: number;
|
|
72
72
|
expiresAt: number;
|
|
73
73
|
};
|
|
74
|
-
export declare function resolveCacheKey(keyFn: ((ctx: RequestContext) => string | Promise<string>) | undefined, store: SegmentCacheStore | null, defaultKey: string
|
|
74
|
+
export declare function resolveCacheKey(keyFn: ((ctx: RequestContext) => string | Promise<string>) | undefined, store: SegmentCacheStore | null, defaultKey: string): Promise<string>;
|
|
75
75
|
export declare function resolveTagsOption<TEnv>(tags: string[] | ((ctx: RequestContext<TEnv>) => string[]) | undefined, ctx: RequestContext<TEnv> | undefined, label: string): string[] | undefined;
|
|
76
76
|
export declare function resolveCacheStore(explicitStore: SegmentCacheStore | undefined): SegmentCacheStore | null;
|
|
@@ -40,6 +40,13 @@ export { isCachedFunction };
|
|
|
40
40
|
* identical arg sets.
|
|
41
41
|
*/
|
|
42
42
|
export declare function replyToCacheKey(encoded: string | FormData): Promise<string>;
|
|
43
|
+
/**
|
|
44
|
+
* @internal Reset this module's per-isolate state: the in-flight leaders a
|
|
45
|
+
* follower would join for up to IN_FLIGHT_LEADER_MAX_WAIT_MS, and the
|
|
46
|
+
* once-per-function warnings. Tests only (testing/serve-shell-request.ts
|
|
47
|
+
* resetShellTestState), never while a request is in flight.
|
|
48
|
+
*/
|
|
49
|
+
export declare function resetCacheRuntimeForTests(): void;
|
|
43
50
|
/**
|
|
44
51
|
* Register a function as a cached function.
|
|
45
52
|
* Called by the Vite transform for each "use cache" function.
|
|
@@ -10,8 +10,9 @@
|
|
|
10
10
|
import type { PartialCacheOptions } from "../types.js";
|
|
11
11
|
import type { ResolvedSegment } from "../types.js";
|
|
12
12
|
import type { SegmentCacheStore } from "./types.js";
|
|
13
|
+
import { type ExecutionStart } from "./tag-invalidation.js";
|
|
14
|
+
import { type OwnedPushDelivery } from "./handle-snapshot.js";
|
|
13
15
|
import type { RequestContext } from "../server/request-context.js";
|
|
14
|
-
export declare function resolveCacheTags(config: PartialCacheOptions | false, ctx: RequestContext | undefined): string[] | undefined;
|
|
15
16
|
type CacheKeyFn = NonNullable<PartialCacheOptions["key"]>;
|
|
16
17
|
/**
|
|
17
18
|
* Discriminated outcome of a route cache lookup — see
|
|
@@ -53,6 +54,19 @@ export declare class CacheScope {
|
|
|
53
54
|
* a ppr route).
|
|
54
55
|
*/
|
|
55
56
|
readonly boundary?: string | undefined;
|
|
57
|
+
/**
|
|
58
|
+
* Awaited on every lookup HIT: the implicit doc scope's marker `onHit`
|
|
59
|
+
* (createShellImplicitDocScope), which arms a partial replay's bake-lane
|
|
60
|
+
* loader pins before the route's loaders resolve.
|
|
61
|
+
*/
|
|
62
|
+
private readonly onHit?;
|
|
63
|
+
/**
|
|
64
|
+
* The record key of the implicit doc scope of a document HIT tail
|
|
65
|
+
* (createShellImplicitDocScope): the shell entry's own `docKey`, used as
|
|
66
|
+
* is. Not a `key()`, which would be namespaced (#975) and miss the
|
|
67
|
+
* record.
|
|
68
|
+
*/
|
|
69
|
+
private readonly fixedKey?;
|
|
56
70
|
readonly config: PartialCacheOptions | false;
|
|
57
71
|
readonly parent: CacheScope | null;
|
|
58
72
|
/** Explicit store from cache() options, if specified */
|
|
@@ -69,6 +83,29 @@ export declare class CacheScope {
|
|
|
69
83
|
readonly keyFns: readonly CacheKeyFn[];
|
|
70
84
|
/** Whether this scope's own config sets `key()` (the last of keyFns). */
|
|
71
85
|
private readonly hasOwnKey;
|
|
86
|
+
/**
|
|
87
|
+
* The `condition()` predicates gating this scope, outermost first: every
|
|
88
|
+
* cache() on the parent chain that sets one, this scope's last (#974). A
|
|
89
|
+
* read or write needs all of them to allow it (conditionAllows). Before,
|
|
90
|
+
* only the innermost config's predicate ran, so an outer condition()
|
|
91
|
+
* refusing a request still let a nested cache() read and write.
|
|
92
|
+
*/
|
|
93
|
+
private readonly conditions;
|
|
94
|
+
/**
|
|
95
|
+
* The `tags` options of this scope and every cache() on the parent chain,
|
|
96
|
+
* outermost first (#974): a nested record carries them all (resolveTags),
|
|
97
|
+
* so `updateTag(outerTag)` evicts it and the shells built from it.
|
|
98
|
+
*/
|
|
99
|
+
private readonly tagOptions;
|
|
100
|
+
/**
|
|
101
|
+
* The enclosing enabled scopes without a `key()` of their own whose
|
|
102
|
+
* `store` option differs from this scope's, outermost first: a store
|
|
103
|
+
* keyGenerator of theirs partitions this scope's records too (#974,
|
|
104
|
+
* resolvePartitionParts). On the same store the keyGenerator already
|
|
105
|
+
* applies through this scope's own default key, or its own `key()`
|
|
106
|
+
* overrides it (#970).
|
|
107
|
+
*/
|
|
108
|
+
private readonly storeScopes;
|
|
72
109
|
constructor(config: PartialCacheOptions | false, parent?: CacheScope | null, defaultKeyPrefix?: "doc" | undefined,
|
|
73
110
|
/**
|
|
74
111
|
* @internal shortCode of the outermost cache() entry of this scope's
|
|
@@ -77,7 +114,20 @@ export declare class CacheScope {
|
|
|
77
114
|
* Undefined covers the whole matched chain (the implicit shell doc scope,
|
|
78
115
|
* a ppr route).
|
|
79
116
|
*/
|
|
80
|
-
boundary?: string | undefined
|
|
117
|
+
boundary?: string | undefined,
|
|
118
|
+
/**
|
|
119
|
+
* Awaited on every lookup HIT: the implicit doc scope's marker `onHit`
|
|
120
|
+
* (createShellImplicitDocScope), which arms a partial replay's bake-lane
|
|
121
|
+
* loader pins before the route's loaders resolve.
|
|
122
|
+
*/
|
|
123
|
+
onHit?: (() => void | Promise<void>) | undefined,
|
|
124
|
+
/**
|
|
125
|
+
* The record key of the implicit doc scope of a document HIT tail
|
|
126
|
+
* (createShellImplicitDocScope): the shell entry's own `docKey`, used as
|
|
127
|
+
* is. Not a `key()`, which would be namespaced (#975) and miss the
|
|
128
|
+
* record.
|
|
129
|
+
*/
|
|
130
|
+
fixedKey?: string | undefined);
|
|
81
131
|
/**
|
|
82
132
|
* @internal Whether a segment belongs to this scope's cache entry. ShortCodes are
|
|
83
133
|
* hierarchical (server/context.ts getShortCode: parent shortCode + include
|
|
@@ -130,17 +180,21 @@ export declare class CacheScope {
|
|
|
130
180
|
* request: a ppr route's shell partition (resolvePartition) and the record
|
|
131
181
|
* lookup share the `key()` runs, and a rejection is shared too.
|
|
132
182
|
*
|
|
133
|
-
* With
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
* (
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
183
|
+
* With partition parts on the chain (resolvePartitionParts: the `key()`
|
|
184
|
+
* results, and the keyGenerator results of enclosing scopes on another
|
|
185
|
+
* store), they are composed by composeCacheKeys, which namespaces every
|
|
186
|
+
* `key()` result (#975), so a nested cache() keys its records within the
|
|
187
|
+
* enclosing partition (#970, #974). A scope whose own config sets no
|
|
188
|
+
* `key()` appends its own default key (resolveDefaultKey). Reusing the
|
|
189
|
+
* outer `key()` result alone would give every route under the inner
|
|
190
|
+
* cache() one record: a `key()` replaces the whole default key, so an
|
|
191
|
+
* outer key that names no route (`tier:gold`) would make `/a` HIT `/b`'s
|
|
192
|
+
* record. A scope with its own `key()` adds no default key: a `key()` is a
|
|
193
|
+
* full override, and its store's keyGenerator does not run. With no
|
|
194
|
+
* partition part it is resolveDefaultKey alone. With a `key()` on the
|
|
195
|
+
* chain but no request context it rejects (keyWithoutContextError).
|
|
196
|
+
* `partitionedPrefix` prefixes a key built from partition parts only (the
|
|
197
|
+
* response family's `response:`).
|
|
144
198
|
*
|
|
145
199
|
* Each `key()` result lives on the request context (`_resolvedCacheKeys`),
|
|
146
200
|
* by function: it runs once per request whatever the default key
|
|
@@ -151,20 +205,30 @@ export declare class CacheScope {
|
|
|
151
205
|
* itself: a `key()` calling `cookies()` would trip the capture guard there,
|
|
152
206
|
* and a capture must store the partition its request resolved.
|
|
153
207
|
*/
|
|
154
|
-
resolveKeyFrom(defaultKey: string): Promise<string>;
|
|
208
|
+
resolveKeyFrom(defaultKey: string, partitionedPrefix?: string): Promise<string>;
|
|
155
209
|
/**
|
|
156
210
|
* @internal The request partition of a ppr route's shell under this scope
|
|
157
|
-
* (resolveShellPartition):
|
|
158
|
-
* record key but without the default key, which the
|
|
159
|
-
* already carries. A scope without its own `key()`
|
|
160
|
-
* keyGenerator adds that result when it differs from the
|
|
161
|
-
* key, as an unkeyed scope's partition always did: the
|
|
162
|
-
* it, so the shell must be too. Undefined
|
|
163
|
-
* when nothing can partition; null when
|
|
211
|
+
* (resolveShellPartition): its partition parts (resolvePartitionParts),
|
|
212
|
+
* composed like the record key but without the default key, which the
|
|
213
|
+
* URL-based shell key already carries. A scope without its own `key()`
|
|
214
|
+
* whose store has a keyGenerator adds that result when it differs from the
|
|
215
|
+
* `doc` default key, as an unkeyed scope's partition always did: the
|
|
216
|
+
* record is split by it, so the shell must be too. Undefined
|
|
217
|
+
* (synchronously, with no work) when nothing can partition; null when
|
|
218
|
+
* nothing does.
|
|
164
219
|
*/
|
|
165
220
|
resolvePartition(pathname: string, params: Record<string, string> | undefined): Promise<string | null> | undefined;
|
|
166
|
-
/**
|
|
167
|
-
private
|
|
221
|
+
/** Whether a partition part can apply: a `key()` or a store scope above. */
|
|
222
|
+
private get mayPartition();
|
|
223
|
+
/**
|
|
224
|
+
* The parts partitioning this scope's records, outermost first: the
|
|
225
|
+
* chain's `key()` results (each once per request, memoizedKey) and the
|
|
226
|
+
* keyGenerator result of each enclosing scope on another store (once per
|
|
227
|
+
* keyGenerator, #974), null where it is `defaultKey`. The callers keep those
|
|
228
|
+
* positions (positionalParts): a result equal to the default key
|
|
229
|
+
* partitions nothing only when every one does (#970).
|
|
230
|
+
*/
|
|
231
|
+
private resolvePartitionParts;
|
|
168
232
|
/**
|
|
169
233
|
* This scope's store keyGenerator result for `defaultKey` (once per request
|
|
170
234
|
* and default key), else `defaultKey` (resolveCacheKey).
|
|
@@ -192,11 +256,11 @@ export declare class CacheScope {
|
|
|
192
256
|
*/
|
|
193
257
|
get isShellImplicitDocScope(): boolean;
|
|
194
258
|
/**
|
|
195
|
-
* Evaluate the cache `condition`
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
|
|
199
|
-
|
|
259
|
+
* Evaluate the cache `condition` predicates of this scope and every
|
|
260
|
+
* enclosing cache() (`conditions`, #974), outermost first. Returns false
|
|
261
|
+
* (skip the cache operation) when one returns false or throws; returns
|
|
262
|
+
* true when there is none or no request context to evaluate them against.
|
|
263
|
+
*
|
|
200
264
|
* One WRITE decision per (scope, request), memoized on the request context.
|
|
201
265
|
* A capture render has TWO writers consulting the same predicate — the
|
|
202
266
|
* explicit tier's cacheRoute and the snapshot-only doc record gate
|
|
@@ -208,6 +272,12 @@ export declare class CacheScope {
|
|
|
208
272
|
* at the replay gate was the round-2 regression.
|
|
209
273
|
*/
|
|
210
274
|
private readonly writeConditionMemo;
|
|
275
|
+
/**
|
|
276
|
+
* Evaluate the cache `condition` predicate. Returns false (skip the cache
|
|
277
|
+
* operation) when the predicate returns false or throws; returns true when
|
|
278
|
+
* there is no condition or no request context to evaluate it against. A
|
|
279
|
+
* write decision is memoized (writeConditionMemo).
|
|
280
|
+
*/
|
|
211
281
|
private conditionAllows;
|
|
212
282
|
/**
|
|
213
283
|
* Lookup cached segments for a route (single cache entry per request).
|
|
@@ -216,10 +286,11 @@ export declare class CacheScope {
|
|
|
216
286
|
* @param pathname - URL pathname for cache key generation
|
|
217
287
|
* @param params - Route params for cache key generation
|
|
218
288
|
* @param isIntercept - Whether this is an intercept navigation (uses different cache key)
|
|
219
|
-
* @param
|
|
220
|
-
*
|
|
289
|
+
* @param ownedPushes - How restoreHandles delivers the record's
|
|
290
|
+
* loader-owned values (withCacheLookup: the handler context's
|
|
291
|
+
* _claimLoaderPushes, and on a document HIT tail the owners it restores)
|
|
221
292
|
*/
|
|
222
|
-
lookupRoute(pathname: string, params: Record<string, string>, isIntercept?: boolean,
|
|
293
|
+
lookupRoute(pathname: string, params: Record<string, string>, isIntercept?: boolean, ownedPushes?: OwnedPushDelivery): Promise<{
|
|
223
294
|
segments: ResolvedSegment[];
|
|
224
295
|
shouldRevalidate: boolean;
|
|
225
296
|
} | null>;
|
|
@@ -241,7 +312,7 @@ export declare class CacheScope {
|
|
|
241
312
|
* A corrupt entry that was evicted reads as `miss`: the store was consulted
|
|
242
313
|
* and holds nothing servable, which is the post-eviction truth.
|
|
243
314
|
*/
|
|
244
|
-
lookupRouteDetailed(pathname: string, params: Record<string, string>, isIntercept?: boolean,
|
|
315
|
+
lookupRouteDetailed(pathname: string, params: Record<string, string>, isIntercept?: boolean, ownedPushes?: OwnedPushDelivery): Promise<CacheRouteLookupOutcome>;
|
|
245
316
|
/**
|
|
246
317
|
* Record this scope's segment-DSL cache({ tags }) into the request tag union
|
|
247
318
|
* synchronously, under the same gate cacheRoute() uses for a write.
|
|
@@ -257,6 +328,12 @@ export declare class CacheScope {
|
|
|
257
328
|
* (the tag union is a Set), so the duplicate record in cacheRoute is harmless.
|
|
258
329
|
*/
|
|
259
330
|
recordTags(requestCtx: RequestContext | undefined): void;
|
|
331
|
+
/**
|
|
332
|
+
* @internal The `tags` of this scope and every enclosing cache()
|
|
333
|
+
* (`tagOptions`, #974), static and function forms, for `ctx`: the tags its
|
|
334
|
+
* records carry. Undefined when none resolve (a disabled scope has none).
|
|
335
|
+
*/
|
|
336
|
+
resolveTags(ctx: RequestContext | undefined): string[] | undefined;
|
|
260
337
|
/**
|
|
261
338
|
* Cache all segments for a route (non-blocking via waitUntil)
|
|
262
339
|
* Single cache entry per route request.
|
|
@@ -266,14 +343,19 @@ export declare class CacheScope {
|
|
|
266
343
|
* @param params - Route params for cache key generation
|
|
267
344
|
* @param segments - All resolved segments to cache
|
|
268
345
|
* @param isIntercept - Whether this is an intercept navigation (uses different cache key)
|
|
346
|
+
* @param start - Where the render of `segments` started: the record is not
|
|
347
|
+
* written when one of its tags was invalidated since (#977,
|
|
348
|
+
* predatesInvalidation). A shell capture's doc record passes none: it
|
|
349
|
+
* lives only in the shell entry, which putShell gates by its own start.
|
|
269
350
|
*/
|
|
270
|
-
cacheRoute(pathname: string, params: Record<string, string>, segments: ResolvedSegment[], isIntercept?: boolean): Promise<void>;
|
|
351
|
+
cacheRoute(pathname: string, params: Record<string, string>, segments: ResolvedSegment[], isIntercept?: boolean, start?: ExecutionStart): Promise<void>;
|
|
271
352
|
}
|
|
272
353
|
/**
|
|
273
354
|
* @internal The request partition of a ppr route's shell: with a route
|
|
274
355
|
* cache() scope, its CacheScope.resolvePartition (the chain's `key()`
|
|
275
|
-
* results, composed, plus
|
|
276
|
-
*
|
|
356
|
+
* results, namespaced and composed (#975), plus the keyGenerator results of
|
|
357
|
+
* enclosing scopes on another store (#974) and of a scope without its own
|
|
358
|
+
* `key()` (#970)); with none, the app store's keyGenerator result
|
|
277
359
|
* given the document default key. Undefined (synchronously, with no work)
|
|
278
360
|
* when neither applies: the shell key stays host + path + filtered search.
|
|
279
361
|
* Resolves to null when the partition is the default key itself (a
|
|
@@ -11,6 +11,13 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import { type RequestContext } from "../server/request-context.js";
|
|
13
13
|
import { type LoaderIdentityRead } from "../server/context.js";
|
|
14
|
+
import type { ExecutionStart } from "./tag-invalidation.js";
|
|
15
|
+
/**
|
|
16
|
+
* Call `fn` outside any "use cache" tag scope: detached work a cached body
|
|
17
|
+
* schedules (a stale entry's background refresh) records nothing onto the
|
|
18
|
+
* entry being filled.
|
|
19
|
+
*/
|
|
20
|
+
export declare function outsideCacheTagScope<T>(fn: () => T): T;
|
|
14
21
|
/**
|
|
15
22
|
* Arm the record tag owners for `ctx`: its match resolved a cache scope, so
|
|
16
23
|
* it can write a route cache() record (match-api.ts). A capture's or
|
|
@@ -148,17 +155,30 @@ export declare function markIdentityRead(set: Set<string>, read: LoaderIdentityR
|
|
|
148
155
|
export declare function recordedIdentityRead(root: Set<string>): LoaderIdentityRead | undefined;
|
|
149
156
|
/** `root`'s tags plus those of every set it links to, transitively. */
|
|
150
157
|
export declare function flattenRecordedTags(root: Set<string>): Set<string>;
|
|
158
|
+
/** Record where the execution recording into `set` started. */
|
|
159
|
+
export declare function markTagSetStart(set: Set<string>, start: ExecutionStart): void;
|
|
160
|
+
/**
|
|
161
|
+
* The earliest start among `root` and every set it links to: a value built
|
|
162
|
+
* from another execution's value is as old as the oldest of them. A
|
|
163
|
+
* loader-cache write gates on it (loader-cache.ts), because the loader value
|
|
164
|
+
* it stores can be a run a reader started before the binding executed, and
|
|
165
|
+
* the values that run read can be older still.
|
|
166
|
+
*/
|
|
167
|
+
export declare function earliestRecordedStart(root: Set<string>): ExecutionStart | undefined;
|
|
151
168
|
/**
|
|
152
|
-
* Run a function within a cache tag scope. Any cacheTag() calls inside `fn
|
|
153
|
-
*
|
|
169
|
+
* Run a function within a cache tag scope. Any cacheTag() calls inside `fn`,
|
|
170
|
+
* and the tags a nested "use cache" call records (recordOwnedTags, #980),
|
|
171
|
+
* accumulate into the returned Set and every scope enclosing it
|
|
172
|
+
* (scopeParents).
|
|
154
173
|
*
|
|
155
174
|
* The returned Set is the LIVE reference - the caller must await `result`
|
|
156
175
|
* before reading `tags`, because an async cached function may call cacheTag()
|
|
157
|
-
* after an await boundary.
|
|
176
|
+
* after an await boundary. Pass `tagSet` to re-enter an execution's scope
|
|
177
|
+
* (its result's Flight encode, #980); it keeps the parent it opened under.
|
|
158
178
|
*
|
|
159
179
|
* @internal Used by cache-runtime.ts to wrap "use cache" execution.
|
|
160
180
|
*/
|
|
161
|
-
export declare function runWithCacheTagScope<T>(fn: () => T): {
|
|
181
|
+
export declare function runWithCacheTagScope<T>(fn: () => T, tagSet?: Set<string>): {
|
|
162
182
|
result: T;
|
|
163
183
|
tags: Set<string>;
|
|
164
184
|
};
|