@rangojs/router 0.5.1 → 0.6.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 (609) hide show
  1. package/README.md +5 -1
  2. package/dist/bin/rango.js +343 -125
  3. package/dist/types/browser/event-controller.d.ts +6 -0
  4. package/dist/types/browser/react/use-router.d.ts +10 -3
  5. package/dist/types/browser/react/use-search-params.d.ts +57 -10
  6. package/dist/types/browser/types.d.ts +22 -0
  7. package/dist/types/build/merge-full-manifests.d.ts +3 -0
  8. package/dist/types/build/route-trie.d.ts +4 -73
  9. package/dist/types/build/route-types/per-module-writer.d.ts +6 -4
  10. package/dist/types/build/route-types/router-processing.d.ts +2 -3
  11. package/dist/types/cache/cache-exec-scope.d.ts +31 -0
  12. package/dist/types/cache/cf/cf-cache-constants.d.ts +8 -1
  13. package/dist/types/cache/cf/cf-cache-store.d.ts +15 -1
  14. package/dist/types/cache/cf/cf-cache-types.d.ts +1 -1
  15. package/dist/types/cache/cf/cf-kv-utils.d.ts +21 -0
  16. package/dist/types/cache/taint.d.ts +12 -6
  17. package/dist/types/client-urls/client-root.d.ts +38 -0
  18. package/dist/types/client-urls/client-urls.d.ts +5 -0
  19. package/dist/types/client-urls/navigation.d.ts +38 -0
  20. package/dist/types/client-urls/revalidation-protocol.d.ts +25 -0
  21. package/dist/types/client-urls/server-projection.d.ts +62 -0
  22. package/dist/types/client-urls/types.d.ts +144 -0
  23. package/dist/types/client.d.ts +12 -4
  24. package/dist/types/client.rsc.d.ts +4 -1
  25. package/dist/types/decode-loader-results.d.ts +37 -0
  26. package/dist/types/errors.d.ts +1 -0
  27. package/dist/types/handles/is-thenable.d.ts +2 -4
  28. package/dist/types/index.d.ts +1 -1
  29. package/dist/types/loader-redirect.d.ts +27 -0
  30. package/dist/types/outlet-context.d.ts +12 -0
  31. package/dist/types/outlet-provider.d.ts +3 -1
  32. package/dist/types/redirect-origin.d.ts +4 -0
  33. package/dist/types/route-content-wrapper.d.ts +42 -1
  34. package/dist/types/route-definition/helpers-types.d.ts +13 -2
  35. package/dist/types/router/error-handling.d.ts +35 -1
  36. package/dist/types/router/intercept-resolution.d.ts +12 -0
  37. package/dist/types/router/loader-resolution.d.ts +24 -2
  38. package/dist/types/router/revalidation.d.ts +7 -0
  39. package/dist/{types.backup/build/route-trie.d.ts → types/router/route-trie-builder.d.ts} +4 -16
  40. package/dist/types/router/router-interfaces.d.ts +20 -0
  41. package/dist/types/router/segment-resolution/helpers.d.ts +1 -1
  42. package/dist/types/router/trie-matching.d.ts +1 -1
  43. package/dist/types/rsc/helpers.d.ts +3 -0
  44. package/dist/types/rsc/manifest-init.d.ts +5 -5
  45. package/dist/types/rsc/render-pipeline.d.ts +9 -0
  46. package/dist/types/rsc/routine-plan.d.ts +124 -0
  47. package/dist/types/rsc/shell-capture-constants.d.ts +17 -0
  48. package/dist/types/rsc/shell-capture.d.ts +9 -0
  49. package/dist/types/rsc/shell-serve.d.ts +11 -0
  50. package/dist/types/rsc/types.d.ts +30 -0
  51. package/dist/types/segment-system.d.ts +2 -0
  52. package/dist/types/server/context.d.ts +10 -0
  53. package/dist/types/server/handle-store.d.ts +34 -3
  54. package/dist/types/server/request-context.d.ts +14 -1
  55. package/dist/types/server.d.ts +1 -0
  56. package/dist/types/ssr/index.d.ts +22 -0
  57. package/dist/types/ssr/ssr-root.d.ts +10 -0
  58. package/dist/types/testing/dom.entry.d.ts +1 -1
  59. package/dist/types/testing/render-route.d.ts +16 -6
  60. package/dist/types/testing/run-loader.d.ts +9 -0
  61. package/dist/types/types/boundaries.d.ts +22 -0
  62. package/dist/types/types/index.d.ts +1 -1
  63. package/dist/types/types/loader-types.d.ts +57 -5
  64. package/dist/types/types/segments.d.ts +7 -0
  65. package/dist/types/urls/path-helper-types.d.ts +10 -4
  66. package/dist/types/vite/discovery/client-urls-projection.d.ts +53 -0
  67. package/dist/types/vite/discovery/discover-routers.d.ts +1 -1
  68. package/dist/types/vite/discovery/state.d.ts +8 -1
  69. package/dist/types/vite/encryption-key.d.ts +2 -0
  70. package/dist/types/vite/plugins/expose-internal-ids.d.ts +10 -0
  71. package/dist/types/vite/plugins/server-ref-hashing.d.ts +24 -0
  72. package/dist/types/vite/plugins/server-reference-pattern.d.ts +1 -0
  73. package/dist/types/vite/utils/shared-utils.d.ts +12 -0
  74. package/dist/vite/index.js +5101 -2056
  75. package/package.json +3 -3
  76. package/skills/breadcrumbs/SKILL.md +39 -9
  77. package/skills/caching/SKILL.md +1 -1
  78. package/skills/catalog.json +7 -1
  79. package/skills/client-urls/SKILL.md +338 -0
  80. package/skills/comparison/references/framework-comparison.md +23 -9
  81. package/skills/hooks/SKILL.md +2 -2
  82. package/skills/hooks/data.md +11 -2
  83. package/skills/hooks/handle-and-actions.md +7 -0
  84. package/skills/hooks/outlets.md +26 -5
  85. package/skills/hooks/urls.md +40 -3
  86. package/skills/loader/SKILL.md +132 -20
  87. package/skills/migrate-nextjs/SKILL.md +70 -10
  88. package/skills/migrate-react-router/SKILL.md +49 -13
  89. package/skills/migrate-react-router/component-migration.md +18 -13
  90. package/skills/migrate-react-router/data-and-actions.md +14 -3
  91. package/skills/migrate-react-router/route-mapping.md +15 -2
  92. package/skills/mime-routes/SKILL.md +3 -1
  93. package/skills/parallel/SKILL.md +32 -1
  94. package/skills/ppr/SKILL.md +16 -6
  95. package/skills/prerender/SKILL.md +8 -4
  96. package/skills/rango/SKILL.md +21 -17
  97. package/skills/react-compiler/SKILL.md +3 -3
  98. package/skills/response-routes/SKILL.md +4 -2
  99. package/skills/route/SKILL.md +5 -2
  100. package/skills/router-setup/SKILL.md +16 -2
  101. package/skills/scripts/SKILL.md +16 -6
  102. package/skills/shell-manifest/SKILL.md +16 -7
  103. package/skills/testing/SKILL.md +2 -2
  104. package/skills/testing/client-components.md +6 -0
  105. package/skills/testing/handles.md +30 -8
  106. package/skills/testing/loader.md +51 -49
  107. package/skills/testing/middleware.md +1 -1
  108. package/skills/theme/SKILL.md +8 -5
  109. package/skills/typesafety/generated-files-and-cli.md +16 -9
  110. package/skills/typesafety/route-types.md +5 -1
  111. package/skills/use-cache/SKILL.md +47 -0
  112. package/src/bin/rango.ts +7 -3
  113. package/src/browser/event-controller.ts +40 -15
  114. package/src/browser/navigation-bridge.ts +6 -0
  115. package/src/browser/navigation-client.ts +5 -0
  116. package/src/browser/partial-update.ts +77 -10
  117. package/src/browser/react/NavigationProvider.tsx +7 -0
  118. package/src/browser/react/use-router.ts +40 -11
  119. package/src/browser/react/use-search-params.ts +140 -17
  120. package/src/browser/rsc-router.tsx +59 -0
  121. package/src/browser/server-action-bridge.ts +26 -0
  122. package/src/browser/types.ts +22 -0
  123. package/src/build/merge-full-manifests.ts +161 -0
  124. package/src/build/route-trie.ts +9 -332
  125. package/src/build/route-types/include-resolution.ts +66 -11
  126. package/src/build/route-types/per-module-writer.ts +11 -6
  127. package/src/build/route-types/router-processing.ts +184 -153
  128. package/src/build/runtime-discovery.ts +23 -12
  129. package/src/cache/cache-exec-scope.ts +47 -0
  130. package/src/cache/cache-runtime.ts +113 -40
  131. package/src/cache/cf/cf-cache-constants.ts +8 -1
  132. package/src/cache/cf/cf-cache-store.ts +41 -64
  133. package/src/cache/cf/cf-cache-types.ts +1 -1
  134. package/src/cache/cf/cf-kv-utils.ts +38 -0
  135. package/src/cache/segment-codec.ts +21 -5
  136. package/src/cache/taint.ts +28 -9
  137. package/src/client-urls/client-root.tsx +168 -0
  138. package/src/client-urls/client-urls.ts +698 -0
  139. package/src/client-urls/navigation.ts +237 -0
  140. package/src/client-urls/revalidation-protocol.ts +56 -0
  141. package/src/client-urls/server-projection.ts +579 -0
  142. package/src/client-urls/types.ts +195 -0
  143. package/src/client.rsc.tsx +12 -0
  144. package/src/client.tsx +49 -6
  145. package/src/decode-loader-results.ts +113 -0
  146. package/src/errors.ts +14 -0
  147. package/src/handles/deferred-resolution.ts +14 -7
  148. package/src/handles/is-thenable.ts +2 -4
  149. package/src/index.ts +1 -0
  150. package/src/loader-redirect.tsx +64 -0
  151. package/src/outlet-context.ts +12 -0
  152. package/src/outlet-provider.tsx +15 -1
  153. package/src/redirect-origin.ts +29 -0
  154. package/src/route-content-wrapper.tsx +96 -3
  155. package/src/route-definition/dsl-helpers.ts +28 -3
  156. package/src/route-definition/helpers-types.ts +13 -0
  157. package/src/route-definition/redirect.ts +17 -18
  158. package/src/router/error-handling.ts +65 -11
  159. package/src/router/intercept-resolution.ts +29 -0
  160. package/src/router/loader-resolution.ts +261 -28
  161. package/src/router/match-middleware/cache-lookup.ts +24 -15
  162. package/src/router/match-result.ts +7 -0
  163. package/src/router/revalidation.ts +24 -11
  164. package/src/router/route-trie-builder.ts +334 -0
  165. package/src/router/router-interfaces.ts +38 -0
  166. package/src/router/segment-resolution/fresh.ts +47 -0
  167. package/src/router/segment-resolution/helpers.ts +9 -11
  168. package/src/router/segment-resolution/loader-cache.ts +14 -24
  169. package/src/router/segment-resolution/revalidation.ts +20 -1
  170. package/src/router/trie-matching.ts +3 -3
  171. package/src/router.ts +46 -1
  172. package/src/rsc/full-payload.ts +6 -0
  173. package/src/rsc/handler.ts +36 -12
  174. package/src/rsc/helpers.ts +13 -0
  175. package/src/rsc/loader-fetch.ts +2 -2
  176. package/src/rsc/manifest-init.ts +28 -9
  177. package/src/rsc/progressive-enhancement.ts +247 -70
  178. package/src/rsc/render-pipeline.ts +68 -24
  179. package/src/rsc/routine-plan.ts +359 -0
  180. package/src/rsc/rsc-rendering.ts +569 -302
  181. package/src/rsc/server-action.ts +180 -71
  182. package/src/rsc/shell-capture-constants.ts +18 -0
  183. package/src/rsc/shell-capture.ts +104 -21
  184. package/src/rsc/shell-serve.ts +15 -2
  185. package/src/rsc/ssr-setup.ts +10 -1
  186. package/src/rsc/types.ts +31 -2
  187. package/src/segment-system.tsx +83 -26
  188. package/src/server/context.ts +10 -0
  189. package/src/server/cookie-store.ts +19 -19
  190. package/src/server/handle-store.ts +185 -48
  191. package/src/server/request-context.ts +36 -6
  192. package/src/server.ts +7 -0
  193. package/src/ssr/index.tsx +37 -2
  194. package/src/ssr/ssr-root.tsx +30 -2
  195. package/src/testing/dom.entry.ts +1 -1
  196. package/src/testing/render-route.tsx +22 -8
  197. package/src/testing/run-loader.ts +51 -13
  198. package/src/types/boundaries.ts +19 -0
  199. package/src/types/index.ts +1 -0
  200. package/src/types/loader-types.ts +60 -5
  201. package/src/types/segments.ts +7 -0
  202. package/src/urls/include-helper.ts +22 -4
  203. package/src/urls/path-helper-types.ts +14 -1
  204. package/src/use-loader.tsx +67 -6
  205. package/src/vite/discovery/client-urls-projection.ts +322 -0
  206. package/src/vite/discovery/discover-routers.ts +43 -17
  207. package/src/vite/discovery/state.ts +11 -1
  208. package/src/vite/discovery/virtual-module-codegen.ts +20 -0
  209. package/src/vite/encryption-key.ts +29 -0
  210. package/src/vite/plugins/expose-action-id.ts +2 -2
  211. package/src/vite/plugins/expose-internal-ids.ts +46 -0
  212. package/src/vite/plugins/server-ref-hashing.ts +74 -0
  213. package/src/vite/plugins/server-reference-pattern.ts +10 -0
  214. package/src/vite/plugins/virtual-entries.ts +12 -3
  215. package/src/vite/rango.ts +9 -0
  216. package/src/vite/router-discovery.ts +184 -14
  217. package/src/vite/utils/shared-utils.ts +12 -7
  218. package/dist/types.backup/__internal.d.ts +0 -127
  219. package/dist/types.backup/bin/rango.d.ts +0 -1
  220. package/dist/types.backup/browser/action-coordinator.d.ts +0 -57
  221. package/dist/types.backup/browser/action-fence.d.ts +0 -33
  222. package/dist/types.backup/browser/app-shell.d.ts +0 -34
  223. package/dist/types.backup/browser/app-version.d.ts +0 -6
  224. package/dist/types.backup/browser/connection-warmup.d.ts +0 -31
  225. package/dist/types.backup/browser/cookie-name.d.ts +0 -66
  226. package/dist/types.backup/browser/event-controller.d.ts +0 -221
  227. package/dist/types.backup/browser/history-state.d.ts +0 -26
  228. package/dist/types.backup/browser/index.d.ts +0 -1
  229. package/dist/types.backup/browser/intercept-utils.d.ts +0 -30
  230. package/dist/types.backup/browser/invalidate-client-cache.d.ts +0 -17
  231. package/dist/types.backup/browser/link-interceptor.d.ts +0 -43
  232. package/dist/types.backup/browser/logging.d.ts +0 -33
  233. package/dist/types.backup/browser/merge-segment-loaders.d.ts +0 -38
  234. package/dist/types.backup/browser/navigation-bridge.d.ts +0 -27
  235. package/dist/types.backup/browser/navigation-client.d.ts +0 -17
  236. package/dist/types.backup/browser/navigation-store-handle.d.ts +0 -25
  237. package/dist/types.backup/browser/navigation-store.d.ts +0 -95
  238. package/dist/types.backup/browser/navigation-transaction.d.ts +0 -75
  239. package/dist/types.backup/browser/network-error-handler.d.ts +0 -35
  240. package/dist/types.backup/browser/partial-update.d.ts +0 -61
  241. package/dist/types.backup/browser/prefetch/cache.d.ts +0 -183
  242. package/dist/types.backup/browser/prefetch/fetch.d.ts +0 -52
  243. package/dist/types.backup/browser/prefetch/observer.d.ts +0 -27
  244. package/dist/types.backup/browser/prefetch/policy.d.ts +0 -13
  245. package/dist/types.backup/browser/prefetch/queue.d.ts +0 -48
  246. package/dist/types.backup/browser/prefetch/resource-ready.d.ts +0 -28
  247. package/dist/types.backup/browser/rango-state.d.ts +0 -52
  248. package/dist/types.backup/browser/react/Link.d.ts +0 -140
  249. package/dist/types.backup/browser/react/NavigationProvider.d.ts +0 -88
  250. package/dist/types.backup/browser/react/ScrollRestoration.d.ts +0 -78
  251. package/dist/types.backup/browser/react/context.d.ts +0 -54
  252. package/dist/types.backup/browser/react/filter-segment-order.d.ts +0 -35
  253. package/dist/types.backup/browser/react/index.d.ts +0 -1
  254. package/dist/types.backup/browser/react/location-state-shared.d.ts +0 -162
  255. package/dist/types.backup/browser/react/location-state.d.ts +0 -29
  256. package/dist/types.backup/browser/react/mount-context.d.ts +0 -23
  257. package/dist/types.backup/browser/react/nonce-context.d.ts +0 -14
  258. package/dist/types.backup/browser/react/shallow-equal.d.ts +0 -5
  259. package/dist/types.backup/browser/react/use-action.d.ts +0 -61
  260. package/dist/types.backup/browser/react/use-handle.d.ts +0 -21
  261. package/dist/types.backup/browser/react/use-href.d.ts +0 -32
  262. package/dist/types.backup/browser/react/use-link-status.d.ts +0 -36
  263. package/dist/types.backup/browser/react/use-mount.d.ts +0 -24
  264. package/dist/types.backup/browser/react/use-navigation.d.ts +0 -15
  265. package/dist/types.backup/browser/react/use-params.d.ts +0 -21
  266. package/dist/types.backup/browser/react/use-pathname.d.ts +0 -13
  267. package/dist/types.backup/browser/react/use-reverse.d.ts +0 -40
  268. package/dist/types.backup/browser/react/use-router.d.ts +0 -23
  269. package/dist/types.backup/browser/react/use-search-params.d.ts +0 -19
  270. package/dist/types.backup/browser/react/use-segments.d.ts +0 -29
  271. package/dist/types.backup/browser/response-adapter.d.ts +0 -58
  272. package/dist/types.backup/browser/rsc-router.d.ts +0 -141
  273. package/dist/types.backup/browser/scroll-restoration.d.ts +0 -103
  274. package/dist/types.backup/browser/segment-reconciler.d.ts +0 -74
  275. package/dist/types.backup/browser/segment-structure-assert.d.ts +0 -16
  276. package/dist/types.backup/browser/server-action-bridge.d.ts +0 -29
  277. package/dist/types.backup/browser/types.d.ts +0 -530
  278. package/dist/types.backup/browser/validate-redirect-origin.d.ts +0 -28
  279. package/dist/types.backup/build/collect-fallback-refs.d.ts +0 -5
  280. package/dist/types.backup/build/generate-manifest.d.ts +0 -100
  281. package/dist/types.backup/build/generate-route-types.d.ts +0 -8
  282. package/dist/types.backup/build/index.d.ts +0 -21
  283. package/dist/types.backup/build/prefix-tree-utils.d.ts +0 -56
  284. package/dist/types.backup/build/route-types/ast-helpers.d.ts +0 -3
  285. package/dist/types.backup/build/route-types/ast-route-extraction.d.ts +0 -13
  286. package/dist/types.backup/build/route-types/codegen.d.ts +0 -16
  287. package/dist/types.backup/build/route-types/include-resolution.d.ts +0 -74
  288. package/dist/types.backup/build/route-types/param-extraction.d.ts +0 -13
  289. package/dist/types.backup/build/route-types/per-module-writer.d.ts +0 -18
  290. package/dist/types.backup/build/route-types/router-processing.d.ts +0 -82
  291. package/dist/types.backup/build/route-types/scan-filter.d.ts +0 -17
  292. package/dist/types.backup/build/route-types/source-scan.d.ts +0 -13
  293. package/dist/types.backup/build/runtime-discovery.d.ts +0 -24
  294. package/dist/types.backup/cache/background-task.d.ts +0 -21
  295. package/dist/types.backup/cache/cache-error.d.ts +0 -71
  296. package/dist/types.backup/cache/cache-key-utils.d.ts +0 -35
  297. package/dist/types.backup/cache/cache-policy.d.ts +0 -59
  298. package/dist/types.backup/cache/cache-runtime.d.ts +0 -51
  299. package/dist/types.backup/cache/cache-scope.d.ts +0 -134
  300. package/dist/types.backup/cache/cache-tag.d.ts +0 -79
  301. package/dist/types.backup/cache/cf/cf-base64.d.ts +0 -4
  302. package/dist/types.backup/cache/cf/cf-cache-constants.d.ts +0 -105
  303. package/dist/types.backup/cache/cf/cf-cache-store.d.ts +0 -481
  304. package/dist/types.backup/cache/cf/cf-cache-types.d.ts +0 -300
  305. package/dist/types.backup/cache/cf/cf-kv-utils.d.ts +0 -22
  306. package/dist/types.backup/cache/cf/cf-tag-marker-memo.d.ts +0 -15
  307. package/dist/types.backup/cache/cf/index.d.ts +0 -3
  308. package/dist/types.backup/cache/document-cache.d.ts +0 -69
  309. package/dist/types.backup/cache/handle-capture.d.ts +0 -23
  310. package/dist/types.backup/cache/handle-snapshot.d.ts +0 -39
  311. package/dist/types.backup/cache/index.d.ts +0 -7
  312. package/dist/types.backup/cache/memory-segment-store.d.ts +0 -163
  313. package/dist/types.backup/cache/profile-registry.d.ts +0 -40
  314. package/dist/types.backup/cache/read-through-swr.d.ts +0 -60
  315. package/dist/types.backup/cache/segment-codec.d.ts +0 -78
  316. package/dist/types.backup/cache/shell-snapshot.d.ts +0 -162
  317. package/dist/types.backup/cache/tag-invalidation.d.ts +0 -74
  318. package/dist/types.backup/cache/taint.d.ts +0 -71
  319. package/dist/types.backup/cache/types.d.ts +0 -407
  320. package/dist/types.backup/cache/vercel/index.d.ts +0 -1
  321. package/dist/types.backup/cache/vercel/vercel-cache-store.d.ts +0 -267
  322. package/dist/types.backup/client.d.ts +0 -184
  323. package/dist/types.backup/client.rsc.d.ts +0 -39
  324. package/dist/types.backup/cloudflare/index.d.ts +0 -7
  325. package/dist/types.backup/cloudflare/tracing.d.ts +0 -53
  326. package/dist/types.backup/component-utils.d.ts +0 -46
  327. package/dist/types.backup/components/DefaultDocument.d.ts +0 -13
  328. package/dist/types.backup/context-var.d.ts +0 -84
  329. package/dist/types.backup/debug.d.ts +0 -57
  330. package/dist/types.backup/decode-loader-results.d.ts +0 -5
  331. package/dist/types.backup/default-error-boundary.d.ts +0 -10
  332. package/dist/types.backup/defer.d.ts +0 -89
  333. package/dist/types.backup/deps/browser.d.ts +0 -1
  334. package/dist/types.backup/deps/html-stream-client.d.ts +0 -1
  335. package/dist/types.backup/deps/html-stream-server.d.ts +0 -1
  336. package/dist/types.backup/deps/rsc.d.ts +0 -1
  337. package/dist/types.backup/deps/ssr.d.ts +0 -1
  338. package/dist/types.backup/encode-kv.d.ts +0 -35
  339. package/dist/types.backup/errors.d.ts +0 -226
  340. package/dist/types.backup/escape-script.d.ts +0 -44
  341. package/dist/types.backup/handle.d.ts +0 -93
  342. package/dist/types.backup/handles/MetaTags.d.ts +0 -17
  343. package/dist/types.backup/handles/Scripts.d.ts +0 -38
  344. package/dist/types.backup/handles/breadcrumbs.d.ts +0 -43
  345. package/dist/types.backup/handles/deferred-resolution.d.ts +0 -53
  346. package/dist/types.backup/handles/is-thenable.d.ts +0 -12
  347. package/dist/types.backup/handles/meta.d.ts +0 -43
  348. package/dist/types.backup/handles/script.d.ts +0 -139
  349. package/dist/types.backup/host/cookie-handler.d.ts +0 -8
  350. package/dist/types.backup/host/errors.d.ts +0 -40
  351. package/dist/types.backup/host/index.d.ts +0 -33
  352. package/dist/types.backup/host/pattern-matcher.d.ts +0 -30
  353. package/dist/types.backup/host/router.d.ts +0 -12
  354. package/dist/types.backup/host/testing.d.ts +0 -41
  355. package/dist/types.backup/host/types.d.ts +0 -148
  356. package/dist/types.backup/host/utils.d.ts +0 -20
  357. package/dist/types.backup/href-client.d.ts +0 -214
  358. package/dist/types.backup/index.d.ts +0 -112
  359. package/dist/types.backup/index.rsc.d.ts +0 -51
  360. package/dist/types.backup/internal-debug.d.ts +0 -1
  361. package/dist/types.backup/loader-store.d.ts +0 -193
  362. package/dist/types.backup/loader.d.ts +0 -18
  363. package/dist/types.backup/loader.rsc.d.ts +0 -18
  364. package/dist/types.backup/missing-id-error.d.ts +0 -1
  365. package/dist/types.backup/outlet-context.d.ts +0 -12
  366. package/dist/types.backup/outlet-provider.d.ts +0 -12
  367. package/dist/types.backup/prerender/build-shell-capture.d.ts +0 -104
  368. package/dist/types.backup/prerender/param-hash.d.ts +0 -6
  369. package/dist/types.backup/prerender/shell-manifest-key.d.ts +0 -18
  370. package/dist/types.backup/prerender/store.d.ts +0 -62
  371. package/dist/types.backup/prerender.d.ts +0 -292
  372. package/dist/types.backup/redirect-origin.d.ts +0 -55
  373. package/dist/types.backup/regex-escape.d.ts +0 -6
  374. package/dist/types.backup/render-error-thrower.d.ts +0 -13
  375. package/dist/types.backup/response-utils.d.ts +0 -35
  376. package/dist/types.backup/reverse.d.ts +0 -206
  377. package/dist/types.backup/root-error-boundary.d.ts +0 -32
  378. package/dist/types.backup/route-content-wrapper.d.ts +0 -40
  379. package/dist/types.backup/route-definition/dsl-helpers.d.ts +0 -130
  380. package/dist/types.backup/route-definition/helper-factories.d.ts +0 -22
  381. package/dist/types.backup/route-definition/helpers-types.d.ts +0 -392
  382. package/dist/types.backup/route-definition/index.d.ts +0 -7
  383. package/dist/types.backup/route-definition/redirect.d.ts +0 -48
  384. package/dist/types.backup/route-definition/resolve-handler-use.d.ts +0 -19
  385. package/dist/types.backup/route-definition/use-item-types.d.ts +0 -1
  386. package/dist/types.backup/route-definition.d.ts +0 -1
  387. package/dist/types.backup/route-map-builder.d.ts +0 -127
  388. package/dist/types.backup/route-name.d.ts +0 -27
  389. package/dist/types.backup/route-types.d.ts +0 -172
  390. package/dist/types.backup/router/basename.d.ts +0 -10
  391. package/dist/types.backup/router/content-negotiation.d.ts +0 -91
  392. package/dist/types.backup/router/debug-manifest.d.ts +0 -7
  393. package/dist/types.backup/router/error-handling.d.ts +0 -76
  394. package/dist/types.backup/router/find-match.d.ts +0 -19
  395. package/dist/types.backup/router/handler-context.d.ts +0 -41
  396. package/dist/types.backup/router/instrument.d.ts +0 -161
  397. package/dist/types.backup/router/intercept-resolution.d.ts +0 -79
  398. package/dist/types.backup/router/lazy-includes.d.ts +0 -26
  399. package/dist/types.backup/router/loader-resolution.d.ts +0 -63
  400. package/dist/types.backup/router/logging.d.ts +0 -41
  401. package/dist/types.backup/router/manifest.d.ts +0 -8
  402. package/dist/types.backup/router/match-api.d.ts +0 -19
  403. package/dist/types.backup/router/match-context.d.ts +0 -184
  404. package/dist/types.backup/router/match-handlers.d.ts +0 -49
  405. package/dist/types.backup/router/match-middleware/background-revalidation.d.ts +0 -113
  406. package/dist/types.backup/router/match-middleware/cache-lookup.d.ts +0 -113
  407. package/dist/types.backup/router/match-middleware/cache-store.d.ts +0 -112
  408. package/dist/types.backup/router/match-middleware/index.d.ts +0 -80
  409. package/dist/types.backup/router/match-middleware/intercept-resolution.d.ts +0 -116
  410. package/dist/types.backup/router/match-middleware/segment-resolution.d.ts +0 -94
  411. package/dist/types.backup/router/match-pipelines.d.ts +0 -103
  412. package/dist/types.backup/router/match-result.d.ts +0 -114
  413. package/dist/types.backup/router/metrics.d.ts +0 -6
  414. package/dist/types.backup/router/middleware-types.d.ts +0 -74
  415. package/dist/types.backup/router/middleware.d.ts +0 -116
  416. package/dist/types.backup/router/navigation-snapshot.d.ts +0 -22
  417. package/dist/types.backup/router/params-util.d.ts +0 -8
  418. package/dist/types.backup/router/parse-pattern.d.ts +0 -38
  419. package/dist/types.backup/router/pattern-matching.d.ts +0 -169
  420. package/dist/types.backup/router/prefetch-cache-ttl.d.ts +0 -27
  421. package/dist/types.backup/router/prefetch-limits.d.ts +0 -20
  422. package/dist/types.backup/router/prerender-match.d.ts +0 -50
  423. package/dist/types.backup/router/preview-match.d.ts +0 -22
  424. package/dist/types.backup/router/request-classification.d.ts +0 -104
  425. package/dist/types.backup/router/revalidation.d.ts +0 -57
  426. package/dist/types.backup/router/route-snapshot.d.ts +0 -112
  427. package/dist/types.backup/router/router-context.d.ts +0 -137
  428. package/dist/types.backup/router/router-interfaces.d.ts +0 -432
  429. package/dist/types.backup/router/router-options.d.ts +0 -738
  430. package/dist/types.backup/router/router-registry.d.ts +0 -15
  431. package/dist/types.backup/router/segment-resolution/fresh.d.ts +0 -55
  432. package/dist/types.backup/router/segment-resolution/helpers.d.ts +0 -93
  433. package/dist/types.backup/router/segment-resolution/loader-cache.d.ts +0 -33
  434. package/dist/types.backup/router/segment-resolution/loader-mask.d.ts +0 -44
  435. package/dist/types.backup/router/segment-resolution/loader-snapshot.d.ts +0 -90
  436. package/dist/types.backup/router/segment-resolution/mask-nested.d.ts +0 -53
  437. package/dist/types.backup/router/segment-resolution/revalidation.d.ts +0 -85
  438. package/dist/types.backup/router/segment-resolution/static-store.d.ts +0 -17
  439. package/dist/types.backup/router/segment-resolution/streamed-handler-telemetry.d.ts +0 -16
  440. package/dist/types.backup/router/segment-resolution/view-transition-default.d.ts +0 -28
  441. package/dist/types.backup/router/segment-resolution.d.ts +0 -3
  442. package/dist/types.backup/router/segment-wrappers.d.ts +0 -53
  443. package/dist/types.backup/router/state-cookie-name.d.ts +0 -1
  444. package/dist/types.backup/router/substitute-pattern-params.d.ts +0 -23
  445. package/dist/types.backup/router/telemetry-otel.d.ts +0 -113
  446. package/dist/types.backup/router/telemetry.d.ts +0 -215
  447. package/dist/types.backup/router/timeout.d.ts +0 -68
  448. package/dist/types.backup/router/tracing.d.ts +0 -125
  449. package/dist/types.backup/router/trie-matching.d.ts +0 -32
  450. package/dist/types.backup/router/types.d.ts +0 -98
  451. package/dist/types.backup/router/url-params.d.ts +0 -26
  452. package/dist/types.backup/router.d.ts +0 -7
  453. package/dist/types.backup/rsc/capture-queue.d.ts +0 -6
  454. package/dist/types.backup/rsc/full-payload.d.ts +0 -22
  455. package/dist/types.backup/rsc/handler-context.d.ts +0 -31
  456. package/dist/types.backup/rsc/handler.d.ts +0 -9
  457. package/dist/types.backup/rsc/helpers.d.ts +0 -213
  458. package/dist/types.backup/rsc/index.d.ts +0 -17
  459. package/dist/types.backup/rsc/json-route-result.d.ts +0 -20
  460. package/dist/types.backup/rsc/loader-fetch.d.ts +0 -14
  461. package/dist/types.backup/rsc/manifest-init.d.ts +0 -18
  462. package/dist/types.backup/rsc/nonce.d.ts +0 -28
  463. package/dist/types.backup/rsc/origin-guard.d.ts +0 -50
  464. package/dist/types.backup/rsc/progressive-enhancement.d.ts +0 -19
  465. package/dist/types.backup/rsc/redirect-guard.d.ts +0 -35
  466. package/dist/types.backup/rsc/response-cache-serve.d.ts +0 -46
  467. package/dist/types.backup/rsc/response-error.d.ts +0 -19
  468. package/dist/types.backup/rsc/response-route-handler.d.ts +0 -29
  469. package/dist/types.backup/rsc/rsc-rendering.d.ts +0 -23
  470. package/dist/types.backup/rsc/runtime-warnings.d.ts +0 -22
  471. package/dist/types.backup/rsc/server-action.d.ts +0 -68
  472. package/dist/types.backup/rsc/shell-build-manifest.d.ts +0 -84
  473. package/dist/types.backup/rsc/shell-capture-constants.d.ts +0 -27
  474. package/dist/types.backup/rsc/shell-capture.d.ts +0 -374
  475. package/dist/types.backup/rsc/shell-serve.d.ts +0 -136
  476. package/dist/types.backup/rsc/ssr-setup.d.ts +0 -48
  477. package/dist/types.backup/rsc/transition-gate.d.ts +0 -27
  478. package/dist/types.backup/rsc/types.d.ts +0 -290
  479. package/dist/types.backup/runtime-env.d.ts +0 -1
  480. package/dist/types.backup/search-params.d.ts +0 -125
  481. package/dist/types.backup/segment-content-promise.d.ts +0 -13
  482. package/dist/types.backup/segment-fragments.d.ts +0 -56
  483. package/dist/types.backup/segment-loader-promise.d.ts +0 -22
  484. package/dist/types.backup/segment-system.d.ts +0 -84
  485. package/dist/types.backup/serialize.d.ts +0 -164
  486. package/dist/types.backup/server/context.d.ts +0 -494
  487. package/dist/types.backup/server/cookie-parse.d.ts +0 -10
  488. package/dist/types.backup/server/cookie-store.d.ts +0 -107
  489. package/dist/types.backup/server/fetchable-loader-store.d.ts +0 -20
  490. package/dist/types.backup/server/handle-store.d.ts +0 -100
  491. package/dist/types.backup/server/loader-registry.d.ts +0 -32
  492. package/dist/types.backup/server/request-context.d.ts +0 -596
  493. package/dist/types.backup/server/root-layout.d.ts +0 -3
  494. package/dist/types.backup/server.d.ts +0 -15
  495. package/dist/types.backup/ssr/index.d.ts +0 -233
  496. package/dist/types.backup/ssr/inject-rsc-eager.d.ts +0 -3
  497. package/dist/types.backup/ssr/preinit-client-references.d.ts +0 -71
  498. package/dist/types.backup/ssr/ssr-root.d.ts +0 -69
  499. package/dist/types.backup/static-handler.d.ts +0 -57
  500. package/dist/types.backup/testing/cache-status.d.ts +0 -63
  501. package/dist/types.backup/testing/collect-handle.d.ts +0 -20
  502. package/dist/types.backup/testing/dispatch.d.ts +0 -123
  503. package/dist/types.backup/testing/dom.entry.d.ts +0 -15
  504. package/dist/types.backup/testing/e2e/fixture.d.ts +0 -37
  505. package/dist/types.backup/testing/e2e/index.d.ts +0 -30
  506. package/dist/types.backup/testing/e2e/matchers.d.ts +0 -17
  507. package/dist/types.backup/testing/e2e/page-helpers.d.ts +0 -62
  508. package/dist/types.backup/testing/e2e/parity.d.ts +0 -111
  509. package/dist/types.backup/testing/e2e/server.d.ts +0 -35
  510. package/dist/types.backup/testing/flight-matchers.d.ts +0 -55
  511. package/dist/types.backup/testing/flight-normalize.d.ts +0 -1
  512. package/dist/types.backup/testing/flight-tree.d.ts +0 -192
  513. package/dist/types.backup/testing/flight.d.ts +0 -115
  514. package/dist/types.backup/testing/flight.entry.d.ts +0 -27
  515. package/dist/types.backup/testing/generated-routes.d.ts +0 -66
  516. package/dist/types.backup/testing/index.d.ts +0 -52
  517. package/dist/types.backup/testing/internal/context.d.ts +0 -225
  518. package/dist/types.backup/testing/internal/flight-client-globals.d.ts +0 -1
  519. package/dist/types.backup/testing/internal/seed-vars.d.ts +0 -30
  520. package/dist/types.backup/testing/render-handler.d.ts +0 -160
  521. package/dist/types.backup/testing/render-route.d.ts +0 -246
  522. package/dist/types.backup/testing/run-loader.d.ts +0 -186
  523. package/dist/types.backup/testing/run-middleware.d.ts +0 -132
  524. package/dist/types.backup/testing/run-transition-when.d.ts +0 -77
  525. package/dist/types.backup/testing/vitest-stubs/cloudflare-email.d.ts +0 -6
  526. package/dist/types.backup/testing/vitest-stubs/cloudflare-workers.d.ts +0 -13
  527. package/dist/types.backup/testing/vitest-stubs/plugin-rsc.d.ts +0 -7
  528. package/dist/types.backup/testing/vitest-stubs/version.d.ts +0 -1
  529. package/dist/types.backup/testing/vitest.d.ts +0 -205
  530. package/dist/types.backup/theme/ThemeProvider.d.ts +0 -13
  531. package/dist/types.backup/theme/ThemeScript.d.ts +0 -45
  532. package/dist/types.backup/theme/constants.d.ts +0 -39
  533. package/dist/types.backup/theme/index.d.ts +0 -29
  534. package/dist/types.backup/theme/theme-context.d.ts +0 -21
  535. package/dist/types.backup/theme/theme-script.d.ts +0 -26
  536. package/dist/types.backup/theme/types.d.ts +0 -162
  537. package/dist/types.backup/theme/use-theme.d.ts +0 -8
  538. package/dist/types.backup/types/boundaries.d.ts +0 -93
  539. package/dist/types.backup/types/cache-types.d.ts +0 -191
  540. package/dist/types.backup/types/error-types.d.ts +0 -114
  541. package/dist/types.backup/types/global-namespace.d.ts +0 -90
  542. package/dist/types.backup/types/handler-context.d.ts +0 -658
  543. package/dist/types.backup/types/index.d.ts +0 -11
  544. package/dist/types.backup/types/loader-types.d.ts +0 -182
  545. package/dist/types.backup/types/request-scope.d.ts +0 -93
  546. package/dist/types.backup/types/route-config.d.ts +0 -105
  547. package/dist/types.backup/types/route-entry.d.ts +0 -95
  548. package/dist/types.backup/types/segments.d.ts +0 -234
  549. package/dist/types.backup/types.d.ts +0 -1
  550. package/dist/types.backup/urls/include-helper.d.ts +0 -17
  551. package/dist/types.backup/urls/include-provider.d.ts +0 -27
  552. package/dist/types.backup/urls/index.d.ts +0 -6
  553. package/dist/types.backup/urls/path-helper-types.d.ts +0 -197
  554. package/dist/types.backup/urls/path-helper.d.ts +0 -12
  555. package/dist/types.backup/urls/pattern-types.d.ts +0 -166
  556. package/dist/types.backup/urls/response-types.d.ts +0 -67
  557. package/dist/types.backup/urls/type-extraction.d.ts +0 -157
  558. package/dist/types.backup/urls/urls-function.d.ts +0 -24
  559. package/dist/types.backup/urls.d.ts +0 -1
  560. package/dist/types.backup/use-loader.d.ts +0 -150
  561. package/dist/types.backup/vercel/index.d.ts +0 -10
  562. package/dist/types.backup/vercel/tracing.d.ts +0 -70
  563. package/dist/types.backup/vite/debug.d.ts +0 -80
  564. package/dist/types.backup/vite/discovery/bundle-postprocess.d.ts +0 -12
  565. package/dist/types.backup/vite/discovery/dev-prerender-cache.d.ts +0 -65
  566. package/dist/types.backup/vite/discovery/discover-routers.d.ts +0 -17
  567. package/dist/types.backup/vite/discovery/discovery-errors.d.ts +0 -113
  568. package/dist/types.backup/vite/discovery/gate-state.d.ts +0 -79
  569. package/dist/types.backup/vite/discovery/prerender-collection.d.ts +0 -24
  570. package/dist/types.backup/vite/discovery/route-types-writer.d.ts +0 -32
  571. package/dist/types.backup/vite/discovery/self-gen-tracking.d.ts +0 -22
  572. package/dist/types.backup/vite/discovery/shell-prerender-phase.d.ts +0 -40
  573. package/dist/types.backup/vite/discovery/state.d.ts +0 -162
  574. package/dist/types.backup/vite/discovery/virtual-module-codegen.d.ts +0 -15
  575. package/dist/types.backup/vite/index.d.ts +0 -11
  576. package/dist/types.backup/vite/inject-client-debug.d.ts +0 -56
  577. package/dist/types.backup/vite/plugin-types.d.ts +0 -298
  578. package/dist/types.backup/vite/plugins/cjs-to-esm.d.ts +0 -6
  579. package/dist/types.backup/vite/plugins/client-ref-dedup.d.ts +0 -40
  580. package/dist/types.backup/vite/plugins/client-ref-hashing.d.ts +0 -35
  581. package/dist/types.backup/vite/plugins/cloudflare-protocol-stub.d.ts +0 -64
  582. package/dist/types.backup/vite/plugins/expose-action-id.d.ts +0 -18
  583. package/dist/types.backup/vite/plugins/expose-id-utils.d.ts +0 -37
  584. package/dist/types.backup/vite/plugins/expose-ids/export-analysis.d.ts +0 -19
  585. package/dist/types.backup/vite/plugins/expose-ids/handler-transform.d.ts +0 -10
  586. package/dist/types.backup/vite/plugins/expose-ids/loader-transform.d.ts +0 -8
  587. package/dist/types.backup/vite/plugins/expose-ids/router-transform.d.ts +0 -13
  588. package/dist/types.backup/vite/plugins/expose-ids/types.d.ts +0 -29
  589. package/dist/types.backup/vite/plugins/expose-internal-ids.d.ts +0 -6
  590. package/dist/types.backup/vite/plugins/performance-tracks.d.ts +0 -25
  591. package/dist/types.backup/vite/plugins/refresh-cmd.d.ts +0 -20
  592. package/dist/types.backup/vite/plugins/use-cache-transform.d.ts +0 -20
  593. package/dist/types.backup/vite/plugins/vercel-output.d.ts +0 -85
  594. package/dist/types.backup/vite/plugins/version-injector.d.ts +0 -21
  595. package/dist/types.backup/vite/plugins/version-plugin.d.ts +0 -19
  596. package/dist/types.backup/vite/plugins/virtual-entries.d.ts +0 -36
  597. package/dist/types.backup/vite/plugins/virtual-stub-plugin.d.ts +0 -7
  598. package/dist/types.backup/vite/rango.d.ts +0 -29
  599. package/dist/types.backup/vite/router-discovery.d.ts +0 -23
  600. package/dist/types.backup/vite/utils/ast-handler-extract.d.ts +0 -64
  601. package/dist/types.backup/vite/utils/banner.d.ts +0 -2
  602. package/dist/types.backup/vite/utils/bundle-analysis.d.ts +0 -28
  603. package/dist/types.backup/vite/utils/client-chunks.d.ts +0 -55
  604. package/dist/types.backup/vite/utils/directive-prologue.d.ts +0 -16
  605. package/dist/types.backup/vite/utils/forward-user-plugins.d.ts +0 -37
  606. package/dist/types.backup/vite/utils/manifest-utils.d.ts +0 -7
  607. package/dist/types.backup/vite/utils/package-resolution.d.ts +0 -6
  608. package/dist/types.backup/vite/utils/prerender-utils.d.ts +0 -32
  609. package/dist/types.backup/vite/utils/shared-utils.d.ts +0 -55
