@rangojs/router 0.16.0 → 0.18.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 (309) hide show
  1. package/README.md +255 -89
  2. package/dist/testing/vitest.js +252 -0
  3. package/dist/types/browser/cookie-name.d.ts +6 -0
  4. package/dist/types/browser/history-state.d.ts +16 -0
  5. package/dist/types/browser/navigation-transaction.d.ts +6 -0
  6. package/dist/types/browser/partial-update.d.ts +11 -0
  7. package/dist/types/browser/react/ScrollRestoration.d.ts +6 -6
  8. package/dist/types/browser/rsc-router.d.ts +1 -1
  9. package/dist/types/browser/scroll-restoration.d.ts +7 -0
  10. package/dist/types/cache/cache-exec-scope.d.ts +18 -1
  11. package/dist/types/cache/cache-key-utils.d.ts +17 -2
  12. package/dist/types/cache/cache-policy.d.ts +17 -0
  13. package/dist/types/cache/cache-scope.d.ts +132 -19
  14. package/dist/types/cache/cache-tag.d.ts +92 -7
  15. package/dist/types/cache/cf/cf-base64.d.ts +6 -0
  16. package/dist/types/cache/cf/cf-cache-constants.d.ts +11 -0
  17. package/dist/types/cache/cf/cf-cache-store.d.ts +185 -44
  18. package/dist/types/cache/cf/cf-cache-types.d.ts +31 -4
  19. package/dist/types/cache/cf/cf-shell-frame.d.ts +95 -0
  20. package/dist/types/cache/cf/cf-tag-marker-memo.d.ts +34 -0
  21. package/dist/types/cache/handle-capture.d.ts +41 -3
  22. package/dist/types/cache/handle-snapshot.d.ts +54 -13
  23. package/dist/types/cache/index.d.ts +1 -0
  24. package/dist/types/cache/isolate-tag-memo.d.ts +149 -0
  25. package/dist/types/cache/segment-codec.d.ts +10 -3
  26. package/dist/types/cache/shell-memo.d.ts +178 -0
  27. package/dist/types/cache/shell-snapshot.d.ts +110 -21
  28. package/dist/types/cache/tag-invalidation.d.ts +30 -3
  29. package/dist/types/cache/taint.d.ts +1 -1
  30. package/dist/types/cache/types.d.ts +220 -44
  31. package/dist/types/cache/vercel/vercel-cache-store.d.ts +111 -13
  32. package/dist/types/client.d.ts +4 -4
  33. package/dist/types/client.rsc.d.ts +4 -5
  34. package/dist/types/components/DefaultDocument.d.ts +5 -2
  35. package/dist/types/context-var.d.ts +6 -5
  36. package/dist/types/escape-script.d.ts +1 -1
  37. package/dist/types/handles/MetaTags.d.ts +5 -4
  38. package/dist/types/handles/Scripts.d.ts +8 -7
  39. package/dist/types/handles/meta.d.ts +2 -2
  40. package/dist/types/handles/script.d.ts +17 -16
  41. package/dist/types/href-client.d.ts +1 -1
  42. package/dist/types/html.d.ts +12 -0
  43. package/dist/types/index.d.ts +1 -1
  44. package/dist/types/index.rsc.d.ts +3 -2
  45. package/dist/types/loader-store.d.ts +7 -4
  46. package/dist/types/prerender/build-shell-capture.d.ts +11 -4
  47. package/dist/types/reverse.d.ts +36 -4
  48. package/dist/types/route-definition/dsl-helpers.d.ts +3 -3
  49. package/dist/types/route-definition/helpers-types.d.ts +33 -9
  50. package/dist/types/route-definition/resolve-handler-use.d.ts +23 -1
  51. package/dist/types/route-types.d.ts +1 -1
  52. package/dist/types/router/debug-manifest.d.ts +3 -2
  53. package/dist/types/router/error-handling.d.ts +20 -0
  54. package/dist/types/router/handler-context.d.ts +6 -0
  55. package/dist/types/router/instrument.d.ts +8 -0
  56. package/dist/types/router/match-middleware/background-revalidation.d.ts +46 -5
  57. package/dist/types/router/middleware-types.d.ts +9 -3
  58. package/dist/types/router/router-context.d.ts +3 -1
  59. package/dist/types/router/router-interfaces.d.ts +24 -2
  60. package/dist/types/router/router-options.d.ts +8 -5
  61. package/dist/types/router/segment-resolution/fresh.d.ts +10 -0
  62. package/dist/types/router/segment-resolution/loader-cache.d.ts +66 -1
  63. package/dist/types/router/segment-resolution/loader-mask.d.ts +9 -19
  64. package/dist/types/router/segment-resolution/loader-snapshot.d.ts +23 -12
  65. package/dist/types/router/segment-resolution/mask-nested.d.ts +67 -26
  66. package/dist/types/router/segment-resolution/revalidation.d.ts +6 -2
  67. package/dist/types/router/segment-wrappers.d.ts +1 -1
  68. package/dist/types/rsc/full-payload.d.ts +14 -0
  69. package/dist/types/rsc/handler.d.ts +1 -1
  70. package/dist/types/rsc/response-route-handler.d.ts +1 -1
  71. package/dist/types/rsc/rsc-rendering.d.ts +1 -2
  72. package/dist/types/rsc/shell-build-manifest.d.ts +8 -0
  73. package/dist/types/rsc/shell-capture-constants.d.ts +61 -6
  74. package/dist/types/rsc/shell-capture.d.ts +151 -19
  75. package/dist/types/rsc/shell-serve.d.ts +140 -17
  76. package/dist/types/rsc/ssr-setup.d.ts +6 -6
  77. package/dist/types/rsc/types.d.ts +17 -0
  78. package/dist/types/server/context.d.ts +139 -15
  79. package/dist/types/server/cookie-store.d.ts +21 -0
  80. package/dist/types/server/handle-store.d.ts +26 -2
  81. package/dist/types/server/request-context.d.ts +182 -53
  82. package/dist/types/ssr/index.d.ts +24 -0
  83. package/dist/types/ssr/ssr-root.d.ts +9 -8
  84. package/dist/types/static-handler.d.ts +4 -1
  85. package/dist/types/testing/flight.entry.d.ts +7 -0
  86. package/dist/types/testing/generated-routes.d.ts +2 -2
  87. package/dist/types/testing/internal/context.d.ts +1 -1
  88. package/dist/types/testing/render-route.d.ts +32 -6
  89. package/dist/types/testing/run-loader.d.ts +18 -3
  90. package/dist/types/testing/serve-shell-request.d.ts +132 -0
  91. package/dist/types/testing/shell-status.d.ts +23 -10
  92. package/dist/types/testing/vitest-stubs/plugin-rsc.d.ts +28 -5
  93. package/dist/types/testing/vitest.d.ts +35 -1
  94. package/dist/types/theme/ThemeScript.d.ts +3 -3
  95. package/dist/types/types/cache-types.d.ts +14 -10
  96. package/dist/types/types/handler-context.d.ts +28 -1
  97. package/dist/types/types/loader-types.d.ts +8 -6
  98. package/dist/types/urls/pattern-types.d.ts +22 -18
  99. package/dist/types/urls/response-types.d.ts +3 -12
  100. package/dist/types/use-loader.d.ts +12 -3
  101. package/dist/types/vite/plugins/use-cache-transform.d.ts +33 -2
  102. package/dist/types/vite/rango.d.ts +1 -1
  103. package/dist/types/vite/router-discovery.d.ts +29 -2
  104. package/dist/vite/index.js +1420 -1348
  105. package/package.json +2 -2
  106. package/skills/api-client/SKILL.md +22 -10
  107. package/skills/breadcrumbs/SKILL.md +75 -22
  108. package/skills/bundle-analysis/SKILL.md +22 -22
  109. package/skills/cache-guide/SKILL.md +306 -124
  110. package/skills/caching/SKILL.md +530 -98
  111. package/skills/catalog.json +16 -16
  112. package/skills/client-urls/SKILL.md +65 -38
  113. package/skills/cloudflare/SKILL.md +87 -20
  114. package/skills/cloudflare/references/d1-and-local-dev.md +15 -2
  115. package/skills/cloudflare/references/streaming-and-deploy.md +10 -3
  116. package/skills/cloudflare/references/webhooks-and-crypto.md +9 -2
  117. package/skills/comparison/SKILL.md +5 -0
  118. package/skills/comparison/references/framework-comparison.md +75 -57
  119. package/skills/composability/SKILL.md +38 -29
  120. package/skills/css/SKILL.md +10 -13
  121. package/skills/debug-manifest/SKILL.md +74 -31
  122. package/skills/defer-hydration/SKILL.md +52 -31
  123. package/skills/deployment-caching/SKILL.md +11 -3
  124. package/skills/document-cache/SKILL.md +98 -28
  125. package/skills/fonts/SKILL.md +16 -8
  126. package/skills/handler-use/SKILL.md +55 -17
  127. package/skills/hooks/SKILL.md +28 -20
  128. package/skills/hooks/data.md +23 -3
  129. package/skills/hooks/handle-and-actions.md +34 -17
  130. package/skills/hooks/navigation.md +39 -10
  131. package/skills/hooks/outlets.md +13 -6
  132. package/skills/hooks/state.md +39 -15
  133. package/skills/hooks/urls.md +7 -5
  134. package/skills/host-router/SKILL.md +64 -12
  135. package/skills/i18n/SKILL.md +60 -34
  136. package/skills/intercept/SKILL.md +161 -26
  137. package/skills/layout/SKILL.md +106 -50
  138. package/skills/links/SKILL.md +51 -19
  139. package/skills/loader/SKILL.md +386 -128
  140. package/skills/middleware/SKILL.md +129 -26
  141. package/skills/migrate-nextjs/SKILL.md +156 -70
  142. package/skills/migrate-nextjs/backend-host-swap.md +5 -2
  143. package/skills/migrate-react-router/SKILL.md +51 -39
  144. package/skills/migrate-react-router/component-migration.md +28 -7
  145. package/skills/migrate-react-router/data-and-actions.md +21 -6
  146. package/skills/migrate-react-router/route-mapping.md +19 -10
  147. package/skills/mime-routes/SKILL.md +12 -7
  148. package/skills/observability/SKILL.md +92 -14
  149. package/skills/parallel/SKILL.md +88 -47
  150. package/skills/ppr/SKILL.md +866 -379
  151. package/skills/prerender/SKILL.md +210 -108
  152. package/skills/rango/SKILL.md +115 -65
  153. package/skills/react-compiler/SKILL.md +6 -5
  154. package/skills/response-routes/SKILL.md +133 -25
  155. package/skills/route/SKILL.md +170 -60
  156. package/skills/router-setup/SKILL.md +420 -240
  157. package/skills/scripts/SKILL.md +39 -21
  158. package/skills/server-actions/SKILL.md +231 -59
  159. package/skills/shell-manifest/SKILL.md +28 -14
  160. package/skills/streams-and-websockets/SKILL.md +32 -14
  161. package/skills/tailwind/SKILL.md +37 -33
  162. package/skills/testing/SKILL.md +73 -33
  163. package/skills/testing/cache-prerender.md +60 -33
  164. package/skills/testing/client-components.md +59 -6
  165. package/skills/testing/e2e-parity.md +12 -2
  166. package/skills/testing/flight.md +19 -11
  167. package/skills/testing/handles.md +8 -5
  168. package/skills/testing/loader.md +26 -6
  169. package/skills/testing/middleware.md +8 -3
  170. package/skills/testing/predicates.md +120 -0
  171. package/skills/testing/render-handler.md +70 -22
  172. package/skills/testing/response-routes.md +11 -4
  173. package/skills/testing/reverse-and-types.md +20 -14
  174. package/skills/testing/serve-shell-request.md +188 -0
  175. package/skills/testing/server-actions.md +12 -3
  176. package/skills/testing/server-tree.md +9 -0
  177. package/skills/testing/setup.md +9 -5
  178. package/skills/theme/SKILL.md +155 -30
  179. package/skills/typesafety/SKILL.md +20 -9
  180. package/skills/typesafety/env-and-bindings.md +137 -50
  181. package/skills/typesafety/generated-files-and-cli.md +26 -14
  182. package/skills/typesafety/params-and-search.md +44 -19
  183. package/skills/typesafety/route-types.md +50 -14
  184. package/skills/use-cache/SKILL.md +224 -83
  185. package/skills/vercel/SKILL.md +35 -13
  186. package/skills/view-transitions/SKILL.md +42 -21
  187. package/src/__augment-tests__/augmented.check.ts +26 -1
  188. package/src/browser/cookie-name.ts +23 -0
  189. package/src/browser/history-state.ts +23 -0
  190. package/src/browser/index.ts +2 -2
  191. package/src/browser/navigation-bridge.ts +3 -4
  192. package/src/browser/navigation-transaction.ts +22 -2
  193. package/src/browser/partial-update.ts +35 -25
  194. package/src/browser/react/ScrollRestoration.tsx +6 -6
  195. package/src/browser/rsc-router.tsx +6 -1
  196. package/src/browser/scroll-restoration.ts +53 -6
  197. package/src/cache/cache-exec-scope.ts +37 -4
  198. package/src/cache/cache-key-utils.ts +23 -8
  199. package/src/cache/cache-policy.ts +22 -0
  200. package/src/cache/cache-runtime.ts +264 -68
  201. package/src/cache/cache-scope.ts +419 -43
  202. package/src/cache/cache-tag.ts +375 -11
  203. package/src/cache/cf/cf-base64.ts +36 -4
  204. package/src/cache/cf/cf-cache-constants.ts +12 -0
  205. package/src/cache/cf/cf-cache-store.ts +990 -348
  206. package/src/cache/cf/cf-cache-types.ts +32 -4
  207. package/src/cache/cf/cf-shell-frame.ts +258 -0
  208. package/src/cache/cf/cf-tag-marker-memo.ts +143 -39
  209. package/src/cache/document-cache.ts +15 -0
  210. package/src/cache/handle-capture.ts +90 -10
  211. package/src/cache/handle-snapshot.ts +133 -28
  212. package/src/cache/index.ts +2 -0
  213. package/src/cache/isolate-tag-memo.ts +308 -0
  214. package/src/cache/segment-codec.ts +26 -7
  215. package/src/cache/shell-memo.ts +341 -0
  216. package/src/cache/shell-snapshot.ts +217 -27
  217. package/src/cache/tag-invalidation.ts +108 -22
  218. package/src/cache/taint.ts +1 -1
  219. package/src/cache/types.ts +225 -44
  220. package/src/cache/vercel/vercel-cache-store.ts +545 -61
  221. package/src/client.rsc.tsx +10 -9
  222. package/src/client.tsx +5 -4
  223. package/src/components/DefaultDocument.tsx +7 -2
  224. package/src/context-var.ts +6 -5
  225. package/src/escape-script.ts +1 -1
  226. package/src/handles/MetaTags.tsx +13 -11
  227. package/src/handles/Scripts.tsx +11 -10
  228. package/src/handles/meta.ts +2 -2
  229. package/src/handles/script.ts +17 -16
  230. package/src/href-client.ts +1 -1
  231. package/src/html.ts +12 -0
  232. package/src/index.rsc.ts +5 -0
  233. package/src/index.ts +1 -0
  234. package/src/loader-store.ts +7 -4
  235. package/src/prerender/build-shell-capture.ts +73 -22
  236. package/src/reverse.ts +44 -4
  237. package/src/route-definition/dsl-helpers.ts +121 -33
  238. package/src/route-definition/helpers-types.ts +33 -9
  239. package/src/route-definition/resolve-handler-use.ts +121 -6
  240. package/src/route-types.ts +0 -3
  241. package/src/router/debug-manifest.ts +10 -2
  242. package/src/router/error-handling.ts +51 -15
  243. package/src/router/handler-context.ts +71 -28
  244. package/src/router/instrument.ts +54 -2
  245. package/src/router/intercept-resolution.ts +141 -43
  246. package/src/router/loader-resolution.ts +115 -39
  247. package/src/router/match-api.ts +40 -26
  248. package/src/router/match-handlers.ts +5 -0
  249. package/src/router/match-middleware/background-revalidation.ts +161 -96
  250. package/src/router/match-middleware/cache-lookup.ts +110 -10
  251. package/src/router/match-middleware/cache-store.ts +48 -101
  252. package/src/router/middleware-types.ts +9 -6
  253. package/src/router/middleware.ts +75 -13
  254. package/src/router/prerender-match.ts +59 -19
  255. package/src/router/route-snapshot.ts +11 -1
  256. package/src/router/router-context.ts +2 -0
  257. package/src/router/router-interfaces.ts +25 -2
  258. package/src/router/router-options.ts +8 -5
  259. package/src/router/segment-resolution/fresh.ts +62 -21
  260. package/src/router/segment-resolution/helpers.ts +4 -2
  261. package/src/router/segment-resolution/loader-cache.ts +407 -76
  262. package/src/router/segment-resolution/loader-mask.ts +12 -22
  263. package/src/router/segment-resolution/loader-snapshot.ts +208 -56
  264. package/src/router/segment-resolution/mask-nested.ts +138 -44
  265. package/src/router/segment-resolution/revalidation.ts +61 -16
  266. package/src/router/segment-wrappers.ts +4 -0
  267. package/src/rsc/full-payload.ts +25 -1
  268. package/src/rsc/handler.ts +14 -2
  269. package/src/rsc/progressive-enhancement.ts +3 -2
  270. package/src/rsc/render-pipeline.ts +3 -0
  271. package/src/rsc/response-cache-serve.ts +9 -6
  272. package/src/rsc/response-route-handler.ts +11 -3
  273. package/src/rsc/rsc-rendering.ts +608 -225
  274. package/src/rsc/shell-build-manifest.ts +27 -9
  275. package/src/rsc/shell-capture-constants.ts +73 -6
  276. package/src/rsc/shell-capture.ts +1068 -296
  277. package/src/rsc/shell-serve.ts +316 -34
  278. package/src/rsc/ssr-setup.ts +14 -8
  279. package/src/rsc/types.ts +18 -0
  280. package/src/server/context.ts +300 -32
  281. package/src/server/cookie-store.ts +87 -61
  282. package/src/server/handle-store.ts +232 -7
  283. package/src/server/request-context.ts +297 -67
  284. package/src/ssr/index.tsx +136 -44
  285. package/src/ssr/ssr-root.tsx +9 -8
  286. package/src/static-handler.ts +4 -1
  287. package/src/testing/flight-runtime.d.ts +21 -0
  288. package/src/testing/flight.entry.ts +14 -0
  289. package/src/testing/generated-routes.ts +2 -2
  290. package/src/testing/internal/context.ts +1 -1
  291. package/src/testing/internal/flight-client-globals.ts +7 -5
  292. package/src/testing/render-route.tsx +85 -24
  293. package/src/testing/run-loader.ts +68 -6
  294. package/src/testing/serve-shell-request.ts +378 -0
  295. package/src/testing/shell-status.ts +34 -12
  296. package/src/testing/vitest-stubs/plugin-rsc.ts +123 -20
  297. package/src/testing/vitest.ts +62 -1
  298. package/src/theme/ThemeProvider.tsx +7 -6
  299. package/src/theme/ThemeScript.tsx +3 -3
  300. package/src/types/cache-types.ts +14 -10
  301. package/src/types/handler-context.ts +28 -1
  302. package/src/types/loader-types.ts +8 -6
  303. package/src/urls/pattern-types.ts +22 -18
  304. package/src/urls/response-types.ts +3 -23
  305. package/src/use-loader.tsx +12 -3
  306. package/src/vite/discovery/shell-prerender-phase.ts +9 -0
  307. package/src/vite/plugins/use-cache-transform.ts +118 -74
  308. package/src/vite/rango.ts +7 -3
  309. package/src/vite/router-discovery.ts +14 -4
