@rangojs/router 0.26.6 → 0.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (234) hide show
  1. package/dist/bin/rango.js +1 -1
  2. package/dist/types/__internal.d.ts +7 -1
  3. package/dist/types/browser/action-coordinator.d.ts +0 -4
  4. package/dist/types/browser/action-fence.d.ts +11 -3
  5. package/dist/types/browser/event-controller.d.ts +20 -1
  6. package/dist/types/browser/history-state.d.ts +7 -9
  7. package/dist/types/browser/intercept-utils.d.ts +23 -0
  8. package/dist/types/browser/navigation-store.d.ts +8 -6
  9. package/dist/types/browser/react/filter-segment-order.d.ts +2 -2
  10. package/dist/types/browser/rsc-router.d.ts +1 -1
  11. package/dist/types/browser/segment-reconciler.d.ts +6 -4
  12. package/dist/types/browser/types.d.ts +2 -1
  13. package/dist/types/browser/wire-protocol.d.ts +25 -0
  14. package/dist/types/cache/cache-key-utils.d.ts +11 -5
  15. package/dist/types/cache/cache-scope.d.ts +34 -22
  16. package/dist/types/cache/cf/cf-cache-constants.d.ts +2 -2
  17. package/dist/types/cache/cf/cf-cache-store.d.ts +47 -65
  18. package/dist/types/cache/cf/cf-kv-utils.d.ts +1 -1
  19. package/dist/types/cache/handle-snapshot.d.ts +9 -4
  20. package/dist/types/cache/segment-codec.d.ts +14 -0
  21. package/dist/types/cache/shell-snapshot.d.ts +1 -1
  22. package/dist/types/cache/tag-invalidation.d.ts +10 -0
  23. package/dist/types/cache/taint.d.ts +5 -3
  24. package/dist/types/cache/types.d.ts +7 -3
  25. package/dist/types/cache/vercel/vercel-cache-store.d.ts +8 -6
  26. package/dist/types/prefetch-markers.d.ts +4 -6
  27. package/dist/types/prerender/store.d.ts +31 -0
  28. package/dist/types/prerender/warm-request.d.ts +3 -3
  29. package/dist/types/prerender.d.ts +2 -2
  30. package/dist/types/route-name.d.ts +5 -0
  31. package/dist/types/router/error-handling.d.ts +4 -4
  32. package/dist/types/router/instrument.d.ts +4 -3
  33. package/dist/types/router/intercept-resolution.d.ts +25 -9
  34. package/dist/types/router/match-context.d.ts +12 -11
  35. package/dist/types/router/match-handlers.d.ts +2 -6
  36. package/dist/types/router/match-middleware/background-revalidation.d.ts +10 -20
  37. package/dist/types/router/match-middleware/cache-lookup.d.ts +35 -87
  38. package/dist/types/router/match-middleware/cache-store.d.ts +2 -2
  39. package/dist/types/router/match-middleware/segment-resolution.d.ts +8 -6
  40. package/dist/types/router/prerender-match.d.ts +21 -6
  41. package/dist/types/router/preview-match.d.ts +2 -7
  42. package/dist/types/router/request-classification.d.ts +5 -0
  43. package/dist/types/router/revalidation.d.ts +6 -1
  44. package/dist/types/router/router-context.d.ts +9 -63
  45. package/dist/types/router/router-interfaces.d.ts +8 -14
  46. package/dist/types/router/segment-resolution/loader-cache.d.ts +3 -3
  47. package/dist/types/router/segment-resolution/loader-mask.d.ts +4 -4
  48. package/dist/types/router/segment-resolution/prefetch-deferral.d.ts +20 -18
  49. package/dist/types/router/segment-resolution/resolution-pass.d.ts +93 -0
  50. package/dist/types/router/segment-resolution/revalidation.d.ts +82 -31
  51. package/dist/types/router/segment-resolution.d.ts +1 -2
  52. package/dist/types/router/segment-wrappers.d.ts +11 -48
  53. package/dist/types/router/telemetry.d.ts +2 -0
  54. package/dist/types/router/types.d.ts +10 -0
  55. package/dist/types/rsc/full-payload.d.ts +2 -2
  56. package/dist/types/rsc/handler-context.d.ts +6 -6
  57. package/dist/types/rsc/json-route-result.d.ts +5 -9
  58. package/dist/types/rsc/request-stages.d.ts +203 -0
  59. package/dist/types/rsc/response-cache-serve.d.ts +7 -12
  60. package/dist/types/rsc/response-route-handler.d.ts +2 -2
  61. package/dist/types/rsc/routine-plan.d.ts +1 -1
  62. package/dist/types/rsc/server-action.d.ts +2 -2
  63. package/dist/types/rsc/shell-capture-constants.d.ts +2 -2
  64. package/dist/types/rsc/shell-capture.d.ts +132 -15
  65. package/dist/types/rsc/shell-serve.d.ts +37 -12
  66. package/dist/types/server/context.d.ts +9 -8
  67. package/dist/types/server/handle-store.d.ts +16 -0
  68. package/dist/types/server/render-pass.d.ts +72 -0
  69. package/dist/types/server/request-context.d.ts +24 -104
  70. package/dist/types/server/rewrite-trail.d.ts +2 -2
  71. package/dist/types/testing/dispatch.d.ts +35 -18
  72. package/dist/types/testing/serve-shell-request.d.ts +7 -0
  73. package/dist/types/types/cache-types.d.ts +6 -3
  74. package/dist/types/types/error-types.d.ts +9 -1
  75. package/dist/types/types/handler-context.d.ts +18 -7
  76. package/dist/types/types/segments.d.ts +1 -1
  77. package/dist/types/vite/discovery/build-discovery-phase.d.ts +40 -0
  78. package/dist/types/vite/discovery/build-env.d.ts +22 -0
  79. package/dist/types/vite/discovery/bundle-scan-phase.d.ts +12 -0
  80. package/dist/types/vite/discovery/dev-prerender-cache.d.ts +3 -2
  81. package/dist/types/vite/discovery/dev-server-phase.d.ts +26 -0
  82. package/dist/types/vite/discovery/discovery-errors.d.ts +1 -1
  83. package/dist/types/vite/discovery/state.d.ts +12 -0
  84. package/dist/types/vite/plugins/version-plugin.d.ts +1 -1
  85. package/dist/types/vite/plugins/virtual-entries.d.ts +1 -1
  86. package/dist/types/vite/router-discovery.d.ts +8 -47
  87. package/dist/types/vite/temp-rsc-server.d.ts +39 -0
  88. package/dist/types/vite/utils/prerender-utils.d.ts +9 -0
  89. package/dist/types/wire-params.d.ts +34 -0
  90. package/dist/vite/index.js +3809 -3710
  91. package/package.json +1 -1
  92. package/skills/cache-guide/SKILL.md +8 -5
  93. package/skills/caching/SKILL.md +37 -18
  94. package/skills/client-urls/SKILL.md +2 -1
  95. package/skills/document-cache/SKILL.md +18 -1
  96. package/skills/handler-use/SKILL.md +1 -1
  97. package/skills/intercept/SKILL.md +53 -13
  98. package/skills/layout/SKILL.md +11 -7
  99. package/skills/loader/SKILL.md +30 -13
  100. package/skills/middleware/SKILL.md +19 -1
  101. package/skills/migrate-nextjs/SKILL.md +5 -4
  102. package/skills/parallel/SKILL.md +5 -4
  103. package/skills/ppr/SKILL.md +19 -3
  104. package/skills/prerender/SKILL.md +39 -15
  105. package/skills/rango/SKILL.md +23 -11
  106. package/skills/server-actions/SKILL.md +51 -6
  107. package/skills/testing/predicates.md +1 -1
  108. package/skills/testing/response-routes.md +6 -4
  109. package/skills/testing/serve-shell-request.md +7 -7
  110. package/skills/use-cache/SKILL.md +46 -8
  111. package/skills/ux-architecture/SKILL.md +3 -2
  112. package/src/__internal.ts +7 -1
  113. package/src/browser/action-coordinator.ts +2 -13
  114. package/src/browser/action-fence.ts +11 -3
  115. package/src/browser/connection-warmup.ts +3 -1
  116. package/src/browser/event-controller.ts +42 -3
  117. package/src/browser/history-state.ts +15 -13
  118. package/src/browser/intercept-utils.ts +51 -0
  119. package/src/browser/navigation-bridge.ts +34 -30
  120. package/src/browser/navigation-client.ts +21 -33
  121. package/src/browser/navigation-store.ts +25 -27
  122. package/src/browser/navigation-transaction.ts +7 -11
  123. package/src/browser/partial-update.ts +8 -0
  124. package/src/browser/prefetch/cache.ts +2 -1
  125. package/src/browser/prefetch/fetch.ts +8 -16
  126. package/src/browser/prefetch/queue.ts +4 -4
  127. package/src/browser/react/NavigationProvider.tsx +2 -1
  128. package/src/browser/react/filter-segment-order.ts +2 -2
  129. package/src/browser/rsc-router.tsx +17 -2
  130. package/src/browser/segment-reconciler.ts +66 -53
  131. package/src/browser/server-action-bridge.ts +265 -127
  132. package/src/browser/types.ts +2 -1
  133. package/src/browser/wire-protocol.ts +41 -0
  134. package/src/cache/cache-key-utils.ts +11 -5
  135. package/src/cache/cache-runtime.ts +110 -50
  136. package/src/cache/cache-scope.ts +110 -64
  137. package/src/cache/cf/cf-cache-constants.ts +2 -2
  138. package/src/cache/cf/cf-cache-store.ts +486 -874
  139. package/src/cache/cf/cf-kv-utils.ts +1 -1
  140. package/src/cache/document-cache.ts +42 -15
  141. package/src/cache/handle-snapshot.ts +19 -7
  142. package/src/cache/segment-codec.ts +55 -0
  143. package/src/cache/shell-snapshot.ts +2 -2
  144. package/src/cache/tag-invalidation.ts +21 -2
  145. package/src/cache/taint.ts +5 -3
  146. package/src/cache/types.ts +7 -3
  147. package/src/cache/vercel/vercel-cache-store.ts +243 -310
  148. package/src/handles/pushed-by.ts +1 -1
  149. package/src/prefetch-markers.ts +4 -7
  150. package/src/prerender/store.ts +76 -0
  151. package/src/prerender/warm-request.ts +8 -4
  152. package/src/prerender.ts +2 -2
  153. package/src/route-name.ts +8 -0
  154. package/src/router/error-handling.ts +4 -4
  155. package/src/router/instrument.ts +4 -3
  156. package/src/router/intercept-resolution.ts +77 -75
  157. package/src/router/loader-resolution.ts +5 -4
  158. package/src/router/match-api.ts +4 -5
  159. package/src/router/match-context.ts +33 -12
  160. package/src/router/match-handlers.ts +8 -20
  161. package/src/router/match-middleware/background-revalidation.ts +41 -53
  162. package/src/router/match-middleware/cache-lookup.ts +680 -720
  163. package/src/router/match-middleware/cache-store.ts +14 -12
  164. package/src/router/match-middleware/intercept-resolution.ts +3 -23
  165. package/src/router/match-middleware/segment-resolution.ts +34 -61
  166. package/src/router/match-result.ts +1 -20
  167. package/src/router/middleware.ts +69 -11
  168. package/src/router/navigation-snapshot.ts +4 -3
  169. package/src/router/prerender-match.ts +100 -44
  170. package/src/router/preview-match.ts +6 -41
  171. package/src/router/request-classification.ts +13 -7
  172. package/src/router/revalidation.ts +33 -7
  173. package/src/router/route-snapshot.ts +2 -5
  174. package/src/router/router-context.ts +14 -117
  175. package/src/router/router-interfaces.ts +8 -14
  176. package/src/router/segment-resolution/loader-cache.ts +14 -9
  177. package/src/router/segment-resolution/loader-mask.ts +5 -5
  178. package/src/router/segment-resolution/prefetch-deferral.ts +30 -27
  179. package/src/router/segment-resolution/resolution-pass.ts +137 -0
  180. package/src/router/segment-resolution/revalidation.ts +897 -776
  181. package/src/router/segment-resolution.ts +4 -13
  182. package/src/router/segment-wrappers.ts +51 -269
  183. package/src/router/telemetry.ts +5 -0
  184. package/src/router/types.ts +10 -0
  185. package/src/router.ts +12 -13
  186. package/src/rsc/full-payload.ts +6 -5
  187. package/src/rsc/handler-context.ts +8 -14
  188. package/src/rsc/handler.ts +126 -507
  189. package/src/rsc/json-route-result.ts +5 -9
  190. package/src/rsc/loader-fetch.ts +6 -5
  191. package/src/rsc/progressive-enhancement.ts +5 -0
  192. package/src/rsc/request-stages.ts +757 -0
  193. package/src/rsc/response-cache-serve.ts +10 -14
  194. package/src/rsc/response-route-handler.ts +13 -5
  195. package/src/rsc/rewrite-passes.ts +2 -1
  196. package/src/rsc/routine-plan.ts +1 -1
  197. package/src/rsc/rsc-rendering.ts +172 -349
  198. package/src/rsc/server-action.ts +87 -113
  199. package/src/rsc/shell-capture-constants.ts +3 -1
  200. package/src/rsc/shell-capture.ts +212 -169
  201. package/src/rsc/shell-serve.ts +121 -18
  202. package/src/rsc/ssr-setup.ts +5 -4
  203. package/src/segment-system.tsx +3 -3
  204. package/src/server/context.ts +22 -25
  205. package/src/server/handle-store.ts +55 -0
  206. package/src/server/render-pass.ts +291 -0
  207. package/src/server/request-context.ts +26 -115
  208. package/src/server/rewrite-trail.ts +6 -4
  209. package/src/ssr/index.tsx +1 -1
  210. package/src/ssr/ssr-root.tsx +1 -0
  211. package/src/testing/dispatch.ts +223 -710
  212. package/src/testing/e2e/page-helpers.ts +2 -2
  213. package/src/testing/serve-shell-request.ts +37 -32
  214. package/src/types/cache-types.ts +6 -3
  215. package/src/types/error-types.ts +9 -1
  216. package/src/types/handler-context.ts +21 -7
  217. package/src/types/segments.ts +1 -1
  218. package/src/vite/discovery/build-discovery-phase.ts +204 -0
  219. package/src/vite/discovery/build-env.ts +148 -0
  220. package/src/vite/discovery/bundle-scan-phase.ts +128 -0
  221. package/src/vite/discovery/dev-prerender-cache.ts +8 -3
  222. package/src/vite/discovery/dev-server-phase.ts +1776 -0
  223. package/src/vite/discovery/discover-routers.ts +1 -1
  224. package/src/vite/discovery/discovery-errors.ts +1 -1
  225. package/src/vite/discovery/prerender-collection.ts +24 -39
  226. package/src/vite/discovery/state.ts +15 -0
  227. package/src/vite/plugins/version-plugin.ts +1 -1
  228. package/src/vite/plugins/virtual-entries.ts +1 -1
  229. package/src/vite/router-discovery.ts +29 -2428
  230. package/src/vite/temp-rsc-server.ts +223 -0
  231. package/src/vite/utils/prerender-utils.ts +47 -0
  232. package/src/wire-params.ts +35 -0
  233. package/dist/types/router/segment-resolution/fresh.d.ts +0 -72
  234. package/src/router/segment-resolution/fresh.ts +0 -945
