@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
@@ -5,20 +5,11 @@ export {
5
5
  buildLoaderErrorContext,
6
6
  } from "./segment-resolution/helpers.js";
7
7
  export {
8
- resolveLoaders,
9
- type ResolveSegmentOptions,
8
+ resolveLoadersOnly,
9
+ buildEntryRevalidateMap,
10
+ resolveParallelSegments,
11
+ resolveEntryHandler,
10
12
  resolveSegment,
11
13
  resolveOrphanLayout,
12
- resolveParallelEntry,
13
14
  resolveAllSegments,
14
- resolveLoadersOnly,
15
- } from "./segment-resolution/fresh.js";
16
- export {
17
- resolveLoadersOnlyWithRevalidation,
18
- buildEntryRevalidateMap,
19
- resolveParallelSegmentsWithRevalidation,
20
- resolveEntryHandlerWithRevalidation,
21
- resolveSegmentWithRevalidation,
22
- resolveOrphanLayoutWithRevalidation,
23
- resolveAllSegmentsWithRevalidation,
24
15
  } from "./segment-resolution/revalidation.js";
@@ -1,19 +1,14 @@
1
- import type { EntryData, InterceptEntry } from "../server/context";
2
- import type {
3
- HandlerContext,
4
- ResolvedSegment,
5
- ShouldRevalidateFn,
6
- } from "../types";
7
1
  import type { SegmentResolutionDeps } from "./types.js";
8
- import type { ResolveSegmentOptions } from "./segment-resolution.js";
9
- import type { RevalidationContext } from "./router-context.js";
2
+ import type { RouterContext } from "./router-context.js";
3
+ import type {
4
+ ResolutionPass,
5
+ ResolutionPassInput,
6
+ } from "./segment-resolution/resolution-pass.js";
10
7
 
11
8
  import {
12
- resolveAllSegments as _resolveAllSegments,
13
9
  resolveLoadersOnly as _resolveLoadersOnly,
14
- resolveLoadersOnlyWithRevalidation as _resolveLoadersOnlyWithRevalidation,
15
10
  buildEntryRevalidateMap as _buildEntryRevalidateMap,
16
- resolveAllSegmentsWithRevalidation as _resolveAllSegmentsWithRevalidation,
11
+ resolveAllSegments as _resolveAllSegments,
17
12
  } from "./segment-resolution.js";
18
13
 
