@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
@@ -0,0 +1,93 @@
1
+ /**
2
+ * ResolutionPass: what one walk over a matched chain reads.
3
+ *
4
+ * Every function of the segment walker (revalidation.ts, intercept-resolution.ts)
5
+ * resolves against the same request: the handler context, the segments the
6
+ * client holds, the previous and next location, the action, the staleness and
7
+ * the router's deps. They take this one object instead of threading the same
8
+ * ten values through each signature in a fixed order, where two adjacent
9
+ * `URL`s or `Record<string, string>`s could swap without a type error.
10
+ *
11
+ * A full match (a document, the background re-render of a route record, a
12
+ * build-time prerender) is a FRESH pass: see FRESH below.
13
+ */
14
+ import type { HandlerContext } from "../../types.js";
15
+ import type { ActionContext, SegmentResolutionDeps } from "../types.js";
16
+ /**
17
+ * The segment ids the client holds, the set resolution works on (match-api.ts
18
+ * may delete a route's id from the listed set to force a render). Empty on a
19
+ * full refetch.
20
+ */
21
+ export type ClientHeld = ReadonlySet<string>;
22
+ /**
23
+ * The client of a full match: it holds nothing and asks for nothing to be
24
+ * kept. Compared by identity (`pass.client === FRESH`), never by size: a
25
+ * partial request whose client holds nothing (NOTHING_HELD, an empty
26
+ * `_rsc_segments`) still asks the revalidate() rules. On a FRESH pass every
27
+ * segment is new without a decision, trace entry or `revalidation.decision`
28
+ * event, and the walker takes the full match's branches (revalidation.ts,
29
+ * each marked FRESH).
30
+ */
31
+ export declare const FRESH: ClientHeld;
32
+ /**
33
+ * A pass without the router's deps: what match middleware knows about the
34
+ * request. createSegmentWrappers (segment-wrappers.ts) binds the deps.
35
+ */
36
+ export interface ResolutionPassInput<TEnv = any> {
37
+ readonly context: HandlerContext<any, TEnv>;
38
+ readonly client: ClientHeld;
39
+ /** The matched route's params, stamped on every segment the walk emits. */
40
+ readonly params: Record<string, string>;
41
+ readonly prevParams: Record<string, string>;
42
+ /** Undefined only on a build-time FRESH pass (freshPassInput). */
43
+ readonly request: Request | undefined;
44
+ readonly prevUrl: URL;
45
+ readonly nextUrl: URL;
46
+ readonly routeKey: string;
47
+ readonly actionContext?: ActionContext;
48
+ readonly stale?: boolean;
49
+ /**
50
+ * No loader is started and no loader segment is emitted: build time
51
+ * (prerender-match.ts) and the background re-render of a route record
52
+ * (background-revalidation.ts), whose records never hold loaders.
53
+ * resolveOwnerLoaders registers each loader instead: in the re-render a
54
+ * handler's read starts it as its declaration; at build time a read
55
+ * throws (setupBuildUse).
56
+ */
57
+ readonly skipLoaders?: boolean;
58
+ /**
59
+ * A render error rethrows instead of rendering the error boundary, and a
60
+ * streamed handler's rejection is not recovered. Build time only, so a
61
+ * failure (or `throw new Skip()`) reaches the build instead of being baked
62
+ * into a frozen 200 (issue #587).
63
+ */
64
+ readonly throwOnError?: boolean;
65
+ /**
66
+ * The request is a navigation, though the pass is FRESH: the background
67
+ * re-render of a record a navigation read stale or wrote
68
+ * (background-revalidation.ts). An entry's error reports isPartial, as the
69
+ * navigation's own pass does.
70
+ */
71
+ readonly partialRequest?: boolean;
72
+ }
73
+ export interface ResolutionPass<TEnv = any> extends ResolutionPassInput<TEnv> {
74
+ readonly deps: SegmentResolutionDeps<TEnv>;
75
+ }
76
+ /**
77
+ * The input of a full match's pass (FRESH). At build time the prerender
78
+ * context's `request` is a throwing getter (handler-context.ts
79
+ * createPrerenderContext): the pass carries undefined instead.
80
+ */
81
+ export declare function freshPassInput<TEnv>(context: HandlerContext<any, TEnv>, routeKey: string, params: Record<string, string>, options?: {
82
+ skipLoaders?: boolean;
83
+ throwOnError?: boolean;
84
+ partialRequest?: boolean;
85
+ }): ResolutionPassInput<TEnv>;
86
+ /**
87
+ * The input of a pass whose client holds nothing: every segment is new and
88
+ * renders. The background re-render of an intercept (background-revalidation.ts)
89
+ * resolves with it.
90
+ */
91
+ export declare function heldNothingPassInput<TEnv>(context: HandlerContext<any, TEnv>, routeKey: string, params: Record<string, string>, options?: {
92
+ skipLoaders?: boolean;
93
+ }): ResolutionPassInput<TEnv>;
@@ -1,13 +1,20 @@
1
1
  /**
2
- * Revalidation Path Segment Resolution
2
+ * The segment walker.
3
3
  *
4
- * Functions for resolving segments during partial (revalidation) requests.
5
- * Mirrors the fresh path but adds revalidation awareness: only re-resolves
6
- * segments whose revalidate() predicate returns true.
4
+ * Resolves a matched chain's segments (loaders, layouts, routes, parallels,
5
+ * orphan layouts, error boundaries) in handler-first order. A partial request
6
+ * re-resolves only what the client lacks and what a held segment's
7
+ * revalidate() rules ask for. A full match (a document, the background
8
+ * re-render of a route record, a build-time prerender) walks the same code
9
+ * with `pass.client === FRESH` (resolution-pass.ts): every segment is new,
10
+ * and the branches marked FRESH keep what the full match has always done
11
+ * differently.
7
12
  */
