@rangojs/router 0.15.1 → 0.17.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 (249) hide show
  1. package/README.md +254 -89
  2. package/dist/testing/vitest.js +252 -0
  3. package/dist/types/browser/navigation-transaction.d.ts +6 -0
  4. package/dist/types/browser/partial-update.d.ts +11 -0
  5. package/dist/types/browser/react/ScrollRestoration.d.ts +6 -6
  6. package/dist/types/browser/rsc-router.d.ts +1 -1
  7. package/dist/types/browser/scroll-restoration.d.ts +7 -0
  8. package/dist/types/cache/cache-exec-scope.d.ts +18 -1
  9. package/dist/types/cache/cache-scope.d.ts +34 -5
  10. package/dist/types/cache/handle-capture.d.ts +41 -3
  11. package/dist/types/cache/handle-snapshot.d.ts +53 -13
  12. package/dist/types/cache/segment-codec.d.ts +10 -3
  13. package/dist/types/cache/taint.d.ts +1 -1
  14. package/dist/types/cache/types.d.ts +15 -3
  15. package/dist/types/client.d.ts +4 -4
  16. package/dist/types/client.rsc.d.ts +4 -5
  17. package/dist/types/components/DefaultDocument.d.ts +5 -2
  18. package/dist/types/context-var.d.ts +6 -5
  19. package/dist/types/escape-script.d.ts +1 -1
  20. package/dist/types/handles/MetaTags.d.ts +5 -4
  21. package/dist/types/handles/Scripts.d.ts +8 -7
  22. package/dist/types/handles/meta.d.ts +2 -2
  23. package/dist/types/handles/script.d.ts +17 -16
  24. package/dist/types/href-client.d.ts +1 -1
  25. package/dist/types/html.d.ts +12 -0
  26. package/dist/types/index.d.ts +1 -1
  27. package/dist/types/index.rsc.d.ts +3 -2
  28. package/dist/types/loader-store.d.ts +52 -0
  29. package/dist/types/reverse.d.ts +36 -4
  30. package/dist/types/route-definition/dsl-helpers.d.ts +3 -3
  31. package/dist/types/route-definition/helpers-types.d.ts +36 -10
  32. package/dist/types/route-definition/resolve-handler-use.d.ts +23 -1
  33. package/dist/types/route-types.d.ts +3 -1
  34. package/dist/types/router/debug-manifest.d.ts +3 -2
  35. package/dist/types/router/error-handling.d.ts +20 -0
  36. package/dist/types/router/handler-context.d.ts +6 -0
  37. package/dist/types/router/match-middleware/background-revalidation.d.ts +46 -5
  38. package/dist/types/router/middleware-types.d.ts +3 -2
  39. package/dist/types/router/router-context.d.ts +3 -1
  40. package/dist/types/router/router-interfaces.d.ts +24 -2
  41. package/dist/types/router/router-options.d.ts +8 -5
  42. package/dist/types/router/segment-resolution/fresh.d.ts +10 -0
  43. package/dist/types/router/segment-resolution/loader-cache.d.ts +37 -1
  44. package/dist/types/router/segment-resolution/loader-mask.d.ts +9 -19
  45. package/dist/types/router/segment-resolution/loader-snapshot.d.ts +3 -3
  46. package/dist/types/router/segment-resolution/mask-nested.d.ts +7 -7
  47. package/dist/types/router/segment-resolution/revalidation.d.ts +6 -2
  48. package/dist/types/router/segment-wrappers.d.ts +1 -1
  49. package/dist/types/rsc/response-route-handler.d.ts +1 -1
  50. package/dist/types/rsc/rsc-rendering.d.ts +1 -2
  51. package/dist/types/rsc/shell-capture-constants.d.ts +8 -0
  52. package/dist/types/rsc/shell-capture.d.ts +5 -4
  53. package/dist/types/rsc/ssr-setup.d.ts +6 -6
  54. package/dist/types/rsc/types.d.ts +10 -0
  55. package/dist/types/server/context.d.ts +33 -3
  56. package/dist/types/server/handle-store.d.ts +26 -2
  57. package/dist/types/server/request-context.d.ts +24 -21
  58. package/dist/types/ssr/index.d.ts +15 -0
  59. package/dist/types/static-handler.d.ts +4 -1
  60. package/dist/types/testing/generated-routes.d.ts +2 -2
  61. package/dist/types/testing/internal/context.d.ts +1 -1
  62. package/dist/types/testing/render-route.d.ts +32 -6
  63. package/dist/types/testing/vitest-stubs/plugin-rsc.d.ts +28 -5
  64. package/dist/types/testing/vitest.d.ts +35 -1
  65. package/dist/types/theme/ThemeScript.d.ts +3 -3
  66. package/dist/types/thenable-status.d.ts +9 -0
  67. package/dist/types/types/cache-types.d.ts +14 -10
  68. package/dist/types/types/handler-context.d.ts +14 -0
  69. package/dist/types/types/loader-types.d.ts +8 -6
  70. package/dist/types/urls/response-types.d.ts +3 -12
  71. package/dist/types/use-loader.d.ts +12 -3
  72. package/dist/types/vite/plugins/use-cache-transform.d.ts +33 -2
  73. package/dist/types/vite/rango.d.ts +1 -1
  74. package/dist/vite/index.js +884 -768
  75. package/package.json +4 -4
  76. package/skills/api-client/SKILL.md +22 -10
  77. package/skills/breadcrumbs/SKILL.md +65 -22
  78. package/skills/bundle-analysis/SKILL.md +22 -22
  79. package/skills/cache-guide/SKILL.md +207 -97
  80. package/skills/caching/SKILL.md +295 -93
  81. package/skills/catalog.json +16 -16
  82. package/skills/client-urls/SKILL.md +53 -31
  83. package/skills/cloudflare/SKILL.md +72 -20
  84. package/skills/cloudflare/references/d1-and-local-dev.md +15 -2
  85. package/skills/cloudflare/references/streaming-and-deploy.md +10 -3
  86. package/skills/cloudflare/references/webhooks-and-crypto.md +9 -2
  87. package/skills/comparison/SKILL.md +5 -0
  88. package/skills/comparison/references/framework-comparison.md +39 -33
  89. package/skills/composability/SKILL.md +38 -29
  90. package/skills/css/SKILL.md +10 -13
  91. package/skills/debug-manifest/SKILL.md +74 -31
  92. package/skills/defer-hydration/SKILL.md +2 -1
  93. package/skills/deployment-caching/SKILL.md +6 -1
  94. package/skills/document-cache/SKILL.md +92 -28
  95. package/skills/fonts/SKILL.md +16 -8
  96. package/skills/handler-use/SKILL.md +53 -17
  97. package/skills/hooks/SKILL.md +28 -20
  98. package/skills/hooks/data.md +43 -1
  99. package/skills/hooks/handle-and-actions.md +31 -16
  100. package/skills/hooks/navigation.md +39 -10
  101. package/skills/hooks/outlets.md +13 -6
  102. package/skills/hooks/state.md +37 -15
  103. package/skills/hooks/urls.md +7 -5
  104. package/skills/host-router/SKILL.md +64 -12
  105. package/skills/i18n/SKILL.md +60 -34
  106. package/skills/intercept/SKILL.md +161 -26
  107. package/skills/layout/SKILL.md +106 -50
  108. package/skills/links/SKILL.md +51 -19
  109. package/skills/loader/SKILL.md +242 -106
  110. package/skills/middleware/SKILL.md +119 -23
  111. package/skills/migrate-nextjs/SKILL.md +100 -45
  112. package/skills/migrate-nextjs/backend-host-swap.md +5 -2
  113. package/skills/migrate-react-router/SKILL.md +49 -38
  114. package/skills/migrate-react-router/component-migration.md +25 -6
  115. package/skills/migrate-react-router/data-and-actions.md +18 -5
  116. package/skills/migrate-react-router/route-mapping.md +12 -6
  117. package/skills/mime-routes/SKILL.md +12 -7
  118. package/skills/observability/SKILL.md +28 -14
  119. package/skills/parallel/SKILL.md +75 -39
  120. package/skills/ppr/SKILL.md +345 -150
  121. package/skills/prerender/SKILL.md +189 -100
  122. package/skills/rango/SKILL.md +65 -34
  123. package/skills/react-compiler/SKILL.md +6 -5
  124. package/skills/response-routes/SKILL.md +133 -25
  125. package/skills/route/SKILL.md +165 -60
  126. package/skills/router-setup/SKILL.md +418 -240
  127. package/skills/scripts/SKILL.md +31 -20
  128. package/skills/server-actions/SKILL.md +220 -59
  129. package/skills/shell-manifest/SKILL.md +12 -7
  130. package/skills/streams-and-websockets/SKILL.md +32 -14
  131. package/skills/tailwind/SKILL.md +37 -33
  132. package/skills/testing/SKILL.md +68 -32
  133. package/skills/testing/cache-prerender.md +55 -29
  134. package/skills/testing/client-components.md +59 -6
  135. package/skills/testing/e2e-parity.md +12 -2
  136. package/skills/testing/flight.md +19 -11
  137. package/skills/testing/handles.md +8 -5
  138. package/skills/testing/loader.md +8 -5
  139. package/skills/testing/middleware.md +8 -3
  140. package/skills/testing/predicates.md +120 -0
  141. package/skills/testing/render-handler.md +70 -22
  142. package/skills/testing/response-routes.md +11 -4
  143. package/skills/testing/reverse-and-types.md +20 -14
  144. package/skills/testing/server-actions.md +12 -3
  145. package/skills/testing/server-tree.md +9 -0
  146. package/skills/testing/setup.md +9 -5
  147. package/skills/theme/SKILL.md +106 -29
  148. package/skills/typesafety/SKILL.md +20 -9
  149. package/skills/typesafety/env-and-bindings.md +126 -47
  150. package/skills/typesafety/generated-files-and-cli.md +26 -14
  151. package/skills/typesafety/params-and-search.md +44 -19
  152. package/skills/typesafety/route-types.md +50 -14
  153. package/skills/use-cache/SKILL.md +200 -82
  154. package/skills/vercel/SKILL.md +21 -11
  155. package/skills/view-transitions/SKILL.md +41 -20
  156. package/src/__augment-tests__/augmented.check.ts +26 -1
  157. package/src/browser/index.ts +2 -2
  158. package/src/browser/navigation-bridge.ts +3 -4
  159. package/src/browser/navigation-transaction.ts +22 -2
  160. package/src/browser/partial-update.ts +75 -80
  161. package/src/browser/react/ScrollRestoration.tsx +6 -6
  162. package/src/browser/rsc-router.tsx +1 -1
  163. package/src/browser/scroll-restoration.ts +53 -6
  164. package/src/cache/cache-exec-scope.ts +37 -4
  165. package/src/cache/cache-key-utils.ts +1 -6
  166. package/src/cache/cache-runtime.ts +230 -61
  167. package/src/cache/cache-scope.ts +76 -12
  168. package/src/cache/document-cache.ts +15 -0
  169. package/src/cache/handle-capture.ts +90 -10
  170. package/src/cache/handle-snapshot.ts +132 -28
  171. package/src/cache/segment-codec.ts +26 -7
  172. package/src/cache/tag-invalidation.ts +4 -3
  173. package/src/cache/taint.ts +1 -1
  174. package/src/cache/types.ts +16 -3
  175. package/src/client.rsc.tsx +10 -9
  176. package/src/client.tsx +5 -4
  177. package/src/components/DefaultDocument.tsx +7 -2
  178. package/src/context-var.ts +6 -5
  179. package/src/escape-script.ts +1 -1
  180. package/src/handles/MetaTags.tsx +13 -11
  181. package/src/handles/Scripts.tsx +11 -10
  182. package/src/handles/meta.ts +2 -2
  183. package/src/handles/script.ts +17 -16
  184. package/src/href-client.ts +1 -1
  185. package/src/html.ts +12 -0
  186. package/src/index.rsc.ts +5 -0
  187. package/src/index.ts +1 -0
  188. package/src/loader-store.ts +106 -0
  189. package/src/prerender/build-shell-capture.ts +8 -11
  190. package/src/reverse.ts +44 -4
  191. package/src/route-definition/dsl-helpers.ts +134 -42
  192. package/src/route-definition/helpers-types.ts +36 -10
  193. package/src/route-definition/resolve-handler-use.ts +121 -6
  194. package/src/route-types.ts +2 -3
  195. package/src/router/debug-manifest.ts +10 -2
  196. package/src/router/error-handling.ts +51 -15
  197. package/src/router/handler-context.ts +34 -25
  198. package/src/router/intercept-resolution.ts +125 -39
  199. package/src/router/loader-resolution.ts +56 -11
  200. package/src/router/match-api.ts +12 -17
  201. package/src/router/match-middleware/background-revalidation.ts +161 -96
  202. package/src/router/match-middleware/cache-lookup.ts +93 -10
  203. package/src/router/match-middleware/cache-store.ts +17 -90
  204. package/src/router/middleware-types.ts +3 -5
  205. package/src/router/middleware.ts +52 -9
  206. package/src/router/prerender-match.ts +53 -19
  207. package/src/router/route-snapshot.ts +11 -1
  208. package/src/router/router-context.ts +2 -0
  209. package/src/router/router-interfaces.ts +25 -2
  210. package/src/router/router-options.ts +8 -5
  211. package/src/router/segment-resolution/fresh.ts +44 -12
  212. package/src/router/segment-resolution/loader-cache.ts +205 -45
  213. package/src/router/segment-resolution/loader-mask.ts +12 -22
  214. package/src/router/segment-resolution/loader-snapshot.ts +6 -6
  215. package/src/router/segment-resolution/mask-nested.ts +7 -7
  216. package/src/router/segment-resolution/revalidation.ts +34 -6
  217. package/src/router/segment-wrappers.ts +4 -0
  218. package/src/rsc/render-pipeline.ts +3 -0
  219. package/src/rsc/response-route-handler.ts +11 -3
  220. package/src/rsc/rsc-rendering.ts +8 -45
  221. package/src/rsc/shell-capture-constants.ts +13 -0
  222. package/src/rsc/shell-capture.ts +111 -90
  223. package/src/rsc/ssr-setup.ts +14 -8
  224. package/src/rsc/types.ts +11 -0
  225. package/src/server/context.ts +88 -11
  226. package/src/server/cookie-store.ts +5 -4
  227. package/src/server/handle-store.ts +232 -7
  228. package/src/server/request-context.ts +35 -30
  229. package/src/ssr/index.tsx +40 -7
  230. package/src/ssr-suspension-warning.ts +2 -13
  231. package/src/static-handler.ts +4 -1
  232. package/src/testing/flight-runtime.d.ts +21 -0
  233. package/src/testing/generated-routes.ts +2 -2
  234. package/src/testing/internal/context.ts +1 -1
  235. package/src/testing/internal/flight-client-globals.ts +7 -5
  236. package/src/testing/render-route.tsx +85 -24
  237. package/src/testing/run-loader.ts +5 -1
  238. package/src/testing/vitest-stubs/plugin-rsc.ts +123 -20
  239. package/src/testing/vitest.ts +62 -1
  240. package/src/theme/ThemeProvider.tsx +14 -12
  241. package/src/theme/ThemeScript.tsx +3 -3
  242. package/src/thenable-status.ts +16 -0
  243. package/src/types/cache-types.ts +14 -10
  244. package/src/types/handler-context.ts +14 -0
  245. package/src/types/loader-types.ts +8 -6
  246. package/src/urls/response-types.ts +3 -23
  247. package/src/use-loader.tsx +24 -4
  248. package/src/vite/plugins/use-cache-transform.ts +118 -74
  249. package/src/vite/rango.ts +7 -3
