@rangojs/router 0.0.0-experimental.259 → 0.0.0-experimental.25dbaac3

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