@rangojs/router 0.0.0-experimental.2 → 0.0.0-experimental.204030a9

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 (1195) hide show
  1. package/AGENTS.md +9 -0
  2. package/README.md +1037 -4
  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/{src/__mocks__/version.ts → dist/__mocks__/version.js} +1 -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 +1779 -0
  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/dist/browser/react/use-client-cache.js +39 -0
  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/dist/handles/index.js +6 -0
  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/dist/network-error-thrower.d.ts +17 -0
  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/theme/ThemeProvider.d.ts +20 -0
  712. package/dist/theme/ThemeProvider.d.ts.map +1 -0
  713. package/dist/theme/ThemeProvider.js +240 -0
  714. package/dist/theme/ThemeProvider.js.map +1 -0
  715. package/dist/theme/ThemeScript.d.ts +48 -0
  716. package/dist/theme/ThemeScript.d.ts.map +1 -0
  717. package/dist/theme/ThemeScript.js +13 -0
  718. package/dist/theme/ThemeScript.js.map +1 -0
  719. package/dist/theme/__tests__/theme.test.d.ts +2 -0
  720. package/dist/theme/__tests__/theme.test.d.ts.map +1 -0
  721. package/dist/theme/__tests__/theme.test.js +103 -0
  722. package/dist/theme/__tests__/theme.test.js.map +1 -0
  723. package/dist/theme/constants.d.ts +29 -0
  724. package/dist/theme/constants.d.ts.map +1 -0
  725. package/dist/theme/constants.js +48 -0
  726. package/dist/theme/constants.js.map +1 -0
  727. package/dist/theme/index.d.ts +31 -0
  728. package/dist/theme/index.d.ts.map +1 -0
  729. package/dist/theme/index.js +36 -0
  730. package/dist/theme/index.js.map +1 -0
  731. package/dist/theme/theme-context.d.ts +40 -0
  732. package/dist/theme/theme-context.d.ts.map +1 -0
  733. package/dist/theme/theme-context.js +60 -0
  734. package/dist/theme/theme-context.js.map +1 -0
  735. package/dist/theme/theme-script.d.ts +27 -0
  736. package/dist/theme/theme-script.d.ts.map +1 -0
  737. package/dist/theme/theme-script.js +147 -0
  738. package/dist/theme/theme-script.js.map +1 -0
  739. package/dist/theme/types.d.ts +163 -0
  740. package/dist/theme/types.d.ts.map +1 -0
  741. package/dist/theme/types.js +11 -0
  742. package/dist/theme/types.js.map +1 -0
  743. package/dist/theme/use-theme.d.ts +12 -0
  744. package/dist/theme/use-theme.d.ts.map +1 -0
  745. package/dist/theme/use-theme.js +40 -0
  746. package/dist/theme/use-theme.js.map +1 -0
  747. package/dist/types.d.ts +1479 -0
  748. package/dist/types.d.ts.map +1 -0
  749. package/dist/types.js +10 -0
  750. package/dist/types.js.map +1 -0
  751. package/dist/urls.d.ts +441 -0
  752. package/dist/urls.d.ts.map +1 -0
  753. package/dist/urls.gen.d.ts +8 -0
  754. package/dist/urls.gen.d.ts.map +1 -0
  755. package/dist/urls.gen.js +8 -0
  756. package/dist/urls.gen.js.map +1 -0
  757. package/dist/urls.js +443 -0
  758. package/dist/urls.js.map +1 -0
  759. package/dist/use-loader.d.ts +127 -0
  760. package/dist/use-loader.d.ts.map +1 -0
  761. package/dist/use-loader.js +237 -0
  762. package/dist/use-loader.js.map +1 -0
  763. package/dist/vite/__tests__/ast-handler-extract.test.d.ts +2 -0
  764. package/dist/vite/__tests__/ast-handler-extract.test.d.ts.map +1 -0
  765. package/dist/vite/__tests__/ast-handler-extract.test.js +294 -0
  766. package/dist/vite/__tests__/ast-handler-extract.test.js.map +1 -0
  767. package/dist/vite/__tests__/expose-id-utils.test.d.ts +2 -0
  768. package/dist/vite/__tests__/expose-id-utils.test.d.ts.map +1 -0
  769. package/dist/vite/__tests__/expose-id-utils.test.js +224 -0
  770. package/dist/vite/__tests__/expose-id-utils.test.js.map +1 -0
  771. package/dist/vite/__tests__/expose-internal-ids.test.d.ts +2 -0
  772. package/dist/vite/__tests__/expose-internal-ids.test.d.ts.map +1 -0
  773. package/dist/vite/__tests__/expose-internal-ids.test.js +647 -0
  774. package/dist/vite/__tests__/expose-internal-ids.test.js.map +1 -0
  775. package/dist/vite/__tests__/expose-router-id.test.d.ts +2 -0
  776. package/dist/vite/__tests__/expose-router-id.test.d.ts.map +1 -0
  777. package/dist/vite/__tests__/expose-router-id.test.js +39 -0
  778. package/dist/vite/__tests__/expose-router-id.test.js.map +1 -0
  779. package/dist/vite/ast-handler-extract.d.ts +49 -0
  780. package/dist/vite/ast-handler-extract.d.ts.map +1 -0
  781. package/dist/vite/ast-handler-extract.js +249 -0
  782. package/dist/vite/ast-handler-extract.js.map +1 -0
  783. package/dist/vite/expose-action-id.d.ts +19 -0
  784. package/dist/vite/expose-action-id.d.ts.map +1 -0
  785. package/dist/vite/expose-action-id.js +250 -0
  786. package/dist/vite/expose-action-id.js.map +1 -0
  787. package/dist/vite/expose-id-utils.d.ts +69 -0
  788. package/dist/vite/expose-id-utils.d.ts.map +1 -0
  789. package/dist/vite/expose-id-utils.js +289 -0
  790. package/dist/vite/expose-id-utils.js.map +1 -0
  791. package/dist/vite/expose-internal-ids.d.ts +22 -0
  792. package/dist/vite/expose-internal-ids.d.ts.map +1 -0
  793. package/dist/vite/expose-internal-ids.js +886 -0
  794. package/dist/vite/expose-internal-ids.js.map +1 -0
  795. package/dist/vite/index.d.ts +149 -0
  796. package/dist/vite/index.d.ts.map +1 -0
  797. package/dist/vite/index.js +6440 -809
  798. package/dist/vite/index.js.bak +5448 -0
  799. package/dist/vite/index.js.map +1 -0
  800. package/dist/vite/index.named-routes.gen.ts +103 -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} +18 -17
  809. package/dist/vite/virtual-entries.js.map +1 -0
  810. package/package.json +140 -57
  811. package/skills/breadcrumbs/SKILL.md +252 -0
  812. package/skills/bundle-analysis/SKILL.md +159 -0
  813. package/skills/cache-guide/SKILL.md +484 -0
  814. package/skills/caching/SKILL.md +276 -226
  815. package/skills/composability/SKILL.md +197 -0
  816. package/skills/debug-manifest/SKILL.md +112 -0
  817. package/skills/document-cache/SKILL.md +106 -53
  818. package/skills/fonts/SKILL.md +167 -0
  819. package/skills/handler-use/SKILL.md +364 -0
  820. package/skills/hooks/SKILL.md +621 -67
  821. package/skills/host-router/SKILL.md +243 -0
  822. package/skills/i18n/SKILL.md +276 -0
  823. package/skills/intercept/SKILL.md +265 -202
  824. package/skills/layout/SKILL.md +261 -146
  825. package/skills/links/SKILL.md +471 -0
  826. package/skills/loader/SKILL.md +701 -250
  827. package/skills/middleware/SKILL.md +254 -320
  828. package/skills/migrate-nextjs/SKILL.md +562 -0
  829. package/skills/migrate-react-router/SKILL.md +769 -0
  830. package/skills/mime-routes/SKILL.md +155 -0
  831. package/skills/observability/SKILL.md +137 -0
  832. package/skills/parallel/SKILL.md +399 -158
  833. package/skills/prerender/SKILL.md +666 -0
  834. package/skills/rango/SKILL.md +338 -0
  835. package/skills/react-compiler/SKILL.md +168 -0
  836. package/skills/response-routes/SKILL.md +468 -0
  837. package/skills/route/SKILL.md +417 -89
  838. package/skills/router-setup/SKILL.md +389 -268
  839. package/skills/server-actions/SKILL.md +751 -0
  840. package/skills/streams-and-websockets/SKILL.md +283 -0
  841. package/skills/tailwind/SKILL.md +129 -0
  842. package/skills/testing/SKILL.md +549 -0
  843. package/skills/theme/SKILL.md +36 -11
  844. package/skills/typesafety/SKILL.md +747 -174
  845. package/skills/use-cache/SKILL.md +353 -0
  846. package/skills/view-transitions/SKILL.md +294 -0
  847. package/src/__augment-tests__/augment.ts +81 -0
  848. package/src/__augment-tests__/augmented.check.ts +117 -0
  849. package/src/__internal.ts +273 -0
  850. package/src/bin/rango.ts +321 -0
  851. package/src/browser/action-coordinator.ts +114 -0
  852. package/src/browser/app-shell.ts +52 -0
  853. package/src/browser/app-version.ts +14 -0
  854. package/src/browser/event-controller.ts +172 -128
  855. package/src/browser/history-state.ts +101 -0
  856. package/src/browser/index.ts +3 -3
  857. package/src/browser/intercept-utils.ts +52 -0
  858. package/src/browser/link-interceptor.ts +24 -4
  859. package/src/browser/logging.ts +55 -0
  860. package/src/browser/merge-segment-loaders.ts +20 -12
  861. package/src/browser/navigation-bridge.ts +390 -557
  862. package/src/browser/navigation-client.ts +228 -70
  863. package/src/browser/navigation-store.ts +104 -63
  864. package/src/browser/navigation-transaction.ts +279 -0
  865. package/src/browser/network-error-handler.ts +61 -0
  866. package/src/browser/partial-update.ts +397 -303
  867. package/src/browser/prefetch/cache.ts +314 -0
  868. package/src/browser/prefetch/fetch.ts +282 -0
  869. package/src/browser/prefetch/observer.ts +65 -0
  870. package/src/browser/prefetch/policy.ts +48 -0
  871. package/src/browser/prefetch/queue.ts +191 -0
  872. package/src/browser/prefetch/resource-ready.ts +77 -0
  873. package/src/browser/rango-state.ts +152 -0
  874. package/src/browser/react/Link.tsx +258 -74
  875. package/src/browser/react/NavigationProvider.tsx +237 -49
  876. package/src/browser/react/context.ts +11 -0
  877. package/src/browser/react/filter-segment-order.ts +55 -0
  878. package/src/browser/react/index.ts +15 -12
  879. package/src/browser/react/location-state-shared.ts +269 -56
  880. package/src/browser/react/location-state.ts +90 -19
  881. package/src/browser/react/mount-context.ts +37 -0
  882. package/src/browser/react/nonce-context.ts +23 -0
  883. package/src/browser/react/shallow-equal.ts +27 -0
  884. package/src/browser/react/use-action.ts +29 -51
  885. package/src/browser/react/use-client-cache.ts +5 -3
  886. package/src/browser/react/use-handle.ts +41 -98
  887. package/src/browser/react/use-href.tsx +20 -188
  888. package/src/browser/react/use-link-status.ts +6 -5
  889. package/src/browser/react/use-mount.ts +31 -0
  890. package/src/browser/react/use-navigation.ts +49 -80
  891. package/src/browser/react/use-params.ts +77 -0
  892. package/src/browser/react/use-pathname.ts +47 -0
  893. package/src/browser/react/use-reverse.ts +106 -0
  894. package/src/browser/react/use-router.ts +96 -0
  895. package/src/browser/react/use-search-params.ts +56 -0
  896. package/src/browser/react/use-segments.ts +85 -99
  897. package/src/browser/response-adapter.ts +98 -0
  898. package/src/browser/rsc-router.tsx +273 -78
  899. package/src/browser/scroll-restoration.ts +132 -49
  900. package/src/browser/segment-reconciler.ts +243 -0
  901. package/src/browser/segment-structure-assert.ts +83 -0
  902. package/src/browser/server-action-bridge.ts +504 -589
  903. package/src/browser/shallow.ts +6 -1
  904. package/src/browser/types.ts +184 -58
  905. package/src/browser/validate-redirect-origin.ts +29 -0
  906. package/src/build/collect-fallback-refs.ts +107 -0
  907. package/src/build/generate-manifest.ts +463 -0
  908. package/src/build/generate-route-types.ts +41 -0
  909. package/src/build/index.ts +37 -0
  910. package/src/build/route-trie.ts +292 -0
  911. package/src/build/route-types/ast-helpers.ts +25 -0
  912. package/src/build/route-types/ast-route-extraction.ts +98 -0
  913. package/src/build/route-types/codegen.ts +102 -0
  914. package/src/build/route-types/include-resolution.ts +418 -0
  915. package/src/build/route-types/param-extraction.ts +48 -0
  916. package/src/build/route-types/per-module-writer.ts +131 -0
  917. package/src/build/route-types/router-processing.ts +659 -0
  918. package/src/build/route-types/scan-filter.ts +85 -0
  919. package/src/build/route-types/source-scan.ts +118 -0
  920. package/src/build/runtime-discovery.ts +220 -0
  921. package/src/cache/background-task.ts +34 -0
  922. package/src/cache/cache-key-utils.ts +44 -0
  923. package/src/cache/cache-policy.ts +125 -0
  924. package/src/cache/cache-runtime.ts +342 -0
  925. package/src/cache/cache-scope.ts +150 -306
  926. package/src/cache/cf/cf-cache-store.ts +619 -24
  927. package/src/cache/cf/index.ts +13 -3
  928. package/src/cache/document-cache.ts +116 -77
  929. package/src/cache/handle-capture.ts +81 -0
  930. package/src/cache/handle-snapshot.ts +41 -0
  931. package/src/cache/index.ts +1 -15
  932. package/src/cache/memory-segment-store.ts +191 -13
  933. package/src/cache/profile-registry.ts +73 -0
  934. package/src/cache/read-through-swr.ts +134 -0
  935. package/src/cache/segment-codec.ts +256 -0
  936. package/src/cache/taint.ts +153 -0
  937. package/src/cache/types.ts +76 -121
  938. package/src/client.rsc.tsx +15 -15
  939. package/src/client.tsx +145 -309
  940. package/src/component-utils.ts +4 -4
  941. package/src/components/DefaultDocument.tsx +6 -2
  942. package/src/context-var.ts +156 -0
  943. package/src/debug.ts +243 -0
  944. package/src/decode-loader-results.ts +36 -0
  945. package/src/errors.ts +138 -3
  946. package/src/handle.ts +90 -22
  947. package/src/handles/MetaTags.tsx +76 -23
  948. package/src/handles/breadcrumbs.ts +66 -0
  949. package/src/handles/index.ts +1 -0
  950. package/src/handles/meta.ts +32 -15
  951. package/src/host/cookie-handler.ts +165 -0
  952. package/src/host/errors.ts +97 -0
  953. package/src/host/index.ts +53 -0
  954. package/src/host/pattern-matcher.ts +214 -0
  955. package/src/host/router.ts +424 -0
  956. package/src/host/testing.ts +79 -0
  957. package/src/host/types.ts +175 -0
  958. package/src/host/utils.ts +25 -0
  959. package/src/href-client.ts +263 -49
  960. package/src/index.rsc.ts +190 -29
  961. package/src/index.ts +278 -38
  962. package/src/internal-debug.ts +11 -0
  963. package/src/loader-store.ts +500 -0
  964. package/src/loader.rsc.ts +24 -142
  965. package/src/loader.ts +21 -11
  966. package/src/missing-id-error.ts +68 -0
  967. package/src/network-error-thrower.tsx +3 -1
  968. package/src/outlet-context.ts +1 -1
  969. package/src/outlet-provider.tsx +45 -0
  970. package/src/prerender/param-hash.ts +37 -0
  971. package/src/prerender/store.ts +186 -0
  972. package/src/prerender.ts +524 -0
  973. package/src/response-utils.ts +37 -0
  974. package/src/reverse.ts +380 -0
  975. package/src/root-error-boundary.tsx +41 -29
  976. package/src/route-content-wrapper.tsx +15 -39
  977. package/src/route-definition/dsl-helpers.ts +1109 -0
  978. package/src/route-definition/helper-factories.ts +90 -0
  979. package/src/route-definition/helpers-types.ts +506 -0
  980. package/src/route-definition/index.ts +55 -0
  981. package/src/route-definition/redirect.ts +101 -0
  982. package/src/route-definition/resolve-handler-use.ts +155 -0
  983. package/src/route-definition/use-item-types.ts +32 -0
  984. package/src/route-definition.ts +1 -1371
  985. package/src/route-map-builder.ts +247 -112
  986. package/src/route-name.ts +53 -0
  987. package/src/route-types.ts +99 -42
  988. package/src/router/basename.ts +14 -0
  989. package/src/router/content-negotiation.ts +228 -0
  990. package/src/router/debug-manifest.ts +72 -0
  991. package/src/router/error-handling.ts +10 -10
  992. package/src/router/find-match.ts +160 -0
  993. package/src/router/handler-context.ts +420 -88
  994. package/src/router/intercept-resolution.ts +388 -0
  995. package/src/router/lazy-includes.ts +237 -0
  996. package/src/router/loader-resolution.ts +374 -128
  997. package/src/router/logging.ts +251 -0
  998. package/src/router/manifest.ts +187 -43
  999. package/src/router/match-api.ts +556 -0
  1000. package/src/router/match-context.ts +6 -4
  1001. package/src/router/match-handlers.ts +483 -0
  1002. package/src/router/match-middleware/background-revalidation.ts +108 -93
  1003. package/src/router/match-middleware/cache-lookup.ts +413 -10
  1004. package/src/router/match-middleware/cache-store.ts +99 -26
  1005. package/src/router/match-middleware/intercept-resolution.ts +57 -17
  1006. package/src/router/match-middleware/segment-resolution.ts +80 -6
  1007. package/src/router/match-pipelines.ts +10 -45
  1008. package/src/router/match-result.ts +156 -36
  1009. package/src/router/metrics.ts +241 -16
  1010. package/src/router/middleware-cookies.ts +55 -0
  1011. package/src/router/middleware-types.ts +209 -0
  1012. package/src/router/middleware.ts +359 -346
  1013. package/src/router/navigation-snapshot.ts +182 -0
  1014. package/src/router/pattern-matching.ts +416 -41
  1015. package/src/router/prerender-match.ts +502 -0
  1016. package/src/router/preview-match.ts +100 -0
  1017. package/src/router/request-classification.ts +286 -0
  1018. package/src/router/revalidation.ts +195 -40
  1019. package/src/router/route-snapshot.ts +245 -0
  1020. package/src/router/router-context.ts +45 -23
  1021. package/src/router/router-interfaces.ts +501 -0
  1022. package/src/router/router-options.ts +657 -0
  1023. package/src/router/router-registry.ts +21 -0
  1024. package/src/router/segment-resolution/fresh.ts +769 -0
  1025. package/src/router/segment-resolution/helpers.ts +268 -0
  1026. package/src/router/segment-resolution/loader-cache.ts +199 -0
  1027. package/src/router/segment-resolution/revalidation.ts +1420 -0
  1028. package/src/router/segment-resolution/static-store.ts +67 -0
  1029. package/src/router/segment-resolution/view-transition-default.ts +36 -0
  1030. package/src/router/segment-resolution.ts +21 -0
  1031. package/src/router/segment-wrappers.ts +291 -0
  1032. package/src/router/substitute-pattern-params.ts +56 -0
  1033. package/src/router/telemetry-otel.ts +299 -0
  1034. package/src/router/telemetry.ts +399 -0
  1035. package/src/router/timeout.ts +148 -0
  1036. package/src/router/trie-matching.ts +244 -0
  1037. package/src/router/types.ts +87 -4
  1038. package/src/router/url-params.ts +49 -0
  1039. package/src/router.ts +768 -3574
  1040. package/src/rsc/handler-context.ts +45 -0
  1041. package/src/rsc/handler.ts +894 -806
  1042. package/src/rsc/helpers.ts +201 -19
  1043. package/src/rsc/index.ts +5 -25
  1044. package/src/rsc/loader-fetch.ts +229 -0
  1045. package/src/rsc/manifest-init.ts +90 -0
  1046. package/src/rsc/nonce.ts +14 -0
  1047. package/src/rsc/origin-guard.ts +159 -0
  1048. package/src/rsc/progressive-enhancement.ts +395 -0
  1049. package/src/rsc/response-error.ts +37 -0
  1050. package/src/rsc/response-route-handler.ts +340 -0
  1051. package/src/rsc/rsc-rendering.ts +230 -0
  1052. package/src/rsc/runtime-warnings.ts +41 -0
  1053. package/src/rsc/server-action.ts +336 -0
  1054. package/src/rsc/ssr-setup.ts +144 -0
  1055. package/src/rsc/types.ts +54 -14
  1056. package/src/search-params.ts +230 -0
  1057. package/src/segment-content-promise.ts +67 -0
  1058. package/src/segment-loader-promise.ts +122 -0
  1059. package/src/segment-system.tsx +265 -115
  1060. package/src/serialize.ts +243 -0
  1061. package/src/server/context.ts +480 -90
  1062. package/src/server/cookie-store.ts +214 -0
  1063. package/src/server/fetchable-loader-store.ts +37 -0
  1064. package/src/server/handle-store.ts +117 -20
  1065. package/src/server/loader-registry.ts +24 -64
  1066. package/src/server/request-context.ts +613 -109
  1067. package/src/server.ts +36 -131
  1068. package/src/ssr/index.tsx +164 -25
  1069. package/src/static-handler.ts +126 -0
  1070. package/src/testing/cache-status.ts +166 -0
  1071. package/src/testing/collect-handle.ts +63 -0
  1072. package/src/testing/dispatch.ts +440 -0
  1073. package/src/testing/dom.entry.ts +22 -0
  1074. package/src/testing/e2e/fixture.ts +154 -0
  1075. package/src/testing/e2e/index.ts +149 -0
  1076. package/src/testing/e2e/matchers.ts +51 -0
  1077. package/src/testing/e2e/page-helpers.ts +272 -0
  1078. package/src/testing/e2e/parity.ts +306 -0
  1079. package/src/testing/e2e/server.ts +183 -0
  1080. package/src/testing/flight-matchers.ts +104 -0
  1081. package/src/testing/flight-runtime.d.ts +21 -0
  1082. package/src/testing/flight.entry.ts +22 -0
  1083. package/src/testing/flight.ts +182 -0
  1084. package/src/testing/generated-routes.ts +223 -0
  1085. package/src/testing/index.ts +98 -0
  1086. package/src/testing/internal/context.ts +151 -0
  1087. package/src/testing/render-route.tsx +536 -0
  1088. package/src/testing/run-loader.ts +296 -0
  1089. package/src/testing/run-middleware.ts +170 -0
  1090. package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
  1091. package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
  1092. package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
  1093. package/src/testing/vitest-stubs/version.ts +5 -0
  1094. package/src/testing/vitest.ts +112 -0
  1095. package/src/theme/ThemeProvider.tsx +21 -15
  1096. package/src/theme/ThemeScript.tsx +5 -5
  1097. package/src/theme/constants.ts +11 -4
  1098. package/src/theme/index.ts +4 -14
  1099. package/src/theme/theme-context.ts +5 -31
  1100. package/src/theme/theme-script.ts +21 -18
  1101. package/src/theme/types.ts +1 -1
  1102. package/src/types/boundaries.ts +158 -0
  1103. package/src/types/cache-types.ts +198 -0
  1104. package/src/types/error-types.ts +192 -0
  1105. package/src/types/global-namespace.ts +113 -0
  1106. package/src/types/handler-context.ts +809 -0
  1107. package/src/types/index.ts +89 -0
  1108. package/src/types/loader-types.ts +209 -0
  1109. package/src/types/request-scope.ts +126 -0
  1110. package/src/types/route-config.ts +170 -0
  1111. package/src/types/route-entry.ts +120 -0
  1112. package/src/types/segments.ts +184 -0
  1113. package/src/types.ts +1 -1561
  1114. package/src/urls/include-helper.ts +164 -0
  1115. package/src/urls/index.ts +50 -0
  1116. package/src/urls/path-helper-types.ts +380 -0
  1117. package/src/urls/path-helper.ts +329 -0
  1118. package/src/urls/pattern-types.ts +124 -0
  1119. package/src/urls/response-types.ts +109 -0
  1120. package/src/urls/type-extraction.ts +282 -0
  1121. package/src/urls/urls-function.ts +94 -0
  1122. package/src/urls.ts +1 -726
  1123. package/src/use-loader.tsx +559 -108
  1124. package/src/vite/debug.ts +185 -0
  1125. package/src/vite/discovery/bundle-postprocess.ts +181 -0
  1126. package/src/vite/discovery/discover-routers.ts +398 -0
  1127. package/src/vite/discovery/discovery-errors.ts +194 -0
  1128. package/src/vite/discovery/gate-state.ts +171 -0
  1129. package/src/vite/discovery/prerender-collection.ts +480 -0
  1130. package/src/vite/discovery/route-types-writer.ts +214 -0
  1131. package/src/vite/discovery/self-gen-tracking.ts +73 -0
  1132. package/src/vite/discovery/state.ts +150 -0
  1133. package/src/vite/discovery/virtual-module-codegen.ts +193 -0
  1134. package/src/vite/index.ts +20 -785
  1135. package/src/vite/plugin-types.ts +170 -0
  1136. package/src/vite/plugins/cjs-to-esm.ts +94 -0
  1137. package/src/vite/plugins/client-ref-dedup.ts +131 -0
  1138. package/src/vite/plugins/client-ref-hashing.ts +128 -0
  1139. package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
  1140. package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  1141. package/src/vite/plugins/cloudflare-protocol-stub.ts +214 -0
  1142. package/src/vite/{expose-action-id.ts → plugins/expose-action-id.ts} +109 -66
  1143. package/src/vite/plugins/expose-id-utils.ts +303 -0
  1144. package/src/vite/plugins/expose-ids/export-analysis.ts +376 -0
  1145. package/src/vite/plugins/expose-ids/handler-transform.ts +156 -0
  1146. package/src/vite/plugins/expose-ids/loader-transform.ts +72 -0
  1147. package/src/vite/plugins/expose-ids/router-transform.ts +127 -0
  1148. package/src/vite/plugins/expose-ids/types.ts +45 -0
  1149. package/src/vite/plugins/expose-internal-ids.ts +796 -0
  1150. package/src/vite/plugins/performance-tracks.ts +92 -0
  1151. package/src/vite/plugins/refresh-cmd.ts +127 -0
  1152. package/src/vite/plugins/use-cache-transform.ts +338 -0
  1153. package/src/vite/plugins/version-injector.ts +99 -0
  1154. package/src/vite/plugins/version-plugin.ts +323 -0
  1155. package/src/vite/plugins/virtual-entries.ts +123 -0
  1156. package/src/vite/plugins/virtual-stub-plugin.ts +29 -0
  1157. package/src/vite/rango.ts +549 -0
  1158. package/src/vite/router-discovery.ts +1568 -0
  1159. package/src/vite/utils/ast-handler-extract.ts +517 -0
  1160. package/src/vite/utils/banner.ts +36 -0
  1161. package/src/vite/utils/bundle-analysis.ts +139 -0
  1162. package/src/vite/utils/client-chunks.ts +190 -0
  1163. package/src/vite/utils/forward-user-plugins.ts +193 -0
  1164. package/src/vite/utils/manifest-utils.ts +86 -0
  1165. package/src/vite/utils/package-resolution.ts +161 -0
  1166. package/src/vite/utils/prerender-utils.ts +222 -0
  1167. package/src/vite/utils/shared-utils.ts +251 -0
  1168. package/CLAUDE.md +0 -7
  1169. package/src/__tests__/component-utils.test.ts +0 -76
  1170. package/src/__tests__/route-definition.test.ts +0 -63
  1171. package/src/__tests__/urls.test.tsx +0 -436
  1172. package/src/browser/lru-cache.ts +0 -69
  1173. package/src/browser/request-controller.ts +0 -164
  1174. package/src/cache/__tests__/document-cache.test.ts +0 -522
  1175. package/src/cache/__tests__/memory-segment-store.test.ts +0 -487
  1176. package/src/cache/__tests__/memory-store.test.ts +0 -484
  1177. package/src/cache/cf/__tests__/cf-cache-store.test.ts +0 -428
  1178. package/src/cache/memory-store.ts +0 -253
  1179. package/src/href.ts +0 -177
  1180. package/src/route-utils.ts +0 -89
  1181. package/src/router/__tests__/match-context.test.ts +0 -104
  1182. package/src/router/__tests__/match-pipelines.test.ts +0 -537
  1183. package/src/router/__tests__/match-result.test.ts +0 -566
  1184. package/src/router/__tests__/on-error.test.ts +0 -935
  1185. package/src/router/__tests__/pattern-matching.test.ts +0 -577
  1186. package/src/router/middleware.test.ts +0 -1355
  1187. package/src/rsc/__tests__/helpers.test.ts +0 -175
  1188. package/src/server/__tests__/request-context.test.ts +0 -171
  1189. package/src/ssr/__tests__/ssr-handler.test.tsx +0 -188
  1190. package/src/theme/__tests__/theme.test.ts +0 -120
  1191. package/src/vite/__tests__/expose-loader-id.test.ts +0 -117
  1192. package/src/vite/expose-handle-id.ts +0 -209
  1193. package/src/vite/expose-loader-id.ts +0 -357
  1194. package/src/vite/expose-location-state-id.ts +0 -177
  1195. /package/src/vite/{version.d.ts → plugins/version.d.ts} +0 -0