@@ -121,9 +121,9 @@ At capture the pending fetch cannot win the task-quantized quiet window, so
121
121
  the boundary postpones — fallback in the frozen prelude, value resumed fresh
122
122
  on every HIT. This is the PHYSICS class from the hole doctrine below, and it
123
123
  is exactly how an existing Suspense-shaped tree (e.g. migrated from Next.js
124
- PPR) works with zero restructuring. The e2e proof is
125
- `e2e/test-app/src/components/ShellPhysicsValue.tsx` a promise hole living in
126
- a LAYOUT with no loader registration at all.
124
+ PPR) works with zero restructuring. The e2e proof lives in the router
125
+ repository (not shipped in this package): a promise hole living in a LAYOUT
126
+ with no loader registration at all.
127
127
 
128
128
  A route WITHOUT the `ppr` option is pure axis 1: no store read, no capture, no
129
129
  logs, zero cost. `ppr` is per page route — declaring it on a layout is not
@@ -658,9 +658,19 @@ Three levers, in preference order:
658
658
  lane — masked at capture, fresh per serve — at the cost of a fallback in
659
659
  the shell.
660
660
 
661
- Head material (Meta) generally cannot be a hole — the head is shell — so its
662
- promises bake by design; make them cheap with lever 2. `bakeWaitMs` on the
663
- capture debug event tells you what each capture actually paid.
661
+ Head material (Meta) pushed by HANDLERS cannot be a hole — the head is shell —
662
+ so those promises bake by design; make them cheap with lever 2. `bakeWaitMs`
663
+ on the capture debug event tells you what each capture actually paid. A
664
+ LOADER-pushed Meta is different: loaders are masked at capture, so the push
665
+ happens at request time and applies client-side (`metadata.handlesLate`) — it
666
+ is never in the cached shell's head, by construction.
667
+
668
+ One flag to know about here: `loader(Def, { stream: "navigation" })` (the
669
+ document-render await, `/loader`) is **inert under PPR** — capture renders
670
+ mask loaders and skip the await, and a shell HIT flushes the stored prelude
671
+ before loaders resolve. Flagging a loader on a `ppr` route does not bake it
672
+ into the shell and does not delay HIT serves; the flag only governs ordinary
673
+ (axis-1) document renders.
664
674
 
