@rangojs/router 0.0.0-experimental.8 → 0.0.0-experimental.8123bb7e

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