@@ -1,5 +1,5 @@
1
1
  /// <reference types="@vitejs/plugin-rsc/types" />
2
- /// <reference path="../vite/version.d.ts" />
2
+ /// <reference path="../vite/plugins/version.d.ts" />
3
3
  /**
4
4
  * RSC Request Handler
5
5
  *
@@ -8,40 +8,108 @@
8
8
  */
9
9
 
10
10
  import { createElement } from "react";
11
- import { renderSegments } from "../segment-system.js";
12
- import { RouteNotFoundError } from "../errors.js";
13
- import { getLoaderLazy } from "../server/loader-registry.js";
14
- import {
15
- matchMiddleware,
16
- executeMiddleware,
17
- executeLoaderMiddleware,
18
- } from "../router/middleware.js";
11
+ import { isRouteNotFoundError } from "../errors.js";
12
+ import { matchMiddleware, executeMiddleware } from "../router/middleware.js";
19
13
  import {
20
14
  runWithRequestContext,
21
15
  setRequestContextParams,
22
16
  requireRequestContext,
17
+ getRequestContext,
18
+ _getRequestContext,
23
19
  createRequestContext,
24
- type ExecutionContext,
25
20
  } from "../server/request-context.js";
26
21
  import * as rscDeps from "@vitejs/plugin-rsc/rsc";
