@rangojs/router 0.0.0-experimental.15 → 0.0.0-experimental.151

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 (1284) hide show
  1. package/AGENTS.md +13 -0
  2. package/README.md +308 -451
  3. package/dist/__internal.d.ts +83 -0
  4. package/dist/__internal.d.ts.map +1 -0
  5. package/dist/__internal.js +19 -0
  6. package/dist/__internal.js.map +1 -0
  7. package/dist/__mocks__/version.d.ts +7 -0
  8. package/dist/__mocks__/version.d.ts.map +1 -0
  9. package/dist/__mocks__/version.js +7 -0
  10. package/dist/__mocks__/version.js.map +1 -0
  11. package/dist/__tests__/client-href.test.d.ts +2 -0
  12. package/dist/__tests__/client-href.test.d.ts.map +1 -0
  13. package/dist/__tests__/client-href.test.js +74 -0
  14. package/dist/__tests__/client-href.test.js.map +1 -0
  15. package/dist/__tests__/component-utils.test.d.ts +2 -0
  16. package/dist/__tests__/component-utils.test.d.ts.map +1 -0
  17. package/dist/__tests__/component-utils.test.js +51 -0
  18. package/dist/__tests__/component-utils.test.js.map +1 -0
  19. package/dist/__tests__/event-controller.test.d.ts +2 -0
  20. package/dist/__tests__/event-controller.test.d.ts.map +1 -0
  21. package/dist/__tests__/event-controller.test.js +538 -0
  22. package/dist/__tests__/event-controller.test.js.map +1 -0
  23. package/dist/__tests__/helpers/route-tree.d.ts +118 -0
  24. package/dist/__tests__/helpers/route-tree.d.ts.map +1 -0
  25. package/dist/__tests__/helpers/route-tree.js +374 -0
  26. package/dist/__tests__/helpers/route-tree.js.map +1 -0
  27. package/dist/__tests__/match-result.test.d.ts +2 -0
  28. package/dist/__tests__/match-result.test.d.ts.map +1 -0
  29. package/dist/__tests__/match-result.test.js +154 -0
  30. package/dist/__tests__/match-result.test.js.map +1 -0
  31. package/dist/__tests__/navigation-store.test.d.ts +2 -0
  32. package/dist/__tests__/navigation-store.test.d.ts.map +1 -0
  33. package/dist/__tests__/navigation-store.test.js +440 -0
  34. package/dist/__tests__/navigation-store.test.js.map +1 -0
  35. package/dist/__tests__/partial-update.test.d.ts +2 -0
  36. package/dist/__tests__/partial-update.test.d.ts.map +1 -0
  37. package/dist/__tests__/partial-update.test.js +1009 -0
  38. package/dist/__tests__/partial-update.test.js.map +1 -0
  39. package/dist/__tests__/reverse-types.test.d.ts +8 -0
  40. package/dist/__tests__/reverse-types.test.d.ts.map +1 -0
  41. package/dist/__tests__/reverse-types.test.js +656 -0
  42. package/dist/__tests__/reverse-types.test.js.map +1 -0
  43. package/dist/__tests__/route-definition.test.d.ts +2 -0
  44. package/dist/__tests__/route-definition.test.d.ts.map +1 -0
  45. package/dist/__tests__/route-definition.test.js +55 -0
  46. package/dist/__tests__/route-definition.test.js.map +1 -0
  47. package/dist/__tests__/router-helpers.test.d.ts +2 -0
  48. package/dist/__tests__/router-helpers.test.d.ts.map +1 -0
  49. package/dist/__tests__/router-helpers.test.js +377 -0
  50. package/dist/__tests__/router-helpers.test.js.map +1 -0
  51. package/dist/__tests__/router-integration-2.test.d.ts +2 -0
  52. package/dist/__tests__/router-integration-2.test.d.ts.map +1 -0
  53. package/dist/__tests__/router-integration-2.test.js +426 -0
  54. package/dist/__tests__/router-integration-2.test.js.map +1 -0
  55. package/dist/__tests__/router-integration.test.d.ts +2 -0
  56. package/dist/__tests__/router-integration.test.d.ts.map +1 -0
  57. package/dist/__tests__/router-integration.test.js +1051 -0
  58. package/dist/__tests__/router-integration.test.js.map +1 -0
  59. package/dist/__tests__/search-params.test.d.ts +5 -0
  60. package/dist/__tests__/search-params.test.d.ts.map +1 -0
  61. package/dist/__tests__/search-params.test.js +306 -0
  62. package/dist/__tests__/search-params.test.js.map +1 -0
  63. package/dist/__tests__/segment-system.test.d.ts +2 -0
  64. package/dist/__tests__/segment-system.test.d.ts.map +1 -0
  65. package/dist/__tests__/segment-system.test.js +627 -0
  66. package/dist/__tests__/segment-system.test.js.map +1 -0
  67. package/dist/__tests__/static-handler-types.test.d.ts +8 -0
  68. package/dist/__tests__/static-handler-types.test.d.ts.map +1 -0
  69. package/dist/__tests__/static-handler-types.test.js +63 -0
  70. package/dist/__tests__/static-handler-types.test.js.map +1 -0
  71. package/dist/__tests__/urls.test.d.ts +2 -0
  72. package/dist/__tests__/urls.test.d.ts.map +1 -0
  73. package/dist/__tests__/urls.test.js +421 -0
  74. package/dist/__tests__/urls.test.js.map +1 -0
  75. package/dist/__tests__/use-mount.test.d.ts +2 -0
  76. package/dist/__tests__/use-mount.test.d.ts.map +1 -0
  77. package/dist/__tests__/use-mount.test.js +35 -0
  78. package/dist/__tests__/use-mount.test.js.map +1 -0
  79. package/dist/bin/rango.d.ts +2 -0
  80. package/dist/bin/rango.d.ts.map +1 -0
  81. package/dist/bin/rango.js +1844 -237
  82. package/dist/bin/rango.js.map +1 -0
  83. package/dist/browser/event-controller.d.ts +191 -0
  84. package/dist/browser/event-controller.d.ts.map +1 -0
  85. package/dist/browser/event-controller.js +559 -0
  86. package/dist/browser/event-controller.js.map +1 -0
  87. package/dist/browser/index.d.ts +2 -0
  88. package/dist/browser/index.d.ts.map +1 -0
  89. package/dist/browser/index.js +14 -0
  90. package/dist/browser/index.js.map +1 -0
  91. package/dist/browser/link-interceptor.d.ts +38 -0
  92. package/dist/browser/link-interceptor.d.ts.map +1 -0
  93. package/dist/browser/link-interceptor.js +99 -0
  94. package/dist/browser/link-interceptor.js.map +1 -0
  95. package/dist/browser/logging.d.ts +10 -0
  96. package/dist/browser/logging.d.ts.map +1 -0
  97. package/dist/browser/logging.js +29 -0
  98. package/dist/browser/logging.js.map +1 -0
  99. package/dist/browser/lru-cache.d.ts +17 -0
  100. package/dist/browser/lru-cache.d.ts.map +1 -0
  101. package/dist/browser/lru-cache.js +50 -0
  102. package/dist/browser/lru-cache.js.map +1 -0
  103. package/dist/browser/merge-segment-loaders.d.ts +39 -0
  104. package/dist/browser/merge-segment-loaders.d.ts.map +1 -0
  105. package/dist/browser/merge-segment-loaders.js +102 -0
  106. package/dist/browser/merge-segment-loaders.js.map +1 -0
  107. package/dist/browser/navigation-bridge.d.ts +102 -0
  108. package/dist/browser/navigation-bridge.d.ts.map +1 -0
  109. package/dist/browser/navigation-bridge.js +708 -0
  110. package/dist/browser/navigation-bridge.js.map +1 -0
  111. package/dist/browser/navigation-client.d.ts +25 -0
  112. package/dist/browser/navigation-client.d.ts.map +1 -0
  113. package/dist/browser/navigation-client.js +157 -0
  114. package/dist/browser/navigation-client.js.map +1 -0
  115. package/dist/browser/navigation-store.d.ts +101 -0
  116. package/dist/browser/navigation-store.d.ts.map +1 -0
  117. package/dist/browser/navigation-store.js +625 -0
  118. package/dist/browser/navigation-store.js.map +1 -0
  119. package/dist/browser/partial-update.d.ts +75 -0
  120. package/dist/browser/partial-update.d.ts.map +1 -0
  121. package/dist/browser/partial-update.js +426 -0
  122. package/dist/browser/partial-update.js.map +1 -0
  123. package/dist/browser/react/Link.d.ts +86 -0
  124. package/dist/browser/react/Link.d.ts.map +1 -0
  125. package/dist/browser/react/Link.js +128 -0
  126. package/dist/browser/react/Link.js.map +1 -0
  127. package/dist/browser/react/NavigationProvider.d.ts +63 -0
  128. package/dist/browser/react/NavigationProvider.d.ts.map +1 -0
  129. package/dist/browser/react/NavigationProvider.js +216 -0
  130. package/dist/browser/react/NavigationProvider.js.map +1 -0
  131. package/dist/browser/react/ScrollRestoration.d.ts +75 -0
  132. package/dist/browser/react/ScrollRestoration.d.ts.map +1 -0
  133. package/dist/browser/react/ScrollRestoration.js +57 -0
  134. package/dist/browser/react/ScrollRestoration.js.map +1 -0
  135. package/dist/browser/react/context.d.ts +46 -0
  136. package/dist/browser/react/context.d.ts.map +1 -0
  137. package/dist/browser/react/context.js +10 -0
  138. package/dist/browser/react/context.js.map +1 -0
  139. package/dist/browser/react/index.d.ts +11 -0
  140. package/dist/browser/react/index.d.ts.map +1 -0
  141. package/dist/browser/react/index.js +22 -0
  142. package/dist/browser/react/index.js.map +1 -0
  143. package/dist/browser/react/location-state-shared.d.ts +63 -0
  144. package/dist/browser/react/location-state-shared.d.ts.map +1 -0
  145. package/dist/browser/react/location-state-shared.js +81 -0
  146. package/dist/browser/react/location-state-shared.js.map +1 -0
  147. package/dist/browser/react/location-state.d.ts +23 -0
  148. package/dist/browser/react/location-state.d.ts.map +1 -0
  149. package/dist/browser/react/location-state.js +29 -0
  150. package/dist/browser/react/location-state.js.map +1 -0
  151. package/dist/browser/react/mount-context.d.ts +24 -0
  152. package/dist/browser/react/mount-context.d.ts.map +1 -0
  153. package/dist/browser/react/mount-context.js +24 -0
  154. package/dist/browser/react/mount-context.js.map +1 -0
  155. package/dist/browser/react/use-action.d.ts +64 -0
  156. package/dist/browser/react/use-action.d.ts.map +1 -0
  157. package/dist/browser/react/use-action.js +134 -0
  158. package/dist/browser/react/use-action.js.map +1 -0
  159. package/dist/browser/react/use-client-cache.d.ts +41 -0
  160. package/dist/browser/react/use-client-cache.d.ts.map +1 -0
  161. package/{src/browser/react/use-client-cache.ts → dist/browser/react/use-client-cache.js} +9 -26
  162. package/dist/browser/react/use-client-cache.js.map +1 -0
  163. package/dist/browser/react/use-handle.d.ts +31 -0
  164. package/dist/browser/react/use-handle.d.ts.map +1 -0
  165. package/dist/browser/react/use-handle.js +144 -0
  166. package/dist/browser/react/use-handle.js.map +1 -0
  167. package/dist/browser/react/use-href.d.ts +33 -0
  168. package/dist/browser/react/use-href.d.ts.map +1 -0
  169. package/dist/browser/react/use-href.js +39 -0
  170. package/dist/browser/react/use-href.js.map +1 -0
  171. package/dist/browser/react/use-link-status.d.ts +37 -0
  172. package/dist/browser/react/use-link-status.d.ts.map +1 -0
  173. package/dist/browser/react/use-link-status.js +99 -0
  174. package/dist/browser/react/use-link-status.js.map +1 -0
  175. package/dist/browser/react/use-mount.d.ts +25 -0
  176. package/dist/browser/react/use-mount.d.ts.map +1 -0
  177. package/dist/browser/react/use-mount.js +30 -0
  178. package/dist/browser/react/use-mount.js.map +1 -0
  179. package/dist/browser/react/use-navigation.d.ts +27 -0
  180. package/dist/browser/react/use-navigation.d.ts.map +1 -0
  181. package/dist/browser/react/use-navigation.js +87 -0
  182. package/dist/browser/react/use-navigation.js.map +1 -0
  183. package/dist/browser/react/use-segments.d.ts +38 -0
  184. package/dist/browser/react/use-segments.d.ts.map +1 -0
  185. package/dist/browser/react/use-segments.js +130 -0
  186. package/dist/browser/react/use-segments.js.map +1 -0
  187. package/dist/browser/request-controller.d.ts +26 -0
  188. package/dist/browser/request-controller.d.ts.map +1 -0
  189. package/dist/browser/request-controller.js +147 -0
  190. package/dist/browser/request-controller.js.map +1 -0
  191. package/dist/browser/rsc-router.d.ts +129 -0
  192. package/dist/browser/rsc-router.d.ts.map +1 -0
  193. package/dist/browser/rsc-router.js +195 -0
  194. package/dist/browser/rsc-router.js.map +1 -0
  195. package/dist/browser/scroll-restoration.d.ts +93 -0
  196. package/dist/browser/scroll-restoration.d.ts.map +1 -0
  197. package/dist/browser/scroll-restoration.js +321 -0
  198. package/dist/browser/scroll-restoration.js.map +1 -0
  199. package/dist/browser/segment-structure-assert.d.ts +17 -0
  200. package/dist/browser/segment-structure-assert.d.ts.map +1 -0
  201. package/dist/browser/segment-structure-assert.js +59 -0
  202. package/dist/browser/segment-structure-assert.js.map +1 -0
  203. package/dist/browser/server-action-bridge.d.ts +26 -0
  204. package/dist/browser/server-action-bridge.d.ts.map +1 -0
  205. package/dist/browser/server-action-bridge.js +668 -0
  206. package/dist/browser/server-action-bridge.js.map +1 -0
  207. package/dist/browser/shallow.d.ts +12 -0
  208. package/dist/browser/shallow.d.ts.map +1 -0
  209. package/dist/browser/shallow.js +34 -0
  210. package/dist/browser/shallow.js.map +1 -0
  211. package/dist/browser/types.d.ts +369 -0
  212. package/dist/browser/types.d.ts.map +1 -0
  213. package/dist/browser/types.js +2 -0
  214. package/dist/browser/types.js.map +1 -0
  215. package/dist/build/__tests__/generate-cli.test.d.ts +2 -0
  216. package/dist/build/__tests__/generate-cli.test.d.ts.map +1 -0
  217. package/dist/build/__tests__/generate-cli.test.js +237 -0
  218. package/dist/build/__tests__/generate-cli.test.js.map +1 -0
  219. package/dist/build/__tests__/generate-manifest.test.d.ts +2 -0
  220. package/dist/build/__tests__/generate-manifest.test.d.ts.map +1 -0
  221. package/dist/build/__tests__/generate-manifest.test.js +119 -0
  222. package/dist/build/__tests__/generate-manifest.test.js.map +1 -0
  223. package/dist/build/__tests__/generate-route-types.test.d.ts +2 -0
  224. package/dist/build/__tests__/generate-route-types.test.d.ts.map +1 -0
  225. package/dist/build/__tests__/generate-route-types.test.js +620 -0
  226. package/dist/build/__tests__/generate-route-types.test.js.map +1 -0
  227. package/dist/build/__tests__/per-router-manifest.test.d.ts +2 -0
  228. package/dist/build/__tests__/per-router-manifest.test.d.ts.map +1 -0
  229. package/dist/build/__tests__/per-router-manifest.test.js +308 -0
  230. package/dist/build/__tests__/per-router-manifest.test.js.map +1 -0
  231. package/dist/build/generate-manifest.d.ts +81 -0
  232. package/dist/build/generate-manifest.d.ts.map +1 -0
  233. package/dist/build/generate-manifest.js +276 -0
  234. package/dist/build/generate-manifest.js.map +1 -0
  235. package/dist/build/generate-route-types.d.ts +115 -0
  236. package/dist/build/generate-route-types.d.ts.map +1 -0
  237. package/dist/build/generate-route-types.js +740 -0
  238. package/dist/build/generate-route-types.js.map +1 -0
  239. package/dist/build/index.d.ts +21 -0
  240. package/dist/build/index.d.ts.map +1 -0
  241. package/dist/build/index.js +21 -0
  242. package/dist/build/index.js.map +1 -0
  243. package/dist/build/route-trie.d.ts +71 -0
  244. package/dist/build/route-trie.d.ts.map +1 -0
  245. package/dist/build/route-trie.js +175 -0
  246. package/dist/build/route-trie.js.map +1 -0
  247. package/dist/cache/__tests__/cache-scope.test.d.ts +2 -0
  248. package/dist/cache/__tests__/cache-scope.test.d.ts.map +1 -0
  249. package/dist/cache/__tests__/cache-scope.test.js +208 -0
  250. package/dist/cache/__tests__/cache-scope.test.js.map +1 -0
  251. package/dist/cache/__tests__/document-cache.test.d.ts +2 -0
  252. package/dist/cache/__tests__/document-cache.test.d.ts.map +1 -0
  253. package/dist/cache/__tests__/document-cache.test.js +345 -0
  254. package/dist/cache/__tests__/document-cache.test.js.map +1 -0
  255. package/dist/cache/__tests__/memory-segment-store.test.d.ts +2 -0
  256. package/dist/cache/__tests__/memory-segment-store.test.d.ts.map +1 -0
  257. package/dist/cache/__tests__/memory-segment-store.test.js +425 -0
  258. package/dist/cache/__tests__/memory-segment-store.test.js.map +1 -0
  259. package/dist/cache/__tests__/memory-store.test.d.ts +2 -0
  260. package/dist/cache/__tests__/memory-store.test.d.ts.map +1 -0
  261. package/dist/cache/__tests__/memory-store.test.js +367 -0
  262. package/dist/cache/__tests__/memory-store.test.js.map +1 -0
  263. package/dist/cache/cache-scope.d.ts +102 -0
  264. package/dist/cache/cache-scope.d.ts.map +1 -0
  265. package/dist/cache/cache-scope.js +440 -0
  266. package/dist/cache/cache-scope.js.map +1 -0
  267. package/dist/cache/cf/__tests__/cf-cache-store.test.d.ts +2 -0
  268. package/dist/cache/cf/__tests__/cf-cache-store.test.d.ts.map +1 -0
  269. package/dist/cache/cf/__tests__/cf-cache-store.test.js +330 -0
  270. package/dist/cache/cf/__tests__/cf-cache-store.test.js.map +1 -0
  271. package/dist/cache/cf/cf-cache-store.d.ts +165 -0
  272. package/dist/cache/cf/cf-cache-store.d.ts.map +1 -0
  273. package/dist/cache/cf/cf-cache-store.js +242 -0
  274. package/dist/cache/cf/cf-cache-store.js.map +1 -0
  275. package/dist/cache/cf/index.d.ts +14 -0
  276. package/dist/cache/cf/index.d.ts.map +1 -0
  277. package/dist/cache/cf/index.js +17 -0
  278. package/dist/cache/cf/index.js.map +1 -0
  279. package/dist/cache/document-cache.d.ts +64 -0
  280. package/dist/cache/document-cache.d.ts.map +1 -0
  281. package/dist/cache/document-cache.js +228 -0
  282. package/dist/cache/document-cache.js.map +1 -0
  283. package/dist/cache/index.d.ts +19 -0
  284. package/dist/cache/index.d.ts.map +1 -0
  285. package/dist/cache/index.js +21 -0
  286. package/dist/cache/index.js.map +1 -0
  287. package/dist/cache/memory-segment-store.d.ts +110 -0
  288. package/dist/cache/memory-segment-store.d.ts.map +1 -0
  289. package/dist/cache/memory-segment-store.js +117 -0
  290. package/dist/cache/memory-segment-store.js.map +1 -0
  291. package/dist/cache/memory-store.d.ts +41 -0
  292. package/dist/cache/memory-store.d.ts.map +1 -0
  293. package/dist/cache/memory-store.js +191 -0
  294. package/dist/cache/memory-store.js.map +1 -0
  295. package/dist/cache/types.d.ts +317 -0
  296. package/dist/cache/types.d.ts.map +1 -0
  297. package/dist/cache/types.js +12 -0
  298. package/dist/cache/types.js.map +1 -0
  299. package/dist/client.d.ts +248 -0
  300. package/dist/client.d.ts.map +1 -0
  301. package/dist/client.js +367 -0
  302. package/dist/client.js.map +1 -0
  303. package/dist/client.rsc.d.ts +26 -0
  304. package/dist/client.rsc.d.ts.map +1 -0
  305. package/dist/client.rsc.js +46 -0
  306. package/dist/client.rsc.js.map +1 -0
  307. package/dist/component-utils.d.ts +36 -0
  308. package/dist/component-utils.d.ts.map +1 -0
  309. package/dist/component-utils.js +61 -0
  310. package/dist/component-utils.js.map +1 -0
  311. package/dist/components/DefaultDocument.d.ts +13 -0
  312. package/dist/components/DefaultDocument.d.ts.map +1 -0
  313. package/dist/components/DefaultDocument.js +15 -0
  314. package/dist/components/DefaultDocument.js.map +1 -0
  315. package/dist/debug.d.ts +58 -0
  316. package/dist/debug.d.ts.map +1 -0
  317. package/dist/debug.js +157 -0
  318. package/dist/debug.js.map +1 -0
  319. package/dist/default-error-boundary.d.ts +11 -0
  320. package/dist/default-error-boundary.d.ts.map +1 -0
  321. package/dist/default-error-boundary.js +45 -0
  322. package/dist/default-error-boundary.js.map +1 -0
  323. package/dist/deps/browser.d.ts +2 -0
  324. package/dist/deps/browser.d.ts.map +1 -0
  325. package/dist/deps/browser.js +3 -0
  326. package/dist/deps/browser.js.map +1 -0
  327. package/dist/deps/html-stream-client.d.ts +2 -0
  328. package/dist/deps/html-stream-client.d.ts.map +1 -0
  329. package/dist/deps/html-stream-client.js +3 -0
  330. package/dist/deps/html-stream-client.js.map +1 -0
  331. package/dist/deps/html-stream-server.d.ts +2 -0
  332. package/dist/deps/html-stream-server.d.ts.map +1 -0
  333. package/dist/deps/html-stream-server.js +3 -0
  334. package/dist/deps/html-stream-server.js.map +1 -0
  335. package/dist/deps/rsc.d.ts +2 -0
  336. package/dist/deps/rsc.d.ts.map +1 -0
  337. package/dist/deps/rsc.js +4 -0
  338. package/dist/deps/rsc.js.map +1 -0
  339. package/dist/deps/ssr.d.ts +2 -0
  340. package/dist/deps/ssr.d.ts.map +1 -0
  341. package/dist/deps/ssr.js +3 -0
  342. package/dist/deps/ssr.js.map +1 -0
  343. package/dist/errors.d.ts +174 -0
  344. package/dist/errors.d.ts.map +1 -0
  345. package/dist/errors.js +241 -0
  346. package/dist/errors.js.map +1 -0
  347. package/dist/handle.d.ts +78 -0
  348. package/dist/handle.d.ts.map +1 -0
  349. package/dist/handle.js +82 -0
  350. package/dist/handle.js.map +1 -0
  351. package/dist/handles/MetaTags.d.ts +14 -0
  352. package/dist/handles/MetaTags.d.ts.map +1 -0
  353. package/dist/handles/MetaTags.js +136 -0
  354. package/dist/handles/MetaTags.js.map +1 -0
  355. package/dist/handles/index.d.ts +6 -0
  356. package/dist/handles/index.d.ts.map +1 -0
  357. package/{src/handles/index.ts → dist/handles/index.js} +1 -1
  358. package/dist/handles/index.js.map +1 -0
  359. package/dist/handles/meta.d.ts +39 -0
  360. package/dist/handles/meta.d.ts.map +1 -0
  361. package/dist/handles/meta.js +202 -0
  362. package/dist/handles/meta.js.map +1 -0
  363. package/dist/host/__tests__/errors.test.d.ts +2 -0
  364. package/dist/host/__tests__/errors.test.d.ts.map +1 -0
  365. package/dist/host/__tests__/errors.test.js +76 -0
  366. package/dist/host/__tests__/errors.test.js.map +1 -0
  367. package/dist/host/__tests__/pattern-comprehensive.test.d.ts +2 -0
  368. package/dist/host/__tests__/pattern-comprehensive.test.d.ts.map +1 -0
  369. package/dist/host/__tests__/pattern-comprehensive.test.js +732 -0
  370. package/dist/host/__tests__/pattern-comprehensive.test.js.map +1 -0
  371. package/dist/host/__tests__/pattern-matcher.test.d.ts +2 -0
  372. package/dist/host/__tests__/pattern-matcher.test.d.ts.map +1 -0
  373. package/dist/host/__tests__/pattern-matcher.test.js +251 -0
  374. package/dist/host/__tests__/pattern-matcher.test.js.map +1 -0
  375. package/dist/host/__tests__/router.test.d.ts +2 -0
  376. package/dist/host/__tests__/router.test.d.ts.map +1 -0
  377. package/dist/host/__tests__/router.test.js +241 -0
  378. package/dist/host/__tests__/router.test.js.map +1 -0
  379. package/dist/host/__tests__/testing.test.d.ts +2 -0
  380. package/dist/host/__tests__/testing.test.d.ts.map +1 -0
  381. package/dist/host/__tests__/testing.test.js +64 -0
  382. package/dist/host/__tests__/testing.test.js.map +1 -0
  383. package/dist/host/__tests__/utils.test.d.ts +2 -0
  384. package/dist/host/__tests__/utils.test.d.ts.map +1 -0
  385. package/dist/host/__tests__/utils.test.js +29 -0
  386. package/dist/host/__tests__/utils.test.js.map +1 -0
  387. package/dist/host/cookie-handler.d.ts +34 -0
  388. package/dist/host/cookie-handler.d.ts.map +1 -0
  389. package/dist/host/cookie-handler.js +124 -0
  390. package/dist/host/cookie-handler.js.map +1 -0
  391. package/dist/host/errors.d.ts +56 -0
  392. package/dist/host/errors.d.ts.map +1 -0
  393. package/dist/host/errors.js +79 -0
  394. package/dist/host/errors.js.map +1 -0
  395. package/dist/host/index.d.ts +29 -0
  396. package/dist/host/index.d.ts.map +1 -0
  397. package/dist/host/index.js +32 -0
  398. package/dist/host/index.js.map +1 -0
  399. package/dist/host/pattern-matcher.d.ts +36 -0
  400. package/dist/host/pattern-matcher.d.ts.map +1 -0
  401. package/dist/host/pattern-matcher.js +172 -0
  402. package/dist/host/pattern-matcher.js.map +1 -0
  403. package/dist/host/router.d.ts +26 -0
  404. package/dist/host/router.d.ts.map +1 -0
  405. package/dist/host/router.js +218 -0
  406. package/dist/host/router.js.map +1 -0
  407. package/dist/host/testing.d.ts +36 -0
  408. package/dist/host/testing.d.ts.map +1 -0
  409. package/dist/host/testing.js +55 -0
  410. package/dist/host/testing.js.map +1 -0
  411. package/dist/host/types.d.ts +115 -0
  412. package/dist/host/types.d.ts.map +1 -0
  413. package/dist/host/types.js +7 -0
  414. package/dist/host/types.js.map +1 -0
  415. package/dist/host/utils.d.ts +21 -0
  416. package/dist/host/utils.d.ts.map +1 -0
  417. package/dist/host/utils.js +23 -0
  418. package/dist/host/utils.js.map +1 -0
  419. package/dist/href-client.d.ts +131 -0
  420. package/dist/href-client.d.ts.map +1 -0
  421. package/dist/href-client.js +64 -0
  422. package/dist/href-client.js.map +1 -0
  423. package/{src/href-context.ts → dist/href-context.d.ts} +7 -11
  424. package/dist/href-context.d.ts.map +1 -0
  425. package/dist/href-context.js +21 -0
  426. package/dist/href-context.js.map +1 -0
  427. package/dist/index.d.ts +73 -0
  428. package/dist/index.d.ts.map +1 -0
  429. package/dist/index.js +91 -0
  430. package/dist/index.js.map +1 -0
  431. package/dist/index.rsc.d.ts +32 -0
  432. package/dist/index.rsc.d.ts.map +1 -0
  433. package/dist/index.rsc.js +40 -0
  434. package/dist/index.rsc.js.map +1 -0
  435. package/dist/internal-debug.d.ts +2 -0
  436. package/dist/internal-debug.d.ts.map +1 -0
  437. package/dist/internal-debug.js +5 -0
  438. package/dist/internal-debug.js.map +1 -0
  439. package/dist/loader.d.ts +14 -0
  440. package/dist/loader.d.ts.map +1 -0
  441. package/dist/loader.js +20 -0
  442. package/dist/loader.js.map +1 -0
  443. package/dist/loader.rsc.d.ts +19 -0
  444. package/dist/loader.rsc.d.ts.map +1 -0
  445. package/dist/loader.rsc.js +99 -0
  446. package/dist/loader.rsc.js.map +1 -0
  447. package/{src/network-error-thrower.tsx → dist/network-error-thrower.d.ts} +4 -8
  448. package/dist/network-error-thrower.d.ts.map +1 -0
  449. package/dist/network-error-thrower.js +14 -0
  450. package/dist/network-error-thrower.js.map +1 -0
  451. package/dist/outlet-context.d.ts +13 -0
  452. package/dist/outlet-context.d.ts.map +1 -0
  453. package/dist/outlet-context.js +3 -0
  454. package/dist/outlet-context.js.map +1 -0
  455. package/dist/prerender/__tests__/param-hash.test.d.ts +2 -0
  456. package/dist/prerender/__tests__/param-hash.test.d.ts.map +1 -0
  457. package/dist/prerender/__tests__/param-hash.test.js +148 -0
  458. package/dist/prerender/__tests__/param-hash.test.js.map +1 -0
  459. package/dist/prerender/param-hash.d.ts +16 -0
  460. package/dist/prerender/param-hash.d.ts.map +1 -0
  461. package/dist/prerender/param-hash.js +36 -0
  462. package/dist/prerender/param-hash.js.map +1 -0
  463. package/dist/prerender/store.d.ts +38 -0
  464. package/dist/prerender/store.d.ts.map +1 -0
  465. package/dist/prerender/store.js +61 -0
  466. package/dist/prerender/store.js.map +1 -0
  467. package/dist/prerender.d.ts +66 -0
  468. package/dist/prerender.d.ts.map +1 -0
  469. package/dist/prerender.js +57 -0
  470. package/dist/prerender.js.map +1 -0
  471. package/dist/reverse.d.ts +196 -0
  472. package/dist/reverse.d.ts.map +1 -0
  473. package/dist/reverse.js +78 -0
  474. package/dist/reverse.js.map +1 -0
  475. package/dist/root-error-boundary.d.ts +33 -0
  476. package/dist/root-error-boundary.d.ts.map +1 -0
  477. package/dist/root-error-boundary.js +165 -0
  478. package/dist/root-error-boundary.js.map +1 -0
  479. package/dist/route-content-wrapper.d.ts +46 -0
  480. package/dist/route-content-wrapper.d.ts.map +1 -0
  481. package/dist/route-content-wrapper.js +77 -0
  482. package/dist/route-content-wrapper.js.map +1 -0
  483. package/dist/route-definition.d.ts +421 -0
  484. package/dist/route-definition.d.ts.map +1 -0
  485. package/dist/route-definition.js +868 -0
  486. package/dist/route-definition.js.map +1 -0
  487. package/dist/route-map-builder.d.ts +155 -0
  488. package/dist/route-map-builder.d.ts.map +1 -0
  489. package/dist/route-map-builder.js +237 -0
  490. package/dist/route-map-builder.js.map +1 -0
  491. package/dist/route-types.d.ts +165 -0
  492. package/dist/route-types.d.ts.map +1 -0
  493. package/dist/route-types.js +7 -0
  494. package/dist/route-types.js.map +1 -0
  495. package/dist/router/__tests__/handler-context.test.d.ts +2 -0
  496. package/dist/router/__tests__/handler-context.test.d.ts.map +1 -0
  497. package/dist/router/__tests__/handler-context.test.js +65 -0
  498. package/dist/router/__tests__/handler-context.test.js.map +1 -0
  499. package/dist/router/__tests__/loader-cycle-detection.test.d.ts +2 -0
  500. package/dist/router/__tests__/loader-cycle-detection.test.d.ts.map +1 -0
  501. package/dist/router/__tests__/loader-cycle-detection.test.js +221 -0
  502. package/dist/router/__tests__/loader-cycle-detection.test.js.map +1 -0
  503. package/dist/router/__tests__/match-context.test.d.ts +2 -0
  504. package/dist/router/__tests__/match-context.test.d.ts.map +1 -0
  505. package/dist/router/__tests__/match-context.test.js +92 -0
  506. package/dist/router/__tests__/match-context.test.js.map +1 -0
  507. package/dist/router/__tests__/match-pipelines.test.d.ts +2 -0
  508. package/dist/router/__tests__/match-pipelines.test.d.ts.map +1 -0
  509. package/dist/router/__tests__/match-pipelines.test.js +417 -0
  510. package/dist/router/__tests__/match-pipelines.test.js.map +1 -0
  511. package/dist/router/__tests__/match-result.test.d.ts +2 -0
  512. package/dist/router/__tests__/match-result.test.d.ts.map +1 -0
  513. package/dist/router/__tests__/match-result.test.js +457 -0
  514. package/dist/router/__tests__/match-result.test.js.map +1 -0
  515. package/dist/router/__tests__/on-error.test.d.ts +2 -0
  516. package/dist/router/__tests__/on-error.test.d.ts.map +1 -0
  517. package/dist/router/__tests__/on-error.test.js +678 -0
  518. package/dist/router/__tests__/on-error.test.js.map +1 -0
  519. package/dist/router/__tests__/pattern-matching.test.d.ts +2 -0
  520. package/dist/router/__tests__/pattern-matching.test.d.ts.map +1 -0
  521. package/dist/router/__tests__/pattern-matching.test.js +629 -0
  522. package/dist/router/__tests__/pattern-matching.test.js.map +1 -0
  523. package/dist/router/__tests__/segment-resolution-parallel-loading.test.d.ts +2 -0
  524. package/dist/router/__tests__/segment-resolution-parallel-loading.test.d.ts.map +1 -0
  525. package/dist/router/__tests__/segment-resolution-parallel-loading.test.js +155 -0
  526. package/dist/router/__tests__/segment-resolution-parallel-loading.test.js.map +1 -0
  527. package/dist/router/error-handling.d.ts +77 -0
  528. package/dist/router/error-handling.d.ts.map +1 -0
  529. package/dist/router/error-handling.js +202 -0
  530. package/dist/router/error-handling.js.map +1 -0
  531. package/dist/router/handler-context.d.ts +20 -0
  532. package/dist/router/handler-context.d.ts.map +1 -0
  533. package/dist/router/handler-context.js +198 -0
  534. package/dist/router/handler-context.js.map +1 -0
  535. package/dist/router/intercept-resolution.d.ts +66 -0
  536. package/dist/router/intercept-resolution.d.ts.map +1 -0
  537. package/dist/router/intercept-resolution.js +246 -0
  538. package/dist/router/intercept-resolution.js.map +1 -0
  539. package/dist/router/loader-resolution.d.ts +64 -0
  540. package/dist/router/loader-resolution.d.ts.map +1 -0
  541. package/dist/router/loader-resolution.js +284 -0
  542. package/dist/router/loader-resolution.js.map +1 -0
  543. package/dist/router/logging.d.ts +15 -0
  544. package/dist/router/logging.d.ts.map +1 -0
  545. package/dist/router/logging.js +99 -0
  546. package/dist/router/logging.js.map +1 -0
  547. package/dist/router/manifest.d.ts +22 -0
  548. package/dist/router/manifest.d.ts.map +1 -0
  549. package/dist/router/manifest.js +181 -0
  550. package/dist/router/manifest.js.map +1 -0
  551. package/dist/router/match-api.d.ts +35 -0
  552. package/dist/router/match-api.d.ts.map +1 -0
  553. package/dist/router/match-api.js +406 -0
  554. package/dist/router/match-api.js.map +1 -0
  555. package/dist/router/match-context.d.ts +206 -0
  556. package/dist/router/match-context.d.ts.map +1 -0
  557. package/dist/router/match-context.js +17 -0
  558. package/dist/router/match-context.js.map +1 -0
  559. package/dist/router/match-middleware/background-revalidation.d.ts +127 -0
  560. package/dist/router/match-middleware/background-revalidation.d.ts.map +1 -0
  561. package/dist/router/match-middleware/background-revalidation.js +75 -0
  562. package/dist/router/match-middleware/background-revalidation.js.map +1 -0
  563. package/dist/router/match-middleware/cache-lookup.d.ts +112 -0
  564. package/dist/router/match-middleware/cache-lookup.d.ts.map +1 -0
  565. package/dist/router/match-middleware/cache-lookup.js +257 -0
  566. package/dist/router/match-middleware/cache-lookup.js.map +1 -0
  567. package/dist/router/match-middleware/cache-store.d.ts +113 -0
  568. package/dist/router/match-middleware/cache-store.d.ts.map +1 -0
  569. package/dist/router/match-middleware/cache-store.js +108 -0
  570. package/dist/router/match-middleware/cache-store.js.map +1 -0
  571. package/dist/router/match-middleware/index.d.ts +81 -0
  572. package/dist/router/match-middleware/index.d.ts.map +1 -0
  573. package/dist/router/match-middleware/index.js +80 -0
  574. package/dist/router/match-middleware/index.js.map +1 -0
  575. package/dist/router/match-middleware/intercept-resolution.d.ts +117 -0
  576. package/dist/router/match-middleware/intercept-resolution.d.ts.map +1 -0
  577. package/dist/router/match-middleware/intercept-resolution.js +134 -0
  578. package/dist/router/match-middleware/intercept-resolution.js.map +1 -0
  579. package/dist/router/match-middleware/segment-resolution.d.ts +99 -0
  580. package/dist/router/match-middleware/segment-resolution.d.ts.map +1 -0
  581. package/dist/router/match-middleware/segment-resolution.js +53 -0
  582. package/dist/router/match-middleware/segment-resolution.js.map +1 -0
  583. package/dist/router/match-pipelines.d.ts +147 -0
  584. package/dist/router/match-pipelines.d.ts.map +1 -0
  585. package/dist/router/match-pipelines.js +82 -0
  586. package/dist/router/match-pipelines.js.map +1 -0
  587. package/dist/router/match-result.d.ts +126 -0
  588. package/dist/router/match-result.d.ts.map +1 -0
  589. package/dist/router/match-result.js +93 -0
  590. package/dist/router/match-result.js.map +1 -0
  591. package/dist/router/metrics.d.ts +20 -0
  592. package/dist/router/metrics.d.ts.map +1 -0
  593. package/dist/router/metrics.js +47 -0
  594. package/dist/router/metrics.js.map +1 -0
  595. package/dist/router/middleware.d.ts +249 -0
  596. package/dist/router/middleware.d.ts.map +1 -0
  597. package/dist/router/middleware.js +434 -0
  598. package/dist/router/middleware.js.map +1 -0
  599. package/dist/router/middleware.test.d.ts +2 -0
  600. package/dist/router/middleware.test.d.ts.map +1 -0
  601. package/dist/router/middleware.test.js +816 -0
  602. package/dist/router/middleware.test.js.map +1 -0
  603. package/dist/router/pattern-matching.d.ts +149 -0
  604. package/dist/router/pattern-matching.d.ts.map +1 -0
  605. package/dist/router/pattern-matching.js +349 -0
  606. package/dist/router/pattern-matching.js.map +1 -0
  607. package/dist/router/revalidation.d.ts +44 -0
  608. package/dist/router/revalidation.d.ts.map +1 -0
  609. package/dist/router/revalidation.js +147 -0
  610. package/dist/router/revalidation.js.map +1 -0
  611. package/dist/router/router-context.d.ts +135 -0
  612. package/dist/router/router-context.d.ts.map +1 -0
  613. package/dist/router/router-context.js +36 -0
  614. package/dist/router/router-context.js.map +1 -0
  615. package/dist/router/segment-resolution.d.ts +127 -0
  616. package/dist/router/segment-resolution.d.ts.map +1 -0
  617. package/dist/router/segment-resolution.js +919 -0
  618. package/dist/router/segment-resolution.js.map +1 -0
  619. package/dist/router/trie-matching.d.ts +40 -0
  620. package/dist/router/trie-matching.d.ts.map +1 -0
  621. package/dist/router/trie-matching.js +127 -0
  622. package/dist/router/trie-matching.js.map +1 -0
  623. package/dist/router/types.d.ts +136 -0
  624. package/dist/router/types.d.ts.map +1 -0
  625. package/dist/router/types.js +7 -0
  626. package/dist/router/types.js.map +1 -0
  627. package/dist/router.d.ts +753 -0
  628. package/dist/router.d.ts.map +1 -0
  629. package/dist/router.gen.d.ts +6 -0
  630. package/dist/router.gen.d.ts.map +1 -0
  631. package/dist/router.gen.js +6 -0
  632. package/dist/router.gen.js.map +1 -0
  633. package/dist/router.js +1304 -0
  634. package/dist/router.js.map +1 -0
  635. package/dist/rsc/__tests__/helpers.test.d.ts +2 -0
  636. package/dist/rsc/__tests__/helpers.test.d.ts.map +1 -0
  637. package/dist/rsc/__tests__/helpers.test.js +140 -0
  638. package/dist/rsc/__tests__/helpers.test.js.map +1 -0
  639. package/dist/rsc/handler.d.ts +45 -0
  640. package/dist/rsc/handler.d.ts.map +1 -0
  641. package/dist/rsc/handler.js +1172 -0
  642. package/dist/rsc/handler.js.map +1 -0
  643. package/dist/rsc/helpers.d.ts +16 -0
  644. package/dist/rsc/helpers.d.ts.map +1 -0
  645. package/dist/rsc/helpers.js +55 -0
  646. package/dist/rsc/helpers.js.map +1 -0
  647. package/dist/rsc/index.d.ts +22 -0
  648. package/dist/rsc/index.d.ts.map +1 -0
  649. package/dist/rsc/index.js +23 -0
  650. package/dist/rsc/index.js.map +1 -0
  651. package/dist/rsc/nonce.d.ts +9 -0
  652. package/dist/rsc/nonce.d.ts.map +1 -0
  653. package/dist/rsc/nonce.js +18 -0
  654. package/dist/rsc/nonce.js.map +1 -0
  655. package/dist/rsc/types.d.ts +206 -0
  656. package/dist/rsc/types.d.ts.map +1 -0
  657. package/dist/rsc/types.js +8 -0
  658. package/dist/rsc/types.js.map +1 -0
  659. package/dist/search-params.d.ts +103 -0
  660. package/dist/search-params.d.ts.map +1 -0
  661. package/dist/search-params.js +74 -0
  662. package/dist/search-params.js.map +1 -0
  663. package/dist/segment-system.d.ts +75 -0
  664. package/dist/segment-system.d.ts.map +1 -0
  665. package/dist/segment-system.js +336 -0
  666. package/dist/segment-system.js.map +1 -0
  667. package/dist/server/context.d.ts +245 -0
  668. package/dist/server/context.d.ts.map +1 -0
  669. package/dist/server/context.js +197 -0
  670. package/dist/server/context.js.map +1 -0
  671. package/dist/server/fetchable-loader-store.d.ts +18 -0
  672. package/dist/server/fetchable-loader-store.d.ts.map +1 -0
  673. package/dist/server/fetchable-loader-store.js +18 -0
  674. package/dist/server/fetchable-loader-store.js.map +1 -0
  675. package/dist/server/handle-store.d.ts +85 -0
  676. package/dist/server/handle-store.d.ts.map +1 -0
  677. package/dist/server/handle-store.js +142 -0
  678. package/dist/server/handle-store.js.map +1 -0
  679. package/dist/server/loader-registry.d.ts +55 -0
  680. package/dist/server/loader-registry.d.ts.map +1 -0
  681. package/dist/server/loader-registry.js +132 -0
  682. package/dist/server/loader-registry.js.map +1 -0
  683. package/dist/server/request-context.d.ts +226 -0
  684. package/dist/server/request-context.d.ts.map +1 -0
  685. package/dist/server/request-context.js +290 -0
  686. package/dist/server/request-context.js.map +1 -0
  687. package/dist/server/root-layout.d.ts +4 -0
  688. package/dist/server/root-layout.d.ts.map +1 -0
  689. package/dist/server/root-layout.js +5 -0
  690. package/dist/server/root-layout.js.map +1 -0
  691. package/dist/server.d.ts +15 -0
  692. package/dist/server.d.ts.map +1 -0
  693. package/dist/server.js +20 -0
  694. package/dist/server.js.map +1 -0
  695. package/dist/ssr/__tests__/ssr-handler.test.d.ts +2 -0
  696. package/dist/ssr/__tests__/ssr-handler.test.d.ts.map +1 -0
  697. package/dist/ssr/__tests__/ssr-handler.test.js +132 -0
  698. package/dist/ssr/__tests__/ssr-handler.test.js.map +1 -0
  699. package/dist/ssr/index.d.ts +98 -0
  700. package/dist/ssr/index.d.ts.map +1 -0
  701. package/dist/ssr/index.js +158 -0
  702. package/dist/ssr/index.js.map +1 -0
  703. package/dist/static-handler.d.ts +50 -0
  704. package/dist/static-handler.d.ts.map +1 -0
  705. package/dist/static-handler.gen.d.ts +5 -0
  706. package/dist/static-handler.gen.d.ts.map +1 -0
  707. package/dist/static-handler.gen.js +5 -0
  708. package/dist/static-handler.gen.js.map +1 -0
  709. package/dist/static-handler.js +29 -0
  710. package/dist/static-handler.js.map +1 -0
  711. package/dist/testing/vitest.js +82 -0
  712. package/dist/theme/ThemeProvider.d.ts +20 -0
  713. package/dist/theme/ThemeProvider.d.ts.map +1 -0
  714. package/dist/theme/ThemeProvider.js +240 -0
  715. package/dist/theme/ThemeProvider.js.map +1 -0
  716. package/dist/theme/ThemeScript.d.ts +48 -0
  717. package/dist/theme/ThemeScript.d.ts.map +1 -0
  718. package/dist/theme/ThemeScript.js +13 -0
  719. package/dist/theme/ThemeScript.js.map +1 -0
  720. package/dist/theme/__tests__/theme.test.d.ts +2 -0
  721. package/dist/theme/__tests__/theme.test.d.ts.map +1 -0
  722. package/dist/theme/__tests__/theme.test.js +103 -0
  723. package/dist/theme/__tests__/theme.test.js.map +1 -0
  724. package/dist/theme/constants.d.ts +29 -0
  725. package/dist/theme/constants.d.ts.map +1 -0
  726. package/dist/theme/constants.js +48 -0
  727. package/dist/theme/constants.js.map +1 -0
  728. package/dist/theme/index.d.ts +31 -0
  729. package/dist/theme/index.d.ts.map +1 -0
  730. package/dist/theme/index.js +36 -0
  731. package/dist/theme/index.js.map +1 -0
  732. package/dist/theme/theme-context.d.ts +40 -0
  733. package/dist/theme/theme-context.d.ts.map +1 -0
  734. package/dist/theme/theme-context.js +60 -0
  735. package/dist/theme/theme-context.js.map +1 -0
  736. package/dist/theme/theme-script.d.ts +27 -0
  737. package/dist/theme/theme-script.d.ts.map +1 -0
  738. package/dist/theme/theme-script.js +147 -0
  739. package/dist/theme/theme-script.js.map +1 -0
  740. package/dist/theme/types.d.ts +163 -0
  741. package/dist/theme/types.d.ts.map +1 -0
  742. package/dist/theme/types.js +11 -0
  743. package/dist/theme/types.js.map +1 -0
  744. package/dist/theme/use-theme.d.ts +12 -0
  745. package/dist/theme/use-theme.d.ts.map +1 -0
  746. package/dist/theme/use-theme.js +40 -0
  747. package/dist/theme/use-theme.js.map +1 -0
  748. package/dist/types.d.ts +1479 -0
  749. package/dist/types.d.ts.map +1 -0
  750. package/dist/types.js +10 -0
  751. package/dist/types.js.map +1 -0
  752. package/dist/urls.d.ts +441 -0
  753. package/dist/urls.d.ts.map +1 -0
  754. package/dist/urls.gen.d.ts +8 -0
  755. package/dist/urls.gen.d.ts.map +1 -0
  756. package/dist/urls.gen.js +8 -0
  757. package/dist/urls.gen.js.map +1 -0
  758. package/dist/urls.js +443 -0
  759. package/dist/urls.js.map +1 -0
  760. package/dist/use-loader.d.ts +127 -0
  761. package/dist/use-loader.d.ts.map +1 -0
  762. package/dist/use-loader.js +237 -0
  763. package/dist/use-loader.js.map +1 -0
  764. package/dist/vite/__tests__/ast-handler-extract.test.d.ts +2 -0
  765. package/dist/vite/__tests__/ast-handler-extract.test.d.ts.map +1 -0
  766. package/dist/vite/__tests__/ast-handler-extract.test.js +294 -0
  767. package/dist/vite/__tests__/ast-handler-extract.test.js.map +1 -0
  768. package/dist/vite/__tests__/expose-id-utils.test.d.ts +2 -0
  769. package/dist/vite/__tests__/expose-id-utils.test.d.ts.map +1 -0
  770. package/dist/vite/__tests__/expose-id-utils.test.js +224 -0
  771. package/dist/vite/__tests__/expose-id-utils.test.js.map +1 -0
  772. package/dist/vite/__tests__/expose-internal-ids.test.d.ts +2 -0
  773. package/dist/vite/__tests__/expose-internal-ids.test.d.ts.map +1 -0
  774. package/dist/vite/__tests__/expose-internal-ids.test.js +647 -0
  775. package/dist/vite/__tests__/expose-internal-ids.test.js.map +1 -0
  776. package/dist/vite/__tests__/expose-router-id.test.d.ts +2 -0
  777. package/dist/vite/__tests__/expose-router-id.test.d.ts.map +1 -0
  778. package/dist/vite/__tests__/expose-router-id.test.js +39 -0
  779. package/dist/vite/__tests__/expose-router-id.test.js.map +1 -0
  780. package/dist/vite/ast-handler-extract.d.ts +49 -0
  781. package/dist/vite/ast-handler-extract.d.ts.map +1 -0
  782. package/dist/vite/ast-handler-extract.js +249 -0
  783. package/dist/vite/ast-handler-extract.js.map +1 -0
  784. package/dist/vite/expose-action-id.d.ts +19 -0
  785. package/dist/vite/expose-action-id.d.ts.map +1 -0
  786. package/dist/vite/expose-action-id.js +250 -0
  787. package/dist/vite/expose-action-id.js.map +1 -0
  788. package/dist/vite/expose-id-utils.d.ts +69 -0
  789. package/dist/vite/expose-id-utils.d.ts.map +1 -0
  790. package/dist/vite/expose-id-utils.js +289 -0
  791. package/dist/vite/expose-id-utils.js.map +1 -0
  792. package/dist/vite/expose-internal-ids.d.ts +22 -0
  793. package/dist/vite/expose-internal-ids.d.ts.map +1 -0
  794. package/dist/vite/expose-internal-ids.js +886 -0
  795. package/dist/vite/expose-internal-ids.js.map +1 -0
  796. package/dist/vite/index.d.ts +149 -0
  797. package/dist/vite/index.d.ts.map +1 -0
  798. package/dist/vite/index.js +7554 -2070
  799. package/dist/vite/index.js.bak +5448 -0
  800. package/dist/vite/index.js.map +1 -0
  801. package/dist/vite/package-resolution.d.ts +43 -0
  802. package/dist/vite/package-resolution.d.ts.map +1 -0
  803. package/{src/vite/package-resolution.ts → dist/vite/package-resolution.js} +53 -66
  804. package/dist/vite/package-resolution.js.map +1 -0
  805. package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  806. package/dist/vite/virtual-entries.d.ts +25 -0
  807. package/dist/vite/virtual-entries.d.ts.map +1 -0
  808. package/{src/vite/virtual-entries.ts → dist/vite/virtual-entries.js} +12 -16
  809. package/dist/vite/virtual-entries.js.map +1 -0
  810. package/package.json +142 -61
  811. package/skills/api-client/SKILL.md +211 -0
  812. package/skills/breadcrumbs/SKILL.md +329 -0
  813. package/skills/bundle-analysis/SKILL.md +159 -0
  814. package/skills/cache-guide/SKILL.md +489 -0
  815. package/skills/caching/SKILL.md +413 -26
  816. package/skills/catalog.json +271 -0
  817. package/skills/comparison/SKILL.md +50 -0
  818. package/skills/comparison/agents/openai.yaml +4 -0
  819. package/skills/comparison/references/framework-comparison.md +837 -0
  820. package/skills/composability/SKILL.md +278 -0
  821. package/skills/css/SKILL.md +76 -0
  822. package/skills/debug-manifest/SKILL.md +16 -18
  823. package/skills/defer-hydration/SKILL.md +235 -0
  824. package/skills/document-cache/SKILL.md +96 -63
  825. package/skills/fonts/SKILL.md +7 -5
  826. package/skills/handler-use/SKILL.md +364 -0
  827. package/skills/hooks/SKILL.md +76 -436
  828. package/skills/hooks/data.md +273 -0
  829. package/skills/hooks/handle-and-actions.md +103 -0
  830. package/skills/hooks/navigation.md +110 -0
  831. package/skills/hooks/outlets.md +41 -0
  832. package/skills/hooks/state.md +228 -0
  833. package/skills/hooks/urls.md +135 -0
  834. package/skills/host-router/SKILL.md +320 -0
  835. package/skills/i18n/SKILL.md +276 -0
  836. package/skills/intercept/SKILL.md +215 -16
  837. package/skills/layout/SKILL.md +147 -7
  838. package/skills/links/SKILL.md +304 -25
  839. package/skills/loader/SKILL.md +629 -55
  840. package/skills/middleware/SKILL.md +251 -38
  841. package/skills/migrate-nextjs/SKILL.md +745 -0
  842. package/skills/migrate-react-router/SKILL.md +153 -0
  843. package/skills/migrate-react-router/cloudflare-workers.md +129 -0
  844. package/skills/migrate-react-router/component-migration.md +196 -0
  845. package/skills/migrate-react-router/data-and-actions.md +225 -0
  846. package/skills/migrate-react-router/route-mapping.md +271 -0
  847. package/skills/mime-routes/SKILL.md +60 -21
  848. package/skills/observability/SKILL.md +202 -0
  849. package/skills/parallel/SKILL.md +296 -4
  850. package/skills/ppr/SKILL.md +658 -0
  851. package/skills/prerender/SKILL.md +487 -52
  852. package/skills/rango/SKILL.md +324 -29
  853. package/skills/react-compiler/SKILL.md +168 -0
  854. package/skills/response-routes/SKILL.md +264 -122
  855. package/skills/route/SKILL.md +359 -22
  856. package/skills/router-setup/SKILL.md +247 -34
  857. package/skills/scripts/SKILL.md +179 -0
  858. package/skills/server-actions/SKILL.md +776 -0
  859. package/skills/shell-manifest/SKILL.md +185 -0
  860. package/skills/streams-and-websockets/SKILL.md +283 -0
  861. package/skills/tailwind/SKILL.md +28 -4
  862. package/skills/testing/SKILL.md +126 -222
  863. package/skills/testing/bindings.md +103 -0
  864. package/skills/testing/cache-prerender.md +127 -0
  865. package/skills/testing/client-components.md +124 -0
  866. package/skills/testing/e2e-parity.md +125 -0
  867. package/skills/testing/flight.md +91 -0
  868. package/skills/testing/handles.md +131 -0
  869. package/skills/testing/loader.md +128 -0
  870. package/skills/testing/middleware.md +99 -0
  871. package/skills/testing/render-handler.md +122 -0
  872. package/skills/testing/response-routes.md +95 -0
  873. package/skills/testing/reverse-and-types.md +85 -0
  874. package/skills/testing/server-actions.md +107 -0
  875. package/skills/testing/server-tree.md +128 -0
  876. package/skills/testing/setup.md +123 -0
  877. package/skills/theme/SKILL.md +10 -9
  878. package/skills/typesafety/SKILL.md +45 -496
  879. package/skills/typesafety/env-and-bindings.md +254 -0
  880. package/skills/typesafety/generated-files-and-cli.md +335 -0
  881. package/skills/typesafety/params-and-search.md +153 -0
  882. package/skills/typesafety/route-types.md +209 -0
  883. package/skills/use-cache/SKILL.md +383 -0
  884. package/skills/vercel/SKILL.md +128 -0
  885. package/skills/view-transitions/SKILL.md +337 -0
  886. package/src/__augment-tests__/augment.ts +81 -0
  887. package/src/__augment-tests__/augmented.check.ts +116 -0
  888. package/src/__internal.ts +77 -44
  889. package/src/bin/rango.ts +275 -29
  890. package/src/browser/action-coordinator.ts +114 -0
  891. package/src/browser/action-fence.ts +47 -0
  892. package/src/browser/app-shell.ts +39 -0
  893. package/src/browser/app-version.ts +14 -0
  894. package/src/browser/connection-warmup.ts +134 -0
  895. package/src/browser/cookie-name.ts +140 -0
  896. package/src/browser/event-controller.ts +348 -212
  897. package/src/browser/history-state.ts +101 -0
  898. package/src/browser/index.ts +3 -3
  899. package/src/browser/intercept-utils.ts +52 -0
  900. package/src/browser/invalidate-client-cache.ts +52 -0
  901. package/src/browser/link-interceptor.ts +24 -4
  902. package/src/browser/logging.ts +39 -0
  903. package/src/browser/merge-segment-loaders.ts +23 -13
  904. package/src/browser/navigation-bridge.ts +385 -576
  905. package/src/browser/navigation-client.ts +249 -75
  906. package/src/browser/navigation-store-handle.ts +38 -0
  907. package/src/browser/navigation-store.ts +230 -124
  908. package/src/browser/navigation-transaction.ts +247 -0
  909. package/src/browser/network-error-handler.ts +88 -0
  910. package/src/browser/partial-update.ts +432 -365
  911. package/src/browser/prefetch/cache.ts +381 -0
  912. package/src/browser/prefetch/fetch.ts +462 -0
  913. package/src/browser/prefetch/observer.ts +65 -0
  914. package/src/browser/prefetch/policy.ts +48 -0
  915. package/src/browser/prefetch/queue.ts +209 -0
  916. package/src/browser/prefetch/resource-ready.ts +77 -0
  917. package/src/browser/rango-state.ts +194 -0
  918. package/src/browser/react/Link.tsx +284 -67
  919. package/src/browser/react/NavigationProvider.tsx +267 -109
  920. package/src/browser/react/ScrollRestoration.tsx +10 -6
  921. package/src/browser/react/context.ts +11 -0
  922. package/src/browser/react/filter-segment-order.ts +70 -0
  923. package/src/browser/react/index.ts +0 -48
  924. package/src/browser/react/location-state-shared.ts +272 -60
  925. package/src/browser/react/location-state.ts +90 -20
  926. package/src/browser/react/mount-context.ts +6 -1
  927. package/src/browser/react/nonce-context.ts +23 -0
  928. package/src/browser/react/shallow-equal.ts +27 -0
  929. package/src/browser/react/use-action.ts +35 -66
  930. package/src/browser/react/use-handle.ts +39 -126
  931. package/src/browser/react/use-href.tsx +8 -1
  932. package/src/browser/react/use-link-status.ts +39 -13
  933. package/src/browser/react/use-navigation.ts +53 -69
  934. package/src/browser/react/use-params.ts +75 -0
  935. package/src/browser/react/use-pathname.ts +47 -0
  936. package/src/browser/react/use-reverse.ts +106 -0
  937. package/src/browser/react/use-router.ts +98 -0
  938. package/src/browser/react/use-search-params.ts +51 -0
  939. package/src/browser/react/use-segments.ts +72 -99
  940. package/src/browser/response-adapter.ts +164 -0
  941. package/src/browser/rsc-router.tsx +355 -73
  942. package/src/browser/scroll-restoration.ts +140 -50
  943. package/src/browser/segment-reconciler.ts +253 -0
  944. package/src/browser/segment-structure-assert.ts +17 -1
  945. package/src/browser/server-action-bridge.ts +668 -613
  946. package/src/browser/types.ts +235 -51
  947. package/src/browser/validate-redirect-origin.ts +56 -0
  948. package/src/build/collect-fallback-refs.ts +107 -0
  949. package/src/build/generate-manifest.ts +243 -183
  950. package/src/build/generate-route-types.ts +41 -848
  951. package/src/build/index.ts +12 -7
  952. package/src/build/prefix-tree-utils.ts +123 -0
  953. package/src/build/route-trie.ts +218 -80
  954. package/src/build/route-types/ast-helpers.ts +25 -0
  955. package/src/build/route-types/ast-route-extraction.ts +105 -0
  956. package/src/build/route-types/codegen.ts +113 -0
  957. package/src/build/route-types/include-resolution.ts +812 -0
  958. package/src/build/route-types/param-extraction.ts +51 -0
  959. package/src/build/route-types/per-module-writer.ts +144 -0
  960. package/src/build/route-types/router-processing.ts +695 -0
  961. package/src/build/route-types/scan-filter.ts +85 -0
  962. package/src/build/route-types/source-scan.ts +216 -0
  963. package/src/build/runtime-discovery.ts +223 -0
  964. package/src/cache/background-task.ts +34 -0
  965. package/src/cache/cache-error.ts +104 -0
  966. package/src/cache/cache-key-utils.ts +88 -0
  967. package/src/cache/cache-policy.ts +199 -0
  968. package/src/cache/cache-runtime.ts +695 -0
  969. package/src/cache/cache-scope.ts +324 -335
  970. package/src/cache/cache-tag.ts +149 -0
  971. package/src/cache/cf/cf-base64.ts +33 -0
  972. package/src/cache/cf/cf-cache-constants.ts +127 -0
  973. package/src/cache/cf/cf-cache-store.ts +2602 -156
  974. package/src/cache/cf/cf-cache-types.ts +349 -0
  975. package/src/cache/cf/cf-kv-utils.ts +46 -0
  976. package/src/cache/cf/cf-tag-marker-memo.ts +105 -0
  977. package/src/cache/cf/index.ts +17 -17
  978. package/src/cache/document-cache.ts +226 -102
  979. package/src/cache/handle-capture.ts +81 -0
  980. package/src/cache/handle-snapshot.ts +132 -0
  981. package/src/cache/index.ts +24 -35
  982. package/src/cache/memory-segment-store.ts +446 -30
  983. package/src/cache/profile-registry.ts +88 -0
  984. package/src/cache/read-through-swr.ts +178 -0
  985. package/src/cache/segment-codec.ts +295 -0
  986. package/src/cache/shell-snapshot.ts +464 -0
  987. package/src/cache/tag-invalidation.ts +230 -0
  988. package/src/cache/taint.ts +153 -0
  989. package/src/cache/types.ts +283 -211
  990. package/src/cache/vercel/index.ts +11 -0
  991. package/src/cache/vercel/vercel-cache-store.ts +1201 -0
  992. package/src/client.rsc.tsx +43 -21
  993. package/src/client.tsx +131 -347
  994. package/src/cloudflare/index.ts +11 -0
  995. package/src/cloudflare/tracing.ts +108 -0
  996. package/src/component-utils.ts +23 -4
  997. package/src/components/DefaultDocument.tsx +13 -3
  998. package/src/context-var.ts +168 -0
  999. package/src/debug.ts +19 -9
  1000. package/src/decode-loader-results.ts +52 -0
  1001. package/src/defer.ts +185 -0
  1002. package/src/deps/ssr.ts +4 -2
  1003. package/src/encode-kv.ts +49 -0
  1004. package/src/errors.ts +106 -10
  1005. package/src/escape-script.ts +52 -0
  1006. package/src/handle.ts +110 -35
  1007. package/src/handles/MetaTags.tsx +83 -59
  1008. package/src/handles/Scripts.tsx +183 -0
  1009. package/src/handles/breadcrumbs.ts +93 -0
  1010. package/src/handles/deferred-resolution.ts +127 -0
  1011. package/src/handles/is-thenable.ts +18 -0
  1012. package/src/handles/meta.ts +44 -53
  1013. package/src/handles/script.ts +244 -0
  1014. package/src/host/cookie-handler.ts +20 -65
  1015. package/src/host/errors.ts +21 -30
  1016. package/src/host/index.ts +13 -9
  1017. package/src/host/pattern-matcher.ts +50 -79
  1018. package/src/host/router.ts +151 -121
  1019. package/src/host/testing.ts +45 -32
  1020. package/src/host/types.ts +52 -11
  1021. package/src/host/utils.ts +2 -2
  1022. package/src/href-client.ts +192 -57
  1023. package/src/index.rsc.ts +180 -35
  1024. package/src/index.ts +245 -73
  1025. package/src/internal-debug.ts +9 -2
  1026. package/src/loader-store.ts +500 -0
  1027. package/src/loader.rsc.ts +31 -99
  1028. package/src/loader.ts +30 -12
  1029. package/src/missing-id-error.ts +68 -0
  1030. package/src/outlet-context.ts +1 -1
  1031. package/src/outlet-provider.tsx +41 -0
  1032. package/src/prerender/build-shell-capture.ts +447 -0
  1033. package/src/prerender/param-hash.ts +16 -14
  1034. package/src/prerender/shell-manifest-key.ts +20 -0
  1035. package/src/prerender/store.ts +131 -22
  1036. package/src/prerender.ts +460 -26
  1037. package/src/redirect-origin.ts +114 -0
  1038. package/src/regex-escape.ts +8 -0
  1039. package/src/render-error-thrower.tsx +20 -0
  1040. package/src/response-utils.ts +62 -0
  1041. package/src/reverse.ts +198 -128
  1042. package/src/root-error-boundary.tsx +42 -48
  1043. package/src/route-content-wrapper.tsx +22 -77
  1044. package/src/route-definition/dsl-helpers.ts +1116 -0
  1045. package/src/route-definition/helper-factories.ts +88 -0
  1046. package/src/route-definition/helpers-types.ts +506 -0
  1047. package/src/route-definition/index.ts +54 -0
  1048. package/src/route-definition/redirect.ts +134 -0
  1049. package/src/route-definition/resolve-handler-use.ts +160 -0
  1050. package/src/route-definition/use-item-types.ts +29 -0
  1051. package/src/route-definition.ts +1 -1481
  1052. package/src/route-map-builder.ts +120 -145
  1053. package/src/route-name.ts +53 -0
  1054. package/src/route-types.ts +71 -45
  1055. package/src/router/basename.ts +14 -0
  1056. package/src/router/content-negotiation.ts +305 -0
  1057. package/src/router/debug-manifest.ts +72 -0
  1058. package/src/router/error-handling.ts +54 -27
  1059. package/src/router/find-match.ts +259 -0
  1060. package/src/router/handler-context.ts +385 -125
  1061. package/src/router/instrument.ts +355 -0
  1062. package/src/router/intercept-resolution.ts +88 -28
  1063. package/src/router/lazy-includes.ts +260 -0
  1064. package/src/router/loader-resolution.ts +449 -157
  1065. package/src/router/logging.ts +106 -6
  1066. package/src/router/manifest.ts +144 -62
  1067. package/src/router/match-api.ts +224 -256
  1068. package/src/router/match-context.ts +4 -24
  1069. package/src/router/match-handlers.ts +499 -0
  1070. package/src/router/match-middleware/background-revalidation.ts +117 -93
  1071. package/src/router/match-middleware/cache-lookup.ts +308 -150
  1072. package/src/router/match-middleware/cache-store.ts +123 -51
  1073. package/src/router/match-middleware/intercept-resolution.ts +44 -43
  1074. package/src/router/match-middleware/segment-resolution.ts +64 -22
  1075. package/src/router/match-pipelines.ts +11 -87
  1076. package/src/router/match-result.ts +143 -52
  1077. package/src/router/metrics.ts +235 -29
  1078. package/src/router/middleware-types.ts +110 -0
  1079. package/src/router/middleware.ts +526 -441
  1080. package/src/router/navigation-snapshot.ts +133 -0
  1081. package/src/router/params-util.ts +23 -0
  1082. package/src/router/parse-pattern.ts +115 -0
  1083. package/src/router/pattern-matching.ts +311 -142
  1084. package/src/router/prefetch-cache-ttl.ts +51 -0
  1085. package/src/router/prefetch-limits.ts +37 -0
  1086. package/src/router/prerender-match.ts +575 -0
  1087. package/src/router/preview-match.ts +102 -0
  1088. package/src/router/request-classification.ts +291 -0
  1089. package/src/router/revalidation.ts +203 -62
  1090. package/src/router/route-snapshot.ts +256 -0
  1091. package/src/router/router-context.ts +45 -48
  1092. package/src/router/router-interfaces.ts +564 -0
  1093. package/src/router/router-options.ts +784 -0
  1094. package/src/router/router-registry.ts +21 -0
  1095. package/src/router/segment-resolution/fresh.ts +812 -0
  1096. package/src/router/segment-resolution/helpers.ts +348 -0
  1097. package/src/router/segment-resolution/loader-cache.ts +315 -0
  1098. package/src/router/segment-resolution/loader-mask.ts +60 -0
  1099. package/src/router/segment-resolution/loader-snapshot.ts +259 -0
  1100. package/src/router/segment-resolution/mask-nested.ts +99 -0
  1101. package/src/router/segment-resolution/revalidation.ts +1340 -0
  1102. package/src/router/segment-resolution/static-store.ts +81 -0
  1103. package/src/router/segment-resolution/streamed-handler-telemetry.ts +52 -0
  1104. package/src/router/segment-resolution/view-transition-default.ts +56 -0
  1105. package/src/router/segment-resolution.ts +25 -1354
  1106. package/src/router/segment-wrappers.ts +292 -0
  1107. package/src/router/state-cookie-name.ts +33 -0
  1108. package/src/router/substitute-pattern-params.ts +75 -0
  1109. package/src/router/telemetry-otel.ts +259 -0
  1110. package/src/router/telemetry.ts +385 -0
  1111. package/src/router/timeout.ts +128 -0
  1112. package/src/router/tracing.ts +215 -0
  1113. package/src/router/trie-matching.ts +240 -61
  1114. package/src/router/types.ts +23 -70
  1115. package/src/router/url-params.ts +57 -0
  1116. package/src/router.ts +795 -2390
  1117. package/src/rsc/capture-queue.ts +67 -0
  1118. package/src/rsc/full-payload.ts +70 -0
  1119. package/src/rsc/handler-context.ts +46 -0
  1120. package/src/rsc/handler.ts +956 -1164
  1121. package/src/rsc/helpers.ts +736 -19
  1122. package/src/rsc/index.ts +2 -25
  1123. package/src/rsc/json-route-result.ts +38 -0
  1124. package/src/rsc/loader-fetch.ts +305 -0
  1125. package/src/rsc/manifest-init.ts +77 -0
  1126. package/src/rsc/nonce.ts +23 -0
  1127. package/src/rsc/origin-guard.ts +155 -0
  1128. package/src/rsc/progressive-enhancement.ts +541 -0
  1129. package/src/rsc/redirect-guard.ts +100 -0
  1130. package/src/rsc/response-cache-serve.ts +238 -0
  1131. package/src/rsc/response-error.ts +104 -0
  1132. package/src/rsc/response-route-handler.ts +257 -0
  1133. package/src/rsc/rsc-rendering.ts +856 -0
  1134. package/src/rsc/runtime-warnings.ts +55 -0
  1135. package/src/rsc/server-action.ts +525 -0
  1136. package/src/rsc/shell-build-manifest.ts +316 -0
  1137. package/src/rsc/shell-capture-constants.ts +27 -0
  1138. package/src/rsc/shell-capture.ts +1716 -0
  1139. package/src/rsc/shell-serve.ts +226 -0
  1140. package/src/rsc/ssr-setup.ts +176 -0
  1141. package/src/rsc/transition-gate.ts +89 -0
  1142. package/src/rsc/types.ts +95 -12
  1143. package/src/runtime-env.ts +18 -0
  1144. package/src/search-params.ts +99 -82
  1145. package/src/segment-content-promise.ts +67 -0
  1146. package/src/segment-fragments.ts +124 -0
  1147. package/src/segment-loader-promise.ts +167 -0
  1148. package/src/segment-system.tsx +464 -135
  1149. package/src/serialize.ts +243 -0
  1150. package/src/server/context.ts +640 -85
  1151. package/src/server/cookie-parse.ts +32 -0
  1152. package/src/server/cookie-store.ts +337 -0
  1153. package/src/server/fetchable-loader-store.ts +11 -6
  1154. package/src/server/handle-store.ts +123 -42
  1155. package/src/server/loader-registry.ts +51 -100
  1156. package/src/server/request-context.ts +1069 -152
  1157. package/src/server.ts +15 -8
  1158. package/src/ssr/index.tsx +661 -140
  1159. package/src/ssr/inject-rsc-eager.ts +167 -0
  1160. package/src/ssr/preinit-client-references.ts +106 -0
  1161. package/src/ssr/ssr-root.tsx +261 -0
  1162. package/src/static-handler.ts +45 -18
  1163. package/src/testing/cache-status.ts +162 -0
  1164. package/src/testing/collect-handle.ts +46 -0
  1165. package/src/testing/dispatch.ts +813 -0
  1166. package/src/testing/dom.entry.ts +22 -0
  1167. package/src/testing/e2e/fixture.ts +188 -0
  1168. package/src/testing/e2e/index.ts +128 -0
  1169. package/src/testing/e2e/matchers.ts +35 -0
  1170. package/src/testing/e2e/page-helpers.ts +272 -0
  1171. package/src/testing/e2e/parity.ts +387 -0
  1172. package/src/testing/e2e/server.ts +195 -0
  1173. package/src/testing/flight-matchers.ts +97 -0
  1174. package/src/testing/flight-normalize.ts +11 -0
  1175. package/src/testing/flight-runtime.d.ts +57 -0
  1176. package/src/testing/flight-tree.ts +682 -0
  1177. package/src/testing/flight.entry.ts +52 -0
  1178. package/src/testing/flight.ts +257 -0
  1179. package/src/testing/generated-routes.ts +199 -0
  1180. package/src/testing/index.ts +105 -0
  1181. package/src/testing/internal/context.ts +380 -0
  1182. package/src/testing/internal/flight-client-globals.ts +30 -0
  1183. package/src/testing/internal/seed-vars.ts +54 -0
  1184. package/src/testing/render-handler.ts +371 -0
  1185. package/src/testing/render-route.tsx +584 -0
  1186. package/src/testing/run-loader.ts +385 -0
  1187. package/src/testing/run-middleware.ts +219 -0
  1188. package/src/testing/run-transition-when.ts +164 -0
  1189. package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
  1190. package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
  1191. package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
  1192. package/src/testing/vitest-stubs/version.ts +5 -0
  1193. package/src/testing/vitest.ts +305 -0
  1194. package/src/theme/ThemeProvider.tsx +76 -98
  1195. package/src/theme/ThemeScript.tsx +12 -14
  1196. package/src/theme/constants.ts +57 -15
  1197. package/src/theme/index.ts +3 -20
  1198. package/src/theme/theme-context.ts +5 -35
  1199. package/src/theme/theme-script.ts +43 -39
  1200. package/src/theme/use-theme.ts +0 -3
  1201. package/src/types/boundaries.ts +123 -0
  1202. package/src/types/cache-types.ts +207 -0
  1203. package/src/types/error-types.ts +132 -0
  1204. package/src/types/global-namespace.ts +113 -0
  1205. package/src/types/handler-context.ts +850 -0
  1206. package/src/types/index.ts +81 -0
  1207. package/src/types/loader-types.ts +212 -0
  1208. package/src/types/request-scope.ts +112 -0
  1209. package/src/types/route-config.ts +138 -0
  1210. package/src/types/route-entry.ts +114 -0
  1211. package/src/types/segments.ts +271 -0
  1212. package/src/types.ts +1 -1795
  1213. package/src/urls/include-helper.ts +162 -0
  1214. package/src/urls/include-provider.ts +71 -0
  1215. package/src/urls/index.ts +44 -0
  1216. package/src/urls/path-helper-types.ts +418 -0
  1217. package/src/urls/path-helper.ts +280 -0
  1218. package/src/urls/pattern-types.ts +189 -0
  1219. package/src/urls/response-types.ts +109 -0
  1220. package/src/urls/type-extraction.ts +316 -0
  1221. package/src/urls/urls-function.ts +80 -0
  1222. package/src/urls.ts +1 -1352
  1223. package/src/use-loader.tsx +406 -141
  1224. package/src/vercel/index.ts +11 -0
  1225. package/src/vercel/tracing.ts +88 -0
  1226. package/src/vite/debug.ts +185 -0
  1227. package/src/vite/discovery/bundle-postprocess.ts +182 -0
  1228. package/src/vite/discovery/dev-prerender-cache.ts +117 -0
  1229. package/src/vite/discovery/discover-routers.ts +408 -0
  1230. package/src/vite/discovery/discovery-errors.ts +255 -0
  1231. package/src/vite/discovery/gate-state.ts +171 -0
  1232. package/src/vite/discovery/prerender-collection.ts +483 -0
  1233. package/src/vite/discovery/route-types-writer.ts +214 -0
  1234. package/src/vite/discovery/self-gen-tracking.ts +73 -0
  1235. package/src/vite/discovery/shell-prerender-phase.ts +397 -0
  1236. package/src/vite/discovery/state.ts +205 -0
  1237. package/src/vite/discovery/virtual-module-codegen.ts +293 -0
  1238. package/src/vite/index.ts +31 -2255
  1239. package/src/vite/inject-client-debug.ts +88 -0
  1240. package/src/vite/plugin-types.ts +336 -0
  1241. package/src/vite/plugins/cjs-to-esm.ts +90 -0
  1242. package/src/vite/plugins/client-ref-dedup.ts +120 -0
  1243. package/src/vite/plugins/client-ref-hashing.ts +118 -0
  1244. package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
  1245. package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  1246. package/src/vite/plugins/cloudflare-protocol-stub.ts +194 -0
  1247. package/src/vite/{expose-action-id.ts → plugins/expose-action-id.ts} +88 -110
  1248. package/src/vite/{expose-id-utils.ts → plugins/expose-id-utils.ts} +89 -79
  1249. package/src/vite/plugins/expose-ids/export-analysis.ts +363 -0
  1250. package/src/vite/plugins/expose-ids/handler-transform.ts +130 -0
  1251. package/src/vite/plugins/expose-ids/loader-transform.ts +64 -0
  1252. package/src/vite/plugins/expose-ids/router-transform.ts +199 -0
  1253. package/src/vite/plugins/expose-ids/types.ts +45 -0
  1254. package/src/vite/plugins/expose-internal-ids.ts +805 -0
  1255. package/src/vite/plugins/performance-tracks.ts +89 -0
  1256. package/src/vite/plugins/refresh-cmd.ts +127 -0
  1257. package/src/vite/plugins/use-cache-transform.ts +313 -0
  1258. package/src/vite/plugins/vercel-output.ts +384 -0
  1259. package/src/vite/plugins/version-injector.ts +94 -0
  1260. package/src/vite/plugins/version-plugin.ts +271 -0
  1261. package/src/vite/plugins/virtual-entries.ts +267 -0
  1262. package/src/vite/plugins/virtual-stub-plugin.ts +29 -0
  1263. package/src/vite/rango.ts +600 -0
  1264. package/src/vite/router-discovery.ts +2120 -0
  1265. package/src/vite/{ast-handler-extract.ts → utils/ast-handler-extract.ts} +200 -37
  1266. package/src/vite/utils/banner.ts +36 -0
  1267. package/src/vite/utils/bundle-analysis.ts +132 -0
  1268. package/src/vite/utils/client-chunks.ts +184 -0
  1269. package/src/vite/utils/directive-prologue.ts +40 -0
  1270. package/src/vite/utils/forward-user-plugins.ts +171 -0
  1271. package/src/vite/utils/manifest-utils.ts +15 -0
  1272. package/src/vite/utils/package-resolution.ts +89 -0
  1273. package/src/vite/utils/prerender-utils.ts +268 -0
  1274. package/src/vite/utils/shared-utils.ts +271 -0
  1275. package/CLAUDE.md +0 -43
  1276. package/src/browser/lru-cache.ts +0 -69
  1277. package/src/browser/request-controller.ts +0 -164
  1278. package/src/browser/shallow.ts +0 -35
  1279. package/src/cache/memory-store.ts +0 -253
  1280. package/src/router.gen.ts +0 -6
  1281. package/src/static-handler.gen.ts +0 -5
  1282. package/src/urls.gen.ts +0 -8
  1283. package/src/vite/expose-internal-ids.ts +0 -1167
  1284. /package/src/vite/{version.d.ts → plugins/version.d.ts} +0 -0
