@rangojs/router 0.16.0 → 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 (245) 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 +7 -4
  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 +33 -9
  32. package/dist/types/route-definition/resolve-handler-use.d.ts +23 -1
  33. package/dist/types/route-types.d.ts +1 -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/types/cache-types.d.ts +14 -10
  67. package/dist/types/types/handler-context.d.ts +14 -0
  68. package/dist/types/types/loader-types.d.ts +8 -6
  69. package/dist/types/urls/response-types.d.ts +3 -12
  70. package/dist/types/use-loader.d.ts +12 -3
  71. package/dist/types/vite/plugins/use-cache-transform.d.ts +33 -2
  72. package/dist/types/vite/rango.d.ts +1 -1
  73. package/dist/vite/index.js +1381 -1346
  74. package/package.json +2 -2
  75. package/skills/api-client/SKILL.md +22 -10
  76. package/skills/breadcrumbs/SKILL.md +65 -22
  77. package/skills/bundle-analysis/SKILL.md +22 -22
  78. package/skills/cache-guide/SKILL.md +207 -97
  79. package/skills/caching/SKILL.md +295 -93
  80. package/skills/catalog.json +16 -16
  81. package/skills/client-urls/SKILL.md +53 -31
  82. package/skills/cloudflare/SKILL.md +72 -20
  83. package/skills/cloudflare/references/d1-and-local-dev.md +15 -2
  84. package/skills/cloudflare/references/streaming-and-deploy.md +10 -3
  85. package/skills/cloudflare/references/webhooks-and-crypto.md +9 -2
  86. package/skills/comparison/SKILL.md +5 -0
  87. package/skills/comparison/references/framework-comparison.md +39 -33
  88. package/skills/composability/SKILL.md +38 -29
  89. package/skills/css/SKILL.md +10 -13
  90. package/skills/debug-manifest/SKILL.md +74 -31
  91. package/skills/defer-hydration/SKILL.md +2 -1
  92. package/skills/deployment-caching/SKILL.md +6 -1
  93. package/skills/document-cache/SKILL.md +92 -28
  94. package/skills/fonts/SKILL.md +16 -8
  95. package/skills/handler-use/SKILL.md +53 -17
  96. package/skills/hooks/SKILL.md +28 -20
  97. package/skills/hooks/data.md +23 -3
  98. package/skills/hooks/handle-and-actions.md +31 -16
  99. package/skills/hooks/navigation.md +39 -10
  100. package/skills/hooks/outlets.md +13 -6
  101. package/skills/hooks/state.md +37 -15
  102. package/skills/hooks/urls.md +7 -5
  103. package/skills/host-router/SKILL.md +64 -12
  104. package/skills/i18n/SKILL.md +60 -34
  105. package/skills/intercept/SKILL.md +161 -26
  106. package/skills/layout/SKILL.md +106 -50
  107. package/skills/links/SKILL.md +51 -19
  108. package/skills/loader/SKILL.md +242 -106
  109. package/skills/middleware/SKILL.md +119 -23
  110. package/skills/migrate-nextjs/SKILL.md +100 -45
  111. package/skills/migrate-nextjs/backend-host-swap.md +5 -2
  112. package/skills/migrate-react-router/SKILL.md +49 -38
  113. package/skills/migrate-react-router/component-migration.md +25 -6
  114. package/skills/migrate-react-router/data-and-actions.md +18 -5
  115. package/skills/migrate-react-router/route-mapping.md +12 -6
  116. package/skills/mime-routes/SKILL.md +12 -7
  117. package/skills/observability/SKILL.md +28 -14
  118. package/skills/parallel/SKILL.md +75 -39
  119. package/skills/ppr/SKILL.md +345 -150
  120. package/skills/prerender/SKILL.md +189 -100
  121. package/skills/rango/SKILL.md +65 -34
  122. package/skills/react-compiler/SKILL.md +6 -5
  123. package/skills/response-routes/SKILL.md +133 -25
  124. package/skills/route/SKILL.md +165 -60
  125. package/skills/router-setup/SKILL.md +418 -240
  126. package/skills/scripts/SKILL.md +31 -20
  127. package/skills/server-actions/SKILL.md +220 -59
  128. package/skills/shell-manifest/SKILL.md +12 -7
  129. package/skills/streams-and-websockets/SKILL.md +32 -14
  130. package/skills/tailwind/SKILL.md +37 -33
  131. package/skills/testing/SKILL.md +68 -32
  132. package/skills/testing/cache-prerender.md +55 -29
  133. package/skills/testing/client-components.md +59 -6
  134. package/skills/testing/e2e-parity.md +12 -2
  135. package/skills/testing/flight.md +19 -11
  136. package/skills/testing/handles.md +8 -5
  137. package/skills/testing/loader.md +8 -5
  138. package/skills/testing/middleware.md +8 -3
  139. package/skills/testing/predicates.md +120 -0
  140. package/skills/testing/render-handler.md +70 -22
  141. package/skills/testing/response-routes.md +11 -4
  142. package/skills/testing/reverse-and-types.md +20 -14
  143. package/skills/testing/server-actions.md +12 -3
  144. package/skills/testing/server-tree.md +9 -0
  145. package/skills/testing/setup.md +9 -5
  146. package/skills/theme/SKILL.md +106 -29
  147. package/skills/typesafety/SKILL.md +20 -9
  148. package/skills/typesafety/env-and-bindings.md +126 -47
  149. package/skills/typesafety/generated-files-and-cli.md +26 -14
  150. package/skills/typesafety/params-and-search.md +44 -19
  151. package/skills/typesafety/route-types.md +50 -14
  152. package/skills/use-cache/SKILL.md +200 -82
  153. package/skills/vercel/SKILL.md +21 -11
  154. package/skills/view-transitions/SKILL.md +41 -20
  155. package/src/__augment-tests__/augmented.check.ts +26 -1
  156. package/src/browser/index.ts +2 -2
  157. package/src/browser/navigation-bridge.ts +3 -4
  158. package/src/browser/navigation-transaction.ts +22 -2
  159. package/src/browser/partial-update.ts +35 -25
  160. package/src/browser/react/ScrollRestoration.tsx +6 -6
  161. package/src/browser/rsc-router.tsx +1 -1
  162. package/src/browser/scroll-restoration.ts +53 -6
  163. package/src/cache/cache-exec-scope.ts +37 -4
  164. package/src/cache/cache-key-utils.ts +1 -6
  165. package/src/cache/cache-runtime.ts +230 -61
  166. package/src/cache/cache-scope.ts +76 -12
  167. package/src/cache/document-cache.ts +15 -0
  168. package/src/cache/handle-capture.ts +90 -10
  169. package/src/cache/handle-snapshot.ts +132 -28
  170. package/src/cache/segment-codec.ts +26 -7
  171. package/src/cache/tag-invalidation.ts +4 -3
  172. package/src/cache/taint.ts +1 -1
  173. package/src/cache/types.ts +16 -3
  174. package/src/client.rsc.tsx +10 -9
  175. package/src/client.tsx +5 -4
  176. package/src/components/DefaultDocument.tsx +7 -2
  177. package/src/context-var.ts +6 -5
  178. package/src/escape-script.ts +1 -1
  179. package/src/handles/MetaTags.tsx +13 -11
  180. package/src/handles/Scripts.tsx +11 -10
  181. package/src/handles/meta.ts +2 -2
  182. package/src/handles/script.ts +17 -16
  183. package/src/href-client.ts +1 -1
  184. package/src/html.ts +12 -0
  185. package/src/index.rsc.ts +5 -0
  186. package/src/index.ts +1 -0
  187. package/src/loader-store.ts +7 -4
  188. package/src/prerender/build-shell-capture.ts +8 -11
  189. package/src/reverse.ts +44 -4
  190. package/src/route-definition/dsl-helpers.ts +117 -30
  191. package/src/route-definition/helpers-types.ts +33 -9
  192. package/src/route-definition/resolve-handler-use.ts +121 -6
  193. package/src/route-types.ts +0 -3
  194. package/src/router/debug-manifest.ts +10 -2
  195. package/src/router/error-handling.ts +51 -15
  196. package/src/router/handler-context.ts +34 -25
  197. package/src/router/intercept-resolution.ts +125 -39
  198. package/src/router/loader-resolution.ts +56 -11
  199. package/src/router/match-api.ts +12 -17
  200. package/src/router/match-middleware/background-revalidation.ts +161 -96
  201. package/src/router/match-middleware/cache-lookup.ts +93 -10
  202. package/src/router/match-middleware/cache-store.ts +17 -90
  203. package/src/router/middleware-types.ts +3 -5
  204. package/src/router/middleware.ts +52 -9
  205. package/src/router/prerender-match.ts +53 -19
  206. package/src/router/route-snapshot.ts +11 -1
  207. package/src/router/router-context.ts +2 -0
  208. package/src/router/router-interfaces.ts +25 -2
  209. package/src/router/router-options.ts +8 -5
  210. package/src/router/segment-resolution/fresh.ts +44 -12
  211. package/src/router/segment-resolution/loader-cache.ts +205 -45
  212. package/src/router/segment-resolution/loader-mask.ts +12 -22
  213. package/src/router/segment-resolution/loader-snapshot.ts +6 -6
  214. package/src/router/segment-resolution/mask-nested.ts +7 -7
  215. package/src/router/segment-resolution/revalidation.ts +34 -6
  216. package/src/router/segment-wrappers.ts +4 -0
  217. package/src/rsc/render-pipeline.ts +3 -0
  218. package/src/rsc/response-route-handler.ts +11 -3
  219. package/src/rsc/rsc-rendering.ts +8 -45
  220. package/src/rsc/shell-capture-constants.ts +13 -0
  221. package/src/rsc/shell-capture.ts +111 -90
  222. package/src/rsc/ssr-setup.ts +14 -8
  223. package/src/rsc/types.ts +11 -0
  224. package/src/server/context.ts +88 -11
  225. package/src/server/cookie-store.ts +5 -4
  226. package/src/server/handle-store.ts +232 -7
  227. package/src/server/request-context.ts +35 -30
  228. package/src/ssr/index.tsx +40 -7
  229. package/src/static-handler.ts +4 -1
  230. package/src/testing/flight-runtime.d.ts +21 -0
  231. package/src/testing/generated-routes.ts +2 -2
  232. package/src/testing/internal/context.ts +1 -1
  233. package/src/testing/internal/flight-client-globals.ts +7 -5
  234. package/src/testing/render-route.tsx +85 -24
  235. package/src/testing/run-loader.ts +5 -1
  236. package/src/testing/vitest-stubs/plugin-rsc.ts +123 -20
  237. package/src/testing/vitest.ts +62 -1
  238. package/src/theme/ThemeScript.tsx +3 -3
  239. package/src/types/cache-types.ts +14 -10
  240. package/src/types/handler-context.ts +14 -0
  241. package/src/types/loader-types.ts +8 -6
  242. package/src/urls/response-types.ts +3 -23
  243. package/src/use-loader.tsx +12 -3
  244. package/src/vite/plugins/use-cache-transform.ts +118 -74
  245. package/src/vite/rango.ts +7 -3