@@ -102,10 +102,10 @@ export type RouteHelpers<T extends RouteDefinition, TEnv> = {
102
102
  * intercept("@modal", "card", () => <CardModal />),
103
103
  * ])
104
104
  *
105
- * // With loaders and revalidation
105
+ * // With loaders and revalidation (revalidate() goes on the loader;
106
+ * // an intercept-level revalidate() throws)
106
107
  * intercept("@modal", "card", () => <CardModal />, () => [
107
- * loader(CardModalLoader),
108
- * revalidate(() => false),
108
+ * loader(CardModalLoader, () => [revalidate(() => false)]),
109
109
  * ])
110
110
  *
111
111
  * // Conditional activation via the config object's `when` selector
@@ -127,7 +127,11 @@ export type RouteHelpers<T extends RouteDefinition, TEnv> = {
127
127
  * @param handler - Component or handler for intercepted render
128
128
  * @param config - Optional InterceptConfig (e.g. `{ when }`), or the use
129
129
  * callback directly when there is no config
130
- * @param use - Optional callback for loaders, middleware, revalidate, etc.
130
+ * @param use - Optional callback for loader(), middleware(), loading(),
131
+ * transition() and a layout() modal chrome without use() items.
132
+ * revalidate() (goes on the loader), errorBoundary()/notFoundBoundary()
133
+ * (go on the enclosing layout) and cache() (goes on the target route)
134
+ * throw here.
131
135
  */
132
136
  intercept: {
133
137
  <K extends keyof ResolvedRouteMap<T> & string>(slotName: `@${string}`, routeName: `.${K}`, handler: ReactNode | Handler<ExtractRouteParams<T, K>, {}, TEnv>, config?: import("../server/context.js").InterceptConfig<TEnv> | (() => UseItems<InterceptUseItem>), use?: () => UseItems<InterceptUseItem>): InterceptItem;
@@ -183,6 +187,9 @@ export type RouteHelpers<T extends RouteDefinition, TEnv> = {
183
187
  * ({ defaultShouldRevalidate: true })
184
188
  * )
185
189
  * ```
190
+ * Not valid directly inside intercept() use() (throws at definition time):
191
+ * intercepts only revalidate their loaders, so attach it there with
192
+ * `loader(Def, () => [revalidate(...)])`.
186
193
  * @param fn - Function returning either:
187
194
  * - `boolean` (hard decision — short-circuits the chain),
188
195
  * - `{ defaultShouldRevalidate: boolean }` (soft — updates the suggestion
@@ -245,16 +252,19 @@ export type RouteHelpers<T extends RouteDefinition, TEnv> = {
245
252
  * ```typescript
246
253
  * errorBoundary(<ErrorFallback />)
247
254
  *
248
- * // With dynamic error handler
249
- * errorBoundary(({ error, reset }) => (
255
+ * // With dynamic error handler (server fallback: receives only { error })
256
+ * errorBoundary(({ error }) => (
250
257
  * <div>
251
258
  * <h2>Something went wrong</h2>
252
259
  * <p>{error.message}</p>
253
- * <button onClick={reset}>Try again</button>
260
+ * <a href="/">Go home</a>
254
261
  * </div>
255
262
  * ))
256
263
  * ```
257
- * @param fallback - Static JSX or handler receiving error info and reset function
264
+ * Not valid inside intercept() use() (throws at definition time): an
265
+ * intercept has no boundary of its own, and its loader errors resolve
266
+ * against the enclosing layout/path boundary.
267
+ * @param fallback - Static JSX or handler receiving `{ error }`
258
268
  */
259
269
  errorBoundary: (fallback: ReactNode | ErrorBoundaryHandler) => ErrorBoundaryItem;
260
270
  /**
@@ -270,6 +280,9 @@ export type RouteHelpers<T extends RouteDefinition, TEnv> = {
270
280
  * </div>
271
281
  * ))
272
282
  * ```
283
+ * Not valid inside intercept() use() (throws at definition time): an
284
+ * intercept has no boundary of its own, and notFound() from its loaders
285
+ * resolves against the enclosing layout/path boundary.
273
286
  * @param fallback - Static JSX or handler receiving not-found info
274
287
  */
275
288
  notFoundBoundary: (fallback: ReactNode | NotFoundBoundaryHandler) => NotFoundBoundaryItem;
@@ -285,6 +298,9 @@ export type RouteHelpers<T extends RouteDefinition, TEnv> = {
285
298
  * Note: Loaders are NOT cached by default. Use cache() inside loader()
286
299
  * to explicitly opt-in to loader caching.
287
300
  *
301
+ * Not valid inside intercept() use() (throws at definition time): an
302
+ * intercept navigation is cached under the target route's cache() scope.
303
+ *
288
304
  * ```typescript
289
305
  * // Using app-level defaults (ttl inherited from store.defaults)
290
306
  * cache(() => [
@@ -319,6 +335,12 @@ export type RouteHelpers<T extends RouteDefinition, TEnv> = {
319
335
  * route("archive/:year"), // uses KV store
320
336
  * ])
321
337
  *
338
+ * // Among a path's children: caches that path (handler, layouts, parallels)
339
+ * path("/product/:id", ProductPage, { name: "product" }, () => [
340
+ * cache({ ttl: 60 }),
341
+ * layout(<ProductChrome />), // cached with the path
342
+ * ])
343
+ *
322
344
  * // Opt-in loader caching
323
345
  * route("product/:id", ProductHandler, () => [
324
346
  * loader(ProductLoader), // NOT cached (default)
@@ -343,8 +365,12 @@ export type RouteHelpers<T extends RouteDefinition, TEnv> = {
343
365
  * through React's startTransition, so a same-route nav (same route,
344
366
  * different params, e.g. /product/1 -> /product/2) holds the previous
345
367
  * content while the new loader resolves instead of flashing the route's
346
- * loading() skeleton (see segment-system.tsx inTransitionScope). This is
347
- * also the precondition for any view-transition animation.
368
+ * loading() skeleton (see segment-system.tsx inTransitionScope). Held
369
+ * useLoader readers of the re-run loaders report isLoading: true until
370
+ * the new data commits (use-loader.tsx). The pin is per loader family
371
+ * (`$$id`), not per segment — a layout reader of the same createLoader
372
+ * the child is re-running is flagged too. This is also the precondition
373
+ * for any view-transition animation.
348
374
  * 2. <ViewTransition> (experimental React only): the segment content is also
349
375
  * wrapped in React's <ViewTransition>, so the held swap cross-fades/morphs.
350
376
  * Layered on by default; pass { viewTransition: false } to keep #1 without
@@ -6,6 +6,28 @@ import type { AllUseItems } from "../route-types.js";
6
6
  * ReactNode handlers return undefined (no .use possible).
7
7
  */
8
8
  export declare function resolveHandlerUse(handler: unknown): (() => any[]) | undefined;
9
+ /**
10
+ * Validate every item an intercept's merged use() returned (explicit use()
11
+ * and handler.use) against MOUNT_SITE_ALLOWED_TYPES.intercept, plus two
12
+ * structural rules:
13
+ * - a nested layout() is only the modal chrome (intercept() keeps its
14
+ * handler), so it may not carry use() items of its own;
15
+ * - a cache entry in `capturedLayouts` means cache() ran in the scope even if
16
+ * it was not returned; its orphan form re-parents the following siblings
17
+ * onto that entry, so it is rejected the same way. Inside a path, cache()
18
+ * writes `sinks.cache` instead (dsl-helpers.ts cache()).
19
+ */
20
+ export declare function validateInterceptUseItems(items: AllUseItems[], capturedLayouts: readonly {
21
+ type: string;
22
+ }[], slotName: string, routeName: string, sinks: {
23
+ readonly revalidate: readonly unknown[];
24
+ readonly errorBoundary: readonly unknown[];
25
+ readonly notFoundBoundary: readonly unknown[];
26
+ readonly intercept: readonly unknown[];
27
+ readonly parallel: Readonly<Record<string, unknown>>;
28
+ /** Set by cache() when the intercept is declared inside a path. */
29
+ readonly cache?: unknown;
30
+ }): void;
9
31
  /**
10
32
  * Validate that items from handler.use() are valid for the given mount site.
11
33
  * Throws a descriptive error if any item is not allowed.
@@ -16,4 +38,4 @@ export declare function validateHandlerUseItems(items: AllUseItems[], mountSite:
16
38
  * handler.use items come first (defaults), explicit items second (overrides).
17
39
  * Returns undefined if both are absent.
18
40
  */
19
- export declare function mergeHandlerUse(handlerUse: (() => any[]) | undefined, explicitUse: (() => any[]) | undefined, mountSite: string): (() => any[]) | undefined;
41
+ export declare function mergeHandlerUse(handlerUse: (() => any[]) | undefined, explicitUse: (() => any[]) | undefined, mountSite: string | null): (() => any[]) | undefined;
@@ -89,6 +89,8 @@ export type CacheItem = {
89
89
  export type TransitionItem = {
90
90
  name: string;
91
91
  type: "transition";
92
+ /** Wrapper form only: the children it wraps (see hasRoutesInItem). */
93
+ uses?: AllUseItems[];
92
94
  };
93
95
  /**
94
96
  * Typed transition item that carries child routes as phantom type
@@ -154,7 +156,7 @@ export type RouteUseItem = LayoutItem | ParallelItem | InterceptItem | Middlewar
154
156
  /** Items that can be used inside a response route (path.json(), etc.) */
155
157
  export type ResponseRouteUseItem = MiddlewareItem | CacheItem;
156
158
  export type ParallelUseItem = RevalidateItem | LoaderItem | LoadingItem | ErrorBoundaryItem | NotFoundBoundaryItem | TransitionItem;
157
- export type InterceptUseItem = MiddlewareItem | RevalidateItem | LoaderItem | LoadingItem | ErrorBoundaryItem | NotFoundBoundaryItem | LayoutItem | RouteItem | TransitionItem;
159
+ export type InterceptUseItem = MiddlewareItem | LoaderItem | LoadingItem | LayoutItem | RouteItem | TransitionItem;
158
160
  export type LoaderUseItem = RevalidateItem | CacheItem;
159
161
  /**
160
162
  * Allow composition factories in use() callbacks.
@@ -1,7 +1,8 @@
1
1
  import { type SerializedManifest } from "../debug.js";
2
2
  import type { RouteEntry } from "../types";
3
3
  /**
4
- * Build a serialized manifest from all route entries for debug inspection.
5
- * Used by the `debugManifest()` method on the router instance.
4
+ * Build a serialized manifest from the eager route entries for debug
5
+ * inspection. Used by the `debugManifest()` method on the router instance.
6
+ * include() children are not expanded (lazy placeholders are skipped).
6
7
  */
7
8
  export declare function buildDebugManifest<TEnv = any>(routesEntries: RouteEntry<TEnv>[]): Promise<SerializedManifest>;
@@ -42,10 +42,30 @@ export interface InvokeOnErrorContext<TEnv = any> {
42
42
  * @param logPrefix - Prefix for console.error messages (e.g., "Router" or "RSC")
43
43
  */
44
44
  export declare function invokeOnError<TEnv = any>(onError: OnErrorCallback<TEnv> | undefined, error: unknown, phase: ErrorPhase, context: InvokeOnErrorContext<TEnv>, logPrefix?: string): void;
45
+ /**
46
+ * First non-undefined `pick(orphan)` over the routeless entries in
47
+ * `entry.layout` and, recursively, in theirs: depth-first in render order
48
+ * (resolveOrphanLayout in segment-resolution/fresh.ts). Since #922 a routeless
49
+ * entry nested in another renders (a layout() after a bare cache() marker, a
50
+ * layout() in a routeless wrapper); a one-level scan missed the boundaries and
51
+ * intercepts it declares (#926).
52
+ *
53
+ * `skip` is the entry an upward walk came from. Only a bare cache() marker is
54
+ * both in its layout's layout[] and in the chain, and its subtree was already
55
+ * scanned at its chain position.
56
+ */
57
+ export declare function findInOrphans<T>(entry: EntryData, pick: (orphan: EntryData) => T | undefined, skip?: EntryData | null): T | undefined;
58
+ /** `findInOrphans` pick: the orphan when it declares an errorBoundary(). */
59
+ export declare const withErrorBoundary: (entry: EntryData) => EntryData | undefined;
45
60
  /**
46
61
  * Find the nearest error boundary by walking up the entry chain
47
62
  * Also checks sibling layouts (orphan layouts) for error boundaries
48
63
  * Returns the first fallback found, or the default error boundary if configured
64
+ *
65
+ * An orphan's parent is null, so from an orphan the walk continues at its
66
+ * orphanOwner (EntryData). Without that step, errors from an intercept declared
67
+ * in a routeless layout, or from that layout's loaders, stopped at the orphan
68
+ * and skipped every ancestor boundary (#898).
49
69
  */
50
70
  export declare function findNearestErrorBoundary(entry: EntryData | null, defaultErrorBoundary?: ReactNode | ErrorBoundaryHandler): ReactNode | ErrorBoundaryHandler | null;
51
71
  /**
@@ -4,6 +4,12 @@
4
4
  * Creates the handler context object passed to route handlers, middleware, and loaders.
5
5
  */
6
6
  import type { InternalHandlerContext } from "../types";
7
+ /**
8
+ * `headers` whose mutating methods run `assertWrite(method)` first. Shared by
9
+ * the handler ctx (createHandlerContext) and the middleware ctx
10
+ * (createMiddlewareContext).
11
+ */
12
+ export declare function guardHeaderWrites(headers: Headers, assertWrite: (method: string | symbol) => void): Headers;
7
13
  /**
8
14
  * Strip internal _rsc* query params from a URL.
9
15
  * Returns a new URL with only user-facing params.
@@ -82,13 +82,13 @@
82
82
  * ISOLATION FROM RESPONSE
83
83
  * =======================
84
84
  *
85
- * Background revalidation creates fully isolated context:
86
- * - Fresh handleStore (prevents polluting the response stream)
85
+ * Background revalidation re-renders through rerenderAndCacheRoute (shared
86
+ * with proactive caching in cache-store.ts):
87
+ * - Derived request context with its own handleStore, transition({ when })
88
+ * predicates and no perf metrics (the shared fields are never touched;
89
+ * the foreground is still producing the page)
87
90
  * - Fresh handlerContext + loaderPromises (prevents reusing memoized
88
91
  * loader results from the foreground pass)
89
- * - handleStore is saved/restored in try/finally
90
- *
91
- * This matches the proactive caching pattern in cache-store.ts.
92
92
  *
93
93
  *
94
94
  * FRESH RESOLUTION (NO REVALIDATION)
@@ -101,7 +101,48 @@
101
101
  */
102
102
  import type { ResolvedSegment } from "../../types.js";
103
103
  import type { MatchContext, MatchPipelineState } from "../match-context.js";
104
+ import { type RouterContext } from "../router-context.js";
105
+ import type { CacheScope } from "../../cache/cache-scope.js";
104
106
  import type { GeneratorMiddleware } from "./cache-lookup.js";
107
+ import { type RequestContext } from "../../server/request-context.js";
108
+ /**
109
+ * Re-render a cached route in the background and write it with
110
+ * cacheScope.cacheRoute: the stale-hit refresh below and proactive caching
111
+ * (cache-store.ts). Returns the number of segments written.
112
+ *
113
+ * A render whose status is not 200 (an error or notFound boundary resolved)
114
+ * is not written and returns 0, as a non-200 MISS is not cached
115
+ * (cache-store.ts): the entry it would replace keeps serving until a later
116
+ * refresh succeeds or it expires. Nothing is held in process; a store's own
117
+ * revalidation marker (CFCacheStore's REVALIDATING) re-arms after
118
+ * MAX_REVALIDATION_INTERVAL, as after a refresh that throws.
119
+ *
120
+ * Runs on a DERIVED request context that owns the per-render state the
121
+ * foreground reads while it is still producing the page (a stale HIT re-runs
122
+ * its loaders; a proactive render starts once the Response exists, while its
123
+ * body streams):
124
+ * - _handleStore: read late (loader pushes and aux-lane tracking in
125
+ * loader-resolution.ts, nested cache restores and captures in
126
+ * cache-scope.ts), so a swap sent live pushes into this render.
127
+ * setupLoaderAccess binds the store at setup, so it runs inside the
128
+ * derived context too.
129
+ * - _transitionWhen: fresh resolution appends transition({ when })
130
+ * predicates; the foreground's gateTransitions reads the array after the
131
+ * match, and a stale HIT (which replays the stored transition) must not
132
+ * evaluate this render's predicates.
133
+ * - _metricsStore: undefined, and the DSL store below has `metrics` unset
134
+ * (track() reads that one), so nothing lands on the foreground's perf
135
+ * timeline. ctx.Store.run closes over ctx.Store, so the derived store
136
+ * needs its own run.
137
+ * - response writes (headers, cookies, status, onResponse callbacks) go to
138
+ * a throwaway context (whose status gates the write, above) and are
139
+ * dropped: a layout above the cache() boundary is outside the header
140
+ * guard and an error boundary sets a status, so they would otherwise
141
+ * reach the live response.
142
+ * runWithRequestContext also re-establishes the request ALS, which a waitUntil
143
+ * task on workerd loses; the DSL store is a different ALS (build context).
144
+ */
145
+ export declare function rerenderAndCacheRoute<TEnv>(ctx: MatchContext<TEnv>, requestCtx: RequestContext<TEnv>, cacheScope: CacheScope, routerCtx: RouterContext<TEnv>): Promise<number>;
105
146
  /**
106
147
  * Creates background revalidation middleware
107
148
  *
@@ -1,6 +1,6 @@
1
1
  import type { ContextVar } from "../context-var.js";
2
2
  import type { DefaultReverseRouteMap, DefaultRouteName, DefaultVars } from "../types/global-namespace.js";
3
- import type { ScopedReverseFunction } from "../reverse.js";
3
+ import type { GlobalReverseFunction } from "../reverse.js";
4
4
  import type { Theme } from "../theme/types.js";
5
5
  import type { LocationStateEntry } from "../browser/react/location-state-shared.js";
6
6
  import type { RequestScope } from "../types/request-scope.js";
@@ -51,7 +51,8 @@ export interface MiddlewareContext<TEnv = any, TParams = Record<string, string |
51
51
  theme?: Theme;
52
52
  setTheme?: (theme: Theme) => void;
53
53
  setLocationState(entries: LocationStateEntry | LocationStateEntry[]): void;
54
- reverse: ScopedReverseFunction<Record<string, string>, DefaultReverseRouteMap>;
54
+ /** Global route names only; see {@link GlobalReverseFunction}. */
55
+ reverse: GlobalReverseFunction<DefaultReverseRouteMap>;
55
56
  }
56
57
  export type MiddlewareFn<TEnv = any, TParams = Record<string, string | undefined>> = (ctx: MiddlewareContext<TEnv, TParams>, next: () => Promise<Response>) => Response | void | Promise<Response | void>;
57
58
  export interface MiddlewareEntry<TEnv = any> {
@@ -49,7 +49,9 @@ export interface RouterContext<TEnv = any> {
49
49
  getMetricsStore: () => MetricsStore | undefined;
50
50
  createCacheScope: (cacheConfig: any, parent: CacheScope | null) => CacheScope | null;
51
51
  findInterceptForRoute: (routeKey: string, parentEntry: EntryData | null, selectorContext: InterceptSelectorContext, isAction: boolean) => InterceptResult | null;
52
- resolveAllSegmentsWithRevalidation: (entries: EntryData[], routeKey: string, params: Record<string, string>, handlerContext: HandlerContext<any, TEnv>, clientSegmentSet: Set<string>, prevParams: Record<string, string>, request: Request, prevUrl: URL, nextUrl: URL, actionContext: any | undefined, interceptResult: InterceptResult | null, localRouteName: string, pathname: string, stale?: boolean) => Promise<{
52
+ resolveAllSegmentsWithRevalidation: (entries: EntryData[], routeKey: string, params: Record<string, string>, handlerContext: HandlerContext<any, TEnv>, clientSegmentSet: Set<string>, prevParams: Record<string, string>, request: Request, prevUrl: URL, nextUrl: URL, actionContext: any | undefined, interceptResult: InterceptResult | null, localRouteName: string, pathname: string, stale?: boolean,
53
+ /** The matched route's full chain when `entries` is part of it (ResolveSegmentOptions.chain). */
54
+ chain?: readonly EntryData[]) => Promise<{
53
55
  segments: ResolvedSegment[];
54
56
  matchedIds: string[];
55
57
  }>;
@@ -137,6 +137,22 @@ export interface Rango<TEnv = any, TRoutes extends Record<string, unknown> = Rec
137
137
  * ```
138
138
  */
139
139
  readonly routeMap: TRoutes;
140
+ /**
141
+ * Serialize the route manifest for inspection: every route and layout the
142
+ * router's `.routes()` / `urls` mounts register, with shortCodes, parent
143
+ * links, and loader/middleware/error-boundary/parallel/intercept flags.
144
+ *
145
+ * Server-only development aid. It re-evaluates each mount's `urls()` tree.
146
+ * Groups mounted with `include()` are lazy and are not expanded: their
147
+ * routes are absent from the result.
148
+ *
149
+ * @example
150
+ * ```typescript
151
+ * const manifest = await router.debugManifest();
152
+ * console.log(manifest.totalRoutes, Object.keys(manifest.routes));
153
+ * ```
154
+ */
155
+ debugManifest(): Promise<SerializedManifest>;
140
156
  /**
141
157
  * Handle an RSC request.
142
158
  *
@@ -147,7 +163,13 @@ export interface Rango<TEnv = any, TRoutes extends Record<string, unknown> = Rec
147
163
  * ```tsx
148
164
  * import { router } from "./router";
149
165
  *
150
- * export default { fetch: router.fetch };
166
+ * // Workers call fetch(request, env, ctx); `{ fetch: router.fetch }` would
167
+ * // drop env and ctx.
168
+ * export default {
169
+ * fetch(request, env, ctx) {
170
+ * return router.fetch(request, { env, ctx });
171
+ * },
172
+ * } satisfies ExportedHandler;
151
173
  * ```
152
174
  *
153
175
  * @example Direct export
@@ -238,7 +260,7 @@ export interface RangoInternal<TEnv = any, TRoutes extends Record<string, unknow
238
260
  readonly notFound?: RangoOptions<TEnv>["notFound"];
239
261
  /**
240
262
  * Resolved theme configuration (null if theme not enabled)
241
- * Used by NavigationProvider to include ThemeProvider and by MetaTags to render theme script
263
+ * Used by NavigationProvider to include ThemeProvider and by `Html.Meta` to render theme script
242
264
  */
243
265
  readonly themeConfig: import("../theme/types.js").ResolvedThemeConfig | null;
244
266
  /**
@@ -146,8 +146,10 @@ export interface RangoOptions<TEnv = any> {
146
146
  *
147
147
  * Must be a client component ("use client") that accepts { children }.
148
148
  *
149
- * If not provided, a default document with basic HTML structure is used:
150
- * `<html><head><meta charset/viewport></head><body>{children}</body></html>`
149
+ * If not provided, a default document is used: `Html.Meta` and `Html.Scripts`
150
+ * in `<head>`, `Html.Scripts position="body"` before `{children}` and
151
+ * `Html.ScrollRestoration` after it. Pass your own to set `getKey` or to
152
+ * leave back/forward scrolling to the browser.
151
153
  *
152
154
  * @example
153
155
  * ```typescript
@@ -181,7 +183,8 @@ export interface RangoOptions<TEnv = any> {
181
183
  defaultErrorBoundary?: ReactNode | ErrorBoundaryHandler;
182
184
  /**
183
185
  * Default not-found boundary fallback used when no notFoundBoundary is defined in the route tree
184
- * If not provided, DataNotFoundError will be treated as a regular error
186
+ * If not provided, notFound() renders the `notFound` option, else a plain
187
+ * `<h1>Not Found</h1>` (status 404)
185
188
  */
186
189
  defaultNotFoundBoundary?: ReactNode | NotFoundBoundaryHandler;
187
190
  /**
@@ -190,7 +193,7 @@ export interface RangoOptions<TEnv = any> {
190
193
  * This is rendered within your document/app shell with a 404 status code.
191
194
  * Use this for a custom 404 page that maintains your app's look and feel.
192
195
  *
193
- * If not provided, a default "Page not found" component is rendered.
196
+ * If not provided, a plain `<h1>Not Found</h1>` is rendered.
194
197
  *
195
198
  * Can be a static ReactNode or a function receiving the pathname.
196
199
  *
@@ -337,7 +340,7 @@ export interface RangoOptions<TEnv = any> {
337
340
  * When provided, enables:
338
341
  * - ctx.theme and ctx.setTheme() in route handlers
339
342
  * - useTheme() hook for client components
340
- * - FOUC prevention via inline script in MetaTags
343
+ * - FOUC prevention via inline script in `<Html.Meta />`
341
344
  * - Automatic ThemeProvider wrapping in NavigationProvider
342
345
  *
343
346
  * @example
@@ -27,6 +27,16 @@ export interface ResolveSegmentOptions {
27
27
  * so error boundaries keep catching at request time.
28
28
  */
29
29
  throwOnError?: boolean;
30
+ /**
31
+ * The matched route's full entry chain. resolveAllSegments defaults it to
32
+ * its `entries`; withCacheLookup passes it when it resolves only the entries
33
+ * above a cache() boundary. An orphan list can hold an entry of the chain: a
34
+ * bare cache() marker sits in its layout's layout[] (it wraps that layout's
35
+ * routes) and is the parent of the routes after it. For those routes it
36
+ * resolves once, as a chain entry, below the cache() header latch (issue
37
+ * #918: resolved twice on a MISS, once and discarded on a HIT).
38
+ */
39
+ chain?: readonly EntryData[];
30
40
  }
31
41
  /**
32
42
  * Resolve segments from EntryData.
@@ -16,8 +16,15 @@
16
16
  * On hit: returns cached data directly, skips loader execution.
17
17
  * On stale hit (SWR): returns stale data, schedules background revalidation.
18
18
  * On miss: executes loader, schedules non-blocking cache write.
19
+ *
20
+ * Handle pushes (`ctx.use(Handle)(...)` in the loader body) are a side effect
21
+ * the HIT must reproduce: the MISS records the pushes of the body and of the
22
+ * loaders it awaits via ctx.use into the entry's `handles` blob (the
23
+ * "use cache" capture/encode), and every HIT — stale included — replays
24
+ * them, each loader's pushes at most once per request (a dependency another
25
+ * reader already ran keeps its live pushes). See replayLoaderHandles.
19
26
  */
20
- import type { LoaderEntry } from "../../server/context.js";
27
+ import { type LoaderEntry } from "../../server/context.js";
21
28
  import type { HandlerContext } from "../../types.js";
22
29
  /**
23
30
  * Resolve loader data with optional caching.
@@ -29,5 +36,34 @@ import type { HandlerContext } from "../../types.js";
29
36
  * (observePhase; see instrument.ts). A cache HIT returns without calling ctx.use,
30
37
  * so it emits no loader phase (the loader did not execute; the hit is only a
31
38
  * LoaderCache debug log).
39
+ *
40
+ * PPR loader lane rule — the canonical source statement; other sites point
41
+ * here (consumer docs: skills/ppr/SKILL.md "The loader lane rule";
42
+ * docs/design/loader-container-bake.md). This is the single funnel every
43
+ * loader segment path routes through (fresh resolveLoaders, cache-hit
44
+ * resolveLoadersOnly, revalidation resolveLoadersOnlyWithRevalidation, and
45
+ * intercept loaders in intercept-resolution.ts, which pass no bake key and
46
+ * never run under a shell capture), so the lane is decided here, per LOADER,
47
+ * never by the entry's loading():
48
+ *
49
+ * - BAKE lane: `loader(Def, { ssr: false })` (awaitBeforeFlush) with a
50
+ * `bakeSegmentKey` from the caller. The loader EXECUTES at capture (the
51
+ * flag's "data in the HTML before first flush" maps to the frozen prelude)
52
+ * and its settled non-promise data bakes into the shell. Promises nested in
53
+ * plain objects/arrays are masked (mask-nested.ts) and stay live holes at
54
+ * the consumer's own Suspense — per-request material must be promise-shaped
55
+ * (the #692 cross-session scar). The masked container registers on
56
+ * `_shellCaptureLoaderRecords`: it holds the capture gate (bounded by
57
+ * `ppr.captureTimeout`) and pins into the snapshot's loader family, and on a
58
+ * HIT the recorded container is overlaid onto the fresh run (below) so the
59
+ * payload matches the frozen prelude byte-for-byte. cookies()/headers() in
60
+ * its body (nested promise bodies included) trip the capture guard.
61
+ * - LIVE lane: every other loader, whatever its entry's loading(). Never
62
+ * executes at capture: the slot gets a never-resolving promise
63
+ * (loader-mask.ts) and postpones at the reader's boundary — loading() or an
64
+ * inline Suspense — then streams fresh per request. A masked read with NO
65
+ * boundary above it root-postpones and the <body> sanity gate refuses the
66
+ * shell (eternal-MISS warning). A route whose loaders are ALL `ssr: false`
67
+ * needs no loading(): nothing masks.
32
68
  */
33
69
  export declare function resolveLoaderData<TEnv>(loaderEntry: LoaderEntry, ctx: HandlerContext<any, TEnv>, pathname: string, bakeSegmentKey?: string | null): Promise<any>;
@@ -2,13 +2,10 @@
2
2
  * PPR shell-capture loader masking.
3
3
  *
4
4
  * During a shell CAPTURE re-render (Axis 2, see docs/design/ppr-shell-resume.md)
5
- * route loaders are the "live lane": they must NOT execute — no side effects, no
6
- * cost, no cache round-trips. Instead every loader segment's value slot receives
7
- * a never-resolving promise, so the loader-consuming Suspense subtree stays
8
- * pending and React's static `prerender` marks it as a postponed hole. The frozen
9
- * shell (prelude) captures only the fallback; the resumed serve pass runs the
10
- * loaders fresh through the unchanged execution path and streams their output
11
- * into the holes.
5
+ * live-lane loaders (lane rule: see resolveLoaderData, loader-cache.ts) must
6
+ * NOT execute; their value slot gets a never-resolving promise so the
7
+ * consuming Suspense subtree postpones as a hole, and the serve pass runs them
8
+ * fresh into it.
12
9
  *
13
10
  * Capture mode is signalled by `requestCtx._shellCaptureRun`, set to true ONLY on
14
11
  * the derived request context of the background capture task (shell-capture.ts) —
@@ -28,17 +25,10 @@ import { type RequestContext } from "../../server/request-context.js";
28
25
  export declare function isShellCaptureActive(reqCtx?: RequestContext<any> | undefined): boolean;
29
26
  export { createMaskedLoaderPromise } from "./mask-nested.js";
30
27
  /**
31
- * Entry-level lane input for an entry's loaders under PPR (the loading()
32
- * value; docs/design/loader-container-bake.md). The CAPTURE decision itself
33
- * is per LOADER in loader-cache.ts: an `ssr: false`
34
- * (awaitBeforeFlush) loader BAKES at capture regardless of this value — the
35
- * flag's document promise ("data in the HTML before first flush") maps to
36
- * the frozen prelude — while every other loader is LIVE (masked at capture,
37
- * fresh on every serve), postponing at loading() or an inline Suspense.
38
- * This helper still gates which entries pass a bake segment key for the
39
- * legacy loading()-less shape and the HIT-tail seed overlay.
40
- *
41
- * Mirrors segment-system's isRenderableLoading so the mask decision and the
42
- * tree's boundary placement can never disagree.
28
+ * True when the entry's loading() is renderable (mirrors segment-system's
29
+ * isRenderableLoading). Not the lane decision (lane rule: see
30
+ * resolveLoaderData, loader-cache.ts): callers only use it to decide whether
31
+ * an unflagged loader's segment key rides as the bake/seed key, which is inert
32
+ * at capture.
43
33
  */
44
34
  export declare function entryLoadingMasksLoaders(loading: unknown): boolean;
@@ -2,9 +2,9 @@
2
2
  * Loader-family capture snapshot: elide + overlay for bake-lane loader
3
3
  * containers (docs/design/loader-container-bake.md).
4
4
  *
5
- * A loader on an entry with NO renderable loading() executes during shell
6
- * capture; its settled container bakes into the prelude while every promise
7
- * still pending at the quiet window postpones as a hole. To keep a HIT's fresh
5
+ * A bake-lane loader (lane rule: see resolveLoaderData, loader-cache.ts)
6
+ * executes during shell capture; its settled container bakes into the prelude
7
+ * while nested promises postpone as holes. To keep a HIT's fresh
8
8
  * payload byte-identical to that frozen prelude, the capture pins the container
9
9
  * in the shell snapshot:
10
10
  *
@@ -1,12 +1,12 @@
1
1
  /**
2
2
  * Capture-side nested-thenable masking — the mechanism behind "nested-promise
3
3
  * shape is the liveness declaration" for BOTH bake-lane loader containers
4
- * (loader-cache.ts) and pushed handle containers (request-context.ts
5
- * createUseFunction).
4
+ * (loader-cache.ts) and pushed handle containers (the capture handle store's
5
+ * push wrap in rsc/shell-capture.ts).
6
6
  *
7
- * Deliberately a LEAF module: request-context needs the mask for handle
8
- * pushes, and loader-mask (the other natural home) imports request-context —
9
- * importing from there would cycle. This module imports only is-thenable.
7
+ * Deliberately a LEAF module: loader-mask (the other natural home) imports
8
+ * request-context, so any funnel importing the mask from there inherits that
9
+ * graph. This module imports only is-thenable.
10
10
  */
11
11
  /**
12
12
  * A promise that never settles — the masked stand-in for a per-request value
@@ -21,8 +21,8 @@ export declare function createMaskedLoaderPromise<T = unknown>(): Promise<T>;
21
21
  * Deep-copy a container with every NESTED thenable replaced by a masked
22
22
  * (never-resolving) promise. Applied during shell capture to (a) bake-lane
23
23
  * loader containers (loader-cache.ts) and (b) pushed handle containers
24
- * (createUseFunction) — the two rango-owned funnels where consumers declare
25
- * per-request data by promise SHAPE.
24
+ * (shell-capture.ts capture store push wrap) — the two rango-owned funnels
25
+ * where consumers declare per-request data by promise SHAPE.
26
26
  *
27
27
  * Why: a nested promise that happened to SETTLE before the capture's quiet
28
28
  * window closed used to bake its value into the SHARED shell (and, for
@@ -66,7 +66,9 @@ export declare function resolveEntryHandlerWithRevalidation<TEnv>(entry: Exclude
66
66
  */
67
67
  export declare function resolveSegmentWithRevalidation<TEnv>(entry: Exclude<EntryData, {
68
68
  type: "parallel";
69
- }>, 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): Promise<SegmentRevalidationResult>;
69
+ }>, 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,
70
+ /** The matched route's full chain; see ResolveSegmentOptions.chain (fresh.ts). */
71
+ chain?: readonly EntryData[]): Promise<SegmentRevalidationResult>;
70
72
  /**
71
73
  * Resolve orphan layout with revalidation.
72
74
  */
@@ -79,7 +81,9 @@ parentRouteEntry?: EntryData): Promise<SegmentRevalidationResult>;
79
81
  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: {
80
82
  intercept: any;
81
83
  entry: EntryData;
82
- } | null, localRouteName: string, pathname: string, deps: SegmentResolutionDeps<TEnv>, stale?: boolean): Promise<{
84
+ } | null, localRouteName: string, pathname: string, deps: SegmentResolutionDeps<TEnv>, stale?: boolean,
85
+ /** The matched route's full chain; see ResolveSegmentOptions.chain (fresh.ts). */
86
+ chain?: readonly EntryData[]): Promise<{
83
87
  segments: ResolvedSegment[];
84
88
  matchedIds: string[];
85
89
  }>;
