@rangojs/router 0.0.0-experimental.18 → 0.0.0-experimental.1878aa49

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 (1030) hide show
  1. package/{CLAUDE.md → AGENTS.md} +4 -0
  2. package/README.md +91 -19
  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 +348 -80
  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 +883 -444
  798. package/dist/vite/index.js.map +1 -0
  799. package/dist/vite/index.named-routes.gen.ts +103 -0
  800. package/dist/vite/package-resolution.d.ts +43 -0
  801. package/dist/vite/package-resolution.d.ts.map +1 -0
  802. package/dist/vite/package-resolution.js +112 -0
  803. package/dist/vite/package-resolution.js.map +1 -0
  804. package/dist/vite/virtual-entries.d.ts +25 -0
  805. package/dist/vite/virtual-entries.d.ts.map +1 -0
  806. package/dist/vite/virtual-entries.js +110 -0
  807. package/dist/vite/virtual-entries.js.map +1 -0
  808. package/package.json +17 -16
  809. package/skills/breadcrumbs/SKILL.md +250 -0
  810. package/skills/cache-guide/SKILL.md +32 -0
  811. package/skills/caching/SKILL.md +49 -8
  812. package/skills/document-cache/SKILL.md +2 -2
  813. package/skills/hooks/SKILL.md +34 -32
  814. package/skills/host-router/SKILL.md +218 -0
  815. package/skills/intercept/SKILL.md +79 -0
  816. package/skills/layout/SKILL.md +62 -2
  817. package/skills/links/SKILL.md +3 -1
  818. package/skills/loader/SKILL.md +166 -23
  819. package/skills/middleware/SKILL.md +83 -0
  820. package/skills/parallel/SKILL.md +183 -2
  821. package/skills/prerender/SKILL.md +189 -19
  822. package/skills/rango/SKILL.md +0 -1
  823. package/skills/route/SKILL.md +76 -5
  824. package/skills/router-setup/SKILL.md +172 -5
  825. package/skills/typesafety/SKILL.md +35 -23
  826. package/src/__internal.ts +93 -1
  827. package/src/bin/rango.ts +56 -19
  828. package/src/browser/action-coordinator.ts +97 -0
  829. package/src/browser/app-version.ts +14 -0
  830. package/src/browser/event-controller.ts +30 -27
  831. package/src/browser/history-state.ts +80 -0
  832. package/src/browser/intercept-utils.ts +1 -1
  833. package/src/browser/link-interceptor.ts +4 -3
  834. package/src/browser/merge-segment-loaders.ts +9 -2
  835. package/src/browser/navigation-bridge.ts +160 -31
  836. package/src/browser/navigation-client.ts +141 -88
  837. package/src/browser/navigation-store.ts +44 -39
  838. package/src/browser/navigation-transaction.ts +55 -214
  839. package/src/browser/partial-update.ts +181 -164
  840. package/src/browser/prefetch/cache.ts +206 -0
  841. package/src/browser/prefetch/fetch.ts +150 -0
  842. package/src/browser/prefetch/policy.ts +48 -0
  843. package/src/browser/prefetch/queue.ts +160 -0
  844. package/src/browser/prefetch/resource-ready.ts +77 -0
  845. package/src/browser/react/Link.tsx +97 -36
  846. package/src/browser/react/NavigationProvider.tsx +49 -5
  847. package/src/browser/react/context.ts +7 -2
  848. package/src/browser/react/index.ts +2 -6
  849. package/src/browser/react/location-state-shared.ts +1 -1
  850. package/src/browser/react/location-state.ts +2 -0
  851. package/src/browser/react/nonce-context.ts +23 -0
  852. package/src/browser/react/use-action.ts +9 -1
  853. package/src/browser/react/use-handle.ts +3 -25
  854. package/src/browser/react/use-params.ts +2 -4
  855. package/src/browser/react/use-pathname.ts +2 -3
  856. package/src/browser/react/use-router.ts +22 -9
  857. package/src/browser/react/use-search-params.ts +2 -1
  858. package/src/browser/react/use-segments.ts +7 -60
  859. package/src/browser/response-adapter.ts +73 -0
  860. package/src/browser/rsc-router.tsx +154 -64
  861. package/src/browser/scroll-restoration.ts +37 -37
  862. package/src/browser/segment-reconciler.ts +6 -1
  863. package/src/browser/server-action-bridge.ts +463 -426
  864. package/src/browser/types.ts +61 -36
  865. package/src/browser/validate-redirect-origin.ts +29 -0
  866. package/src/build/generate-manifest.ts +8 -0
  867. package/src/build/generate-route-types.ts +7 -0
  868. package/src/build/route-trie.ts +19 -3
  869. package/src/build/route-types/codegen.ts +13 -4
  870. package/src/build/route-types/include-resolution.ts +21 -1
  871. package/src/build/route-types/per-module-writer.ts +15 -3
  872. package/src/build/route-types/router-processing.ts +391 -90
  873. package/src/build/runtime-discovery.ts +13 -1
  874. package/src/cache/background-task.ts +34 -0
  875. package/src/cache/cache-key-utils.ts +44 -0
  876. package/src/cache/cache-policy.ts +125 -0
  877. package/src/cache/cache-runtime.ts +136 -96
  878. package/src/cache/cache-scope.ts +119 -80
  879. package/src/cache/cf/cf-cache-store.ts +462 -15
  880. package/src/cache/cf/index.ts +5 -1
  881. package/src/cache/document-cache.ts +88 -53
  882. package/src/cache/handle-capture.ts +81 -0
  883. package/src/cache/index.ts +1 -0
  884. package/src/cache/memory-segment-store.ts +18 -7
  885. package/src/cache/profile-registry.ts +43 -8
  886. package/src/cache/read-through-swr.ts +134 -0
  887. package/src/cache/segment-codec.ts +101 -112
  888. package/src/cache/taint.ts +81 -0
  889. package/src/client.rsc.tsx +2 -1
  890. package/src/client.tsx +54 -76
  891. package/src/context-var.ts +72 -2
  892. package/src/debug.ts +2 -2
  893. package/src/errors.ts +6 -1
  894. package/src/handle.ts +1 -1
  895. package/src/handles/MetaTags.tsx +5 -2
  896. package/src/handles/breadcrumbs.ts +66 -0
  897. package/src/handles/index.ts +1 -0
  898. package/src/host/cookie-handler.ts +8 -3
  899. package/src/host/index.ts +0 -3
  900. package/src/host/router.ts +14 -1
  901. package/src/href-client.ts +3 -1
  902. package/src/index.rsc.ts +24 -23
  903. package/src/index.ts +45 -52
  904. package/src/loader.rsc.ts +12 -4
  905. package/src/loader.ts +8 -0
  906. package/src/prerender/store.ts +60 -18
  907. package/src/prerender.ts +76 -18
  908. package/src/reverse.ts +11 -7
  909. package/src/root-error-boundary.tsx +30 -26
  910. package/src/route-definition/dsl-helpers.ts +41 -13
  911. package/src/route-definition/helpers-types.ts +6 -5
  912. package/src/route-definition/index.ts +0 -3
  913. package/src/route-definition/redirect.ts +24 -4
  914. package/src/route-map-builder.ts +45 -3
  915. package/src/route-name.ts +53 -0
  916. package/src/route-types.ts +7 -0
  917. package/src/router/content-negotiation.ts +1 -1
  918. package/src/router/debug-manifest.ts +16 -3
  919. package/src/router/find-match.ts +4 -2
  920. package/src/router/handler-context.ts +159 -34
  921. package/src/router/intercept-resolution.ts +17 -8
  922. package/src/router/lazy-includes.ts +8 -1
  923. package/src/router/loader-resolution.ts +11 -3
  924. package/src/router/logging.ts +104 -4
  925. package/src/router/manifest.ts +45 -7
  926. package/src/router/match-api.ts +62 -8
  927. package/src/router/match-context.ts +3 -0
  928. package/src/router/match-handlers.ts +185 -11
  929. package/src/router/match-middleware/background-revalidation.ts +94 -86
  930. package/src/router/match-middleware/cache-lookup.ts +138 -13
  931. package/src/router/match-middleware/cache-store.ts +55 -10
  932. package/src/router/match-middleware/intercept-resolution.ts +9 -7
  933. package/src/router/match-middleware/segment-resolution.ts +8 -5
  934. package/src/router/match-pipelines.ts +8 -43
  935. package/src/router/match-result.ts +22 -15
  936. package/src/router/metrics.ts +238 -13
  937. package/src/router/middleware-types.ts +60 -12
  938. package/src/router/middleware.ts +214 -42
  939. package/src/router/pattern-matching.ts +61 -10
  940. package/src/router/prerender-match.ts +40 -8
  941. package/src/router/preview-match.ts +7 -1
  942. package/src/router/revalidation.ts +87 -8
  943. package/src/router/router-context.ts +20 -0
  944. package/src/router/router-interfaces.ts +73 -5
  945. package/src/router/router-options.ts +250 -19
  946. package/src/router/segment-resolution/fresh.ts +277 -45
  947. package/src/router/segment-resolution/helpers.ts +49 -25
  948. package/src/router/segment-resolution/loader-cache.ts +38 -146
  949. package/src/router/segment-resolution/revalidation.ts +619 -275
  950. package/src/router/segment-wrappers.ts +5 -0
  951. package/src/router/telemetry-otel.ts +299 -0
  952. package/src/router/telemetry.ts +300 -0
  953. package/src/router/timeout.ts +148 -0
  954. package/src/router/trie-matching.ts +20 -2
  955. package/src/router/types.ts +8 -1
  956. package/src/router.ts +230 -25
  957. package/src/rsc/handler-context.ts +11 -0
  958. package/src/rsc/handler.ts +492 -96
  959. package/src/rsc/helpers.ts +25 -16
  960. package/src/rsc/index.ts +0 -20
  961. package/src/rsc/loader-fetch.ts +84 -42
  962. package/src/rsc/manifest-init.ts +5 -1
  963. package/src/rsc/origin-guard.ts +141 -0
  964. package/src/rsc/progressive-enhancement.ts +249 -19
  965. package/src/rsc/response-route-handler.ts +37 -26
  966. package/src/rsc/rsc-rendering.ts +40 -41
  967. package/src/rsc/runtime-warnings.ts +42 -0
  968. package/src/rsc/server-action.ts +150 -68
  969. package/src/rsc/ssr-setup.ts +128 -0
  970. package/src/rsc/types.ts +18 -1
  971. package/src/search-params.ts +38 -23
  972. package/src/segment-system.tsx +140 -4
  973. package/src/server/context.ts +187 -20
  974. package/src/server/fetchable-loader-store.ts +11 -6
  975. package/src/server/handle-store.ts +66 -9
  976. package/src/server/loader-registry.ts +20 -54
  977. package/src/server/request-context.ts +188 -41
  978. package/src/server.ts +6 -0
  979. package/src/ssr/index.tsx +66 -26
  980. package/src/static-handler.ts +7 -0
  981. package/src/theme/ThemeProvider.tsx +6 -1
  982. package/src/theme/index.ts +4 -18
  983. package/src/theme/theme-context.ts +1 -28
  984. package/src/theme/theme-script.ts +2 -1
  985. package/src/types/cache-types.ts +9 -4
  986. package/src/types/error-types.ts +3 -0
  987. package/src/types/global-namespace.ts +9 -0
  988. package/src/types/handler-context.ts +167 -55
  989. package/src/types/loader-types.ts +11 -5
  990. package/src/types/route-config.ts +17 -8
  991. package/src/types/route-entry.ts +35 -0
  992. package/src/types/segments.ts +2 -5
  993. package/src/urls/include-helper.ts +49 -8
  994. package/src/urls/index.ts +1 -0
  995. package/src/urls/path-helper-types.ts +30 -12
  996. package/src/urls/path-helper.ts +18 -3
  997. package/src/urls/pattern-types.ts +33 -1
  998. package/src/urls/response-types.ts +27 -2
  999. package/src/urls/type-extraction.ts +23 -15
  1000. package/src/use-loader.tsx +12 -4
  1001. package/src/vite/discovery/bundle-postprocess.ts +32 -52
  1002. package/src/vite/discovery/discover-routers.ts +53 -23
  1003. package/src/vite/discovery/prerender-collection.ts +58 -41
  1004. package/src/vite/discovery/route-types-writer.ts +7 -7
  1005. package/src/vite/discovery/state.ts +4 -9
  1006. package/src/vite/discovery/virtual-module-codegen.ts +5 -2
  1007. package/src/vite/index.ts +4 -3
  1008. package/src/vite/plugin-types.ts +0 -83
  1009. package/src/vite/plugins/client-ref-dedup.ts +115 -0
  1010. package/src/vite/plugins/client-ref-hashing.ts +3 -3
  1011. package/src/vite/plugins/expose-action-id.ts +1 -3
  1012. package/src/vite/plugins/performance-tracks.ts +88 -0
  1013. package/src/vite/plugins/refresh-cmd.ts +65 -0
  1014. package/src/vite/plugins/use-cache-transform.ts +91 -3
  1015. package/src/vite/plugins/version-plugin.ts +13 -1
  1016. package/src/vite/rango.ts +172 -210
  1017. package/src/vite/router-discovery.ts +115 -44
  1018. package/src/vite/utils/banner.ts +3 -3
  1019. package/src/vite/utils/prerender-utils.ts +81 -0
  1020. package/src/vite/utils/shared-utils.ts +6 -3
  1021. package/skills/testing/SKILL.md +0 -226
  1022. package/src/browser/prefetch-cache.ts +0 -48
  1023. package/src/browser/prefetch-fetch.ts +0 -109
  1024. package/src/browser/prefetch-queue.ts +0 -81
  1025. package/src/browser/request-controller.ts +0 -164
  1026. package/src/route-definition/route-function.ts +0 -119
  1027. package/src/router.gen.ts +0 -6
  1028. package/src/static-handler.gen.ts +0 -5
  1029. package/src/urls.gen.ts +0 -8
  1030. /package/src/browser/{prefetch-observer.ts → prefetch/observer.ts} +0 -0
