@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
@@ -29,6 +29,7 @@ import type { RenderMode, RenderPhase } from "../router/timeout.js";
29
29
  import type { LocationStateEntry } from "../browser/react/location-state-shared.js";
30
30
  import type { RoutineTrace } from "../rsc/routine-plan.js";
31
31
  import type { ActionContinuation } from "../rsc/server-action.js";
32
+ import type { ShellCaptureState } from "../rsc/shell-capture.js";
32
33
  import type { FormActionOutcome } from "../rsc/progressive-enhancement.js";
33
34
  import { type ExecutionStart } from "../cache/invalidation-order.js";
34
35
  export interface RenderForegroundCursor {
@@ -182,8 +183,8 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
182
183
  method: string;
183
184
  /**
184
185
  * @internal Handle store for tracking handle data across segments.
185
- * Readonly: a background render that needs its own store derives a context
186
- * (rerenderAndCacheRoute, shell-capture.ts) instead of swapping this field,
186
+ * Readonly: a render that needs its own store derives a render pass
187
+ * (deriveRenderPass, server/render-pass.ts) instead of swapping this field,
187
188
  * which the foreground still reads while it produces the page.
188
189
  */
189
190
  readonly _handleStore: HandleStore;
@@ -233,52 +234,13 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
233
234
  */
234
235
  _searchParamsFilter?: import("../cache/search-params-filter.js").SearchParamsFilter;
235
236
  /**
236
- * @internal PPR shell-capture ACTIVE marker. True ONLY inside the background
237
- * capture task's derived request context (built by shell-capture.ts). This is
238
- * the switch every capture-specific behavior reads: loader masking
239
- * (loader-mask.ts isShellCaptureActive / fresh.ts emitStreaming) and the
240
- * identity-read capture guard (server/context.ts guardIdentityRead). The
241
- * foreground render never sets it, so the
242
- * served response is byte-identical to axis 1. The capture descriptor itself
243
- * (key/ttl/swr/tags/store) is NOT threaded through the request context — the
244
- * integrated PPR serve path (rsc/shell-serve.ts + rsc-rendering.ts) builds it
245
- * locally and passes it to scheduleShellCapture directly.
246
- */
247
- _shellCaptureRun?: boolean;
248
- /**
249
- * @internal Set beside `_shellCaptureRun` when the shell is keyed by the
250
- * visitor's URL (`rewrite(...).shell("visitor")`): the capture renders the
251
- * visitor's location and `ctx.rewrittenFrom`; the theme stays the default.
252
- */
253
- _shellCaptureForVisitor?: boolean;
254
- /**
255
- * @internal Bake-lane loader containers collected DURING a shell capture:
256
- * segment-key -> the loader's (pre-wrap) result promise. Populated by
257
- * resolveLoaderData for bake-lane loaders (lane rule: see its JSDoc in
258
- * loader-cache.ts). Drained by captureAndStoreShell after the shell
259
- * quiesces: settled containers are promise-elided, Flight-serialized, and
260
- * pinned into the snapshot's loader family; a REJECTED container refuses
261
- * the capture (error UI must never bake into the shared shell). Own
262
- * property of the capture's derived context only.
263
- */
264
- _shellCaptureLoaderRecords?: Map<string, Promise<unknown>>;
265
- /**
266
- * @internal Set on a capture's derived context when a loader pushed a
267
- * value the record cannot keep (masked nested promises, a pushed promise
268
- * that settled to one, a live-lane loader's push, or a push outside a
269
- * loader body): the loader records then carry `runs: 1`, so a HIT still
270
- * runs their bodies for those pushes.
271
- */
272
- _shellCaptureUnrecordedLoaderPush?: true;
273
- /**
274
- * @internal The lane of each loader the capture's matched route registers
275
- * (loader-cache.ts routeLoaderLanes), set by createMatchContextForFull
276
- * before any loader runs. The capture's push funnel credits a push made
277
- * under a live-lane loader's body, at any depth, to that loader
278
- * (shell-capture.ts deriveShellCaptureContext). Own property of the
279
- * capture's derived context only.
280
- */
281
- _shellCaptureLoaderLanes?: ReadonlyMap<string, "live" | "bake">;
237
+ * @internal A PPR shell capture's own state (rsc/shell-capture.ts
238
+ * ShellCaptureState): created by RENDER_PASS_FIELDS["shell-capture"]
239
+ * (server/render-pass.ts) on the capture's derived context. The foreground
240
+ * render and every background re-render never have one, so
241
+ * `_shellCaptureState?.run` is the capture switch.
242
+ */
243
+ _shellCaptureState?: ShellCaptureState;
282
244
  /**
283
245
  * @internal Record keys resolved for this request (CacheScope
284
246
  * resolveKeyFrom): by the scope's `key()` (one result) or its store's
@@ -295,9 +257,9 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
295
257
  _shellKey?: string;
296
258
  /**
297
259
  * @internal The request carried the forced-MISS reload marker
298
- * (shell-serve.ts SHELL_MISS_PARAM). The handler strips the marker from the
299
- * request on entry and sets this; the shell gate renders the request like a
300
- * cache miss.
260
+ * (`WIRE.shellMiss`). The handler strips the marker from the request on
261
+ * entry (shell-serve.ts withoutShellMissMarker) and sets this; the shell
262
+ * gate renders the request like a cache miss.
301
263
  */