@@ -33,11 +33,11 @@ export interface SsrHtmlStageOptions<TEnv> {
33
33
  /** Metrics store for ssr:module-load / ssr:stream-mode timing (per call site). */
34
34
  metricsStore: MetricsStore | undefined;
35
35
  /**
36
- * renderHTML options minus streamMode (the stage resolves streamMode). Carries
37
- * the per-site nonce and, for the PE action re-render, formState. Spread
38
- * verbatim so each call site's exact key set is preserved.
36
+ * renderHTML options minus streamMode and onError (the stage owns both).
37
+ * Carries the per-site nonce and, for the PE action re-render, formState.
38
+ * Spread verbatim so each call site's exact key set is preserved.
39
39
  */
40
- render: Omit<SSRRenderOptions, "streamMode">;
40
+ render: Omit<SSRRenderOptions, "streamMode" | "onError">;
41
41
  /** ResponseInit merged into the prepared render (e.g. content-type). */
42
42
  init?: ResponseInit;
43
43
  }
@@ -59,8 +59,8 @@ export declare function getSSRSetup<TEnv>(ctx: HandlerContext<TEnv>, request: Re
59
59
  * Classify whether a request may require SSR (HTML rendering).
60
60
  *
61
61
  * Returns false for requests that are definitively RSC-only: transport
62
- * params (partial/action/loader/__rsc), prerender collection, or an explicit
63
- * Accept: text/x-component. Must never return false for a request whose
62
+ * params (partial/action/loader/__rsc) or an explicit Accept:
63
+ * text/x-component. Must never return false for a request whose
64
64
  * render-time decision (isRscRequest) will be HTML — the two share
65
65
  * acceptsFlightExplicitly so the Accept rule cannot drift. document-cache.ts
66
66
  * keys its HTML/RSC response slots off this function, so any divergence from
@@ -181,6 +181,12 @@ export interface SSRRenderOptions {
181
181
  * the browser across hydration. Absent on host-agnostic build captures.
182
182
  */
183
183
  origin?: string;
184
+ /**
185
+ * Called for each error Fizz reports through its onError: a component that
186
+ * threw inside a Suspense boundary, which leaves the boundary errored in an
187
+ * otherwise completed document. React's default console.error is kept.
188
+ */
189
+ onError?: (error: unknown) => void;
184
190
  }
185
191
  /**
186
192
  * SSR module interface for HTML rendering
@@ -200,6 +206,15 @@ export interface SSRModule {
200
206
  maxWaitMs?: number;
201
207
  search?: string;
202
208
  origin?: string;
209
+ /** Each component error the prerender reports (never the capture's own abort). */
210
+ onError?: (error: unknown) => void;
211
+ /**
212
+ * React's errorInfo for each task still pending at the capture's abort
213
+ * (its componentStack is computed when read).
214
+ */
215
+ onAbortedTask?: (errorInfo: {
216
+ componentStack?: string;
217
+ } | undefined) => void;
203
218
  }) => Promise<{
204
219
  prelude: Uint8Array;
205
220
  postponed: string | null;
@@ -217,6 +232,8 @@ export interface SSRModule {
217
232
  nonce?: string;
218
233
  search?: string;
219
234
  origin?: string;
235
+ /** Each component error the resumed holes report. */
236
+ onError?: (error: unknown) => void;
220
237
  }) => Promise<ReadableStream<Uint8Array>>;