@@ -11,16 +11,68 @@
11
11
  */
12
12
 
13
13
  import { AsyncLocalStorage } from "node:async_hooks";
14
+ import { parseCookiesFromHeader } from "./cookie-parse.js";
15
+ import type { CacheErrorCategory } from "../cache/cache-error.js";
14
16
  import type { CookieOptions } from "../router/middleware.js";
17
+ import {
18
+ KEEP_CACHE_HEADER,
19
+ getRawCookieValue,
20
+ mintStateValue,
21
+ serializeStateCookie,
22
+ } from "../browser/cookie-name.js";
15
23
  import type { LoaderDefinition, LoaderContext } from "../types.js";
24
+ import type { ScopedReverseFunction } from "../reverse.js";
25
+ import type {
26
+ DefaultEnv,
27
+ DefaultReverseRouteMap,
28
+ DefaultRouteName,
29
+ } from "../types/global-namespace.js";
16
30
  import type { Handle } from "../handle.js";
17
- import { createHandleStore, type HandleStore } from "./handle-store.js";
31
+ import {
32
+ type ContextVar,
33
+ contextGet,
34
+ contextSet,
35
+ isNonCacheable,
36
+ } from "../context-var.js";
37
+ import {
38
+ createHandleStore,
39
+ buildHandleSnapshot,
40
+ type HandleStore,
41
+ type HandleData,
42
+ } from "./handle-store.js";
18
43
  import { isHandle } from "../handle.js";