@@ -31,7 +31,7 @@ export declare function decodeHandleValue<T>(encoded: string): Promise<T | null>
31
31
  *
32
32
  * DSL-loader pushes stay out of the CACHE WRITE: a HIT runs loaders exactly
33
33
  * as an uncached render of the same request would (cache-lookup.ts
34
- * resolveFreshLoadersAndYield), so replaying a recorded copy would duplicate
34
+ * serveStoredSegments), so replaying a recorded copy would duplicate
35
35
  * the live push. Handler pushes, including
36
36
  * handler-invoked ctx.use(Loader) bodies (skipped with their handler on a
37
37
  * HIT), are kept. The store tags loader pushes by array position at push
@@ -75,19 +75,24 @@ export type OwnedPushDelivery = (loaderId: string) => RecordAuthority;
75
75
  * owner. Neither claims its loader, so the loader's own cache() HIT still
76
76
  * delivers (the pushes holding a promise a restored copy lets through, or its
77
77
  * entry's pushes in a placeholder's place).
78
+ *
79
+ * `sent` (a partial request) names the segments the response sends. Any
80
+ * other segment is kept with its handler's values, as on a live walk: only
81
+ * its loaders' copies are restored, which follow their loader as above.
78
82
  */
79
- export declare function restoreHandles(handles: Record<string, SegmentHandleData>, handleStore: HandleStore, owners?: HandleOwners, owned?: OwnedPushDelivery): void;
83
+ export declare function restoreHandles(handles: Record<string, SegmentHandleData>, handleStore: HandleStore, owners?: HandleOwners, owned?: OwnedPushDelivery, sent?: ReadonlySet<string>): void;
80
84
  /**
81
85
  * Serve a doc record's handles: set its authority over the loaders' pushes
82
86
  * (with or without a handles blob: a pinned loader whose capture pushed
83
87
  * nothing has no copy, and its run must still add no settled push), then
84
88
  * decode and restoreHandles. `keepIds` limits the restore to the segments a
85
- * boundary-scoped scope serves. A decode failure skips the restore.
89
+ * boundary-scoped scope serves; `sent` is restoreHandles'. A decode failure
90
+ * skips the restore.
86
91
  */