302
264
  _shellForcedMiss?: true;
303
265
  /**
@@ -314,16 +276,6 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
314
276
  * runtime has no AsyncLocalStorage.snapshot.
315
277
  */
316
278
  _runAtRequestEntry?: <T>(fn: () => T) => T;
317
- /**
318
- * @internal The freshness window of the route cache() records this
319
- * request read or wrote (cache-scope.ts noteRouteRecordWindow), as ms
320
- * timestamps: `freshUntil` is the record's `expiresAt`, `staleUntil` adds
321
- * its scope's swr. The narrowest record wins. A shell capture caps its
322
- * entry's ttl and ttl+swr to it (shell-capture.ts capShellWindow), so a
323
- * shell is never fresher, or served longer, than the route cache() entry
324
- * it replayed or wrote.
325
- */
326
- _routeRecordWindow?: RouteRecordWindow;
327
279
  /**
328
280
  * @internal Loader-family snapshot seed for a shell HIT's tail render:
329
281
  * loader id -> the capture's elided container (already Flight-deserialized
@@ -445,30 +397,6 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
445
397
  * it as an own property for exactly that reason.
446
398
  */
447
399
  _shellFragmentPayload?: boolean;
448
- /**
449
- * @internal Set by the capture guard (server/context.ts
450
- * guardIdentityRead) when it throws DURING a capture render: the read
451
- * ("cookies()", "headers()", `ctx.get() for a non-cacheable variable`,
452
- * "ctx.theme") and the fix the
453
- * refusal warning gives for it. Load-bearing for the
454
- * bake lane: a guard throw inside an executing loader is swallowed by
455
- * wrapLoaderPromise into per-loader error UI, which would otherwise bake
456
- * silently into the shared shell — the capture checks this flag after the
457
- * render and refuses instead. Deterministic, so the capture does not retry.
458
- */
459
- _shellCaptureGuardTripped?: {
460
- surface: string;
461
- fix: string;
462
- };
463
- /**
464
- * @internal The loader $$id whose BODY was executing when the capture guard
465
- * tripped (read off the loader-body ALS scope at trip time), or undefined
466
- * when the read came from handler/render code. Only used to make the
467
- * once-per-key refusal warning name the real source — the old text
468
- * hardcoded "a bake-lane loader", which misattributed handler-land reads
469
- * and sent users debugging the wrong lane (issue #672, secondary).
470
- */
471
- _shellCaptureGuardTrippedLoaderId?: string;
472
400
  /**
473
401
  * @internal Handler-owned registry of explicit per-scope stores from
474
402
  * cache({ store }). Created once per createRSCHandler() and threaded into
@@ -732,8 +660,8 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
732
660
  * (loader(Def, { ssr: false })): segment resolution awaits these
733
661
  * before returning, so the render barrier cannot resolve until they settle.
734
662
  * rendered() checks this set to fail fast — a flagged loader awaiting the
735
- * barrier is a guaranteed cycle, not a race. Registered by resolveLoaders
736
- * (fresh.ts) before loader kickoff; only ever populated on document renders
663
+ * barrier is a guaranteed cycle, not a race. Registered by resolveOwnerLoaders
664
+ * before loader kickoff; only ever populated on document renders
737
665
  * (the flag is stamped per-isSSR at DSL evaluation).
738
666
  */
739
667
  _awaitBeforeFlushLoaderIds?: Set<string>;
@@ -811,6 +739,12 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
811
739
  * keeping phases that began before the opt-in at their true (non-negative) offset.
812
740
  */
813
741
  _handlerStart?: number;
742
+ /**
743
+ * @internal Handler-level Server-Timing entries (rsc/handler.ts): the
744
+ * bootstrap timings, then the core handler's classify. A stale document
745
+ * cache entry's re-run has its own (render-pass.ts).
746
+ */
747
+ _handlerTiming?: string[];
814
748
  /** @internal Resolved platform phase-span tracing for this request (Cloudflare or OTel) */
815
749
  _tracing?: ResolvedTracing;
816
750
  /** @internal Router basename for this request (used by redirect()) */
@@ -846,27 +780,13 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
846
780
  */
847
781
  _cacheSignal?: import("../router/telemetry.js").CacheSegmentSignal[];
848
782
  }
849
- /**
850
- * @internal The freshness window of a route cache() record, as ms
851
- * timestamps: fresh until `freshUntil` (its `expiresAt`), stale until
852
- * `staleUntil` (plus its scope's swr). `ttl`, `swr` and `written` describe
853
- * the record that sets `staleUntil`: its cache() config, and whether this
854
- * request wrote it (cacheRoute) rather than read it.
855
- */
856
- export interface RouteRecordWindow {
857
- freshUntil: number;
858
- staleUntil: number;
859
- ttl: number;
860
- swr: number;
861
- written: boolean;
862
- }
863
783
  /**
864
784
  * Public view of RequestContext, without internal methods and fields.
865
785
  *
866
786
  * This is the type exported to library consumers. Internal code should
867
787
  * use the full RequestContext interface directly.
868
788
  */
