@rangojs/router 0.19.1 → 0.21.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 +26 -14
- package/dist/types/browser/event-controller.d.ts +32 -0
- package/dist/types/browser/history-state.d.ts +16 -4
- package/dist/types/browser/navigation-transaction.d.ts +7 -0
- package/dist/types/browser/rango-state.d.ts +3 -1
- package/dist/types/browser/react/context.d.ts +11 -0
- package/dist/types/browser/react/location-state-shared.d.ts +84 -10
- package/dist/types/browser/react/location-state.d.ts +7 -2
- package/dist/types/browser/react/subscribe-to-nothing.d.ts +7 -0
- package/dist/types/cache/cache-scope.d.ts +4 -5
- package/dist/types/cache/cf/cf-cache-store.d.ts +27 -6
- package/dist/types/cache/cf/cf-cache-types.d.ts +12 -4
- package/dist/types/cache/handle-snapshot.d.ts +36 -50
- package/dist/types/cache/index.d.ts +2 -0
- package/dist/types/cache/shell-snapshot.d.ts +19 -3
- package/dist/types/cache/types.d.ts +21 -10
- package/dist/types/cache/vercel/vercel-cache-store.d.ts +28 -16
- package/dist/types/client-urls/navigation.d.ts +7 -1
- package/dist/types/client-urls/optimistic-location.d.ts +10 -4
- package/dist/types/handles/deferred-resolution.d.ts +11 -1
- package/dist/types/prerender/build-shell-capture.d.ts +8 -6
- package/dist/types/router/match-middleware/cache-lookup.d.ts +1 -1
- package/dist/types/router/navigation-snapshot.d.ts +8 -1
- package/dist/types/router/router-interfaces.d.ts +2 -1
- package/dist/types/router/router-options.d.ts +17 -7
- package/dist/types/router/segment-resolution/loader-cache.d.ts +21 -9
- package/dist/types/router-versions.d.ts +39 -0
- package/dist/types/rsc/handler-context.d.ts +5 -0
- package/dist/types/rsc/shell-build-manifest.d.ts +3 -2
- package/dist/types/rsc/types.d.ts +4 -6
- package/dist/types/server/build-version-table.d.ts +44 -0
- package/dist/types/server/handle-store.d.ts +87 -46
- package/dist/types/server/request-context.d.ts +22 -8
- package/dist/types/ssr/entry-preload-priority.d.ts +69 -0
- package/dist/types/ssr/index.d.ts +1 -0
- package/dist/types/ssr/preinit-client-references.d.ts +17 -5
- package/dist/types/testing/build-versions.d.ts +32 -0
- package/dist/types/testing/dom.entry.d.ts +1 -1
- package/dist/types/testing/flight.entry.d.ts +1 -1
- package/dist/types/testing/index.d.ts +2 -0
- package/dist/types/testing/internal/seed-vars.d.ts +7 -2
- package/dist/types/testing/location-state-key.d.ts +5 -1
- package/dist/types/testing/render-route.d.ts +77 -6
- package/dist/types/testing/serve-shell-request.d.ts +21 -0
- package/dist/types/testing/vitest-stubs/version.d.ts +1 -0
- package/dist/types/types/handler-context.d.ts +8 -5
- package/dist/types/vite/discovery/build-versions.d.ts +393 -0
- package/dist/types/vite/discovery/installed-packages.d.ts +26 -0
- package/dist/types/vite/discovery/router-versions-phase.d.ts +52 -0
- package/dist/types/vite/discovery/shell-prerender-phase.d.ts +7 -17
- package/dist/types/vite/discovery/state.d.ts +14 -0
- package/dist/types/vite/encryption-key.d.ts +18 -0
- package/dist/types/vite/plugin-types.d.ts +47 -6
- package/dist/types/vite/plugins/{version-injector.d.ts → entry-bootstrap-injector.d.ts} +4 -6
- package/dist/types/vite/plugins/expose-ids/export-analysis.d.ts +1 -0
- package/dist/types/vite/plugins/expose-ids/router-transform.d.ts +14 -0
- package/dist/types/vite/plugins/stable-rsc-output.d.ts +51 -0
- package/dist/types/vite/plugins/version-plugin.d.ts +9 -11
- package/dist/types/vite/plugins/virtual-entries.d.ts +21 -2
- package/dist/types/vite/router-discovery.d.ts +6 -0
- package/dist/types/vite/utils/client-chunks.d.ts +24 -2
- package/dist/types/vite/utils/compare-strings.d.ts +7 -0
- package/dist/types/vite/utils/package-resolution.d.ts +8 -0
- package/dist/types/vite/utils/prerender-utils.d.ts +2 -0
- package/dist/vite/index.js +1544 -420
- package/package.json +1 -2
- package/skills/bundle-analysis/SKILL.md +1 -1
- package/skills/cache-guide/SKILL.md +84 -20
- package/skills/caching/SKILL.md +16 -5
- package/skills/client-urls/SKILL.md +16 -0
- package/skills/cloudflare/SKILL.md +2 -1
- package/skills/comparison/references/framework-comparison.md +16 -12
- package/skills/hooks/SKILL.md +3 -0
- package/skills/hooks/handle-and-actions.md +6 -0
- package/skills/hooks/navigation.md +28 -0
- package/skills/hooks/state.md +209 -8
- package/skills/hooks/urls.md +40 -1
- package/skills/host-router/SKILL.md +13 -0
- package/skills/intercept/SKILL.md +6 -0
- package/skills/loader/SKILL.md +19 -1
- package/skills/middleware/SKILL.md +2 -0
- package/skills/ppr/SKILL.md +119 -40
- package/skills/prerender/SKILL.md +7 -3
- package/skills/rango/SKILL.md +8 -7
- package/skills/router-setup/SKILL.md +23 -3
- package/skills/testing/SKILL.md +30 -26
- package/skills/testing/client-components.md +193 -8
- package/skills/testing/handles.md +2 -0
- package/skills/testing/loader.md +1 -1
- package/skills/testing/middleware.md +1 -1
- package/skills/testing/render-handler.md +18 -18
- package/skills/testing/serve-shell-request.md +63 -14
- package/skills/testing/server-actions.md +17 -17
- package/skills/testing/server-tree.md +1 -1
- package/skills/typesafety/generated-files-and-cli.md +1 -1
- package/skills/use-cache/SKILL.md +16 -5
- package/skills/vercel/SKILL.md +3 -3
- package/src/bin/rango.ts +1 -1
- package/src/browser/event-controller.ts +75 -2
- package/src/browser/history-state.ts +39 -17
- package/src/browser/navigation-bridge.ts +41 -18
- package/src/browser/navigation-transaction.ts +15 -10
- package/src/browser/partial-update.ts +10 -2
- package/src/browser/rango-state.ts +3 -1
- package/src/browser/react/Link.tsx +2 -3
- package/src/browser/react/NavigationProvider.tsx +25 -1
- package/src/browser/react/context.ts +13 -0
- package/src/browser/react/location-state-shared.ts +200 -34
- package/src/browser/react/location-state.ts +40 -75
- package/src/browser/react/subscribe-to-nothing.ts +7 -0
- package/src/browser/react/use-handle.ts +20 -1
- package/src/browser/rsc-router.tsx +33 -11
- package/src/browser/server-action-bridge.ts +17 -1
- package/src/cache/cache-scope.ts +18 -8
- package/src/cache/cf/cf-cache-store.ts +75 -55
- package/src/cache/cf/cf-cache-types.ts +12 -4
- package/src/cache/handle-snapshot.ts +69 -87
- package/src/cache/index.ts +4 -0
- package/src/cache/shell-snapshot.ts +35 -5
- package/src/cache/types.ts +21 -10
- package/src/cache/vercel/vercel-cache-store.ts +48 -20
- package/src/client-urls/client-root.tsx +1 -0
- package/src/client-urls/navigation.ts +10 -0
- package/src/client-urls/optimistic-location.ts +10 -4
- package/src/handles/deferred-resolution.ts +31 -0
- package/src/prerender/build-shell-capture.ts +11 -9
- package/src/router/manifest.ts +2 -0
- package/src/router/match-middleware/cache-lookup.ts +11 -18
- package/src/router/navigation-snapshot.ts +25 -6
- package/src/router/request-classification.ts +15 -12
- package/src/router/router-interfaces.ts +2 -1
- package/src/router/router-options.ts +17 -7
- package/src/router/segment-resolution/loader-cache.ts +95 -60
- package/src/router-versions.ts +60 -0
- package/src/rsc/full-payload.ts +6 -2
- package/src/rsc/handler-context.ts +5 -0
- package/src/rsc/handler.ts +14 -4
- package/src/rsc/rsc-rendering.ts +12 -1
- package/src/rsc/shell-build-manifest.ts +10 -7
- package/src/rsc/shell-capture.ts +36 -26
- package/src/rsc/types.ts +4 -6
- package/src/server/build-version-table.ts +115 -0
- package/src/server/handle-store.ts +344 -127
- package/src/server/request-context.ts +62 -11
- package/src/ssr/entry-preload-priority.ts +308 -0
- package/src/ssr/index.tsx +46 -9
- package/src/ssr/preinit-client-references.ts +17 -5
- package/src/ssr/ssr-root.tsx +16 -4
- package/src/testing/build-versions.ts +64 -0
- package/src/testing/dispatch.ts +6 -0
- package/src/testing/dom.entry.ts +1 -0
- package/src/testing/flight.entry.ts +1 -0
- package/src/testing/index.ts +3 -0
- package/src/testing/internal/context.ts +2 -1
- package/src/testing/internal/seed-vars.ts +14 -2
- package/src/testing/location-state-key.ts +18 -8
- package/src/testing/render-handler.ts +2 -1
- package/src/testing/render-route.tsx +277 -43
- package/src/testing/serve-shell-request.ts +80 -11
- package/src/testing/vitest-stubs/version.ts +4 -1
- package/src/types/handler-context.ts +8 -5
- package/src/vite/discovery/build-versions.ts +1281 -0
- package/src/vite/discovery/installed-packages.ts +159 -0
- package/src/vite/discovery/prerender-collection.ts +38 -1
- package/src/vite/discovery/router-versions-phase.ts +336 -0
- package/src/vite/discovery/shell-prerender-phase.ts +28 -38
- package/src/vite/discovery/state.ts +19 -0
- package/src/vite/discovery/virtual-module-codegen.ts +7 -2
- package/src/vite/encryption-key.ts +101 -9
- package/src/vite/plugin-types.ts +48 -6
- package/src/vite/plugins/{version-injector.ts → entry-bootstrap-injector.ts} +7 -22
- package/src/vite/plugins/expose-ids/export-analysis.ts +1 -1
- package/src/vite/plugins/expose-ids/router-transform.ts +36 -15
- package/src/vite/plugins/expose-internal-ids.ts +12 -3
- package/src/vite/plugins/stable-rsc-output.ts +147 -0
- package/src/vite/plugins/version-plugin.ts +19 -24
- package/src/vite/plugins/version.d.ts +17 -2
- package/src/vite/plugins/virtual-entries.ts +40 -7
- package/src/vite/rango.ts +30 -3
- package/src/vite/router-discovery.ts +82 -13
- package/src/vite/utils/client-chunks.ts +84 -14
- package/src/vite/utils/compare-strings.ts +9 -0
- package/src/vite/utils/package-resolution.ts +9 -0
- package/src/vite/utils/prerender-utils.ts +4 -1
- package/src/vite/utils/shared-utils.ts +1 -1
package/dist/bin/rango.js
CHANGED
|
@@ -1599,14 +1599,33 @@ var init_merge_full_manifests = __esm({
|
|
|
1599
1599
|
}
|
|
1600
1600
|
});
|
|
1601
1601
|
|
|
1602
|
+
// src/router-versions.ts
|
|
1603
|
+
var DEFAULT_ROUTER_VERSIONS_KEY;
|
|
1604
|
+
var init_router_versions = __esm({
|
|
1605
|
+
"src/router-versions.ts"() {
|
|
1606
|
+
"use strict";
|
|
1607
|
+
DEFAULT_ROUTER_VERSIONS_KEY = "*";
|
|
1608
|
+
}
|
|
1609
|
+
});
|
|
1610
|
+
|
|
1602
1611
|
// src/vite/plugins/virtual-entries.ts
|
|
1603
1612
|
function getVirtualVersionContent(version) {
|
|
1604
|
-
return
|
|
1605
|
-
}
|
|
1606
|
-
|
|
1613
|
+
return [
|
|
1614
|
+
`export const VERSION = ${JSON.stringify(version)};`,
|
|
1615
|
+
`export const ROUTER_VERSIONS = undefined;`
|
|
1616
|
+
].join("\n");
|
|
1617
|
+
}
|
|
1618
|
+
function getVirtualBuildVersionContent() {
|
|
1619
|
+
return [
|
|
1620
|
+
`export const ROUTER_VERSIONS = ${ROUTER_VERSIONS_PLACEHOLDER};`,
|
|
1621
|
+
`export const VERSION = ROUTER_VERSIONS[${JSON.stringify(DEFAULT_ROUTER_VERSIONS_KEY)}][1];`
|
|
1622
|
+
].join("\n");
|
|
1623
|
+
}
|
|
1624
|
+
var VIRTUAL_ENTRY_BROWSER, VIRTUAL_IDS, ROUTER_VERSIONS_PLACEHOLDER;
|
|
1607
1625
|
var init_virtual_entries = __esm({
|
|
1608
1626
|
"src/vite/plugins/virtual-entries.ts"() {
|
|
1609
1627
|
"use strict";
|
|
1628
|
+
init_router_versions();
|
|
1610
1629
|
VIRTUAL_ENTRY_BROWSER = `
|
|
1611
1630
|
import {
|
|
1612
1631
|
createFromReadableStream,
|
|
@@ -1660,6 +1679,7 @@ initializeApp().catch(console.error);
|
|
|
1660
1679
|
rsc: "virtual:rsc-router/entry.rsc.js",
|
|
1661
1680
|
version: "@rangojs/router:version"
|
|
1662
1681
|
};
|
|
1682
|
+
ROUTER_VERSIONS_PLACEHOLDER = "__RANGO_ROUTER_VERSIONS__";
|
|
1663
1683
|
}
|
|
1664
1684
|
});
|
|
1665
1685
|
|
|
@@ -1772,8 +1792,7 @@ function getClientModuleSignature(source) {
|
|
|
1772
1792
|
};
|
|
1773
1793
|
}
|
|
1774
1794
|
function createVersionPlugin() {
|
|
1775
|
-
|
|
1776
|
-
let currentVersion = buildVersion;
|
|
1795
|
+
let currentVersion = Date.now().toString(16);
|
|
1777
1796
|
let isDev = false;
|
|
1778
1797
|
let server = null;
|
|
1779
1798
|
let resolvedCacheDir;
|
|
@@ -1793,13 +1812,6 @@ function createVersionPlugin() {
|
|
|
1793
1812
|
return {
|
|
1794
1813
|
name: "@rangojs/router:version",
|
|
1795
1814
|
enforce: "pre",
|
|
1796
|
-
// The build-time shell capture phase (producer B, #699) stamps entries
|
|
1797
|
-
// with THIS instance's version — the value folded into the shipped worker
|
|
1798
|
-
// — never the discovery temp server's own version-plugin value (a
|
|
1799
|
-
// different Date.now() stamp that would fail the serve-side gate).
|
|
1800
|
-
api: {
|
|
1801
|
-
getBuildVersion: () => currentVersion
|
|
1802
|
-
},
|
|
1803
1815
|
configResolved(config) {
|
|
1804
1816
|
isDev = config.command === "serve";
|
|
1805
1817
|
resolvedCacheDir = config.cacheDir ? String(config.cacheDir).replace(/\\/g, "/") : void 0;
|
|
@@ -1821,7 +1833,7 @@ function createVersionPlugin() {
|
|
|
1821
1833
|
},
|
|
1822
1834
|
load(id) {
|
|
1823
1835
|
if (id === "\0" + VIRTUAL_IDS.version) {
|
|
1824
|
-
return getVirtualVersionContent(currentVersion);
|
|
1836
|
+
return isDev ? getVirtualVersionContent(currentVersion) : getVirtualBuildVersionContent();
|
|
1825
1837
|
}
|
|
1826
1838
|
return null;
|
|
1827
1839
|
},
|
|
@@ -2150,7 +2162,7 @@ if (command === "generate") {
|
|
|
2150
2162
|
Modes:
|
|
2151
2163
|
(default) Static parser with error on unresolvable includes
|
|
2152
2164
|
--runtime Vite-based runtime discovery (100% coverage)
|
|
2153
|
-
Requires vite
|
|
2165
|
+
Requires vite
|
|
2154
2166
|
--static Static parser, accept partial output with warnings
|
|
2155
2167
|
|
|
2156
2168
|
Options:
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
2
|
import type { NavigationLocation, NavigateOptionsInternal, TrackedActionState, InflightAction, RscMetadata, HandleData, StreamingToken } from "./types.js";
|
|
3
|
+
import { type LocationStateSnapshot } from "./react/location-state-shared.js";
|
|
3
4
|
/**
|
|
4
5
|
* Phase of a navigation operation
|
|
5
6
|
*/
|
|
@@ -196,6 +197,23 @@ export interface EventController {
|
|
|
196
197
|
*/
|
|
197
198
|
resolvedIds?: string[]): void;
|
|
198
199
|
getHandleState(): HandleState;
|
|
200
|
+
/**
|
|
201
|
+
* Keep the current handle state as the one the document's HTML was rendered
|
|
202
|
+
* with. initBrowserApp calls it before hydrateRoot, once the document's
|
|
203
|
+
* handle snapshot is applied.
|
|
204
|
+
*/
|
|
205
|
+
freezeHydrationHandleState(): void;
|
|
206
|
+
/**
|
|
207
|
+
* The handle state the document's HTML was rendered with, once the live
|
|
208
|
+
* state has moved on from it; undefined while the live state is still that
|
|
209
|
+
* state (nothing changed since the freeze, or nothing was frozen: a tree
|
|
210
|
+
* that was mounted, an SSR pass). A render React is hydrating reads it
|
|
211
|
+
* (useHandle), whenever its boundary hydrates: the late handle channel
|
|
212
|
+
* (rsc-router.tsx) waits for the root to hydrate, not for a `<Suspense>`
|
|
213
|
+
* boundary that hydrates after it, and by then the live state can hold
|
|
214
|
+
* values that boundary's HTML does not (issue #1035).
|
|
215
|
+
*/
|
|
216
|
+
getHydrationHandleState(): HandleState | undefined;
|
|
199
217
|
/**
|
|
200
218
|
* Update ONLY `routeSegmentIds` (what `useSegments` reads) from `matched`,
|
|
201
219
|
* leaving `data` and `segmentOrder` (what `useHandle` collects over) untouched.
|
|
@@ -206,6 +224,20 @@ export interface EventController {
|
|
|
206
224
|
setRouteSegmentIds(matched: string[]): void;
|
|
207
225
|
setParams(params: Record<string, string>): void;
|
|
208
226
|
getParams(): Record<string, string>;
|
|
227
|
+
/**
|
|
228
|
+
* Record the committed history entry's location state from `entryState`:
|
|
229
|
+
* the state object the commit pushed, restored or merged into the entry,
|
|
230
|
+
* so the entry and its readers have one source. Notifies nobody:
|
|
231
|
+
* NavigationProvider takes the snapshot with the entry's payload
|
|
232
|
+
* (LocationStateContext). `treeless` marks a commit no payload follows (a
|
|
233
|
+
* shallow navigation, a commit that keeps every segment, an action's
|
|
234
|
+
* state): the provider takes it with this commit's state notification, in
|
|
235
|
+
* the batch of the location.
|
|
236
|
+
*/
|
|
237
|
+
commitLocationState(entryState: unknown, treeless?: boolean): void;
|
|
238
|
+
getLocationState(): LocationStateSnapshot;
|
|
239
|
+
/** True once after a `treeless` commit. */
|
|
240
|
+
takeTreelessLocationState(): boolean;
|
|
209
241
|
getCurrentNavigation(): NavigationEntry | null;
|
|
210
242
|
getInflightActions(): Map<string, ActionEntry>;
|
|
211
243
|
/** Whether any concurrent actions have occurred (shared across all handles) */
|
|
@@ -37,8 +37,20 @@ export declare const SHELL_MISS_MARKER: string;
|
|
|
37
37
|
*/
|
|
38
38
|
export declare function stripShellMissMarker(): void;
|
|
39
39
|
/**
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* so
|
|
40
|
+
* Remove the `clearOnReload` slots of the entry a document load starts on:
|
|
41
|
+
* the server rendered this document without them. One pass before hydration
|
|
42
|
+
* (initBrowserApp; renderRoute's `hydrate` mode), so no reader needs to know
|
|
43
|
+
* the page began as a document load, and a slot nobody reads is removed too.
|
|
44
|
+
* No server-set state exists yet to lose: a document response carries none
|
|
45
|
+
* (rsc-rendering.ts attaches it to partial payloads only).
|
|
46
|
+
*
|
|
47
|
+
* A slot is recognised by its key alone (the `~r` suffix): at start-up the
|
|
48
|
+
* module that defines it may not be loaded.
|
|
43
49
|
*/
|
|
44
|
-
export declare function
|
|
50
|
+
export declare function clearLocationStateOnDocumentLoad(): void;
|
|
51
|
+
/**
|
|
52
|
+
* Merge server-set location state into the current history entry and return
|
|
53
|
+
* the entry state written. Readers see it when the caller commits it
|
|
54
|
+
* (EventController.commitLocationState).
|
|
55
|
+
*/
|
|
56
|
+
export declare function mergeLocationState(locationState: Record<string, unknown>): Record<string, unknown>;
|
|
@@ -36,6 +36,11 @@ interface CommitOptions {
|
|
|
36
36
|
* partial updater reuses it instead of deciding again.
|
|
37
37
|
*/
|
|
38
38
|
transitionGatedOff?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* No payload follows this commit: every segment is kept and the tree on
|
|
41
|
+
* screen stays (EventController.commitLocationState).
|
|
42
|
+
*/
|
|
43
|
+
treeless?: boolean;
|
|
39
44
|
}
|
|
40
45
|
/**
|
|
41
46
|
* Options that can override the pre-configured commit settings
|
|
@@ -57,6 +62,8 @@ interface BoundCommitOverrides {
|
|
|
57
62
|
serverState?: Record<string, unknown>;
|
|
58
63
|
/** The committed route's name (payload metadata), remembered per history entry. */
|
|
59
64
|
routeName?: string;
|
|
65
|
+
/** No payload follows this commit (CommitOptions.treeless). */
|
|
66
|
+
treeless?: boolean;
|
|
60
67
|
}
|
|
61
68
|
/**
|
|
62
69
|
* Bound transaction with pre-configured commit options (without segmentIds/segments)
|
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
* cache keys responses by (URL, X-Rango-State value).
|
|
8
8
|
*
|
|
9
9
|
* Value format: `{buildVersion}:{invalidationTimestamp}`
|
|
10
|
-
* - Build version
|
|
10
|
+
* - Build version: the router's document version. It changes when a deploy
|
|
11
|
+
* changes the router's server code or the client assets, busting all cached
|
|
12
|
+
* prefetches at boot; a deploy that changes neither keeps them.
|
|
11
13
|
* - Timestamp rotates on invalidation (server action, invalidateClientCache).
|
|
12
14
|
*
|
|
13
15
|
* Storage is a session cookie named by the server-resolved name passed to
|
|
@@ -2,6 +2,7 @@ import { type Context } from "react";
|
|
|
2
2
|
import type { NavigationStore, NavigateOptionsInternal } from "../types.js";
|
|
3
3
|
import type { EventController } from "../event-controller.js";
|
|
4
4
|
import type { PrefetchStrategy } from "../../router/prefetch-default.js";
|
|
5
|
+
import type { LocationStateSnapshot } from "./location-state-shared.js";
|
|
5
6
|
/**
|
|
6
7
|
* Navigation context value provided by NavigationProvider
|
|
7
8
|
*
|
|
@@ -55,3 +56,13 @@ export interface NavigationStoreContextValue {
|
|
|
55
56
|
* Use useNavigation hook for reactive state access.
|
|
56
57
|
*/
|
|
57
58
|
export declare const NavigationStoreContext: Context<NavigationStoreContextValue | null>;
|
|
59
|
+
/**
|
|
60
|
+
* The location state of the history entry whose tree is on screen, for
|
|
61
|
+
* useLocationState. NavigationProvider holds it as React state next to the
|
|
62
|
+
* payload and sets both in one update, so a render sees an entry's state
|
|
63
|
+
* exactly when it sees that entry's tree: a transition React holds renders
|
|
64
|
+
* the destination's value, an urgent render of the content still on screen
|
|
65
|
+
* (a reader mounting there included) the value of the entry being left
|
|
66
|
+
* (#1029). Undefined on the server and outside a provider.
|
|
67
|
+
*/
|
|
68
|
+
export declare const LocationStateContext: Context<LocationStateSnapshot>;
|
|
@@ -9,12 +9,82 @@ export interface LocationStateEntry {
|
|
|
9
9
|
readonly __rsc_ls_value: unknown;
|
|
10
10
|
readonly __rsc_ls_lazy?: boolean;
|
|
11
11
|
}
|
|
12
|
+
/** Prefix of every typed location-state slot in `history.state`. */
|
|
13
|
+
export declare const LOCATION_STATE_KEY_PREFIX: string;
|
|
14
|
+
export declare function isLocationStateKey(key: string): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* `clearOnReload` is part of a slot's KEY (`<key>~r`); the value is always
|
|
17
|
+
* stored raw. Slots outlive deploys, so nothing that reads one may depend on a
|
|
18
|
+
* stored format: a definition without the option reads the plain key and never
|
|
19
|
+
* sees such a slot.
|
|
20
|
+
*
|
|
21
|
+
* An injected key ends in `#<ExportName>` (expose-id-utils.ts makeStubId; only
|
|
22
|
+
* identifier exports are keyed) and "~" cannot occur in an identifier, so no
|
|
23
|
+
* file or export name produces a suffix. withLocationStateKey rejects it.
|
|
24
|
+
*/
|
|
25
|
+
export declare const LOCATION_STATE_KEY_SUFFIX_SEPARATOR: string;
|
|
26
|
+
export declare const CLEAR_ON_RELOAD_KEY_SUFFIX: string;
|
|
27
|
+
/**
|
|
28
|
+
* @internal The version the document loaded under (rsc-router.tsx
|
|
29
|
+
* initBrowserApp). Deliberately not getAppVersion(): a dev HMR bump moves that
|
|
30
|
+
* one inside a running session (bridge.updateVersion), and the state that
|
|
31
|
+
* session wrote must stay readable until the next document load.
|
|
32
|
+
*/
|
|
33
|
+
export declare function setLocationStateVersion(version: string | undefined): void;
|
|
34
|
+
/**
|
|
35
|
+
* The state of a `{ state }` snapshot when its location state may be read:
|
|
36
|
+
* an object recorded under the client's version. Without a snapshot, the
|
|
37
|
+
* current entry (`window.history` is a `{ state }`), and nothing on the
|
|
38
|
+
* server.
|
|
39
|
+
*/
|
|
40
|
+
export declare function readableLocationState(location?: {
|
|
41
|
+
readonly state: unknown;
|
|
42
|
+
} | undefined): Record<string, unknown> | undefined;
|
|
43
|
+
/**
|
|
44
|
+
* One history entry's location state as useLocationState readers receive it:
|
|
45
|
+
* its typed slots and plain `state`, or undefined when it holds none.
|
|
46
|
+
*/
|
|
47
|
+
export type LocationStateSnapshot = Readonly<Record<string, unknown>> | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* The snapshot of `entryState`: the state object a commit pushes, restores or
|
|
50
|
+
* merges into its history entry. Only state recorded under the client's
|
|
51
|
+
* version is in it (readableLocationState).
|
|
52
|
+
*
|
|
53
|
+
* The snapshot is a React context value, so identity decides who re-renders.
|
|
54
|
+
* It is `previous` itself when every slot holds the value `previous` holds:
|
|
55
|
+
* an entry without state after another, a primitive carried over, or the
|
|
56
|
+
* object a reader got from `previous` passed back by the navigation. Any
|
|
57
|
+
* other value is new, equal content included: a link clicked twice announces
|
|
58
|
+
* its state twice (a flash message, a scroll target). A new value is a
|
|
59
|
+
* structured clone, as history.state holds it, so a reader never shares an
|
|
60
|
+
* object with the caller of the navigation.
|
|
61
|
+
*/
|
|
62
|
+
export declare function locationStateSnapshot(entryState: unknown, previous?: LocationStateSnapshot): LocationStateSnapshot;
|
|
63
|
+
/**
|
|
64
|
+
* Record the client's version on a state object that carries location state
|
|
65
|
+
* and no record yet. A client without a version (a renderRoute tree) writes
|
|
66
|
+
* none.
|
|
67
|
+
*/
|
|
68
|
+
export declare function stampLocationState(state: Record<string, unknown>): void;
|
|
69
|
+
/**
|
|
70
|
+
* `entryState` plus `additions`, recorded under the client's version. The
|
|
71
|
+
* record is per entry, so location state another version left there is dropped
|
|
72
|
+
* first, with its record: under the new one it would be readable again. Router
|
|
73
|
+
* bookkeeping (idx, scroll key, intercept) is kept.
|
|
74
|
+
*/
|
|
75
|
+
export declare function addLocationState(entryState: unknown, additions?: Record<string, unknown>): Record<string, unknown>;
|
|
12
76
|
/**
|
|
13
77
|
* Options for createLocationState
|
|
14
78
|
*/
|
|
15
79
|
export interface LocationStateOptions {
|
|
16
80
|
/** When true, the state is cleared from history after first read (flash message pattern) */
|
|
17
81
|
flash?: boolean;
|
|
82
|
+
/**
|
|
83
|
+
* When true, the state does not survive a document load of its entry (a
|
|
84
|
+
* refresh, a back/forward that loads the document): the server rendered
|
|
85
|
+
* without it. Not together with `flash`.
|
|
86
|
+
*/
|
|
87
|
+
clearOnReload?: boolean;
|
|
18
88
|
}
|
|
19
89
|
type LocationStateUnsafeFn = (...args: never[]) => unknown;
|
|
20
90
|
type LocationStateUnsafeCtor = abstract new (...args: never[]) => unknown;
|
|
@@ -116,13 +186,16 @@ export interface LocationStateDefinition<TArgs extends unknown[], TState> {
|
|
|
116
186
|
(...args: TArgs): LocationStateEntry;
|
|
117
187
|
/**
|
|
118
188
|
* Injected by Vite plugin - do not set manually. Unit tests without the
|
|
119
|
-
* plugin use withLocationStateKey() from @rangojs/router/testing.
|
|
189
|
+
* plugin use withLocationStateKey() from @rangojs/router/testing. Reads back
|
|
190
|
+
* as the slot's key in `history.state`: the injected key plus the
|
|
191
|
+
* `clearOnReload` suffix.
|
|
120
192
|
*/
|
|
121
193
|
__rsc_ls_key: string;
|
|
122
194
|
/** Whether this state auto-clears after first read */
|
|
123
195
|
readonly __rsc_ls_flash: boolean;
|
|
124
196
|
/**
|
|
125
|
-
* Read the current value from history.state.
|
|
197
|
+
* Read the current value from history.state. State the entry holds from
|
|
198
|
+
* another version of the app (an older build) reads as undefined.
|
|
126
199
|
*
|
|
127
200
|
* Returns undefined during SSR (no `window`). To stay hydration-safe, do
|
|
128
201
|
* NOT call read() inline during the initial render — the server returns
|
|
@@ -145,13 +218,14 @@ export interface LocationStateDefinition<TArgs extends unknown[], TState> {
|
|
|
145
218
|
/**
|
|
146
219
|
* Statically write the value into the current history entry under this
|
|
147
220
|
* definition's key, preserving any other keys already on history.state
|
|
148
|
-
* (e.g. router bookkeeping, other LocationState slots).
|
|
221
|
+
* (e.g. router bookkeeping, other LocationState slots). Location state
|
|
222
|
+
* another version of the app left on the entry is dropped.
|
|
149
223
|
*
|
|
150
|
-
* This is the non-reactive counterpart to read(): it
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
*
|
|
224
|
+
* This is the non-reactive counterpart to read(): it changes the history
|
|
225
|
+
* entry and nothing a useLocationState() reader shows, whether the reader
|
|
226
|
+
* is mounted now or mounts later. read() returns the value at once; a
|
|
227
|
+
* reader gets it when the entry is next restored: back/forward to it, or
|
|
228
|
+
* (unless the definition sets `clearOnReload`) a hard refresh of it.
|
|
155
229
|
*
|
|
156
230
|
* Client-only: throws when called on the server (no history available).
|
|
157
231
|
*/
|
|
@@ -161,8 +235,8 @@ export interface LocationStateDefinition<TArgs extends unknown[], TState> {
|
|
|
161
235
|
* leaving any other keys on history.state untouched. Idempotent: removing
|
|
162
236
|
* a slot that isn't present is a no-op.
|
|
163
237
|
*
|
|
164
|
-
* Same non-reactive semantics as write():
|
|
165
|
-
*
|
|
238
|
+
* Same non-reactive semantics as write(): useLocationState() readers keep
|
|
239
|
+
* the value until the entry is next restored.
|
|
166
240
|
*
|
|
167
241
|
* Client-only: throws when called on the server (no history available).
|
|
168
242
|
*/
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { type LocationStateDefinition } from "./location-state-shared.js";
|
|
2
2
|
export { createLocationState, isLocationStateEntry, resolveLocationStateEntries, type LocationStateEntry, type LocationStateDefinition, type LocationStateOptions, } from "./location-state-shared.js";
|
|
3
3
|
/**
|
|
4
|
-
* Hook to read location state
|
|
4
|
+
* Hook to read the location state of the history entry on screen
|
|
5
|
+
*
|
|
6
|
+
* A reader sees an entry's state together with that entry's tree: on a
|
|
7
|
+
* navigation the value changes in the React commit that brings the
|
|
8
|
+
* destination, so content a pending navigation keeps on screen keeps the
|
|
9
|
+
* state of the entry being left, for a reader that mounts there too (#1029).
|
|
5
10
|
*
|
|
6
11
|
* Behavior depends on the definition:
|
|
7
|
-
* - Normal state: persists across navigations
|
|
12
|
+
* - Normal state: persists across navigations and back/forward
|
|
8
13
|
* - Flash state (created with { flash: true }): read once, cleared after paint
|
|
9
14
|
*
|
|
10
15
|
* Overloaded:
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `subscribe` for a useSyncExternalStore whose snapshot nothing notifies: the
|
|
3
|
+
* hook is there for its server snapshot (useLocationState, useHandle), or the
|
|
4
|
+
* value only changes with a render (Link's non-adaptive prefetch strategy).
|
|
5
|
+
* One function, so its identity is stable across renders and hooks.
|
|
6
|
+
*/
|
|
7
|
+
export declare const subscribeToNothing: () => () => void;
|
|
@@ -286,11 +286,10 @@ export declare class CacheScope {
|
|
|
286
286
|
* @param pathname - URL pathname for cache key generation
|
|
287
287
|
* @param params - Route params for cache key generation
|
|
288
288
|
* @param isIntercept - Whether this is an intercept navigation (uses different cache key)
|
|
289
|
-
* @param ownedPushes -
|
|
290
|
-
* loader-
|
|
291
|
-
* _claimLoaderPushes, and on a document HIT tail the owners it restores)
|
|
289
|
+
* @param ownedPushes - What the record is to each loader's handle pushes
|
|
290
|
+
* (withCacheLookup: loader-cache.ts loaderPins), called on a hit
|
|
292
291
|
*/
|
|
293
|
-
lookupRoute(pathname: string, params: Record<string, string>, isIntercept?: boolean, ownedPushes?: OwnedPushDelivery): Promise<{
|
|
292
|
+
lookupRoute(pathname: string, params: Record<string, string>, isIntercept?: boolean, ownedPushes?: () => OwnedPushDelivery): Promise<{
|
|
294
293
|
segments: ResolvedSegment[];
|
|
295
294
|
shouldRevalidate: boolean;
|
|
296
295
|
} | null>;
|
|
@@ -312,7 +311,7 @@ export declare class CacheScope {
|
|
|
312
311
|
* A corrupt entry that was evicted reads as `miss`: the store was consulted
|
|
313
312
|
* and holds nothing servable, which is the post-eviction truth.
|
|
314
313
|
*/
|
|
315
|
-
lookupRouteDetailed(pathname: string, params: Record<string, string>, isIntercept?: boolean, ownedPushes?: OwnedPushDelivery): Promise<CacheRouteLookupOutcome>;
|
|
314
|
+
lookupRouteDetailed(pathname: string, params: Record<string, string>, isIntercept?: boolean, ownedPushes?: () => OwnedPushDelivery): Promise<CacheRouteLookupOutcome>;
|
|
316
315
|
/**
|
|
317
316
|
* Record this scope's segment-DSL cache({ tags }) into the request tag union
|
|
318
317
|
* synchronously, under the same gate cacheRoute() uses for a write.
|
|
@@ -21,7 +21,8 @@ export declare class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<T
|
|
|
21
21
|
private readonly namespace?;
|
|
22
22
|
private readonly explicitBaseUrl?;
|
|
23
23
|
private readonly waitUntil?;
|
|
24
|
-
|
|
24
|
+
/** The `version` option: used for every versioned family when set. */
|
|
25
|
+
private readonly explicitVersion?;
|
|
25
26
|
private readonly edgeLookupTimeoutMs;
|
|
26
27
|
private readonly edgeReadTimeoutMs;
|
|
27
28
|
private readonly kvReadTimeoutMs;
|
|
@@ -327,9 +328,12 @@ export declare class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<T
|
|
|
327
328
|
* on the same context) read their markers as before.
|
|
328
329
|
*/
|
|
329
330
|
private recordShellHit;
|
|
330
|
-
/**
|
|
331
|
+
/**
|
|
332
|
+
* The isolate marker memo's key for a tag: markers are per namespace, and
|
|
333
|
+
* shared by every version (tagMarkerKey).
|
|
334
|
+
*/
|
|
331
335
|
private markerMemoKey;
|
|
332
|
-
/** The memo key: one per namespace,
|
|
336
|
+
/** The memo key: one per namespace, document version, base URL, and shell key. */
|
|
333
337
|
private shellMemoKey;
|
|
334
338
|
/**
|
|
335
339
|
* Serve a memoized shell (shell-memo.ts). The tag-marker check is the only
|
|
@@ -400,9 +404,16 @@ export declare class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<T
|
|
|
400
404
|
private kvReadShellDocument;
|
|
401
405
|
/** Promote a valid KV shell into the per-colo Cache API tier. */
|
|
402
406
|
private promoteShellToL1;
|
|
407
|
+
private shellRequest;
|
|
408
|
+
private shellKVKey;
|
|
403
409
|
/**
|
|
404
410
|
* Convert string key to Request object for CF Cache API.
|
|
405
|
-
*
|
|
411
|
+
*
|
|
412
|
+
* `family` picks the version in the URL path, so a version change misses:
|
|
413
|
+
* `"data"` for segment entries and `fn:` items (cached RSC data, valid while
|
|
414
|
+
* the router's server code is unchanged), `"document"` for `doc:` responses
|
|
415
|
+
* and `shell2:` shells (their bytes carry asset URLs and the handler
|
|
416
|
+
* version), `null` for tag markers, which apply to every version.
|
|
406
417
|
* @internal
|
|
407
418
|
*/
|
|
408
419
|
private keyToRequest;
|
|
@@ -477,7 +488,13 @@ export declare class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<T
|
|
|
477
488
|
* @internal
|
|
478
489
|
*/
|
|
479
490
|
private kvGetOrEvict;
|
|
480
|
-
/**
|
|
491
|
+
/**
|
|
492
|
+
* KV key for a tag's invalidation marker. Unversioned: a content-hash
|
|
493
|
+
* version can come back (deploy A, deploy B, roll back to A), and a marker
|
|
494
|
+
* written while B was live has to be visible to A's entries. The staleness
|
|
495
|
+
* check compares the marker time with the entry's taggedAt and nothing else
|
|
496
|
+
* (isGloballyInvalidated), so one marker per tag serves every version.
|
|
497
|
+
*/
|
|
481
498
|
private tagMarkerKey;
|
|
482
499
|
/**
|
|
483
500
|
* Header entries carrying an entry's tags (JSON-encoded, comma-safe) and the
|
|
@@ -554,7 +571,11 @@ export declare class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<T
|
|
|
554
571
|
* @internal
|
|
555
572
|
*/
|
|
556
573
|
private isL1Invalidated;
|
|
557
|
-
/**
|
|
574
|
+
/**
|
|
575
|
+
* Synthetic Cache API request for a tag's L1-cached invalidation marker.
|
|
576
|
+
* Unversioned for the same reason as tagMarkerKey; the cache namespace
|
|
577
|
+
* (getCache) still scopes it.
|
|
578
|
+
*/
|
|
558
579
|
private tagMarkerRequest;
|
|
559
580
|
/**
|
|
560
581
|
* Read a tag's latest invalidation timestamp (or null if never invalidated)
|
|
@@ -276,11 +276,19 @@ export interface CFCacheStoreOptions<TEnv = unknown> {
|
|
|
276
276
|
*/
|
|
277
277
|
tagCacheTtl?: number;
|
|
278
278
|
/**
|
|
279
|
-
* Cache version string override. When this
|
|
280
|
-
*
|
|
279
|
+
* Cache version string override. When set, this exact value prefixes every
|
|
280
|
+
* versioned key the store writes (`v/{version}/...`), for cached data and
|
|
281
|
+
* stored HTML alike; changing it makes every earlier entry unreachable.
|
|
281
282
|
*
|
|
282
|
-
*
|
|
283
|
-
*
|
|
283
|
+
* Leave it unset for the default: the store keys with the versions of the
|
|
284
|
+
* router serving the request. Segment entries and `"use cache"` items use
|
|
285
|
+
* the router's data version; document responses and PPR shells use its
|
|
286
|
+
* document version (see `createRouter({ version })`). Those are computed
|
|
287
|
+
* from the router's built code, so a deploy that does not change the router
|
|
288
|
+
* keeps its entries.
|
|
289
|
+
*
|
|
290
|
+
* Tag invalidation markers are never versioned: an invalidation applies to
|
|
291
|
+
* the entries of every version, including one that comes back in a rollback.
|
|
284
292
|
*/
|
|
285
293
|
version?: string;
|
|
286
294
|
/**
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* during segment resolution and stored alongside cached segments.
|
|
7
7
|
*/
|
|
8
8
|
import type { ResolvedSegment } from "../types.js";
|
|
9
|
-
import type { HandleStore } from "../server/handle-store.js";
|
|
9
|
+
import type { HandleStore, RecordAuthority } from "../server/handle-store.js";
|
|
10
10
|
import type { HandleOwners, SegmentHandleData } from "./types.js";
|
|
11
11
|
type HandleRecord = Record<string, SegmentHandleData>;
|
|
12
12
|
/**
|
|
@@ -44,52 +44,25 @@ export declare function decodeHandleValue<T>(encoded: string): Promise<T | null>
|
|
|
44
44
|
export declare function captureHandles(segments: ResolvedSegment[], handleStore: HandleStore): Record<string, SegmentHandleData>;
|
|
45
45
|
/** The owners of captureHandles' values; undefined when none is owned. */
|
|
46
46
|
export declare function captureHandleOwners(segments: ResolvedSegment[], handleStore: HandleStore): HandleOwners | undefined;
|
|
47
|
-
/**
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* A PPR shell's record (capture, document HIT tail, navigation replay): the
|
|
56
|
-
* loaders the route runs on the live lane (liveLaneLoaderIds), marked on
|
|
57
|
-
* the store (HandleStore.markLiveLane). A hole's values are replayed
|
|
58
|
-
* unclaimed, so its own cache() HIT redelivers its entry's pushes in their
|
|
59
|
-
* place (HandleStore.redeliverReplays), and its run ending without a push
|
|
60
|
-
* drops them (HandleStore.settleLoaderRun).
|
|
61
|
-
*/
|
|
62
|
-
liveLane?: ReadonlySet<string>;
|
|
63
|
-
/**
|
|
64
|
-
* A document HIT tail: every owner outside `liveLane` goes through
|
|
65
|
-
* pushRestored and stands, unclaimed.
|
|
66
|
-
*/
|
|
67
|
-
restore?: boolean;
|
|
68
|
-
}
|
|
47
|
+
/**
|
|
48
|
+
* What the record being restored is to each loader's handle pushes on this
|
|
49
|
+
* request (HandleStore RecordAuthority). Built by loaderPins (loader-cache.ts)
|
|
50
|
+
* over the pins resolveLoaderData serves a loader's value from, so a value
|
|
51
|
+
* and its record copies get one answer.
|
|
52
|
+
*/
|
|
53
|
+
export type OwnedPushDelivery = (loaderId: string) => RecordAuthority;
|
|
69
54
|
/**
|
|
70
55
|
* Restore handle data from a cached snapshot into the handle store.
|
|
71
56
|
* Used when serving cached segments to replay their handle data: a route
|
|
72
57
|
* cache() record owns its segments' arrays, so it REPLACES them.
|
|
73
58
|
*
|
|
74
59
|
* A segment with `owners` is replaced with empty arrays and re-pushed in
|
|
75
|
-
* recorded order
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
* restores as a plain replay.
|
|
82
|
-
*
|
|
83
|
-
* `owned.restore`: a document HIT tail restoring the shell's doc record
|
|
84
|
-
* (withCacheLookup). A bake-lane owner's values are the prelude's, so they go
|
|
85
|
-
* through pushRestored and stand: a run of that loader on the HIT (a
|
|
86
|
-
* promise-carrying `ssr: false` loader, one whose record asks for a run)
|
|
87
|
-
* reads the store, and its settled pushes are dropped, not swapped in.
|
|
88
|
-
* Nothing is claimed, so the loader's own cache() HIT still replays the
|
|
89
|
-
* pushes the record could not keep (the thenable ones pushRestored lets
|
|
90
|
-
* through). A loader the route also runs on the live lane is a hole: its
|
|
91
|
-
* values keep pushReplayed, unclaimed, and its live run replaces them
|
|
92
|
-
* (#936), even inside a restored loader's body (`owned.liveLane`).
|
|
60
|
+
* recorded order. A loader-owned value stands (pushRestored) where `owned`
|
|
61
|
+
* says the record supplies that loader's value too ("pin", "copies"), and is
|
|
62
|
+
* a placeholder (pushPlaceholder) everywhere else: without `owned`, every
|
|
63
|
+
* owner. Neither claims its loader, so the loader's own cache() HIT still
|
|
64
|
+
* delivers (the thenable pushes a restored copy lets through, or its entry's
|
|
65
|
+
* pushes in a placeholder's place).
|
|
93
66
|
*/
|
|
94
67
|
export declare function restoreHandles(handles: Record<string, SegmentHandleData>, handleStore: HandleStore, owners?: HandleOwners, owned?: OwnedPushDelivery): void;
|
|
95
68
|
/**
|
|
@@ -99,14 +72,27 @@ export declare function restoreHandles(handles: Record<string, SegmentHandleData
|
|
|
99
72
|
* restoreHandles would wipe those. `segmentId` redirects every value to one
|
|
100
73
|
* segment (the caller's).
|
|
101
74
|
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
75
|
+
* The replay of every cached unit that records by owner: a "use cache"
|
|
76
|
+
* function (useCacheRecordKey) and a loader's own cache() (loader-cache.ts
|
|
77
|
+
* recordOwnerKey, with `unitLoader` the cached loader).
|
|
78
|
+
*
|
|
79
|
+
* A `${seq}:${loaderId}` group is that loader's pushes, which reach the page
|
|
80
|
+
* once per request: `claim` (setupLoaderAccess _claimLoaderPushes) is asked
|
|
81
|
+
* once per loader and skips one that already ran or was replayed in this
|
|
82
|
+
* request; a claimed loader that runs later replaces its replayed values
|
|
83
|
+
* (HandleStore.pushReplayed). A group without an owner (`${seq}:`, or a key
|
|
84
|
+
* without ":" from a record written before owner keys, which is a segment
|
|
85
|
+
* id) is the unit's own: `unitLoader`'s, or no loader's for a function,
|
|
86
|
+
* whose pushes are plain.
|
|
87
|
+
*
|
|
88
|
+
* The claimed loaders' placeholders give way to this delivery
|
|
89
|
+
* (HandleStore.replacePlaceholders), `unitLoader`'s even when the entry
|
|
90
|
+
* recorded no push for it: the entry stands for that loader's run.
|
|
91
|
+
*
|
|
92
|
+
* No `claim` means the caller's pushes are diverted off the page (a stale
|
|
93
|
+
* refresh: cache-runtime.ts refreshView, setupLoaderAccess
|
|
94
|
+
* _runLoaderIsolated): every group is delivered, into the diverting capture,
|
|
95
|
+
* and the page's placeholders stay, or the page would lose the push.
|
|
110
96
|
*/
|
|
111
|
-
export declare function appendHandles(handles: Record<string, SegmentHandleData>, handleStore: HandleStore, segmentId
|
|
97
|
+
export declare function appendHandles(handles: Record<string, SegmentHandleData>, handleStore: HandleStore, segmentId: string | undefined, claim: ((loaderId: string) => boolean) | undefined, unitLoader?: string): void;
|
|
112
98
|
export {};
|
|
@@ -8,3 +8,5 @@ export { TRACKING_SEARCH_PARAMS, type CacheSearchParams, } from "./search-params
|
|
|
8
8
|
export { CacheScope, createCacheScope } from "./cache-scope.js";
|
|
9
9
|
export { createDocumentCacheMiddleware, type DocumentCacheOptions, } from "./document-cache.js";
|
|
10
10
|
export type { CacheErrorCategory } from "./cache-error.js";
|
|
11
|
+
export { getCacheVersions } from "../server/build-version-table.js";
|
|
12
|
+
export type { RouterVersions } from "../router-versions.js";
|