87
92
  export declare function restoreRecordHandles(handleStore: HandleStore, record: {
88
93
  handles?: string;
89
94
  handleOwners?: HandleOwners;
90
- }, owned: OwnedPushDelivery | undefined, keepIds?: ReadonlySet<string>): Promise<void>;
95
+ }, owned: OwnedPushDelivery | undefined, keepIds?: ReadonlySet<string>, sent?: ReadonlySet<string>): Promise<void>;
91
96
  /**
92
97
  * Append recorded handle pushes to the store, in recorded order, via push()
93
98
  * so active captures and loader-scope tagging see them like live pushes. For
@@ -37,6 +37,20 @@ export declare function rscDeserialize<T>(encoded: string | undefined): Promise<
37
37
  * Returns null only on serialization failure.
38
38
  */
39
39
  export declare function serializeResult(value: unknown, onError?: (error: unknown) => void): Promise<string | null>;
40
+ /** The Flight encode of a value and a decoded copy of it (teeResult). */
41
+ export interface TeedResult {
42
+ /** The copy: settles when the root row arrives; later rows stream in. */
43
+ decoded: Promise<unknown>;
44
+ /** The whole encoded text, or null when the stream failed. */
45
+ serialized: Promise<string | null>;
46
+ }
47
+ /**
48
+ * Encode `value` once and decode a copy of it as the encode streams, so a
49
+ * "use cache" miss renders the copy as a hit renders a stored entry, and
50
+ * stores the same bytes. Null when the encode could not start.
51
+ */
52
+ export declare function teeResult(value: unknown, onError?: (error: unknown) => void): TeedResult | null;
53
+ export declare function isUnsupportedValueError(error: unknown): boolean;
40
54
  /**
41
55
  * RSC-deserialize a cached result string.
42
56
  * Counterpart to serializeResult() — always receives a non-empty string.
@@ -210,7 +210,7 @@ export declare function buildShellLoaderSeed(snapshot: ShellSnapshotRecord[], on
210
210
  export declare const SHELL_HANDLES_RECORD_KEY = "handles";
211
211
  /**
212
212
  * The `handles` record of a prerender-served entry, which a HIT tail restores
213
- * after the prerender store's handles (cache-lookup.ts yieldFromStore), or
213
+ * after the prerender store's handles (cache-lookup.ts decodeStoredEntry), or
214
214
  * undefined: an entry with a doc record, or one written before the record
215
215
  * existed (v0.21), which serves as it did.
216
216
  */