221
238
  }
222
239
  /**
@@ -2,6 +2,7 @@ import { AsyncLocalStorage } from "node:async_hooks";
2
2
  import type { ReactNode } from "react";
3
3
  import type { PartialCacheOptions, ErrorBoundaryHandler, Handler, LoaderDefinition, MiddlewareFn, NotFoundBoundaryHandler, ShouldRevalidateFn, TransitionConfig } from "../types";
4
4
  import type { DefaultRouteName } from "../types/global-namespace.js";
5
+ import type { ContextVar } from "../context-var.js";
5
6
  /**
6
7
  * Performance metric entry for a single measured operation
7
8
  *
@@ -44,6 +45,17 @@ export type EntryPropCommon = {
44
45
  id: string;
45
46
  shortCode: string;
46
47
  parent: EntryData | null;
48
+ /**
49
+ * Orphan siblings only (attachOrphanSibling in
50
+ * route-definition/dsl-helpers.ts): the entry whose `layout[]` holds this
51
+ * one. `parent` stays null on an orphan (matchError's matched-id stack in
52
+ * router/match-api.ts starts at the boundary-holding entry, possibly an
53
+ * orphan, and must stop there), so the boundary walkers in
54
+ * router/error-handling.ts follow this instead. A lookup that starts at an
55
+ * orphan (its loaders, an intercept it declares) then reaches the owner's
56
+ * boundaries and the owner's ancestors.
57
+ */
58
+ orphanOwner?: EntryData;
47
59
  /** Cache configuration for this entry (set by cache() DSL) */