869
- export type PublicRequestContext<TEnv = DefaultEnv, TParams = Record<string, string>> = Omit<RequestContext<TEnv, TParams>, "cookie" | "cookies" | "_readCookie" | "_readCookies" | "setCookie" | "deleteCookie" | "_handleStore" | "_transitionWhenRefs" | "_pprReplayPostMatchReason" | "_cacheStore" | "_prerender" | "_onDemandProducer" | "_searchParamsFilter" | "_shellCaptureRun" | "_shellCaptureForVisitor" | "_shellImplicitCache" | "_shellLoaderSeed" | "_shellCaptureLoaderRecords" | "_shellCaptureUnrecordedLoaderPush" | "_shellCaptureLoaderLanes" | "_resolvedCacheKeys" | "_shellKey" | "_shellForcedMiss" | "_prerenderWarm" | "_runAtRequestEntry" | "_routeRecordWindow" | "_shellFragmentPayload" | "_shellCaptureGuardTripped" | "_shellCaptureGuardTrippedLoaderId" | "_explicitTaggedStores" | "_requestTags" | "_recordTagOwners" | "_recordLoaderTags" | "_cacheProfiles" | "_onResponseCallbacks" | "_pendingBackgroundTasks" | "_themeConfig" | "_readTheme" | "_documentCacheRender" | "_payloadVisitorTheme" | "_payloadDeferred" | "_requestKind" | "_payloadVisitorLocation" | "_locationState" | "_routeName" | "_prevRouteKey" | "_visitorMoved" | "_inActionRevalidation" | "_actionRan" | "_reportedErrors" | "_printedErrors" | "_renderErrors" | "_recoveredHandlerErrors" | "_renderBarrier" | "_resolveRenderBarrier" | "_renderBarrierSegmentOrder" | "_treeHasStreaming" | "_renderBarrierWaiters" | "_handlerLoaderDeps" | "_awaitBeforeFlushLoaderIds" | "_renderBarrierHandleSnapshot" | "_renderBarrierGuardClosed" | "_reportBackgroundError" | "_debugPerformance" | "_metricsStore" | "_renderForeground" | "_activeRoutine" | "_renderDiagnosticsEnabled" | "_handlerStart" | "_tracing" | "_basename" | "_routerId" | "_versions" | "_setStatus" | "_rotateStateCookie" | "_setKeepCacheDirective" | "_freshReads" | "_setFreshReadsCookie" | "_requestRoot" | "_requestStart" | "_responseSent" | "_variables" | "_classifiedRoute" | "_requestMode" | "_cacheSignal" | "_dynamic" | "res">;
789
+ export type PublicRequestContext<TEnv = DefaultEnv, TParams = Record<string, string>> = Omit<RequestContext<TEnv, TParams>, "cookie" | "cookies" | "_readCookie" | "_readCookies" | "setCookie" | "deleteCookie" | "_handleStore" | "_transitionWhenRefs" | "_pprReplayPostMatchReason" | "_cacheStore" | "_prerender" | "_onDemandProducer" | "_searchParamsFilter" | "_shellCaptureState" | "_shellImplicitCache" | "_shellLoaderSeed" | "_resolvedCacheKeys" | "_shellKey" | "_shellForcedMiss" | "_prerenderWarm" | "_runAtRequestEntry" | "_shellFragmentPayload" | "_explicitTaggedStores" | "_requestTags" | "_recordTagOwners" | "_recordLoaderTags" | "_cacheProfiles" | "_onResponseCallbacks" | "_pendingBackgroundTasks" | "_themeConfig" | "_readTheme" | "_documentCacheRender" | "_payloadVisitorTheme" | "_payloadDeferred" | "_requestKind" | "_payloadVisitorLocation" | "_locationState" | "_routeName" | "_prevRouteKey" | "_visitorMoved" | "_inActionRevalidation" | "_actionRan" | "_reportedErrors" | "_printedErrors" | "_renderErrors" | "_recoveredHandlerErrors" | "_renderBarrier" | "_resolveRenderBarrier" | "_renderBarrierSegmentOrder" | "_treeHasStreaming" | "_renderBarrierWaiters" | "_handlerLoaderDeps" | "_awaitBeforeFlushLoaderIds" | "_renderBarrierHandleSnapshot" | "_renderBarrierGuardClosed" | "_reportBackgroundError" | "_debugPerformance" | "_metricsStore" | "_renderForeground" | "_activeRoutine" | "_renderDiagnosticsEnabled" | "_handlerStart" | "_handlerTiming" | "_tracing" | "_basename" | "_routerId" | "_versions" | "_setStatus" | "_rotateStateCookie" | "_setKeepCacheDirective" | "_freshReads" | "_setFreshReadsCookie" | "_requestRoot" | "_requestStart" | "_responseSent" | "_variables" | "_classifiedRoute" | "_requestMode" | "_cacheSignal" | "_dynamic" | "res">;
870
790
  /**
871
791
  * Marker for a waitUntil-scheduled fn whose task promise must NOT enter
872
792
  * _pendingBackgroundTasks. Used by the PPR shell capture for its own task:
@@ -1004,8 +924,8 @@ export declare function rebaseRequestContext(ctx: RequestContext<any>, request:
1004
924
  /**
1005
925
  * Wire a fresh render barrier onto `ctx`, closure-bound to THIS ctx and THIS
1006
926
  * handle store. Called by createRequestContext for every fresh context, and by
1007
- * deriveShellCaptureContext (rsc/shell-capture.ts) for the PPR capture's
1008
- * derived context.
927
+ * deriveRenderPass (server/render-pass.ts) for a derived pass whose
928
+ * RENDER_PASS_FIELDS row owns its barrier (the PPR capture and the HIT tail).
1009
929
  *
1010
930
  * The derived-context call is load-bearing (issue #684, plan 009): the capture
1011
931
  * context is `Object.create(reqCtx)`, so without its own wiring every
@@ -25,12 +25,12 @@ export declare function recordRewriteHop(reqCtx: TrailContext, from: URL, to: UR
25
25
  export declare function recordRewriteShell(reqCtx: TrailContext, audience: RewriteShell | undefined): void;
26
26
  /** The last hop's `rewrite(...).shell()` choice; undefined: none. */
