@rangojs/router 0.31.0 → 0.33.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/README.md +3 -2
- package/dist/bin/browser-7KIJ5HSV.js +15 -0
- package/dist/bin/chunk-3B7CKBRO.js +463 -0
- package/dist/bin/chunk-524VACCG.js +71 -0
- package/dist/bin/chunk-LD7UBHT4.js +196 -0
- package/dist/bin/chunk-TO6CRWLN.js +1429 -0
- package/dist/bin/chunk-TTXC2U3G.js +2477 -0
- package/dist/bin/client-urls-projection-DQLWPDAT.js +28 -0
- package/dist/bin/forward-user-plugins-URBZKJP4.js +62 -0
- package/dist/bin/rango.js +42 -10143
- package/dist/bin/runtime-EPUDEHO4.js +596 -0
- package/dist/bin/runtime-discovery-CZ2QHT4Q.js +352 -0
- package/dist/bin/state-ACD2MGKJ.js +16 -0
- package/dist/bin/temp-rsc-server-QRR6HD6T.js +3190 -0
- package/dist/types/bin/rango.d.ts +1 -0
- package/dist/types/browser/action-fence.d.ts +20 -0
- package/dist/types/browser/cookie-name.d.ts +51 -10
- package/dist/types/browser/history-state.d.ts +13 -2
- package/dist/types/browser/invalidate-client-cache.d.ts +8 -6
- package/dist/types/browser/navigation-bridge.d.ts +36 -1
- package/dist/types/browser/navigation-client.d.ts +19 -0
- package/dist/types/browser/navigation-store-handle.d.ts +37 -4
- package/dist/types/browser/navigation-store.d.ts +2 -2
- package/dist/types/browser/navigation-transaction.d.ts +0 -1
- package/dist/types/browser/partial-update.d.ts +13 -0
- package/dist/types/browser/prefetch/cache.d.ts +96 -8
- package/dist/types/browser/prefetch/fetch.d.ts +26 -2
- package/dist/types/browser/prefetch/queue.d.ts +3 -2
- package/dist/types/browser/rango-state.d.ts +34 -5
- package/dist/types/browser/react/Link.d.ts +19 -13
- package/dist/types/browser/react/location-state-shared.d.ts +2 -1
- package/dist/types/browser/types.d.ts +25 -0
- package/dist/types/build/generate-route-types.d.ts +1 -1
- package/dist/types/build/route-types/include-resolution.d.ts +9 -1
- package/dist/types/build/route-types/router-processing.d.ts +3 -1
- package/dist/types/cache/cache-key-utils.d.ts +12 -8
- package/dist/types/cache/cache-scope.d.ts +4 -2
- package/dist/types/cache/cf/cf-cache-types.d.ts +9 -5
- package/dist/types/cache/document-cache-policy.d.ts +9 -1
- package/dist/types/cache/memory-segment-store.d.ts +3 -2
- package/dist/types/cache/segment-codec.d.ts +2 -2
- package/dist/types/cache/shell-snapshot.d.ts +1 -1
- package/dist/types/cache/types.d.ts +12 -7
- package/dist/types/cache/vercel/vercel-cache-store.d.ts +2 -1
- package/dist/types/client-urls/types.d.ts +7 -5
- package/dist/types/prefetch-markers.d.ts +9 -0
- package/dist/types/prefetch-source-scope.d.ts +66 -0
- package/dist/types/route-definition/helpers-types.d.ts +8 -5
- package/dist/types/route-definition/redirect.d.ts +5 -0
- package/dist/types/router/intercept-resolution.d.ts +25 -11
- package/dist/types/router/match-context.d.ts +1 -0
- package/dist/types/router/match-handlers.d.ts +1 -1
- package/dist/types/router/middleware-types.d.ts +6 -0
- package/dist/types/router/prefetch-cache-ttl.d.ts +11 -3
- package/dist/types/router/router-context.d.ts +1 -1
- package/dist/types/router/router-options.d.ts +6 -3
- package/dist/types/router/segment-resolution/loader-cache.d.ts +8 -0
- package/dist/types/router/segment-resolution/prefetch-deferral.d.ts +23 -7
- package/dist/types/router/segment-resolution/revalidation.d.ts +19 -0
- package/dist/types/router/source-reads.d.ts +53 -0
- package/dist/types/router/types.d.ts +1 -1
- package/dist/types/rsc/helpers.d.ts +8 -3
- package/dist/types/rsc/prefetch-render-error.d.ts +7 -2
- package/dist/types/rsc/request-stages.d.ts +4 -0
- package/dist/types/rsc/shell-serve.d.ts +6 -1
- package/dist/types/server/context.d.ts +23 -6
- package/dist/types/server/cookie-store.d.ts +15 -1
- package/dist/types/server/document-location-state.d.ts +59 -0
- package/dist/types/server/handle-store.d.ts +2 -0
- package/dist/types/server/request-context.d.ts +65 -12
- package/dist/types/testing/e2e/server.d.ts +16 -1
- package/dist/types/testing/render-route.d.ts +83 -2
- package/dist/types/testing/serve-shell-request.d.ts +15 -3
- package/dist/types/types/handler-context.d.ts +21 -4
- package/dist/types/types/loader-types.d.ts +7 -4
- package/dist/types/types/segments.d.ts +18 -1
- package/dist/types/urls/path-helper-types.d.ts +7 -5
- package/dist/types/vite/temp-rsc-server.d.ts +2 -2
- package/dist/types/vite/utils/forward-user-plugins.d.ts +32 -2
- package/dist/vite/index.js +451 -191
- package/package.json +2 -2
- package/skills/app-structure/SKILL.md +74 -0
- package/skills/app-structure/e-commerce.md +10 -9
- package/skills/app-structure/large-app.md +15 -2
- package/skills/caching/SKILL.md +10 -5
- package/skills/client-urls/SKILL.md +18 -11
- package/skills/comparison/references/framework-comparison.md +16 -10
- package/skills/document-cache/SKILL.md +13 -0
- package/skills/hooks/navigation.md +8 -8
- package/skills/hooks/state.md +132 -12
- package/skills/intercept/SKILL.md +33 -11
- package/skills/layout/SKILL.md +11 -0
- package/skills/links/SKILL.md +101 -4
- package/skills/loader/SKILL.md +49 -22
- package/skills/migrate-nextjs/SKILL.md +8 -2
- package/skills/migrate-react-router/data-and-actions.md +5 -0
- package/skills/ppr/SKILL.md +38 -5
- package/skills/prerender/SKILL.md +4 -1
- package/skills/route/SKILL.md +6 -6
- package/skills/router-setup/SKILL.md +2 -1
- package/skills/server-actions/SKILL.md +49 -8
- package/skills/testing/client-components.md +73 -32
- package/skills/testing/serve-shell-request.md +45 -20
- package/skills/testing/server-actions.md +8 -0
- package/skills/ux-architecture/SKILL.md +67 -15
- package/src/bin/rango.ts +39 -13
- package/src/browser/action-fence.ts +72 -0
- package/src/browser/cookie-name.ts +82 -14
- package/src/browser/history-state.ts +24 -2
- package/src/browser/invalidate-client-cache.ts +9 -7
- package/src/browser/navigation-bridge.ts +164 -32
- package/src/browser/navigation-client.ts +95 -20
- package/src/browser/navigation-store-handle.ts +67 -5
- package/src/browser/navigation-store.ts +86 -17
- package/src/browser/navigation-transaction.ts +0 -6
- package/src/browser/partial-update.ts +31 -12
- package/src/browser/prefetch/cache.ts +188 -11
- package/src/browser/prefetch/fetch.ts +211 -51
- package/src/browser/prefetch/queue.ts +3 -2
- package/src/browser/rango-state.ts +50 -8
- package/src/browser/react/Link.tsx +24 -16
- package/src/browser/react/location-state-shared.ts +8 -1
- package/src/browser/react/use-navigation.ts +1 -1
- package/src/browser/rsc-router.tsx +13 -3
- package/src/browser/server-action-bridge.ts +3 -3
- package/src/browser/types.ts +25 -0
- package/src/build/generate-route-types.ts +1 -0
- package/src/build/route-types/include-resolution.ts +40 -3
- package/src/build/route-types/router-processing.ts +170 -25
- package/src/build/route-types/scan-filter.ts +1 -0
- package/src/build/runtime-discovery.ts +46 -8
- package/src/cache/cache-key-utils.ts +12 -8
- package/src/cache/cache-runtime.ts +5 -1
- package/src/cache/cache-scope.ts +28 -7
- package/src/cache/cf/cf-cache-types.ts +9 -5
- package/src/cache/document-cache-policy.ts +37 -1
- package/src/cache/document-cache.ts +12 -0
- package/src/cache/memory-segment-store.ts +3 -2
- package/src/cache/segment-codec.ts +2 -2
- package/src/cache/shell-snapshot.ts +1 -1
- package/src/cache/types.ts +12 -7
- package/src/cache/vercel/vercel-cache-store.ts +2 -1
- package/src/client-urls/types.ts +7 -5
- package/src/prefetch-markers.ts +10 -0
- package/src/prefetch-source-scope.ts +137 -0
- package/src/route-definition/helpers-types.ts +8 -5
- package/src/route-definition/redirect.ts +5 -0
- package/src/router/intercept-resolution.ts +94 -50
- package/src/router/loader-resolution.ts +8 -6
- package/src/router/match-api.ts +33 -29
- package/src/router/match-context.ts +5 -0
- package/src/router/match-handlers.ts +2 -1
- package/src/router/match-middleware/cache-lookup.ts +39 -14
- package/src/router/match-result.ts +45 -85
- package/src/router/middleware-types.ts +6 -0
- package/src/router/navigation-snapshot.ts +18 -3
- package/src/router/prefetch-cache-ttl.ts +15 -3
- package/src/router/revalidation.ts +63 -13
- package/src/router/router-context.ts +2 -1
- package/src/router/router-options.ts +6 -3
- package/src/router/segment-resolution/loader-cache.ts +21 -3
- package/src/router/segment-resolution/prefetch-deferral.ts +38 -31
- package/src/router/segment-resolution/revalidation.ts +40 -12
- package/src/router/source-reads.ts +122 -0
- package/src/router/types.ts +2 -1
- package/src/router.ts +11 -12
- package/src/rsc/helpers.ts +20 -6
- package/src/rsc/prefetch-render-error.ts +7 -2
- package/src/rsc/progressive-enhancement.ts +8 -2
- package/src/rsc/request-stages.ts +87 -1
- package/src/rsc/rsc-rendering.ts +78 -32
- package/src/rsc/server-action.ts +2 -1
- package/src/rsc/shell-capture.ts +4 -5
- package/src/rsc/shell-serve.ts +12 -1
- package/src/segment-system.tsx +1 -1
- package/src/server/context.ts +37 -6
- package/src/server/cookie-store.ts +22 -1
- package/src/server/document-location-state.ts +334 -0
- package/src/server/handle-store.ts +2 -0
- package/src/server/request-context.ts +137 -33
- package/src/testing/dispatch.ts +6 -0
- package/src/testing/e2e/fixture.ts +4 -12
- package/src/testing/e2e/server.ts +91 -4
- package/src/testing/render-route.tsx +309 -10
- package/src/testing/run-revalidate.ts +11 -1
- package/src/testing/serve-shell-request.ts +22 -3
- package/src/types/handler-context.ts +21 -4
- package/src/types/loader-types.ts +7 -4
- package/src/types/segments.ts +18 -1
- package/src/urls/path-helper-types.ts +7 -5
- package/src/vite/temp-rsc-server.ts +2 -2
- package/src/vite/utils/forward-user-plugins.ts +13 -5
|
@@ -6,11 +6,25 @@
|
|
|
6
6
|
* requests; the server responds with `Vary: X-Rango-State`, so the browser HTTP
|
|
7
7
|
* cache keys responses by (URL, X-Rango-State value).
|
|
8
8
|
*
|
|
9
|
-
* Value format: `{buildVersion}:{invalidationTimestamp}`
|
|
9
|
+
* Value format: `{buildVersion}:{invalidationTimestamp}[:{write}]`
|
|
10
10
|
* - Build version: the router's document version. It changes when a deploy
|
|
11
11
|
* changes the router's server code or the client assets, busting all cached
|
|
12
12
|
* prefetches at boot; a deploy that changes neither keeps them.
|
|
13
|
-
* - Timestamp rotates on invalidation (
|
|
13
|
+
* - Timestamp rotates on invalidation (invalidateClientCache, either seat).
|
|
14
|
+
* - Write: bumped by the response of a server action without a directive (its
|
|
15
|
+
* `Set-Cookie`, server side, so a no-JS action bumps it too); left out while
|
|
16
|
+
* 0. It changes the `X-Rango-State` every tab and every reload sends, so
|
|
17
|
+
* responses the browser HTTP cache holds from before the write miss.
|
|
18
|
+
*
|
|
19
|
+
* The client's in-memory comparisons read only `{buildVersion}:{timestamp}`
|
|
20
|
+
* (`stateEpoch`): the prefetch cache keys, the action fence's rotation check,
|
|
21
|
+
* the external-rotation observer below and the cross-tab adopt. A write-only
|
|
22
|
+
* change is soft: prefetches and history entries are marked stale and nothing
|
|
23
|
+
* is flushed. The tab that ran the action marks its own when it lands
|
|
24
|
+
* (navigation-store.ts markStaleSoftAndBroadcast) and tells the tabs that
|
|
25
|
+
* share a segment with it. Any other tab marks its own when a read sees the
|
|
26
|
+
* write part change (the write observer below), so a tab that ignores the
|
|
27
|
+
* broadcast or has crossTabSync off does not serve a pre-write prefetch fresh.
|
|
14
28
|
*
|
|
15
29
|
* Storage is a session cookie named by the server-resolved name passed to
|
|
16
30
|
* initRangoState (`{prefix}_{routerId}`, default prefix `rango-state`). The
|
|
@@ -27,10 +41,20 @@
|
|
|
27
41
|
*/
|
|
28
42
|
/**
|
|
29
43
|
* Register the observer invoked when a read detects an EXTERNAL rotation (a
|
|
30
|
-
* sibling tab, a server `Set-Cookie`, or a cookie clear)
|
|
44
|
+
* sibling tab, a server `Set-Cookie`, or a cookie clear) of the
|
|
45
|
+
* `{version}:{timestamp}` part. A change to the write part alone (a server
|
|
46
|
+
* action's write) goes to the write observer instead. Self-rotations
|
|
31
47
|
* (invalidateRangoState) update the mirror synchronously and never fire it.
|
|
32
48
|
*/
|
|
33
49
|
export declare function setRangoStateObserver(observer: ((value: string) => void) | null): void;
|
|
50
|
+
/**
|
|
51
|
+
* Register the observer invoked when a read sees the write part change while
|
|
52
|
+
* the `{version}:{timestamp}` part stays: a server action's response, in this
|
|
53
|
+
* tab or another, bumped it in the shared jar since the last read. Every read
|
|
54
|
+
* updates the mirror, and a prefetch reads the state before it starts, so a
|
|
55
|
+
* prefetch sent with the new value is never one this observer sees as old.
|
|
56
|
+
*/
|
|
57
|
+
export declare function setRangoStateWriteObserver(observer: (() => void) | null): void;
|
|
34
58
|
/** Return the resolved cookie name used to namespace cross-tab messages. */
|
|
35
59
|
export declare function getRangoStateCookieName(): string;
|
|
36
60
|
/**
|
|
@@ -49,10 +73,15 @@ export declare function initRangoState(version: string, stateCookieName?: string
|
|
|
49
73
|
export declare function getRangoState(): string;
|
|
50
74
|
/**
|
|
51
75
|
* Invalidate the Rango state (self-rotation). Called when the client clears its
|
|
52
|
-
* prefetch caches (e.g.
|
|
76
|
+
* prefetch caches (e.g. invalidateClientCache()). Rotates the timestamp,
|
|
53
77
|
* keeps the version, writes the cookie, and updates the mirror synchronously so
|
|
54
78
|
* the external-rotation observer is NOT triggered by our own write.
|
|
55
79
|
*/
|
|
56
80
|
export declare function invalidateRangoState(): void;
|
|
57
|
-
/**
|
|
81
|
+
/**
|
|
82
|
+
* Adopt the state carried by a same-origin cache-invalidation broadcast when
|
|
83
|
+
* its timestamp is newer (a rotation). The write part is not compared: a soft
|
|
84
|
+
* broadcast's newer write is already in the shared jar, and a value that
|
|
85
|
+
* differs only there is no rotation to adopt.
|
|
86
|
+
*/
|
|
58
87
|
export declare function adoptRangoState(value: string): boolean;
|
|
@@ -66,23 +66,29 @@ export interface LinkProps extends Omit<React.AnchorHTMLAttributes<HTMLAnchorEle
|
|
|
66
66
|
* keyed on Rango state + target URL. This is correct for routes whose
|
|
67
67
|
* response shape doesn't depend on where the user navigates from.
|
|
68
68
|
*
|
|
69
|
-
* Set `":source"`
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
* `currentUrl` / `currentParams`, and the wildcard entry would
|
|
73
|
-
* therefore serve the wrong diff to a navigation from a different
|
|
74
|
-
* source.
|
|
69
|
+
* Set `":source"` to scope every prefetch of this Link to the page that
|
|
70
|
+
* sent it, when its response would differ by source page in a way the
|
|
71
|
+
* server cannot see.
|
|
75
72
|
*
|
|
76
|
-
*
|
|
77
|
-
* (
|
|
78
|
-
*
|
|
79
|
-
* both source-specific
|
|
80
|
-
*
|
|
73
|
+
* The server scopes a prefetch to its source automatically
|
|
74
|
+
* (`x-rsc-prefetch-scope: source`) when an intercept targets the route or
|
|
75
|
+
* the source page, whether or not it applies (the modal and the full page
|
|
76
|
+
* are both source-specific), when the answer defers a `prefetch: false`
|
|
77
|
+
* unit the source does not hold, when a `revalidate()` of the target read
|
|
78
|
+
* `currentUrl` and kept the segment, and when a kept answer sends no
|
|
79
|
+
* segment. A `revalidate()` that read `currentParams` or `fromRouteName`
|
|
80
|
+
* and kept the segment, or a prerendered target that keeps segments on
|
|
81
|
+
* equal params (`storedEntrySends`), shares the answer between the pages
|
|
82
|
+
* with equal values of what was read (`x-rsc-prefetch-scope: params`,
|
|
83
|
+
* #1331). Every other response stays shared. Use the key
|
|
84
|
+
* for what the server does not track: `context` in a `revalidate()`, or
|
|
85
|
+
* a `Referer` read.
|
|
86
|
+
*
|
|
87
|
+
* A source-scoped entry is keyed by the source page's full URL, query
|
|
88
|
+
* and hash included, so every page prefetches the link again.
|
|
81
89
|
*
|
|
82
90
|
* @example
|
|
83
91
|
* ```tsx
|
|
84
|
-
* // Route uses a `revalidate()` that branches on currentUrl — opt in
|
|
85
|
-
* // so prefetches don't bleed across source pages.
|
|
86
92
|
* <Link to="/dashboard" prefetch="hover" prefetchKey=":source" />
|
|
87
93
|
* ```
|
|
88
94
|
*/
|
|
@@ -269,7 +269,8 @@ export declare function isLocationStateDefinition(value: unknown): value is Loca
|
|
|
269
269
|
*/
|
|
270
270
|
export declare function isLocationStateEntry(value: unknown): value is LocationStateEntry;
|
|
271
271
|
/**
|
|
272
|
-
* Resolve state entries into a flat object for history.state
|
|
272
|
+
* Resolve state entries into a flat object for history.state. One slot per
|
|
273
|
+
* definition: a later entry of the same definition replaces an earlier one.
|
|
273
274
|
*/
|
|
274
275
|
export declare function resolveLocationStateEntries(entries: LocationStateEntry[]): Record<string, unknown>;
|
|
275
276
|
export {};
|
|
@@ -600,7 +600,15 @@ export interface NavigationStore {
|
|
|
600
600
|
*/
|
|
601
601
|
getPageHistoryKeys(historyKey: string): string[];
|
|
602
602
|
markHistoryCacheStale(): void;
|
|
603
|
+
/**
|
|
604
|
+
* Mark history entries and prefetches stale without a broadcast: a cookie
|
|
605
|
+
* read saw another write (rango-state.ts setRangoStateWriteObserver).
|
|
606
|
+
*/
|
|
607
|
+
markCachesStaleAfterWrite(): void;
|
|
608
|
+
/** A server action without a directive: mark stale, soft broadcast. */
|
|
603
609
|
markCacheAsStaleAndBroadcast(): void;
|
|
610
|
+
/** The client seat of invalidateClientCache(): flush, rotate, broadcast. */
|
|
611
|
+
invalidateCacheAndBroadcast(): void;
|
|
604
612
|
clearHistoryCache(): void;
|
|
605
613
|
setCrossTabRefreshCallback(callback: () => void): void;
|
|
606
614
|
getInterceptSourceUrl(): string | null;
|
|
@@ -637,6 +645,16 @@ export interface FetchPartialOptions {
|
|
|
637
645
|
* to a prefetch cache or the HTTP cache, and it cancels no prefetch.
|
|
638
646
|
*/
|
|
639
647
|
fill?: boolean;
|
|
648
|
+
/**
|
|
649
|
+
* Whether a prefetch a server action marked stale (prefetch/cache.ts
|
|
650
|
+
* isPrefetchStale) may answer this navigation. Only a click sets it: it
|
|
651
|
+
* revalidates its page once it settled (navigation-bridge.ts navigate,
|
|
652
|
+
* partial-update.ts onStalePrefetch). For any other caller (Back/Forward on
|
|
653
|
+
* a history-cache miss, leaving an intercept) a stale stored entry is a
|
|
654
|
+
* miss, and a stale in-flight one is dropped and fetched again, so no path
|
|
655
|
+
* that never revalidates commits pre-write data.
|
|
656
|
+
*/
|
|
657
|
+
acceptStalePrefetch?: boolean;
|
|
640
658
|
}
|
|
641
659
|
/**
|
|
642
660
|
* Result of a partial fetch including stream completion tracking
|
|
@@ -654,6 +672,13 @@ export interface FetchPartialResult {
|
|
|
654
672
|
* fallbacks stream as usual.
|
|
655
673
|
*/
|
|
656
674
|
fullyPrefetched?: boolean;
|
|
675
|
+
/**
|
|
676
|
+
* True when the payload is a prefetch a server action marked stale after it
|
|
677
|
+
* was fetched (prefetch/cache.ts isPrefetchStale). The click commits it as
|
|
678
|
+
* any prefetch; the navigation then revalidates its page once it settled,
|
|
679
|
+
* as Back onto a stale history entry does (navigation-bridge.ts navigate).
|
|
680
|
+
*/
|
|
681
|
+
stalePrefetch?: boolean;
|
|
657
682
|
}
|
|
658
683
|
/**
|
|
659
684
|
* Navigation client for fetching RSC payloads
|
|
@@ -4,5 +4,5 @@ export { generatePerModuleTypesSource, generateRouteTypesSource, } from "./route
|
|
|
4
4
|
export { DEFAULT_EXCLUDE_PATTERNS, type ScanFilter, createScanFilter, findTsFiles, isInSkippedScanDir, } from "./route-types/scan-filter.js";
|
|
5
5
|
export { writePerModuleRouteTypes, writePerModuleRouteTypesForFile, } from "./route-types/per-module-writer.js";
|
|
6
6
|
export { type UnresolvableReason, type UnresolvableInclude, extractIncludesWithDiagnostics, } from "./route-types/include-resolution.js";
|
|
7
|
-
export { extractUrlsFromRouter, type UrlsExtractionResult, buildCombinedRouteMapForRouterFile, detectUnresolvableIncludes, detectUnresolvableIncludesForUrlsFile, findNestedRouterConflict, formatNestedRouterConflictError, findRouterFiles, findHostRouterFiles, writeCombinedRouteTypes, genFileTsPath, resolveSearchSchemas, } from "./route-types/router-processing.js";
|
|
7
|
+
export { extractUrlsFromRouter, type UrlsExtractionResult, buildCombinedRouteMapForRouterFile, detectUnresolvableIncludes, detectUnresolvableIncludesForUrlsFile, findNestedRouterConflict, formatNestedRouterConflictError, findRouterFiles, findHostRouterFiles, isRoutableSourceFile, writeCombinedRouteTypes, genFileTsPath, resolveSearchSchemas, } from "./route-types/router-processing.js";
|
|
8
8
|
export { findUrlsVariableNames } from "./route-types/per-module-writer.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import ts from "typescript";
|
|
2
|
-
export type UnresolvableReason = "factory-call" | "dynamic-expression" | "unresolvable-import" | "file-not-found" | "unresolvable-basename";
|
|
2
|
+
export type UnresolvableReason = "factory-call" | "dynamic-expression" | "unresolvable-import" | "file-not-found" | "unresolvable-basename" | "unresolvable-routes";
|
|
3
3
|
export interface UnresolvableInclude {
|
|
4
4
|
pathPrefix: string;
|
|
5
5
|
namePrefix: string | null;
|
|
@@ -25,6 +25,14 @@ export interface ScanMemo {
|
|
|
25
25
|
blockSourceFiles: Map<string, ts.SourceFile>;
|
|
26
26
|
}
|
|
27
27
|
export declare function createScanMemo(): ScanMemo;
|
|
28
|
+
export declare function isUrlsDefinitionCall(node: ts.CallExpression, aliases?: ReadonlySet<string>): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Local names that `import { urls as u, clientUrls as cu } from
|
|
31
|
+
* "@rangojs/router"` (or `/client`) binds to urls()/clientUrls(), so a renamed
|
|
32
|
+
* import is read like the plain name. Other modules' exports are not guessed
|
|
33
|
+
* at: a `urls` from elsewhere is read only under its own name.
|
|
34
|
+
*/
|
|
35
|
+
export declare function collectUrlsImportAliases(sourceFile: ts.SourceFile): ReadonlySet<string>;
|
|
28
36
|
/**
|
|
29
37
|
* Extract include() calls with diagnostics for unresolvable ones.
|
|
30
38
|
* Returns both resolved includes (identifier second args) and unresolvable
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type ScanFilter } from "./scan-filter.js";
|
|
2
2
|
import { type UnresolvableInclude } from "./include-resolution.js";
|
|
3
|
+
export declare function isRoutableSourceFile(name: string): boolean;
|
|
3
4
|
export declare function findNestedRouterConflict(routerFiles: string[]): {
|
|
4
5
|
ancestor: string;
|
|
5
6
|
nested: string;
|
|
@@ -22,11 +23,12 @@ export type UrlsExtractionResult = {
|
|
|
22
23
|
};
|
|
23
24
|
/**
|
|
24
25
|
* Extract the url patterns from a router file using AST.
|
|
25
|
-
* Detects
|
|
26
|
+
* Detects these patterns, in either mount (`.routes(x)` or `urls: x`):
|
|
26
27
|
* 1. createRouter(...).routes(variableName)
|
|
27
28
|
* 2. createRouter({ urls: variableName, ... })
|
|
28
29
|
* 3. createRouter(...).routes(({ path, ... }) => [...])
|
|
29
30
|
* 4. createRouter({ urls: ({ path, ... }) => [...], ... })
|
|
31
|
+
* 5. createRouter(...).routes(urls(({ path, ... }) => [...])), and clientUrls()
|
|
30
32
|
* Returns either a variable name or an inline code block.
|
|
31
33
|
*/
|
|
32
34
|
export declare function extractUrlsFromRouter(code: string): UrlsExtractionResult | null;
|
|
@@ -97,9 +97,10 @@ export declare const KEY_PART_PREFIX = "key:";
|
|
|
97
97
|
* (CacheScope.resolveKeyFrom, CacheScope.resolvePartition): the `key()`
|
|
98
98
|
* results of the scope's cache() chain, outermost first, then its default
|
|
99
99
|
* parts: the keyGenerator results of enclosing scopes on another store
|
|
100
|
-
* (#974) and, for a route record key, the scope's own
|
|
100
|
+
* (#974) and, for a route record key, the scope's own parts: without a
|
|
101
101
|
* `key()` of its own, its default key (or its store's keyGenerator result,
|
|
102
|
-
* #970
|
|
102
|
+
* #970, then the request kind when that result does not start with it,
|
|
103
|
+
* #1298); with one, the default key's request kind (`doc`, `partial` or
|
|
103
104
|
* `intercept:<intercept>`, routeRecordKind in cache-scope.ts).
|
|
104
105
|
*
|
|
105
106
|
* Key scheme invariant (#975). A `key()` result is often request input,
|
|
@@ -119,7 +120,9 @@ export declare const KEY_PART_PREFIX = "key:";
|
|
|
119
120
|
* - one `key()` part is the key; two or more parts are joined by `|`,
|
|
120
121
|
* `key()` parts first;
|
|
121
122
|
* - a lone default part stays raw: with no `key()` on the chain the record
|
|
122
|
-
* key is the default key or the store's keyGenerator result, unchanged
|
|
123
|
+
* key is the default key or the store's keyGenerator result, unchanged
|
|
124
|
+
* when that result starts with its request kind, else that result and
|
|
125
|
+
* the kind composed (`items|doc`).
|
|
123
126
|
*
|
|
124
127
|
* Why nothing collides: the router's default keys (`doc:`, `partial:`,
|
|
125
128
|
* `intercept:`, `response:<type>:`) never start with `key:` and hold a `:`.
|
|
@@ -128,11 +131,12 @@ export declare const KEY_PART_PREFIX = "key:";
|
|
|
128
131
|
* Among composed keys, splitting on `|` recovers each part, a part's kind
|
|
129
132
|
* (a `key:` prefix, or no `:` at all) and its value. A request kind part is
|
|
130
133
|
* a default key's prefix without the URL after it, so it never equals a
|
|
131
|
-
* default key part
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
134
|
+
* default key part. A raw keyGenerator record key starts with its kind and
|
|
135
|
+
* holds a `:`, so it never equals a composed one, and two kinds' prefixes
|
|
136
|
+
* differ; a result without its kind is composed with it, never prefixed,
|
|
137
|
+
* since `doc:` + `x` would be the raw result `doc:x`. Pinned by the
|
|
138
|
+
* collision probes in src/cache/__tests__/cache-scope-chain.test.ts. A
|
|
139
|
+
* keyGenerator result is the store's own namespace, as before.
|
|
136
140
|
*
|
|
137
141
|
* Shared with the testing helper `shellCacheKey`, so a test builds the
|
|
138
142
|
* production partition.
|
|
@@ -200,8 +200,10 @@ export declare class CacheScope {
|
|
|
200
200
|
* replaces the URL part, and its store's keyGenerator does not run. It
|
|
201
201
|
* appends `kind` instead (routeRecordKind): the `key()` decides which
|
|
202
202
|
* requests of one kind share a record, never that a document, a
|
|
203
|
-
* navigation and an intercept navigation do.
|
|
204
|
-
*
|
|
203
|
+
* navigation and an intercept navigation do. A keyGenerator result that
|
|
204
|
+
* does not start with its kind gets `kind` after it too (ownParts). With
|
|
205
|
+
* no partition part it is resolveDefaultKey alone, or that result and
|
|
206
|
+
* `kind` composed. With a `key()` on the chain but no request
|
|
205
207
|
* context it rejects (keyWithoutContextError). `partitionedPrefix`
|
|
206
208
|
* prefixes a key built from partition parts only (the response family's
|
|
207
209
|
* `response:`, which passes no `kind`: a response route answers every
|
|
@@ -369,19 +369,23 @@ export interface CFCacheStoreOptions<TEnv = unknown> {
|
|
|
369
369
|
/**
|
|
370
370
|
* Custom key generator applied to all cache operations.
|
|
371
371
|
* Receives the full RequestContext (including env) and the default-generated key.
|
|
372
|
-
*
|
|
372
|
+
* The return value is the cache key (unless route overrides with `key`
|
|
373
|
+
* option), except that a route record keeps its request kind: a result that
|
|
374
|
+
* does not start with `defaultKey`'s prefix (`doc:`, `partial:`,
|
|
375
|
+
* `intercept:<intercept>:`) gets the kind appended (see
|
|
376
|
+
* SegmentCacheStore.keyGenerator).
|
|
373
377
|
*
|
|
374
378
|
* Reserved prefixes: tag-invalidation markers live in the SAME KV namespace as
|
|
375
379
|
* data, keyed `__tag__/<tag>` (and `__tagmarker__/<tag>` for the L1 cache). A
|
|
376
380
|
* returned key must NOT begin with `__tag__/` or `__tagmarker__/`, or it can
|
|
377
381
|
* collide with a tag marker and corrupt invalidation. The documented
|
|
378
|
-
*
|
|
382
|
+
* generators below start with `defaultKey` and are safe.
|
|
379
383
|
*
|
|
380
384
|
* @example Using headers for user segmentation
|
|
381
385
|
* ```typescript
|
|
382
386
|
* keyGenerator: (ctx, defaultKey) => {
|
|
383
387
|
* const segment = ctx.request.headers.get('x-user-segment') || 'default';
|
|
384
|
-
* return `${
|
|
388
|
+
* return `${defaultKey}|${segment}`;
|
|
385
389
|
* }
|
|
386
390
|
* ```
|
|
387
391
|
*
|
|
@@ -389,7 +393,7 @@ export interface CFCacheStoreOptions<TEnv = unknown> {
|
|
|
389
393
|
* ```typescript
|
|
390
394
|
* keyGenerator: (ctx, defaultKey) => {
|
|
391
395
|
* const region = ctx.env.REGION || 'us';
|
|
392
|
-
* return `${
|
|
396
|
+
* return `${defaultKey}|${region}`;
|
|
393
397
|
* }
|
|
394
398
|
* ```
|
|
395
399
|
*
|
|
@@ -397,7 +401,7 @@ export interface CFCacheStoreOptions<TEnv = unknown> {
|
|
|
397
401
|
* ```typescript
|
|
398
402
|
* keyGenerator: (ctx, defaultKey) => {
|
|
399
403
|
* const locale = cookies().get('locale')?.value || 'en';
|
|
400
|
-
* return `${
|
|
404
|
+
* return `${defaultKey}|${locale}`;
|
|
401
405
|
* }
|
|
402
406
|
* ```
|
|
403
407
|
*/
|
|
@@ -12,7 +12,15 @@ export interface CacheDirectives {
|
|
|
12
12
|
/**
|
|
13
13
|
* Check if response should be cached based on Cache-Control headers
|
|
14
14
|
*/
|
|
15
|
-
export declare function shouldCacheResponse(response: Response, requestCtx?: Pick<RequestContext, "_payloadVisitorTheme" | "_payloadDeferred" | "_payloadVisitorLocation">): CacheDirectives | null;
|
|
15
|
+
export declare function shouldCacheResponse(response: Response, requestCtx?: Pick<RequestContext, "_payloadVisitorTheme" | "_payloadDeferred" | "_payloadSourceScoped" | "_payloadVisitorLocation" | "_documentLocationState">): CacheDirectives | null;
|
|
16
|
+
/**
|
|
17
|
+
* Whether a response carries one client's state, which a stored copy would
|
|
18
|
+
* replay to that client's later requests: a per-client signal header (a state
|
|
19
|
+
* cookie rotation, `x-rango-keep-cache`) or location state. The stored
|
|
20
|
+
* prefetch Cache-Control (rsc/request-stages.ts) is not sent on
|
|
21
|
+
* one.
|
|
22
|
+
*/
|
|
23
|
+
export declare function carriesClientState(response: Response, requestCtx: Pick<RequestContext, "_locationState" | "_documentLocationState">): boolean;
|
|
16
24
|
/**
|
|
17
25
|
* Whether this cache will store the response the current render produces, as
|
|
18
26
|
* far as the render can tell: the middleware runs it (a MISS or a stale
|
|
@@ -46,13 +46,14 @@ export interface MemorySegmentCacheStoreOptions<TEnv = unknown> {
|
|
|
46
46
|
defaults?: CacheDefaults;
|
|
47
47
|
/**
|
|
48
48
|
* Custom key generator applied to all cache operations.
|
|
49
|
-
* Receives the full RequestContext and the default-generated key.
|
|
49
|
+
* Receives the full RequestContext and the default-generated key. A route
|
|
50
|
+
* record keeps its request kind (see SegmentCacheStore.keyGenerator).
|
|
50
51
|
*
|
|
51
52
|
* @example
|
|
52
53
|
* ```typescript
|
|
53
54
|
* keyGenerator: (ctx, defaultKey) => {
|
|
54
55
|
* const locale = cookies().get('locale')?.value || 'en';
|
|
55
|
-
* return `${
|
|
56
|
+
* return `${defaultKey}|${locale}`;
|
|
56
57
|
* }
|
|
57
58
|
* ```
|
|
58
59
|
*/
|
|
@@ -88,8 +88,8 @@ export declare function serializeSegments(segments: ResolvedSegment[], onError?:
|
|
|
88
88
|
* cached with the route record).
|
|
89
89
|
*
|
|
90
90
|
* The loading "null" sentinel decodes here (not on the consumer): loading:null
|
|
91
|
-
* must survive as null, and shipping the raw sentinel would
|
|
92
|
-
*
|
|
91
|
+
* must survive as null, and shipping the raw sentinel would hand renderSegments
|
|
92
|
+
* a truthy `loading`, the fallback tree shape (docs/tree-structure.md).
|
|
93
93
|
*/
|
|
94
94
|
export declare function fragmentSegments(data: SerializedSegmentData[]): Promise<ResolvedSegment[]>;
|
|
95
95
|
/**
|
|
@@ -201,7 +201,7 @@ export interface ShellLoaderSeedEntry {
|
|
|
201
201
|
* Deserializations run in parallel; a record that fails to decode is skipped
|
|
202
202
|
* and reported to `onUndecodable`: its loader runs instead, which a document
|
|
203
203
|
* HIT has already committed a prelude against, so serveShellHit retires the
|
|
204
|
-
* entry
|
|
204
|
+
* entry. Returns undefined when the snapshot carries no loader
|
|
205
205
|
* records, without touching the Flight codec (kept lazy for cold paths and
|
|
206
206
|
* non-RSC configs).
|
|
207
207
|
*/
|
|
@@ -83,16 +83,21 @@ export interface SegmentCacheStore<TEnv = unknown> {
|
|
|
83
83
|
/**
|
|
84
84
|
* Custom key generator applied to all cache operations using this store.
|
|
85
85
|
* Receives the full RequestContext and the default-generated key.
|
|
86
|
-
*
|
|
86
|
+
* The return value is the cache key (unless route overrides with `key`
|
|
87
|
+
* option), with a route record's request kind appended when it does not
|
|
88
|
+
* start with that kind (below).
|
|
87
89
|
*
|
|
88
90
|
* Resolution priority:
|
|
89
91
|
* 1. Route-level `key` function (replaces the URL part; the request kind stays)
|
|
90
92
|
* 2. Store-level `keyGenerator` (modifies default key)
|
|
91
93
|
* 3. Default key generation (prefix:pathname:params)
|
|
92
94
|
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
95
|
+
* A route record keeps its request kind (a document, a navigation or an
|
|
96
|
+
* intercept navigation), whose records hold different segments: the kind
|
|
97
|
+
* is `defaultKey`'s prefix (`doc:`, `partial:`, `intercept:<intercept>:`),
|
|
98
|
+
* and a result that does not start with it gets the kind appended as a
|
|
99
|
+
* key part of its own. Build on `defaultKey` (`${defaultKey}|${segment}`)
|
|
100
|
+
* and the result is the record key byte for byte.
|
|
96
101
|
*
|
|
97
102
|
* Return `defaultKey` unchanged to leave a request unpartitioned. An empty
|
|
98
103
|
* string is not a key: where the result partitions a nested cache() on
|
|
@@ -104,7 +109,7 @@ export interface SegmentCacheStore<TEnv = unknown> {
|
|
|
104
109
|
* ```typescript
|
|
105
110
|
* keyGenerator: (ctx, defaultKey) => {
|
|
106
111
|
* const segment = ctx.request.headers.get('x-user-segment') || 'default';
|
|
107
|
-
* return `${
|
|
112
|
+
* return `${defaultKey}|${segment}`;
|
|
108
113
|
* }
|
|
109
114
|
* ```
|
|
110
115
|
*
|
|
@@ -112,7 +117,7 @@ export interface SegmentCacheStore<TEnv = unknown> {
|
|
|
112
117
|
* ```typescript
|
|
113
118
|
* keyGenerator: (ctx, defaultKey) => {
|
|
114
119
|
* const region = ctx.env.REGION || 'us';
|
|
115
|
-
* return `${
|
|
120
|
+
* return `${defaultKey}|${region}`;
|
|
116
121
|
* }
|
|
117
122
|
* ```
|
|
118
123
|
*
|
|
@@ -120,7 +125,7 @@ export interface SegmentCacheStore<TEnv = unknown> {
|
|
|
120
125
|
* ```typescript
|
|
121
126
|
* keyGenerator: (ctx, defaultKey) => {
|
|
122
127
|
* const locale = cookies().get('locale')?.value || 'en';
|
|
123
|
-
* return `${
|
|
128
|
+
* return `${defaultKey}|${locale}`;
|
|
124
129
|
* }
|
|
125
130
|
* ```
|
|
126
131
|
*/
|
|
@@ -125,7 +125,8 @@ export interface VercelCacheStoreOptions<TEnv = unknown> {
|
|
|
125
125
|
defaults?: CacheDefaults;
|
|
126
126
|
/**
|
|
127
127
|
* Custom key generator applied to all cache operations (region/locale/user
|
|
128
|
-
* segmentation). Receives the request context and the default key.
|
|
128
|
+
* segmentation). Receives the request context and the default key. A route
|
|
129
|
+
* record keeps its request kind (see SegmentCacheStore.keyGenerator).
|
|
129
130
|
*/
|
|
130
131
|
keyGenerator?: (ctx: RequestContext<TEnv>, defaultKey: string) => string | Promise<string>;
|
|
131
132
|
/**
|
|
@@ -48,8 +48,9 @@ export interface ClientUrlLoaderRecord {
|
|
|
48
48
|
*/
|
|
49
49
|
readonly ssr?: false;
|
|
50
50
|
/**
|
|
51
|
-
* loader(Def, { prefetch: false }): a
|
|
52
|
-
* intercept's target from its source, defers this loader
|
|
51
|
+
* loader(Def, { prefetch: false }): a viewport or render prefetch of the
|
|
52
|
+
* route, or of an intercept's target from its source, defers this loader
|
|
53
|
+
* (a hover prefetch runs it) and the click
|
|
53
54
|
* that adopts it runs it in its fill request (see {@link LoaderOptions}).
|
|
54
55
|
* Projected onto the materialized stub.
|
|
55
56
|
*/
|
|
@@ -118,12 +119,13 @@ export interface ClientUrlHelpers {
|
|
|
118
119
|
* holes).
|
|
119
120
|
*
|
|
120
121
|
* Pass `{ prefetch: false }` to keep this loader out of the route's
|
|
121
|
-
*
|
|
122
|
+
* viewport and render prefetches; a hover prefetch runs it (see
|
|
123
|
+
* {@link LoaderOptions}). An in-group click still shows
|
|
122
124
|
* the destination at once, commits the adopted prefetch with the other
|
|
123
125
|
* loaders' data, and runs only the flagged loaders in its one fill
|
|
124
126
|
* request. A `layout()` loader with the flag is flagged on every route
|
|
125
|
-
* below it. Inside intercept() it defers the loader in a
|
|
126
|
-
* intercept from its source, as in urls().
|
|
127
|
+
* below it. Inside intercept() it defers the loader in a viewport or
|
|
128
|
+
* render prefetch of the intercept from its source, as in urls().
|
|
127
129
|
*/
|
|
128
130
|
readonly loader: <TData>(definition: LoaderDefinition<TData>, optionsOrUse?: Pick<LoaderOptions, "ssr" | "prefetch"> | ClientUrlUse, use?: ClientUrlUse) => ClientUrlItem;
|
|
129
131
|
readonly loading: (component: ReactNode) => ClientUrlItem;
|
|
@@ -7,6 +7,15 @@
|
|
|
7
7
|
*/
|
|
8
8
|
/** Request header of a `<Link>` prefetch (browser/prefetch/fetch.ts). */
|
|
9
9
|
export declare const PREFETCH_HEADER = "X-Rango-Prefetch";
|
|
10
|
+
/**
|
|
11
|
+
* PREFETCH_HEADER's value on an intent prefetch: a hover or an explicit
|
|
12
|
+
* `prefetch()` call (browser/prefetch/fetch.ts prefetchDirect). The server
|
|
13
|
+
* defers nothing in it: `prefetch: false` loaders and the work behind a
|
|
14
|
+
* flagged `loading()` run, as in the navigation it starts early. A
|
|
15
|
+
* speculative prefetch (viewport, render) sends `1`, and any value other than
|
|
16
|
+
* this one reads as speculative.
|
|
17
|
+
*/
|
|
18
|
+
export declare const PREFETCH_INTENT = "intent";
|
|
10
19
|
/**
|
|
11
20
|
* The last row of a prefetch whose render reported an error
|
|
12
21
|
* (rsc/prefetch-render-error.ts): a Flight hint with a code React does not
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The source group of a prefetch answer a revalidate() rule kept from the
|
|
3
|
+
* page being left (#1331). Shared by the server, which reports
|
|
4
|
+
* the group in `x-rsc-prefetch-scope: params; <label>` (rsc/rsc-rendering.ts),
|
|
5
|
+
* and the browser, which stores the answer under that label and rebuilds it
|
|
6
|
+
* from the page on screen to look it up (browser/prefetch/cache.ts).
|
|
7
|
+
* Dependency free, like prefetch-markers.ts: the browser must not import the
|
|
8
|
+
* server modules that record the reads (router/source-reads.ts).
|
|
9
|
+
*
|
|
10
|
+
* Why a label is enough: a rule's decision depends on the source page only
|
|
11
|
+
* through what it read. Two pages with equal values of everything the kept
|
|
12
|
+
* rules read run every rule the same way, so one answer serves both.
|
|
13
|
+
*/
|
|
14
|
+
/** What the revalidate() rules that kept a segment read of the source page. */
|
|
15
|
+
export interface SourceReads {
|
|
16
|
+
/**
|
|
17
|
+
* `currentParams` was read. Its key set is then part of the group: a rule
|
|
18
|
+
* can test a key's presence (`in`, `Object.keys`) without reading a value.
|
|
19
|
+
*/
|
|
20
|
+
keys: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Each `currentParams` value read; a spread or JSON.stringify reads all.
|
|
23
|
+
* Non-empty only with `keys`: a value is read through `currentParams`.
|
|
24
|
+
*/
|
|
25
|
+
params: Set<string>;
|
|
26
|
+
/** `fromRouteName` was read. */
|
|
27
|
+
route: boolean;
|
|
28
|
+
/** `currentUrl` was read: the answer is the exact page's. */
|
|
29
|
+
url: boolean;
|
|
30
|
+
}
|
|
31
|
+
/** The page a label describes: the source on the server, the screen in the browser. */
|
|
32
|
+
export interface SourcePage {
|
|
33
|
+
params: Readonly<Record<string, string | undefined>>;
|
|
34
|
+
/** The public route name (route-name.ts publicRouteName). */
|
|
35
|
+
routeName: string | undefined;
|
|
36
|
+
}
|
|
37
|
+
/** What a label reads, without the values: one per kind of rule set. */
|
|
38
|
+
export interface SourceShape {
|
|
39
|
+
keys: boolean;
|
|
40
|
+
route: boolean;
|
|
41
|
+
/** Sorted. */
|
|
42
|
+
names: readonly string[];
|
|
43
|
+
}
|
|
44
|
+
/** `x-rsc-prefetch-scope` value prefix of a params-grouped answer. */
|
|
45
|
+
export declare const PARAMS_SCOPE_PREFIX = "params; ";
|
|
46
|
+
export declare function createSourceReads(): SourceReads;
|
|
47
|
+
export declare function hasSourceReads(reads: SourceReads): boolean;
|
|
48
|
+
/** Union `from` into `into`. */
|
|
49
|
+
export declare function mergeSourceReads(into: SourceReads, from: SourceReads): void;
|
|
50
|
+
export declare function shapeOfReads(reads: SourceReads): SourceShape;
|
|
51
|
+
/**
|
|
52
|
+
* The label of `page` under `shape`: `&`-joined, `$k=<keys>` first, then
|
|
53
|
+
* `$r[=<route>]`, then `<name>[=<value>]` per read param, sorted. A missing
|
|
54
|
+
* value has no `=`. Names and values are URI-encoded, so a `$` entry never
|
|
55
|
+
* collides with a param (encodeURIComponent encodes `$`).
|
|
56
|
+
*/
|
|
57
|
+
export declare function formatSourceLabel(shape: SourceShape, page: SourcePage): string;
|
|
58
|
+
/**
|
|
59
|
+
* The label of an `x-rsc-prefetch-scope` value, or undefined when the value
|
|
60
|
+
* is not a params scope.
|
|
61
|
+
*/
|
|
62
|
+
export declare function paramsScopeLabel(header: string | null | undefined): string | undefined;
|
|
63
|
+
/** The shape of a label formatSourceLabel wrote. */
|
|
64
|
+
export declare function parseSourceShape(label: string): SourceShape;
|
|
65
|
+
/** A stable id of a shape, for indexing. */
|
|
66
|
+
export declare function sourceShapeId(shape: SourceShape): string;
|
|
@@ -231,9 +231,10 @@ export type RouteHelpers<T extends RouteDefinition, TEnv> = {
|
|
|
231
231
|
* loader(RecommendationsLoader), // still streams behind loading()
|
|
232
232
|
* ```
|
|
233
233
|
*
|
|
234
|
-
* Pass `{ prefetch: false }` to keep the loader out of
|
|
235
|
-
* prefetch skips it and the click
|
|
236
|
-
* one follow-up request
|
|
234
|
+
* Pass `{ prefetch: false }` to keep the loader out of speculative
|
|
235
|
+
* prefetches (viewport, render): such a prefetch skips it and the click
|
|
236
|
+
* that adopts it fetches it in one follow-up request; a hover prefetch runs
|
|
237
|
+
* it (see {@link LoaderOptions}). Only on a segment the
|
|
237
238
|
* client does not have yet: a loader the client already holds runs in the
|
|
238
239
|
* prefetch when it revalidates.
|
|
239
240
|
*
|
|
@@ -255,14 +256,16 @@ export type RouteHelpers<T extends RouteDefinition, TEnv> = {
|
|
|
255
256
|
* // Skip loading on SSR, only show on client navigation
|
|
256
257
|
* loading(<Skeleton />, { ssr: false })
|
|
257
258
|
*
|
|
258
|
-
* // Keep everything behind this fallback out of
|
|
259
|
+
* // Keep everything behind this fallback out of viewport and render
|
|
260
|
+
* // prefetches (a hover prefetch runs it)
|
|
259
261
|
* loading(<Skeleton />, { prefetch: false })
|
|
260
262
|
* ```
|
|
261
263
|
* @param component - The loading UI to show during navigation
|
|
262
264
|
* @param options - Configuration options
|
|
263
265
|
* @param options.ssr - If false, skip showing loading on document requests (SSR)
|
|
264
266
|
* @param options.prefetch - If false, the flag applies when this entry's
|
|
265
|
-
* segment is new to the client. A prefetch then skips
|
|
267
|
+
* segment is new to the client. A viewport or render prefetch then skips
|
|
268
|
+
* the whole unit (a hover prefetch runs it): the
|
|
266
269
|
* handler, its loaders, its orphan layouts and parallel slots and, for a
|
|
267
270
|
* layout, every deeper entry; the click that adopts the prefetch shows
|
|
268
271
|
* this fallback and fetches them in one follow-up request, which reads
|
|
@@ -9,6 +9,11 @@ import type { LocationStateEntry } from "../browser/react/location-state-shared.
|
|
|
9
9
|
* Supports an optional state parameter to carry location state through the
|
|
10
10
|
* redirect. On the target page, state can be read via useLocationState()
|
|
11
11
|
* (use { flash: true } in createLocationState for read-once flash messages).
|
|
12
|
+
* On a client navigation or action the state travels in the redirect's
|
|
13
|
+
* payload. On a document request (a page load, a no-JS form post) it travels
|
|
14
|
+
* in a one-shot cookie the target's document request reads and clears, as
|
|
15
|
+
* JSON: give it plain JSON data there. `{ external: true }` carries none.
|
|
16
|
+
* Two entries of the same definition keep only the last.
|
|
12
17
|
*
|
|
13
18
|
* @param url - The URL to redirect to
|
|
14
19
|
* @param statusOrOptions - HTTP status code (default: 302) or options object
|