48
60
  cache?: EntryCacheConfig;
49
61
  /** URL prefix from include() scope, used for MountContext on client */
@@ -94,6 +106,15 @@ export type LoaderEntry = {
94
106
  * appears on navigation-lane entries.
95
107
  */
96
108
  awaitBeforeFlush?: true;
109
+ /**
110
+ * loader(Def, { ssr: false }) on every DSL evaluation, document and
111
+ * navigation: the loader's PPR bake lane (loader-cache.ts
112
+ * resolveLoaderData). The bake/seed key rides on it, so a client
113
+ * navigation's shell replay pins exactly the loaders a document HIT pins,
114
+ * whatever the entry's loading(). awaitBeforeFlush cannot carry that: a
115
+ * navigation evaluation never has it.
116
+ */
117
+ bake?: true;
97
118
  };
98
119
  /**
99
120
  * Segments state for intercept context
@@ -156,9 +177,6 @@ export type InterceptEntry = {
156
177
  routeName: string;
157
178
  handler: ReactNode | Handler<any, any, any>;
158
179
  middleware: MiddlewareFn<any, any>[];
159
- revalidate: ShouldRevalidateFn<any, any>[];
160
- errorBoundary: (ReactNode | ErrorBoundaryHandler)[];
161
- notFoundBoundary: (ReactNode | NotFoundBoundaryHandler)[];
162
180
  loader: LoaderEntry[];
163
181
  loading?: ReactNode | false;
164
182
  transition?: TransitionConfig;
@@ -399,10 +417,113 @@ export declare function getParallelSlotCount(parallels: ParallelEntries | EntryD
399
417
  export declare function track(label: string, depth?: number): () => void;
400
418
  /**
401
419
  * Check if the current execution is inside a cache() DSL boundary.
402
- * Returns false inside loader execution — loaders are always fresh
403
- * (never cached), so non-cacheable reads are safe.
420
+ * Returns false inside loader execution: a route cache() does not store
421
+ * loader values, so non-cacheable reads are safe. A loader bound with its own
422
+ * cache() stores its value; recordLoaderIdentityRead guards that.
404
423
  */