@@ -9,7 +9,6 @@ import {
9
9
  reconcileSegments,
10
10
  reconcileErrorSegments,
11
11
  } from "./segment-reconciler.js";
12
- import { classifyActionResponse } from "./action-response-classifier.js";
13
12
  import { startTransition } from "react";
14
13
  import type { EventController } from "./event-controller.js";
15
14
  import {
@@ -22,6 +21,15 @@ import {
22
21
  isBrowserDebugEnabled,
23
22
  startBrowserTransaction,
24
23
  } from "./logging.js";
24
+ import { validateRedirectOrigin } from "./validate-redirect-origin.js";
25
+ import {
26
+ extractRscHeaderUrl,
27
+ emptyResponse,
28
+ teeWithCompletion,
29
+ } from "./response-adapter.js";
30
+ import { mergeLocationState } from "./history-state.js";
31
+ import { classifyActionOutcome } from "./action-coordinator.js";
32
+ import { getAppVersion } from "./app-version.js";
25
33
 
26
34
  // Polyfill Symbol.dispose/asyncDispose for Safari and older browsers
27
35
  if (typeof Symbol.dispose === "undefined") {
@@ -36,8 +44,6 @@ if (typeof Symbol.asyncDispose === "undefined") {
36
44
  */
37
45
  export interface ServerActionBridgeConfigWithController extends ServerActionBridgeConfig {
38
46
  eventController: EventController;
39
- /** RSC version from initial payload metadata */
40
- version?: string;
41
47
  /** Callback to trigger SPA navigation (for action redirects) */
42
48
  onNavigate?: (
43
49
  url: string,
@@ -68,7 +74,6 @@ export function createServerActionBridge(
68
74
  deps,
69
75
  onUpdate,
70
76
  renderSegments,
71
- version,
72
77
  onNavigate,
73
78
  } = config;
74
79
 
@@ -79,7 +84,7 @@ export function createServerActionBridge(
79
84
  client,
80
85
  onUpdate,
81
86
  renderSegments,
82
- version,
87
+ getVersion: getAppVersion,
83
88
  });
84
89
 
85
90
  /**
@@ -92,27 +97,31 @@ export function createServerActionBridge(
92
97
  interceptSourceUrl?: string | null;
93
98
  }): Promise<void> {
94
99
  const src = opts?.interceptSourceUrl ?? null;
95
- using navTx = createNavigationTransaction(
100
+ const navTx = createNavigationTransaction(
96
101
  store,
97
102
  eventController,
98
103
  window.location.href,
99
104
  { replace: true, skipLoadingState: true },
100
105
  );
101
- await fetchPartialUpdate(
102
- window.location.href,
103
- opts?.segments ?? [],
104
- false,
105
- navTx.handle.signal,
106
- navTx.with({
107
- url: window.location.href,
108
- storeOnly: true,
109
- ...(src ? { intercept: true, interceptSourceUrl: src } : {}),
110
- }),
111
- {
112
- isAction: true,
113
- ...(src ? { interceptSourceUrl: src } : {}),
114
- },
115
- );
106
+ try {
107
+ await fetchPartialUpdate(
108
+ window.location.href,
109
+ opts?.segments ?? [],
110
+ false,
111
+ navTx.handle.signal,
112
+ navTx.with({
113
+ url: window.location.href,
114
+ storeOnly: true,
115
+ ...(src ? { intercept: true, interceptSourceUrl: src } : {}),
116
+ }),
117
+ {
118
+ type: "action" as const,
119
+ ...(src ? { interceptSourceUrl: src } : {}),
120
+ },
121
+ );
122
+ } finally {
123
+ navTx[Symbol.dispose]();
124
+ }
116
125
  }
117
126
 
118
127
  /**
@@ -130,406 +139,499 @@ export function createServerActionBridge(
130
139
  log("action start", { id, argsCount: args.length });
131
140
 
132
141
  // Start action in event controller - handles lifecycle tracking
133
- using handle = eventController.startAction(id, args);
134
-
135
- const segmentState = store.getSegmentState();
142
+ const handle = eventController.startAction(id, args);
143
+ try {
144
+ const segmentState = store.getSegmentState();
145
+
146
+ // Mark cache as stale immediately when action starts
147
+ // This ensures SWR pattern kicks in if user navigates away during action
148
+ store.markCacheAsStaleAndBroadcast();
149
+
150
+ // Create temporary references for serialization
151
+ const temporaryReferences = deps.createTemporaryReferenceSet();
152
+
153
+ // Capture URL pathname at action start to detect navigation during action
154
+ // Must use window.location (not store.path) because intercepts change URL
155
+ // without changing store.path (e.g., /kanban -> /kanban/card/1)
156
+ const actionStartPathname = window.location.pathname;
157
+
158
+ // Build action request URL with current segments
159
+ const url = new URL(window.location.href);
160
+ url.searchParams.set("_rsc_action", id);
161
+ url.searchParams.set(
162
+ "_rsc_segments",
163
+ segmentState.currentSegmentIds.join(","),
164
+ );
165
+ // Add version param for version mismatch detection
166
+ const version = getAppVersion();
167
+ if (version) {
168
+ url.searchParams.set("_rsc_v", version);
169
+ }
170
+ // Add router ID for app switch detection
171
+ const rid = store.getRouterId?.();
172
+ if (rid) {
173
+ url.searchParams.set("_rsc_rid", rid);
174
+ }
136
175
 
137
- // Mark cache as stale immediately when action starts
138
- // This ensures SWR pattern kicks in if user navigates away during action
139
- store.markCacheAsStaleAndBroadcast();
176
+ // Encode arguments
177
+ const encodedBody = await deps.encodeReply(args, { temporaryReferences });
140
178
 
141
- // Create temporary references for serialization
142
- const temporaryReferences = deps.createTemporaryReferenceSet();
179
+ log("sending action request", {
180
+ url: url.href,
181
+ bodyType: typeof encodedBody,
182
+ isFormData: encodedBody instanceof FormData,
183
+ segmentCount: segmentState.currentSegmentIds.length,
184
+ });
143
185
 
144
- // Capture URL pathname at action start to detect navigation during action
145
- // Must use window.location (not store.path) because intercepts change URL
146
- // without changing store.path (e.g., /kanban -> /kanban/card/1)
147
- const actionStartPathname = window.location.pathname;
186
+ // Track when the stream completes
187
+ let resolveStreamComplete: () => void;
188
+ const streamComplete = new Promise<void>((resolve) => {
189
+ resolveStreamComplete = resolve;
190
+ });
148
191
 
149
- // Build action request URL with current segments
150
- const url = new URL(window.location.href);
151
- url.searchParams.set("_rsc_action", id);
152
- url.searchParams.set(
153
- "_rsc_segments",
154
- segmentState.currentSegmentIds.join(","),
155
- );
156
- // Add version param for version mismatch detection
157
- if (version) {
158
- url.searchParams.set("_rsc_v", version);
159
- }
192
+ // Get intercept source URL if in intercept context
193
+ const interceptSourceUrl = store.getInterceptSourceUrl();
194
+
195
+ // Track streaming token - will be set when response arrives
196
+ let streamingToken: { end(): void } | null = null;
197
+
198
+ // Use a dedicated abort controller for the fetch so we can cancel network
199
+ // I/O without disrupting the Flight stream once the response has arrived.
200
+ // Aborting a response mid-stream causes React's Flight decoder to throw
201
+ // asynchronous unhandled errors (BodyStreamBuffer was aborted).
202
+ const fetchAbort = new AbortController();
203
+ const onHandleAbort = () => fetchAbort.abort();
204
+ handle.signal.addEventListener("abort", onHandleAbort, { once: true });
205
+
206
+ // Send action request with stream tracking
207
+ const responsePromise = fetch(url, {
208
+ method: "POST",
209
+ headers: {
210
+ "rsc-action": id,
211
+ "X-RSC-Router-Client-Path": segmentState.currentUrl,
212
+ ...(tx && { "X-RSC-Router-Request-Id": tx.requestId }),
213
+ ...(interceptSourceUrl && {
214
+ "X-RSC-Router-Intercept-Source": interceptSourceUrl,
215
+ }),
216
+ },
217
+ body: encodedBody,
218
+ signal: fetchAbort.signal,
219
+ }).then(async (response) => {
220
+ // Response arrived — disconnect fetch abort from handle abort so
221
+ // abortAllActions() doesn't disrupt the in-progress Flight stream.
222
+ handle.signal.removeEventListener("abort", onHandleAbort);
223
+
224
+ // Check for version mismatch - server wants us to reload
225
+ const reload = extractRscHeaderUrl(response, "X-RSC-Reload");
226
+ if (reload === "blocked") {
227
+ resolveStreamComplete();
228
+ return emptyResponse();
229
+ }
230
+ if (reload) {
231
+ log("version mismatch on action, reloading", {
232
+ reloadUrl: reload.url,
233
+ });
234
+ window.location.href = reload.url;
235
+ return new Promise<Response>(() => {});
236
+ }
160
237
 
161
- // Encode arguments
162
- const encodedBody = await deps.encodeReply(args, { temporaryReferences });
163
-
164
- log("sending action request", {
165
- url: url.href,
166
- bodyType: typeof encodedBody,
167
- isFormData: encodedBody instanceof FormData,
168
- segmentCount: segmentState.currentSegmentIds.length,
169
- });
170
-
171
- // Track when the stream completes
172
- let resolveStreamComplete: () => void;
173
- const streamComplete = new Promise<void>((resolve) => {
174
- resolveStreamComplete = resolve;
175
- });
176
-
177
- // Get intercept source URL if in intercept context
178
- const interceptSourceUrl = store.getInterceptSourceUrl();
179
-
180
- // Track streaming token - will be set when response arrives
181
- let streamingToken: { end(): void } | null = null;
182
-
183
- // Send action request with stream tracking
184
- const responsePromise = fetch(url, {
185
- method: "POST",
186
- headers: {
187
- "rsc-action": id,
188
- "X-RSC-Router-Client-Path": segmentState.currentUrl,
189
- ...(tx && { "X-RSC-Router-Request-Id": tx.requestId }),
190
- // Send intercept source URL so server can maintain intercept context
191
- ...(interceptSourceUrl && {
192
- "X-RSC-Router-Intercept-Source": interceptSourceUrl,
193
- }),
194
- },
195
- body: encodedBody,
196
- }).then(async (response) => {
197
- // Check for version mismatch - server wants us to reload
198
- const reloadUrl = response.headers.get("X-RSC-Reload");
199
- if (reloadUrl) {
200
- // Validate origin to prevent open redirect via crafted headers
201
- try {
202
- const target = new URL(reloadUrl, window.location.origin);
203
- if (target.origin !== window.location.origin) {
204
- throw new Error(
205
- `X-RSC-Reload blocked: origin mismatch (${target.origin})`,
206
- );
238
+ // Simple redirect from action (no state, no RSC payload).
239
+ // Short-circuits before createFromFetch no Flight deserialization needed.
240
+ // Check handle.signal.aborted to avoid redirecting from a stale action
241
+ // when the user has already navigated away.
242
+ const redirect = extractRscHeaderUrl(response, "X-RSC-Redirect");
243
+ if (redirect && redirect !== "blocked" && !handle.signal.aborted) {
244
+ log("action simple redirect", { url: redirect.url });
245
+ handle.complete(undefined);
246
+ if (onNavigate) {
247
+ await onNavigate(redirect.url, {
248
+ replace: true,
249
+ _skipCache: true,
250
+ });
251
+ } else {
252
+ window.location.href = redirect.url;
207
253
  }
208
- } catch (e) {
209
- console.error("[rango]", e);
210
- return response;
254
+ return new Promise<Response>(() => {});
255
+ }
256
+ if (redirect === "blocked") {
257
+ resolveStreamComplete();
258
+ return emptyResponse();
259
+ }
260
+
261
+ // Start streaming immediately when response arrives
262
+ if (!handle.signal.aborted) {
263
+ streamingToken = handle.startStreaming();
264
+ }
265
+
266
+ return teeWithCompletion(response, () => {
267
+ log("stream complete");
268
+ streamingToken?.end();
269
+ resolveStreamComplete();
270
+ });
271
+ });
272
+
273
+ // Deserialize response (MUST use same temporaryReferences)
274
+ let payload: RscPayload;
275
+ try {
276
+ payload = await deps.createFromFetch<RscPayload>(responsePromise, {
277
+ temporaryReferences,
278
+ });
279
+ } catch (error) {
280
+ // Clean up streaming token on error (may be null if fetch failed before .then() ran)
281
+ // The token is assigned in .then() callback which runs before this catch block,
282
+ // but TypeScript doesn't track cross-async assignments, so use type assertion
283
+ (streamingToken as { end(): void } | null)?.end();
284
+ // resolveStreamComplete is assigned in the Promise constructor so it's safe to call
285
+ resolveStreamComplete!();
286
+
287
+ // Silently swallow abort errors — the action was intentionally cancelled
288
+ // (e.g., user navigated away or abortAllActions was called).
289
+ // Return undefined instead of throwing to avoid surfacing as a page error.
290
+ // Check both DOMException AbortError and stream-level abort messages
291
+ // (BodyStreamBuffer was aborted) that propagate from the aborted fetch.
292
+ if (handle.signal.aborted) {
293
+ return undefined;
294
+ }
295
+
296
+ // Convert network-level errors to NetworkError for proper handling
297
+ const networkError = toNetworkError(error, {
298
+ url: url.toString(),
299
+ operation: "action",
300
+ });
301
+ if (networkError) {
302
+ handle.fail(networkError);
303
+ emitNetworkError(onUpdate, networkError, segmentState.currentUrl);
304
+ throw networkError;
211
305
  }
212
- log("version mismatch on action, reloading", { reloadUrl });
213
- window.location.href = reloadUrl;
214
- // Return a never-resolving promise to prevent further processing
215
- return new Promise<Response>(() => {});
306
+ throw error;
216
307
  }
217
308
 
218
- // Simple redirect from action (no state, no RSC payload).
219
- // Short-circuits before createFromFetch — no Flight deserialization needed.
309
+ log("action response received", {
310
+ isPartial: payload.metadata?.isPartial,
311
+ isError: payload.metadata?.isError,
312
+ matchedCount: payload.metadata?.matched?.length ?? 0,
313
+ diffCount: payload.metadata?.diff?.length ?? 0,
314
+ });
315
+ // Guard: if the action was aborted while streaming (e.g., user navigated
316
+ // away or abortAllActions fired), bail out before any reconcile/render/cache
317
+ // writes to avoid overwriting the current UI with stale action results.
318
+ if (handle.signal.aborted) {
319
+ log("action aborted after response, skipping reconciliation");
320
+ return undefined;
321
+ }
322
+
323
+ // Process response
324
+ const { metadata, returnValue } = payload;
325
+
326
+ // Handle action redirect: server converted the redirect to a Flight payload
327
+ // so we can perform SPA navigation instead of a full page reload.
220
328
  // Check handle.signal.aborted to avoid redirecting from a stale action
221
329
  // when the user has already navigated away.
222
- const simpleRedirectUrl = response.headers.get("X-RSC-Redirect");
223
- if (simpleRedirectUrl && !handle.signal.aborted) {
224
- if (tx) {
225
- browserDebugLog(tx, "action simple redirect", {
226
- url: simpleRedirectUrl,
330
+ if (metadata?.redirect && !handle.signal.aborted) {
331
+ const redirectUrl = validateRedirectOrigin(
332
+ metadata.redirect.url,
333
+ window.location.origin,
334
+ );
335
+ if (!redirectUrl) {
336
+ log("blocked action redirect payload", {
337
+ url: metadata.redirect.url,
227
338
  });
339
+ handle.complete(returnValue?.data);
340
+ return returnValue?.data;
228
341
  }
229
- handle.complete(undefined);
342
+ const redirectState = metadata.locationState;
343
+ log("action redirect", { url: redirectUrl });
344
+ handle.complete(returnValue?.data);
230
345
  if (onNavigate) {
231
- await onNavigate(simpleRedirectUrl, {
346
+ await onNavigate(redirectUrl, {
347
+ state: redirectState,
232
348
  replace: true,
233
349
  _skipCache: true,
234
350
  });
235
351
  } else {
236
- window.location.href = simpleRedirectUrl;
352
+ window.location.href = redirectUrl;
237
353
  }
238
- return new Promise<Response>(() => {});
354
+ return returnValue?.data;
239
355
  }
240
356
 
241
- // Start streaming immediately when response arrives
242
- if (!handle.signal.aborted) {
243
- streamingToken = handle.startStreaming();
357
+ // Bail out if the action was aborted after deserialization (e.g. user
358
+ // navigated away or abortAllActions was called while the Flight stream
359
+ // was being consumed). Without this check the code below would mutate
360
+ // the store / UI for a stale action.
361
+ if (handle.signal.aborted) {
362
+ log("action aborted after deserialization, skipping mutations");
363
+ return returnValue?.data;
244
364
  }
245
365
 
246
- if (!response.body) {
247
- // No body means stream is already complete
248
- streamingToken?.end();
249
- resolveStreamComplete();
250
- return response;
366
+ const { matched, diff, segments, isPartial, isError } = metadata || {};
367
+
368
+ // Log action result
369
+ if (returnValue && !returnValue.ok) {
370
+ console.error(`[Browser] Action failed:`, returnValue.data);
251
371
  }
252
372
 
253
- // Tee the stream: one for RSC runtime, one for tracking completion
254
- const [rscStream, trackingStream] = response.body.tee();
373
+ // Handle error responses with error boundary UI
374
+ if (isError && isPartial && segments && diff) {
375
+ log("processing error boundary response");
255
376
 
256
- // Consume the tracking stream to detect when it closes
257
- (async () => {
258
- const reader = trackingStream.getReader();
259
- try {
260
- while (true) {
261
- const { done } = await reader.read();
262
- if (done) break;
263
- }
264
- } finally {
265
- reader.releaseLock();
266
- log("stream complete");
267
- streamingToken?.end();
268
- resolveStreamComplete();
377
+ // Fail current handle BEFORE aborting all actions so the event controller
378
+ // records the error state (abortAllActions clears inflight entries)
379
+ if (returnValue && !returnValue.ok) {
380
+ handle.fail(returnValue.data);
269
381
  }
270
- })().catch((error) => {
271
- console.error("[STREAMING] Error reading tracking stream:", error);
272
- streamingToken?.end();
273
- });
274
382
 
275
- // Return response with the RSC stream
276
- return new Response(rscStream, {
277
- headers: response.headers,
278
- status: response.status,
279
- statusText: response.statusText,
280
- });
281
- });
383
+ // Abort all other pending action requests - error takes precedence
384
+ // This prevents other actions from completing and overwriting the error UI
385
+ eventController.abortAllActions();
282
386
 
283
- // Deserialize response (MUST use same temporaryReferences)
284
- let payload: RscPayload;
285
- try {
286
- payload = await deps.createFromFetch<RscPayload>(responsePromise, {
287
- temporaryReferences,
288
- });
289
- } catch (error) {
290
- // Clean up streaming token on error (may be null if fetch failed before .then() ran)
291
- // The token is assigned in .then() callback which runs before this catch block,
292
- // but TypeScript doesn't track cross-async assignments, so use type assertion
293
- (streamingToken as { end(): void } | null)?.end();
294
- // resolveStreamComplete is assigned in the Promise constructor so it's safe to call
295
- resolveStreamComplete!();
296
-
297
- // Convert network-level errors to NetworkError for proper handling
298
- const networkError = toNetworkError(error, {
299
- url: url.toString(),
300
- operation: "action",
301
- });
302
- if (networkError) {
303
- handle.fail(networkError);
304
- emitNetworkError(onUpdate, networkError, segmentState.currentUrl);
305
- throw networkError;
306
- }
307
- throw error;
308
- }
387
+ // Clear concurrent action tracking - no consolidation needed when showing error
388
+ handle.clearConsolidation();
389
+
390
+ // Get current page's cached segments
391
+ const currentKey = store.getHistoryKey();
392
+ const cached = store.getCachedSegments(currentKey);
393
+ const cachedSegments = cached?.segments || [];
394
+
395
+ // Reconcile error segments with cached tree
396
+ const errorResult = reconcileErrorSegments(cachedSegments, segments);
309
397
 
310
- log("action response received", {
311
- isPartial: payload.metadata?.isPartial,
312
- isError: payload.metadata?.isError,
313
- matchedCount: payload.metadata?.matched?.length ?? 0,
314
- diffCount: payload.metadata?.diff?.length ?? 0,
315
- });
316
-
317
- // Process response
318
- const { metadata, returnValue } = payload;
319
-
320
- // Handle action redirect: server converted the redirect to a Flight payload
321
- // so we can perform SPA navigation instead of a full page reload.
322
- // Check handle.signal.aborted to avoid redirecting from a stale action
323
- // when the user has already navigated away.
324
- if (metadata?.redirect && !handle.signal.aborted) {
325
- const { url: redirectUrl } = metadata.redirect;
326
- const redirectState = metadata.locationState;
327
- console.log(`[Browser] Action redirect to ${redirectUrl}`);
328
- handle.complete(returnValue?.data);
329
- if (onNavigate) {
330
- await onNavigate(redirectUrl, {
331
- state: redirectState,
332
- replace: true,
333
- _skipCache: true,
398
+ // Render the full tree with error segment merged with parent layouts
399
+ const errorTree = await renderSegments(errorResult.mainSegments, {
400
+ isAction: true,
401
+ interceptSegments:
402
+ errorResult.interceptSegments.length > 0
403
+ ? errorResult.interceptSegments
404
+ : undefined,
334
405
  });
335
- } else {
336
- window.location.href = redirectUrl;
337
- }
338
- return returnValue?.data;
339
- }
340
406
 
341
- const { matched, diff, segments, isPartial, isError } = metadata || {};
407
+ // Re-check route stability after async renderSegments user may have
408
+ // navigated away while the error tree was being prepared.
409
+ if (window.location.pathname !== actionStartPathname) {
410
+ log("user navigated during error render, skipping");
411
+ if (returnValue && !returnValue.ok) {
412
+ throw returnValue.data;
413
+ }
414
+ handle.complete(undefined);
415
+ return undefined;
416
+ }
417
+ const currentKeyNow = store.getHistoryKey();
418
+ if (currentKeyNow !== currentKey) {
419
+ log("history key changed during error render, skipping cache update");
420
+ if (returnValue && !returnValue.ok) {
421
+ throw returnValue.data;
422
+ }
423
+ handle.complete(undefined);
424
+ return undefined;
425
+ }
342
426
 
343
- // Log action result
344
- if (returnValue && !returnValue.ok) {
345
- console.error(`[Browser] Action failed:`, returnValue.data);
346
- }
427
+ // Update UI with error boundary
428
+ startTransition(() => {
429
+ onUpdate({ root: errorTree, metadata: metadata! });
430
+ });
431
+
432
+ // Update segment tracking to exclude error segment IDs
433
+ const errorSegmentIds = new Set(diff);
434
+ const segmentIdsAfterError = segmentState.currentSegmentIds.filter(
435
+ (id) => !errorSegmentIds.has(id),
436
+ );
437
+
438
+ // Update store state
439
+ store.setSegmentIds(segmentIdsAfterError);
440
+ const currentHandleData = eventController.getHandleState().data;
441
+ store.cacheSegmentsForHistory(
442
+ currentKey,
443
+ errorResult.segments,
444
+ currentHandleData,
445
+ );
446
+
447
+ // Throw the error so the action promise rejects
448
+ if (returnValue && !returnValue.ok) {
449
+ throw returnValue.data;
450
+ }
451
+
452
+ // No error in returnValue (shouldn't happen with isError: true)
453
+ handle.complete(undefined);
454
+ return undefined;
455
+ }
347
456
 
348
- // Handle error responses with error boundary UI
349
- if (isError && isPartial && segments && diff) {
350
- log("processing error boundary response");
457
+ if (!isPartial) {
458
+ // Protocol invariant: action revalidation responses MUST be partial.
459
+ // The server always sends isPartial: true for successful revalidation
460
+ // and isPartial: true + isError: true for error boundary responses.
461
+ // A non-partial payload here indicates a server-side bug.
462
+ throw new Error(
463
+ `[Browser] Action response missing isPartial — the server must ` +
464
+ `always send partial payloads for action revalidation.`,
465
+ );
466
+ }
351
467
 
352
- // Abort all other pending action requests - error takes precedence
353
- // This prevents other actions from completing and overwriting the error UI
354
- eventController.abortAllActions();
468
+ log("processing partial update", {
469
+ serverSegments: segments?.length ?? 0,
470
+ diff: diff?.join(", ") ?? "",
471
+ matched: matched?.join(", ") ?? "",
472
+ });
355
473
 
356
- // Clear concurrent action tracking - no consolidation needed when showing error
357
- handle.clearConsolidation();
474
+ // Record revalidated segments for concurrent action tracking
475
+ if (diff) {
476
+ handle.recordRevalidatedSegments(diff);
477
+ }
358
478
 
359
- // Get current page's cached segments
479
+ // Get current page's cached segments for merging
360
480
  const currentKey = store.getHistoryKey();
361
481
  const cached = store.getCachedSegments(currentKey);
362
482
  const cachedSegments = cached?.segments || [];
363
483
 
364
- // Reconcile error segments with cached tree
365
- const errorResult = reconcileErrorSegments(cachedSegments, segments);
366
-
367
- // Render the full tree with error segment merged with parent layouts
368
- const errorTree = await renderSegments(errorResult.mainSegments, {
369
- isAction: true,
370
- interceptSegments:
371
- errorResult.interceptSegments.length > 0
372
- ? errorResult.interceptSegments
373
- : undefined,
374
- });
484
+ if (!matched) {
485
+ throw new Error("No matched segments in response");
486
+ }
375
487
 
376
- // Update UI with error boundary
377
- startTransition(() => {
378
- onUpdate({ root: errorTree, metadata: metadata! });
488
+ // Reconcile server segments with cached segments (single source of truth)
489
+ const reconciled = reconcileSegments({
490
+ actor: "action",
491
+ matched,
492
+ diff: diff || [],
493
+ serverSegments: segments || [],
494
+ cachedSegments,
379
495
  });
496
+ const fullSegments = reconciled.segments;
380
497
 
381
- // Update segment tracking to exclude error segment IDs
382
- const errorSegmentIds = new Set(diff);
383
- const segmentIdsAfterError = segmentState.currentSegmentIds.filter(
384
- (id) => !errorSegmentIds.has(id),
385
- );
386
-
387
- // Update store state
388
- store.setSegmentIds(segmentIdsAfterError);
389
- const currentHandleData = eventController.getHandleState().data;
390
- store.cacheSegmentsForHistory(
391
- currentKey,
392
- errorResult.segments,
393
- currentHandleData,
394
- );
498
+ const returnData = returnValue?.data;
395
499
 
396
- // Throw the error so the action promise rejects
397
500
  if (returnValue && !returnValue.ok) {
398
501
  handle.fail(returnValue.data);
399
502
  throw returnValue.data;
400
503
  }
401
504
 
402
- // No error in returnValue (shouldn't happen with isError: true)
403
- handle.complete(undefined);
404
- return undefined;
405
- }
406
-
407
- if (!isPartial) {
408
- // Full update not supported for actions
409
- throw new Error(
410
- `[Browser] Full update after action is not supported yet`,
411
- );
412
- }
505
+ // Classify the post-reconciliation scenario
506
+ const scenario = classifyActionOutcome({
507
+ handleId: handle.id,
508
+ inflightActions: eventController.getInflightActions(),
509
+ hadAnyConcurrentActions: eventController.hadAnyConcurrentActions(),
510
+ revalidatedSegments: handle.getRevalidatedSegments(),
511
+ actionStartPathname,
512
+ currentPathname: window.location.pathname,
513
+ actionStartLocationKey: locationKey,
514
+ currentLocationKey: window.history.state?.key,
515
+ reconciledSegmentCount: fullSegments.length,
516
+ matchedCount: matched.length,
517
+ currentInterceptSource: store.getInterceptSourceUrl(),
518
+ });
413
519
 
414
- log("processing partial update", {
415
- serverSegments: segments?.length ?? 0,
416
- diff: diff?.join(", ") ?? "",
417
- matched: matched?.join(", ") ?? "",
418
- });
520
+ switch (scenario.type) {
521
+ case "navigated-away": {
522
+ log("user navigated away during action", {
523
+ from: actionStartPathname,
524
+ to: window.location.pathname,
525
+ historyKeyChanged: scenario.historyKeyChanged,
526
+ });
527
+ // Clear concurrent action tracking - don't consolidate for old route's segments
528
+ handle.clearConsolidation();
529
+
530
+ if (scenario.historyKeyChanged) {
531
+ if (!scenario.onInterceptRoute) {
532
+ store.markCacheAsStaleAndBroadcast();
533
+ refetchRoute().catch((error) => {
534
+ if (isBackgroundSuppressible(error)) return;
535
+ console.error(
536
+ "[Browser] Background revalidation failed:",
537
+ error,
538
+ );
539
+ });
540
+ }
541
+ break;
542
+ }
419
543
 
420
- // Record revalidated segments for concurrent action tracking
421
- if (diff) {
422
- handle.recordRevalidatedSegments(diff);
423
- }
544
+ // Same history key but different pathname - safe to refetch current route
545
+ store.markCacheAsStaleAndBroadcast();
546
+ await refetchRoute({
547
+ interceptSourceUrl: store.getInterceptSourceUrl(),
548
+ });
549
+ break;
550
+ }
424
551
 
425
- // Get current page's cached segments for merging
426
- const currentKey = store.getHistoryKey();
427
- const cached = store.getCachedSegments(currentKey);
428
- const cachedSegments = cached?.segments || [];
552
+ case "hmr-missing": {
553
+ console.warn(
554
+ `[Browser] Missing segments after action (HMR detected), refetching...`,
555
+ );
556
+ await refetchRoute({ interceptSourceUrl });
557
+ store.broadcastCacheInvalidation();
558
+ break;
559
+ }
429
560
 
430
- if (!matched) {
431
- throw new Error("No matched segments in response");
432
- }
561
+ case "consolidation-needed": {
562
+ log("consolidation fetch needed", {
563
+ segmentIds: scenario.segmentIds,
564
+ });
565
+ // Calculate segments to send (exclude the ones we want fresh)
566
+ const currentSegmentIds = store.getSegmentState().currentSegmentIds;
567
+ const segmentsToSend = currentSegmentIds.filter(
568
+ (sid) => !scenario.segmentIds.includes(sid),
569
+ );
433
570
 
434
- // Reconcile server segments with cached segments (single source of truth)
435
- const reconciled = reconcileSegments({
436
- actor: "action",
437
- matched,
438
- diff: diff || [],
439
- serverSegments: segments || [],
440
- cachedSegments,
441
- });
442
- const fullSegments = reconciled.segments;
443
-
444
- const returnData = returnValue?.data;
445
-
446
- if (returnValue && !returnValue.ok) {
447
- handle.fail(returnValue.data);
448
- throw returnValue.data;
449
- }
571
+ // Clear consolidation tracking before fetch
572
+ handle.clearConsolidation();
450
573
 
451
- // Classify the post-reconciliation scenario
452
- const consolidationSegments = handle.getConsolidationSegments();
453
- const otherFetchingActions = [
454
- ...eventController.getInflightActions().values(),
455
- ].filter((a) => a.phase === "fetching" && a.id !== handle.id);
456
-
457
- const scenario = classifyActionResponse({
458
- actionStartPathname,
459
- currentPathname: window.location.pathname,
460
- actionStartLocationKey: locationKey,
461
- currentLocationKey: window.history.state?.key,
462
- reconciledSegmentCount: fullSegments.length,
463
- matchedCount: matched.length,
464
- consolidationSegments: consolidationSegments || null,
465
- otherFetchingActionCount: otherFetchingActions.length,
466
- currentInterceptSource: store.getInterceptSourceUrl(),
467
- });
468
-
469
- switch (scenario.type) {
470
- case "navigated-away": {
471
- log("user navigated away during action", {
472
- from: actionStartPathname,
473
- to: window.location.pathname,
474
- historyKeyChanged: scenario.historyKeyChanged,
475
- });
476
- // Clear concurrent action tracking - don't consolidate for old route's segments
477
- handle.clearConsolidation();
574
+ await refetchRoute({
575
+ segments: segmentsToSend,
576
+ interceptSourceUrl,
577
+ });
578
+ store.broadcastCacheInvalidation();
579
+ break;
580
+ }
478
581
 
479
- if (scenario.historyKeyChanged) {
480
- if (!scenario.onInterceptRoute) {
481
- store.markCacheAsStaleAndBroadcast();
482
- refetchRoute().catch((error) => {
483
- if (isBackgroundSuppressible(error)) return;
484
- console.error("[Browser] Background revalidation failed:", error);
485
- });
582
+ case "concurrent-skip": {
583
+ log("skipping UI update, other actions fetching", {
584
+ otherCount: scenario.otherFetchingCount,
585
+ });
586
+ // Only update store if history key hasn't changed (user didn't navigate away)
587
+ const currentKeyNow = store.getHistoryKey();
588
+ if (currentKeyNow === currentKey) {
589
+ store.setSegmentIds(matched);
590
+ const currentHandleData = eventController.getHandleState().data;
591
+ store.cacheSegmentsForHistory(
592
+ currentKey,
593
+ fullSegments,
594
+ currentHandleData,
595
+ );
486
596
  }
487
597
  break;
488
598
  }
489
599
 
490
- // Same history key but different pathname - safe to refetch current route
491
- store.markCacheAsStaleAndBroadcast();
492
- await refetchRoute({
493
- interceptSourceUrl: store.getInterceptSourceUrl(),
494
- });
495
- break;
496
- }
600
+ case "normal": {
601
+ // Prepare new tree (await loader data resolution)
602
+ const newTree = await renderSegments(reconciled.mainSegments, {
603
+ isAction: true,
604
+ interceptSegments:
605
+ reconciled.interceptSegments.length > 0
606
+ ? reconciled.interceptSegments
607
+ : undefined,
608
+ });
497
609
 
498
- case "hmr-missing": {
499
- console.warn(
500
- `[Browser] Missing segments after action (HMR detected), refetching...`,
501
- );
502
- await refetchRoute({ interceptSourceUrl });
503
- store.broadcastCacheInvalidation();
504
- break;
505
- }
610
+ // Re-check if user navigated away (could happen during async renderSegments)
611
+ if (window.location.pathname !== actionStartPathname) {
612
+ log("user navigated during render, skipping");
613
+ break;
614
+ }
506
615
 
507
- case "consolidation-needed": {
508
- log("consolidation fetch needed", { segmentIds: scenario.segmentIds });
509
- // Calculate segments to send (exclude the ones we want fresh)
510
- const currentSegmentIds = store.getSegmentState().currentSegmentIds;
511
- const segmentsToSend = currentSegmentIds.filter(
512
- (sid) => !scenario.segmentIds.includes(sid),
513
- );
616
+ // Verify the store's current key still matches what we captured at action start
617
+ // If they differ, user navigated away and we should NOT cache under the old key
618
+ const currentKeyNow = store.getHistoryKey();
619
+ if (currentKeyNow !== currentKey) {
620
+ log("history key changed during action, skipping cache update");
621
+ break;
622
+ }
514
623
 
515
- // Clear consolidation tracking before fetch
516
- handle.clearConsolidation();
624
+ startTransition(() => {
625
+ onUpdate({ root: newTree, metadata: metadata! });
626
+ });
517
627
 
518
- await refetchRoute({
519
- segments: segmentsToSend,
520
- interceptSourceUrl,
521
- });
522
- store.broadcastCacheInvalidation();
523
- break;
524
- }
628
+ // Apply server-set location state to history.state (non-redirect flow)
629
+ const actionLocationState = metadata?.locationState;
630
+ if (actionLocationState) {
631
+ mergeLocationState(actionLocationState);
632
+ }
525
633
 
526
- case "concurrent-skip": {
527
- log("skipping UI update, other actions fetching", {
528
- otherCount: scenario.otherFetchingCount,
529
- });
530
- // Only update store if history key hasn't changed (user didn't navigate away)
531
- const currentKeyNow = store.getHistoryKey();
532
- if (currentKeyNow === currentKey) {
634
+ // Update store state
533
635
  store.setSegmentIds(matched);
534
636
  const currentHandleData = eventController.getHandleState().data;
535
637
  store.cacheSegmentsForHistory(
@@ -537,71 +639,16 @@ export function createServerActionBridge(
537
639
  fullSegments,
538
640
  currentHandleData,
539
641
  );
540
- }
541
- break;
542
- }
543
-
544
- case "normal": {
545
- // Prepare new tree (await loader data resolution)
546
- const newTree = await renderSegments(reconciled.mainSegments, {
547
- isAction: true,
548
- interceptSegments:
549
- reconciled.interceptSegments.length > 0
550
- ? reconciled.interceptSegments
551
- : undefined,
552
- });
553
-
554
- // Re-check if user navigated away (could happen during async renderSegments)
555
- if (window.location.pathname !== actionStartPathname) {
556
- log("user navigated during render, skipping");
557
- break;
558
- }
559
-
560
- // Verify the store's current key still matches what we captured at action start
561
- // If they differ, user navigated away and we should NOT cache under the old key
562
- const currentKeyNow = store.getHistoryKey();
563
- if (currentKeyNow !== currentKey) {
564
- log("history key changed during action, skipping cache update");
642
+ store.markCacheAsStaleAndBroadcast();
565
643
  break;
566
644
  }
567
-
568
- startTransition(() => {
569
- onUpdate({ root: newTree, metadata: metadata! });
570
- });
571
-
572
- // Apply server-set location state to history.state (non-redirect flow)
573
- const actionLocationState = metadata?.locationState;
574
- if (actionLocationState) {
575
- const merged = {
576
- ...window.history.state,
577
- ...actionLocationState,
578
- };
579
- window.history.replaceState(merged, "", window.location.href);
580
- // Notify useLocationState hooks so they re-read from history.state
581
- if (
582
- Object.keys(actionLocationState).some((k) =>
583
- k.startsWith("__rsc_ls_"),
584
- )
585
- ) {
586
- window.dispatchEvent(new Event("__rsc_locationstate"));
587
- }
588
- }
589
-
590
- // Update store state
591
- store.setSegmentIds(matched);
592
- const currentHandleData = eventController.getHandleState().data;
593
- store.cacheSegmentsForHistory(
594
- currentKey,
595
- fullSegments,
596
- currentHandleData,
597
- );
598
- store.markCacheAsStaleAndBroadcast();
599
- break;
600
645
  }
601
- }
602
646
 
603
- handle.complete(returnData);
604
- return returnData;
647
+ handle.complete(returnData);
648
+ return returnData;
649
+ } finally {
650
+ handle[Symbol.dispose]();
651
+ }
605
652
  }
606
653
 
607
654
  return {
@@ -616,16 +663,6 @@ export function createServerActionBridge(
616
663
  deps.setServerCallback(handleServerAction);
617
664
  isRegistered = true;
618
665
  },
619
-
620
- /**
621
- * Unregister the server action callback
622
- */
623
- unregister(): void {
624
- if (!isRegistered) {
625
- return;
626
- }
627
- isRegistered = false;
628
- },
629
666
  };
630
667
  }
631
668