19
- import { track } from "./context.js";
44
+ import { withDefer } from "../defer.js";
45
+ import { type MetricsStore } from "./context.js";
46
+ import { observePhase, PHASES } from "../router/instrument.js";
20
47
  import { getFetchableLoader } from "./fetchable-loader-store.js";
21
48
  import type { SegmentCacheStore } from "../cache/types.js";
22
49
  import type { Theme, ResolvedThemeConfig } from "../theme/types.js";
23
- import { THEME_COOKIE } from "../theme/constants.js";
50
+ import type { ExecutionContext, RequestScope } from "../types/request-scope.js";
51
+ import type { TransitionWhenFn } from "../types/segments.js";
52
+ import type { ResolvedTracing } from "../router/tracing.js";
53
+ import {
54
+ THEME_COOKIE,
55
+ isValidTheme,
56
+ warnInvalidTheme,
57
+ } from "../theme/constants.js";
58
+ import type { LocationStateEntry } from "../browser/react/location-state-shared.js";
59
+ import { NOCACHE_SYMBOL, assertNotInsideCacheExec } from "../cache/taint.js";
60
+ import {
61
+ assertCachedHeaderWriteAllowed,
62
+ isInsideCacheScope,
63
+ } from "./context.js";
64
+ import {
65
+ createReverseFunction,
66
+ stripInternalParams,
67
+ } from "../router/handler-context.js";
68
+ import {
69
+ getGlobalRouteMap,
70
+ isRouteRootScoped,
71
+ getSearchSchema,
72
+ } from "../route-map-builder.js";
73
+ import { parseSearchParams } from "../search-params.js";
74
+ import { invariant } from "../errors.js";
75
+ import { isAutoGeneratedRouteName } from "../route-name.js";
24
76
 