8
13
  import { type EntryData, type LoaderEntry } from "../../server/context";
9
14
  import type { HandlerContext, ResolvedSegment, ShouldRevalidateFn } from "../../types";
10
- import type { SegmentResolutionDeps, SegmentRevalidationResult, ActionContext } from "../types.js";
15
+ import type { SegmentRevalidationResult } from "../types.js";
16
+ import type { InterceptResult } from "../router-context.js";
17
+ import { type ResolutionPass } from "./resolution-pass.js";
11
18
  /**
12
19
  * A deferred loader something started in this request (a handler that awaits
13
20
  * it with ctx.use(), or another loader) ran in the prefetch whatever its flag
@@ -37,23 +44,37 @@ export interface LoaderOwner {
37
44
  * False for an intercept: never a document.
38
45
  */
39
46
  readonly bakeLane: boolean;
47
+ /**
48
+ * The owner declares loading(false). A FRESH pass then settles every loader
49
+ * before the handler runs (resolveOwnerLoaders). Unset for an intercept.
50
+ */
51
+ readonly loadingDisabled?: boolean;
40
52
  readonly traceSource: "loader" | "intercept-loader";
41
53
  }
42
54
  /** A route entry as a LoaderOwner, under `shortCodeOverride` when inherited. */
43
55
  export declare function ownerOf(entry: EntryData, shortCodeOverride?: string): LoaderOwner;
44
56
  /**
45
- * The partial lane's one loader funnel: each loader is a segment, run when
46
- * the client lacks it, asked its revalidate() when held, kept outright in a
47
- * fill (fillSends), deferred in a prefetch that defers it (defersLoader).
57
+ * The walker's one loader funnel: each loader is a segment, run when the
58
+ * client lacks it, asked its revalidate() when held, kept outright in a fill
59
+ * (fillSends), deferred in a prefetch that defers it (defersLoader).
60
+ *
61
+ * Loaders run lazily via ctx.use() and are memoized, so they run in
62
+ * parallel. A FRESH pass kicks every loader off without an await, in the
63
+ * tick the call starts: a reader's ctx.use(Loader) finds the binding only if
64
+ * it registered first (docs/design/handle-push-ownership.md).
48
65
  */