665
675
  ## Execution matrix
666
676
 
@@ -553,10 +553,14 @@ Passthrough entries are logged distinctly:
553
553
  Loaders on pre-rendered routes run at request time. They are bundled normally
554
554
  and need `cache()` for caching. Do not use build-only APIs in loaders.
555
555
 
556
- ### Handle data is frozen
557
-
558
- Handle values pushed via `ctx.use()` during pre-rendering are baked into the
559
- Flight payload. They do not update at request time.
556
+ ### Build-time handle data is frozen
557
+
558
+ Handle values pushed via `ctx.use()` DURING pre-rendering (handler pushes at
559
+ build) are baked into the Flight payload and do not update at request time.
560
+ Loader pushes are the exception by construction: loaders run live at request
561
+ time (previous section), so a loader-pushed handle (a data-derived Meta title,
562
+ say) is request-time data — delivery follows the loader race model, see
563
+ `/loader` → "Writing Handles from Loaders".
560
564
 
561
565
  ### Server actions work normally
562
566
 
@@ -95,23 +95,26 @@ stated, greppable contract.
95
95
 
96
96
  ## Pick a primitive
97
97
 
98
- | I need to… | Use | Skill |
99
- | --------------------------------------- | ---------------------------------- | ----------------------- |
100
- | render data fresh every request | `loader()` + `useLoader()` | /loader |
101
- | cache a rendered subtree | `cache()` on a segment | /caching |
102
- | cache one function/component's result | `"use cache"` | /use-cache |
103
- | cache a loader's data | `loader(L, () => [cache()])` | /loader, /caching |
104
- | re-render a segment after an action | `revalidate()` | /loader |
105
- | mutate | `"use server"` action | /server-actions |
106
- | debug a slow request | `debugPerformance` / telemetry | /observability |
107
- | share config across routes | factory returning a helper array | /composability |
108
- | compose a sub-app / module | `include()` | /route |
109
- | modal / soft navigation | `intercept()` | /intercept |
110
- | pre-render a route at build time | `Prerender(...)` wrapper | /prerender |
111
- | feed live loaders from a cached shell | replayed handle + `ctx.rendered()` | /shell-manifest |
112
- | cache the HTML shell, keep loaders live | `ppr` path option | /ppr |
113
- | choose in-function vs CDN caching | deployment cache boundary | /deployment-caching |
114
- | stream SSE / upgrade a WebSocket | `path.stream()` / `path.any()` | /streams-and-websockets |
98
+ | I need to… | Use | Skill |
99
+ | --------------------------------------- | ------------------------------------- | ----------------------- |
100
+ | render data fresh every request | `loader()` + `useLoader()` | /loader |
101
+ | cache a rendered subtree | `cache()` on a segment | /caching |
102
+ | cache one function/component's result | `"use cache"` | /use-cache |
103
+ | cache a loader's data | `loader(L, () => [cache()])` | /loader, /caching |
104
+ | re-render a segment after an action | `revalidate()` | /loader |
105
+ | mutate | `"use server"` action | /server-actions |
106
+ | debug a slow request | `debugPerformance` / telemetry | /observability |
107
+ | share config across routes | factory returning a helper array | /composability |
108
+ | compose a sub-app / module | `include()` | /route |
109
+ | modal / soft navigation | `intercept()` | /intercept |
110
+ | route group of client components | `clientUrls()` in `"use client"` | /client-urls |
111
+ | set meta/breadcrumbs from loader data | `ctx.use(Handle)` in the loader | /loader |
112
+ | guarantee loader output in the SSR HTML | `loader(L, { stream: "navigation" })` | /loader |
113
+ | pre-render a route at build time | `Prerender(...)` wrapper | /prerender |
114
+ | feed live loaders from a cached shell | replayed handle + `ctx.rendered()` | /shell-manifest |
115
+ | cache the HTML shell, keep loaders live | `ppr` path option | /ppr |
116
+ | choose in-function vs CDN caching | deployment cache boundary | /deployment-caching |
117
+ | stream SSE / upgrade a WebSocket | `path.stream()` / `path.any()` | /streams-and-websockets |
115
118
 