@@ -27,7 +27,7 @@ export interface SegmentWrappers<TEnv = any> {
27
27
  } | undefined, interceptResult: {
28
28
  intercept: InterceptEntry;
29
29
  entry: EntryData;
30
- } | null, localRouteName: string, pathname: string) => Promise<{
30
+ } | null, localRouteName: string, pathname: string, stale?: boolean, chain?: readonly EntryData[]) => Promise<{
31
31
  segments: ResolvedSegment[];
32
32
  matchedIds: string[];
33
33
  }>;
@@ -6,7 +6,7 @@
6
6
  * dispatch, route middleware execution, and response caching with SWR.
7
7
  */
8
8
  import type { MiddlewareFn } from "../router/middleware.js";
9
- import type { EntryData } from "../server/context.js";
9
+ import { type EntryData } from "../server/context.js";
10
10
  import type { HandlerContext } from "./handler-context.js";
11
11
  export interface ResponseRouteMatch {
12
12
  responseType: string;
@@ -2,8 +2,7 @@
2
2
  * RSC Rendering Handler (Navigation)
3
3
  *
4
4
  * Handles RSC rendering for both partial (client-side navigation) and full
5
- * (initial page load) requests. Includes prerender collection for build-time
6
- * static generation.
5
+ * (initial page load) requests.
7
6
  */
8
7
  import { getRequestContext } from "../server/request-context.js";
9
8
  import type { HandlerContext } from "./handler-context.js";
@@ -42,3 +42,11 @@ export declare const SHELL_CAPTURE_MAX_WAIT_MS = 15000;
42
42
  * check on the stampede guard, keyed off the same constant.
43
43
  */
44
44
  export declare const SHELL_CAPTURE_TASK_HARD_CAP_MS = 25000;
45
+ /**
46
+ * Shared PPR loader-lane hint, appended to every capture warning or error
47
+ * whose fix depends on the lane (shell-capture.ts warnings, the cookie-store.ts
48
+ * capture guard). Lives in this import-free leaf so cookie-store.ts can import
49
+ * it without pulling the capture orchestration module. Source anchor for the
50
+ * rule: resolveLoaderData (router/segment-resolution/loader-cache.ts).
51
+ */
52
+ export declare const PPR_LANE_HINT: string;