405
424
  export declare function isInsideCacheScope(): boolean;
425
+ /**
426
+ * Throw if called during the ACTIVE background shell-capture render
427
+ * (`_shellCaptureRun` true on the derived request context built by
428
+ * shell-capture.ts). The captured shell is shared across every user hitting
429
+ * the URL, so a request-scoped read here would bake one user's cookies,
430
+ * headers, or per-request variables into markup served to others — same
431
+ * hazard as the cache scopes above, at the document tier. DSL segment loaders
432
+ * need no exemption: the live lane is masked (never executed) during capture,
433
+ * and the bake lane is exactly what this guard exists for.
434
+ *
435
+ * It covers everything the capture waits for, not only synchronous handler
436
+ * code: a promise the handler passes or pushes, an async server component,
437
+ * and a loader the handler awaits (`await ctx.use(Loader)`) all run under the
438
+ * capture context and all bake. The last one used to be exempt (the
439
+ * consumption-lane rule, #672/#674): while a HIT re-ran handlers, a slot
440
+ * handler's `ctx.use` of an identity loader rendered per visitor on the HIT.
441
+ * Now every HIT replays the capture's copy, so the exemption would bake the
442
+ * capturing request's identity into every visitor's page. The cache()
443
+ * guards above keep it (a cache() HIT is a separate tier).
444
+ *
445
+ * Keys off `_shellCaptureRun`, NOT the `_shellCapture` descriptor: the descriptor
446
+ * is also present during the FOREGROUND render (it means "a capture is wanted"),
447
+ * and the foreground must read cookies/headers normally to serve the real user.
448
+ * Only the derived capture context sets `_shellCaptureRun`.
449
+ *
450
+ * Applies only to the READ surfaces (cookies(), headers(), a { cache: false }
451
+ * variable, and the theme reads through tripShellCaptureGuard) whose values
452
+ * become markup. Response directives
453
+ * (invalidateClientCache(), keepClientCache()) stay callable: during capture
454
+ * they are header effects on a discarded response, and on the live HIT path
455
+ * the full pipeline runs so their headers flow to the client normally.
456
+ *
457
+ * The throw can be caught by the code that made the read, so the guard also
458
+ * flags the capture context; the capture refuses on the flag
459
+ * (shell-capture.ts refuseOnCaptureGuard), nothing is stored, and every
460
+ * request keeps getting the normal axis-1 render.
461
+ */
462
+ export declare function assertNotInsideShellCapture(ctx: unknown, fnName: string): void;
463
+ /**
464
+ * True when `ctx` is the active capture render (assertNotInsideShellCapture
465
+ * above). On true the capture context is flagged with the read (`surface`,
466
+ * e.g. "cookies()", "ctx.theme") and the fix the refusal warning gives, plus
467
+ * the loader body (if any) that made the read, and the caller throws.
468
+ */
469
+ export declare function tripShellCaptureGuard(ctx: unknown, surface: string, fix: string): boolean;
470
+ /**
471
+ * Read guard for a non-cacheable variable (`createVar({ cache: false })` or a
472
+ * `ctx.set(..., { cache: false })` write). Callers check isNonCacheable() first
473
+ * so ordinary reads never reach the scope lookups.
474
+ *
475
+ * Throws during a PPR shell capture (`requestCtx` is the ambient request
476
+ * context; assertNotInsideShellCapture): the shell is shared per host+URL.
477
+ *
478
+ * Throws inside a "use cache" body: the key does not include the value, so the
479
+ * first caller's value would be stored and served to later callers (#925). A
480
+ * loader body entered INSIDE the cached function is exempt, the same baked-copy
481
+ * trade isInsideCacheScope() makes for cache(). A cached function called FROM a
482
+ * loader is not: the loader re-runs, the cached body does not. The body scope
483
+ * records the exec scope it was entered in, so the exemption holds only while
484
+ * that is still the innermost one.
485
+ */
486
+ export declare function assertNonCacheableReadAllowed(keyOrVar: string | ContextVar<unknown>, requestCtx?: unknown): void;
487
+ /** How the identity error words a read: a function call or a property read. */
488
+ export type LoaderIdentityReadVerb = "called" | "read";
489
+ /** A request-identity read a loader execution made (recordLoaderIdentityRead). */
490
+ export interface LoaderIdentityRead {
491
+ /**
492
+ * The read as the error names it: "cookies()", "headers()",
493
+ * `ctx.get() for a non-cacheable variable "x"`, "ctx.theme" or
494
+ * "getRequestContext().theme".
495
+ */
496
+ surface: string;
497
+ /** "called" for a function, "read" for a property (the theme getters). */
498
+ verb: LoaderIdentityReadVerb;
499
+ /** The loader body that made the read. */
500
+ bodyId: string | undefined;
501
+ /**
502
+ * The cached loader whose value carries a read another loader made
503
+ * (loader-cache.ts identity mark): its readers read it through `via`.
504
+ */
505
+ via?: string;
506
+ }
507
+ /**
508
+ * Record a request-identity read (cookies(), headers(), a non-cacheable
509
+ * ctx.get()) on the current loader execution (#972).
510
+ *
511
+ * isInsideCacheScope() exempts loader bodies because a route cache() never
512
+ * stores their values. A loader bound with its own cache() does: with no key()
513
+ * and no store keyGenerator its entry is keyed by loader, host, path and
514
+ * params only, and an enclosing route cache() key does not partition it
515
+ * (#974). A cookies() read there stored the first visitor's session and served
516
+ * it to everyone for the TTL. The read is recorded on the execution, not
517
+ * thrown at the call: a reader that starts the loader before its binding does
518
+ * runs it outside any fill, and the binding's MISS then reuses that run. The
519
+ * fill checks what its execution recorded, through the same links as its tags
520
+ * (cache-tag.ts recordedIdentityRead), so both orders fail the same way.
521
+ * Response directives do not record: a key cannot make a skipped body's side
522
+ * effect reach a HIT.
523
+ */
524
+ export declare function recordLoaderIdentityRead(surface: string, verb?: LoaderIdentityReadVerb): void;
525
+ /** The error a loader cache() fill with no declared key fails with (#972). */
526
+ export declare function loaderCacheIdentityError(read: LoaderIdentityRead, cachedLoaderId: string): Error;
406
527
  /**
407
528
  * Check if the current execution is inside a DSL loader scope
408
529
  * (wrapped by runInsideLoaderScope). Used by rendered() barrier
@@ -416,6 +537,10 @@ export declare function isInsideLoaderScope(): boolean;
416
537
  * Takes scalars so the already-latched path allocates nothing.
417
538
  */