116
119
  ## Invariants
117
120
 
@@ -243,6 +246,7 @@ Grouped by concern — read when you need to…
243
246
  | ------------------------- | -------------------------------------------------------------------------- |
244
247
  | `/router-setup` | Create and configure the RSC router |
245
248
  | `/route` | Define routes with `urls()`, `path()`, and `include()` |
249
+ | `/client-urls` | Client-component route groups with `clientUrls()` — no handlers |
246
250
  | `/layout` | Layouts that wrap child routes |
247
251
  | `/parallel` | Multi-column layouts and sidebars |
248
252
  | `/intercept` | Modal/slide-over patterns for soft navigation |
@@ -163,6 +163,6 @@ should find **none** — that is the client-only contract.
163
163
  ## Reference
164
164
 
165
165
  A worked, tested wiring (dev + production e2e markers, incl. the client-only
166
- contract) lives in the `@rangojs/router` repo: `docs/react-compiler.md` and the
167
- `react-compiler.test.ts` files under `e2e/e2e-basic`, `tests/cloudflare-basic`,
168
- and `tests/vite-rsc-demo`.
166
+ contract) lives in the `@rangojs/router` repository not shipped in this
167
+ package: `docs/react-compiler.md` and the `react-compiler.test.ts` files under
168
+ `e2e/e2e-basic`, `tests/cloudflare-basic`, and `tests/vite-rsc-demo`.
@@ -289,9 +289,11 @@ has no response payload metadata, so response routes resolve to `never`:
289
289
  // router.tsx