49
- export declare function resolveOwnerLoaders<TEnv>(owner: LoaderOwner, ctx: HandlerContext<any, TEnv>, belongsToRoute: boolean, clientSegmentIds: ReadonlySet<string>, prevParams: Record<string, string>, request: Request, prevUrl: URL, nextUrl: URL, routeKey: string, deps: SegmentResolutionDeps<TEnv>, actionContext?: ActionContext, stale?: boolean): Promise<{
66
+ export declare function resolveOwnerLoaders<TEnv>(pass: ResolutionPass<TEnv>, owner: LoaderOwner, belongsToRoute: boolean): Promise<{
50
67
  segments: ResolvedSegment[];
51
68
  matchedIds: string[];
52
69
  }>;
53
70
  /**
54
- * Resolve only loader segments for all entries with revalidation logic.
71
+ * Resolve only loader segments for all entries: a cache() or prerender HIT
72
+ * serves the cached non-loader segments, and loaders are never cached. Under
73
+ * an intercept the route's entry, and on an intercept's fill an entry the
74
+ * client lacks, are skipped as resolveAllSegments skips them, after the ppr
75
+ * header latch below has read the chain's leaf.
55
76
  */
56
- export declare function resolveLoadersOnlyWithRevalidation<TEnv>(entries: EntryData[], context: HandlerContext<any, TEnv>, clientSegmentIds: Set<string>, prevParams: Record<string, string>, request: Request, prevUrl: URL, nextUrl: URL, routeKey: string, deps: SegmentResolutionDeps<TEnv>, actionContext?: ActionContext, stale?: boolean): Promise<{
77
+ export declare function resolveLoadersOnly<TEnv>(pass: ResolutionPass<TEnv>, entries: EntryData[], walk?: Pick<RevalidatingWalkOptions, "interceptResult">): Promise<{
57
78
  segments: ResolvedSegment[];
58
79
  matchedIds: string[];
59
80
  }>;
@@ -65,9 +86,9 @@ export declare function buildEntryRevalidateMap(entries: EntryData[]): Map<strin
65
86
  revalidate: ShouldRevalidateFn<any, any>[];
66
87
  }>;
67
88
  /**
68
- * Resolve parallel segments with revalidation.
89
+ * Resolve an entry's parallel slots: each slot's segment and its loaders.
69
90
  */
70
- export declare function resolveParallelSegmentsWithRevalidation<TEnv>(entry: EntryData, params: Record<string, string>, context: HandlerContext<any, TEnv>, belongsToRoute: boolean, clientSegmentIds: Set<string>, prevParams: Record<string, string>, request: Request, prevUrl: URL, nextUrl: URL, routeKey: string, deps: SegmentResolutionDeps<TEnv>, actionContext?: ActionContext, stale?: boolean, options?: {
91
+ export declare function resolveParallelSegments<TEnv>(pass: ResolutionPass<TEnv>, entry: EntryData, belongsToRoute: boolean, options?: {
71
92
  /**
72
93
  * Seed for an unknown parent-chain slot (slot not in clientSegmentIds) when
73
94
  * there are no deciding revalidate fns. "type-derived" (default, main path):
@@ -85,43 +106,73 @@ export declare function resolveParallelSegmentsWithRevalidation<TEnv>(entry: Ent
85
106
  * to it: loader sub-ids are filtered out and slots are re-grouped by parent).
86
107
  */
87
108
  loaderOrder?: "after" | "before";
88
- /** Matched chain entry being resolved; see ResolveSegmentOptions.boundaryEntry. */
109
+ /**
110
+ * The matched chain entry being resolved: where the sync path catches a
111
+ * handler error, so a streamed slot handler (or a slot owned by a
112
+ * routeless layout) recovers into the same boundary. Defaults to `entry`.
113
+ */
89
114
  boundaryEntry?: EntryData;
90
115
  }): Promise<SegmentRevalidationResult>;
91
116
  /**
92
- * Resolve entry handler (layout, cache, or route) with revalidation.
117
+ * Resolve a chain entry's handler (layout, cache, or route) into its segment.
93
118
  */
94
- export declare function resolveEntryHandlerWithRevalidation<TEnv>(entry: Exclude<EntryData, {
119
+ export declare function resolveEntryHandler<TEnv>(pass: ResolutionPass<TEnv>, entry: Exclude<EntryData, {
95
120
  type: "parallel";
96
- }>, params: Record<string, string>, context: HandlerContext<any, TEnv>, belongsToRoute: boolean, clientSegmentIds: Set<string>, prevParams: Record<string, string>, request: Request, prevUrl: URL, nextUrl: URL, routeKey: string, deps: SegmentResolutionDeps<TEnv>, actionContext?: ActionContext, stale?: boolean): Promise<{
121
+ }>, belongsToRoute: boolean): Promise<{
97
122
  segment: ResolvedSegment;
98
123
  matchedId: string;
99
124
  }>;
100
125
  /**
101
- * Resolve segments with revalidation awareness (for partial rendering).
126
+ * Resolve one chain entry's segments: its loaders, its handler, its orphan
127
+ * layouts and its parallels, handler first.
102
128
  */
103
- export declare function resolveSegmentWithRevalidation<TEnv>(entry: Exclude<EntryData, {
129
+ export declare function resolveSegment<TEnv>(pass: ResolutionPass<TEnv>, entry: Exclude<EntryData, {
104
130
  type: "parallel";
105
- }>, routeKey: string, params: Record<string, string>, context: HandlerContext<any, TEnv>, clientSegmentIds: Set<string>, prevParams: Record<string, string>, request: Request, prevUrl: URL, nextUrl: URL, deps: SegmentResolutionDeps<TEnv>, actionContext?: ActionContext, stale?: boolean,
106
- /** The matched route's full chain; see ResolveSegmentOptions.chain (fresh.ts). */
131
+ }>,
132
+ /** The matched route's full chain; see RevalidatingWalkOptions.chain. */
107
133
  chain?: readonly EntryData[]): Promise<SegmentRevalidationResult>;
108
134
  /**
109
- * Resolve orphan layout with revalidation.
135
+ * Resolve an orphan layout: its loaders, its handler, its slots and the
136
+ * routeless entries nested in it.
110
137
  */
111
- export declare function resolveOrphanLayoutWithRevalidation<TEnv>(orphan: EntryData, params: Record<string, string>, context: HandlerContext<any, TEnv>, clientSegmentIds: Set<string>, prevParams: Record<string, string>, request: Request, prevUrl: URL, nextUrl: URL, routeKey: string, belongsToRoute: boolean, deps: SegmentResolutionDeps<TEnv>, actionContext?: ActionContext, stale?: boolean,
138
+ export declare function resolveOrphanLayout<TEnv>(pass: ResolutionPass<TEnv>, orphan: EntryData, belongsToRoute: boolean,
112
139
  /** Parent route entry — its loaders are inherited so parallel slots can access them. */
113
140
  parentRouteEntry?: EntryData,
114
- /** Matched chain entry being resolved (see ResolveSegmentOptions.boundaryEntry); defaults to parentRouteEntry. */
141
+ /**
142
+ * Matched chain entry being resolved (see
143
+ * resolveParallelSegments's boundaryEntry); defaults to
144
+ * parentRouteEntry.
145
+ */
115
146
  boundaryEntry?: EntryData | undefined): Promise<SegmentRevalidationResult>;
147
+ /** What resolveAllSegments needs beyond its pass. */
148
+ export interface RevalidatingWalkOptions {
149
+ /**
150
+ * The intercept the request resolves: the route's entry (its handler and
151
+ * loaders) is skipped and only its id is matched. None on a full match.
152
+ */
153
+ readonly interceptResult?: InterceptResult | null;
154
+ /** For the intercept skip's debug log. */
155
+ readonly localRouteName?: string;
156
+ /** Where an entry's error boundary reports (resolveWithErrorBoundary). */
157
+ readonly pathname: string;
158
+ /**
159
+ * The matched route's full entry chain. Defaults to `entries`;
160
+ * withCacheLookup passes it when it resolves only the entries above a
161
+ * cache() boundary. An orphan list can hold an entry of the chain: a bare
162
+ * cache() marker sits in its layout's layout[] (it wraps that layout's
163
+ * routes) and is the parent of the routes after it. For those routes it
164
+ * resolves once, as a chain entry, below the cache() header latch (issue
165
+ * #918: resolved twice on a MISS, once and discarded on a HIT).
166
+ */
167
+ readonly chain?: readonly EntryData[];
168
+ }
116
169
  /**
117
- * Resolve all segments for a route with revalidation logic (for matchPartial).
170
+ * Resolve all segments for a route: a partial match (matchPartial), a full
171
+ * match with a FRESH pass, or the FRESH pass of an intercept record's
172
+ * background re-render (rerenderAndCacheRoute). A thrown action's pass is cut
173
+ * at its error boundary (ActionContext.boundary).
118
174
  */
119
- export declare function resolveAllSegmentsWithRevalidation<TEnv>(entries: EntryData[], routeKey: string, params: Record<string, string>, context: HandlerContext<any, TEnv>, clientSegmentSet: Set<string>, prevParams: Record<string, string>, request: Request, prevUrl: URL, nextUrl: URL, actionContext: ActionContext | undefined, interceptResult: {
120
- intercept: any;
121
- entry: EntryData;
122
- } | null, localRouteName: string, pathname: string, deps: SegmentResolutionDeps<TEnv>, stale?: boolean,
123
- /** The matched route's full chain; see ResolveSegmentOptions.chain (fresh.ts). */
124
- chain?: readonly EntryData[]): Promise<{
175
+ export declare function resolveAllSegments<TEnv>(pass: ResolutionPass<TEnv>, entries: EntryData[], walk: RevalidatingWalkOptions): Promise<{
125
176
  segments: ResolvedSegment[];
126
177
  matchedIds: string[];
127
178
  }>;
@@ -1,3 +1,2 @@
1
1
  export { handleHandlerResult, warnOnStreamedResponse, buildLoaderErrorContext, } from "./segment-resolution/helpers.js";
2
- export { resolveLoaders, type ResolveSegmentOptions, resolveSegment, resolveOrphanLayout, resolveParallelEntry, resolveAllSegments, resolveLoadersOnly, } from "./segment-resolution/fresh.js";
3
- export { resolveLoadersOnlyWithRevalidation, buildEntryRevalidateMap, resolveParallelSegmentsWithRevalidation, resolveEntryHandlerWithRevalidation, resolveSegmentWithRevalidation, resolveOrphanLayoutWithRevalidation, resolveAllSegmentsWithRevalidation, } from "./segment-resolution/revalidation.js";
2
+ export { resolveLoadersOnly, buildEntryRevalidateMap, resolveParallelSegments, resolveEntryHandler, resolveSegment, resolveOrphanLayout, resolveAllSegments, } from "./segment-resolution/revalidation.js";
@@ -1,51 +1,14 @@
1
- import type { EntryData, InterceptEntry } from "../server/context";
2
- import type { HandlerContext, ResolvedSegment, ShouldRevalidateFn } from "../types";
3
1
  import type { SegmentResolutionDeps } from "./types.js";
4
- import type { ResolveSegmentOptions } from "./segment-resolution.js";
5
- import type { RevalidationContext } from "./router-context.js";
6
- import type { InterceptSelectorContext } from "../server/context";
7
- export interface SegmentWrappers<TEnv = any> {
8
- resolveAllSegments: (entries: EntryData[], routeKey: string, params: Record<string, string>, context: HandlerContext<any, TEnv>, loaderPromises: Map<string, Promise<any>>, options?: ResolveSegmentOptions) => Promise<ResolvedSegment[]>;
9
- resolveLoadersOnly: (entries: EntryData[], context: HandlerContext<any, TEnv>) => Promise<ResolvedSegment[]>;
10
- resolveLoadersOnlyWithRevalidation: (entries: EntryData[], context: HandlerContext<any, TEnv>, clientSegmentIds: Set<string>, prevParams: Record<string, string>, request: Request, prevUrl: URL, nextUrl: URL, routeKey: string, actionContext?: {
11
- actionId?: string;
12
- actionUrl?: URL;
13
- actionResult?: any;
14
- formData?: FormData;
15
- }, stale?: boolean) => Promise<{
16
- segments: ResolvedSegment[];
17
- matchedIds: string[];
18
- }>;
19
- buildEntryRevalidateMap: (entries: EntryData[]) => Map<string, {
20
- entry: EntryData;
21
- revalidate: ShouldRevalidateFn<any, any>[];
22
- }>;
23
- resolveAllSegmentsWithRevalidation: (entries: EntryData[], routeKey: string, params: Record<string, string>, context: HandlerContext<any, TEnv>, clientSegmentSet: Set<string>, prevParams: Record<string, string>, request: Request, prevUrl: URL, nextUrl: URL, actionContext: {
24
- actionId?: string;
25
- actionUrl?: URL;
26
- actionResult?: any;
27
- formData?: FormData;
28
- } | undefined, interceptResult: {
29
- intercept: InterceptEntry;
30
- entry: EntryData;
31
- } | null, localRouteName: string, pathname: string, stale?: boolean, chain?: readonly EntryData[]) => Promise<{
32
- segments: ResolvedSegment[];
33
- matchedIds: string[];
34
- }>;
35
- findInterceptForRoute: (targetRouteKey: string, fromEntry: EntryData | null, selectorContext?: InterceptSelectorContext | null, isAction?: boolean) => {
36
- intercept: InterceptEntry;
37
- entry: EntryData;
38
- } | null;
39
- resolveInterceptEntry: (interceptEntry: InterceptEntry, parentEntry: EntryData, params: Record<string, string>, context: HandlerContext<any, TEnv>, belongsToRoute?: boolean, revalidationContext?: any, options?: {
40
- background?: boolean;
41
- }) => Promise<ResolvedSegment[]>;
42
- resolveInterceptLoadersOnly: (interceptEntry: InterceptEntry, parentEntry: EntryData, context: HandlerContext<any, TEnv>, belongsToRoute: boolean, revalidationContext: RevalidationContext) => Promise<ResolvedSegment[]>;
43
- }
2
+ import type { RouterContext } from "./router-context.js";
3
+ import { findInterceptForRoute as _findInterceptForRoute } from "./intercept-resolution.js";
4
+ /** The resolvers RouterContext exposes, with the router's deps bound. */
5
+ export type SegmentWrappers<TEnv = any> = Pick<RouterContext<TEnv>, "resolveAllSegments" | "resolveInterceptEntry"> & Required<Pick<RouterContext<TEnv>, "resolveLoadersOnly" | "buildEntryRevalidateMap" | "resolveInterceptLoadersOnly">> & {
6
+ /** Its own signature: a null selector context, isAction defaulting to false. */
7
+ findInterceptForRoute: typeof _findInterceptForRoute;
8
+ };
44
9
  /**
45
- * Create thin wrapper functions that bind segmentDeps to extracted
46
- * segment resolution and intercept resolution functions.
47
- *
48
- * These maintain the same signatures as the original inline functions
49
- * so that RouterContext and call sites don't need to change.
10
+ * Bind the router's segment deps into the extracted segment and intercept
11
+ * resolvers. Each gets a ResolutionPass: the caller's request-side input with
12
+ * the deps added here, once per call.
50
13
  */
51
- export declare function createSegmentWrappers<TEnv = any>(segmentDeps: SegmentResolutionDeps<TEnv>): SegmentWrappers<TEnv>;
14
+ export declare function createSegmentWrappers<TEnv = any>(deps: SegmentResolutionDeps<TEnv>): SegmentWrappers<TEnv>;
@@ -208,6 +208,8 @@ export declare function safeEmit(sink: TelemetrySink, event: TelemetryEvent): vo
208
208
  * Generated IDs use format "t-{base36}" to distinguish from header values.
209
209
  */
210
210
  export declare function getRequestId(request: Request): string;
211
+ /** Make `id` the id getRequestId returns for `request`. */
212
+ export declare function setRequestId(request: Request, id: string): void;
211
213
  /**
212
214
  * Built-in console sink that logs events in a structured format.
213
215
  * Designed as the default sink for development / debugging.
@@ -15,6 +15,16 @@ export type ActionContext = {
15
15
  actionUrl?: URL;
16
16
  actionResult?: any;
17
17
  formData?: FormData;
18
+ /**
19
+ * A thrown action's error segment (matchError), set on the action's
20
+ * revalidation (rsc/server-action.ts matchBoundaryRevalidation). The walk
21
+ * (resolveAllSegments) resolves every entry above the segment's outlet as on
22
+ * a success, emits the segment in the outlet's place and stops, so nothing
23
+ * at or below the outlet runs. The pass skips the prerender store
24
+ * (cache-lookup.ts): the evicted handler is under the cut. No revalidate()
25
+ * predicate sees it.
26
+ */
27
+ boundary?: ResolvedSegment;
18
28
  };
19
29
  export interface SegmentResolutionDeps<TEnv = any> {
20
30
  wrapLoaderPromise: <T>(promise: Promise<T>, entry: EntryData, segmentId: string, pathname: string, errorContext?: {
@@ -32,7 +32,7 @@ export declare function buildFullPayload(m: MatchResult, ctx: HandlerContext<any
32
32
  * visitor's URL. Any other render that shows the visitor's URL marks
33
33
  * `_payloadVisitorLocation`, and the document cache does not store it.
34
34
  */
35
- export declare function renderedLocation(reqCtx: Pick<RequestContext<any>, "_variables" | "_shellCaptureRun" | "_shellCaptureForVisitor" | "_documentCacheRender" | "_payloadVisitorLocation" | "res"> | undefined, url: URL): URL;
35
+ export declare function renderedLocation(reqCtx: Pick<RequestContext<any>, "_variables" | "_shellCaptureState" | "_documentCacheRender" | "_payloadVisitorLocation" | "res"> | undefined, url: URL): URL;
36
36
  /**
37
37
  * A payload's `pathname` (renderedLocation) and, when middleware rewrote the
38
38
  * request, `rewriteTarget`: the path and search the route rendered (the
@@ -63,4 +63,4 @@ export declare function payloadLocation(reqCtx: Parameters<typeof renderedLocati
63
63
  * default it marks `_payloadVisitorTheme`, and the document cache does not
64
64
  * store the response.
65
65
  */
66
- export declare function payloadInitialTheme(reqCtx: Pick<RequestContext<any>, "_themeConfig" | "_shellCaptureRun" | "_readTheme" | "_documentCacheRender" | "_payloadVisitorTheme" | "res">): Theme | undefined;
66
+ export declare function payloadInitialTheme(reqCtx: Pick<RequestContext<any>, "_themeConfig" | "_shellCaptureState" | "_readTheme" | "_documentCacheRender" | "_payloadVisitorTheme" | "res">): Theme | undefined;
@@ -6,11 +6,14 @@
6
6
  * RSC rendering) so they can be standalone modules without closure coupling.
7
7
  */
8
8
  import type { RangoInternal } from "../router/router-interfaces.js";
9
- import type { ErrorPhase } from "../types.js";
10
- import type { InvokeOnErrorContext } from "../router/error-handling.js";
11
9
  import type { RSCDependencies, LoadSSRModule } from "./types.js";
12
10
  import type { SSRStreamMode } from "../router/router-options.js";
13
- export interface HandlerContext<TEnv = unknown> {
11
+ import type { RequestStageContext } from "./request-stages.js";
12
+ /**
13
+ * Extends what the request stages (rsc/request-stages.ts) call back into, so
14
+ * the handler hands this one bundle to them as well.
15
+ */
16
+ export interface HandlerContext<TEnv = unknown> extends RequestStageContext<TEnv> {
14
17
  router: RangoInternal<TEnv, any>;
15
18
  /**
16
19
  * The router's DOCUMENT version (router-versions.ts): payload metadata, the
@@ -26,9 +29,6 @@ export interface HandlerContext<TEnv = unknown> {
26
29
  decodeAction: RSCDependencies["decodeAction"];
27
30
  decodeFormState: RSCDependencies["decodeFormState"];
28
31
  loadSSRModule: LoadSSRModule;
29
- callOnError: (error: unknown, phase: ErrorPhase, context: InvokeOnErrorContext<TEnv>) => void;
30
- getRequiredRouteMap: () => Record<string, string>;
31
- createRedirectFlightResponse: (redirectUrl: string, locationState?: Record<string, unknown>, external?: boolean) => Response;
32
32
  /**
33
33
  * Resolve the SSR stream mode for a given request.
34
34
  * Returns "stream" when no resolveStreaming callback is configured.
@@ -1,10 +1,6 @@
1
1
  /**
2
- * Shared serialization for `json()` response-route results.
3
- *
4
- * Kept in its own lightweight module (depends only on `errors.js`) so the
5
- * `dispatch()` testing primitive can import it WITHOUT dragging in
6
- * `response-route-handler.ts`'s heavy runtime graph, which transitively reaches
7
- * a Vite virtual module and breaks a plain (non-Vite) vitest import.
2
+ * Serialization for `json()` response-route results (depends only on
3
+ * `errors.js`).
8
4
  */
9
5
  /**
10
6
  * Serialize a `json()` response-route result, rejecting a nested unresolved
@@ -13,8 +9,8 @@
13
9
  * the RSC pipeline awaits nested promises but this path does not. Throwing
14
10
  * `RESPONSE_NOT_SERIALIZABLE` makes the failure loud.
15
11
  *
16
- * Shared by the production response-route handler and the `dispatch()` testing
17
- * primitive so a `dispatch` json test of a forgotten await fails exactly where
18
- * production 500s, instead of going green.
12
+ * The `dispatch()` testing primitive runs the same response-route handler, so
13
+ * a `dispatch` json test of a forgotten await fails exactly where production
14
+ * 500s, instead of going green.
19
15
  */
20
16
  export declare function stringifyJsonRouteResult(result: unknown): string;
@@ -0,0 +1,203 @@
1
+ /**
2
+ * Request stages
3
+ *
4
+ * The stages a request runs through before and after rendering: classify,
5
+ * guard, the global middleware passes, the response route, and the
6
+ * response's finalization. The RSC handler (rsc/handler.ts createRSCHandler)
7
+ * runs them all around its Flight executor. The dispatch testing primitive
8
+ * (testing/dispatch.ts) runs classify, the terminal plans, the passes, the
9
+ * response route and the finalization, and throws where a plan would render
10
+ * a component. Sharing them keeps dispatch's responses identical to
11
+ * production's; a hand-kept mirror drifted once (#1128).
12
+ *
13
+ * No import of @vitejs/plugin-rsc on this graph: dispatch loads it in a
14
+ * plain Vitest project, where plugin-rsc's entries cannot load (they import
15
+ * Vite virtuals). testing/__tests__/testing-module-graph.test.ts pins it.
16
+ */
17
+ import type { MiddlewareEntry } from "../router/middleware-types.js";
18
+ import { type RequestContext } from "../server/request-context.js";
19
+ import { type RewritePassesOptions, type RewritePassesResult } from "./rewrite-passes.js";
20
+ import { type ResponseRouteMatch } from "./response-route-handler.js";
21
+ import type { ErrorPhase } from "../types.js";
22
+ import type { OnErrorCallback } from "../types/error-types.js";
23
+ import { type InvokeOnErrorContext } from "../router/error-handling.js";
24
+ import type { OriginCheckPhase } from "./origin-guard.js";
25
+ import { type OnTimeoutCallback, type ResolvedTimeouts, type TimeoutPhase } from "../router/timeout.js";
26
+ import { type TelemetrySink } from "../router/telemetry.js";
27
+ import { type ClassifyRequestDeps, type ExecutableRequestPlan, type RequestPlan, type ResponseRoutePlan } from "../router/request-classification.js";
28
+ /**
29
+ * The router members the stages read. The handler's `RangoInternal` carries
30
+ * them; dispatch reads them off the router a test passes.
31
+ */
32
+ export interface StageRouter<TEnv = unknown> {
33
+ readonly basename: string | undefined;
34
+ readonly middleware: MiddlewareEntry<TEnv>[];
35
+ readonly onError?: OnErrorCallback<TEnv>;
36
+ readonly telemetry?: TelemetrySink;
37
+ readonly timeouts?: ResolvedTimeouts;
38
+ readonly onTimeout?: OnTimeoutCallback<TEnv>;
39
+ }
40
+ /** Report an error through the router's onError. */
41
+ export type ReportError<TEnv = unknown> = (error: unknown, phase: ErrorPhase, context: InvokeOnErrorContext<TEnv>) => void;
42
+ /**
43
+ * What the stages call back into. The handler's context bundle
44
+ * (rsc/handler-context.ts HandlerContext) extends it.
45
+ */
46
+ export interface RequestStageContext<TEnv = unknown> {
47
+ router: StageRouter<TEnv>;
48
+ callOnError: ReportError<TEnv>;
49
+ getRequiredRouteMap: () => Record<string, string>;
50
+ /**
51
+ * The redirect a partial or action request receives: a Flight payload in
52
+ * the handler (fetch() would follow a raw 3xx to HTML). dispatch has no
53
+ * Flight runtime and answers 204 + X-RSC-Redirect.
54
+ */
55
+ createRedirectFlightResponse: (redirectUrl: string, locationState?: Record<string, unknown>, external?: boolean) => Response;
56
+ /**
57
+ * Reports a response-route handler's own throw; absent, it goes to
58
+ * callOnError with phase "handler". dispatch passes a no-op: it does not
59
+ * report that throw (its documented boundary, testing/dispatch.ts).
60
+ */
61
+ reportResponseRouteError?: (error: unknown, context: InvokeOnErrorContext<TEnv>) => void;
62
+ }
63
+ /** What classify and the terminal plans read beyond the stage context. */
64
+ export interface ClassifyContext<TEnv = unknown> {
65
+ router: {
66
+ readonly id: string;
67
+ readonly findMatch: ClassifyRequestDeps<TEnv>["findMatch"];
68
+ };
69
+ /** The router's DOCUMENT version: the `_rsc_v` reload check. */
70
+ version: string;
71
+ }
72
+ /**
73
+ * Per-request error reporter that deduplicates via the ALS request context.
74
+ *
75
+ * Uses the same _reportedErrors WeakSet as the router layer so errors
76
+ * that propagate across layers are only reported once per request.
77
+ */
78
+ export declare function createErrorReporter<TEnv>(router: {
79
+ readonly onError?: OnErrorCallback<TEnv>;
80
+ }): ReportError<TEnv>;
81
+ /**
82
+ * Wire background error reporting so "use cache" and other subsystems can
83
+ * surface non-fatal errors through the router's onError callback.
84
+ */
85
+ export declare function reportBackgroundErrors<TEnv>(reqCtx: RequestContext<TEnv>, request: Request, url: URL, callOnError: ReportError<TEnv>): void;
86
+ /**
87
+ * Classify a request into its plan. classifyRequest throws
88
+ * RouteNotFoundError for an unknown route; that falls through to a
89
+ * full-render plan with no matched route, so the render path renders the
90
+ * 404 page (match()/matchPartial() re-throw and the render's catch renders
91
+ * it).
92
+ */
93
+ export declare function classify<TEnv>(request: Request, url: URL, ctx: ClassifyContext<TEnv>): Promise<RequestPlan<TEnv>>;
94
+ /** The plan classify answers an unknown route with (the render path's 404). */
95
+ export declare function isUnmatchedPlan(plan: RequestPlan<any>): boolean;
96
+ /**
97
+ * Record a plan's route on the request context: its params and name, and the
98
+ * classified snapshot match()/matchPartial() reuse instead of resolving the
99
+ * route again. Runs inside the global chain, so global middleware sees the
100
+ * route after next(). A redirect has none.
101
+ */
102
+ export declare function recordPlanRoute<TEnv>(plan: ExecutableRequestPlan<TEnv>): void;
103
+ /**
104
+ * The checks between classification and execution that need no await.
105
+ * Returns the response of a terminal plan (a partial request's redirect, a
106
+ * version or app-switch reload), null to go on. Throws for a rewritten
107
+ * action whose target is not a page route.
108
+ *
109
+ * Synchronous, and the origin guard is a separate step: the caller awaits
110
+ * checkRequestOrigin only for the modes ORIGIN_CHECK_PHASE_BY_MODE gates, so
111
+ * a full, partial or response plan reaches execution without an added
112
+ * microtask (rsc/__tests__/request-microtasks.rsc-test.tsx).
113
+ */
114
+ export declare function terminalPlanResponse<TEnv>(plan: RequestPlan<TEnv>, url: URL, ctx: RequestStageContext<TEnv> & ClassifyContext<TEnv>): Response | null;
115
+ /**
116
+ * The origin guard's rejection: reports it through onError and telemetry,
117
+ * and returns the response checkRequestOrigin rejected the request with. The
118
+ * caller awaits checkRequestOrigin itself, for the modes
119
+ * ORIGIN_CHECK_PHASE_BY_MODE gates (action, loader, PE form), so the guard
120
+ * adds no microtask over that await.
121
+ */
122
+ export declare function originRejectedResponse<TEnv>(rejection: Response, phase: OriginCheckPhase, request: Request, env: TEnv, url: URL, ctx: RequestStageContext<TEnv>): Response;
123
+ export interface RequestPassesOptions<TEnv> {
124
+ ctx: RequestStageContext<TEnv>;
125
+ reqCtx: RequestContext<TEnv>;
126
+ /** The visitor's request and raw URL: the first pass. */
127
+ request: Request;
128
+ url: URL;
129
+ env: TEnv;
130
+ variables: Record<string, any>;
131
+ /** The visitor's global middleware, when the caller matched it already. */
132
+ firstPassMiddleware?: Array<{
133
+ entry: MiddlewareEntry<TEnv>;
134
+ params: Record<string, string>;
135
+ }>;
136
+ /** Runs before a pass's global chain; dispatch matches the pass there. */
137
+ beforePass?: (request: Request, url: URL, index: number) => Promise<void>;
138
+ /** The core handler a pass's global chain wraps. */
139
+ core: (request: Request, url: URL) => Promise<Response>;
140
+ onHop?: RewritePassesOptions["onHop"];
141
+ refuse?: RewritePassesOptions["refuse"];
142
+ }
143
+ export interface RequestPassesResult extends RewritePassesResult {
144
+ /** Whether the last pass ran a global middleware chain. */
145
+ hasMiddleware: boolean;
146
+ }
147
+ /**
148
+ * One pass per URL: the global middleware chain matched on the pass's path,
149
+ * wrapping the core handler. A `throw rewrite()` from global or route
150
+ * middleware unwinds the pass, and the next one runs the same request as
151
+ * the target from the top, as a direct visit would (rsc/rewrite-passes.ts).
152
+ */
153
+ export declare function runRequestPasses<TEnv>(opts: RequestPassesOptions<TEnv>): Promise<RequestPassesResult>;
154
+ /**
155
+ * The flat match handleResponseRoute takes, with params at the top level,
156
+ * built from a response-route plan.
157
+ */
158
+ export declare function responseRouteMatch(plan: ResponseRoutePlan<any>): ResponseRouteMatch;
159
+ export interface ServeResponseRouteOptions<TEnv> {
160
+ match: ResponseRouteMatch;
161
+ /** The matched route's key, for the timeout report. */
162
+ routeKey: string | undefined;
163
+ /** The pass's request, raw URL and env. */
164
+ request: Request;
165
+ url: URL;
166
+ env: TEnv;
167
+ variables: Record<string, any>;
168
+ /**
169
+ * Receives the handler's work when the deadline wins. The handler leaves
170
+ * it running; dispatch cancels its body.
171
+ */
172
+ abandon?: (work: Promise<Response>) => void;
173
+ }
174
+ /**
175
+ * A response route: its handler (rsc/response-route-handler.ts) under the
176
+ * renderStartMs deadline, which starts here, inside the global chain, so
177
+ * global middleware time never counts toward it.
178
+ */
179
+ export declare function serveResponseRoute<TEnv>(ctx: RequestStageContext<TEnv>, opts: ServeResponseRouteOptions<TEnv>): Promise<Response>;
180
+ /**
181
+ * Handle a timeout by reporting the error, emitting telemetry,
182
+ * and returning either the custom onTimeout response or a default 504.
183
+ */
184
+ export declare function timeoutResponse<TEnv>(ctx: RequestStageContext<TEnv>, request: Request, env: TEnv, url: URL, phase: TimeoutPhase, durationMs: number, routeKey?: string, actionId?: string): Promise<Response>;
185
+ export interface FinalizeRequestOptions<TEnv> {
186
+ ctx: RequestStageContext<TEnv>;
187
+ reqCtx: RequestContext<TEnv>;
188
+ /** The visitor's request, raw URL and env. */
189
+ request: Request;
190
+ url: URL;
191
+ env: TEnv;
192
+ /** runRequestPasses' result. */
193
+ hasMiddleware: boolean;
194
+ rewrittenTo?: string;
195
+ /** Runs on the response before the open-redirect guard. */
196
+ beforeGuard?: (response: Response) => void;
197
+ }
198
+ /**
199
+ * The response the global chain returned, made ready to leave: a partial or
200
+ * action request's redirect converted, onResponse callbacks drained, the
201
+ * rewrite header, the open-redirect guard and the stream-idle watchdog.
202
+ */
203
+ export declare function finalizeRequestResponse<TEnv>(downstream: Response, opts: FinalizeRequestOptions<TEnv>): Response;