418
539
  export declare function latchCachedHeaderScope(kind: CachedHeaderScope["kind"], routeKey?: string): void;
540
+ /** True inside ANY loader execution — DSL loader scope or a loader body
541
+ * (however invoked). The "loaders always re-run fresh" exemptions key off
542
+ * this. */
543
+ export declare function isInsideAnyLoaderScope(): boolean;
419
544
  /**
420
545
  * The one ppr opt-in predicate: a page route entry that DECLARED `ppr`
421
546
  * (`false` and undefined mean plain axis 1). Shared by the serve path
@@ -488,26 +613,25 @@ export declare function runInsideLoaderScope<T>(fn: () => T): T;
488
613
  * and handler-invoked via ctx.use) so request-scoped reads inside a loader
489
614
  * never trip the cache-scope guards — loaders always run fresh.
490
615
  */
491
- export declare function runInsideLoaderBodyScope<T>(fn: () => T, loaderId?: string, handlerInvoked?: boolean): T;
616
+ export declare function runInsideLoaderBodyScope<T>(fn: () => T, loaderId?: string, tags?: Set<string>): T;
617
+ /** The innermost loader body's execution tag set (runInsideLoaderBodyScope). */
618
+ export declare function getLoaderBodyTags(): Set<string> | undefined;
492
619
  /**
493
620
  * The $$id of the loader whose body is currently executing, or undefined
494
621
  * outside any loader body. Used by the shell-capture identity guard
495
- * (cookie-store.ts) so its refusal warning can name the loader that read
622
+ * (assertNotInsideShellCapture) so its refusal warning can name the loader that read
496
623
  * cookies()/headers() instead of blaming a lane it cannot see — the old
497
624
  * hardcoded "bake-lane loader" text misled a live-lane debugging session
498
625
  * (issue #672, secondary).
499
626
  */