290
290
  export const router = createRouter({ document: Document }).routes(urlpatterns);
291
291
 
292
+ type AppRoutes = typeof router.routeMap;
293
+
292
294
  declare global {
293
295
  namespace Rango {
294
- interface RegisteredRoutes extends typeof router.routeMap {}
296
+ interface RegisteredRoutes extends AppRoutes {}
295
297
  }
296
298
  }
297
299
  ```
@@ -480,7 +482,7 @@ type Stats = RouteResponse<typeof blogApiPatterns, "stats">;
480
482
  // = { views: number; visitors: number }
481
483
 
482
484
  // After mounting -- names get prefixed.
483
- // Rango.PathResponse needs `RegisteredRoutes extends typeof router.routeMap` (see above),
485
+ // Rango.PathResponse needs the RegisteredRoutes augmentation (see above),
484
486
  // otherwise it resolves to never.
485
487
  type BlogStats = Rango.PathResponse<"/blog/api/stats">;
486
488
  // = { views: number; visitors: number }
@@ -358,8 +358,11 @@ path("/moved", () => redirect("/new-location", 301), { name: "moved" });
358
358
  > **Redirecting from a route with `loading()`:** an `async` handler that returns
359
359
  > a `Response`/`redirect()` on a route that also declares `loading()` is streamed,
360
360
  > so the redirect is rendered into the RSC stream instead of becoming an HTTP
361
- > redirect. Issue the redirect from `middleware`, a loader, or a **synchronous**
362
- > handler return instead. (Dev logs a warning if this is hit.)
361
+ > redirect. For a real HTTP redirect, issue it from `middleware` or a
362
+ > **synchronous** handler return pre-stream redirect authority belongs there.
363
+ > (A loader `throw redirect()` also navigates the user, but it is ALWAYS a
364
+ > client-side replace on document loads — 200 document, never a 302; see
365
+ > `/loader` → "Loader Authority". Dev logs a warning if this is hit.)
363
366
 
364
367
  ### Redirect with location state
365
368
 
@@ -347,12 +347,19 @@ Two distinct 404 scenarios:
347
347
  ```typescript
348
348
  import { notFound } from "@rangojs/router";
349
349
 
350
- // In a handler or loader
350
+ // In a handler
351
351
  path("/product/:slug", async (ctx) => {
352
352
  const product = await db.getProduct(ctx.params.slug);
353
353
  if (!product) notFound("Product not found");
354
354
  return <ProductPage product={product} />;
355
355
  });
356
+
357
+ // In a loader — data-dependent authority lives with the data
358
+ export const ProductLoader = createLoader(async (ctx) => {
359
+ "use server";
360
+ if (!(await exists(ctx.params.slug))) notFound("Product not found");
361
+ return getProduct(ctx.params.slug);
362
+ });
356
363
  ```
357
364
 
358
365
  ### Fallback chain for `notFound()`
@@ -364,7 +371,14 @@ When `notFound()` is thrown, the router looks for a fallback in this order:
364
371
  3. **`notFound`** — from `createRouter()` config (same component used for no-route-match)
365
372
  4. **Default `<h1>Not Found</h1>`** — built-in fallback
366
373
 
367
- All cases set HTTP 404 status.
374
+ Handler and no-match cases set HTTP 404 status. A LOADER-thrown `notFound()`
375
+ on a document load always streams the resolved not-found UI, but the 404
376
+ STATUS is opportunistic — real only when the rejection settles before the
377
+ document Response is constructed (loaders stream). Register the loader as
378
+ `loader(Def, { stream: "navigation" })` to make the 404 status deterministic;
379
+ on client navigations the 404 UI swaps in with the URL preserved (payload
380
+ stays 200 — the client owns presentation there). See `/loader` → "Loader
381
+ Authority".
368
382
 
369
383
  ### notFoundBoundary
370
384
 
@@ -7,9 +7,9 @@ argument-hint: "[vendor]"
7
7
  # Scripts
8
8
 
9
9
  Inject `<script>` tags into the document the idiomatic Rango way: push a config
10
- from a **server** route/layout handler with `ctx.use(Script)(config)`, and render
11
- them with the built-in **`<Scripts />`** component (the `Meta` / `<MetaTags>`
12
- pair, but for scripts). The request CSP **nonce is applied automatically to
10
+ from a **server** route/layout handler or a loader body — with
11
+ `ctx.use(Script)(config)`, and render them with the built-in **`<Scripts />`**
12
+ component (the `Meta` / `<MetaTags>` pair, but for scripts). The request CSP **nonce is applied automatically to
13
13
  document-rendered scripts** — you never read or pass it. (The one exception is an
14
14
  async script first encountered on a soft navigation; see the nonce caveat under
15
15
  "Execution contract".)
@@ -40,7 +40,7 @@ export function Document({ children }) {
40
40
  }
41
41
  ```