@@ -377,9 +377,8 @@ export type DocumentShellCacheEntry = ShellCacheEntry & {
377
377
  /**
378
378
  * The families a shell snapshot pins. The item/segment/response families are
379
379
  * cache-store reads/writes (recorded by RecordingShellStore); the loader family
380
- * pins the settled CONTAINER of a bake-lane loader (a loader on an entry with
381
- * no renderable loading(), executed during capture — see
382
- * docs/design/loader-container-bake.md). Excludes the shell family itself
380
+ * pins the settled CONTAINER of a bake-lane loader (lane rule: see
381
+ * resolveLoaderData, loader-cache.ts). Excludes the shell family itself
383
382
  * (getShell/putShell) — the snapshot rides INSIDE a shell entry, so recording
384
383
  * it would be self-referential.
385
384
  */
@@ -481,6 +480,11 @@ export interface CachedEntryData {
481
480
  * (see handle-snapshot.ts encodeHandles) so Promise/ReactNode handle values
482
481
  * round-trip through JSON-serializing stores instead of being flattened. */
483
482
  handles: string;
483
+ /**
484
+ * Owning loader ids index-aligned with the decoded `handles` values
485
+ * (HandleOwners). Absent: every value restores as a plain replay.
486
+ */
487
+ handleOwners?: HandleOwners;
484
488
  /** Expiration timestamp (ms since epoch) */
485
489
  expiresAt: number;
486
490
  /** Cache tags for invalidation */
@@ -520,3 +524,11 @@ export interface CacheDefaults {
520
524
  * Structure: { handleName: [values...] }
521
525
  */
522
526
  export type SegmentHandleData = Record<string, unknown[]>;
527
+ /**
528
+ * segmentId -> handleName -> the owning loader id of each recorded value, by
529
+ * index (null: not owned). Only a PPR shell capture writes owners: the
530
+ * settled pushes of an `ssr: false` loader's own body, which the record keeps
531
+ * because the prelude rendered them. restoreHandles replays an owned value
532
+ * through HandleStore.pushReplayed, so that loader's live re-run replaces it.
533
+ */
534
+ export type HandleOwners = Record<string, Record<string, (string | null)[]>>;
@@ -1,4 +1,5 @@
1
1
  import { Component, type ReactNode } from "react";
2
+ import * as Html from "./html.js";
2
3
  import { type ClientErrorBoundaryFallbackProps } from "./types";
3
4
  /**
4
5
  * Outlet component - renders child content in layouts
@@ -125,7 +126,7 @@ interface ErrorBoundaryState {
125
126
  * @example
126
127
  * ```tsx
127
128
  * "use client";
128
- * import { ErrorBoundary } from "rsc-router/client";
129
+ * import { ErrorBoundary } from "@rangojs/router/client";
129
130
  *
130
131
  * function MyComponent() {
131
132
  * return (
@@ -172,14 +173,13 @@ export { useSegments, type SegmentsState, } from "./browser/react/use-segments.j
172
173
  export { NavigationProvider, type NavigationProviderProps, } from "./browser/react/NavigationProvider.js";
173
174
  export { Link, type LinkProps, type PrefetchStrategy, type StateOrGetter, type LinkState, } from "./browser/react/Link.js";
174
175
  export { useLinkStatus, type LinkStatus, } from "./browser/react/use-link-status.js";
175
- export { ScrollRestoration, useScrollRestoration, type ScrollRestorationProps, } from "./browser/react/ScrollRestoration.js";
176
+ export { useScrollRestoration, type ScrollRestorationProps, } from "./browser/react/ScrollRestoration.js";
176
177
  export { type Handle } from "./handle.js";
177
178
  export { useHandle } from "./browser/react/use-handle.js";
178
179
  export { Meta } from "./handles/meta.js";
179
- export { MetaTags } from "./handles/MetaTags.js";
180
180
  export type { MetaDescriptor, MetaDescriptorBase } from "./router/types.js";
181
181
  export { Script, type ScriptConfig, type ScriptAttributes, } from "./handles/script.js";
182
- export { Scripts } from "./handles/Scripts.js";
182
+ export { Html };
183
183
  export { Breadcrumbs, type BreadcrumbItem } from "./handles/breadcrumbs.js";
184
184
  export { createLocationState, useLocationState, type LocationStateDefinition, type LocationStateEntry, type LocationStateOptions, } from "./browser/react/location-state.js";
185
185
  export { href, type PatternToPath } from "./href-client.js";
@@ -1,13 +1,14 @@
1
1
  /**
2
2
  * RSC-environment version of client exports
3
3
  *
4
- * This file is used when importing "rsc-router/client" from RSC (server components).
4
+ * This file is used when importing "@rangojs/router/client" from RSC (server components).
5
5
  * It re-exports the server's createLoader so that loader definitions work in both
6
6
  * environments with the same import.
7
7
  *
8
8
  * The bundler uses the "react-server" export condition to select this file
9
9
  * in RSC context, while the regular client.tsx is used in client components.
10
10
  */
11
+ import * as Html from "./html.js";
11
12
  export { Outlet, ParallelOutlet, useOutlet, type OutletState, useLoader, ErrorBoundary, type ErrorBoundaryProps, } from "./client.js";
12
13
  export { useFetchLoader, useRefreshLoaders, type LoadFunction, type UseLoaderResult, type UseFetchLoaderResult, type UseLoaderOptions, } from "./use-loader.js";
13
14
  export { createLoader } from "./route-definition.js";
@@ -22,18 +23,16 @@ export { useNonce } from "./browser/react/nonce-context.js";
22
23
  export { useMount } from "./browser/react/use-mount.js";
23
24
  export { useSegments, type SegmentsState, } from "./browser/react/use-segments.js";
24
25
  export { useLinkStatus, type LinkStatus, } from "./browser/react/use-link-status.js";
25
- export { useScrollRestoration } from "./browser/react/ScrollRestoration.js";
26
+ export { useScrollRestoration, type ScrollRestorationProps, } from "./browser/react/ScrollRestoration.js";
26
27
  export { Link, type LinkProps, type PrefetchStrategy, } from "./browser/react/Link.js";
27
- export { ScrollRestoration, type ScrollRestorationProps, } from "./browser/react/ScrollRestoration.js";
28
28
  export { NavigationProvider, type NavigationProviderProps, } from "./browser/react/NavigationProvider.js";
29
29
  export { href } from "./href-client.js";
30
30
  export { MountContext } from "./browser/react/mount-context.js";
31
31
  export { createHandle, isHandle, type Handle } from "./handle.js";
32
32
  export { Meta } from "./handles/meta.js";
33
- export { MetaTags } from "./handles/MetaTags.js";
34
33
  export type { MetaDescriptor, MetaDescriptorBase } from "./router/types.js";
35
34
  export { Script, type ScriptConfig, type ScriptAttributes, } from "./handles/script.js";
36
- export { Scripts } from "./handles/Scripts.js";
35
+ export { Html };
37
36
  export { Breadcrumbs, type BreadcrumbItem } from "./handles/breadcrumbs.js";
38
37
  export { createLocationState, type LocationStateDefinition, type LocationStateEntry, type LocationStateOptions, } from "./browser/react/location-state-shared.js";
39
38
  export { useHref } from "./browser/react/use-href.js";
@@ -2,8 +2,11 @@ import type { ReactNode, ReactElement } from "react";
2
2
  /**
3
3
  * Default document component that provides a basic HTML structure.
4
4
  * Used when no custom document is provided to createRouter.
5
- * Includes MetaTags for automatic charset, viewport, and route meta support,
6
- * and Scripts (head + body sites) so the Script handle works out of the box.
5
+ * Renders every Html member: Html.Meta (charset, viewport, route meta), head +
6
+ * body Html.Scripts sites for the Script handle, and Html.ScrollRestoration.
7
+ * An app that wants a custom getKey or no scroll restoration passes its own
8
+ * document; rendering a second Html.ScrollRestoration under this one only
9
+ * warns ("[Scroll] Already initialized").
7
10
  *
8
11
  * Uses suppressHydrationWarning on <html> because the theme script
9
12
  * may modify class/style attributes before React hydrates.
@@ -12,7 +12,7 @@
12
12
  * interface PaginationData { current: number; total: number }
13
13
  * export const Pagination = createVar<PaginationData>();
14
14
  *
15
- * // Non-cacheable var — ctx.get(User) throws inside a cache() boundary
15
+ * // Non-cacheable var — ctx.get(User) throws inside cache() or "use cache"
16
16
  * export const User = createVar<UserData>({ cache: false });
17
17
  *
18
18
  * // handler
@@ -25,7 +25,7 @@
25
25
  export interface ContextVar<T> {
26
26
  readonly __brand: "context-var";
27
27
  readonly key: symbol;
28
- /** When false, ctx.get(var) throws inside a cache() boundary. */
28
+ /** When false, ctx.get(var) throws inside cache() or "use cache". */
29
29
  readonly cache: boolean;
30
30
  /** Phantom field to carry the type parameter. Never set at runtime. */
31
31
  readonly __type?: T;
@@ -33,9 +33,10 @@ export interface ContextVar<T> {
33
33
  export interface ContextVarOptions {
34
34
  /**
35
35
  * When false, marks this variable as non-cacheable.
36
- * Reading this var with ctx.get() inside a cache() boundary throws. Use for
37
- * inherently request-specific data (user sessions, auth tokens, etc.) that
38
- * must never be baked into cached segments.
36
+ * Reading this var with ctx.get() inside a cache() boundary or a "use cache"
37
+ * function throws. Use for inherently request-specific data (user sessions,
38
+ * auth tokens, etc.) that must never be baked into cached segments or
39
+ * entries; pass the value into a "use cache" function as an argument.
39
40
  *
40
41
  * @default true
41
42
  */
@@ -39,6 +39,6 @@ export declare function escapeJsonForScript(json: string): string;
39
39
  * source; for untrusted dynamic data, JSON-encode it and read it back, rather than
40
40
  * inlining it as code.
41
41
  *
42
- * Used by the Script handle's <Scripts> renderer for inline `children`.
42
+ * Used by the Script handle's <Html.Scripts> renderer for inline `children`.
43
43
  */
44
44
  export declare function escapeScriptBody(js: string): string;
@@ -1,17 +1,18 @@
1
1
  import type { MetaDescriptorBase } from "../router/types.js";
2
2
  export declare function renderMetaDescriptor(descriptor: MetaDescriptorBase, index: number): React.ReactNode;
3
3
  /**
4
- * Renders all collected meta descriptors from route handlers.
4
+ * Renders all collected meta descriptors from route handlers. Public as
5
+ * `Html.Meta` (`@rangojs/router/client`).
5
6
  *
6
- * Place this component inside the `<head>` element of your document.
7
+ * Place `<Html.Meta />` inside the `<head>` element of your document.
7
8
  * It will automatically update when meta descriptors change during navigation.
8
9
  *
9
10
  * When theme is enabled in router config, also renders the theme initialization
10
11
  * script to prevent FOUC (flash of unstyled content).
11
12
  *
12
- * Deferred (Promise) meta descriptors are resolved BEFORE MetaTags renders —
13
+ * Deferred (Promise) meta descriptors are resolved BEFORE this renders —
13
14
  * server-side on the full/SSR render, client-side before apply on navigation
14
- * (resolve-by-default) — so MetaTags only ever receives resolved descriptors and
15
+ * (resolve-by-default) — so it only ever receives resolved descriptors and
15
16
  * never suspends.
16
17
  */
17
18
  export declare function MetaTags(): React.ReactNode;
@@ -1,9 +1,10 @@
1
1
  /**
2
- * Renders the scripts collected by the Script handle into the document.
2
+ * Renders the scripts collected by the Script handle into the document. Public
3
+ * as `Html.Scripts` (`@rangojs/router/client`).
3
4
  *
4
- * Place `<Scripts />` inside `<head>` (default) and, if you push body scripts,
5
- * `<Scripts position="body" />` at the top of `<body>`. Each site renders the
6
- * configs whose `position` matches; the request CSP nonce is applied
5
+ * Place `<Html.Scripts />` inside `<head>` (default) and, if you push body
6
+ * scripts, `<Html.Scripts position="body" />` at the top of `<body>`. Each site
7
+ * renders the configs whose `position` matches; the request CSP nonce is applied
7
8
  * automatically to every DOCUMENT-RENDERED <script> (consumers never pass it). An
8
9
  * async script first encountered on a soft navigation is injected client-side
9
10
  * where the nonce is unavailable, so it carries no nonce and relies on
@@ -22,11 +23,11 @@
22
23
  * ```tsx
23
24
  * <html>
24
25
  * <head>
25
- * <MetaTags />
26
- * <Scripts />
26
+ * <Html.Meta />
27
+ * <Html.Scripts />
27
28
  * </head>
28
29
  * <body>
29
- * <Scripts position="body" />
30
+ * <Html.Scripts position="body" />
30
31
  * {children}
31
32
  * </body>
32
33
  * </html>
@@ -19,7 +19,7 @@
19
19
  * return (
20
20
  * <html>
21
21
  * <head>
22
- * <MetaTags />
22
+ * <Html.Meta />
23
23
  * </head>
24
24
  * ...
25
25
  * </html>
@@ -33,7 +33,7 @@ import type { MetaDescriptor } from "../router/types.js";
33
33
  * Built-in handle for managing document metadata.
34
34
  *
35
35
  * Use `ctx.use(Meta)` in route handlers to push meta descriptors.
36
- * Use `<MetaTags />` component to render them in the document head.
36
+ * Use the `<Html.Meta />` component to render them in the document head.
37
37
  *
38
38
  * Deferred (Promise) descriptors are resolved before collectMeta runs
39
39
  * (resolve-by-default), so they participate in deduplication and `%s`
@@ -3,22 +3,23 @@
3
3
  * route/layout handlers.
4
4
  *
5
5
  * Push from a SERVER handler with `ctx.use(Script)(config)`; render with the
6
- * `<Scripts />` component (from `@rangojs/router/client`) placed in the Document
7
- * `<head>` (and optionally a second `<Scripts position="body" />` at the top of
8
- * `<body>`). This mirrors the Meta / <MetaTags> pair.
6
+ * `<Html.Scripts />` component (from `@rangojs/router/client`) placed in the
7
+ * Document `<head>` (and optionally a second `<Html.Scripts position="body" />`
8
+ * at the top of `<body>`). This mirrors the Meta / <Html.Meta> pair.
9
9
  *
10
- * The request CSP nonce is applied AUTOMATICALLY by <Scripts> to document-rendered
11
- * scripts; consumers never pass a nonce. (An async script first loaded on a soft
12
- * navigation is injected client-side without a nonce — it relies on
13
- * 'strict-dynamic' or a host allowance; see the EXECUTION CONTRACT below and the
14
- * /scripts skill.) A ScriptConfig is fully serializable (it crosses the
15
- * server -> client handle-collection boundary), so callbacks like onLoad are NOT
16
- * supported — a consumer needing them renders their own "use client" script.
10
+ * The request CSP nonce is applied AUTOMATICALLY by <Html.Scripts> to
11
+ * document-rendered scripts; consumers never pass a nonce. (An async script
12
+ * first loaded on a soft navigation is injected client-side without a nonce —
13
+ * it relies on 'strict-dynamic' or a host allowance; see the EXECUTION CONTRACT
14
+ * below and the /scripts skill.) A ScriptConfig is fully serializable (it
15
+ * crosses the server -> client handle-collection boundary), so callbacks like
16
+ * onLoad are NOT supported — a consumer needing them renders their own
17
+ * "use client" script.
17
18
  *
18
19
  * EXECUTION CONTRACT (see the /scripts skill for the full story):
19
20
  * - Inline (`children`) and ordered external (`src`, optional `defer`) scripts
20
21
  * are DOCUMENT-LOAD scripts: they execute only when present in the initial HTML
21
- * response. <Scripts> freezes them after hydration, so a later client (soft)
22
+ * response. <Html.Scripts> freezes them after hydration, so a later client (soft)
22
23
  * navigation never inserts an inert copy — React creates client-mounted
23
24
  * <script> elements via innerHTML, which the HTML spec makes non-executing.
24
25
  * - Async external scripts (`src` + `async: true`) are React RESOURCES: they load
@@ -64,9 +65,9 @@ export type ScriptAttributes = Omit<ScriptHTMLAttributes<HTMLScriptElement>, "id
64
65
  /** Fields shared by every script shape. */
65
66
  interface ScriptConfigBase {
66
67
  /**
67
- * Where <Scripts> renders this script.
68
- * - "head" (default): the `<head>` <Scripts> site.
69
- * - "body": the `<Scripts position="body" />` site at the top of <body>.
68
+ * Where <Html.Scripts> renders this script.
69
+ * - "head" (default): the `<head>` <Html.Scripts> site.
70
+ * - "body": the `<Html.Scripts position="body" />` site at the top of <body>.
70
71
  * Note: an external `async` script is hoisted into <head> by React regardless.
71
72
  */
72
73
  position?: "head" | "body";
@@ -81,7 +82,7 @@ interface ScriptConfigBase {
81
82
  /**
82
83
  * Inline script: a raw JS body rendered in place, escaped against `</script>`
83
84
  * breakout. DOCUMENT-LOAD only (executes when present in the initial HTML;
84
- * <Scripts> freezes it after hydration so navigation never inserts an inert
85
+ * <Html.Scripts> freezes it after hydration so navigation never inserts an inert
85
86
  * copy). `id` is REQUIRED — inline scripts are never deduped by React, so a
86
87
  * layout and a child pushing the same bootstrap would inject it twice. It is also
87
88
  * rendered as the script's DOM `id`. Forbids `src`/`async`/`defer`. For analytics
@@ -128,7 +129,7 @@ export interface OrderedScriptConfig extends ScriptConfigBase {
128
129
  * inline (`id` + `children`), external async (`src` + `async: true`), or external
129
130
  * ordered (`src`, optional `defer`). Invalid combinations (both `src`+`children`,
130
131
  * `async`+`defer`, inline without `id`) are compile errors. The CSP nonce is
131
- * applied by <Scripts>, never here.
132
+ * applied by <Html.Scripts>, never here.
132
133
  */
133
134
  export type ScriptConfig = InlineScriptConfig | AsyncScriptConfig | OrderedScriptConfig;
134
135
  /**
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * @example
8
8
  * ```typescript
9
- * import { href } from "rsc-router/client";
9
+ * import { href } from "@rangojs/router/client";
10
10
  *
11
11
  * href("/blog/my-post"); // ✓ matches /blog/:slug
12
12
  * href("/shop/product/widget"); // ✓ matches /shop/product/:slug
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Members of the `Html` namespace; client.tsx and client.rsc.tsx expose this
3
+ * module as `import * as Html`. A module namespace, not an object literal, so
4
+ * bundlers drop members an app never renders (a literal kept opt-in
5
+ * ScrollRestoration in every app: +313 B gzip, over the router-chunk ratchet).
6
+ * No "use client": each member stays its own module's client reference, so a
7
+ * server component can dot into `Html`. Pinned by __tests__/html.test.ts and
8
+ * testing/__tests__/html-namespace.rsc-test.tsx.
9
+ */
10
+ export { MetaTags as Meta } from "./handles/MetaTags.js";
11
+ export { Scripts } from "./handles/Scripts.js";
12
+ export { ScrollRestoration } from "./browser/react/ScrollRestoration.js";
@@ -103,7 +103,7 @@ export { Script, type ScriptConfig, type ScriptAttributes, } from "./handles/scr
103
103
  export { Breadcrumbs } from "./handles/breadcrumbs.js";
104
104
  export type { MetaDescriptor, MetaDescriptorBase } from "./router/types.js";
105
105
  export type { BreadcrumbItem } from "./handles/breadcrumbs.js";
106
- export type { ScopedReverseFunction, ReverseFunction, ExtractLocalRoutes, ParamsFor, } from "./reverse.js";
106
+ export type { ScopedReverseFunction, ReverseFunction, GlobalReverseFunction, ExtractLocalRoutes, ParamsFor, } from "./reverse.js";
107
107
  export { scopedReverse } from "./reverse.js";
108
108
  export { createLocationState, type LocationStateDefinition, type LocationStateEntry, type LocationStateOptions, } from "./browser/react/location-state-shared.js";
109
109
  export type { OTelTracer, OTelActiveSpanTracer, OTelSpan, OTelTracingOptions, } from "./router/telemetry-otel.js";
@@ -9,7 +9,7 @@
9
9
  * in RSC context, while the regular index.ts is used in client components.
10
10
  */
11
11
  export { RouteNotFoundError, DataNotFoundError, notFound, MiddlewareError, HandlerError, BuildError, DslContextError, InvalidHandlerError, RouterError, Skip, isSkip, } from "./index.js";
12
- export type { DocumentProps, DefaultEnv, RouteDefinition, RouteConfig, RouteDefinitionOptions, TrailingSlashMode, Handler, HandlerContext, ExtractParams, GenericParams, Middleware, RevalidateParams, Revalidate, ActionRef, IsActionFn, RouteKeys, LoaderDefinition, LoaderFn, LoaderContext, FetchableLoaderOptions, LoadOptions, ErrorInfo, ErrorBoundaryFallbackProps, ErrorBoundaryHandler, ClientErrorBoundaryFallbackProps, NotFoundInfo, NotFoundBoundaryFallbackProps, NotFoundBoundaryHandler, ErrorPhase, OnErrorContext, OnErrorCallback, TransitionConfig, TransitionWhenFn, TransitionWhenContext, ViewTransitionClass, } from "./types.js";
12
+ export type { DocumentProps, DefaultEnv, RouteDefinition, RouteConfig, RouteDefinitionOptions, TrailingSlashMode, Handler, HandlerContext, ExtractParams, GenericParams, Middleware, RevalidateParams, Revalidate, ActionRef, IsActionFn, RouteKeys, LoaderDefinition, LoaderFn, LoaderContext, LoaderOptions, FetchableLoaderOptions, LoadOptions, ErrorInfo, ErrorBoundaryFallbackProps, ErrorBoundaryHandler, ClientErrorBoundaryFallbackProps, NotFoundInfo, NotFoundBoundaryFallbackProps, NotFoundBoundaryHandler, ErrorPhase, OnErrorContext, OnErrorCallback, TransitionConfig, TransitionWhenFn, TransitionWhenContext, ViewTransitionClass, } from "./types.js";
13
13
  export type { RangoOptions, SSRStreamMode, SSROptions, ResolveStreamingContext, } from "./router.js";
14
14
  export type { OriginCheckConfig, OriginCheckContext, OriginCheckPhase, } from "./rsc/origin-guard.js";
15
15
  export type { ShellCaptureDebug, ShellCaptureDebugEvent, } from "./rsc/shell-capture.js";
@@ -23,6 +23,7 @@ export { Prerender, Passthrough, type PrerenderHandlerDefinition, type Passthrou
23
23
  export { Static, type StaticHandlerDefinition, type StaticHandlerOptions, } from "./static-handler.js";
24
24
  export { urls, type PathHelpers, type PathOptions, type PartialPrerenderProps, type UrlPatterns, type IncludeOptions, type IncludeItem, type RouteResponse, type ProblemDetails, type ResponseHandler, type ResponseHandlerContext, type JsonResponseHandler, type TextResponseHandler, type JsonValue, type ResponsePathFn, type JsonResponsePathFn, type TextResponsePathFn, } from "./urls.js";
25
25
  export { createRouter, type Rango, type RootLayoutProps, type RouterRequestInput, } from "./router.js";
26
+ export type { SerializedManifest } from "./debug.js";
26
27
  export type { HandlerCacheConfig } from "./rsc/types.js";
27
28
  export { TRACKING_SEARCH_PARAMS, type CacheSearchParams, } from "./cache/search-params-filter.js";
28
29
  export { Meta } from "./handles/meta.js";
@@ -38,7 +39,7 @@ export { cacheTag } from "./cache/cache-tag.js";
38
39
  export { updateTag, revalidateTag } from "./cache/tag-invalidation.js";
39
40
  export type { MetaDescriptor, MetaDescriptorBase } from "./router/types.js";
40
41
  export type { MiddlewareContext, CookieOptions, MiddlewareFn, } from "./router/middleware.js";
41
- export type { ScopedReverseFunction, ReverseFunction, ExtractLocalRoutes, ParamsFor, } from "./reverse.js";
42
+ export type { ScopedReverseFunction, ReverseFunction, GlobalReverseFunction, ExtractLocalRoutes, ParamsFor, } from "./reverse.js";
42
43
  export { scopedReverse, createReverse } from "./reverse.js";
43
44
  export type { SearchSchema, SearchSchemaValue, ResolveSearchSchema, RouteSearchParams, RouteParams, } from "./search-params.js";
44
45
  export { createLocationState, type LocationStateDefinition, type LocationStateEntry, type LocationStateOptions, } from "./browser/react/location-state-shared.js";
@@ -104,10 +104,13 @@ export declare class LoaderStore {
104
104
  * browser/partial-update.ts calls INSIDE every transition commit, so a
105
105
  * reader whose content is held on screen by that transition pins
106
106
  * `isLoading: true` for the data it is still showing until the transition
107
- * lands (use-loader.tsx). The new tree's own read of the loader suspends at
108
- * the read site and never observes the flag. A Set, not a flag: overlapping
109
- * navigations (second click before the first stream lands) keep the family
110
- * pending until the LAST stream settles.
107
+ * lands (use-loader.tsx). Family-keyed on purpose: a persisting layout
108
+ * reader of the same createLoader the child is re-running is pinned too
109
+ * (the loader is in flight; not "this segment's copy is being replaced" —
110
+ * issue #862, working as designed). The new tree's own read of the loader
111
+ * suspends at the read site and never observes the flag. A Set, not a
112
+ * flag: overlapping navigations (second click before the first stream
113
+ * lands) keep the family pending until the LAST stream settles.
111
114
  */
112
115
  private readonly pendingStreams;
113
116
  private getOrCreate;
@@ -119,6 +119,35 @@ export type ScopedReverseFunction<TLocalRoutes, TGlobalRoutes = TLocalRoutes> =
119
119
  */
120
120
  <TName extends keyof TLocalRoutes & string>(name: `.${TName}`, params: ExtractParams<RoutePatternFor<TLocalRoutes, TName>>, search: ResolveSearchSchema<ExtractSearchSchema<TLocalRoutes, TName>>): string;
121
121
  };
122
+ /**
123
+ * Reverse function that resolves global route names only: no include() scope,
124
+ * no param auto-fill.
125
+ *
126
+ * This is the `ctx.reverse` of middleware (`MiddlewareContext`) and
127
+ * response-route handlers (`ResponseHandlerContext`). On a live request both
128
+ * get `createReverseFunction(routeMap)` with no route name or params (the
129
+ * middleware callers in rsc/handler.ts and rsc/loader-fetch.ts,
130
+ * handleResponseRoute, router/intercept-resolution.ts; mirrored by
131
+ * testing/run-middleware.ts and testing/dispatch.ts), so a dot-local `.name`
132
+ * has no scope to resolve against and throws `Unknown route`. Build-time PPR
133
+ * shell capture (prerender/build-shell-capture.ts) gives global and route
134
+ * middleware the same global-only reverse.
135
+ *
136
+ * - Route map with a string index signature (no generated map, the permissive
137
+ * `Record<string, string>` fallback): any name except a dot-prefixed literal.
138
+ * `Exclude` is required because `keyof` collapses to `string` there, so the
139
+ * global overloads of `ScopedReverseFunction` would accept `.name` too.
140
+ * - Concrete route map: the global overloads of `ScopedReverseFunction`, with
141
+ * name and param validation. The empty local map (`{}`) leaves no dot-prefixed
142
+ * overload that can match.
143
+ *
144
+ * @example
145
+ * ```typescript
146
+ * reverse("blog.post", { slug: "hello" }) // ok: global route + params
147
+ * reverse(".post", { slug: "hello" }) // compile error: no include() scope
148
+ * ```
149
+ */
150
+ export type GlobalReverseFunction<TGlobalRoutes> = string extends keyof TGlobalRoutes ? <TName extends string>(name: Exclude<TName, `.${string}`>, params?: Record<string, string>, search?: Record<string, unknown>) => string : ScopedReverseFunction<{}, TGlobalRoutes>;
122
151
  /**
123
152
  * Extract local routes type from UrlPatterns
124
153
  * Used with scopedReverse() to get the routes type from patterns
@@ -178,11 +207,14 @@ export type { RouteResponse } from "./urls.js";
178
207
  * Get a locally-typed reverse function from ctx.reverse for composable modules.
179
208
  *
180
209
  * This is a type-only cast - ctx.reverse already resolves names at runtime.
181
- * Provides type safety: `.name` validates against local routes,
182
- * `name` validates against global named-routes.
210
+ * Only the module's LOCAL routes are typed: `.name` and bare `name` both
211
+ * validate against the local map (the global map parameter defaults to it).
212
+ * Always dot-prefix local names — a bare name type-checks against the local
213
+ * map but resolves as a global name at runtime. For global names, call
214
+ * ctx.reverse directly.
183
215
  *
184
216
  * @param reverse - The ctx.reverse function from HandlerContext
185
- * @returns The same reverse function, typed with local + global routes
217
+ * @returns The same reverse function, typed with the module's local routes
186
218
  *
187
219
  * @example
188
220
  * ```typescript
@@ -193,7 +225,7 @@ export type { RouteResponse } from "./urls.js";
193
225
  *
194
226
  * reverse(".index"); // ✓ Local route
195
227
  * reverse(".post", { slug: "x" }); // ✓ Local with params
196
- * reverse("shop.cart"); // ✓ Global route
228
+ * ctx.reverse("shop.cart"); // Global route: use ctx.reverse
197
229
  *
198
230
  * return <BlogIndex />;
199
231
  * }, { name: "index" }),
@@ -26,7 +26,7 @@ declare const revalidate: RouteHelpers<any, any>["revalidate"];
26
26
  * When an error occurs during rendering of this segment or its children,
27
27
  * the fallback will be rendered instead. The fallback can be:
28
28
  * - A static ReactNode (e.g., <ErrorPage />)
29
- * - A handler function that receives error info and reset function
29
+ * - A handler function that receives `{ error }` (server fallbacks get no reset)
30
30
  *
31
31
  * Error boundaries catch errors from:
32
32
  * - Middleware execution
@@ -42,11 +42,11 @@ declare const revalidate: RouteHelpers<any, any>["revalidate"];
42
42
  *
43
43
  * // Or with handler for dynamic error UI:
44
44
  * route("products.detail", ProductDetail, () => [
45
- * errorBoundary(({ error, reset }) => (
45
+ * errorBoundary(({ error }) => (
46
46
  * <div>
47
47
  * <h2>Product failed to load</h2>
48
48
  * <p>{error.message}</p>
49
- * <button onClick={reset}>Retry</button>
49
+ * <a href="/products">Back to products</a>
50
50
  * </div>
51
51
  * )),
52
52
  * ])
@@ -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)
@@ -345,7 +367,9 @@ export type RouteHelpers<T extends RouteDefinition, TEnv> = {
345
367
  * content while the new loader resolves instead of flashing the route's
346
368
  * loading() skeleton (see segment-system.tsx inTransitionScope). Held
347
369
  * useLoader readers of the re-run loaders report isLoading: true until
348
- * the new data commits (use-loader.tsx). This is also the precondition
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
349
373
  * for any view-transition animation.
350
374
  * 2. <ViewTransition> (experimental React only): the segment content is also
351
375
  * wrapped in React's <ViewTransition>, so the held swap cross-fades/morphs.
@@ -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;
@@ -156,7 +156,7 @@ export type RouteUseItem = LayoutItem | ParallelItem | InterceptItem | Middlewar
156
156
  /** Items that can be used inside a response route (path.json(), etc.) */
157
157
  export type ResponseRouteUseItem = MiddlewareItem | CacheItem;
158
158
  export type ParallelUseItem = RevalidateItem | LoaderItem | LoadingItem | ErrorBoundaryItem | NotFoundBoundaryItem | TransitionItem;
159
- export type InterceptUseItem = MiddlewareItem | RevalidateItem | LoaderItem | LoadingItem | ErrorBoundaryItem | NotFoundBoundaryItem | LayoutItem | RouteItem | TransitionItem;
159
+ export type InterceptUseItem = MiddlewareItem | LoaderItem | LoadingItem | LayoutItem | RouteItem | TransitionItem;
160
160
  export type LoaderUseItem = RevalidateItem | CacheItem;
161
161
  /**
162
162
  * Allow composition factories in use() callbacks.