500
627
  export declare function getCurrentLoaderBodyId(): string | undefined;
501
628
  /**
502
- * True while a HANDLER-invoked loader body (`await ctx.use(Loader)` from a
503
- * handler, not the DSL segment funnel) is executing. The consumption-lane
504
- * rule keys off this: handler consumption yields a BAKED copy in every shared
505
- * artifact — cache(), "use cache", and the PPR shell — so the shell-capture
506
- * identity guard (cookie-store.ts) permits cookies()/headers() here, exactly
507
- * like the cache-purity guards do. DSL segment loaders (live lane masked at
508
- * capture, bake lane guarded) never set the flag.
629
+ * True while `loaderId`'s body, or a loader it awaits via ctx.use at any
630
+ * depth, is executing. The loader-level cache records these pushes
631
+ * (loader-cache.ts): a HIT skips the cached body, so a dep that no other
632
+ * reader runs in that request only reaches the page through the replay.
509
633
  */
510
- export declare function isInsideHandlerInvokedLoaderBody(): boolean;
634
+ export declare function isInsideLoaderBody(loaderId: string): boolean;
511
635
  /**
512
636
  * Check if the current execution is inside a handle push callback (sync or an
513
637
  * async callback's continuation). Used by the handler-to-loader deadlock guard
@@ -63,6 +63,27 @@ export interface ReadonlyHeaders {
63
63
  [Symbol.iterator](): HeadersIterator<[string, string]>;
64
64
  }
65
65
  type HeadersIterator<T> = IterableIterator<T>;
66
+ /** The public reads of the visitor's theme cookie that assertThemeReadAllowed guards. */
67
+ export type ThemeReadSurface = "ctx.theme" | "getRequestContext().theme";
68
+ /**
69
+ * Guard for a read of the visitor's theme: the handler and middleware
70
+ * `ctx.theme` (handler-context.ts, middleware.ts) and `getRequestContext().theme`
71
+ * (request-context.ts). The theme is the visitor's theme cookie, so it is an
72
+ * identity read like cookies(): it refuses in the same scopes, in the same
73
+ * order (refusingCacheScope, then tripShellCaptureGuard in context.ts), with
74
+ * the same exemption (a loader body under cache(); at capture there is none).
75
+ * Before #971 each read was a plain cookie read, so a ppr shell, a cache()
76
+ * entry or a "use cache" entry stored the first visitor's theme and served it
77
+ * to every later visitor.
78
+ *
79
+ * A read the guards allow is recorded on the current loader execution, as a
80
+ * cookies() read method records it (#972, recordLoaderIdentityRead).
81
+ *
82
+ * `ctx` is the request context at read time, as cookies() reads it. The
83
+ * router's own payload read (payloadInitialTheme, rsc/full-payload.ts) goes
84
+ * through the unguarded `_readTheme()`.
85
+ */
86
+ export declare function assertThemeReadAllowed(ctx: unknown, surface: ThemeReadSurface): void;
66
87
  /**
67
88
  * Get the original request headers (read-only).
68
89
  *
@@ -71,8 +71,23 @@ export interface HandleStore {
71
71
  * Push handle data for a specific handle and segment.
72
72
  * Multiple pushes to the same handle/segment accumulate in an array.
73
73
  * Each push triggers an emission on the stream.
74
+ *
75
+ * `loaderPush` overrides the push-time DSL-loader tag
76
+ * (isInsideLoaderScope()) that getDataForSegment(id, true) excludes. The
77
+ * PPR shell capture passes false for the bake-lane pushes its record keeps
78
+ * (shell-capture.ts deriveShellCaptureContext), with `owner` set to the
79
+ * pushing loader's id so the record can restore them through pushReplayed
80
+ * (getRecordOwners).
74
81
  */