42
42
 
43
- ## Push from a handler
43
+ ## Push from a handler (or loader)
44
44
 
45
45
  `ScriptConfig` is a discriminated union — exactly one of three shapes, so invalid
46
46
  combinations are compile errors:
@@ -101,6 +101,15 @@ inert (silently dead) `<script>`. Async configs stay reactive. Reusing an `id`
101
101
  shapes the INITIAL document output (last-push-wins) — it does not re-run a script
102
102
  during navigation.
103
103
 
104
+ > **Loader pushes meet the freeze.** A LOADER push to the Script handle
105
+ > follows the delivery race (`/loader`): it is in the initial HTML only if it
106
+ > settles before the handler barrier. A push that lands after a slow fetch
107
+ > arrives post-hydration — and for an inline/ordered script the frozen set
108
+ > means it is silently dropped. If a loader must contribute an inline script
109
+ > to the document, register it `loader(Def, { stream: "navigation" })` so the
110
+ > document render awaits the push; otherwise push from a handler (or use an
111
+ > `async` config, which stays reactive).
112
+
104
113
  **Nonce caveat for soft-nav async.** The "nonce is applied automatically" claim
105
114
  holds for DOCUMENT-RENDERED scripts (they carry the nonce in the SSR HTML). An
106
115
  async script first encountered on a soft navigation is injected by React on the
@@ -143,7 +152,7 @@ per-route data into the FIRST (hard-load) page_view server-side — the Script
143
152
  handle is collected after handlers run (parent → child, last-wins):
144
153
 
145
154
  ```ts
146
- // root layout: generic bootstrap
155
+ // root layout: generic bootstrap (handler push — always pre-barrier)
147
156
  ctx.use(Script)({ id: "gtm", children: gtmBootstrap("GTM-XXXX") });
148
157
  // a route: same id, with content_group baked in
149
158
  ctx.use(Script)({
@@ -176,4 +185,5 @@ Otherwise allow the vendor hosts. For GTM/GA4 (Google's wildcards): `script-src
176
185
  `type: "text/partytown"` and wire Partytown's own nonce config manually.
177
186
 
178
187
  A full GTM + GA4-style integration (page_view on first render + soft nav, nonce,
179
- ecommerce events) lives in `tests/vite-rsc-demo`.
188
+ ecommerce events) lives in the router repository's `tests/vite-rsc-demo` app
189
+ (not shipped in this package).
@@ -33,14 +33,18 @@ batched.
33
33
 
34
34
  1. **Handles record data at render time.** The handler pushes to a handle
35
35
  (`ctx.use(Handle)`) while it renders — at build time for `Prerender`, on
36
- the cache miss for `cache()`.
36
+ the cache miss for `cache()`. (Loader bodies can push handles too — see
37
+ `/loader` — but a loader push is request-time and is NOT part of the
38
+ replayed artifact; a manifest handle must be pushed by the code that gets
39
+ frozen with the shell.)
37
40
  2. **Replay on every hit.** Handle data is stored with the Flight payload
38
41
  and replayed into the handle store on cache/prerender hits — handler code
39
42
  does not re-run, but its pushes do.
40
43
  3. **Loaders read after the render barrier.** A DSL loader can
41
44
  `await ctx.rendered()` (waits for all non-loader segments to settle —
42
- fresh render or replay alike), then `ctx.use(Handle)` returns the
43
- **collected** handle data.
45
+ fresh render or replay alike), then `ctx.get(Handle)` returns the
46
+ **collected** handle data. (`ctx.use(Handle)` in a loader is the WRITE —
47
+ it returns the push function; reads live on `ctx.get`.)
44
48
 
45
49
  Loaders are live by default, so the read happens on every request even when
46
50
  the shell is a hit.
@@ -90,7 +94,7 @@ import { RenderedProducts } from "../handles/rendered-products";
90
94
  export const PriceLoader = createLoader(async (ctx) => {
91
95
  "use server";
92
96
  await ctx.rendered();
93
- const ids = ctx.use(RenderedProducts);
97
+ const ids = ctx.get(RenderedProducts);
94
98
  return db.pricesFor(ids); // Map<string, number> keyed by product id
95
99
  });
96
100
  ```
@@ -144,15 +148,20 @@ cache({ ttl: 600, tags: ["products"] }, () => [
144
148
  Ids, slugs, slot names, variant keys: yes. Anything derived from
145
149
  `cookies()`/`headers()`: no.
146
150
  - **`ctx.rendered()` is experimental and DSL-loaders-only.** It throws in
147
- fetchable/standalone loader calls that run outside a route render.
151
+ fetchable/standalone loader calls that run outside a route render, in
152
+ handler-invoked loaders (a handler already awaiting the loader via
153
+ `ctx.use()` is a detected deadlock), and in loaders registered with
154
+ `{ stream: "navigation" }` (the document render awaits the loader before
155
+ the barrier — a cycle by construction; see `/loader`).
148
156
  - **The reading loader serializes after the shell.** `await ctx.rendered()`
149
157
  deliberately gives up loader/render parallelism — on a miss the loader
150
158
  waits for segment resolution; on a hit (the common case for a cached
151
159
  shell) replay is immediate and the wait is negligible. A
152
160
  `debugPerformance` waterfall shows this loader after the render bar; for
153
161
  this pattern that is the contract, not a regression.
154
- - **`ctx.use(Handle)` before `await ctx.rendered()` throws** in a loader,
155
- with an error saying to await the barrier first.
162
+ - **`ctx.get(handle)` before `await ctx.rendered()` throws** in a loader,
163
+ with an error saying to await the barrier first. (`ctx.use(Handle)` — the
164
+ push — is legal for the whole loader body, no barrier required.)
156
165
  - **Deferred handle values are resolved before storage** (resolve-by-default),
157
166
  so the manifest read always sees plain values, never promises.
158
167
 
@@ -85,11 +85,11 @@ Each primitive links to its sub-file (API + recipe + caveats).
85
85
  | ---------------------------------------------------------------------------------------------------------------------------------- | ------------ | --------------------------------------------------------------------------------------------- | -------------------------------- |
86
86
  | a pure function / `reverse` / `href` / a predicate (`revalidate`, `isAction`) | unit + types | [`reverse`/`@ts-expect-error`](./reverse-and-types.md) | `@rangojs/router/testing` |
87
87
  | one loader's data logic | unit (node) | [`runLoader`](./loader.md) | `@rangojs/router/testing` |
88
- | a loader's cookie / header / redirect output (auth-loader pattern) | unit (node) | [`runLoaderResult`](./loader.md) | `@rangojs/router/testing` |
88
+ | a loader's cookie / header / thrown `redirect()`/`notFound()` / handle-push output | unit (node) | [`runLoaderResult`](./loader.md) | `@rangojs/router/testing` |
89
89
  | one middleware's ordering / short-circuit / cookie+header merge | unit (node) | [`runMiddleware`](./middleware.md) | `@rangojs/router/testing` |
90
90
  | a `"use server"` action's cookie / header / flash output (even on `throw redirect()`) | unit (node) | [`runInRequestContext`](./server-actions.md) | `@rangojs/router/testing` |
91
91
  | a `transition({ when })` gate (keep/drop) against nav source / target / action metadata | unit (node) | `runTransitionWhen` (`{ kept, whenContext }`; pass `{ ppr: true }` for pre-handler timing) | `@rangojs/router/testing` |
92
- | a handle's `collect`/accumulator, or a seeded handle read | unit | [`collectHandle` / seeded `handles`](./handles.md) | `@rangojs/router/testing` |
92
+ | a handle's `collect`/accumulator, a seeded handle read, or a loader handle write | unit | [`collectHandle` / seeded `handles` / `handlePushes`](./handles.md) | `@rangojs/router/testing` |
93
93
  | a CLIENT component reading router context (`useParams`/`useReverse`/`Outlet`/`useNavigation`/`useLoader`) | unit (DOM) | [`renderRoute`](./client-components.md) | `@rangojs/router/testing/dom` |
94
94
  | a redirect / status / headers / cookies / **response route** (json/text/html/xml/md), no Flight | integration | [`dispatch`](./response-routes.md) | `@rangojs/router/testing` |
95
95
  | a real async **Server Component** (assert what it rendered: typed boundary props, server-rendered host content, inlined-vs-island) | RSC unit | [`renderServerTree` + `findClientBoundaries`/`findElements`](./server-tree.md) | `@rangojs/router/testing/flight` |
@@ -12,6 +12,7 @@ RTL-style stub (peer of React Router's `createRoutesStub` / Expo's `renderRouter
12
12
  | ----------------- | ---------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
13
13
  | `request` | `Request \| string` | Initial location. Only the URL is read (client render — headers/method ignored). Defaults to the leaf spec's static prefix or `"/"`. |
14
14
  | `loaderData` | `Record<string, unknown>` | Loader data keyed by loader `$$id`. `useLoader(L)` reads `loaderData[L.$$id]`. |
15
+ | `outletPending` | `boolean` | Seed `useOutlet().pending` through each synthetic segment's production `OutletProvider`. Defaults to `false`; this is context seeding, not a simulated navigation/Suspense/action lifecycle. |
15
16
  | `loaders` | `ReadonlyArray<readonly [LoaderDefinition<any>, unknown]>` | Seed by REFERENCE: `[loader, data]` pairs. Robust for real `createLoader()` handles whose `$$id` is empty in a bare test. Prefer over `loaderData`. |
16
17
  | `params` | `Record<string, string>` | Explicit params, merged over (and overriding) params extracted from the `request` URL. |
17
18
  | `locationState` | `ReadonlyArray<readonly [LocationStateDefinition<any, any>, unknown]>` | Seed `useLocationState(def)` by REFERENCE: `[def, value]` pairs; written to `history.state`. |