27
-
28
22
  import type {
29
23
  RscPayload,
30
- ReactFormState,
31
24
  CreateRSCHandlerOptions,
25
+ LoadSSRModule,
26
+ SSRModule,
32
27
  } from "./types.js";
33
- import { hasBodyContent, createResponseWithMergedHeaders } from "./helpers.js";
34
- import { generateNonce } from "./nonce.js";
28
+ import {
29
+ createResponseWithMergedHeaders,
30
+ finalizeResponse,
31
+ interceptRedirectForPartial,
32
+ buildRouteMiddlewareEntries,
33
+ } from "./helpers.js";
34
+ import { isWebSocketUpgradeResponse } from "../response-utils.js";
35
+ import {
36
+ handleResponseRoute,
37
+ type ResponseRouteMatch,
38
+ } from "./response-route-handler.js";
39
+ import { generateNonce, nonce as nonceToken } from "./nonce.js";
35
40
  import { VERSION } from "@rangojs/router:version";
36
41
  import type { ErrorPhase } from "../types.js";
42
+ import type { RouterRequestInput } from "../router/router-interfaces.js";
37
43
  import { invokeOnError } from "../router/error-handling.js";
44
+ import {
45
+ createReverseFunction,
46
+ stripInternalParams,
47
+ } from "../router/handler-context.js";
48
+ import { getRouterContext } from "../router/router-context.js";
49
+ import { resolveSink, safeEmit } from "../router/telemetry.js";
50
+ import { contextSet } from "../context-var.js";
51
+ import {
52
+ hasCachedManifest,
53
+ getRouteTrie,
54
+ getPrecomputedEntries,
55
+ waitForManifestReady,
56
+ getRouterManifest,
57
+ getRouterTrie,
58
+ } from "../route-map-builder.js";
59
+ import type { HandlerContext } from "./handler-context.js";
60
+ import type { SegmentCacheStore } from "../cache/types.js";
61
+ import { buildRouterTrieFromUrlpatterns } from "./manifest-init.js";
62
+ import { handleProgressiveEnhancement } from "./progressive-enhancement.js";
63
+ import {
64
+ executeServerAction,
65
+ revalidateAfterAction,
66
+ type ActionContinuation,
67
+ } from "./server-action.js";
68
+ import { handleLoaderFetch } from "./loader-fetch.js";
69
+ import {
70
+ checkRequestOrigin,
71
+ ORIGIN_CHECK_PHASE_BY_MODE,
72
+ } from "./origin-guard.js";
73
+ import { handleRscRendering } from "./rsc-rendering.js";
74
+ import {
75
+ withTimeout,
76
+ RouterTimeoutError,
77
+ createDefaultTimeoutResponse,
78
+ type TimeoutPhase,
79
+ } from "../router/timeout.js";
80
+ import {
81
+ createMetricsStore,
82
+ appendMetric,
83
+ buildMetricsTiming,
84
+ } from "../router/metrics.js";
85
+ import {
86
+ startSSRSetup,
87
+ getSSRSetup,
88
+ mayNeedSSR,
89
+ isRscRequest,
90
+ SSR_SETUP_VAR,
91
+ } from "./ssr-setup.js";
92
+ import {
93
+ classifyRequest,
94
+ type RequestPlan,
95
+ type ExecutableRequestPlan,
96
+ } from "../router/request-classification.js";
38
97
 
39
98
  /**
40
99
  * Create an RSC request handler.
41
100
  *
101
+ * **Recommended:** Use `router.createHandler()` instead for simpler setup:
102
+ * ```tsx
103
+ * const router = createRouter({ document, urls, nonce: () => true });
104
+ * export const fetch = router.createHandler();
105
+ * ```
106
+ *
107
+ * This function is still useful for advanced cases like per-request cache
108
+ * configuration (e.g., Cloudflare Workers with ExecutionContext).
109
+ *
42
110
  * @example Basic usage (deps and loadSSRModule have sensible defaults)
43
111
  * ```tsx
44
- * import { createRSCHandler } from "rsc-router/rsc";
112
+ * import { createRSCHandler } from "@rangojs/router/rsc";
45
113
  * import { router } from "./router.js";
46
114
  *
47
115
  * export default createRSCHandler({ router });
@@ -49,7 +117,7 @@ import { invokeOnError } from "../router/error-handling.js";
49
117
  *
50
118
  * @example With custom deps (advanced)
51
119
  * ```tsx
52
- * import { createRSCHandler } from "rsc-router/rsc";
120
+ * import { createRSCHandler } from "@rangojs/router/rsc";
53
121
  * import * as rsc from "@vitejs/plugin-rsc/rsc";
54
122
  * import { router } from "./router.js";
55
123
  *
@@ -66,9 +134,6 @@ export function createRSCHandler<
66
134
  >(options: CreateRSCHandlerOptions<TEnv, TRoutes>) {
67
135
  const { router, version = VERSION, nonce: nonceProvider } = options;
68
136
 
69
- // Get the route map for useHref() - converts route names to URL patterns
70
- const routeMap = router.routeMap as Record<string, string>;
71
-
72
137
  // Use provided deps or default to @vitejs/plugin-rsc/rsc exports
73
138
  const deps = options.deps ?? rscDeps;
74
139
  const {
@@ -80,75 +145,320 @@ export function createRSCHandler<
80
145
  decodeFormState,
81
146
  } = deps;
82
147
 
83
- // Use provided loadSSRModule or default to vite RSC module loader
84
- const loadSSRModule =
148
+ // Use provided loadSSRModule or default to vite RSC module loader.
149
+ // In production the SSR module is stable across requests, so memoize
150
+ // the dynamic import to avoid repeated module resolution overhead.
151
+ // In dev mode Vite may hot-reload the module, so skip memoization.
152
+ const rawLoadSSRModule: LoadSSRModule =
85
153
  options.loadSSRModule ??
86
154
  (() => import.meta.viteRsc.loadModule("ssr", "index"));
155
+ let _ssrModulePromise: Promise<SSRModule> | undefined;
156
+ const loadSSRModule: LoadSSRModule =
157
+ process.env.NODE_ENV === "production"
158
+ ? () =>
159
+ (_ssrModulePromise ??= rawLoadSSRModule().catch((err) => {
160
+ _ssrModulePromise = undefined;
161
+ throw err;
162
+ }))
163
+ : rawLoadSSRModule;
87
164
 
88
165
  /**
89
- * Wrapper for invokeOnError that binds the router's onError callback.
90
- * Uses the shared utility from router/error-handling.ts for consistent behavior.
166
+ * Per-request error reporter that deduplicates via the ALS request context.
167
+ *
168
+ * Uses the same _reportedErrors WeakSet as the router layer so errors
169
+ * that propagate across layers are only reported once per request.
91
170
  */