75
- push(handleName: string, segmentId: string, data: unknown): void;
82
+ push(handleName: string, segmentId: string, data: unknown, loaderPush?: boolean, owner?: string): void;
83
+ /**
84
+ * push() a loader-cache HIT's replayed value, recorded from `loaderId`'s
85
+ * body (loader-cache.ts replayLoaderHandles). If that loader then runs live
86
+ * in this request, its first push removes every value replayed for it and
87
+ * takes the first one's position (later live pushes follow it), so the
88
+ * handle output stays live without a duplicate.
89
+ */
90
+ pushReplayed(handleName: string, segmentId: string, data: unknown, loaderId: string): void;
76
91
  /**
77
92
  * Get all collected handle data after all handlers have settled.
78
93
  * Waits for `settled` (handler lane), then returns the data at that point.
@@ -100,8 +115,17 @@ export interface HandleStore {
100
115
  /**
101
116
  * Get handle data for a specific segment (for caching).
102
117
  * Returns data in format: { handleName: [values...] }
118
+ *
119
+ * `excludeLoaderPushes` drops values tagged as DSL-loader pushes at push
120
+ * time (see push); see captureHandles.
121
+ */
122
+ getDataForSegment(segmentId: string, excludeLoaderPushes?: boolean): Record<string, unknown[]>;
123
+ /**
124
+ * The push `owner` of each value in getDataForSegment(segmentId, true),
125
+ * index-aligned per handle (null: no owner). Handles without an owned
126
+ * value are omitted; undefined when none has one.
103
127
  */
104
- getDataForSegment(segmentId: string): Record<string, unknown[]>;
128
+ getRecordOwners(segmentId: string): Record<string, (string | null)[]> | undefined;
105
129
  /**
106
130
  * Replay cached handle data back into the store (for cache hits).
107
131
  * Used to restore handle data when serving cached segments.