@@ -43,6 +44,7 @@ RTL-style stub (peer of React Router's `createRoutesStub` / Expo's `renderRouter
43
44
  | `useLocationState` | SEEDED `history.state` value. |
44
45
  | `useHandle` | SEEDED handle output (globally accumulated). |
45
46
  | `Outlet` | Renders the next segment in the chain (layout nesting). |
47
+ | `useOutlet` | Next-segment `content` plus SEEDED `options.outletPending`. |
46
48
  | `useTheme` | Theme; throws without `options.theme` (see caveat). |
47
49
 
48
50
  ### Returns — `RenderRouteResult`
@@ -110,6 +112,10 @@ it("resolves params + reverse + Outlet through the layout chain", async () => {
110
112
 
111
113
  - Client tree ONLY. Does NOT catch server/client boundary reference-identity remount bugs, real Flight serialization errors, loader execution, middleware, or handler ordering — those are `renderServerTree` / `renderHandler` / e2e territory. Loader data is SEEDED, never run.
112
114
  - `router.navigate()` bypasses the navigation lifecycle, so the controller never leaves `idle`. `useNavigation()` / `useLinkStatus()` / `useAction()` non-idle states (loading/streaming/pending, action result/error) are NOT reachable — test those at e2e.
115
+ - `outletPending` seeds only the production-shaped outlet context. It is useful
116
+ for the two settled render states of a layout that reads `useOutlet()`, but it
117
+ does not prove the hydrated `clientUrls()` transition that toggles the value;
118
+ keep that transition in dev + production e2e.
113
119
  - CATCH — streaming `use(promise)` Suspense content (e.g. an async breadcrumb `content: Promise<ReactNode>`): a plain `Promise.resolve(node)` does NOT flush its Suspense retry in RTL/happy-dom, so the DOM stays on the fallback. Assert the PENDING fallback with `new Promise(() => {})`; for the ARRIVED state pass an already-settled promise so `use()` reads it synchronously: `const p = Promise.resolve(node) as any; p.status = "fulfilled"; p.value = node;`. The real pending->resolved transition is an e2e concern.
114
120
  - ARIA gotcha — an explicit `role` on a `<Link>` (e.g. `<Link role="tab">` in a tablist) OVERRIDES the implicit `link` role, so `getByRole("link")` finds nothing. Query the explicit role (`getByRole("tab")`) or fall back to `getByText` / `getByTestId` and assert `getAttribute("href")`.
115
121
  - `ctx.theme` is undefined unless `theme` is passed; the typed `ctx.search` defaults to `{}` (seed `searchData` on `runLoader`, not here).
@@ -1,8 +1,8 @@
1
- # Testing a handle — collectHandle, plus the loader and client read paths
1
+ # Testing a handle — collectHandle, plus the loader read/write and client read paths
2
2
 
3
3
  **Layer:** unit (node + DOM) · **Import:** `@rangojs/router/testing` (collectHandle), `@rangojs/router/testing/dom` (renderRoute) · **DSL it tests:** a handle e.g. Breadcrumbs/Meta (see `/handler-use`, `/breadcrumbs`)
4
4
 
5
- A handle's `collect`/accumulator (the `createHandle(collect)` argument that maps per-segment pushed values into one accumulated result) is otherwise unreachable — `createHandle` keeps it in a private registry keyed by `$$id`. These three primitives test it from different angles: `collectHandle` runs the REAL registered collect on per-segment values you SEED; `runLoader` seeds the POST-collect accumulated value a loader reads after the barrier; `renderRoute` seeds the RAW pushed values for a client component reading `useHandle`. None of them run the real push -> accumulate -> barrier wiring (that stays e2e).
5
+ A handle's `collect`/accumulator (the `createHandle(collect)` argument that maps per-segment pushed values into one accumulated result) is otherwise unreachable — `createHandle` keeps it in a private registry keyed by `$$id`. These primitives test it from different angles: `collectHandle` runs the REAL registered collect on per-segment values you SEED; `runLoader` seeds the POST-collect accumulated value a loader READS (`ctx.get(handle)` after the barrier); `runLoaderResult(...).handlePushes` records what a loader WRITES (`ctx.use(SomeHandle)({...})`, in push order); `renderRoute` seeds the RAW pushed values for a client component reading `useHandle`. None of them run the real push -> accumulate -> barrier wiring (that stays e2e).
6
6
 
7
7
  ## API
8
8
 
@@ -17,10 +17,10 @@ A handle's `collect`/accumulator (the `createHandle(collect)` argument that maps
17
17
 
18
18
  ### runLoader option — `handles` — `src/testing/run-loader.ts`
19
19
 
20
- | Field | Type | Meaning |
21
- | ---------- | ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
22
- | `handles` | `ReadonlyArray<readonly [Handle, unknown]>` | Seeds the value `ctx.use(SomeHandle)` returns — the POST-collect **ACCUMULATED** value (singular `unknown`), what a loader reads after `await ctx.rendered()`. Matched by handle reference. Pair with `rendered`. |
23
- | `rendered` | `boolean \| (() => void \| Promise<void>)` | Mocks the `ctx.rendered()` barrier (throws by default). `true` resolves it immediately; a function controls timing/side effects. A `ctx.use(handle)` read before the barrier settles throws, exactly as in production. |
20
+ | Field | Type | Meaning |
21
+ | ---------- | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
22
+ | `handles` | `ReadonlyArray<readonly [Handle, unknown]>` | Seeds the value `ctx.get(SomeHandle)` returns — the POST-collect **ACCUMULATED** value (singular `unknown`), what a loader reads after `await ctx.rendered()`. Matched by handle reference. Pair with `rendered`. |
23
+ | `rendered` | `boolean \| (() => void \| Promise<void>)` | Mocks the `ctx.rendered()` barrier (throws by default). `true` resolves it immediately; a function controls timing/side effects. A `ctx.get(handle)` read before the barrier settles throws, exactly as in production. (`ctx.use(handle)` — the WRITE — is never gated.) |
24
24
 
25
25
  ### renderRoute option — `handles` — `src/testing/render-route.tsx`
26
26
 
@@ -66,7 +66,7 @@ import { RenderedProducts } from "../src/handles"; // a createHandle(...)
66
66
 
67
67
  const livePricesBody = async (ctx) => {
68
68
  await ctx.rendered(); // barrier: handle data is now readable
69
- const ids = ctx.use(RenderedProducts) as string[];
69
+ const ids = ctx.get(RenderedProducts) as string[];
70
70
  return ids.map((id) => ({ id, price: 9.99 }));
71
71
  };
72
72
 
@@ -82,6 +82,27 @@ it("reads the accumulated handle value (seed the OUTPUT, mock the barrier)", asy
82
82
  });
83
83
  ```
84
84
 
85
+ ```ts
86
+ // loader-writes-handle.test.ts — a loader PUSHING meta/breadcrumbs (handler parity)
87
+ import { it, expect } from "vitest";
88
+ import { runLoaderResult } from "@rangojs/router/testing";
89
+ import { Meta } from "../src/handles";
90
+
91
+ const productBody = async (ctx) => {
92
+ const product = { name: "Widget", slug: "widget" };
93
+ ctx.use(Meta)({ title: `${product.name} — Shop` });
94
+ return product;
95
+ };
96
+
97
+ it("records loader handle writes in push order", async () => {
98
+ const { result, handlePushes } = await runLoaderResult(productBody);
99
+ expect(result?.name).toBe("Widget");
100
+ expect(handlePushes).toEqual([
101
+ { handle: Meta, value: { title: "Widget — Shop" } },
102
+ ]);
103
+ });
104
+ ```
105
+
85
106
  ```tsx
86
107
  // breadcrumb-trail.test.tsx — a client component reading useHandle
87
108
  // @vitest-environment happy-dom
@@ -121,7 +142,8 @@ it("renders the seeded trail (seed the INPUT pushes, the collect runs)", async (
121
142
 
122
143
  - `collectHandle` tests the pure collect/accumulator in ISOLATION (parent -> child segment order, empty arrays filtered to match production). It does NOT run the real push -> accumulate -> barrier wiring — that stays e2e.
123
144
  - renderRoute `handles` seeds the CLIENT read path with the RAW pushed values array (`unknown[]`), attached to the leaf segment. Handle data accumulates GLOBALLY (not segment-scoped like loaders), so a LAYOUT reading the same handle sees the seeded values too, not just the leaf route.
124
- - runLoader `handles` seeds the POST-collect ACCUMULATED value (singular `unknown`) a loader reads after `await ctx.rendered()`; pair with `{ rendered: true }`. Shape contrast: renderRoute feeds the barrier INPUT (pushes[]), runLoader feeds its OUTPUT (the accumulated value).
145
+ - runLoader `handles` seeds the POST-collect ACCUMULATED value (singular `unknown`) a loader reads via `ctx.get(handle)` after `await ctx.rendered()`; pair with `{ rendered: true }`. Shape contrast: renderRoute feeds the barrier INPUT (pushes[]), runLoader feeds its OUTPUT (the accumulated value).
146
+ - Loader WRITES are the other direction: `ctx.use(SomeHandle)({...})` records into `runLoaderResult(...).handlePushes` (push order; a `.defer()` resolver's value is recorded when the resolver runs). Nothing to seed — assert the envelope.
125
147
  - The renderRoute path is the CLIENT tree only: it does NOT catch server/client boundary remount bugs, real Flight serialization errors, or loader execution.
126
148
 
127
149
  ## See also
@@ -8,62 +8,64 @@
8
8
 
9
9
  ### Options — `RunLoaderOptions<TEnv>`
10
10
 
11
- | Field | Type | Meaning |
12
- | --------------- | --------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
13
- | `params` | `Record<string, string>` | Route params; surfaced as `ctx.params` and `ctx.routeParams`. |
14
- | `search` | `Record<string, string>` | Search params; merged into the request URL so `ctx.searchParams` reflects them. |
15
- | `searchData` | `Record<string, unknown>` | The TYPED `ctx.search` object a route's search schema would produce. Distinct from `search` (which sets the raw `ctx.searchParams`). |
16
- | `basename` | `string` | Router basename surfaced on the context; drives `redirect()` prefixing. |
17
- | `theme` | `ThemeConfig \| true` | Theme config in the `createRouter({ theme })` shape (e.g. `true` or `{ themes: [...] }`). Without it `ctx.theme`/`ctx.setTheme` are inert. |
18
- | `env` | `TEnv` | Environment bindings surfaced as `ctx.env`. |
19
- | `request` | `Request \| string` | Override the backing Request. Defaults to a localhost GET. |
20
- | `vars` | `VarsInit` | Variables a prior middleware would have set (object `{ key: value }`, or `[key, value]` tuples where the key may be a `createVar()` handle). |
21
- | `routeMap` | `Record<string, string>` | Route name -> pattern map enabling `ctx.reverse()`. |
22
- | `routeName` | `string` | Matched route name for scoped `.name` reverse resolution. |
23
- | `method` | `string` | HTTP method surfaced as `ctx.method`. Defaults to `"GET"`. |
24
- | `body` | `unknown` | Request body surfaced as `ctx.body`. |
25
- | `formData` | `FormData` | Form data surfaced as `ctx.formData` (exposed verbatim; no multipart parsing). |
26
- | `loaders` | `ReadonlyArray<readonly [LoaderDefinition<any, any>, unknown]>` | Seed `ctx.use(OtherLoader)` by REFERENCE as `[[OtherLoader, data]]` tuples (same shape as `renderHandler`/`renderRoute`). Checked before `use`. |
27
- | `use` | `UseResolver` | Dynamic resolver for `ctx.use(OtherLoader)` composition. `loaders` wins when both match. |
28
- | `cacheStore` | `SegmentCacheStore` | Cache store backing `use cache` functions. Without one, a cached function bypasses and runs uncached (its taint/profile guards never fire). |
29
- | `cacheProfiles` | `Record<string, CacheProfile>` | Cache profiles, the `createRouter({ cacheProfiles })` shape. |
30
- | `stateCookie` | `StateCookieSeed` (`{ prefix?, routerId?, version? }`) | Customize the rango state cookie a loader calling `invalidateClientCache()` rotates (the name is always seeded — default `rango-state_router_0`). |
31
- | `rendered` | `boolean \| (() => void \| Promise<void>)` | Mock the `ctx.rendered()` render barrier so a loader that `await ctx.rendered()`s can be unit-tested. By default `ctx.rendered()` throws. `true` resolves immediately; a function controls timing/side effects. |
32
- | `handles` | `ReadonlyArray<readonly [Handle<any, any>, unknown]>` | Seed the values `ctx.use(SomeHandle)` returns — the ACCUMULATED handle data read after `await ctx.rendered()`. Matched by handle reference. |
11
+ | Field | Type | Meaning |
12
+ | --------------- | --------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
13
+ | `params` | `Record<string, string>` | Route params; surfaced as `ctx.params` and `ctx.routeParams`. |
14
+ | `search` | `Record<string, string>` | Search params; merged into the request URL so `ctx.searchParams` reflects them. |
15
+ | `searchData` | `Record<string, unknown>` | The TYPED `ctx.search` object a route's search schema would produce. Distinct from `search` (which sets the raw `ctx.searchParams`). |
16
+ | `basename` | `string` | Router basename surfaced on the context; drives `redirect()` prefixing. |
17
+ | `theme` | `ThemeConfig \| true` | Theme config in the `createRouter({ theme })` shape (e.g. `true` or `{ themes: [...] }`). Without it `ctx.theme`/`ctx.setTheme` are inert. |
18
+ | `env` | `TEnv` | Environment bindings surfaced as `ctx.env`. |
19
+ | `request` | `Request \| string` | Override the backing Request. Defaults to a localhost GET. |
20
+ | `vars` | `VarsInit` | Variables a prior middleware would have set (object `{ key: value }`, or `[key, value]` tuples where the key may be a `createVar()` handle). |
21
+ | `routeMap` | `Record<string, string>` | Route name -> pattern map enabling `ctx.reverse()`. |
22
+ | `routeName` | `string` | Matched route name for scoped `.name` reverse resolution. |
23
+ | `method` | `string` | HTTP method surfaced as `ctx.method`. Defaults to `"GET"`. |
24
+ | `body` | `unknown` | Request body surfaced as `ctx.body`. |
25
+ | `formData` | `FormData` | Form data surfaced as `ctx.formData` (exposed verbatim; no multipart parsing). |
26
+ | `loaders` | `ReadonlyArray<readonly [LoaderDefinition<any, any>, unknown]>` | Seed `ctx.use(OtherLoader)` by REFERENCE as `[[OtherLoader, data]]` tuples (same shape as `renderHandler`/`renderRoute`). Checked before `use`. |
27
+ | `use` | `UseResolver` | Dynamic resolver for `ctx.use(OtherLoader)` composition. `loaders` wins when both match. |
28
+ | `cacheStore` | `SegmentCacheStore` | Cache store backing `use cache` functions. Without one, a cached function bypasses and runs uncached (its taint/profile guards never fire). |
29
+ | `cacheProfiles` | `Record<string, CacheProfile>` | Cache profiles, the `createRouter({ cacheProfiles })` shape. |
30
+ | `stateCookie` | `StateCookieSeed` (`{ prefix?, routerId?, version? }`) | Customize the rango state cookie a loader calling `invalidateClientCache()` rotates (the name is always seeded — default `rango-state_router_0`). |
31
+ | `rendered` | `boolean \| (() => void \| Promise<void>)` | Mock the `ctx.rendered()` render barrier so a loader that `await ctx.rendered()`s can be unit-tested. By default `ctx.rendered()` throws. `true` resolves immediately; a function controls timing/side effects. |
32
+ | `handles` | `ReadonlyArray<readonly [Handle<any, any>, unknown]>` | Seed the values `ctx.get(SomeHandle)` returns — the ACCUMULATED handle data read after `await ctx.rendered()`. Matched by handle reference. (Loader handle WRITES need no seed — see `runLoaderResult(...).handlePushes`.) |
33
33
 
34
34
  ### Context — `TestLoaderContext<TEnv>` (what your loader receives)
35
35
 
36
- | Field | Type | Meaning |
37
- | ------------------ | ----------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
38
- | `params` | `Record<string, string>` | Route params (from `opts.params`). |
39
- | `routeParams` | `Record<string, string>` | Same values as `params`. |
40
- | `request` | `Request` | The backing request. |
41
- | `searchParams` | `URLSearchParams` | Raw search params (from `opts.search` baked into the URL). |
42
- | `search` | `Record<string, unknown>` | The TYPED search object (from `opts.searchData`); defaults to `{}`. |
43
- | `pathname` | `string` | Request pathname. |
44
- | `url` | `URL` | Request URL. |
45
- | `originalUrl` | `URL` | Pre-basename-rewrite URL. |
46
- | `env` | `TEnv` | Environment bindings (from `opts.env`). |
47
- | `get` | `<T>(contextVar: ContextVar<T>) => T \| undefined` / `<T>(key: string) => T \| undefined` | Read a var seeded via `opts.vars` (by `createVar()` handle or string key). |
48
- | `use` | `(dep) => ...` | Resolve `ctx.use(OtherLoader)`/`ctx.use(SomeHandle)`: handle seeds first, then loader seeds, then the `use` resolver, then the real context `use()`. |
49
- | `method` | `string` | HTTP method (from `opts.method`, default `"GET"`). |
50
- | `body` | `unknown` | Request body (from `opts.body`). |
51
- | `formData` | `FormData \| undefined` | Form data (from `opts.formData`). |
52
- | `reverse` | `(name, params?, search?) => string` | Build a URL; throws unless `opts.routeMap` was passed. |
53
- | `rendered` | `() => Promise<void>` | The render barrier; throws by default, mocked via `opts.rendered`. |
54
- | `waitUntil` | `(p: Promise<unknown>) => void` | Register background work (no-op accounting in tests). |
55
- | `executionContext` | `ExecutionContext \| undefined` | Platform execution context from the backing request; pairs with `waitUntil`. |
36
+ | Field | Type | Meaning |
37
+ | ------------------ | ----------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
38
+ | `params` | `Record<string, string>` | Route params (from `opts.params`). |
39
+ | `routeParams` | `Record<string, string>` | Same values as `params`. |
40
+ | `request` | `Request` | The backing request. |
41
+ | `searchParams` | `URLSearchParams` | Raw search params (from `opts.search` baked into the URL). |
42
+ | `search` | `Record<string, unknown>` | The TYPED search object (from `opts.searchData`); defaults to `{}`. |
43
+ | `pathname` | `string` | Request pathname. |
44
+ | `url` | `URL` | Request URL. |
45
+ | `originalUrl` | `URL` | Pre-basename-rewrite URL. |
46
+ | `env` | `TEnv` | Environment bindings (from `opts.env`). |
47
+ | `get` | `<T>(contextVar: ContextVar<T>) => T \| undefined` / `<T>(key: string) => T \| undefined` | Read a var seeded via `opts.vars` or READ a handle: `ctx.get(handle)` is rendered-gated (throws before the barrier) and returns the `opts.handles` seed. |
48
+ | `use` | `(dep) => ...` | Resolve `ctx.use(OtherLoader)` (loader seeds, then the `use` resolver, then the real context `use()`) — or WRITE a handle: `ctx.use(SomeHandle)` returns the push function (withDefer-wrapped), recording into `runLoaderResult(...).handlePushes`. |
49
+ | `method` | `string` | HTTP method (from `opts.method`, default `"GET"`). |
50
+ | `body` | `unknown` | Request body (from `opts.body`). |
51
+ | `formData` | `FormData \| undefined` | Form data (from `opts.formData`). |
52
+ | `reverse` | `(name, params?, search?) => string` | Build a URL; throws unless `opts.routeMap` was passed. |
53
+ | `rendered` | `() => Promise<void>` | The render barrier; throws by default, mocked via `opts.rendered`. |
54
+ | `waitUntil` | `(p: Promise<unknown>) => void` | Register background work (no-op accounting in tests). |
55
+ | `executionContext` | `ExecutionContext \| undefined` | Platform execution context from the backing request; pairs with `waitUntil`. |
56
56
 
57
57
  ### Returns — `Promise<T>`
58
58
 
59
59
  The loader data DIRECTLY (no envelope). `T` is the loader's return type.
60
60
 
61
- To assert a loader's EFFECTS — a `Set-Cookie`, a response header, or a
62
- `throw redirect(...)` (the auth-loader pattern) use the sibling
63
- **`runLoaderResult(loader, opts)`** instead. Same options, but it returns an
64
- envelope: `{ result, thrown, response, cookies, headers, locationState, stateCookieName }`
65
- (parity with `runInRequestContext`; `result` is the loader's data). `runLoader`
66
- discards those effects.
61
+ To assert a loader's EFFECTS — a `Set-Cookie`, a response header, a
62
+ `throw redirect(...)` or `notFound()` (loader authority signals), or handle
63
+ writes — use the sibling **`runLoaderResult(loader, opts)`** instead. Same
64
+ options, but it returns an envelope:
65
+ `{ result, thrown, response, cookies, headers, locationState, stateCookieName, handlePushes }`
66
+ (parity with `runInRequestContext`; `result` is the loader's data;
67
+ `handlePushes` records every `ctx.use(SomeHandle)({...})` write in push
68
+ order). `runLoader` discards those effects.
67
69
 
68
70
  ## Recipe
69
71
 
@@ -113,7 +115,7 @@ it("asserts a loader's set-cookie + redirect (runLoaderResult)", async () => {
113
115
  ## Caveats
114
116
 
115
117
  - `ctx.reverse(...)` throws unless you pass `routeMap` (and `routeName` for scoped `.name` resolution). It does NOT fall back to the global route map.
116
- - `ctx.rendered()` throws by default (the render barrier only exists in a full match); pass `{ rendered: true }` to mock it for post-barrier logic, and `{ handles: [[SomeHandle, data]] }` to seed `ctx.use(SomeHandle)`. `ctx.isAction(...)` is unavailable — cover those at e2e.
118
+ - `ctx.rendered()` throws by default (the render barrier only exists in a full match); pass `{ rendered: true }` to mock it for post-barrier logic, and `{ handles: [[SomeHandle, data]] }` to seed the `ctx.get(SomeHandle)` read. `ctx.isAction(...)` is unavailable — cover those at e2e.
117
119
  - Seeded `loaders` (by-reference tuples) are NOT executed — `ctx.use(OtherLoader)` returns the seeded value. The dynamic `use` resolver, by contrast, IS executed (it is a function called to compute the value). Either way the REAL loader body is not run; real loader execution and side-effects are e2e-only. `loaders` is checked before the `use` resolver.
118
120
  - A handle imported through the CLIENT build has its body dropped — `runLoader` throws a clear error pointing to the `rangoTestConfig()` preset or the raw body. A router using `Prerender()`/`createLoader()`/`Static()` now constructs in a bare test (each assigns a runtime fallback `$$id`); only the whole router _file_ may still need the plugin (its page modules pull app deps / `virtual:` modules).
119
121
  - No `cookies`/`headers` option: seed a cookie by passing a full Request with a Cookie header — `{ request: new Request(url, { headers: { Cookie: "sid=abc" } }) }`. (`search`/`method` are baked onto this request for you.)