92
171
  function callOnError(
93
172
  error: unknown,
94
173
  phase: ErrorPhase,
95
174
  context: Parameters<typeof invokeOnError<TEnv>>[3],
96
175
  ): void {
176
+ // Guard: abort signal handlers fire asynchronously outside the ALS
177
+ // request scope, so the context may be gone. Skip dedup in that
178
+ // case — the error is from a cancelled stream, not a real failure.
179
+ const reqCtx = _getRequestContext();
180
+ if (error != null && typeof error === "object" && reqCtx) {
181
+ if (reqCtx._reportedErrors.has(error)) return;
182
+ reqCtx._reportedErrors.add(error);
183
+ }
97
184
  invokeOnError(router.onError, error, phase, context, "RSC");
98
185
  }
99
186
 
100
- return async function handler(
187
+ function getRequiredRouteMap(): Record<string, string> {
188
+ const routeMap = getRouterManifest(router.id);
189
+ if (!routeMap) {
190
+ throw new Error(
191
+ `Route manifest for router "${router.id}" is not available.`,
192
+ );
193
+ }
194
+ return routeMap;
195
+ }
196
+
197
+ /**
198
+ * Handle a timeout by reporting the error, emitting telemetry,
199
+ * and returning either the custom onTimeout response or a default 504.
200
+ */
201
+ async function handleTimeoutResponse(
101
202
  request: Request,
102
- env: TEnv & { ctx?: ExecutionContext } = {} as TEnv & {
103
- ctx?: ExecutionContext;
203
+ env: TEnv,
204
+ url: URL,
205
+ phase: TimeoutPhase,
206
+ durationMs: number,
207
+ routeKey?: string,
208
+ actionId?: string,
209
+ ): Promise<Response> {
210
+ const timeoutError = new RouterTimeoutError(phase, durationMs);
211
+
212
+ callOnError(timeoutError, phase === "action" ? "action" : "handler", {
213
+ request,
214
+ url,
215
+ env,
216
+ routeKey,
217
+ actionId,
218
+ handledByBoundary: false,
219
+ metadata: { timeout: true, phase, durationMs },
220
+ });
221
+
222
+ try {
223
+ const routerCtx = getRouterContext();
224
+ if (routerCtx?.telemetry) {
225
+ safeEmit(resolveSink(routerCtx.telemetry), {
226
+ type: "request.timeout" as const,
227
+ timestamp: performance.now(),
228
+ requestId: routerCtx.requestId,
229
+ phase,
230
+ pathname: url.pathname,
231
+ routeKey,
232
+ actionId,
233
+ durationMs,
234
+ customHandler: !!router.onTimeout,
235
+ });
236
+ }
237
+ } catch {
238
+ // Router context may not be available
239
+ }
240
+
241
+ if (router.onTimeout) {
242
+ try {
243
+ return await router.onTimeout({
244
+ phase,
245
+ request,
246
+ url,
247
+ env,
248
+ routeKey,
249
+ actionId,
250
+ durationMs,
251
+ });
252
+ } catch (e) {
253
+ if (process.env.NODE_ENV !== "production") {
254
+ console.error("[RSC] onTimeout callback error:", e);
255
+ }
256
+ return createDefaultTimeoutResponse(phase);
257
+ }
258
+ }
259
+
260
+ return createDefaultTimeoutResponse(phase);
261
+ }
262
+
263
+ /**
264
+ * Build a 200 Flight response that carries a redirect URL and optional state.
265
+ * Used when a partial/action request results in a redirect -- fetch
266
+ * auto-follows 3xx so we send the redirect as payload metadata instead.
267
+ */
268
+ function createRedirectFlightResponse(
269
+ redirectUrl: string,
270
+ locationState?: Record<string, unknown>,
271
+ ): Response {
272
+ const redirectPayload: RscPayload = {
273
+ metadata: {
274
+ pathname: redirectUrl,
275
+ segments: [],
276
+ redirect: { url: redirectUrl },
277
+ ...(locationState && { locationState }),
278
+ },
279
+ };
280
+ const rscStream = renderToReadableStream<RscPayload>(redirectPayload);
281
+ return createResponseWithMergedHeaders(rscStream, {
282
+ status: 200,
283
+ headers: { "content-type": "text/x-component;charset=utf-8" },
284
+ });
285
+ }
286
+
287
+ // Bundle shared dependencies for extracted handler functions.
288
+ // callOnError reads from ALS so it's inherently per-request scoped.
289
+ const handlerCtx: HandlerContext<TEnv> = {
290
+ router,
291
+ version,
292
+ renderToReadableStream,
293
+ decodeReply,
294
+ createTemporaryReferenceSet,
295
+ loadServerAction,
296
+ decodeAction,
297
+ decodeFormState,
298
+ loadSSRModule,
299
+ callOnError,
300
+ getRequiredRouteMap,
301
+ createRedirectFlightResponse,
302
+ resolveStreamMode: async (request, env, url) => {
303
+ const resolver = router.ssr?.resolveStreaming;
304
+ if (!resolver) return "stream";
305
+ return resolver({ request, env, url });
104
306
  },
307
+ };
308
+
309
+ return async function handler(
310
+ request: Request,
311
+ input: RouterRequestInput<TEnv> = {},
105
312
  ): Promise<Response> {
313
+ const handlerStart = performance.now();
314
+ // Create the metrics store at handler start so handler:total has startTime=0
315
+ // and all metrics are relative to the request entry point.
316
+ const earlyMetricsStore = router.debugPerformance
317
+ ? createMetricsStore(true, handlerStart)
318
+ : undefined;
319
+
320
+ const { env = {} as TEnv, vars: initialVars, ctx: executionCtx } = input;
321
+
322
+ // Connection warmup: return 204 immediately before any processing
323
+ if (router?.warmupEnabled && request.method === "HEAD") {
324
+ const warmupUrl = new URL(request.url);
325
+ if (warmupUrl.searchParams.has("_rsc_warmup")) {
326
+ return new Response(null, { status: 204 });
327
+ }
328
+ }
329
+
106
330
  // Resolve nonce if provider is set
331
+ const nonceStart = performance.now();
107
332
  let nonce: string | undefined;
108
333
  if (nonceProvider) {
109
334
  const result = await nonceProvider(request, env);
110
335
  nonce = result === true ? generateNonce() : result;
111
336
  }
337
+ const nonceDur = performance.now() - nonceStart;
112
338
 
113
339
  const url = new URL(request.url);
114
340
 
115
341
  // Match global middleware
342
+ const mwMatchStart = performance.now();
116
343
  const matchedMiddleware = matchMiddleware(url.pathname, router.middleware);
344
+ const mwMatchDur = performance.now() - mwMatchStart;
117
345
 
118
346
  // Shared variables between middleware and route handlers
119
- const variables: Record<string, any> = {};
347
+ // Initialize from input.vars if provided (allows pre-seeding from worker entry)
348
+ const variables: Record<string, any> = initialVars
349
+ ? { ...initialVars }
350
+ : {};
120
351
 
121
- // Store nonce in variables so middleware can access via ctx.get('nonce')
352
+ // Store nonce via ContextVar token and string key for backward compat
122
353
  if (nonce) {
354
+ contextSet(variables, nonceToken, nonce);
123
355
  variables.nonce = nonce;
124
356
  }
125
357
 
126
358
  // Resolve cache store configuration
127
359
  // Priority: options.cache (handler override) > router.cache (router default)
128
360
  // Store is enabled only if: config provided, enabled, and no ?__no_cache query param
129
- let cacheStore = undefined;
361
+ let cacheStore: SegmentCacheStore | undefined;
130
362
  const cacheOption = options.cache ?? router.cache;
131
363
  if (cacheOption && !url.searchParams.has("__no_cache")) {
132
364
  const cacheConfig =
133
- typeof cacheOption === "function" ? cacheOption(env) : cacheOption;
365
+ typeof cacheOption === "function"
366
+ ? cacheOption(env, executionCtx)
367
+ : cacheOption;
134
368
 
135
369
  if (cacheConfig.enabled !== false) {
136
370
  cacheStore = cacheConfig.store;
137
371
  }
138
372
  }
139
373
 
374
+ // Route manifest is populated at startup via the virtual module
375
+ // (virtual:rsc-router/routes-manifest). In build/production, it's inlined
376
+ // into the bundle. In dev mode (Node), the discovery plugin populates it
377
+ // via setManifestReadyPromise(). In dev mode (Cloudflare), Miniflare runs
378
+ // in a separate isolate where module-level state doesn't carry over, so
379
+ // we generate inline from the router's urlpatterns.
380
+ //
381
+ // In multi-router setups (e.g. createHostRouter), each router must have
382
+ // its own per-router manifest. We check per-router data first: even if
383
+ // the global manifest was set by a different router, this router still
384
+ // needs its own trie and manifest for correct matching.
385
+ const manifestCacheStart = performance.now();
386
+ const hasRouterData = getRouterManifest(router.id) !== undefined;
387
+ if (!hasRouterData) {
388
+ if (!hasCachedManifest()) {
389
+ const readyPromise = waitForManifestReady();
390
+ if (readyPromise) {
391
+ await readyPromise;
392
+ }
393
+ }
394
+ if (!getRouterManifest(router.id) && router.urlpatterns) {
395
+ // Cloudflare dev: generate manifest inline for this router.
396
+ // Each router generates its own manifest independently so
397
+ // multi-router setups (host routing) work correctly.
398
+ await buildRouterTrieFromUrlpatterns(router);
399
+ }
400
+ if (!getRouterManifest(router.id) && !hasCachedManifest()) {
401
+ throw new Error(
402
+ 'Route manifest not available. Ensure "virtual:rsc-router/routes-manifest" is imported in your entry file.',
403
+ );
404
+ }
405
+ }
406
+
407
+ // Rebuild the trie when the manifest exists but the per-router trie is
408
+ // missing. This happens in dev mode after HMR: the virtual module sets
409
+ // the manifest (from fresh gen files) but the trie is intentionally not
410
+ // injected to avoid stale discovery-time data. Without the trie, route
411
+ // matching falls back to regex iteration which does not handle wildcard
412
+ // priority correctly (catch-all patterns match before specific routes).
413
+ if (!getRouterTrie(router.id) && router.urlpatterns) {
414
+ await buildRouterTrieFromUrlpatterns(router);
415
+ }
416
+ const manifestCacheDur = performance.now() - manifestCacheStart;
417
+
140
418
  // Create unified request context with all methods
141
419
  // Includes: stub response, handle store, loader memoization, use(), cookies, headers, cache store
142
420
  // params starts empty, populated after route matching via setRequestContextParams
421
+ const ctxCreateStart = performance.now();
143
422
  const requestContext = createRequestContext({
144
423
  env,
145
424
  request,
146
425
  url,
147
426
  variables,
148
427
  cacheStore,
149
- executionContext: env.ctx,
428
+ cacheProfiles: router.cacheProfiles,
429
+ executionContext: executionCtx,
150
430
  themeConfig: router.themeConfig,
151
431
  });
432
+ if (earlyMetricsStore) {
433
+ requestContext._debugPerformance = true;
434
+ requestContext._metricsStore = earlyMetricsStore;
435
+ }
436
+ // Wire background error reporting so "use cache" and other subsystems
437
+ // can surface non-fatal errors through the router's onError callback.
438
+ requestContext._reportBackgroundError = (
439
+ error: unknown,
440
+ category: string,
441
+ ) => {
442
+ callOnError(error, "cache", {
443
+ request,
444
+ url,
445
+ metadata: { category },
446
+ });
447
+ };
448
+
449
+ const ctxCreateDur = performance.now() - ctxCreateStart;
450
+
451
+ // Accumulate handler-level timing for Server-Timing header
452
+ const handlerTiming = [
453
+ `handler-nonce;dur=${nonceDur.toFixed(2)}`,
454
+ `handler-mw-match;dur=${mwMatchDur.toFixed(2)}`,
455
+ `handler-manifest-cache;dur=${manifestCacheDur.toFixed(2)}`,
456
+ `handler-ctx-create;dur=${ctxCreateDur.toFixed(2)}`,
457
+ ];
458
+
459
+ // Store timing data in variables for downstream access
460
+ variables.__handlerTiming = handlerTiming;
461
+ variables.__handlerStart = handlerStart;
152
462
 
153
463
  // Wrap entire request handling in request context
154
464
  // Makes context available via getRequestContext() throughout:
@@ -157,6 +467,9 @@ export function createRSCHandler<
157
467
  // - Server components during rendering
158
468
  // - Error boundaries
159
469
  // - Streaming
470
+ // Store basename on request context (scoped per-request via existing ALS)
471
+ requestContext._basename = router.basename;
472
+
160
473
  return runWithRequestContext(requestContext, async () => {
161
474
  // Core handler logic (wrapped by middleware)
162
475
  const coreHandler = async (): Promise<Response> => {
@@ -164,21 +477,79 @@ export function createRSCHandler<
164
477
  };
165
478
 
166
479
  // Execute middleware chain if any, otherwise call core handler directly
480
+ let response: Response;
167
481
  if (matchedMiddleware.length > 0) {
168
- return executeMiddleware(
482
+ const mwResponse = await executeMiddleware(
169
483
  matchedMiddleware,
170
484
  request,
171
485
  env,
172
486
  variables,
173
487
  coreHandler,
488
+ createReverseFunction(getRequiredRouteMap()),
174
489
  );
490
+
491
+ if (
492
+ url.searchParams.has("_rsc_partial") ||
493
+ url.searchParams.has("_rsc_action")
494
+ ) {
495
+ const intercepted = interceptRedirectForPartial(
496
+ mwResponse,
497
+ createRedirectFlightResponse,
498
+ );
499
+ response = intercepted ?? finalizeResponse(mwResponse);
500
+ } else {
501
+ response = finalizeResponse(mwResponse);
502
+ }
503
+ } else {
504
+ response = await coreHandler();
175
505
  }
176
506
 
177
- return coreHandler();
507
+ // Finalize metrics after all middleware (including post-next work)
508
+ // has completed so :post spans are captured in the timeline.
509
+ // Handler timing parts are always emitted (even without debug metrics)
510
+ // so non-debug requests still get bootstrap Server-Timing entries.
511
+ const handlerTimingArr: string[] = variables.__handlerTiming || [];
512
+ // Preserve any existing Server-Timing set by response routes or middleware
513
+ const existingTiming = response.headers.get("Server-Timing");
514
+ const timingParts = existingTiming
515
+ ? [existingTiming, ...handlerTimingArr]
516
+ : [...handlerTimingArr];
517
+
518
+ const metricsStore = requestContext._metricsStore;
519
+ if (metricsStore) {
520
+ // When the store was created at handler start (earlyMetricsStore),
521
+ // handler:total covers the full request. When ctx.debugPerformance()
522
+ // created the store mid-request, use its requestStart to avoid a
523
+ // negative startTime offset.
524
+ const totalStart = earlyMetricsStore
525
+ ? handlerStart
526
+ : metricsStore.requestStart;
527
+ appendMetric(
528
+ metricsStore,
529
+ "handler:total",
530
+ totalStart,
531
+ performance.now() - totalStart,
532
+ );
533
+ const metricsTiming = buildMetricsTiming(
534
+ request.method,
535
+ url.pathname,
536
+ metricsStore,
537
+ );
538
+ if (metricsTiming) timingParts.push(metricsTiming);
539
+ }
540
+
541
+ const fullTiming = timingParts.join(", ");
542
+ if (fullTiming && !isWebSocketUpgradeResponse(response)) {
543
+ response.headers.set("Server-Timing", fullTiming);
544
+ }
545
+
546
+ return response;
178
547
  });
179
548
  };
180
549
 
181
- // Core request handling logic (separated for middleware wrapping)
550
+ // Core request handling logic (separated for middleware wrapping).
551
+ // Uses the classify → execute model: classifyRequest produces a RequestPlan,
552
+ // then execution dispatches on the plan mode.
182
553
  async function coreRequestHandler(
183
554
  request: Request,
184
555
  env: TEnv,
@@ -186,875 +557,592 @@ export function createRSCHandler<
186
557
  variables: Record<string, any>,
187
558
  nonce: string | undefined,
188
559
  ): Promise<Response> {
189
- // First, check for route-level middleware
190
- const preview = await router.previewMatch(request, env);
191
- if (preview?.routeMiddleware && preview.routeMiddleware.length > 0) {
192
- // Convert route middleware to app middleware format for execution
193
- const middlewareEntries = preview.routeMiddleware.map((mw) => ({
194
- entry: {
195
- pattern: null,
196
- regex: null,
197
- paramNames: [],
198
- handler: mw.handler,
199
- mountPrefix: null,
560
+ const handlerTiming: string[] = variables.__handlerTiming || [];
561
+
562
+ // Debug manifest endpoint: handled before classification since it
563
+ // doesn't need a route match and needs trie access from the closure.
564
+ const isDev = process.env.NODE_ENV !== "production";
565
+ if (
566
+ url.searchParams.has("__debug_manifest") &&
567
+ (isDev || router.allowDebugManifest)
568
+ ) {
569
+ const trie = getRouterTrie(router.id) ?? getRouteTrie();
570
+ const routeManifest = getRequiredRouteMap();
571
+ const { extractAncestryFromTrie } =
572
+ await import("../build/route-trie.js");
573
+ return new Response(
574
+ JSON.stringify(
575
+ {
576
+ routerId: router.id,
577
+ routeManifest,
578
+ routeAncestry: trie ? extractAncestryFromTrie(trie) : {},
579
+ routeTrie: trie,
580
+ precomputedEntries: getPrecomputedEntries(),
581
+ },
582
+ null,
583
+ 2,
584
+ ),
585
+ {
586
+ headers: { "Content-Type": "application/json" },
200
587
  },
201
- params: mw.params,
202
- }));
203
-
204
- // Execute route middleware wrapping the actual request handling
205
- return executeMiddleware(middlewareEntries, request, env, variables, () =>
206
- coreRequestHandlerInner(request, env, url, variables, nonce),
207
588
  );
208
589
  }
209
590
 
210
- // No route middleware, proceed directly
211
- return coreRequestHandlerInner(request, env, url, variables, nonce);
212
- }
213
-
214
- // Inner request handler (actual RSC logic, wrapped by route middleware if any)
215
- async function coreRequestHandlerInner(
216
- request: Request,
217
- env: TEnv,
218
- url: URL,
219
- variables: Record<string, any>,
220
- nonce: string | undefined,
221
- ): Promise<Response> {
222
- // Early return for static file requests that don't need RSC handling
223
- if (url.pathname === "/favicon.ico" || url.pathname === "/robots.txt") {
224
- return new Response(null, { status: 404 });
591
+ // ---- 1. Classify ----
592
+ // classifyRequest may throw RouteNotFoundError for unknown routes.
593
+ // In that case, fall through to a full-render plan so the pipeline
594
+ // can render the 404 page via the existing error handling path.
595
+ const classifyStart = performance.now();
596
+ let plan: RequestPlan<TEnv>;
597
+ try {
598
+ plan = await classifyRequest<TEnv>(request, url, {
599
+ findMatch: router.findMatch,
600
+ routerVersion: version,
601
+ routerId: router.id,
602
+ });
603
+ } catch (error) {
604
+ if (isRouteNotFoundError(error)) {
605
+ // Let the render path handle 404 — match()/matchPartial() will
606
+ // re-throw RouteNotFoundError and the catch block in
607
+ // executeRenderWithMiddleware renders the not-found page.
608
+ plan = {
609
+ mode: "full-render",
610
+ route: {
611
+ matched: null as any,
612
+ manifestEntry: null as any,
613
+ entries: [],
614
+ routeKey: "",
615
+ localRouteName: "",
616
+ params: {},
617
+ routeMiddleware: [],
618
+ cacheScope: null,
619
+ isPassthrough: false,
620
+ },
621
+ negotiated: false,
622
+ };
623
+ } else {
624
+ throw error;
625
+ }
626
+ }
627
+ const classifyDur = performance.now() - classifyStart;
628
+ handlerTiming.push(`handler-classify;dur=${classifyDur.toFixed(2)}`);
629
+
630
+ // ---- 2. Terminal plans (no execution needed) ----
631
+ if (plan.mode === "redirect") {
632
+ // Redirects are handled by the pipeline (match/matchPartial),
633
+ // but for partial requests we short-circuit with a Flight redirect.
634
+ if (url.searchParams.has("_rsc_partial")) {
635
+ return createRedirectFlightResponse(plan.redirectUrl);
636
+ }
637
+ // Full requests: let the pipeline handle the redirect via match()
638
+ // which returns { redirect: url }. Fall through to full-render.
225
639
  }
226
640
 
227
- const isPartial = url.searchParams.has("_rsc_partial");
228
- const isAction =
229
- request.headers.has("rsc-action") || url.searchParams.has("_rsc_action");
230
- const actionId =
231
- request.headers.get("rsc-action") || url.searchParams.get("_rsc_action");
232
-
233
- // Version mismatch detection - client may have stale code after HMR/deployment
234
- // If versions don't match, tell the client to reload
235
- const clientVersion = url.searchParams.get("_rsc_v");
236
- if (version && clientVersion && clientVersion !== version) {
641
+ if (plan.mode === "version-mismatch") {
237
642
  console.log(
238
- `[RSC] Version mismatch: client=${clientVersion}, server=${version}. Forcing reload.`,
643
+ `[RSC] Version mismatch: client=${url.searchParams.get("_rsc_v")}, server=${version}. Forcing reload.`,
239
644
  );
240
-
241
- // Clean URL by removing RSC params
242
- const cleanUrl = new URL(url);
243
- cleanUrl.searchParams.delete("_rsc_partial");
244
- cleanUrl.searchParams.delete("_rsc_segments");
245
- cleanUrl.searchParams.delete("_rsc_v");
246
- cleanUrl.searchParams.delete("_rsc_stale");
247
- cleanUrl.searchParams.delete("_rsc_action");
248
- cleanUrl.searchParams.delete("_rsc_prev");
249
-
250
- // For actions, reload current page (referer)
251
- // For navigation, load the target URL
252
- const reloadUrl = isAction
253
- ? request.headers.get("referer") || cleanUrl.toString()
254
- : cleanUrl.toString();
255
-
256
- // Return special response that tells client to reload
257
645
  return createResponseWithMergedHeaders(null, {
258
646
  status: 200,
259
647
  headers: {
260
- "X-RSC-Reload": reloadUrl,
648
+ "X-RSC-Reload": plan.reloadUrl,
261
649
  "content-type": "text/x-component;charset=utf-8",
262
650
  },
263
651
  });
264
652
  }
265
653
 
266
- // Get handle store from request context (created at start of request)
267
- const handleStore = requireRequestContext()._handleStore;
268
-
269
- try {
270
- // ============================================================================
271
- // PROGRESSIVE ENHANCEMENT: No-JS Form Submissions
272
- // ============================================================================
273
- const progressiveResult = await handleProgressiveEnhancement(
654
+ // ---- 3. Origin guard (gate for action/loader/PE modes) ----
655
+ const originPhase = ORIGIN_CHECK_PHASE_BY_MODE[plan.mode];
656
+ if (originPhase) {
657
+ const originResult = await checkRequestOrigin(
274
658
  request,
275
- env,
276
659
  url,
277
- isAction,
278
- handleStore,
279
- nonce,
280
- );
281
- if (progressiveResult) {
282
- return progressiveResult;
283
- }
284
-
285
- // ============================================================================
286
- // SERVER ACTION EXECUTION (JavaScript-enabled client)
287
- // ============================================================================
288
- if (isAction && actionId) {
289
- return handleServerAction(request, env, url, actionId, handleStore);
290
- }
291
-
292
- // ============================================================================
293
- // LOADER FETCH EXECUTION (data fetching with RSC serialization)
294
- // ============================================================================
295
- const isLoaderRequest = url.searchParams.has("_rsc_loader");
296
- if (isLoaderRequest) {
297
- return handleLoaderFetch(request, env, url, variables);
298
- }
299
-
300
- // ============================================================================
301
- // REGULAR RSC RENDERING (Navigation)
302
- // ============================================================================
303
- // Note: Must use "return await" for try/catch to catch async rejections
304
- return await handleRscRendering(
305
- request,
660
+ router.originCheck,
306
661
  env,
307
- url,
308
- isPartial,
309
- handleStore,
310
- nonce,
662
+ router.id,
663
+ originPhase,
311
664
  );
312
- } catch (error) {
313
- // Check if middleware/handler returned Response
314
- if (error instanceof Response) {
315
- return error;
316
- }
665
+ if (originResult) {
666
+ const originError = new Error(
667
+ `Origin check rejected: ${request.headers.get("origin") ?? "none"} vs ${request.headers.get("host") ?? "none"}`,
668
+ );
669
+ originError.name = "OriginCheckError";
317
670
 
318
- // Render 404 page for unmatched routes
319
- // Check both instanceof and error.name for cross-bundle compatibility
320
- const isRouteNotFound =
321
- error instanceof RouteNotFoundError ||
322
- (error instanceof Error && error.name === "RouteNotFoundError");
323
- if (isRouteNotFound) {
324
- callOnError(error, "routing", {
671
+ callOnError(originError, "origin", {
325
672
  request,
326
673
  url,
327
674
  env,
328
- handledByBoundary: true, // Handled by notFound component
329
- });
330
-
331
- // Get notFound component from router options or use default
332
- const notFoundOption = router.notFound;
333
- const notFoundComponent =
334
- typeof notFoundOption === "function"
335
- ? notFoundOption({ pathname: url.pathname })
336
- : (notFoundOption ?? createElement("h1", null, "Not Found"));
337
-
338
- // Create a simple segment for the 404 page
339
- const notFoundSegment = {
340
- id: "notFound",
341
- namespace: "notFound",
342
- type: "route" as const,
343
- index: 0,
344
- component: notFoundComponent,
345
- params: {},
346
- };
347
-
348
- // Render with rootLayout to maintain app shell
349
- const root = await renderSegments([notFoundSegment], {
350
- rootLayout: router.rootLayout,
351
- routeMap,
352
- // No routeName for not-found routes
353
- });
354
-
355
- const payload: RscPayload = {
356
- root,
675
+ handledByBoundary: false,
357
676
  metadata: {
358
- pathname: url.pathname,
359
- segments: [notFoundSegment],
360
- matched: [],
361
- diff: [],
362
- isPartial: false,
363
- handles: handleStore.stream(),
364
- version,
365
- themeConfig: router.themeConfig,
366
- initialTheme: requireRequestContext().theme,
367
- routeMap,
368
- // No routeName for not-found routes
677
+ phase: originPhase,
678
+ origin: request.headers.get("origin"),
679
+ host: request.headers.get("host"),
369
680
  },
370
- };
371
-
372
- const rscStream = renderToReadableStream(payload);
373
-
374
- // Determine if this is an RSC request or HTML request
375
- const isRscRequest =
376
- (!request.headers.get("accept")?.includes("text/html") &&
377
- !url.searchParams.has("__html")) ||
378
- url.searchParams.has("__rsc");
681
+ });
379
682
 
380
- if (isRscRequest) {
381
- return createResponseWithMergedHeaders(rscStream, {
382
- status: 404,
383
- headers: { "content-type": "text/x-component;charset=utf-8" },
384
- });
683
+ try {
684
+ const routerCtx = getRouterContext();
685
+ if (routerCtx?.telemetry) {
686
+ safeEmit(resolveSink(routerCtx.telemetry), {
687
+ type: "request.origin-rejected" as const,
688
+ timestamp: performance.now(),
689
+ requestId: routerCtx.requestId,
690
+ method: request.method,
691
+ pathname: url.pathname,
692
+ phase: originPhase,
693
+ origin: request.headers.get("origin"),
694
+ host: request.headers.get("host"),
695
+ });
696
+ }
697
+ } catch {
698
+ // Router context may not be available
385
699
  }
386
700
 
387
- // Delegate to SSR for HTML response
388
- const ssrModule = await loadSSRModule();
389
- const htmlStream = await ssrModule.renderHTML(rscStream, { nonce });
390
-
391
- return createResponseWithMergedHeaders(htmlStream, {
392
- status: 404,
393
- headers: { "content-type": "text/html;charset=utf-8" },
394
- });
701
+ return originResult;
395
702
  }
396
-
397
- // Report unhandled errors
398
- callOnError(error, "routing", {
399
- request,
400
- url,
401
- env,
402
- handledByBoundary: false,
403
- });
404
- console.error(`[RSC] Error:`, error);
405
- throw error;
406
703
  }
704
+
705
+ // ---- 4. Execute ----
706
+ return executeRequest(
707
+ plan as ExecutableRequestPlan<TEnv>,
708
+ request,
709
+ env,
710
+ url,
711
+ variables,
712
+ nonce,
713
+ );
407
714
  }
408
715
 
409
- // ============================================================================
410
- // PROGRESSIVE ENHANCEMENT HANDLER
411
- // When JavaScript is disabled, React renders forms with hidden fields
412
- // ($ACTION_REF_*, $ACTION_KEY) containing the action reference.
413
- // We detect these and return HTML instead of RSC stream.
414
- // ============================================================================
415
- async function handleProgressiveEnhancement(
716
+ // Execute a classified request plan. Dispatches to the appropriate handler
717
+ // based on plan.mode. Lives in the createRSCHandler closure for access to
718
+ // handlerCtx, router, callOnError, etc.
719
+ // Only receives executable plans (version-mismatch is handled above).
720
+ async function executeRequest(
721
+ plan: ExecutableRequestPlan<TEnv>,
416
722
  request: Request,
417
723
  env: TEnv,
418
724
  url: URL,
419
- isAction: boolean,
420
- handleStore: ReturnType<typeof requireRequestContext>["_handleStore"],
725
+ variables: Record<string, any>,
421
726
  nonce: string | undefined,
422
- ): Promise<Response | null> {
423
- const contentType = request.headers.get("content-type") || "";
424
- const isFormSubmission =
425
- contentType.includes("multipart/form-data") ||
426
- contentType.includes("application/x-www-form-urlencoded");
427
-
428
- if (request.method !== "POST" || isAction || !isFormSubmission) {
429
- return null;
430
- }
431
-
432
- // Clone the request to read FormData without consuming it
433
- const formData = await request.clone().formData();
434
-
435
- // Look for React's progressive enhancement hidden fields
436
- let isDirectAction = false;
437
- let isUseActionState = false;
438
- let directActionId: string | null = null;
727
+ ): Promise<Response> {
728
+ // Common setup
729
+ const handleStore = requireRequestContext()._handleStore;
439
730
 
440
- formData.forEach((_value, key) => {
441
- if (key.startsWith("$ACTION_ID_")) {
442
- isDirectAction = true;
443
- directActionId = key.slice("$ACTION_ID_".length);
444
- } else if (key.startsWith("$ACTION_REF_")) {
445
- isUseActionState = true;
731
+ // Wire up error reporting for late streaming-handle failures
732
+ handleStore.onError = (error: Error) => {
733
+ const reqCtx = requireRequestContext();
734
+ callOnError(error, "handler", {
735
+ request,
736
+ url,
737
+ routeKey: reqCtx._routeName,
738
+ params: reqCtx.params as Record<string, string>,
739
+ handledByBoundary: true,
740
+ });
741
+ try {
742
+ const routerCtx = getRouterContext();
743
+ if (routerCtx?.telemetry) {
744
+ safeEmit(resolveSink(routerCtx.telemetry), {
745
+ type: "handler.error" as const,
746
+ timestamp: performance.now(),
747
+ requestId: routerCtx.requestId,
748
+ error,
749
+ handledByBoundary: true,
750
+ pathname: url.pathname,
751
+ routeKey: reqCtx._routeName,
752
+ params: reqCtx.params as Record<string, string>,
753
+ });
754
+ }
755
+ } catch {
756
+ // Router context may not be available (e.g. prerender path)
446
757
  }
447
- });
758
+ };
448
759
 
449
- if (!isDirectAction && !isUseActionState) {
450
- return null;
760
+ // Set route params early so all execution paths can access ctx.params.
761
+ // Also store the classified snapshot so match/matchPartial can reuse it
762
+ // instead of calling resolveRoute again.
763
+ if (plan.mode !== "redirect") {
764
+ setRequestContextParams(plan.route.params, plan.route.routeKey);
765
+ requireRequestContext()._classifiedRoute = plan.route;
451
766
  }
452
767
 
453
- // Execute action and return HTML
454
- let actionResult: unknown = undefined;
455
- let reactFormState: ReactFormState | null = null;
456
-
457
- if (isUseActionState) {
458
- try {
459
- const boundAction = await decodeAction(formData);
460
- actionResult = await boundAction();
461
- } catch (error) {
462
- callOnError(error, "action", {
768
+ const routeReverse = createReverseFunction(getRequiredRouteMap());
769
+
770
+ // ---- Response route: skip entire RSC pipeline ----
771
+ if (plan.mode === "response") {
772
+ // Build ResponseRouteMatch from plan fields. handleResponseRoute
773
+ // expects a flat object with params at the top level.
774
+ const responseMatch: ResponseRouteMatch = {
775
+ responseType: plan.responseType,
776
+ handler: plan.handler,
777
+ params: plan.route.params,
778
+ negotiated: plan.negotiated,
779
+ manifestEntry: plan.manifestEntry,
780
+ routeMiddleware: plan.routeMiddleware,
781
+ };
782
+ const responseOutcome = await withTimeout(
783
+ handleResponseRoute(
784
+ handlerCtx,
785
+ responseMatch,
463
786
  request,
464
- url,
465
787
  env,
466
- handledByBoundary: false,
467
- });
468
- console.error("[RSC] Progressive enhancement action error:", error);
469
- }
470
- } else if (isDirectAction && directActionId) {
471
- const temporaryReferences = createTemporaryReferenceSet();
472
-
473
- let args: unknown[] = [];
474
- try {
475
- args = await decodeReply(formData, { temporaryReferences });
476
- } catch {
477
- args = [formData];
478
- }
479
-
480
- try {
481
- const loadedAction = await loadServerAction(directActionId);
482
- actionResult = await loadedAction.apply(null, args);
483
- } catch (error) {
484
- callOnError(error, "action", {
485
- request,
486
788
  url,
789
+ variables,
790
+ ),
791
+ router.timeouts.renderStartMs,
792
+ "render-start",
793
+ );
794
+ if (responseOutcome.timedOut) {
795
+ return handleTimeoutResponse(
796
+ request,
487
797
  env,
488
- actionId: directActionId,
489
- handledByBoundary: false,
490
- });
491
- console.error("[RSC] Progressive enhancement action error:", error);
798
+ url,
799
+ "render-start",
800
+ responseOutcome.durationMs,
801
+ plan.route.routeKey,
802
+ );
492
803
  }
804
+ const response = responseOutcome.result;
805
+ if (plan.negotiated && !isWebSocketUpgradeResponse(response)) {
806
+ response.headers.append("Vary", "Accept");
807
+ }
808
+ return response;
493
809
  }
494
810
 
495
- // Decode form state for useActionState progressive enhancement
496
- try {
497
- reactFormState = await decodeFormState(actionResult, formData);
498
- } catch (error) {
499
- callOnError(error, "action", {
811
+ // SSR setup: kick off in parallel for modes that need HTML rendering.
812
+ // Placed after response-route short-circuit so response/mime routes
813
+ // never pay for SSR work.
814
+ if (plan.mode !== "loader" && mayNeedSSR(request, url)) {
815
+ variables[SSR_SETUP_VAR] = startSSRSetup(
816
+ handlerCtx,
500
817
  request,
501
- url,
502
818
  env,
503
- handledByBoundary: false,
504
- });
505
- console.error("[RSC] Failed to decode form state:", error);
506
- }
507
-
508
- // Re-render the page and return HTML
509
- const renderRequest = new Request(url.toString(), {
510
- method: "GET",
511
- headers: new Headers({ accept: "text/html" }),
512
- });
513
-
514
- const match = await router.match(renderRequest, env);
515
-
516
- if (match.redirect) {
517
- return new Response(null, {
518
- status: 308,
519
- headers: { Location: match.redirect },
520
- });
819
+ url,
820
+ router.debugPerformance
821
+ ? () => requireRequestContext()._metricsStore
822
+ : undefined,
823
+ );
521
824
  }
522
825
 
523
- const root = renderSegments(match.segments, {
524
- rootLayout: router.rootLayout,
525
- routeMap,
526
- routeName: match.routeName,
527
- });
528
-
529
- const payload: RscPayload = {
530
- root,
531
- metadata: {
532
- pathname: url.pathname,
533
- segments: match.segments,
534
- matched: match.matched,
535
- diff: match.diff,
536
- isPartial: false,
537
- rootLayout: router.rootLayout,
538
- handles: handleStore.stream(),
539
- version,
540
- themeConfig: router.themeConfig,
541
- initialTheme: requireRequestContext().theme,
542
- routeMap,
543
- routeName: match.routeName,
544
- },
545
- formState: actionResult,
546
- };
547
-
548
- const rscStream = renderToReadableStream<RscPayload>(payload);
549
- const ssrModule = await loadSSRModule();
550
- const htmlStream = await ssrModule.renderHTML(rscStream, {
551
- formState: reactFormState,
552
- nonce,
553
- });
554
-
555
- return new Response(htmlStream, {
556
- headers: { "content-type": "text/html;charset=utf-8" },
557
- });
558
- }
559
-
560
- // ============================================================================
561
- // SERVER ACTION HANDLER
562
- // ============================================================================
563
- async function handleServerAction(
564
- request: Request,
565
- env: TEnv,
566
- url: URL,
567
- actionId: string,
568
- handleStore: ReturnType<typeof requireRequestContext>["_handleStore"],
569
- ): Promise<Response> {
570
- const temporaryReferences = createTemporaryReferenceSet();
571
-
572
- // Decode action arguments from request body
573
- const contentType = request.headers.get("content-type") || "";
574
- let args: unknown[] = [];
575
- let actionFormData: FormData | undefined;
576
-
577
- try {
578
- const body = contentType.includes("multipart/form-data")
579
- ? await request.formData()
580
- : await request.text();
581
-
582
- if (body instanceof FormData) {
583
- actionFormData = body;
584
- }
585
-
586
- if (hasBodyContent(body)) {
587
- args = await decodeReply(body, { temporaryReferences });
588
- }
589
- } catch (error) {
590
- callOnError(error, "action", {
826
+ // ---- Loader fetch ----
827
+ if (plan.mode === "loader") {
828
+ return handleLoaderFetch(
829
+ handlerCtx,
591
830
  request,
592
- url,
593
831
  env,
594
- actionId,
595
- handledByBoundary: false,
596
- });
597
- throw new Error(`Failed to decode action arguments: ${error}`, {
598
- cause: error,
599
- });
832
+ url,
833
+ variables,
834
+ plan.route.params,
835
+ );
600
836
  }
601
837
 
602
- // Execute the server action
603
- let returnValue: { ok: boolean; data: unknown };
604
- let actionStatus = 200;
605
- let loadedAction: Function | undefined;
606
-
607
- try {
608
- loadedAction = await loadServerAction(actionId);
609
- const data = await loadedAction!.apply(null, args);
610
- returnValue = { ok: true, data };
611
- } catch (error) {
612
- returnValue = { ok: false, data: error };
613
- actionStatus = 500;
614
-
615
- // Try to render error boundary
616
- const errorResult = await router.matchError(request, env, error, "route");
617
-
618
- // Report the action error (handledByBoundary indicates if error boundary will render)
619
- callOnError(error, "action", {
838
+ // ---- Progressive enhancement ----
839
+ if (plan.mode === "pe-render") {
840
+ const peResult = await handleProgressiveEnhancement(
841
+ handlerCtx,
620
842
  request,
621
- url,
622
843
  env,
623
- actionId,
624
- handledByBoundary: !!errorResult,
625
- });
626
-
627
- if (errorResult) {
628
- setRequestContextParams(errorResult.params);
629
-
630
- const payload: RscPayload = {
631
- root: null,
632
- metadata: {
633
- pathname: url.pathname,
634
- segments: errorResult.segments,
635
- isPartial: true,
636
- matched: errorResult.matched,
637
- diff: errorResult.diff,
638
- isError: true,
639
- handles: handleStore.stream(),
640
- version,
641
- routeMap,
642
- routeName: errorResult.routeName,
643
- },
644
- returnValue,
645
- };
646
-
647
- const rscStream = renderToReadableStream<RscPayload>(payload, {
648
- temporaryReferences,
649
- });
650
-
651
- return createResponseWithMergedHeaders(rscStream, {
652
- status: actionStatus,
653
- headers: { "content-type": "text/x-component;charset=utf-8" },
654
- });
655
- }
844
+ url,
845
+ false, // isAction = false for PE
846
+ handleStore,
847
+ nonce,
848
+ {
849
+ routeMiddleware: plan.route.routeMiddleware,
850
+ variables,
851
+ routeReverse,
852
+ },
853
+ );
854
+ if (peResult) return peResult;
855
+ // PE handler returned null (not a PE form) — fall through to render
656
856
  }
657
857
 
658
- // Revalidate after action
659
- const resolvedActionId =
660
- (loadedAction as { $id?: string; $$id?: string } | undefined)?.$id ??
661
- (loadedAction as { $$id?: string } | undefined)?.$$id ??
662
- actionId;
663
- const actionContext = {
664
- actionId: resolvedActionId,
665
- actionUrl: new URL(request.url),
666
- actionResult: returnValue.data,
667
- formData: actionFormData,
668
- };
669
-
670
- const matchResult = await router.matchPartial(request, env, actionContext);
671
-
672
- if (!matchResult) {
673
- // Fall back to full render
674
- const fullMatch = await router.match(request, env);
675
- setRequestContextParams(fullMatch.params);
676
-
677
- if (fullMatch.redirect) {
678
- return createResponseWithMergedHeaders(null, {
679
- status: 308,
680
- headers: { Location: fullMatch.redirect },
858
+ // ---- Action: execute action, then revalidate wrapped in route middleware ----
859
+ if (plan.mode === "action") {
860
+ let actionContinuation: ActionContinuation | undefined;
861
+ try {
862
+ const actionOutcome = await withTimeout(
863
+ executeServerAction(
864
+ handlerCtx,
865
+ request,
866
+ env,
867
+ url,
868
+ plan.actionId,
869
+ handleStore,
870
+ ),
871
+ router.timeouts.actionMs,
872
+ "action",
873
+ );
874
+ if (actionOutcome.timedOut) {
875
+ return handleTimeoutResponse(
876
+ request,
877
+ env,
878
+ url,
879
+ "action",
880
+ actionOutcome.durationMs,
881
+ plan.route.routeKey,
882
+ plan.actionId,
883
+ );
884
+ }
885
+ const result = actionOutcome.result;
886
+ // Response means redirect or error boundary — done.
887
+ if (result instanceof Response) return result;
888
+ actionContinuation = result;
889
+ } catch (error) {
890
+ callOnError(error, "action", {
891
+ request,
892
+ url,
893
+ env,
894
+ actionId: plan.actionId,
895
+ handledByBoundary: false,
681
896
  });
897
+ console.error(`[RSC] Action error:`, error);
898
+ throw error;
682
899
  }
683
900
 
684
- const renderStart = performance.now();
685
- const root = renderSegments(fullMatch.segments, {
686
- rootLayout: router.rootLayout,
687
- isAction: true,
688
- routeMap,
689
- routeName: fullMatch.routeName,
690
- });
691
- const renderDuration = performance.now() - renderStart;
692
- const serverTiming = fullMatch.serverTiming
693
- ? `${fullMatch.serverTiming}, rendering;dur=${renderDuration.toFixed(2)}`
694
- : `rendering;dur=${renderDuration.toFixed(2)}`;
695
-
696
- const payload: RscPayload = {
697
- root,
698
- metadata: {
699
- pathname: url.pathname,
700
- segments: fullMatch.segments,
701
- matched: fullMatch.matched,
702
- diff: fullMatch.diff,
703
- handles: handleStore.stream(),
704
- version,
705
- routeMap,
706
- routeName: fullMatch.routeName,
707
- },
708
- returnValue,
709
- };
710
-
711
- const rscStream = renderToReadableStream<RscPayload>(payload, {
712
- temporaryReferences,
713
- });
714
-
715
- const headers: Record<string, string> = {
716
- "content-type": "text/x-component;charset=utf-8",
717
- };
718
- if (serverTiming) {
719
- headers["Server-Timing"] = serverTiming;
720
- }
721
-
722
- return createResponseWithMergedHeaders(rscStream, {
723
- status: actionStatus,
724
- headers,
725
- });
726
- }
727
-
728
- // Return updated segments
729
- setRequestContextParams(matchResult.params);
730
-
731
- const renderStart = performance.now();
732
- renderSegments(matchResult.segments, {
733
- rootLayout: router.rootLayout,
734
- isAction: true,
735
- routeMap,
736
- routeName: matchResult.routeName,
737
- });
738
- const renderDuration = performance.now() - renderStart;
739
- const serverTiming = matchResult.serverTiming
740
- ? `${matchResult.serverTiming}, rendering;dur=${renderDuration.toFixed(2)}`
741
- : `rendering;dur=${renderDuration.toFixed(2)}`;
742
-
743
- const payload: RscPayload = {
744
- root: null,
745
- metadata: {
746
- pathname: url.pathname,
747
- segments: matchResult.segments,
748
- isPartial: true,
749
- matched: matchResult.matched,
750
- diff: matchResult.diff,
751
- slots: matchResult.slots,
752
- handles: handleStore.stream(),
753
- version,
754
- routeMap,
755
- routeName: matchResult.routeName,
756
- },
757
- returnValue,
758
- };
759
-
760
- const rscStream = renderToReadableStream<RscPayload>(payload, {
761
- temporaryReferences,
762
- });
763
-
764
- const actionHeaders: Record<string, string> = {
765
- "content-type": "text/x-component;charset=utf-8",
766
- };
767
- if (serverTiming) {
768
- actionHeaders["Server-Timing"] = serverTiming;
901
+ // Revalidation render wrapped in route middleware.
902
+ // Actions from client-side navigation include _rsc_partial — preserve
903
+ // the partial flag so the revalidation returns a Flight stream, not HTML.
904
+ // App-switch is already excluded by classifyRequest (would be full-render).
905
+ const isPartialAction = url.searchParams.has("_rsc_partial");
906
+ return executeRenderWithMiddleware(
907
+ plan.route.routeMiddleware,
908
+ plan.negotiated,
909
+ plan.route.routeKey,
910
+ routeReverse,
911
+ request,
912
+ env,
913
+ url,
914
+ variables,
915
+ nonce,
916
+ handleStore,
917
+ isPartialAction,
918
+ actionContinuation,
919
+ );
769
920
  }
770
921
 
771
- return createResponseWithMergedHeaders(rscStream, {
772
- status: actionStatus,
773
- headers: actionHeaders,
774
- });
922
+ // Full render, partial render, fallen-through PE, and full-page redirect all
923
+ // render through the same middleware-wrapped path. Only full/partial-render
924
+ // carry negotiation + the partial flag; pe/redirect render plainly.
925
+ const isPartial = plan.mode === "partial-render";
926
+ const negotiated =
927
+ plan.mode === "full-render" || plan.mode === "partial-render"
928
+ ? plan.negotiated
929
+ : false;
930
+ return executeRenderWithMiddleware(
931
+ plan.route.routeMiddleware,
932
+ negotiated,
933
+ plan.route.routeKey,
934
+ routeReverse,
935
+ request,
936
+ env,
937
+ url,
938
+ variables,
939
+ nonce,
940
+ handleStore,
941
+ isPartial,
942
+ );
775
943
  }
776
944
 
777
- // ============================================================================
778
- // LOADER FETCH HANDLER
779
- // Supports GET (params in query string) and POST/PUT/PATCH/DELETE (JSON body)
780
- // ============================================================================
781
- async function handleLoaderFetch(
945
+ // Shared render execution: wraps handleRscRendering (or revalidateAfterAction)
946
+ // in route middleware and timeout handling. Consolidates the pattern used by
947
+ // action-revalidate, full-render, and partial-render modes.
948
+ async function executeRenderWithMiddleware(
949
+ routeMiddleware: import("../router/middleware-types.js").CollectedMiddleware[],
950
+ negotiated: boolean,
951
+ routeKey: string,
952
+ routeReverse: ReturnType<typeof createReverseFunction>,
782
953
  request: Request,
783
954
  env: TEnv,
784
955
  url: URL,
785
956
  variables: Record<string, any>,
957
+ nonce: string | undefined,
958
+ handleStore: ReturnType<typeof requireRequestContext>["_handleStore"],
959
+ isPartial: boolean,
960
+ actionContinuation?: ActionContinuation,
786
961
  ): Promise<Response> {
787
- const loaderId = url.searchParams.get("_rsc_loader");
962
+ const renderHandler = async (): Promise<Response> => {
963
+ try {
964
+ let response: Response;
965
+ if (actionContinuation) {
966
+ response = await revalidateAfterAction(
967
+ handlerCtx,
968
+ request,
969
+ env,
970
+ url,
971
+ handleStore,
972
+ actionContinuation,
973
+ );
974
+ } else {
975
+ response = await handleRscRendering(
976
+ handlerCtx,
977
+ request,
978
+ env,
979
+ url,
980
+ isPartial,
981
+ handleStore,
982
+ nonce,
983
+ );
984
+ }
985
+ if (negotiated && !isWebSocketUpgradeResponse(response)) {
986
+ response.headers.append("Vary", "Accept");
987
+ }
988
+ return response;
989
+ } catch (error) {
990
+ // Check if middleware/handler returned Response
991
+ if (error instanceof Response) {
992
+ // During partial (client-side navigation), a 200 Response from a handler
993
+ // means the route serves raw content (JSON, text, etc.), not JSX.
994
+ // Signal the browser to hard-navigate so it renders the raw response.
995
+ if (isPartial && error.status === 200) {
996
+ console.warn(
997
+ `[RSC] Route handler at ${url.pathname} returned a Response during client-side navigation. ` +
998
+ `Falling back to hard navigation. Use data-external on the <Link> to avoid the extra round-trip.`,
999
+ );
1000
+ return createResponseWithMergedHeaders(null, {
1001
+ status: 200,
1002
+ headers: {
1003
+ "X-RSC-Reload": stripInternalParams(url).toString(),
1004
+ "content-type": "text/x-component;charset=utf-8",
1005
+ },
1006
+ });
1007
+ }
788
1008
 
789
- if (!loaderId) {
790
- return createResponseWithMergedHeaders("Missing _rsc_loader parameter", {
791
- status: 400,
792
- });
793
- }
1009
+ if (isPartial) {
1010
+ const intercepted = interceptRedirectForPartial(
1011
+ error,
1012
+ createRedirectFlightResponse,
1013
+ );
1014
+ if (intercepted) return intercepted;
1015
+ }
794
1016
 
795
- // Look up loader lazily
796
- const registeredLoader = await getLoaderLazy(loaderId);
797
- if (!registeredLoader) {
798
- return createResponseWithMergedHeaders(
799
- `Loader "${loaderId}" not found in registry`,
800
- { status: 404 },
801
- );
802
- }
1017
+ return error;
1018
+ }
803
1019
 
804
- // Parse params and body based on request method
805
- let loaderParams: Record<string, string> = {};
806
- let loaderBody: unknown = undefined;
807
- const isBodyMethod = request.method !== "GET" && request.method !== "HEAD";
1020
+ // Render 404 page for unmatched routes
1021
+ if (isRouteNotFoundError(error)) {
1022
+ callOnError(error, "routing", {
1023
+ request,
1024
+ url,
1025
+ env,
1026
+ handledByBoundary: true,
1027
+ });
808
1028
 
809
- if (isBodyMethod) {
810
- try {
811
- const contentType = request.headers.get("content-type") || "";
812
- if (contentType.includes("application/json")) {
813
- const jsonBody = (await request.json()) as {
814
- params?: Record<string, string>;
815
- body?: unknown;
1029
+ const notFoundOption = router.notFound;
1030
+ const notFoundComponent =
1031
+ typeof notFoundOption === "function"
1032
+ ? notFoundOption({ pathname: url.pathname })
1033
+ : (notFoundOption ?? createElement("h1", null, "Not Found"));
1034
+
1035
+ const notFoundSegment = {
1036
+ id: "notFound",
1037
+ namespace: "notFound",
1038
+ type: "route" as const,
1039
+ index: 0,
1040
+ component: notFoundComponent,
1041
+ params: {},
816
1042
  };
817
- loaderParams = jsonBody.params ?? {};
818
- loaderBody = jsonBody.body;
819
- }
820
- } catch {
821
- return createResponseWithMergedHeaders("Invalid JSON body", {
822
- status: 400,
823
- });
824
- }
825
- } else {
826
- const loaderParamsJson = url.searchParams.get("_rsc_loader_params");
827
- if (loaderParamsJson) {
828
- try {
829
- loaderParams = JSON.parse(loaderParamsJson);
830
- } catch {
831
- return createResponseWithMergedHeaders(
832
- "Invalid _rsc_loader_params JSON",
833
- { status: 400 },
834
- );
835
- }
836
- }
837
- }
838
1043
 
839
- // Execute the loader with middleware
840
- try {
841
- const { fn, middleware } = registeredLoader;
842
-
843
- return await executeLoaderMiddleware(
844
- middleware,
845
- request,
846
- env,
847
- loaderParams,
848
- variables,
849
- async () => {
850
- const ctx = requireRequestContext();
851
- const loaderCtx: any = {
852
- ...ctx,
853
- params: loaderParams,
854
- body: loaderBody,
1044
+ const payload: RscPayload = {
1045
+ metadata: {
1046
+ pathname: url.pathname,
1047
+ routerId: router.id,
1048
+ basename: router.basename,
1049
+ segments: [notFoundSegment],
1050
+ matched: [],
1051
+ diff: [],
1052
+ isPartial: false,
1053
+ rootLayout: router.rootLayout,
1054
+ handles: handleStore.stream(),
1055
+ version,
1056
+ themeConfig: router.themeConfig,
1057
+ warmupEnabled: router.warmupEnabled,
1058
+ initialTheme: requireRequestContext().theme,
1059
+ },
855
1060
  };
856
1061
 
857
- const result = await fn(loaderCtx);
1062
+ const rscStream = renderToReadableStream(payload, {
1063
+ onError: (error: unknown) => {
1064
+ callOnError(error, "rendering", { request, url, env });
1065
+ },
1066
+ });
858
1067
 
859
- interface LoaderPayload {
860
- loaderResult: unknown;
1068
+ if (isRscRequest(request, url, isPartial)) {
1069
+ return createResponseWithMergedHeaders(rscStream, {
1070
+ status: 404,
1071
+ headers: { "content-type": "text/x-component;charset=utf-8" },
1072
+ });
861
1073
  }
862
- const loaderPayload: LoaderPayload = { loaderResult: result };
863
- const rscStream =
864
- renderToReadableStream<LoaderPayload>(loaderPayload);
865
1074
 
866
- return createResponseWithMergedHeaders(rscStream, {
867
- headers: { "content-type": "text/x-component;charset=utf-8" },
1075
+ const [ssrModule, streamMode] = await getSSRSetup(
1076
+ handlerCtx,
1077
+ request,
1078
+ env,
1079
+ url,
1080
+ requireRequestContext()._metricsStore,
1081
+ );
1082
+ const htmlStream = await ssrModule.renderHTML(rscStream, {
1083
+ nonce,
1084
+ streamMode,
868
1085
  });
869
- },
870
- );
871
- } catch (error) {
872
- const err = error instanceof Error ? error : new Error(String(error));
873
- const isDev = process.env.NODE_ENV !== "production";
874
-
875
- console.error("[RSC] Loader error:", error);
876
1086
 
877
- callOnError(error, "loader", {
878
- request,
879
- url,
880
- env,
881
- loaderName: loaderId,
882
- handledByBoundary: false,
883
- });
884
-
885
- const errorPayload = {
886
- loaderResult: null,
887
- loaderError: {
888
- message: isDev ? err.message : "An error occurred",
889
- name: err.name,
890
- },
891
- };
892
- const rscStream = renderToReadableStream(errorPayload);
893
-
894
- return createResponseWithMergedHeaders(rscStream, {
895
- status: 500,
896
- headers: { "content-type": "text/x-component;charset=utf-8" },
897
- });
898
- }
899
- }
900
-
901
- // ============================================================================
902
- // RSC RENDERING HANDLER (Navigation)
903
- // ============================================================================
904
- async function handleRscRendering(
905
- request: Request,
906
- env: TEnv,
907
- url: URL,
908
- isPartial: boolean,
909
- handleStore: ReturnType<typeof requireRequestContext>["_handleStore"],
910
- nonce: string | undefined,
911
- ): Promise<Response> {
912
- let payload: RscPayload;
913
- let serverTiming: string | undefined;
914
-
915
- if (isPartial) {
916
- // Partial render (navigation)
917
- const result = await router.matchPartial(request, env);
918
-
919
- if (!result) {
920
- // Fall back to full render
921
- const match = await router.match(request, env);
922
- setRequestContextParams(match.params);
923
-
924
- if (match.redirect) {
925
- return createResponseWithMergedHeaders(null, {
926
- status: 308,
927
- headers: { Location: match.redirect },
1087
+ return createResponseWithMergedHeaders(htmlStream, {
1088
+ status: 404,
1089
+ headers: { "content-type": "text/html;charset=utf-8" },
928
1090
  });
929
1091
  }
930
1092
 
931
- const renderStart = performance.now();
932
- const root = renderSegments(match.segments, {
933
- rootLayout: router.rootLayout,
934
- routeMap,
935
- routeName: match.routeName,
936
- });
937
- const renderDuration = performance.now() - renderStart;
938
- serverTiming = match.serverTiming
939
- ? `${match.serverTiming}, rendering;dur=${renderDuration.toFixed(2)}`
940
- : `rendering;dur=${renderDuration.toFixed(2)}`;
941
-
942
- payload = {
943
- root,
944
- metadata: {
945
- pathname: url.pathname,
946
- segments: match.segments,
947
- matched: match.matched,
948
- diff: match.diff,
949
- isPartial: false,
950
- handles: handleStore.stream(),
951
- version,
952
- themeConfig: router.themeConfig,
953
- initialTheme: requireRequestContext().theme,
954
- routeMap,
955
- routeName: match.routeName,
956
- },
957
- };
958
- } else {
959
- setRequestContextParams(result.params);
960
- serverTiming = result.serverTiming;
961
-
962
- payload = {
963
- root: null,
964
- metadata: {
965
- pathname: url.pathname,
966
- segments: result.segments,
967
- matched: result.matched,
968
- diff: result.diff,
969
- isPartial: true,
970
- slots: result.slots,
971
- handles: handleStore.stream(),
972
- version,
973
- routeMap,
974
- routeName: result.routeName,
975
- },
976
- };
977
- }
978
- } else {
979
- // Full render (initial page load)
980
- const match = await router.match(request, env);
981
- setRequestContextParams(match.params);
982
-
983
- if (match.redirect) {
984
- return createResponseWithMergedHeaders(null, {
985
- status: 308,
986
- headers: { Location: match.redirect },
1093
+ // Report unhandled errors
1094
+ callOnError(error, "routing", {
1095
+ request,
1096
+ url,
1097
+ env,
1098
+ handledByBoundary: false,
987
1099
  });
1100
+ console.error(`[RSC] Error:`, error);
1101
+ throw error;
988
1102
  }
1103
+ };
989
1104
 
990
- // Caching is now handled in router.match() via cache provider in request context
991
- // match.segments already contains cached or fresh segments as appropriate
992
-
993
- const renderStart = performance.now();
994
- const root = renderSegments(match.segments, {
995
- rootLayout: router.rootLayout,
996
- routeMap,
997
- routeName: match.routeName,
998
- });
999
- const renderDuration = performance.now() - renderStart;
1000
- serverTiming = match.serverTiming
1001
- ? `${match.serverTiming}, rendering;dur=${renderDuration.toFixed(2)}`
1002
- : `rendering;dur=${renderDuration.toFixed(2)}`;
1003
-
1004
- payload = {
1005
- root,
1006
- metadata: {
1007
- pathname: url.pathname,
1008
- segments: match.segments,
1009
- matched: match.matched,
1010
- diff: match.diff,
1011
- isPartial: false,
1012
- rootLayout: router.rootLayout,
1013
- handles: handleStore.stream(),
1014
- version,
1015
- themeConfig: router.themeConfig,
1016
- initialTheme: requireRequestContext().theme,
1017
- routeMap,
1018
- routeName: match.routeName,
1019
- },
1020
- };
1021
- }
1022
-
1023
- // Serialize to RSC stream
1024
- const rscStream = renderToReadableStream<RscPayload>(payload);
1105
+ // Wrap the render path in a renderStartMs timeout
1106
+ const executeRender = async (): Promise<Response> => {
1107
+ if (routeMiddleware.length > 0) {
1108
+ const mwResponse = await executeMiddleware(
1109
+ buildRouteMiddlewareEntries<TEnv>(routeMiddleware),
1110
+ request,
1111
+ env,
1112
+ variables,
1113
+ renderHandler,
1114
+ routeReverse,
1115
+ );
1025
1116
 
1026
- // Determine if this is an RSC request or HTML request
1027
- const isRscRequest =
1028
- (!request.headers.get("accept")?.includes("text/html") &&
1029
- !url.searchParams.has("__html")) ||
1030
- url.searchParams.has("__rsc");
1117
+ if (isPartial || actionContinuation) {
1118
+ const intercepted = interceptRedirectForPartial(
1119
+ mwResponse,
1120
+ createRedirectFlightResponse,
1121
+ );
1122
+ if (intercepted) return intercepted;
1123
+ }
1031
1124
 
1032
- if (isRscRequest) {
1033
- const rscHeaders: Record<string, string> = {
1034
- "content-type": "text/x-component;charset=utf-8",
1035
- vary: "accept",
1036
- };
1037
- if (serverTiming) {
1038
- rscHeaders["Server-Timing"] = serverTiming;
1125
+ return finalizeResponse(mwResponse);
1039
1126
  }
1040
- return createResponseWithMergedHeaders(rscStream, {
1041
- headers: rscHeaders,
1042
- });
1043
- }
1044
-
1045
- // Delegate to SSR for HTML response
1046
- const ssrModule = await loadSSRModule();
1047
- const htmlStream = await ssrModule.renderHTML(rscStream, { nonce });
1048
1127
 
1049
- const htmlHeaders: Record<string, string> = {
1050
- "content-type": "text/html;charset=utf-8",
1128
+ return renderHandler();
1051
1129
  };
1052
- if (serverTiming) {
1053
- htmlHeaders["Server-Timing"] = serverTiming;
1054
- }
1055
1130
 
1056
- return createResponseWithMergedHeaders(htmlStream, {
1057
- headers: htmlHeaders,
1058
- });
1131
+ const renderOutcome = await withTimeout(
1132
+ executeRender(),
1133
+ router.timeouts.renderStartMs,
1134
+ "render-start",
1135
+ );
1136
+ if (renderOutcome.timedOut) {
1137
+ return handleTimeoutResponse(
1138
+ request,
1139
+ env,
1140
+ url,
1141
+ "render-start",
1142
+ renderOutcome.durationMs,
1143
+ routeKey,
1144
+ );
1145
+ }
1146
+ return renderOutcome.result;
1059
1147
  }
1060
1148
  }