19
14
  import {
@@ -22,270 +17,57 @@ import {
22
17
  resolveInterceptLoadersOnly as _resolveInterceptLoadersOnly,
23
18
  } from "./intercept-resolution.js";
24
19
 
25
- import type { InterceptSelectorContext } from "../server/context";
26
-
27
- export interface SegmentWrappers<TEnv = any> {
28
- resolveAllSegments: (
29
- entries: EntryData[],
30
- routeKey: string,
31
- params: Record<string, string>,
32
- context: HandlerContext<any, TEnv>,
33
- loaderPromises: Map<string, Promise<any>>,
34
- options?: ResolveSegmentOptions,
35
- ) => Promise<ResolvedSegment[]>;
36
- resolveLoadersOnly: (
37
- entries: EntryData[],
38
- context: HandlerContext<any, TEnv>,
39
- ) => Promise<ResolvedSegment[]>;
40
- resolveLoadersOnlyWithRevalidation: (
41
- entries: EntryData[],
42
- context: HandlerContext<any, TEnv>,
43
- clientSegmentIds: Set<string>,
44
- prevParams: Record<string, string>,
45
- request: Request,
46
- prevUrl: URL,
47
- nextUrl: URL,
48
- routeKey: string,
49
- actionContext?: {
50
- actionId?: string;
51
- actionUrl?: URL;
52
- actionResult?: any;
53
- formData?: FormData;
54
- },
55
- stale?: boolean,
56
- ) => Promise<{ segments: ResolvedSegment[]; matchedIds: string[] }>;
57
- buildEntryRevalidateMap: (
58
- entries: EntryData[],
59
- ) => Map<
60
- string,
61
- { entry: EntryData; revalidate: ShouldRevalidateFn<any, any>[] }
62
- >;
63
- resolveAllSegmentsWithRevalidation: (
64
- entries: EntryData[],
65
- routeKey: string,
66
- params: Record<string, string>,
67
- context: HandlerContext<any, TEnv>,
68
- clientSegmentSet: Set<string>,
69
- prevParams: Record<string, string>,
70
- request: Request,
71
- prevUrl: URL,
72
- nextUrl: URL,
73
- actionContext:
74
- | {
75
- actionId?: string;
76
- actionUrl?: URL;
77
- actionResult?: any;
78
- formData?: FormData;
79
- }
80
- | undefined,
81
- interceptResult: { intercept: InterceptEntry; entry: EntryData } | null,
82
- localRouteName: string,
83
- pathname: string,
84
- stale?: boolean,
85
- chain?: readonly EntryData[],
86
- ) => Promise<{ segments: ResolvedSegment[]; matchedIds: string[] }>;
87
- findInterceptForRoute: (
88
- targetRouteKey: string,
89
- fromEntry: EntryData | null,
90
- selectorContext?: InterceptSelectorContext | null,
91
- isAction?: boolean,
92
- ) => { intercept: InterceptEntry; entry: EntryData } | null;
93
- resolveInterceptEntry: (
94
- interceptEntry: InterceptEntry,
95
- parentEntry: EntryData,
96
- params: Record<string, string>,
97
- context: HandlerContext<any, TEnv>,
98
- belongsToRoute?: boolean,
99
- revalidationContext?: any,
100
- options?: { background?: boolean },
101
- ) => Promise<ResolvedSegment[]>;
102
- resolveInterceptLoadersOnly: (
103
- interceptEntry: InterceptEntry,
104
- parentEntry: EntryData,
105
- context: HandlerContext<any, TEnv>,
106
- belongsToRoute: boolean,
107
- revalidationContext: RevalidationContext,
108
- ) => Promise<ResolvedSegment[]>;
109
- }
20
+ /** The resolvers RouterContext exposes, with the router's deps bound. */
21
+ export type SegmentWrappers<TEnv = any> = Pick<
22
+ RouterContext<TEnv>,
23
+ "resolveAllSegments" | "resolveInterceptEntry"
24
+ > &
25
+ Required<
26
+ Pick<
27
+ RouterContext<TEnv>,
28
+ | "resolveLoadersOnly"
29
+ | "buildEntryRevalidateMap"
30
+ | "resolveInterceptLoadersOnly"
31
+ >
32
+ > & {
33
+ /** Its own signature: a null selector context, isAction defaulting to false. */
34
+ findInterceptForRoute: typeof _findInterceptForRoute;
35
+ };
110
36
 
111
37
  /**
112
- * Create thin wrapper functions that bind segmentDeps to extracted
113
- * segment resolution and intercept resolution functions.
114
- *
115
- * These maintain the same signatures as the original inline functions
116
- * so that RouterContext and call sites don't need to change.
38
+ * Bind the router's segment deps into the extracted segment and intercept
39
+ * resolvers. Each gets a ResolutionPass: the caller's request-side input with
40
+ * the deps added here, once per call.
117
41
  */
118
42
  export function createSegmentWrappers<TEnv = any>(
119
- segmentDeps: SegmentResolutionDeps<TEnv>,
43
+ deps: SegmentResolutionDeps<TEnv>,
120
44
  ): SegmentWrappers<TEnv> {
121
- function resolveAllSegments(
122
- entries: EntryData[],
123
- routeKey: string,
124
- params: Record<string, string>,
125
- context: HandlerContext<any, TEnv>,
126
- loaderPromises: Map<string, Promise<any>>,
127
- options?: ResolveSegmentOptions,
128
- ): ReturnType<typeof _resolveAllSegments> {
129
- return _resolveAllSegments(
130
- entries,
131
- routeKey,
132
- params,
133
- context,
134
- loaderPromises,
135
- segmentDeps,
136
- options,
137
- );
138
- }
139
-
140
- function resolveLoadersOnly(
141
- entries: EntryData[],
142
- context: HandlerContext<any, TEnv>,
143
- ): ReturnType<typeof _resolveLoadersOnly> {
144
- return _resolveLoadersOnly(entries, context, segmentDeps);
145
- }
146
-
147
- function resolveLoadersOnlyWithRevalidation(
148
- entries: EntryData[],
149
- context: HandlerContext<any, TEnv>,
150
- clientSegmentIds: Set<string>,
151
- prevParams: Record<string, string>,
152
- request: Request,
153
- prevUrl: URL,
154
- nextUrl: URL,
155
- routeKey: string,
156
- actionContext?: {
157
- actionId?: string;
158
- actionUrl?: URL;
159
- actionResult?: any;
160
- formData?: FormData;
161
- },
162
- stale?: boolean,
163
- ): ReturnType<typeof _resolveLoadersOnlyWithRevalidation> {
164
- return _resolveLoadersOnlyWithRevalidation(
165
- entries,
166
- context,
167
- clientSegmentIds,
168
- prevParams,
169
- request,
170
- prevUrl,
171
- nextUrl,
172
- routeKey,
173
- segmentDeps,
174
- actionContext,
175
- stale,
176
- );
177
- }
178
-
179
- function buildEntryRevalidateMap(
180
- entries: EntryData[],
181
- ): ReturnType<typeof _buildEntryRevalidateMap> {
182
- return _buildEntryRevalidateMap(entries);
183
- }
184
-
185
- function resolveAllSegmentsWithRevalidation(
186
- entries: EntryData[],
187
- routeKey: string,
188
- params: Record<string, string>,
189
- context: HandlerContext<any, TEnv>,
190
- clientSegmentSet: Set<string>,
191
- prevParams: Record<string, string>,
192
- request: Request,
193
- prevUrl: URL,
194
- nextUrl: URL,
195
- actionContext:
196
- | {
197
- actionId?: string;
198
- actionUrl?: URL;
199
- actionResult?: any;
200
- formData?: FormData;
201
- }
202
- | undefined,
203
- interceptResult: { intercept: InterceptEntry; entry: EntryData } | null,
204
- localRouteName: string,
205
- pathname: string,
206
- stale?: boolean,
207
- chain?: readonly EntryData[],
208
- ): ReturnType<typeof _resolveAllSegmentsWithRevalidation> {
209
- return _resolveAllSegmentsWithRevalidation(
210
- entries,
211
- routeKey,
212
- params,
213
- context,
214
- clientSegmentSet,
215
- prevParams,
216
- request,
217
- prevUrl,
218
- nextUrl,
219
- actionContext,
220
- interceptResult,
221
- localRouteName,
222
- pathname,
223
- segmentDeps,
224
- stale,
225
- chain,
226
- );
227
- }
228
-
229
- function findInterceptForRoute(
230
- targetRouteKey: string,
231
- fromEntry: EntryData | null,
232
- selectorContext: InterceptSelectorContext | null = null,
233
- isAction: boolean = false,
234
- ): ReturnType<typeof _findInterceptForRoute> {
235
- return _findInterceptForRoute(
236
- targetRouteKey,
237
- fromEntry,
238
- selectorContext,
239
- isAction,
240
- );
241
- }
242
-
243
- function resolveInterceptEntry(
244
- interceptEntry: InterceptEntry,
245
- parentEntry: EntryData,
246
- params: Record<string, string>,
247
- context: HandlerContext<any, TEnv>,
248
- belongsToRoute: boolean = true,
249
- revalidationContext?: any,
250
- options?: { background?: boolean },
251
- ): ReturnType<typeof _resolveInterceptEntry> {
252
- return _resolveInterceptEntry(
253
- interceptEntry,
254
- parentEntry,
255
- params,
256
- context,
257
- belongsToRoute,
258
- segmentDeps,
259
- revalidationContext,
260
- options,
261
- );
262
- }
263
-
264
- function resolveInterceptLoadersOnly(
265
- interceptEntry: InterceptEntry,
266
- parentEntry: EntryData,
267
- context: HandlerContext<any, TEnv>,
268
- belongsToRoute: boolean,
269
- revalidationContext: RevalidationContext,
270
- ): ReturnType<typeof _resolveInterceptLoadersOnly> {
271
- return _resolveInterceptLoadersOnly(
272
- interceptEntry,
273
- parentEntry,
274
- context,
275
- belongsToRoute,
276
- segmentDeps,
277
- revalidationContext,
278
- );
279
- }
45
+ const pass = (input: ResolutionPassInput<TEnv>): ResolutionPass<TEnv> => ({
46
+ ...input,
47
+ deps,
48
+ });
280
49
 
281
50
  return {
282
- resolveAllSegments: resolveAllSegments,
283
- resolveLoadersOnly: resolveLoadersOnly,
284
- resolveLoadersOnlyWithRevalidation: resolveLoadersOnlyWithRevalidation,
285
- buildEntryRevalidateMap: buildEntryRevalidateMap,
286
- resolveAllSegmentsWithRevalidation: resolveAllSegmentsWithRevalidation,
287
- findInterceptForRoute: findInterceptForRoute,
288
- resolveInterceptEntry: resolveInterceptEntry,
289
- resolveInterceptLoadersOnly: resolveInterceptLoadersOnly,
51
+ resolveLoadersOnly: (input, entries, walk) =>
52
+ _resolveLoadersOnly(pass(input), entries, walk),
53
+ buildEntryRevalidateMap: _buildEntryRevalidateMap,
54
+ resolveAllSegments: (input, entries, walk) =>
55
+ _resolveAllSegments(pass(input), entries, walk),
56
+ findInterceptForRoute: _findInterceptForRoute,
57
+ resolveInterceptEntry: (input, intercept, entry, belongsToRoute, options) =>
58
+ _resolveInterceptEntry(
59
+ pass(input),
60
+ intercept,
61
+ entry,
62
+ belongsToRoute,
63
+ options,
64
+ ),
65
+ resolveInterceptLoadersOnly: (input, intercept, entry, belongsToRoute) =>
66
+ _resolveInterceptLoadersOnly(
67
+ pass(input),
68
+ intercept,
69
+ entry,
70
+ belongsToRoute,
71
+ ),
290
72
  };
291
73
  }
@@ -317,6 +317,11 @@ export function getRequestId(request: Request): string {
317
317
  return id;
318
318
  }
319
319
 
320
+ /** Make `id` the id getRequestId returns for `request`. */
321
+ export function setRequestId(request: Request, id: string): void {
322
+ requestIds.set(request, id);
323
+ }
324
+
320
325
  /**
321
326
  * Built-in console sink that logs events in a structured format.
322
327
  * Designed as the default sink for development / debugging.
@@ -32,6 +32,16 @@ export type ActionContext = {
32
32
  actionUrl?: URL;
33
33
  actionResult?: any;
34
34
  formData?: FormData;
35
+ /**
36
+ * A thrown action's error segment (matchError), set on the action's
37
+ * revalidation (rsc/server-action.ts matchBoundaryRevalidation). The walk
38
+ * (resolveAllSegments) resolves every entry above the segment's outlet as on
39
+ * a success, emits the segment in the outlet's place and stops, so nothing
40
+ * at or below the outlet runs. The pass skips the prerender store
41
+ * (cache-lookup.ts): the evicted handler is under the cut. No revalidate()
42
+ * predicate sees it.
43
+ */
44
+ boundary?: ResolvedSegment;
35
45
  };
