@rangojs/router 0.0.0-experimental.2 → 0.0.0-experimental.20

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