25
77
  /**
26
78
  * Unified request context available via getRequestContext()
@@ -29,46 +81,75 @@ import { THEME_COOKIE } from "../theme/constants.js";
29
81
  * Use this when you need access to request data outside of route handlers.
30
82
  */
31
83
  export interface RequestContext<
32
- TEnv = unknown,
84
+ TEnv = DefaultEnv,
33
85
  TParams = Record<string, string>,
34
- > {
35
- /** Platform bindings (Cloudflare env, etc.) */
36
- env: TEnv;
37
- /** Original HTTP request */
38
- request: Request;
39
- /** Parsed URL (system params like _rsc* are NOT filtered here) */
40
- url: URL;
41
- /** URL pathname */
42
- pathname: string;
43
- /** URL search params (system params like _rsc* are NOT filtered here) */
44
- searchParams: URLSearchParams;
45
- /** Variables set by middleware (same as ctx.var) */
46
- var: Record<string, any>;
86
+ > extends RequestScope<TEnv> {
87
+ /** @internal Shared variable backing store for ctx.get()/ctx.set(). */
88
+ _variables: Record<string, any>;
47
89
  /** Get a variable set by middleware */
48
- get: <K extends string>(key: K) => any;
90
+ get: {
91
+ <T>(contextVar: ContextVar<T>): T | undefined;
92
+ <K extends string>(key: K): any;
93
+ };
49
94
  /** Set a variable (shared with middleware and handlers) */
50
- set: <K extends string>(key: K, value: any) => void;
95
+ set: {
96
+ <T>(
97
+ contextVar: ContextVar<T>,
98
+ value: T,
99
+ options?: { cache?: boolean },
100
+ ): void;
101
+ <K extends string>(key: K, value: any, options?: { cache?: boolean }): void;
102
+ };
51
103
  /**
52
104
  * Route params (populated after route matching)
53
105
  * Initially empty, then set to matched params
54
106
  */
55
107
  params: TParams;
108
+ /** @internal Stub response for collecting headers/cookies. Use ctx.headers or ctx.header() instead. */
109
+ readonly res: Response;
110
+
111
+ /**
112
+ * True for build-time render/capture requests. Live requests use false.
113
+ * Build-time shell capture sets this while replaying middleware so apps can
114
+ * skip side-effectful runtime work.
115
+ */
116
+ readonly build: boolean;
117
+
56
118
  /**
57
- * Stub response for setting headers/cookies
58
- * Headers set here are merged into the final response
119
+ * Opt this request out of PPR shell serving/capture.
120
+ * Runtime middleware can call this before the PPR commit point; handlers can
121
+ * call it on a MISS to prevent the follow-up capture.
122
+ *
123
+ * Scope: the PPR SHELL axis only. It does NOT disable prerender B-segment
124
+ * (Prerender/Static) serving, and it is inert in the prerender-collect /
125
+ * static-render contexts (no live shell decision to influence there).
59
126
  */
60
- res: Response;
127
+ dynamic(): void;
128
+
129
+ /** @internal Request-local PPR opt-out marker set by ctx.dynamic(). */
130
+ _dynamic?: boolean;
61
131
 
62
- /** Get a cookie value from the request */
132
+ /** @internal Get a cookie value (effective: request + response mutations). Use cookies().get() instead. */
63
133
  cookie(name: string): string | undefined;
64
- /** Get all cookies from the request */
134
+ /** @internal Get all cookies (effective merged view). Use cookies().getAll() instead. */
65
135
  cookies(): Record<string, string>;
66
- /** Set a cookie on the response */
136
+ /** @internal Set a cookie on the response. Use cookies().set() instead. */
67
137
  setCookie(name: string, value: string, options?: CookieOptions): void;
68
- /** Delete a cookie */
69
- deleteCookie(name: string, options?: Pick<CookieOptions, "domain" | "path">): void;
138
+ /** @internal Delete a cookie. Use cookies().delete() instead. */
139
+ deleteCookie(
140
+ name: string,
141
+ options?: Pick<CookieOptions, "domain" | "path">,
142
+ ): void;
70
143
  /** Set a response header */
71
144
  header(name: string, value: string): void;
145
+ /** Set the response status code */
146
+ setStatus(status: number): void;
147
+ /** @internal Set status bypassing cache-exec guard (for framework error handling) */
148
+ _setStatus(status: number): void;
149
+ /** @internal Rotate the rango state cookie (server seat of invalidateClientCache). */
150
+ _rotateStateCookie(): void;
151
+ /** @internal Set the keepClientCache() directive header on the response. */
152
+ _setKeepCacheDirective(): void;
72
153
 
73
154
  /**
74
155
  * Access loader data or push handle data.
@@ -90,10 +171,12 @@ export interface RequestContext<
90
171
  * ```
91
172
  */
92
173
  use: {
93
- <T, TLoaderParams = any>(loader: LoaderDefinition<T, TLoaderParams>): Promise<T>;
94
- <TData, TAccumulated = TData[]>(handle: Handle<TData, TAccumulated>): (
95
- data: TData | Promise<TData> | (() => Promise<TData>)
96
- ) => void;
174
+ <T, TLoaderParams = any>(
175
+ loader: LoaderDefinition<T, TLoaderParams>,
176
+ ): Promise<T>;
177
+ <TData, TAccumulated = TData[]>(
178
+ handle: Handle<TData, TAccumulated>,
179
+ ): (data: TData | Promise<TData> | (() => Promise<TData>)) => void;
97
180
  };
98
181
 
99
182
  /** HTTP method (GET, POST, PUT, PATCH, DELETE, etc.) */
@@ -102,22 +185,159 @@ export interface RequestContext<
102
185
  /** @internal Handle store for tracking handle data across segments */
103
186
  _handleStore: HandleStore;
104
187
 
188
+ /**
189
+ * @internal transition({ when }) predicates for segments matched this request,
190
+ * keyed by segment id. Collected during resolution (the function is stripped
191
+ * from the serialized segment config), then evaluated post-handler in
192
+ * rsc-rendering — outside any cache scope — to drop the transition of any
193
+ * segment whose predicate returns false.
194
+ */
195
+ _transitionWhen?: Array<{ id: string; when: TransitionWhenFn }>;
196
+
105
197
  /** @internal Cache store for segment caching (optional, used by CacheScope) */
106
198
  _cacheStore?: SegmentCacheStore;
107
199
 
108
200
  /**
109
- * Schedule work to run after the response is sent.
110
- * On Cloudflare Workers, uses ctx.waitUntil().
111
- * On Node.js, runs as fire-and-forget.
112
- *
113
- * @example
114
- * ```typescript
115
- * ctx.waitUntil(async () => {
116
- * await cacheStore.set(key, data, ttl);
117
- * });
118
- * ```
201
+ * @internal PPR shell-capture ACTIVE marker. True ONLY inside the background
202
+ * capture task's derived request context (built by shell-capture.ts). This is
203
+ * the switch every capture-specific behavior reads: loader masking
204
+ * (loader-mask.ts isShellCaptureActive / fresh.ts emitStreaming) and the
205
+ * cookies()/headers() capture guard (cookie-store.ts
206
+ * assertNotInsideShellCapture). The foreground render never sets it, so the
207
+ * served response is byte-identical to axis 1. The capture descriptor itself
208
+ * (key/ttl/swr/tags/store) is NOT threaded through the request context — the
209
+ * integrated PPR serve path (rsc/shell-serve.ts + rsc-rendering.ts) builds it
210
+ * locally and passes it to scheduleShellCapture directly.
211
+ */
212
+ _shellCaptureRun?: boolean;
213
+
214
+ /**
215
+ * @internal Bake-lane loader containers collected DURING a shell capture:
216
+ * segment-key -> the loader's (pre-wrap) result promise. Populated by
217
+ * resolveLoaderData for loaders on entries with no renderable loading() (the
218
+ * bake lane — they execute at capture instead of being masked; see
219
+ * docs/design/loader-container-bake.md). Drained by captureAndStoreShell
220
+ * after the shell quiesces: settled containers are promise-elided,
221
+ * Flight-serialized, and pinned into the snapshot's loader family; a
222
+ * REJECTED container refuses the capture (error UI must never bake into the
223
+ * shared shell). Own property of the capture's derived context only.
224
+ */
225
+ _shellCaptureLoaderRecords?: Map<string, Promise<unknown>>;
226
+
227
+ /**
228
+ * @internal Loader-family snapshot seed for a shell HIT's tail render:
229
+ * segment-key -> the capture's elided container (already Flight-deserialized
230
+ * by serveShellHit). resolveLoaderData overlays it onto the fresh run's
231
+ * container (recorded paths pinned, hole-marker paths keep the fresh nested
232
+ * promises) so the payload's baked bytes match the frozen prelude. Own
233
+ * property of the HIT tail's derived context only.
234
+ */
235
+ _shellLoaderSeed?: Map<string, unknown>;
236
+
237
+ /**
238
+ * @internal Shell fast-path marker: makes the NEXT full match treat the whole
239
+ * matched route as an implicit doc-level cache() boundary (see
240
+ * resolveShellImplicitCacheScope in cache/cache-scope.ts). Set ONLY on
241
+ * (a) the capture's derived context — with a record-only store so the
242
+ * capture's cacheRoute write lands in the snapshot, never the real store —
243
+ * and (b) a HIT tail's seeded context when the entry is eligible
244
+ * (!handlerLiveHoles), where the SeededShellStore serves the recorded doc
245
+ * entry and the match skips handler execution entirely. Routes with their
246
+ * own cache() config (including cache(false)) are never overridden: the
247
+ * marker only applies when the route tree derived NO cache scope.
119
248
  */
120
- waitUntil(fn: () => Promise<void>): void;
249
+ _shellImplicitCache?: {
250
+ ttl?: number;
251
+ swr?: number;
252
+ store?: SegmentCacheStore;
253
+ };
254
+
255
+ /**
256
+ * @internal Shell-HIT tail marker: cache/prerender-store hits during THIS
257
+ * render emit stored segment fragments VERBATIM into the payload
258
+ * (segment-codec fragmentSegments) instead of deserialize -> re-serialize
259
+ * per request; the payload consumers (SSR resume + browser hydration)
260
+ * expand them (segment-fragments.ts, issue #700). Own property of
261
+ * serveShellHit's derived tail context ONLY — it must never be visible to a
262
+ * capture render: the capture SSR-prerenders the payload AND serializes
263
+ * segments into records (cacheRoute), and an envelope reaching
264
+ * serializeSegments would store a double-encoded fragment.
265
+ */
266
+ _shellFragmentPayload?: boolean;
267
+
268
+ /**
269
+ * @internal Handler-layer liveness observed DURING a shell capture, from
270
+ * three sources: (a) the capture handle-store push wrapper (shell-capture.ts)
271
+ * when a push made OUTSIDE a DSL loader scope carries a nested thenable
272
+ * (masked to a never-filling hole); (b) still-pending top-level handler
273
+ * pushes (liveness unknowable at the barrier); (c) a handler-invoked loader
274
+ * executing during the capture (loader-resolution.ts — its consumption-lane
275
+ * value would freeze on a handler-free HIT). captureAndStoreShell folds it
276
+ * into ShellCacheEntry.handlerLiveHoles at the putShell barrier. Own
277
+ * property of the capture's derived context only.
278
+ */
279
+ _shellCaptureHandleLiveness?: {
280
+ holes: boolean;
281
+ pendingPushes: number;
282
+ handlerInvokedLoader: boolean;
283
+ };
284
+
285
+ /**
286
+ * @internal Handle values pushed from a DSL loader scope DURING a shell
287
+ * capture (identity set; populated by the capture push wrapper in
288
+ * shell-capture.ts). cacheRoute threads it into captureHandles so those
289
+ * values stay out of cache-write handle records — loaders re-run fresh on
290
+ * every HIT, so replaying their captured (masked) values would duplicate
291
+ * the fresh push and stall the Flight handle encode. Own property of the
292
+ * capture's derived context only; render-time handle consumers are
293
+ * unaffected (the exclusion applies only at the captureHandles call site).
294
+ */
295
+ _shellCaptureLoaderHandleValues?: WeakSet<object>;
296
+
297
+ /**
298
+ * @internal Set (to the offending fn name) by the cookies()/headers()
299
+ * capture guard when it throws DURING a capture render. Load-bearing for the
300
+ * bake lane: a guard throw inside an executing loader is swallowed by
301
+ * wrapLoaderPromise into per-loader error UI, which would otherwise bake
302
+ * silently into the shared shell — the capture checks this flag after the
303
+ * render and refuses instead. Deterministic, so the capture does not retry.
304
+ */
305
+ _shellCaptureGuardTripped?: string;
306
+
307
+ /**
308
+ * @internal The loader $$id whose BODY was executing when the capture guard
309
+ * tripped (read off the loader-body ALS scope at trip time), or undefined
310
+ * when the read came from handler/render code. Only used to make the
311
+ * once-per-key refusal warning name the real source — the old text
312
+ * hardcoded "a bake-lane loader", which misattributed handler-land reads
313
+ * and sent users debugging the wrong lane (issue #672, secondary).
314
+ */
315
+ _shellCaptureGuardTrippedLoaderId?: string;
316
+
317
+ /**
318
+ * @internal Handler-owned registry of explicit per-scope stores from
319
+ * cache({ store }). Created once per createRSCHandler() and threaded into
320
+ * every request context, so it accumulates every explicit store the handler
321
+ * resolves. updateTag()/revalidateTag() iterate this set plus _cacheStore to
322
+ * reach every store that may hold tagged entries. The app-level store is not
323
+ * added here (it is always reachable via _cacheStore).
324
+ */
325
+ _explicitTaggedStores?: Set<SegmentCacheStore>;
326
+
327
+ /**
328
+ * @internal Union of every cache tag resolved while producing this request's
329
+ * response (from cache({ tags }), runtime cacheTag(), and loader cache tags).
330
+ * Populated at the tag-resolution sites via recordRequestTags(). Read by the
331
+ * document cache middleware so a full-page entry is tagged with everything its
332
+ * content used and can therefore be invalidated by updateTag()/revalidateTag().
333
+ */
334
+ _requestTags: Set<string>;
335
+
336
+ /** @internal Cache profiles for "use cache" profile resolution (per-router) */
337
+ _cacheProfiles?: Record<
338
+ string,
339
+ import("../cache/profile-registry.js").CacheProfile
340
+ >;
121
341
 
122
342
  /**
123
343
  * Register a callback to run when the response is created.
@@ -141,6 +361,19 @@ export interface RequestContext<
141
361
  /** @internal Registered onResponse callbacks */
142
362
  _onResponseCallbacks: Array<(response: Response) => Response>;
143
363
 
364
+ /**
365
+ * @internal Promises of the background tasks scheduled via this context's
366
+ * waitUntil (deferred cache writes, revalidations, consumer tasks). The PPR
367
+ * shell capture drains this list BEFORE its match/render as an ORDERING EDGE:
368
+ * every foreground deferred cache write is scheduled here before the capture
369
+ * task is, so settling the list first guarantees the capture's cache reads
370
+ * observe the foreground's generation instead of racing it (see
371
+ * shell-capture.ts). Tasks whose scheduling fn carries
372
+ * UNTRACKED_BACKGROUND_TASK are not tracked (the capture task itself —
373
+ * tracking it would make that drain await its own promise).
374
+ */
375
+ _pendingBackgroundTasks?: Array<Promise<unknown>>;
376
+
144
377
  /**
145
378
  * Current theme setting (only available when theme is enabled in router config)
146
379
  *
@@ -178,8 +411,259 @@ export interface RequestContext<
178
411
 
179
412
  /** @internal Theme configuration (null if theme not enabled) */
180
413
  _themeConfig?: ResolvedThemeConfig | null;
414
+
415
+ /**
416
+ * Attach location state entries to the current response.
417
+ *
418
+ * For partial (SPA) requests, the state is included in the RSC payload
419
+ * metadata and merged into history.pushState on the client. For redirect
420
+ * responses, the state travels through the redirect payload so the target
421
+ * page can read it via useLocationState.
422
+ *
423
+ * Multiple calls accumulate entries.
424
+ *
425
+ * @example
426
+ * ```typescript
427
+ * ctx.setLocationState(Flash({ text: "Item saved!" }));
428
+ * ```
429
+ */
430
+ setLocationState(entries: LocationStateEntry | LocationStateEntry[]): void;
431
+
432
+ /** @internal Accumulated location state entries */
433
+ _locationState?: LocationStateEntry[];
434
+
435
+ /**
436
+ * The matched route name, if the route has an explicit name.
437
+ * Undefined before route matching or for unnamed routes.
438
+ * Includes the namespace prefix from include() (e.g., "blog.post").
439
+ */
440
+ routeName?: DefaultRouteName;
441
+
442
+ /**
443
+ * Generate URLs from route names.
444
+ * Uses the global route map. After route matching, scoped (`.name`) resolution
445
+ * works within the matched include() scope.
446
+ */
447
+ reverse: ScopedReverseFunction<
448
+ Record<string, string>,
449
+ DefaultReverseRouteMap
450
+ >;
451
+
452
+ /** @internal Route name from route matching, used for scoped reverse resolution */
453
+ _routeName?: string;
454
+
455
+ /** @internal Previous route key (from the navigation source), used for revalidation */
456
+ _prevRouteKey?: string;
457
+
458
+ /**
459
+ * @internal Navigation/action source data the transition({ when }) gate reads
460
+ * to build its ShouldRevalidateFn-shaped predicate context. currentUrl/Params
461
+ * come from the navigation snapshot (set at match time); action* are stashed
462
+ * at the action-bearing gate call sites. All undefined when there is no source
463
+ * (initial full load) or no action (plain navigation).
464
+ */
465
+ _gateCurrentUrl?: URL;
466
+ _gateCurrentParams?: Record<string, string>;
467
+ _gateActionId?: string;
468
+ _gateActionUrl?: URL;
469
+ _gateActionResult?: unknown;
470
+ _gateFormData?: FormData;
471
+
472
+ /**
473
+ * @internal True while the post-action revalidation render is running (set by
474
+ * revalidateAfterAction). The "use cache" runtime reads this to prefer
475
+ * freshness over a fast stale response during an action: a stale entry
476
+ * re-executes in the foreground (so the action response reflects the refreshed
477
+ * value) with only the store write deferred, instead of serving stale and
478
+ * revalidating in the background. A plain navigation (flag unset) keeps SWR.
479
+ */
480
+ _inActionRevalidation?: boolean;
481
+
482
+ /**
483
+ * @internal Render barrier for experimental `rendered()` API.
484
+ * Resolves when all non-loader segments have settled and handle data
485
+ * is available. Used by DSL loaders that call `ctx.rendered()`.
486
+ */
487
+ _renderBarrier: Promise<void>;
488
+
489
+ /**
490
+ * @internal Resolve the render barrier. Accepts resolved segments, filters
491
+ * out loaders, and captures non-loader segment IDs as the handle ordering.
492
+ * Called after segment resolution (fresh) or handle replay (cache/prerender).
493
+ */
494
+ _resolveRenderBarrier: (
495
+ segments: Array<{ type: string; id: string }>,
496
+ ) => void;
497
+
498
+ /**
499
+ * @internal Segment order at barrier resolution time, used by loader
500
+ * ctx.use(handle) to collect handle data in correct order.
501
+ */
502
+ _renderBarrierSegmentOrder?: string[];
503
+
504
+ /**
505
+ * @internal Set to true when the matched entry tree contains any `loading()`
506
+ * entries (streaming). On a streaming tree rendered() waits for the streaming
507
+ * handlers to settle (via handleStore.settled) before resolving, and the
508
+ * deadlock guard state is kept live until that wait completes.
509
+ */
510
+ _treeHasStreaming?: boolean;
511
+
512
+ /**
513
+ * @internal Loader IDs that have called rendered() and are waiting for the
514
+ * barrier. Used to detect deadlocks when a handler tries to await the same
515
+ * loader via ctx.use(Loader).
516
+ */
517
+ _renderBarrierWaiters?: Set<string>;
518
+
519
+ /**
520
+ * @internal Loader IDs that handlers have started awaiting via ctx.use().
521
+ * Used for bidirectional deadlock detection: if a loader later calls
522
+ * rendered() and a handler already awaits it, we can detect the deadlock.
523
+ */
524
+ _handlerLoaderDeps?: Set<string>;
525
+
526
+ /**
527
+ * @internal Cached HandleData snapshot built at barrier resolution time.
528
+ * Avoids rebuilding the snapshot on every loader ctx.use(handle) call.
529
+ */
530
+ _renderBarrierHandleSnapshot?: HandleData;
531
+
532
+ /**
533
+ * @internal The deadlock guard window is closed (no further handler-awaits-
534
+ * loader cycle is possible). For non-streaming trees this is set when the
535
+ * barrier resolves. For streaming trees the window stays open until
536
+ * handleStore.settled — rendered() keeps waiting past the barrier and a
537
+ * loading() handler can still resume and await a still-waiting loader — so it
538
+ * is set only after settled. The guard (loader-resolution `setupLoaderAccess`)
539
+ * reads this instead of `_renderBarrierSegmentOrder` so it does not go blind
540
+ * during the streaming settle wait.
541
+ */
542
+ _renderBarrierGuardClosed?: boolean;
543
+
544
+ /** @internal Per-request error dedup set for onError reporting */
545
+ _reportedErrors: WeakSet<object>;
546
+
547
+ /**
548
+ * @internal Report a non-fatal background error through the router's
549
+ * onError callback. Wired by the RSC handler / router during request
550
+ * creation. Cache-runtime and other subsystems call this to surface
551
+ * errors without failing the response. `category` is surfaced to consumers as
552
+ * `metadata.category` on the onError context (phase `cache`).
553
+ */
554
+ _reportBackgroundError?: (
555
+ error: unknown,
556
+ category: CacheErrorCategory,
557
+ ) => void;
558
+
559
+ /** @internal Per-request debug performance override (set via ctx.debugPerformance()) */
560
+ _debugPerformance?: boolean;
561
+
562
+ /** @internal Request-scoped performance metrics store */
563
+ _metricsStore?: MetricsStore;
564
+
565
+ /**
566
+ * @internal True request entry timestamp (performance.now() at handler entry).
567
+ * Set once at request-context creation (rsc/handler.ts) so a metrics store
568
+ * created MID-request — ctx.debugPerformance() or the getMetricsStore wrapper —
569
+ * anchors its timeline to the real request start instead of the opt-in moment,
570
+ * keeping phases that began before the opt-in at their true (non-negative) offset.
571
+ */
572
+ _handlerStart?: number;
573
+
574
+ /** @internal Resolved platform phase-span tracing for this request (Cloudflare or OTel) */
575
+ _tracing?: ResolvedTracing;
576
+
577
+ /** @internal Router basename for this request (used by redirect()) */
578
+ _basename?: string;
579
+
580
+ /**
581
+ * @internal RouteSnapshot from classifyRequest, reused by match/matchPartial
582
+ * to avoid a second resolveRoute call. Cleared on HMR invalidation.
583
+ */
584
+ _classifiedRoute?: import("../router/route-snapshot.js").RouteSnapshot;
585
+
586
+ /**
587
+ * @internal Coarse route-level cache signal for the X-Rango-Cache debug
588
+ * header. Populated by match/matchPartial only when the debug cache signal
589
+ * gate is enabled (debugCacheSignal option or RANGO_TEST_SIGNALS=1). Read by
590
+ * the response-finalization path (createResponseWithMergedHeaders). Undefined
591
+ * when the gate is off, so no header is emitted.
592
+ */
593
+ _cacheSignal?: import("../router/telemetry.js").CacheSegmentSignal[];
181
594
  }
182
595
 
596
+ /**
597
+ * Public view of RequestContext, without internal methods and fields.
598
+ *
599
+ * This is the type exported to library consumers. Internal code should
600
+ * use the full RequestContext interface directly.
601
+ */
602
+ export type PublicRequestContext<
603
+ TEnv = DefaultEnv,
604
+ TParams = Record<string, string>,
605
+ > = Omit<
606
+ RequestContext<TEnv, TParams>,
607
+ | "cookie"
608
+ | "cookies"
609
+ | "setCookie"
610
+ | "deleteCookie"
611
+ | "_handleStore"
612
+ | "_transitionWhen"
613
+ | "_cacheStore"
614
+ | "_shellCaptureRun"
615
+ | "_shellFragmentPayload"
616
+ | "_shellCaptureGuardTrippedLoaderId"
617
+ | "_explicitTaggedStores"
618
+ | "_requestTags"
619
+ | "_cacheProfiles"
620
+ | "_onResponseCallbacks"
621
+ | "_themeConfig"
622
+ | "_locationState"
623
+ | "_routeName"
624
+ | "_prevRouteKey"
625
+ | "_gateCurrentUrl"
626
+ | "_gateCurrentParams"
627
+ | "_gateActionId"
628
+ | "_gateActionUrl"
629
+ | "_gateActionResult"
630
+ | "_gateFormData"
631
+ | "_inActionRevalidation"
632
+ | "_reportedErrors"
633
+ | "_renderBarrier"
634
+ | "_resolveRenderBarrier"
635
+ | "_renderBarrierSegmentOrder"
636
+ | "_treeHasStreaming"
637
+ | "_renderBarrierWaiters"
638
+ | "_handlerLoaderDeps"
639
+ | "_renderBarrierHandleSnapshot"
640
+ | "_renderBarrierGuardClosed"
641
+ | "_reportBackgroundError"
642
+ | "_debugPerformance"
643
+ | "_metricsStore"
644
+ | "_handlerStart"
645
+ | "_basename"
646
+ | "_setStatus"
647
+ | "_rotateStateCookie"
648
+ | "_setKeepCacheDirective"
649
+ | "_variables"
650
+ | "_classifiedRoute"
651
+ | "_cacheSignal"
652
+ | "_dynamic"
653
+ | "res"
654
+ >;
655
+
656
+ /**
657
+ * Marker for a waitUntil-scheduled fn whose task promise must NOT enter
658
+ * _pendingBackgroundTasks. Used by the PPR shell capture for its own task:
659
+ * the capture's pre-render write barrier settles that list, so tracking the
660
+ * capture itself would make the drain wait on its own (still-running) promise.
661
+ * @internal
662
+ */
663
+ export const UNTRACKED_BACKGROUND_TASK: unique symbol = Symbol.for(
664
+ "rango.untrackedBackgroundTask",
665
+ );
666
+
183
667
  // AsyncLocalStorage instance for request context
184
668
  const requestContextStorage = new AsyncLocalStorage<RequestContext<any>>();
185
669
 
@@ -189,16 +673,33 @@ const requestContextStorage = new AsyncLocalStorage<RequestContext<any>>();
189
673
  */
190
674
  export function runWithRequestContext<TEnv, T>(
191
675
  context: RequestContext<TEnv>,
192
- fn: () => T
676
+ fn: () => T,
193
677
  ): T {
194
678
  return requestContextStorage.run(context, fn);
195
679
  }
196
680
 
197
681
  /**
198
682
  * Get the current request context
199
- * Returns undefined if not running within a request context
683
+ * Throws if called outside of a request context
684
+ */
685
+ export function getRequestContext<TEnv = DefaultEnv>(): RequestContext<TEnv> {
686
+ const ctx = requestContextStorage.getStore() as
687
+ | RequestContext<TEnv>
688
+ | undefined;
689
+ invariant(
690
+ ctx,
691
+ "getRequestContext() called outside of a request context. " +
692
+ "This function must be called from within a route handler, loader, middleware, " +
693
+ "server action, or server component.",
694
+ );
695
+ return ctx;
696
+ }
697
+
698
+ /**
699
+ * @internal Get the request context without throwing — for internal code that
700
+ * may run outside a request context (cache stores, optional handle lookups, etc.)
200
701
  */
201
- export function getRequestContext<TEnv = unknown>():
702
+ export function _getRequestContext<TEnv = DefaultEnv>():
202
703
  | RequestContext<TEnv>
203
704
  | undefined {
204
705
  return requestContextStorage.getStore() as RequestContext<TEnv> | undefined;
@@ -206,38 +707,72 @@ export function getRequestContext<TEnv = unknown>():
206
707
 
207
708
  /**
208
709
  * Update params on the current request context
209
- * Called after route matching to populate route params
710
+ * Called after route matching to populate route params and route name
210
711
  */
211
- export function setRequestContextParams(params: Record<string, string>): void {
712
+ export function setRequestContextParams(
713
+ params: Record<string, string>,
714
+ routeName?: string,
715
+ routeMap?: Record<string, string>,
716
+ ): void {
212
717
  const ctx = requestContextStorage.getStore();
213
718
  if (ctx) {
214
719
  ctx.params = params;
720
+ if (routeName !== undefined) {
721
+ ctx._routeName = routeName;
722
+ ctx.routeName = (
723
+ routeName && !isAutoGeneratedRouteName(routeName)
724
+ ? routeName
725
+ : undefined
726
+ ) as DefaultRouteName | undefined;
727
+ }
728
+ // Update reverse with scoped resolution now that route is known. Production
729
+ // omits routeMap and uses the global map (routes are registered globally);
730
+ // the testing primitives (renderToFlightString/renderServerTree) pass a
731
+ // scoped routeMap so `ctx.reverse` is not order-dependent on whatever router
732
+ // registered last.
733
+ ctx.reverse = createReverseFunction(
734
+ routeMap ?? getGlobalRouteMap(),
735
+ routeName,
736
+ params,
737
+ routeName ? isRouteRootScoped(routeName) : undefined,
738
+ );
215
739
  }
216
740
  }
217
741
 
218
742
  /**
219
- * Get the current request context, throwing if not available
220
- * Use this when context is required (e.g., in loader actions)
743
+ * Store the previous route key on the request context.
744
+ * Called during partial-match context creation to make the navigation source
745
+ * route key available for revalidation and intercept evaluation.
746
+ * @internal
221
747
  */
222
- export function requireRequestContext<TEnv = unknown>(): RequestContext<TEnv> {
223
- const ctx = getRequestContext<TEnv>();
224
- if (!ctx) {
225
- throw new Error(
226
- "Request context not available. This function must be called from within a server action " +
227
- "executed through the RSC handler."
228
- );
229
- }
230
- return ctx;
748
+ export function setRequestContextPrevRouteKey(
749
+ prevRouteKey: string | undefined,
750
+ currentUrl?: URL,
751
+ currentParams?: Record<string, string>,
752
+ ): void {
753
+ const ctx = requestContextStorage.getStore();
754
+ if (!ctx) return;
755
+ if (prevRouteKey !== undefined) ctx._prevRouteKey = prevRouteKey;
756
+ // Source URL/params for the transition({ when }) gate (effectiveFromUrl /
757
+ // effectiveFromMatch.params from the navigation snapshot). Same write point as
758
+ // _prevRouteKey, which doubles as fromRouteName.
759
+ if (currentUrl !== undefined) ctx._gateCurrentUrl = currentUrl;
760
+ if (currentParams !== undefined) ctx._gateCurrentParams = currentParams;
231
761
  }
232
762
 
233
763
  /**
234
- * Cloudflare Workers ExecutionContext (subset we need)
764
+ * Get accumulated location state entries from the current request context.
765
+ * Returns undefined if no state has been set.
766
+ *
767
+ * @internal Used by the RSC handler to include state in payload metadata.
235
768
  */
236
- export interface ExecutionContext {
237
- waitUntil(promise: Promise<any>): void;
238
- passThroughOnException(): void;
769
+ export function getLocationState(): LocationStateEntry[] | undefined {
770
+ const ctx = getRequestContext();
771
+ return ctx?._locationState;
239
772
  }
240
773
 
774
+ export type { ExecutionContext };
775
+
241
776
  /**
242
777
  * Options for creating a request context
243
778
  */
@@ -246,12 +781,30 @@ export interface CreateRequestContextOptions<TEnv> {
246
781
  request: Request;
247
782
  url: URL;
248
783
  variables: Record<string, any>;
784
+ /** Optional initial response stub headers/status to seed effective cookie reads */
785
+ initialResponse?: Response;
249
786
  /** Optional cache store for segment caching (used by CacheScope) */
250
787
  cacheStore?: SegmentCacheStore;
788
+ /**
789
+ * Handler-owned registry of explicit per-scope stores for cross-store tag
790
+ * invalidation. Created once per handler, reused across requests.
791
+ */
792
+ explicitTaggedStores?: Set<SegmentCacheStore>;
793
+ /** Optional cache profiles for "use cache" resolution (per-router) */
794
+ cacheProfiles?: Record<
795
+ string,
796
+ import("../cache/profile-registry.js").CacheProfile
797
+ >;
251
798
  /** Optional Cloudflare execution context for waitUntil support */
252
799
  executionContext?: ExecutionContext;
800
+ /** Build-time render/capture request marker. Defaults to false. */
801
+ build?: boolean;
253
802
  /** Optional theme configuration (enables ctx.theme and ctx.setTheme) */
254
803
  themeConfig?: ResolvedThemeConfig | null;
804
+ /** Resolved rango state cookie name, for the server seat of invalidateClientCache(). */
805
+ stateCookieName?: string;
806
+ /** Build version, used as the prefix of a server-rotated rango state value. */
807
+ version?: string;
255
808
  }
256
809
 
257
810
  /**
@@ -263,20 +816,82 @@ export interface CreateRequestContextOptions<TEnv> {
263
816
  * - Passed to handlers as ctx
264
817
  */
265
818
  export function createRequestContext<TEnv>(
266
- options: CreateRequestContextOptions<TEnv>
819
+ options: CreateRequestContextOptions<TEnv>,
267
820
  ): RequestContext<TEnv> {
268
- const { env, request, url, variables, cacheStore, executionContext, themeConfig } = options;
821
+ const {
822
+ env,
823
+ request,
824
+ url,
825
+ variables,
826
+ initialResponse,
827
+ cacheStore,
828
+ explicitTaggedStores,
829
+ cacheProfiles,
830
+ executionContext,
831
+ build = false,
832
+ themeConfig,
833
+ stateCookieName,
834
+ version: stateVersion,
835
+ } = options;
269
836
  const cookieHeader = request.headers.get("Cookie");
837
+ let rangoStateRotated = false;
270
838
  let parsedCookies: Record<string, string> | null = null;
271
839
 
272
- // Create stub response for collecting headers/cookies
273
- const stubResponse = new Response(null, { status: 200 });
840
+ let stubResponse = initialResponse
841
+ ? new Response(null, {
842
+ status: initialResponse.status,
843
+ statusText: initialResponse.statusText,
844
+ headers: new Headers(initialResponse.headers),
845
+ })
846
+ : new Response(null, { status: 200 });
847
+
848
+ // The #713 choke point: `rawStubHeaders` is the stub's REAL Headers; the
849
+ // proxy below is the only view reachable from consumer code, and its
850
+ // mutating methods consult the cached-scope guard first. shadowStubHeaders
851
+ // shadows `headers` on the stub Response INSTANCE (a real Response, not a
852
+ // facade — safe to hand to the platform), so every surface that ends in a
853
+ // stub-header mutation — ctx.header/setCookie/deleteCookie, ctx.setTheme,
854
+ // the handler ctx.headers proxy, and raw `ctx.res.headers.set(...)` — is
855
+ // guarded at the mutation itself, not per enumerated wrapper. Guard-exempt
856
+ // internal writers (_rotateStateCookie, _setKeepCacheDirective — serve
857
+ // machinery, documented callable from loaders/during capture) write to
858
+ // rawStubHeaders directly. The serve/commit path's stub reads and its
859
+ // Set-Cookie drain (rsc/helpers.ts) run outside any latched funnel scope,
860
+ // where assertCachedHeaderWriteAllowed is a no-op.
861
+ let rawStubHeaders = stubResponse.headers;
862
+ const guardedStubHeaders: Headers = new Proxy(new Headers(), {
863
+ get(_target, prop) {
864
+ const raw = rawStubHeaders;
865
+ const value = Reflect.get(raw, prop) as unknown;
866
+ if (typeof value !== "function") return value;
867
+ if (prop === "set" || prop === "append" || prop === "delete") {
868
+ return (...args: unknown[]) => {
869
+ assertCachedHeaderWriteAllowed("response headers", prop);
870
+ return (value as (...a: unknown[]) => unknown).apply(raw, args);
871
+ };
872
+ }
873
+ return (value as (...a: unknown[]) => unknown).bind(raw);
874
+ },
875
+ });
876
+ const shadowStubHeaders = (res: Response): void => {
877
+ Object.defineProperty(res, "headers", {
878
+ value: guardedStubHeaders,
879
+ enumerable: true,
880
+ configurable: true,
881
+ });
882
+ };
883
+ shadowStubHeaders(stubResponse);
884
+ // Rebuild the stub with a new status, re-shadowing the fresh instance
885
+ // (the Response constructor copies rawStubHeaders into new raw Headers).
886
+ const replaceStubStatus = (status: number): void => {
887
+ stubResponse = new Response(null, { status, headers: rawStubHeaders });
888
+ rawStubHeaders = stubResponse.headers;
889
+ shadowStubHeaders(stubResponse);
890
+ };
274
891
 
275
- // Create handle store and loader memoization for this request
276
892
  const handleStore = createHandleStore();
277
893
  const loaderPromises = new Map<string, Promise<any>>();
278
894
 
279
- // Lazy parse cookies
280
895
  const getParsedCookies = (): Record<string, string> => {
281
896
  if (!parsedCookies) {
282
897
  parsedCookies = parseCookiesFromHeader(cookieHeader);
@@ -284,13 +899,40 @@ export function createRequestContext<TEnv>(
284
899
  return parsedCookies;
285
900
  };
286
901
 
287
- // Theme helpers (only used when themeConfig is provided)
902
+ let responseCookieCache: Map<string, string | null> | null = null;
903
+ const getResponseCookies = (): Map<string, string | null> => {
904
+ if (!responseCookieCache) {
905
+ responseCookieCache = parseResponseCookies(stubResponse);
906
+ }
907
+ return responseCookieCache;
908
+ };
909
+ const invalidateResponseCookieCache = () => {
910
+ responseCookieCache = null;
911
+ };
912
+
913
+ // Guard for the two response-write surfaces that are NOT Headers mutations
914
+ // (setStatus rebuilds the stub Response, onResponse registers a callback) —
915
+ // these can't ride the guarded-headers choke point above, so they stay
916
+ // enumerated. Same unified #713 guard, same message family.
917
+ function assertResponseWriteAllowed(methodName: string): void {
918
+ assertCachedHeaderWriteAllowed("ctx", methodName);
919
+ }
920
+
921
+ // Response stub Set-Cookie wins, then original header (source of truth for mutations).
922
+ const effectiveCookie = (name: string): string | undefined => {
923
+ const mutations = getResponseCookies();
924
+ if (mutations.has(name)) {
925
+ const v = mutations.get(name);
926
+ return v === null ? undefined : v;
927
+ }
928
+ return getParsedCookies()[name];
929
+ };
930
+
288
931
  const getTheme = (): Theme | undefined => {
289
932
  if (!themeConfig) return undefined;
290
933
 
291
- const stored = getParsedCookies()[themeConfig.storageKey];
934
+ const stored = effectiveCookie(themeConfig.storageKey);
292
935
  if (stored) {
293
- // Validate stored value
294
936
  if (stored === "system" && themeConfig.enableSystem) {
295
937
  return "system";
296
938
  }
@@ -304,135 +946,394 @@ export function createRequestContext<TEnv>(
304
946
  const setTheme = (theme: Theme): void => {
305
947
  if (!themeConfig) return;
306
948
 
307
- // Validate theme value
308
- if (theme !== "system" && !themeConfig.themes.includes(theme)) {
309
- console.warn(`[Theme] Invalid theme value: "${theme}". Valid values: system, ${themeConfig.themes.join(", ")}`);
949
+ // Shared guard (isValidTheme): reject any value not in the configured theme
950
+ // set, AND reject "system" when system detection is off — a cookie of
951
+ // theme=system with enableSystem:false would re-apply a bogus class="system"
952
+ // on the next SSR.
953
+ if (!isValidTheme(theme, themeConfig)) {
954
+ warnInvalidTheme(theme, themeConfig);
310
955
  return;
311
956
  }
312
957
 
313
- // Set cookie
314
958
  stubResponse.headers.append(
315
959
  "Set-Cookie",
316
960
  serializeCookieValue(themeConfig.storageKey, theme, {
317
961
  path: THEME_COOKIE.path,
318
962
  maxAge: THEME_COOKIE.maxAge,
319
963
  sameSite: THEME_COOKIE.sameSite,
320
- })
964
+ }),
321
965
  );
966
+ invalidateResponseCookieCache();
322
967
  };
323
968
 
324
- // Build the context object first (without use), then add use
969
+ const cleanUrl = stripInternalParams(url);
970
+
325
971
  const ctx: RequestContext<TEnv> = {
326
972
  env,
327
973
  request,
328
- url,
974
+ url: cleanUrl,
975
+ originalUrl: new URL(request.url),
329
976
  pathname: url.pathname,
330
- searchParams: url.searchParams,
331
- var: variables,
332
- get: <K extends string>(key: K) => variables[key],
333
- set: <K extends string>(key: K, value: any) => {
334
- variables[key] = value;
977
+ searchParams: cleanUrl.searchParams,
978
+ _variables: variables,
979
+ build,
980
+ dynamic(): void {
981
+ ctx._dynamic = true;
335
982
  },
983
+ _dynamic: false,
984
+ get: ((keyOrVar: any) => {
985
+ if (isNonCacheable(variables, keyOrVar) && isInsideCacheScope()) {
986
+ throw new Error(
987
+ `ctx.get() for a non-cacheable variable cannot be called inside a cache() boundary. ` +
988
+ `The variable was created with { cache: false } or set with { cache: false }, ` +
989
+ `and its value would be stale on cache hit. Move the read outside the cached scope.`,
990
+ );
991
+ }
992
+ return contextGet(variables, keyOrVar);
993
+ }) as RequestContext<TEnv>["get"],
994
+ set: ((keyOrVar: any, value: any, options?: any) => {
995
+ assertNotInsideCacheExec(ctx, "set");
996
+ contextSet(variables, keyOrVar, value, options);
997
+ }) as RequestContext<TEnv>["set"],
336
998
  params: {} as Record<string, string>,
337
- res: stubResponse,
999
+
1000
+ get res(): Response {
1001
+ return stubResponse;
1002
+ },
1003
+ set res(_: Response) {
1004
+ throw new Error(
1005
+ "ctx.res is read-only. Use ctx.header() to set response headers, or cookies() for cookie mutations.",
1006
+ );
1007
+ },
338
1008
 
339
1009
  cookie(name: string): string | undefined {
340
- return getParsedCookies()[name];
1010
+ return effectiveCookie(name);
341
1011
  },
342
1012
 
343
1013
  cookies(): Record<string, string> {
344
- return { ...getParsedCookies() };
1014
+ const parsed = getParsedCookies();
1015
+ const mutations = getResponseCookies();
1016
+ if (mutations.size === 0) return { ...parsed };
1017
+ // Build result without delete (avoids V8 dictionary-mode de-opt)
1018
+ const deleted = new Set<string>();
1019
+ for (const [k, v] of mutations) {
1020
+ if (v === null) deleted.add(k);
1021
+ }
1022
+ const result: Record<string, string> = {};
1023
+ for (const key of Object.keys(parsed)) {
1024
+ if (!deleted.has(key)) result[key] = parsed[key];
1025
+ }
1026
+ for (const [k, v] of mutations) {
1027
+ if (v !== null) result[k] = v;
1028
+ }
1029
+ return result;
345
1030
  },
346
1031
 
347
1032
  setCookie(name: string, value: string, options?: CookieOptions): void {
1033
+ assertNotInsideCacheExec(ctx, "setCookie");
348
1034
  stubResponse.headers.append(
349
1035
  "Set-Cookie",
350
- serializeCookieValue(name, value, options)
1036
+ serializeCookieValue(name, value, options),
351
1037
  );
1038
+ invalidateResponseCookieCache();
352
1039
  },
353
1040
 
354
1041
  deleteCookie(
355
1042
  name: string,
356
- options?: Pick<CookieOptions, "domain" | "path">
1043
+ options?: Pick<CookieOptions, "domain" | "path">,
357
1044
  ): void {
1045
+ assertNotInsideCacheExec(ctx, "deleteCookie");
358
1046
  stubResponse.headers.append(
359
1047
  "Set-Cookie",
360
- serializeCookieValue(name, "", { ...options, maxAge: 0 })
1048
+ serializeCookieValue(name, "", { ...options, maxAge: 0 }),
361
1049
  );
1050
+ invalidateResponseCookieCache();
362
1051
  },
363
1052
 
364
1053
  header(name: string, value: string): void {
1054
+ assertNotInsideCacheExec(ctx, "header");
365
1055
  stubResponse.headers.set(name, value);
366
1056
  },
367
1057
 
368
- // Placeholder - will be replaced below
1058
+ // Rotate the rango state cookie for the responding client (the server seat
1059
+ // of invalidateClientCache). Writes ONE Set-Cookie per request with the
1060
+ // value {version}:{timestamp}; the `:` stays raw (the cookie-name.ts
1061
+ // serializer), not the URL-encoded form serializeCookieValue would produce.
1062
+ // The timestamp is strictly greater than the client's current one (inbound
1063
+ // X-Rango-State), so a same-millisecond server rotation still differs from
1064
+ // the client value and the divergence observer fires.
1065
+ _rotateStateCookie(): void {
1066
+ if (rangoStateRotated) return;
1067
+ rangoStateRotated = true;
1068
+ if (!stateCookieName) return;
1069
+ // The client's current value, for the monotonic guard: prefer the
1070
+ // X-Rango-State header (router navigation/prefetch fetches send it), but
1071
+ // fall back to the request's rango state cookie — action POSTs / plain
1072
+ // app fetch()s carry no router header yet DO send the cookie. Without the
1073
+ // fallback, prevTs stays 0 and a same-ms mint can equal the client value,
1074
+ // leaving the divergence observer silent. `|| null` so an empty header
1075
+ // ('' from proxy normalization) falls through instead of short-circuiting.
1076
+ // getRawCookieValue reads the cookie undecoded (the wire value
1077
+ // decodeStateValue decodes exactly once) AND is the same parser the client
1078
+ // mirror uses, so both seats read the same jar entry.
1079
+ const prevRaw =
1080
+ (request.headers.get("x-rango-state") || null) ??
1081
+ getRawCookieValue(cookieHeader, stateCookieName);
1082
+ const value = mintStateValue(stateVersion ?? "0", prevRaw);
1083
+ // rawStubHeaders: guard-exempt internal writer — invalidateClientCache()
1084
+ // is documented callable from loaders and during shell capture.
1085
+ rawStubHeaders.append(
1086
+ "Set-Cookie",
1087
+ serializeStateCookie(stateCookieName, value, url.protocol === "https:"),
1088
+ );
1089
+ invalidateResponseCookieCache();
1090
+ },
1091
+
1092
+ // Set the keepClientCache() directive header. The action bridge reads it on
1093
+ // the response and suppresses its automatic invalidation. `.set` makes this
1094
+ // idempotent (one header regardless of call count). rawStubHeaders:
1095
+ // guard-exempt internal writer.
1096
+ _setKeepCacheDirective(): void {
1097
+ rawStubHeaders.set(KEEP_CACHE_HEADER, "1");
1098
+ },
1099
+
1100
+ setStatus(status: number): void {
1101
+ assertNotInsideCacheExec(ctx, "setStatus");
1102
+ assertResponseWriteAllowed("setStatus");
1103
+ replaceStubStatus(status);
1104
+ },
1105
+
1106
+ _setStatus(status: number): void {
1107
+ replaceStubStatus(status);
1108
+ },
1109
+
369
1110
  use: null as any,
370
1111
 
371
1112
  method: request.method,
372
1113
 
373
1114
  _handleStore: handleStore,
1115
+ _transitionWhen: [],
374
1116
  _cacheStore: cacheStore,
1117
+ _explicitTaggedStores: explicitTaggedStores,
1118
+ _requestTags: new Set<string>(),
1119
+ _cacheProfiles: cacheProfiles,
375
1120
 
376
1121
  waitUntil(fn: () => Promise<void>): void {
1122
+ if (ctx.build) return;
1123
+ // Wrap in Promise.resolve().then(fn) so a SYNCHRONOUS throw in a
1124
+ // non-async callback becomes a rejected promise handed to the host's
1125
+ // waitUntil (logged as a background failure), instead of escaping into
1126
+ // the request flow. Mirrors fireAndForgetWaitUntil's deferral.
1127
+ const task = Promise.resolve().then(fn);
1128
+ // Track the task promise so the PPR shell capture can settle the
1129
+ // foreground's deferred cache writes before its own match/render (the
1130
+ // ordering edge; see _pendingBackgroundTasks). The capture task itself
1131
+ // opts out via the marker — the drain must never await its own promise.
1132
+ if (
1133
+ !(fn as { [UNTRACKED_BACKGROUND_TASK]?: boolean })[
1134
+ UNTRACKED_BACKGROUND_TASK
1135
+ ]
1136
+ ) {
1137
+ ctx._pendingBackgroundTasks?.push(task);
1138
+ }
377
1139
  if (executionContext?.waitUntil) {
378
- // Cloudflare Workers: use native waitUntil
379
- executionContext.waitUntil(fn());
1140
+ executionContext.waitUntil(task);
380
1141
  } else {
381
- // Node.js / dev: fire-and-forget with error logging
382
- fn().catch((err) => console.error("[waitUntil] Background task failed:", err));
1142
+ // Node/dev fallback: fire-and-forget with error logging (the same
1143
+ // policy fireAndForgetWaitUntil applies).
1144
+ task.catch((err) =>
1145
+ console.error("[waitUntil] Background task failed:", err),
1146
+ );
383
1147
  }
384
1148
  },
385
1149
 
1150
+ executionContext,
1151
+
386
1152
  _onResponseCallbacks: [],
1153
+ _pendingBackgroundTasks: [],
387
1154
 
388
1155
  onResponse(callback: (response: Response) => Response): void {
1156
+ assertNotInsideCacheExec(ctx, "onResponse");
1157
+ assertResponseWriteAllowed("onResponse");
389
1158
  this._onResponseCallbacks.push(callback);
390
1159
  },
391
1160
 
392
- // Theme properties (only set when themeConfig is provided)
393
- theme: themeConfig ? getTheme() : undefined,
394
- setTheme: themeConfig ? setTheme : undefined,
1161
+ get theme() {
1162
+ return themeConfig ? getTheme() : undefined;
1163
+ },
1164
+ setTheme: themeConfig
1165
+ ? (theme: Theme) => {
1166
+ assertNotInsideCacheExec(ctx, "setTheme");
1167
+ setTheme(theme);
1168
+ }
1169
+ : undefined,
395
1170
  _themeConfig: themeConfig,
1171
+
1172
+ setLocationState(entries: LocationStateEntry | LocationStateEntry[]): void {
1173
+ assertNotInsideCacheExec(ctx, "setLocationState");
1174
+ const arr = Array.isArray(entries) ? entries : [entries];
1175
+ this._locationState = this._locationState
1176
+ ? [...this._locationState, ...arr]
1177
+ : arr;
1178
+ },
1179
+ _locationState: undefined,
1180
+
1181
+ _reportedErrors: new WeakSet<object>(),
1182
+ _metricsStore: undefined,
1183
+ _handlerStart: undefined,
1184
+
1185
+ _renderBarrier: null as any,
1186
+ _resolveRenderBarrier: null as any,
1187
+ _renderBarrierSegmentOrder: undefined,
1188
+
1189
+ reverse: createReverseFunction(getGlobalRouteMap(), undefined, {}),
396
1190
  };
397
1191
 
398
- // Now create use() with access to ctx
1192
+ wireRenderBarrier(ctx, handleStore);
1193
+
399
1194
  ctx.use = createUseFunction({
400
1195
  handleStore,
401
1196
  loaderPromises,
402
1197
  getContext: () => ctx,
403
1198
  });
404
1199
 
1200
+ (ctx as any)[NOCACHE_SYMBOL] = true;
405
1201
  return ctx;
406
1202
  }
407
1203
 
408
1204
  /**
409
- * Parse cookies from Cookie header
1205
+ * Wire a fresh render barrier onto `ctx`, closure-bound to THIS ctx and THIS
1206
+ * handle store. Called by createRequestContext for every fresh context, and by
1207
+ * deriveShellCaptureContext (rsc/shell-capture.ts) for the PPR capture's
1208
+ * derived context.
1209
+ *
1210
+ * The derived-context call is load-bearing (issue #684, plan 009): the capture
1211
+ * context is `Object.create(reqCtx)`, so without its own wiring every
1212
+ * `_renderBarrier*` read fell through the prototype to the FOREGROUND
1213
+ * request's barrier — whose getter and resolver are closure-bound to the
1214
+ * foreground ctx and its handle store, and whose resolver no-ops once
1215
+ * resolved. A bake-lane loader's `await ctx.rendered()` during capture then
1216
+ * resolved instantly against the foreground's barrier and `ctx.use(handle)`
1217
+ * read the foreground's handle snapshot; the capture's fresh `_handleStore`
1218
+ * was invisible, so foreground per-request handle data could bake into the
1219
+ * shared shell.
410
1220
  */
411
- function parseCookiesFromHeader(
412
- cookieHeader: string | null
413
- ): Record<string, string> {
414
- if (!cookieHeader) return {};
415
-
416
- const cookies: Record<string, string> = {};
417
- const pairs = cookieHeader.split(";");
418
-
419
- for (const pair of pairs) {
420
- const [name, ...rest] = pair.trim().split("=");
421
- if (name) {
422
- cookies[name] = decodeURIComponent(rest.join("="));
1221
+ export function wireRenderBarrier(
1222
+ ctx: RequestContext<any, any>,
1223
+ handleStore: HandleStore,
1224
+ ): void {
1225
+ // Reset the whole barrier family as OWN properties. No-op for a fresh
1226
+ // context; for the derived capture context this shadows the foreground's
1227
+ // resolved state so the capture runs its own barrier lifecycle. In
1228
+ // particular _treeHasStreaming must be recomputed for the CAPTURE's tree
1229
+ // (cache-lookup/segment-resolution only set it when undefined): an
1230
+ // inherited `true` made a capture-lane rendered() seal the capture's fresh
1231
+ // store at loader start and pair it with the foreground's segment order.
1232
+ ctx._renderBarrierSegmentOrder = undefined;
1233
+ ctx._renderBarrierWaiters = undefined;
1234
+ ctx._renderBarrierHandleSnapshot = undefined;
1235
+ ctx._renderBarrierGuardClosed = undefined;
1236
+ ctx._handlerLoaderDeps = undefined;
1237
+ ctx._treeHasStreaming = undefined;
1238
+
1239
+ // Lazy allocation: only create the Promise when a loader calls rendered().
1240
+ let barrierResolved = false;
1241
+ let resolveBarrier: (() => void) | undefined;
1242
+ ctx._resolveRenderBarrier = (
1243
+ segments: Array<{ type: string; id: string }>,
1244
+ ) => {
1245
+ if (barrierResolved) return;
1246
+ barrierResolved = true;
1247
+ const segOrder = segments
1248
+ .filter((s) => s.type !== "loader")
1249
+ .map((s) => s.id);
1250
+ ctx._renderBarrierSegmentOrder = segOrder;
1251
+
1252
+ const closeGuard = () => {
1253
+ ctx._renderBarrierWaiters = undefined;
1254
+ ctx._handlerLoaderDeps = undefined;
1255
+ ctx._renderBarrierGuardClosed = true;
1256
+ };
1257
+
1258
+ if (ctx._treeHasStreaming) {
1259
+ handleStore.settled.then(closeGuard);
1260
+ } else {
1261
+ ctx._renderBarrierHandleSnapshot = buildHandleSnapshot(
1262
+ handleStore,
1263
+ segOrder,
1264
+ );
1265
+ closeGuard();
1266
+ }
1267
+ if (resolveBarrier) resolveBarrier();
1268
+ };
1269
+ // defineProperty, not assignment: on a derived context the prototype's
1270
+ // _renderBarrier may already be a non-writable data property (the getter
1271
+ // pins it after first access), which would reject a plain assignment.
1272
+ Object.defineProperty(ctx, "_renderBarrier", {
1273
+ get() {
1274
+ const p = barrierResolved
1275
+ ? Promise.resolve()
1276
+ : new Promise<void>((resolve) => {
1277
+ resolveBarrier = resolve;
1278
+ });
1279
+ Object.defineProperty(ctx, "_renderBarrier", {
1280
+ value: p,
1281
+ writable: false,
1282
+ configurable: false,
1283
+ });
1284
+ return p;
1285
+ },
1286
+ configurable: true,
1287
+ });
1288
+ }
1289
+
1290
+ // Capture the Max-Age value so it can be parsed numerically. A leading zero
1291
+ // (Max-Age=05) is a non-zero lifetime, not a deletion; only a value that parses
1292
+ // to <= 0 marks a cookie for deletion. Pattern-matching a leading "0" misread
1293
+ // zero-prefixed values like 05 / 010 as deletions.
1294
+ const MAX_AGE_RE = /;\s*Max-Age\s*=\s*(-?\d+)/i;
1295
+
1296
+ function isCookieDeletion(header: string): boolean {
1297
+ const m = MAX_AGE_RE.exec(header);
1298
+ if (!m) return false;
1299
+ return Number(m[1]) <= 0;
1300
+ }
1301
+
1302
+ function parseResponseCookies(response: Response): Map<string, string | null> {
1303
+ const result = new Map<string, string | null>();
1304
+ const setCookies = response.headers.getSetCookie();
1305
+
1306
+ for (const header of setCookies) {
1307
+ const semiIdx = header.indexOf(";");
1308
+ const pair = semiIdx === -1 ? header : header.substring(0, semiIdx);
1309
+ const eqIdx = pair.indexOf("=");
1310
+ if (eqIdx === -1) continue;
1311
+
1312
+ let name: string;
1313
+ let value: string;
1314
+ try {
1315
+ name = decodeURIComponent(pair.substring(0, eqIdx).trim());
1316
+ value = decodeURIComponent(pair.substring(eqIdx + 1).trim());
1317
+ } catch {
1318
+ continue;
423
1319
  }
1320
+
1321
+ const isDeleted = isCookieDeletion(header);
1322
+ result.set(name, isDeleted ? null : value);
424
1323
  }
425
1324
 
426
- return cookies;
1325
+ return result;
427
1326
  }
428
1327
 
429
- /**
430
- * Serialize a cookie for Set-Cookie header
431
- */
432
- function serializeCookieValue(
1328
+ // Re-exported for unit tests and the existing import path. The implementation
1329
+ // lives in the dependency-free ./cookie-parse leaf so consumers (e.g. the host
1330
+ // dispatcher) can share it without pulling this module's request-context graph.
1331
+ export { parseCookiesFromHeader };
1332
+
1333
+ export function serializeCookieValue(
433
1334
  name: string,
434
1335
  value: string,
435
- options: CookieOptions = {}
1336
+ options: CookieOptions = {},
436
1337
  ): string {
437
1338
  let cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;
438
1339
 
@@ -456,20 +1357,12 @@ export interface CreateUseFunctionOptions<TEnv> {
456
1357
  getContext: () => RequestContext<TEnv>;
457
1358
  }
458
1359
 
459
- /**
460
- * Create the use() function for loader and handle composition.
461
- *
462
- * This is the unified implementation used by both RequestContext and HandlerContext.
463
- * - For loaders: executes and memoizes loader functions
464
- * - For handles: returns a push function to add handle data
465
- */
466
1360
  export function createUseFunction<TEnv>(
467
- options: CreateUseFunctionOptions<TEnv>
1361
+ options: CreateUseFunctionOptions<TEnv>,
468
1362
  ): RequestContext["use"] {
469
1363
  const { handleStore, loaderPromises, getContext } = options;
470
1364
 
471
1365
  return ((item: LoaderDefinition<any, any> | Handle<any, any>) => {
472
- // Handle case: return a push function
473
1366
  if (isHandle(item)) {
474
1367
  const handle = item;
475
1368
  const ctx = getContext();
@@ -478,31 +1371,28 @@ export function createUseFunction<TEnv>(
478
1371
  if (!segmentId) {
479
1372
  throw new Error(
480
1373
  `Handle "${handle.$$id}" used outside of handler context. ` +
481
- `Handles must be used within route/layout handlers.`
1374
+ `Handles must be used within route/layout handlers.`,
482
1375
  );
483
1376
  }
484
1377
 
485
- // Return a push function bound to this handle and segment
486
- return (dataOrFn: unknown | Promise<unknown> | (() => Promise<unknown>)) => {
487
- // If it's a function, call it immediately to get the promise
488
- const valueOrPromise = typeof dataOrFn === "function"
489
- ? (dataOrFn as () => Promise<unknown>)()
490
- : dataOrFn;
1378
+ return withDefer(
1379
+ (dataOrFn: unknown | Promise<unknown> | (() => Promise<unknown>)) => {
1380
+ const valueOrPromise =
1381
+ typeof dataOrFn === "function"
1382
+ ? (dataOrFn as () => Promise<unknown>)()
1383
+ : dataOrFn;
491
1384
 
492
- // Push directly - promises will be serialized by RSC and streamed
493
- handleStore.push(handle.$$id, segmentId, valueOrPromise);
494
- };
1385
+ handleStore.push(handle.$$id, segmentId, valueOrPromise);
1386
+ },
1387
+ );
495
1388
  }
496
1389
 
497
- // Loader case
498
1390
  const loader = item as LoaderDefinition<any, any>;
499
1391
 
500
- // Return cached promise if already started
501
1392
  if (loaderPromises.has(loader.$$id)) {
502
1393
  return loaderPromises.get(loader.$$id);
503
1394
  }
504
1395
 
505
- // Get loader function - either from loader object or fetchable registry
506
1396
  let loaderFn = loader.fn;
507
1397
  if (!loaderFn) {
508
1398
  const fetchable = getFetchableLoader(loader.$$id);
@@ -513,39 +1403,66 @@ export function createUseFunction<TEnv>(
513
1403
 
514
1404
  if (!loaderFn) {
515
1405
  throw new Error(
516
- `Loader "${loader.$$id}" has no function. This usually means the loader was defined without "use server" and the function was not included in the build.`
1406
+ `Loader "${loader.$$id}" has no function. This usually means the loader was defined without "use server" and the function was not included in the build.`,
517
1407
  );
518
1408
  }
519
1409
 
520
1410
  const ctx = getContext();
521
1411
 
522
- // Create loader context with recursive use() support
1412
+ // Build the typed ctx.search the same way the render path
1413
+ // (createHandlerContext) and the fetchable-loader path (loader-fetch.ts) do:
1414
+ // parse the route's search schema over the cleaned searchParams. The base
1415
+ // RequestContext carries no `search` field, so reading `(ctx as any).search`
1416
+ // here always yielded {} — dropping typed search for action/dispatch loaders.
1417
+ const searchSchema = ctx._routeName
1418
+ ? getSearchSchema(ctx._routeName)
1419
+ : undefined;
1420
+ const loaderSearch = searchSchema
1421
+ ? parseSearchParams(ctx.searchParams, searchSchema)
1422
+ : {};
1423
+
523
1424
  const loaderCtx: LoaderContext<Record<string, string | undefined>, TEnv> = {
524
1425
  params: ctx.params,
1426
+ routeParams: (ctx.params ?? {}) as Record<string, string>,
525
1427
  request: ctx.request,
526
1428
  searchParams: ctx.searchParams,
1429
+ search: loaderSearch,
527
1430
  pathname: ctx.pathname,
528
1431
  url: ctx.url,
1432
+ originalUrl: ctx.originalUrl,
529
1433
  env: ctx.env as any,
530
- var: ctx.var as any,
1434
+ waitUntil: ctx.waitUntil.bind(ctx),
1435
+ executionContext: ctx.executionContext,
531
1436
  get: ctx.get as any,
532
- use: <TDep, TDepParams = any>(
533
- dep: LoaderDefinition<TDep, TDepParams>
1437
+ use: (<TDep, TDepParams = any>(
1438
+ dep: LoaderDefinition<TDep, TDepParams>,
534
1439
  ): Promise<TDep> => {
535
- // Recursive call - will start dep loader if not already started
536
1440
  return ctx.use(dep);
537
- },
1441
+ }) as LoaderContext["use"],
538
1442
  method: "GET",
539
1443
  body: undefined,
1444
+ reverse: createReverseFunction(
1445
+ getGlobalRouteMap(),
1446
+ ctx._routeName,
1447
+ ctx.params as Record<string, string>,
1448
+ ctx._routeName ? isRouteRootScoped(ctx._routeName) : undefined,
1449
+ ),
1450
+ rendered: () => {
1451
+ throw new Error(
1452
+ `ctx.rendered() is only available in DSL loaders (registered via loader() in urls()). ` +
1453
+ `It cannot be used from request-context loaders or server actions.`,
1454
+ );
1455
+ },
540
1456
  };
541
1457
 
542
- // Start loader execution with tracking
543
- const doneLoader = track(`loader:${loader.$$id}`);
544
- const promise = Promise.resolve(loaderFn(loaderCtx)).finally(() => {
545
- doneLoader();
546
- });
1458
+ // Meter through the same unified phase API as the loader-resolution funnel
1459
+ // (observePhase), so a loader resolved via this base request-context ctx.use
1460
+ // co-emits the "loader:<id>" perf metric AND the "rango.loader" span — no
1461
+ // drift between the two ctx.use implementations.
1462
+ const promise = observePhase(PHASES.loader(loader.$$id), () =>
1463
+ Promise.resolve(loaderFn(loaderCtx)),
1464
+ );
547
1465
 
548
- // Memoize for subsequent calls
549
1466
  loaderPromises.set(loader.$$id, promise);
550
1467
 
551
1468
  return promise;