36
46
 
37
47
  export interface SegmentResolutionDeps<TEnv = any> {
package/src/router.ts CHANGED
@@ -546,18 +546,21 @@ export function createRouter<TEnv = any>(
546
546
  },
547
547
  useDefaultErrorBoundary?: boolean,
548
548
  ): Promise<LoaderDataResult<T>> {
549
- const loaderStart = telemetrySink ? performance.now() : 0;
550
- const loaderRequestId = telemetrySink
549
+ // A PPR shell capture sends nothing to the sink: the same switch as match().
550
+ const emitTelemetry =
551
+ !!telemetrySink && !_getRequestContext()?._shellCaptureState?.run;
552
+ const loaderStart = emitTelemetry ? performance.now() : 0;
553
+ const loaderRequestId = emitTelemetry
551
554
  ? errorContext?.request
552
555
  ? getRequestId(errorContext.request)
553
556
  : undefined
554
557
  : undefined;
555
558
  // Derived once here for both the loader.start and loader.end emits (the
556
559
  // loader.error emit uses ctx.loaderName from wrapLoaderWithErrorHandling).
557
- const loaderName = telemetrySink
560
+ const loaderName = emitTelemetry
558
561
  ? segmentId.split(".").pop() || "unknown"
559
562
  : "";
560
- if (telemetrySink) {
563
+ if (emitTelemetry) {
561
564
  safeEmit(telemetry, {
562
565
  type: "loader.start",
563
566
  timestamp: loaderStart,
@@ -591,7 +594,7 @@ export function createRouter<TEnv = any>(
591
594
  handledByBoundary: ctx.handledByBoundary,
592
595
  requestStartTime: errorContext.requestStartTime,
593
596
  });
594
- if (telemetrySink) {
597
+ if (emitTelemetry) {
595
598
  const errorObj =
596
599
  error instanceof Error ? error : new Error(String(error));
597
600
  safeEmit(telemetry, {
@@ -618,7 +621,7 @@ export function createRouter<TEnv = any>(
618
621
  );
619
622
 
620
623
  // Emit loader.end after the promise settles (fire-and-forget)
621
- if (telemetrySink) {
624
+ if (emitTelemetry) {
622
625
  result.then((r) => {
623
626
  safeEmit(telemetry, {
624
627
  type: "loader.end",
@@ -663,11 +666,9 @@ export function createRouter<TEnv = any>(
663
666
 
664
667
  // Create segment resolution wrappers bound to segmentDeps
665
668
  const {
666
- resolveAllSegments,
667
669
  resolveLoadersOnly,
668
- resolveLoadersOnlyWithRevalidation,
669
670
  buildEntryRevalidateMap,
670
- resolveAllSegmentsWithRevalidation,
671
+ resolveAllSegments,
671
672
  findInterceptForRoute,
672
673
  resolveInterceptEntry,
673
674
  resolveInterceptLoadersOnly,
@@ -713,16 +714,14 @@ export function createRouter<TEnv = any>(
713
714
  getMetricsStore,
714
715
  createCacheScope,
715
716
  findInterceptForRoute,
716
- resolveAllSegmentsWithRevalidation,
717
+ resolveAllSegments,
717
718
  resolveInterceptEntry,
718
719
  evaluateRevalidation,
719
720
  getRequestContext,
720
- resolveAllSegments,
721
721
  createHandleStore,
722
722
  buildEntryRevalidateMap,
723
- resolveLoadersOnlyWithRevalidation,
724
- resolveInterceptLoadersOnly,
725
723
  resolveLoadersOnly,
724
+ resolveInterceptLoadersOnly,
726
725
  telemetry: telemetrySink,
727
726
  };
728
727
  }
@@ -61,7 +61,7 @@ export function buildFullPayload(
61
61
  // capture renders from what its record keeps (resolvedHandleStream).
62
62
  handles: resolvedHandleStream(
63
63
  handleStore,
64
- reqCtx._shellCaptureRun === true,
64
+ reqCtx._shellCaptureState?.run === true,
65
65
  ),
66
66
  // Post-handler-barrier pushes (streaming loader ctx.handle() writes)
67
67
  // stream here; the client applies them after hydration. Instantly
@@ -105,8 +105,7 @@ export function renderedLocation(
105
105
  | Pick<
106
106
  RequestContext<any>,
107
107
  | "_variables"
108
- | "_shellCaptureRun"
109
- | "_shellCaptureForVisitor"
108
+ | "_shellCaptureState"
110
109
  | "_documentCacheRender"
111
110
  | "_payloadVisitorLocation"
112
111
  | "res"
@@ -116,7 +115,9 @@ export function renderedLocation(
116
115
  ): URL {
117
116
  if (!reqCtx || !rewriteTrail(reqCtx)) return url;
118
117
  if (rendersForSharedAudience(reqCtx)) {
119
- return reqCtx._shellCaptureForVisitor ? visitorUrl(reqCtx, url) : url;
118
+ return reqCtx._shellCaptureState?.forVisitor
119
+ ? visitorUrl(reqCtx, url)
120
+ : url;
120
121
  }
121
122
  reqCtx._payloadVisitorLocation = true;
122
123
  return visitorUrl(reqCtx, url);
@@ -163,7 +164,7 @@ export function payloadInitialTheme(
163
164
  reqCtx: Pick<
164
165
  RequestContext<any>,
165
166
  | "_themeConfig"
166
- | "_shellCaptureRun"
167
+ | "_shellCaptureState"
167
168
  | "_readTheme"
168
169
  | "_documentCacheRender"
169
170
  | "_payloadVisitorTheme"
@@ -7,12 +7,17 @@
7
7
  */
8
8
 
9
9
  import type { RangoInternal } from "../router/router-interfaces.js";
10
- import type { ErrorPhase } from "../types.js";
11
- import type { InvokeOnErrorContext } from "../router/error-handling.js";
12
10
  import type { RSCDependencies, LoadSSRModule } from "./types.js";
13
11
  import type { SSRStreamMode } from "../router/router-options.js";
12
+ import type { RequestStageContext } from "./request-stages.js";
14
13
 
15
- export interface HandlerContext<TEnv = unknown> {
14
+ /**
15
+ * Extends what the request stages (rsc/request-stages.ts) call back into, so
16
+ * the handler hands this one bundle to them as well.
17
+ */
18
+ export interface HandlerContext<
19
+ TEnv = unknown,
20
+ > extends RequestStageContext<TEnv> {
16
21
  router: RangoInternal<TEnv, any>;
17
22
  /**
18
23
  * The router's DOCUMENT version (router-versions.ts): payload metadata, the
@@ -28,17 +33,6 @@ export interface HandlerContext<TEnv = unknown> {
28
33
  decodeAction: RSCDependencies["decodeAction"];
29
34
  decodeFormState: RSCDependencies["decodeFormState"];
30
35
  loadSSRModule: LoadSSRModule;
31
- callOnError: (
32
- error: unknown,
33
- phase: ErrorPhase,
34
- context: InvokeOnErrorContext<TEnv>,
35
- ) => void;
36
- getRequiredRouteMap: () => Record<string, string>;
37
- createRedirectFlightResponse: (
38
- redirectUrl: string,
39
- locationState?: Record<string, unknown>,
40
- external?: boolean,
41
- ) => Response;
42
36
 
43
37
  /**
44
38
  * Resolve the SSR stream mode for a given request.