27
27
  export declare function rewriteShellAudience(reqCtx: TrailContext | undefined): RewriteShell | undefined;
28
- type AudienceContext = Pick<RequestContext<any>, "_shellCaptureRun" | "_documentCacheRender" | "res">;
28
+ type AudienceContext = Pick<RequestContext<any>, "_shellCaptureState" | "_documentCacheRender" | "res">;
29
29
  /**
30
30
  * A render other visitors may be served: a PPR shell capture, or a render
31
31
  * the document cache stores (its response opted in before next()). It shows
32
32
  * no visitor theme, and no visitor URL unless it is a visitor-keyed shell
33
- * capture (`_shellCaptureForVisitor`).
33
+ * capture (`_shellCaptureState.forVisitor`).
34
34
  */
35
35
  export declare function rendersForSharedAudience(reqCtx: AudienceContext): boolean;
36
36
  /**
@@ -2,9 +2,12 @@
2
2
  * dispatch — in-process request -> Response for unit/integration tests,
3
3
  * WITHOUT the Flight RSC runtime.
4
4
  *
5
- * dispatch runs the router's real matching and middleware execution so that
6
- * redirects, 404s, response routes (path.json / path.text / path.html / ...),
7
- * and middleware short-circuits behave exactly as in production. It deliberately
5
+ * dispatch runs the production handler's request stages
6
+ * (rsc/request-stages.ts: classify, the terminal plans, the global middleware
7
+ * passes, the response route and the response's finalization) so that
8
+ * redirects, 404s, reloads, response routes (path.json / path.text /
9
+ * path.html / ...), and middleware short-circuits behave exactly as in
10
+ * production. It deliberately
8
11
  * does NOT render React Server Components: there is no Flight stream, no SSR,
9
12
  * and no DOM. Hit an RSC (component) route and dispatch throws a clear error
10
13
  * directing you to renderToFlightString/renderServerTree/renderHandler or an e2e test.
@@ -17,19 +20,20 @@
17
20
  * so a global auth middleware can 401/redirect them and middleware-set
18
21
  * cookies/headers merge onto the 308/404 the way createResponseWithMergedHeaders
19
22
  * merges them in production.
20
- * - Response routes (non-RSC) -> serialized Response
23
+ * - Response routes (non-RSC), served by production's handleResponseRoute
24
+ * (rsc/response-route-handler.ts) -> serialized Response
21
25
  * - json: JSON.stringify(result) (bare value) with application/json
22
26
  * - text/html/xml/md: String(result) with the mapped MIME type
23
- * - handler returning or throwing a Response: re-wrapped like
24
- * handleResponseRoute (stub headers/cookies merged, Set-Cookie preserved,
25
- * WebSocket upgrade passed through without reconstruction)
27
+ * - handler returning or throwing a Response: re-wrapped (stub
28
+ * headers/cookies merged, Set-Cookie preserved, WebSocket upgrade passed
29
+ * through without reconstruction)
26
30
  * - handler throwing a non-Response error: typed 500 / RouterError
27
- * status, matching handleResponseRoute (RFC 9457 problem+json body with
28
- * application/problem+json for json routes, text/plain message otherwise)
31
+ * status (RFC 9457 problem+json body with application/problem+json for
32
+ * json routes, text/plain message otherwise)
29
33
  * - content-negotiated route: Vary: Accept appended
30
34
  * - cached response route (cache({...})): getResponse/putResponse
31
- * hit/SWR/tag write, resolved from the matched entry tree exactly as
32
- * handleResponseRoute does. The write is scheduled via ctx.waitUntil
35
+ * hit/SWR/tag write, resolved from the matched entry tree. The write is
36
+ * scheduled via ctx.waitUntil
33
37
  * (a microtask without an executionContext), so a HIT-asserting test must
34
38
  * flush microtasks between the seeding dispatch and the asserting one.
35
39
  * - Global middleware (router.use(...)) AND route-level middleware, with full
@@ -38,10 +42,17 @@
38
42
  * global middleware runs first (so an auth gate can still 401/redirect),
39
43
  * then — if it passes through — an X-RSC-Reload is returned. Route-level
40
44
  * middleware is skipped on a partial, exactly as production skips it.
41
- * - A middleware redirect (3xx + Location) on a partial/action request
42
- * (?_rsc_partial / ?_rsc_action): converted to a 204 + X-RSC-Redirect via the
43
- * real interceptRedirectForPartial, so fetch() does not auto-follow the 3xx —
45
+ * - A global middleware redirect (3xx + Location) on a partial/action request
46
+ * (?_rsc_partial / ?_rsc_action), and a findMatch() redirect on a partial
47
+ * request: a 204 + X-RSC-Redirect, so fetch() does not auto-follow the 3xx —
44
48
  * identical to production's no-location-state path.
49
+ * - The terminal plans production answers inside the global chain
50
+ * (terminalPlanResponse): a `_rsc_v` version mismatch and a `_rsc_rid` app
51
+ * switch reload (X-RSC-Reload), and an action (?_rsc_action) a rewrite moved
52
+ * to a target that is not a page route throws production's error.
53
+ * - Route params and name are set inside the global chain, after classify, by
54
+ * the stage production's executeRequest runs (recordPlanRoute): global
55
+ * middleware sees them after next(), not before it.
45
56
  * - The open-redirect guard (rsc/redirect-guard.ts) on full (browser-followed)
46
57
  * redirects: a cross-origin Location is rewritten to the basename root unless
47
58
  * redirect(url, { external: true }) opted out, mirroring production's single
@@ -60,7 +71,9 @@
60
71
  * after finalizeResponse (segmentCount 0 / cacheHit false — dispatch renders no
61
72
  * RSC segments and holds no match-cache state), and a thrown non-Response error
62
73
  * emits request.error with phase "routing". All three carry the same requestId
63
- * (getRequestId). Emission is gated entirely on a configured sink; with none,
74
+ * (getRequestId), as does a response-route timeout on a rewritten pass
75
+ * (runRequestPasses carries the id to each pass's request, as in
76
+ * production). Emission is gated entirely on a configured sink; with none,
64
77
  * dispatch does zero new work and stays byte-identical for existing callers.
65
78
  * Lets a consumer unit-test their sink wiring in-process instead of only at e2e.
66
79
  * - Response-route `renderStartMs` timeouts and `onTimeout`: dispatch races the
@@ -96,9 +109,13 @@
96
109
  * request.start/end/error lifecycle above; cover cache/loader telemetry with an
97
110
  * e2e test driving a real RSC request.
98
111
  *
99
- * dispatch reuses router.previewMatch(), which itself runs content negotiation
100
- * and resolves route middleware from the matched entry tree, so dispatch's
101
- * route-middleware collection is exactly the router's, not a re-implementation.
112
+ * Each pass is classified with the handler's classify stage
113
+ * (router/request-classification.ts classifyRequest), which runs content
114
+ * negotiation and resolves route middleware from the matched entry tree, so
115
+ * dispatch's route-middleware collection is exactly the router's, not a
116
+ * re-implementation. The origin guard is not run: it gates only the action,
117
+ * loader and PE-form plans, which classify gives a component route only, and
118
+ * dispatch throws on those before the pass's middleware.
102
119
  */