@@ -35,9 +35,19 @@
35
35
  * request, is neither joined nor written (#973, #977): see
36
36
  * predatesInvalidation, and docs/design/caching.md "Read-your-own-writes".
37
37
  */
38
+ import { type RequestContext } from "../server/request-context.js";
38
39
  import type { SegmentCacheStore } from "./types.js";
39
40
  import { type ExecutionStart } from "./invalidation-order.js";
40
41
  export { executionStart, invalidatedSince, markResponseStart, type ExecutionStart, } from "./invalidation-order.js";
42
+ /**
43
+ * Run a stale entry's background refresh on the visitor's request context: a
44
+ * "use cache" function's (cache-runtime.ts) or a cached loader's
45
+ * (loader-cache.ts). No visitor made the invalidations in it, so they set no
46
+ * fresh-reads cookie, as in a stale cache() HIT's re-render or a document
47
+ * cache entry's re-run, whose passes take a sink's no-op writer
48
+ * (server/render-pass.ts).
49
+ */
50
+ export declare function runAsBackgroundRefresh<T>(ctx: RequestContext, fn: () => T): T;
41
51
  /**
42
52
  * The write gate of every cache execution (#977): whether one of `tags` was
43
53
  * invalidated after the execution that produced the value started.
@@ -11,9 +11,11 @@ export declare const NOCACHE_SYMBOL: unique symbol;
11
11
  */
12
12
  export declare function isTainted(value: unknown): boolean;
13
13
  /**
14
- * Symbol stamped on tainted ctx objects PASSED AS ARGUMENTS to a "use cache"
15
- * function during its execution. ctx.set(), ctx.header(), etc. check this
16
- * flag and throw if present — those side effects are lost on cache hit.
14
+ * Symbol stamped on tainted handler and middleware ctx objects PASSED AS
15
+ * ARGUMENTS to a "use cache" function during its execution. ctx.set(),
16
+ * ctx.header(), etc. check this flag and throw if present — those side
17
+ * effects are lost on cache hit. A request context passed as an argument is
18
+ * not stamped (registerCachedFunction in cache-runtime.ts).
17
19
  *
18
20
  * Argument objects only. Ambient access (cookies()/headers() and ctx methods
19
21
  * reached via getRequestContext()) is guarded by the AsyncLocalStorage scope
@@ -86,10 +86,14 @@ export interface SegmentCacheStore<TEnv = unknown> {
86
86
  * Return value becomes the final cache key (unless route overrides with `key` option).
87
87
  *
88
88
  * Resolution priority:
89
- * 1. Route-level `key` function (full override)
89
+ * 1. Route-level `key` function (replaces the URL part; the request kind stays)
90
90
  * 2. Store-level `keyGenerator` (modifies default key)
91
91
  * 3. Default key generation (prefix:pathname:params)
92
92
  *
93
+ * Keep `defaultKey` in the result: its prefix names the request kind (a
94
+ * document, a navigation or an intercept navigation), whose records hold
95
+ * different segments. A result without it gives every kind one record.
96
+ *
93
97
  * Return `defaultKey` unchanged to leave a request unpartitioned. An empty
94
98
  * string is not a key: where the result partitions a nested cache() on
95
99
  * another store, or a ppr shell, it fails key resolution, so the request
@@ -250,7 +254,7 @@ export interface SegmentCacheStore<TEnv = unknown> {
250
254
  /**
251
255
  * Declares the shell family present-but-inert: getShell/putShell exist but
252
256
  * no-op (a custom store whose backing tier is conditionally unavailable).
253
- * scheduleShellCapture skips captures whose only write target is inert —
257
+ * planShellCapture skips captures whose only write target is inert —
254
258
  * the background render would be dead work that still occupies the
255
259
  * per-isolate serialized capture queue (a promise-heavy route bakes for
256
260
  * seconds per MISS with nothing stored). Absent/false means the family,
@@ -602,7 +606,7 @@ export type ShellSnapshotFamily = "segment" | "loader" | "handles";
602
606
  * format (CachedEntryData `handles` + `handleOwners`). A Prerender + ppr
603
607
  * route's handler layer comes from the prerender store, whose build-time
604
608
  * entry has no loader push, so the entry keeps these for the HIT to restore
605
- * as a doc record's (issue #1057, yieldFromStore in cache-lookup.ts). An
609
+ * as a doc record's (issue #1057, decodeStoredEntry in cache-lookup.ts). An
606
610
  * entry written before it (v0.21) has none and serves as it did.
607
611
  */
608
612
  export type ShellSnapshotHandlesValue = Pick<CachedEntryData, "handles" | "handleOwners">;
@@ -326,8 +326,14 @@ export declare class VercelCacheStore<TEnv = unknown> implements SegmentCacheSto
326
326
  * `taggedAt`. An entry without a stamp counts as older than any mask.
327
327
  */
328
328
  private maskedForRequest;
329
- /** A data read's mask check: reports the miss and returns true when masked. */
330
- private maskedMiss;
329
+ /**
330
+ * The read of a data family (get, getItem, getResponse): a failed read is
331
+ * the family's `readError`; a missing, corrupt, expired or masked entry is a
332
+ * miss, and a corrupt or expired one is evicted. The hit is built before the
333
+ * stale claim, so an entry that does not rebuild is evicted as corrupt with
334
+ * no revalidation lock written for it.
335
+ */
336
+ private readRecord;
331
337
  private toStoreKey;
332
338
  private write;
333
339
  /**
@@ -370,8 +376,4 @@ export declare class VercelCacheStore<TEnv = unknown> implements SegmentCacheSto
370
376
  private clampTagsForWrite;
371
377
  private safeDelete;
372
378
  private emitDebug;
373
- private asSegmentEnvelope;
374
- private asItemEnvelope;
375
- private asShellEnvelope;
376
- private asResponseEnvelope;
377
379
  }
@@ -1,14 +1,12 @@
1
1
  /**
2
- * The wire markers of prefetches and of `prefetch: false`
3
- * (docs/design/prefetch-false.md): shared by the browser and the server
2
+ * The wire markers of prefetches: shared by the browser and the server
4
3
  * (router/segment-resolution/prefetch-deferral.ts requestKind,
5
- * rsc/prefetch-render-error.ts). Dependency free, like segment-fragments.ts:
6
- * the browser must not import the server modules that use them.
4
+ * rsc/prefetch-render-error.ts, rsc/rsc-rendering.ts). Dependency free, like
5
+ * segment-fragments.ts: the browser must not import the server modules that
6
+ * use them.
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
- /** Query param of a fill request (browser/navigation-client.ts). */
11
- export declare const FILL_PARAM = "_rsc_fill";
12
10
  /**
13
11
  * The last row of a prefetch whose render reported an error
14
12
  * (rsc/prefetch-render-error.ts): a Flight hint with a code React does not
@@ -54,6 +54,37 @@ export declare function createDevPrerenderStore(devUrl: string): PrerenderStore;
54
54
  * Returns null if no prerender data is available.
55
55
  */
56
56
  export declare function createPrerenderStore(): PrerenderStore | null;
57
+ /**
58
+ * The segments of a prerendered URL's intercept variant (`/i`): the main
59
+ * variant's without the intercepted route's own (`belongsToRoute`: its
60
+ * handler, layouts and slots), then the intercept's. A render under an
61
+ * intercept skips the route's entry (resolveAllSegments), so the variant
62
+ * holds what a cache() intercept record holds. The producer
63
+ * (matchForPrerender) encodes `interceptHandles` for exactly these segments.
64
+ */
65
+ export declare function interceptVariantSegments(segments: SerializedSegmentData[], interceptSegments: SerializedSegmentData[]): SerializedSegmentData[];
66
+ /**
67
+ * The intercept variant as served under the intercept the match selected
68
+ * (findInterceptForRoute): its main segments and that intercept's slot,
69
+ * `slotId` in `intercept:<routeName>`. The build bakes every intercept that
70
+ * can target the route, since it cannot evaluate when(). Null when the
71
+ * variant does not hold that slot: the request renders live. The handles
72
+ * string is kept whole; decodeStoredEntry (cache-lookup.ts) replays only the
73
+ * served segments' pushes.
74
+ */
75
+ export declare function selectInterceptVariant(entry: PrerenderEntry, slotId: string, routeName: string): PrerenderEntry | null;
76
+ /**
77
+ * The manifest entries ([key, PrerenderEntry JSON]) one prerendered URL
78
+ * bakes, keyed as the production store's get() reads them. The intercept
79
+ * variant (`/i`) holds interceptVariantSegments with the handle string the
80
+ * producer encoded for it. Written by the build
81
+ * (vite/discovery/prerender-collection.ts) and serveShellRequest.
82
+ */
83
+ export declare function prerenderManifestEntries(result: PrerenderEntry & {
84
+ routeName: string;
85
+ interceptSegments?: SerializedSegmentData[];
86
+ interceptHandles?: string;
87
+ }, paramHash: string): Array<[key: string, value: string]>;
57
88
  /**
58
89
  * Create a static segment store.
59
90
  * Production only: backed by globalThis.__STATIC_MANIFEST injected at build time.
@@ -7,7 +7,7 @@
7
7
  * layers import this without pulling the trigger.
8
8
  */
9
9
  import type { HandlerCacheConfig } from "../rsc/types.js";
10
- import type { ShellCaptureDebugEvent } from "../rsc/shell-capture.js";
10
+ import type { ShellCaptureDebugEvent, ShellCaptureState } from "../rsc/shell-capture.js";
11
11
  import type { PrerenderWarmCaches } from "./on-demand.js";
12
12
  /** What one warm request did: written by the layers, read by the trigger. */
13
13
  export interface PrerenderWarmRecord extends PrerenderWarmCaches {
@@ -33,7 +33,7 @@ export interface PrerenderWarmRecord extends PrerenderWarmCaches {
33
33
  /** What the helpers read; a derived capture context inherits the record. */
34
34
  export interface WarmContext {
35
35
  _prerenderWarm?: PrerenderWarmRecord;
36
- _shellCaptureRun?: boolean;
36
+ _shellCaptureState?: Pick<ShellCaptureState, "run">;
37
37
  }
38
38
  export declare function createWarmRecord(mode: PrerenderWarmRecord["mode"], cacheConfig: HandlerCacheConfig): PrerenderWarmRecord;
39
39
  /** The mark is the object: a clone or a rebuilt request carries none. */
@@ -46,7 +46,7 @@ export declare function readWarmMark(request: Request): PrerenderWarmRecord | un
46
46
  * "use cache" in-flight dedup lives outside the store, so a wrapper would
47
47
  * miss both.
48
48
  *
49
- * False in the warm's own shell capture (`_shellCaptureRun`): it runs after
49
+ * False in the warm's own shell capture (`_shellCaptureState`): it runs after
50
50
  * the warm's writes settled and must replay them, or it would render every
51
51
  * handler a second time and could bake another generation than the one just
52
52
  * written.
@@ -264,8 +264,8 @@ export declare function isPrerenderPassthrough(value: unknown): value is Prerend
264
264
  * A build handler signals passthrough by returning `ctx.passthrough()` (the
265
265
  * PRERENDER_PASSTHROUGH sentinel), which lands on the segment's `component`.
266
266
  * But when the route declares `loading()`, the handler result is deferred
267
- * upstream (segment-resolution/fresh.ts), so `component` is a thenable resolving
268
- * to the sentinel rather than the sentinel itself — a synchronous
267
+ * upstream (resolveEntryHandler), so `component` is a thenable
268
+ * resolving to the sentinel rather than the sentinel itself — a synchronous
269
269
  * `isPrerenderPassthrough(component)` on the Promise returns false and the build
270
270
  * bakes a corrupt artifact instead of deferring. Resolve thenables first.
271
271
  *
@@ -32,3 +32,8 @@ export declare function publicRouteName(routeKey: string | undefined): string |
32
32
  * Throws with a clear message when a reserved prefix is detected.
33
33
  */
34
34
  export declare function validateUserRouteName(name: string): void;
35
+ /**
36
+ * The route key's last name segment ("item" for "shop.item"). An intercept
37
+ * that targets it is selected when none targets the full key (match-api.ts).
38
+ */
39
+ export declare function localRouteName(routeKey: string): string;
@@ -45,10 +45,10 @@ export declare function invokeOnError<TEnv = any>(onError: OnErrorCallback<TEnv>
45
45
  /**
46
46
  * First non-undefined `pick(orphan)` over the routeless entries in
47
47
  * `entry.layout` and, recursively, in theirs: depth-first in render order
48
- * (resolveOrphanLayout in segment-resolution/fresh.ts). Since #922 a routeless
49
- * entry nested in another renders (a layout() after a bare cache() marker, a
50
- * layout() in a routeless wrapper); a one-level scan missed the boundaries and
51
- * intercepts it declares (#926).
48
+ * (resolveOrphanLayout in segment-resolution/revalidation.ts).
49
+ * Since #922 a routeless entry nested in another renders (a layout() after a
50
+ * bare cache() marker, a layout() in a routeless wrapper); a one-level scan
51
+ * missed the boundaries and intercepts it declares (#926).
52
52
  *
53
53
  * `skip` is the entry an upward walk came from. Only a bare cache() marker is
54
54
  * both in its layout's layout[] and in the chain, and its subtree was already
@@ -190,9 +190,10 @@ export declare function observeSegmentHandler<C, R>(segmentId: string, spanId: s
190
190
  * loop (request.start/end/error, cache.decision, ...).
191
191
  * - segment-resolution/helpers.ts emits via a caller-provided report.telemetry
192
192
  * sink rather than the ALS router context.
193
- * - rsc/handler.ts handleTimeoutResponse (request.timeout), the origin guard
194
- * (request.origin-rejected), and handleStore.onError (late-handle
195
- * handler.error) emit via router.telemetry directly — they run outside the
193
+ * - rsc/request-stages.ts timeoutResponse (request.timeout) and
194
+ * originRejectedResponse (request.origin-rejected), and rsc/handler.ts
195
+ * handleStore.onError (late-handle handler.error) emit via
196
+ * router.telemetry directly — they run outside the
196
197
  * RouterContext ALS (only match()/matchPartial() enter it), so a
197
198
  * getRouterContext() read there throws and the event would vanish.
198
199
  */
@@ -5,9 +5,8 @@
5
5
  * functions for soft navigation (modals).
6
6
  */
7
7
  import type { EntryData, InterceptEntry, InterceptSelectorContext } from "../server/context";
8
- import type { HandlerContext, ResolvedSegment } from "../types";
9
- import type { SegmentResolutionDeps } from "./types.js";
10
- import type { RevalidationContext } from "./router-context.js";
8
+ import type { ResolvedSegment } from "../types";
9
+ import type { ResolutionPass } from "./segment-resolution/resolution-pass.js";
11
10
  /**
12
11
  * Check if an intercept's when conditions are satisfied.
13
12
  * All when() functions must return true for the intercept to activate.
@@ -40,6 +39,19 @@ export declare function findInterceptForRoute(targetRouteKey: string, fromEntry:
40
39
  } | null;
41
40
  /** The segment id of `intercept`'s slot on `parentEntry`. */
42
41
  export declare function interceptSlotId(parentEntry: EntryData, intercept: InterceptEntry): string;
42
+ /**
43
+ * The intercept a match selected (findInterceptForRoute), as its cache()
44
+ * record names it (CacheScope): the slot id, then `~` and its position among
45
+ * the intercepts its entry declares for the same slot and target route. Two
46
+ * such intercepts share the slot id, and the position tells them apart; one
47
+ * for another slot or route does not renumber it. `~` is unreserved in a
48
+ * URL, so a store that maps the key onto one unencoded keeps the whole key.
49
+ * Undefined when the match selected none.
50
+ */
51
+ export declare function interceptRecordKey(selected: {
52
+ intercept: InterceptEntry;
53
+ entry: EntryData;
54
+ } | null): string | undefined;
43
55
  /**
44
56
  * Every segment id an intercept's slot owns, in order: the slot, then one
45
57
  * loader segment per loader in declaration order, run or not. A request that
@@ -47,15 +59,19 @@ export declare function interceptSlotId(parentEntry: EntryData, intercept: Inter
47
59
  */
48
60
  export declare function interceptSegmentIds(parentEntry: EntryData, intercept: InterceptEntry): string[];
49
61
  /**
50
- * Resolve an intercept entry: its slot segment, then its loader segments.
62
+ * Resolve an intercept entry: its slot segment, then its loader segments. The
63
+ * background re-render resolves with a pass that holds nothing
64
+ * (heldNothingPassInput, resolution-pass.ts): every segment renders fresh, and
65
+ * its loaders are skipped (skipLoaders), each registered for the handler's
66
+ * read.
51
67
  */
52
- export declare function resolveInterceptEntry<TEnv>(interceptEntry: InterceptEntry, parentEntry: EntryData, params: Record<string, string>, context: HandlerContext<any, TEnv>, belongsToRoute: boolean, deps: SegmentResolutionDeps<TEnv>, revalidationContext?: RevalidationContext, options?: {
68
+ export declare function resolveInterceptEntry<TEnv>(pass: ResolutionPass<TEnv>, interceptEntry: InterceptEntry, parentEntry: EntryData, belongsToRoute: boolean, options?: {
53
69
  /**
54
70
  * Set ONLY by the post-response background re-render (stale background
55
71
  * revalidation), whose sole purpose is to re-render the segment tree to
56
- * populate the cache: a handler error rejects instead of rendering the
57
- * error boundary, so a failure is never cached. Never set on the
58
- * foreground path.
72
+ * populate the cache: a handler error is reported, then rejects instead
73
+ * of rendering the error boundary, so a failure is never cached. Never
74
+ * set on the foreground path.
59
75
  */
60
76
  background?: boolean;
61
77
  }): Promise<ResolvedSegment[]>;
@@ -63,4 +79,4 @@ export declare function resolveInterceptEntry<TEnv>(interceptEntry: InterceptEnt
63
79
  * The loader segments of a cached intercept slot, on a cache hit: the slot
64
80
  * keeps its cached component and layout, its loaders are never cached.
65
81
  */
66
- export declare function resolveInterceptLoadersOnly<TEnv>(interceptEntry: InterceptEntry, parentEntry: EntryData, context: HandlerContext<any, TEnv>, belongsToRoute: boolean, deps: SegmentResolutionDeps<TEnv>, revalidationContext: RevalidationContext): Promise<ResolvedSegment[]>;
82
+ export declare function resolveInterceptLoadersOnly<TEnv>(pass: ResolutionPass<TEnv>, interceptEntry: InterceptEntry, parentEntry: EntryData, belongsToRoute: boolean): Promise<ResolvedSegment[]>;
@@ -63,7 +63,6 @@
63
63
  *
64
64
  * Handler Context:
65
65
  * - handlerContext: Context passed to loaders
66
- * - loaderPromises: Memoized loader promises
67
66
  *
68
67
  * Intercepts:
69
68
  * - interceptResult: Detected intercept (if soft navigation)
@@ -114,15 +113,8 @@ import type { EntryData, InterceptSelectorContext, MetricsStore } from "../serve
114
113
  import type { HandlerContext, ResolvedSegment } from "../types.js";
115
114
  import type { RouteMatchResult } from "./pattern-matching.js";
116
115
  import type { InterceptResult } from "./router-context.js";
117
- /**
118
- * Action context passed to matchPartial
119
- */
120
- export interface ActionContext {
121
- actionId?: string;
122
- actionUrl?: URL;
123
- actionResult?: any;
124
- formData?: FormData;
125
- }
116
+ import type { ResolutionPassInput } from "./segment-resolution/resolution-pass.js";
117
+ import type { ActionContext } from "./types.js";
126
118
  /**
127
119
  * Match context containing all state for the match pipeline
128
120
  */
@@ -143,7 +135,6 @@ export interface MatchContext<TEnv = any> {
143
135
  routeKey: string;
144
136
  localRouteName: string;
145
137
  handlerContext: HandlerContext<any, TEnv>;
146
- loaderPromises: Map<string, Promise<any>>;
147
138
  routeMap: Record<string, string>;
148
139
  metricsStore: MetricsStore | undefined;
149
140
  Store: any;
@@ -166,6 +157,16 @@ export interface MatchContext<TEnv = any> {
166
157
  }>;
167
158
  isFullMatch: boolean;
168
159
  }
160
+ /**
161
+ * An action, or a stale partial (`_rsc_stale`: Back/Forward onto an entry
162
+ * marked stale, `refresh()`, the cross-tab refresh, the action follow-up, a
163
+ * zero-segment refetch), renders live: no route-cache or prerender-store read
164
+ * a live handler can replace, and no store. An action's render is never
165
+ * stored, so a record can be older than the copy the client holds after it.
166
+ */
167
+ export declare function rendersLive(ctx: Pick<MatchContext, "isAction" | "stale">): boolean;
168
+ /** This match as the input of a revalidating resolution pass (resolution-pass.ts). */
169
+ export declare function resolutionPassInput<TEnv>(ctx: MatchContext<TEnv>): ResolutionPassInput<TEnv>;
169
170
  /**
170
171
  * Mutable state that flows through the pipeline
171
172
  */
@@ -1,9 +1,8 @@
1
1
  import type { ReactNode } from "react";
2
2
  import type { ErrorBoundaryHandler, ErrorInfo, ErrorPhase, MatchResult } from "../types";
3
3
  import { type EntryData, type InterceptEntry, type InterceptSelectorContext } from "../server/context.js";
4
- import type { MatchApiDeps } from "./types.js";
4
+ import type { ActionContext, MatchApiDeps } from "./types.js";
5
5
  import type { RouterContext } from "./router-context.js";
6
- import { type ActionContext } from "./match-context.js";
7
6
  import type { MiddlewareFn } from "./middleware.js";
8
7
  import { type TelemetrySink } from "./telemetry.js";
9
8
  export interface MatchHandlerDeps<TEnv = any> {
@@ -33,11 +32,8 @@ export interface MatchHandlers<TEnv = any> {
33
32
  handler: MiddlewareFn;
34
33
  params: Record<string, string>;
35
34
  }>;
36
- responseType?: string;
37
- handler?: Function;
38
35
  params?: Record<string, string>;
39
- negotiated?: boolean;
40
- manifestEntry?: EntryData;
36
+ routeKey?: string;
41
37
  } | null>;
42
38
  }
43
39
  /**
@@ -36,7 +36,7 @@
36
36
  * |
37
37
  * v
38
38
  * +---------------------------+
39
- * | resolveAllSegments() | Fresh resolution (no revalidation)
39
+ * | FRESH segment pass | Fresh resolution (no revalidation)
40
40
  * | + resolveIntercepts() | Ensures complete components
41
41
  * +---------------------------+
42
42
  * |
@@ -94,10 +94,12 @@
94
94
  * FRESH RESOLUTION (NO REVALIDATION)
95
95
  * ===================================
96
96
  *
97
- * Both full and partial requests use resolveAllSegments() (without
97
+ * Both full and partial requests resolve with a FRESH pass (without
98
98
  * revalidation logic) to ensure all segments have complete components.
99
99
  * Using revalidation-aware resolution would produce null components
100
- * for skipped segments, which would corrupt the cache entry.
100
+ * for skipped segments, which would corrupt the cache entry. Under an
101
+ * intercept the walk still skips the intercepted route's entry, as the MISS
102
+ * does: an intercept: record never holds the route's page.
101
103
  */
102
104
  import type { ResolvedSegment } from "../../types.js";
103
105
  import type { MatchContext, MatchPipelineState } from "../match-context.js";
@@ -118,23 +120,11 @@ import { type RequestContext } from "../../server/request-context.js";
118
120
  * MAX_REVALIDATION_INTERVAL, as after a refresh that throws.
119
121
  *
120
122
  * Runs on a DERIVED request context that owns the per-render state the
121
- * foreground reads while it is still producing the page (a stale HIT re-runs
122
- * its loaders; a proactive render starts once the Response exists, while its
123
- * body streams):
124
- * - _handleStore: read late (loader pushes and aux-lane tracking in
125
- * loader-resolution.ts, nested cache restores and captures in
126
- * cache-scope.ts), so a swap sent live pushes into this render.
127
- * setupLoaderAccess binds the store at setup, so it runs inside the
128
- * derived context too.
129
- * - _metricsStore: undefined, and the DSL store below has `metrics` unset
130
- * (track() reads that one), so nothing lands on the foreground's perf
131
- * timeline. ctx.Store.run closes over ctx.Store, so the derived store
132
- * needs its own run.
133
- * - response writes (headers, cookies, status, onResponse callbacks) go to
134
- * a throwaway context (whose status gates the write, above) and are
135
- * dropped: a layout above the cache() boundary is outside the header
136
- * guard and an error boundary sets a status, so they would otherwise
137
- * reach the live response.
123
+ * foreground reads while it is still producing the page:
124
+ * RENDER_PASS_FIELDS["background-revalidation"] (server/render-pass.ts) lists
125
+ * each field and why. The DSL store below has `metrics` unset too (track()
126
+ * reads that one), so nothing lands on the foreground's perf timeline;
127
+ * ctx.Store.run closes over ctx.Store, so the derived store needs its own run.
138
128
  * runWithRequestContext also re-establishes the request ALS, which a waitUntil
139
129
  * task on workerd loses; the DSL store is a different ALS (build context).
140
130
  */