103
120
  import type { Rango } from "../router/router-interfaces.js";
104
121
  /**
@@ -76,6 +76,12 @@ export interface ServeShellRequestOptions<TEnv = any> {
76
76
  * that source. `rewriteTarget` sends the `metadata.rewriteTarget` the page at
77
77
  * `from` carried when middleware rewrote it (`_rsc_rt`), as the browser
78
78
  * does: the server then diffs against the route that rendered that page.
79
+ * `stale: true` sends a stale request (`_rsc_stale`), as the browser sends
80
+ * it: every `revalidate()` sees `stale: true` (see `revalidate()`'s `stale`)
81
+ * and segments take an action's revalidation defaults; it renders live, as
82
+ * an action does, so neither the route cache nor the document cache answers
83
+ * or stores it, and a `ppr` route's `replayStatus` is
84
+ * `{ outcome: "BYPASS", reason: "stale" }`.
79
85
  */
80
86
  partial?: true | {
81
87
  from?: string;
@@ -84,6 +90,7 @@ export interface ServeShellRequestOptions<TEnv = any> {
84
90
  prefetch?: boolean;
85
91
  fill?: boolean;
86
92
  interceptSource?: string;
93
+ stale?: boolean;
87
94
  };
88
95
  /**
89
96
  * POST this form as a submit before hydration: the no-JS request the
@@ -130,9 +130,12 @@ export interface CacheOptions<TEnv = unknown> {
130
130
  */
131
131
  condition?: (ctx: import("../server/request-context.js").RequestContext<TEnv>) => boolean;
132
132
  /**
133
- * Custom cache key function - FULL OVERRIDE.
134
- * Bypasses default key generation AND store's keyGenerator. The result is
135
- * stored namespaced (`key:` plus its URI encoding), so no value it returns
133
+ * Custom cache key function. Replaces the URL part of the default key
134
+ * (host, path, params, search) AND bypasses the store's keyGenerator. The
135
+ * request kind stays: a document request, a navigation and each intercept
136
+ * navigation keep their own record under one result, so the result decides
137
+ * which requests of one kind share a record. It is stored namespaced
138
+ * (`key:` plus its URI encoding, then the kind), so no value it returns
136
139
  * names another route's record; a nested cache() keys its records within
137
140
  * this partition.
138
141
  *
@@ -69,7 +69,15 @@ export interface OnErrorContext<TEnv = any> {
69
69
  env?: TEnv;
70
70
  /** Duration from request start to error (milliseconds) */
71
71
  duration?: number;
72
- /** Whether this is a partial/navigation request */
72
+ /**
73
+ * Whether this is a partial/navigation request, on an error the segment
74
+ * walk catches (a handler that throws, a DSL loader that rejects): `true`
75
+ * for a navigation, unset for a document. An error in the background
76
+ * re-render of a `cache()` record (a stale HIT's refresh, the write of a
77
+ * navigation that kept a layout mounted) reports the request that started
78
+ * it. A streamed (`loading()`) handler's rejection does not carry it, in
79
+ * either render; the `routing` phase reports `false`.
80
+ */
73
81
  isPartial?: boolean;
74
82
  /** Whether an error boundary caught the error */
75
83
  handledByBoundary?: boolean;
@@ -342,7 +342,7 @@ export type InternalHandlerContext<TParams = {}, TEnv = DefaultEnv, TSearch exte
342
342
  _reverseScope?: import("../server/context.js").ReverseScope;
343
343
  /**
344
344
  * @internal The on-demand overlay holds a "removed" marker for this request
345
- * (tryPrerenderLookup, cache-lookup.ts); gateOnDemandProducer reads it. On
345
+ * (readPrerenderSource, cache-lookup.ts); gateOnDemandProducer reads it. On
346
346
  * this context, not the request's: withCacheLookup documents that the
347
347
  * request ALS can be lost mid-pipeline on workerd.
348
348
  */
@@ -390,6 +390,14 @@ export type InternalHandlerContext<TParams = {}, TEnv = DefaultEnv, TSearch exte
390
390
  * request is a fill. See router/segment-resolution/prefetch-deferral.ts.
391
391
  */
392
392
  _prefetchDeferral?: import("../router/segment-resolution/prefetch-deferral.js").PrefetchDeferral;
393
+ /**
394
+ * @internal DSL loaders registered and not started, by `$$id`: a prefetch
395
+ * deferred them, or a pass that skips loaders (`skipLoaders`) did not run
396
+ * them. A reader's ctx.use() starts one through its registration
397
+ * (registerDeferredLoader, startDeferredLoader in
398
+ * router/segment-resolution/prefetch-deferral.ts).
399
+ */
400
+ _deferredLoaders?: Map<string, import("../router/segment-resolution/prefetch-deferral.js").DeferredLoader>;
393
401
  /**
394
402
  * @internal Whether a loader was started in this request: a run of it (a
395
403
  * handler's or another loader's ctx.use()) or its cache() binding. A
@@ -510,10 +518,10 @@ export type IsActionFn = (...actions: ActionRef[]) => boolean;
510
518
  * ```ts
511
519
  * import * as CartActions from "./actions/cart";
512
520
  *
513
- * // Idiom A — "mine, else defer": re-render on my actions, otherwise return
514
- * // undefined so the segment's default decision still applies (and downstream
515
- * // revalidators get a say).
516
- * revalidate((ctx) => ctx.isAction(CartActions) || undefined)
521
+ * // Idiom A — "mine, else defer": re-render on my actions and on Back after
522
+ * // an action, otherwise return undefined so the segment's default decision
523
+ * // still applies (and downstream revalidators get a say).
524
+ * revalidate((ctx) => ctx.isAction(CartActions) || ctx.stale || undefined)
517
525
  *
518
526
  * // Idiom B — "mine only": re-render on my actions and suppress everything
519
527
  * // else (isAction returns a raw boolean, so an unrelated action yields false).
@@ -629,8 +637,11 @@ export type ShouldRevalidateFn<TParams = GenericParams, TEnv = any> = (args: {
629
637
  */
630
638
  toRouteName?: DefaultRouteName;
631
639
  /**
632
- * `true` when the browser signals that data may be stale — typically because
633
- * a server action was executed in this or another tab (`_rsc_stale` header).
640
+ * `true` on a revalidation of a page the browser marked stale (the
641
+ * `_rsc_stale` query param): Back/Forward onto a history entry after a
642
+ * server action in this or another tab, or while one is in flight. A request
643
+ * that holds no segments (the follow-up after an action, `refresh()`) is
644
+ * marked stale too, but there every segment renders and no predicate runs.
634
645
  *
635
646
  * This is NOT segment cache staleness (loaders are never segment-cached).
636
647
  * Use this to decide whether loader data should be re-fetched after an
@@ -151,7 +151,7 @@ export interface ResolvedSegment {
151
151
  loaderData?: any;
152
152
  /**
153
153
  * True when this loader was awaited before first flush
154
- * (loader(Def, { ssr: false })). Stamped by resolveLoaders (fresh.ts) on
154
+ * (loader(Def, { ssr: false })). Stamped by resolveOwnerLoaders on
155
155
  * document AND shell-capture renders — capture bakes flagged loaders and
156
156
  * awaits the same lane. Feeds segment-system's settled-value delivery and
157
157
  * the dev SSR suspension warning (ssr-suspension-warning.ts).
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Build discovery phase: the discovery plugin's buildStart, buildApp (post)
3
+ * and buildEnd hooks.
4
+ *
5
+ * buildStart discovers routers through a temp RSC server and writes the
6
+ * generated route types. When PPR shell candidates exist, it defers closing
7
+ * that server, and releasing the buildEnv, as a PAIR: the buildApp post hook
8
+ * releases them after the shell capture (success), buildEnd after an
9
+ * environment build failure (abort).
10
+ */
11
+ import type { Rolldown, ViteBuilder } from "vite";
12
+ import type { DiscoveryState } from "./state.js";
13
+ /**
14
+ * buildStart. Build mode: create a temporary Vite dev server to access the
15
+ * RSC environment's module runner, then discover routers and generate
16
+ * manifests. The manifest data is stored for the virtual module's load hook.
17
+ */
18
+ export declare function buildDiscoveryPhase(s: DiscoveryState, context: Rolldown.PluginContext): Promise<void>;
19
+ /**
20
+ * buildApp (post). Post-build phases, after EVERY environment bundle is
21
+ * written.
22
+ *
23
+ * 1. Cache versions (router-versions-phase.ts): hashes the server output as
24
+ * postprocessBundle left it and writes the per-router table into the
25
+ * built version module. First, because phase 2 stamps its entries with
26
+ * these versions and reads the same RSC out dir.
27
+ * 2. PPR shell capture (producer B, #699): the shell prelude embeds built
28
+ * client asset URLs (bootstrap entry), which do not exist at buildStart.
29
+ * The kept temp server and the buildEnv were deferred AS A PAIR in
30
+ * buildStart's finally; this finally is the pair's success-path owner
31
+ * (buildEndPhase owns the aborted-build path) — the phase itself is a pure
32
+ * producer and tears down only the globals it installs.
33
+ */
34
+ export declare function postBuildPhase(s: DiscoveryState, builder: ViteBuilder): Promise<void>;
35
+ /**
36
+ * buildEnd. An environment build failure aborts the builder before the
37
+ * buildApp post hook — never leak the kept temp server (open handles hang
38
+ * the CLI) or the deferred buildEnv (a live miniflare proxy).
39
+ */
40
+ export declare function buildEndPhase(s: DiscoveryState, error: Error | undefined): Promise<void>;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Build-time env (rango({ buildEnv })): resolution of the option and the
3
+ * lifetime of the resolved bindings on DiscoveryState. Acquired by dev
4
+ * discovery (dev-server-phase.ts) and build discovery
5
+ * (build-discovery-phase.ts).
6
+ */
7
+ import type { BuildEnvOption, BuildEnvFactoryContext, BuildEnvResult } from "../plugin-types.js";
8
+ import type { DiscoveryState } from "./state.js";
9
+ /**
10
+ * Resolve the buildEnv option into a concrete { env, dispose? } result.
11
+ * Handles all four input shapes: false, "auto", factory, plain object.
12
+ */
13
+ export declare function resolveBuildEnv(option: BuildEnvOption | undefined, factoryCtx: BuildEnvFactoryContext): Promise<BuildEnvResult | null>;
14
+ /**
15
+ * Acquire build-time env bindings and store on discovery state.
16
+ * Returns true if env was acquired, false if buildEnv is disabled.
17
+ */
18
+ export declare function acquireBuildEnv(s: DiscoveryState, command: "serve" | "build", mode: string): Promise<boolean>;
19
+ /**
20
+ * Release build-time env resources and clear state.
21
+ */
22
+ export declare function releaseBuildEnv(s: DiscoveryState): Promise<void>;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Bundle scan phase: the discovery plugin's generateBundle hook.
3
+ *
4
+ * Records the inputs of the per-router cache versions (build-versions.ts) for
5
+ * every environment and, during the RSC build, the RSC entry filename and the
6
+ * chunks holding Prerender/Static handler exports. closeBundle
7
+ * (bundle-postprocess.ts) uses them for handler code eviction and prerender
8
+ * data injection.
9
+ */
10
+ import type { Rolldown } from "vite";
11
+ import type { DiscoveryState } from "./state.js";
12
+ export declare function bundleScanPhase(s: DiscoveryState, context: Rolldown.PluginContext, bundle: any): void;
@@ -34,8 +34,9 @@ export interface DevPrerenderPayloadBodies {
34
34
  /** `intercept != 1` response: the route's own segments + handles. */
35
35
  main: string;
36
36
  /**
37
- * `intercept=1` response: main + intercept segments with the MERGED handle
38
- * string. Falls back to `main` byte-for-byte when the route has no
37
+ * `intercept=1` response: the build's intercept variant
38
+ * (interceptVariantSegments, prerender/store.ts) with the producer's handle
39
+ * string for it. Falls back to `main` byte-for-byte when the route has no
39
40
  * intercept segments — mirroring the endpoint's historical behavior.
40
41
  */
41
42
  intercept: string;
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Dev server phase: the discovery plugin's configureServer hook.
3
+ *
4
+ * Runs dev discovery (the Node RSC runner, or a temp Node server under
5
+ * Cloudflare, whose RSC env has no runner), serves the dev /__rsc_prerender
6
+ * and /__rsc_shell endpoints, and watches route files to regenerate the
7
+ * generated route types and re-run runtime discovery on HMR.
8
+ */
9
+ import type { ViteDevServer } from "vite";
10
+ import { type DiscoveryState } from "./state.js";
11
+ /** The slice of a Vite environment module graph the route-file watcher reads. */
12
+ interface ModulesByFileGraph {
13
+ getModulesByFile(file: string): ReadonlySet<unknown> | undefined;
14
+ }
15
+ /**
16
+ * Whether the dev route-file watcher ignores `file`: it sits in a directory
17
+ * every discovery scan skips (isInSkippedScanDir) and the RSC graph has not
18
+ * loaded it. See docs/manifests.md, "A reload no file of the app asked for".
19
+ */
20
+ export declare function isFileOutsideApp(root: string, file: string, rscGraph: ModulesByFileGraph | undefined): boolean;
21
+ /**
22
+ * configureServer. Dev mode: discover routers and populate manifest in
23
+ * memory. Skipped in build mode (buildDiscoveryPhase handles it).
24
+ */
25
+ export declare function devServerPhase(s: DiscoveryState, server: ViteDevServer): void;
26
+ export {};
@@ -95,7 +95,7 @@ export interface DiscoveryFailureReport {
95
95
  * - a transient artifact of a Vite dependency re-optimization racing with boot
96
96
  * discovery (a module read before the entry import resolves to the
97
97
  * pre-optimize copy of the runner graph while createRouter() populated the
98
- * post-optimize copy — see router-discovery.ts).
98
+ * post-optimize copy — see dev-server-phase.ts).
99
99
  *
100
100
  * We can only tell them apart when the caller observed the dep optimizer's
101
101
  * `browserHash` change across the discovery attempt (`reoptimizeObserved`): a
@@ -117,6 +117,9 @@ export interface DiscoveryState {
117
117
  resolvedEntryPath: string | undefined;
118
118
  projectRoot: string;
119
119
  isBuildMode: boolean;
120
+ /** Vite's resolved command and mode (configResolved), for resolveBuildEnv. */
121
+ viteCommand: "serve" | "build";
122
+ viteMode: string;
120
123
  userResolveAlias: any;
121
124
  /**
122
125
  * Data-only slice of the user's resolved config (resolve.* incl. native
@@ -199,6 +202,15 @@ export interface DiscoveryState {
199
202
  devDiscoveryEpoch?: number;
200
203
  devServerOrigin: string | null;
201
204
  devServer: any;
205
+ /**
206
+ * Dev: the pending transition({ when }) definition error, re-sent as the
207
+ * Vite error overlay until a discovery succeeds (dev-server-phase.ts).
208
+ */
209
+ transitionWhenOverlay: {
210
+ message: string;
211
+ stack: string;
212
+ plugin: string;
213
+ } | null;
202
214
  selfWrittenGenFiles: Map<string, {
203
215
  at: number;
204
216
  hash: string;
@@ -10,7 +10,7 @@ import { type Plugin } from "vite";
10
10
  * Build: exports a placeholder for the per-router versions table. The module
11
11
  * holds nothing that varies between builds; the table is written into the
12
12
  * built chunk after the server output is hashed (the buildApp post hook in
13
- * router-discovery.ts). See docs/design/per-app-cache-version.md.
13
+ * discovery/build-discovery-phase.ts). See docs/design/per-app-cache-version.md.
14
14
  * @internal
15
15
  */
16
16
  export declare function createVersionPlugin(): Plugin;
@@ -47,7 +47,7 @@ export declare function getVirtualVersionContent(version: string): string;
47
47
  /**
48
48
  * Free identifier the production version module ships in place of the table.
49
49
  * The versions are hashes of the built server code, so they cannot be part of
50
- * it: the buildApp post hook (router-discovery.ts) replaces this token in the
50
+ * it: the buildApp post hook (discovery/build-discovery-phase.ts) replaces this token in the
51
51
  * written chunk once the hashes are final (runRouterVersionsPhase,
52
52
  * discovery/router-versions-phase.ts). An unreplaced token throws a ReferenceError
53
53
  * when the module evaluates, so a build that skipped the step cannot serve