vinext 0.0.46 → 0.0.48

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 (351) hide show
  1. package/README.md +8 -6
  2. package/dist/build/layout-classification.js +3 -1
  3. package/dist/build/layout-classification.js.map +1 -1
  4. package/dist/build/prerender.d.ts +2 -1
  5. package/dist/build/prerender.js +80 -24
  6. package/dist/build/prerender.js.map +1 -1
  7. package/dist/build/report.d.ts +9 -5
  8. package/dist/build/report.js +17 -7
  9. package/dist/build/report.js.map +1 -1
  10. package/dist/build/route-classification-injector.d.ts +35 -0
  11. package/dist/build/route-classification-injector.js +61 -0
  12. package/dist/build/route-classification-injector.js.map +1 -0
  13. package/dist/build/route-classification-manifest.d.ts +1 -1
  14. package/dist/build/run-prerender.d.ts +5 -0
  15. package/dist/build/run-prerender.js +4 -1
  16. package/dist/build/run-prerender.js.map +1 -1
  17. package/dist/build/server-manifest.js +2 -7
  18. package/dist/build/server-manifest.js.map +1 -1
  19. package/dist/build/standalone.js +3 -5
  20. package/dist/build/standalone.js.map +1 -1
  21. package/dist/build/static-export.d.ts +1 -1
  22. package/dist/check.js +45 -29
  23. package/dist/check.js.map +1 -1
  24. package/dist/cli-args.d.ts +33 -0
  25. package/dist/cli-args.js +121 -0
  26. package/dist/cli-args.js.map +1 -0
  27. package/dist/cli.js +11 -20
  28. package/dist/cli.js.map +1 -1
  29. package/dist/cloudflare/kv-cache-handler.js +29 -9
  30. package/dist/cloudflare/kv-cache-handler.js.map +1 -1
  31. package/dist/config/config-matchers.js +46 -37
  32. package/dist/config/config-matchers.js.map +1 -1
  33. package/dist/config/next-config.d.ts +4 -2
  34. package/dist/config/next-config.js +3 -0
  35. package/dist/config/next-config.js.map +1 -1
  36. package/dist/deploy.d.ts +18 -2
  37. package/dist/deploy.js +47 -4
  38. package/dist/deploy.js.map +1 -1
  39. package/dist/entries/app-rsc-entry.d.ts +4 -3
  40. package/dist/entries/app-rsc-entry.js +379 -858
  41. package/dist/entries/app-rsc-entry.js.map +1 -1
  42. package/dist/entries/app-rsc-manifest.d.ts +1 -1
  43. package/dist/entries/app-rsc-manifest.js +6 -1
  44. package/dist/entries/app-rsc-manifest.js.map +1 -1
  45. package/dist/entries/pages-client-entry.js +3 -2
  46. package/dist/entries/pages-client-entry.js.map +1 -1
  47. package/dist/entries/pages-server-entry.js +19 -61
  48. package/dist/entries/pages-server-entry.js.map +1 -1
  49. package/dist/entries/runtime-entry-module.d.ts +12 -3
  50. package/dist/entries/runtime-entry-module.js +15 -4
  51. package/dist/entries/runtime-entry-module.js.map +1 -1
  52. package/dist/index.js +40 -58
  53. package/dist/index.js.map +1 -1
  54. package/dist/plugins/fonts.js +54 -32
  55. package/dist/plugins/fonts.js.map +1 -1
  56. package/dist/plugins/og-assets.js +15 -16
  57. package/dist/plugins/og-assets.js.map +1 -1
  58. package/dist/plugins/rsc-client-shim-excludes.d.ts +2 -1
  59. package/dist/plugins/rsc-client-shim-excludes.js +11 -1
  60. package/dist/plugins/rsc-client-shim-excludes.js.map +1 -1
  61. package/dist/routing/app-route-graph.d.ts +195 -0
  62. package/dist/routing/app-route-graph.js +1022 -0
  63. package/dist/routing/app-route-graph.js.map +1 -0
  64. package/dist/routing/app-router.d.ts +14 -88
  65. package/dist/routing/app-router.js +21 -712
  66. package/dist/routing/app-router.js.map +1 -1
  67. package/dist/routing/file-matcher.d.ts +3 -1
  68. package/dist/routing/file-matcher.js +6 -1
  69. package/dist/routing/file-matcher.js.map +1 -1
  70. package/dist/routing/pages-router.js +10 -19
  71. package/dist/routing/pages-router.js.map +1 -1
  72. package/dist/routing/route-matching.d.ts +28 -0
  73. package/dist/routing/route-matching.js +44 -0
  74. package/dist/routing/route-matching.js.map +1 -0
  75. package/dist/routing/route-pattern.js +4 -1
  76. package/dist/routing/route-pattern.js.map +1 -1
  77. package/dist/routing/route-trie.d.ts +8 -0
  78. package/dist/routing/route-trie.js +12 -1
  79. package/dist/routing/route-trie.js.map +1 -1
  80. package/dist/routing/route-validation.js +3 -4
  81. package/dist/routing/route-validation.js.map +1 -1
  82. package/dist/routing/utils.d.ts +8 -1
  83. package/dist/routing/utils.js +25 -2
  84. package/dist/routing/utils.js.map +1 -1
  85. package/dist/server/app-browser-entry.js +145 -294
  86. package/dist/server/app-browser-entry.js.map +1 -1
  87. package/dist/server/app-browser-error.d.ts +3 -4
  88. package/dist/server/app-browser-error.js +8 -4
  89. package/dist/server/app-browser-error.js.map +1 -1
  90. package/dist/server/app-browser-navigation-controller.d.ts +75 -0
  91. package/dist/server/app-browser-navigation-controller.js +290 -0
  92. package/dist/server/app-browser-navigation-controller.js.map +1 -0
  93. package/dist/server/app-browser-state.d.ts +33 -15
  94. package/dist/server/app-browser-state.js +52 -59
  95. package/dist/server/app-browser-state.js.map +1 -1
  96. package/dist/server/app-browser-visible-commit.d.ts +68 -0
  97. package/dist/server/app-browser-visible-commit.js +182 -0
  98. package/dist/server/app-browser-visible-commit.js.map +1 -0
  99. package/dist/server/app-client-reference-preloader.d.ts +15 -0
  100. package/dist/server/app-client-reference-preloader.js +46 -0
  101. package/dist/server/app-client-reference-preloader.js.map +1 -0
  102. package/dist/server/app-elements-wire.d.ts +130 -0
  103. package/dist/server/app-elements-wire.js +205 -0
  104. package/dist/server/app-elements-wire.js.map +1 -0
  105. package/dist/server/app-elements.d.ts +2 -84
  106. package/dist/server/app-elements.js +4 -107
  107. package/dist/server/app-elements.js.map +1 -1
  108. package/dist/server/app-fallback-renderer.d.ts +57 -0
  109. package/dist/server/app-fallback-renderer.js +79 -0
  110. package/dist/server/app-fallback-renderer.js.map +1 -0
  111. package/dist/server/app-hook-warning-suppression.d.ts +7 -0
  112. package/dist/server/app-hook-warning-suppression.js +12 -0
  113. package/dist/server/app-hook-warning-suppression.js.map +1 -0
  114. package/dist/server/app-middleware.d.ts +2 -1
  115. package/dist/server/app-middleware.js +34 -11
  116. package/dist/server/app-middleware.js.map +1 -1
  117. package/dist/server/app-mounted-slots-header.d.ts +17 -0
  118. package/dist/server/app-mounted-slots-header.js +21 -0
  119. package/dist/server/app-mounted-slots-header.js.map +1 -0
  120. package/dist/server/app-page-boundary-render.d.ts +3 -3
  121. package/dist/server/app-page-boundary-render.js +8 -5
  122. package/dist/server/app-page-boundary-render.js.map +1 -1
  123. package/dist/server/app-page-boundary.js +2 -1
  124. package/dist/server/app-page-boundary.js.map +1 -1
  125. package/dist/server/app-page-cache.d.ts +19 -4
  126. package/dist/server/app-page-cache.js +60 -22
  127. package/dist/server/app-page-cache.js.map +1 -1
  128. package/dist/server/app-page-dispatch.d.ts +9 -5
  129. package/dist/server/app-page-dispatch.js +41 -17
  130. package/dist/server/app-page-dispatch.js.map +1 -1
  131. package/dist/server/app-page-element-builder.d.ts +61 -0
  132. package/dist/server/app-page-element-builder.js +142 -0
  133. package/dist/server/app-page-element-builder.js.map +1 -0
  134. package/dist/server/app-page-execution.d.ts +23 -5
  135. package/dist/server/app-page-execution.js +39 -24
  136. package/dist/server/app-page-execution.js.map +1 -1
  137. package/dist/server/app-page-head.js +2 -1
  138. package/dist/server/app-page-head.js.map +1 -1
  139. package/dist/server/app-page-method.js +2 -5
  140. package/dist/server/app-page-method.js.map +1 -1
  141. package/dist/server/app-page-params.d.ts +2 -1
  142. package/dist/server/app-page-params.js +3 -3
  143. package/dist/server/app-page-params.js.map +1 -1
  144. package/dist/server/app-page-probe.d.ts +1 -1
  145. package/dist/server/app-page-probe.js +5 -1
  146. package/dist/server/app-page-probe.js.map +1 -1
  147. package/dist/server/app-page-render.d.ts +6 -2
  148. package/dist/server/app-page-render.js +118 -30
  149. package/dist/server/app-page-render.js.map +1 -1
  150. package/dist/server/app-page-request.d.ts +19 -5
  151. package/dist/server/app-page-request.js +49 -7
  152. package/dist/server/app-page-request.js.map +1 -1
  153. package/dist/server/app-page-response.d.ts +1 -0
  154. package/dist/server/app-page-response.js +6 -9
  155. package/dist/server/app-page-response.js.map +1 -1
  156. package/dist/server/app-page-route-wiring.d.ts +20 -4
  157. package/dist/server/app-page-route-wiring.js +15 -12
  158. package/dist/server/app-page-route-wiring.js.map +1 -1
  159. package/dist/server/app-page-stream.d.ts +7 -0
  160. package/dist/server/app-page-stream.js +9 -2
  161. package/dist/server/app-page-stream.js.map +1 -1
  162. package/dist/server/app-post-middleware-context.d.ts +16 -0
  163. package/dist/server/app-post-middleware-context.js +28 -0
  164. package/dist/server/app-post-middleware-context.js.map +1 -0
  165. package/dist/server/app-prerender-endpoints.js +3 -2
  166. package/dist/server/app-prerender-endpoints.js.map +1 -1
  167. package/dist/server/app-request-context.d.ts +22 -0
  168. package/dist/server/app-request-context.js +30 -0
  169. package/dist/server/app-request-context.js.map +1 -0
  170. package/dist/server/app-route-handler-cache.d.ts +1 -0
  171. package/dist/server/app-route-handler-cache.js +7 -2
  172. package/dist/server/app-route-handler-cache.js.map +1 -1
  173. package/dist/server/app-route-handler-dispatch.d.ts +1 -0
  174. package/dist/server/app-route-handler-dispatch.js +8 -5
  175. package/dist/server/app-route-handler-dispatch.js.map +1 -1
  176. package/dist/server/app-route-handler-execution.d.ts +2 -1
  177. package/dist/server/app-route-handler-execution.js +2 -2
  178. package/dist/server/app-route-handler-execution.js.map +1 -1
  179. package/dist/server/app-route-handler-policy.js +13 -13
  180. package/dist/server/app-route-handler-policy.js.map +1 -1
  181. package/dist/server/app-route-handler-response.d.ts +4 -2
  182. package/dist/server/app-route-handler-response.js +9 -7
  183. package/dist/server/app-route-handler-response.js.map +1 -1
  184. package/dist/server/app-route-handler-runtime.d.ts +9 -1
  185. package/dist/server/app-route-handler-runtime.js +11 -1
  186. package/dist/server/app-route-handler-runtime.js.map +1 -1
  187. package/dist/server/app-router-entry.js +9 -4
  188. package/dist/server/app-router-entry.js.map +1 -1
  189. package/dist/server/app-rsc-cache-busting.d.ts +34 -0
  190. package/dist/server/app-rsc-cache-busting.js +137 -0
  191. package/dist/server/app-rsc-cache-busting.js.map +1 -0
  192. package/dist/server/app-rsc-error-handler.d.ts +21 -0
  193. package/dist/server/app-rsc-error-handler.js +30 -0
  194. package/dist/server/app-rsc-error-handler.js.map +1 -0
  195. package/dist/server/app-rsc-handler.d.ts +117 -0
  196. package/dist/server/app-rsc-handler.js +271 -0
  197. package/dist/server/app-rsc-handler.js.map +1 -0
  198. package/dist/server/app-rsc-request-normalization.d.ts +42 -0
  199. package/dist/server/app-rsc-request-normalization.js +67 -0
  200. package/dist/server/app-rsc-request-normalization.js.map +1 -0
  201. package/dist/server/app-rsc-response-finalizer.d.ts +30 -0
  202. package/dist/server/app-rsc-response-finalizer.js +38 -0
  203. package/dist/server/app-rsc-response-finalizer.js.map +1 -0
  204. package/dist/server/app-rsc-route-matching.js +8 -4
  205. package/dist/server/app-rsc-route-matching.js.map +1 -1
  206. package/dist/server/app-segment-config.d.ts +33 -0
  207. package/dist/server/app-segment-config.js +90 -0
  208. package/dist/server/app-segment-config.js.map +1 -0
  209. package/dist/server/app-server-action-execution.d.ts +2 -0
  210. package/dist/server/app-server-action-execution.js +45 -51
  211. package/dist/server/app-server-action-execution.js.map +1 -1
  212. package/dist/server/app-ssr-entry.js +21 -20
  213. package/dist/server/app-ssr-entry.js.map +1 -1
  214. package/dist/server/artifact-compatibility.d.ts +44 -0
  215. package/dist/server/artifact-compatibility.js +82 -0
  216. package/dist/server/artifact-compatibility.js.map +1 -0
  217. package/dist/server/cache-control.d.ts +24 -0
  218. package/dist/server/cache-control.js +33 -0
  219. package/dist/server/cache-control.js.map +1 -0
  220. package/dist/server/cache-proof.d.ts +200 -0
  221. package/dist/server/cache-proof.js +342 -0
  222. package/dist/server/cache-proof.js.map +1 -0
  223. package/dist/server/dev-error-overlay-store.d.ts +23 -0
  224. package/dist/server/dev-error-overlay-store.js +67 -0
  225. package/dist/server/dev-error-overlay-store.js.map +1 -0
  226. package/dist/server/dev-error-overlay.d.ts +15 -0
  227. package/dist/server/dev-error-overlay.js +548 -0
  228. package/dist/server/dev-error-overlay.js.map +1 -0
  229. package/dist/server/dev-origin-check.js +8 -4
  230. package/dist/server/dev-origin-check.js.map +1 -1
  231. package/dist/server/dev-server.js +1 -6
  232. package/dist/server/dev-server.js.map +1 -1
  233. package/dist/server/http-error-responses.d.ts +67 -0
  234. package/dist/server/http-error-responses.js +77 -0
  235. package/dist/server/http-error-responses.js.map +1 -0
  236. package/dist/server/image-optimization.js +2 -1
  237. package/dist/server/image-optimization.js.map +1 -1
  238. package/dist/server/instrumentation-runtime.d.ts +44 -0
  239. package/dist/server/instrumentation-runtime.js +29 -0
  240. package/dist/server/instrumentation-runtime.js.map +1 -0
  241. package/dist/server/isr-cache.d.ts +2 -7
  242. package/dist/server/isr-cache.js +7 -10
  243. package/dist/server/isr-cache.js.map +1 -1
  244. package/dist/server/metadata-route-response.js +6 -5
  245. package/dist/server/metadata-route-response.js.map +1 -1
  246. package/dist/server/metadata-routes.d.ts +1 -0
  247. package/dist/server/metadata-routes.js +6 -0
  248. package/dist/server/metadata-routes.js.map +1 -1
  249. package/dist/server/middleware-matcher.js +2 -2
  250. package/dist/server/middleware-matcher.js.map +1 -1
  251. package/dist/server/middleware-response-headers.js +21 -0
  252. package/dist/server/middleware-response-headers.js.map +1 -1
  253. package/dist/server/middleware-runtime.js +3 -3
  254. package/dist/server/middleware-runtime.js.map +1 -1
  255. package/dist/server/navigation-trace.d.ts +33 -0
  256. package/dist/server/navigation-trace.js +35 -0
  257. package/dist/server/navigation-trace.js.map +1 -0
  258. package/dist/server/next-error-digest.d.ts +44 -0
  259. package/dist/server/next-error-digest.js +40 -0
  260. package/dist/server/next-error-digest.js.map +1 -0
  261. package/dist/server/pages-api-route.js +2 -1
  262. package/dist/server/pages-api-route.js.map +1 -1
  263. package/dist/server/pages-node-compat.js +4 -16
  264. package/dist/server/pages-node-compat.js.map +1 -1
  265. package/dist/server/pages-page-data.d.ts +2 -1
  266. package/dist/server/pages-page-data.js +6 -5
  267. package/dist/server/pages-page-data.js.map +1 -1
  268. package/dist/server/pages-page-response.d.ts +3 -8
  269. package/dist/server/pages-page-response.js +46 -15
  270. package/dist/server/pages-page-response.js.map +1 -1
  271. package/dist/server/prod-server.d.ts +6 -0
  272. package/dist/server/prod-server.js +28 -21
  273. package/dist/server/prod-server.js.map +1 -1
  274. package/dist/server/request-pipeline.d.ts +42 -1
  275. package/dist/server/request-pipeline.js +97 -17
  276. package/dist/server/request-pipeline.js.map +1 -1
  277. package/dist/server/rsc-stream-hints.d.ts +3 -1
  278. package/dist/server/rsc-stream-hints.js +4 -1
  279. package/dist/server/rsc-stream-hints.js.map +1 -1
  280. package/dist/server/seed-cache.js +19 -8
  281. package/dist/server/seed-cache.js.map +1 -1
  282. package/dist/shims/cache-runtime.d.ts +2 -2
  283. package/dist/shims/cache-runtime.js +31 -17
  284. package/dist/shims/cache-runtime.js.map +1 -1
  285. package/dist/shims/cache.d.ts +15 -3
  286. package/dist/shims/cache.js +45 -20
  287. package/dist/shims/cache.js.map +1 -1
  288. package/dist/shims/error-boundary.d.ts +17 -1
  289. package/dist/shims/error-boundary.js +31 -1
  290. package/dist/shims/error-boundary.js.map +1 -1
  291. package/dist/shims/fetch-cache.d.ts +4 -1
  292. package/dist/shims/fetch-cache.js +57 -16
  293. package/dist/shims/fetch-cache.js.map +1 -1
  294. package/dist/shims/head-state.js +2 -3
  295. package/dist/shims/head-state.js.map +1 -1
  296. package/dist/shims/headers.js +4 -44
  297. package/dist/shims/headers.js.map +1 -1
  298. package/dist/shims/i18n-state.js +2 -3
  299. package/dist/shims/i18n-state.js.map +1 -1
  300. package/dist/shims/image.js +93 -5
  301. package/dist/shims/image.js.map +1 -1
  302. package/dist/shims/internal/als-registry.d.ts +15 -0
  303. package/dist/shims/internal/als-registry.js +55 -0
  304. package/dist/shims/internal/als-registry.js.map +1 -0
  305. package/dist/shims/internal/cookie-serialize.d.ts +46 -0
  306. package/dist/shims/internal/cookie-serialize.js +51 -0
  307. package/dist/shims/internal/cookie-serialize.js.map +1 -0
  308. package/dist/shims/link.js +31 -26
  309. package/dist/shims/link.js.map +1 -1
  310. package/dist/shims/metadata.d.ts +26 -1
  311. package/dist/shims/metadata.js +94 -4
  312. package/dist/shims/metadata.js.map +1 -1
  313. package/dist/shims/navigation-state.js +2 -3
  314. package/dist/shims/navigation-state.js.map +1 -1
  315. package/dist/shims/navigation.d.ts +2 -7
  316. package/dist/shims/navigation.js +44 -36
  317. package/dist/shims/navigation.js.map +1 -1
  318. package/dist/shims/request-context.js +2 -4
  319. package/dist/shims/request-context.js.map +1 -1
  320. package/dist/shims/request-state-types.d.ts +1 -1
  321. package/dist/shims/router-state.js +2 -3
  322. package/dist/shims/router-state.js.map +1 -1
  323. package/dist/shims/router.js +2 -2
  324. package/dist/shims/router.js.map +1 -1
  325. package/dist/shims/server.js +5 -30
  326. package/dist/shims/server.js.map +1 -1
  327. package/dist/shims/slot.d.ts +1 -1
  328. package/dist/shims/slot.js +5 -4
  329. package/dist/shims/slot.js.map +1 -1
  330. package/dist/shims/thenable-params.d.ts +5 -2
  331. package/dist/shims/thenable-params.js +26 -6
  332. package/dist/shims/thenable-params.js.map +1 -1
  333. package/dist/shims/unified-request-context.d.ts +1 -1
  334. package/dist/shims/unified-request-context.js +3 -14
  335. package/dist/shims/unified-request-context.js.map +1 -1
  336. package/dist/shims/use-merged-ref.d.ts +7 -0
  337. package/dist/shims/use-merged-ref.js +40 -0
  338. package/dist/shims/use-merged-ref.js.map +1 -0
  339. package/dist/utils/base-path.d.ts +7 -1
  340. package/dist/utils/base-path.js +12 -1
  341. package/dist/utils/base-path.js.map +1 -1
  342. package/dist/utils/cache-control-metadata.d.ts +6 -0
  343. package/dist/utils/cache-control-metadata.js +16 -0
  344. package/dist/utils/cache-control-metadata.js.map +1 -0
  345. package/dist/utils/safe-json-file.d.ts +18 -0
  346. package/dist/utils/safe-json-file.js +25 -0
  347. package/dist/utils/safe-json-file.js.map +1 -0
  348. package/dist/utils/text-stream.d.ts +29 -0
  349. package/dist/utils/text-stream.js +66 -0
  350. package/dist/utils/text-stream.js.map +1 -0
  351. package/package.json +5 -5
@@ -1,94 +1,69 @@
1
- import { DANGEROUS_URL_BLOCK_MESSAGE, isDangerousScheme } from "../shims/url-safety.js";
2
1
  import { stripBasePath } from "../utils/base-path.js";
2
+ import { DANGEROUS_URL_BLOCK_MESSAGE, isDangerousScheme } from "../shims/url-safety.js";
3
3
  import { notifyAppRouterTransitionStart } from "../client/instrumentation-client-state.js";
4
- import { createAppPayloadCacheKey, getMountedSlotIdsHeader, normalizeAppElements, readAppElementsMetadata, resolveVisitedResponseInterceptionContext } from "./app-elements.js";
5
- import { __basePath, activateNavigationSnapshot, clearPendingPathname, commitClientNavigationState, consumePrefetchResponse, createClientNavigationRenderSnapshot, getClientNavigationRenderContext, getClientNavigationState, getCurrentInterceptionContext, getCurrentNextUrl, getPrefetchCache, getPrefetchedUrls, pushHistoryStateWithoutNotify, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, restoreRscResponse, setClientParams, setMountedSlotsHeader, setNavigationContext, setPendingPathname, snapshotRscResponse, toRscUrl } from "../shims/navigation.js";
4
+ import { AppElementsWire } from "./app-elements-wire.js";
5
+ import { getMountedSlotIdsHeader, resolveVisitedResponseInterceptionContext } from "./app-elements.js";
6
+ import { VINEXT_RSC_MOUNTED_SLOTS_HEADER, createRscRequestHeaders, createRscRequestUrl, stripRscCacheBustingSearchParam, stripRscSuffix } from "./app-rsc-cache-busting.js";
7
+ import { __basePath, commitClientNavigationState, consumePrefetchResponse, createClientNavigationRenderSnapshot, getClientNavigationRenderContext, getClientNavigationState, getCurrentInterceptionContext, getCurrentNextUrl, getPrefetchCache, getPrefetchedUrls, pushHistoryStateWithoutNotify, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, restoreRscResponse, setClientParams, setMountedSlotsHeader, setNavigationContext, setPendingPathname, snapshotRscResponse } from "../shims/navigation.js";
8
+ import { DevRecoveryBoundary } from "../shims/error-boundary.js";
6
9
  import { ElementsContext, Slot } from "../shims/slot.js";
7
10
  import "../client/instrumentation-client.js";
8
11
  import { chunksToReadableStream, createProgressiveRscStream, getVinextBrowserGlobal } from "./app-browser-stream.js";
9
- import { createHistoryStateWithPreviousNextUrl, createPendingNavigationCommit, readHistoryStatePreviousNextUrl, resolveAndClassifyNavigationCommit, resolveInterceptionContextFromPreviousNextUrl, resolvePendingNavigationCommitDisposition, resolveServerActionRequestState, routerReducer } from "./app-browser-state.js";
10
- import { devOnCaughtError } from "./app-browser-error.js";
12
+ import { createHistoryStateWithPreviousNextUrl, readHistoryStatePreviousNextUrl, resolveInterceptionContextFromPreviousNextUrl, resolveServerActionRequestState } from "./app-browser-state.js";
13
+ import { createAppBrowserNavigationController } from "./app-browser-navigation-controller.js";
14
+ import { createOnUncaughtError } from "./app-browser-error.js";
15
+ import { dismissOverlay } from "./dev-error-overlay-store.js";
16
+ import { devOnCaughtError, devOnUncaughtError, installDevErrorOverlay } from "./dev-error-overlay.js";
11
17
  import { getServerActionNotFoundClientMessage, isServerActionNotFoundResponse } from "./server-action-not-found.js";
12
- import { createElement, startTransition, use, useLayoutEffect, useRef, useState } from "react";
18
+ import { createElement, use, useLayoutEffect, useRef, useState } from "react";
13
19
  import { createFromFetch, createFromReadableStream, createTemporaryReferenceSet, encodeReply, setServerCallback } from "@vitejs/plugin-rsc/browser";
14
20
  import { hydrateRoot } from "react-dom/client";
15
21
  //#region src/server/app-browser-entry.ts
16
22
  function toActionType(kind) {
17
23
  return kind === "traverse" ? "traverse" : "navigate";
18
24
  }
25
+ function toOperationLane(kind) {
26
+ switch (kind) {
27
+ case "navigate": return "navigation";
28
+ case "refresh": return "refresh";
29
+ case "traverse": return "traverse";
30
+ default: throw new Error("[vinext] Unknown navigation kind: " + String(kind));
31
+ }
32
+ }
19
33
  const MAX_VISITED_RESPONSE_CACHE_SIZE = 50;
20
34
  const VISITED_RESPONSE_CACHE_TTL = 5 * 6e4;
21
35
  const MAX_TRAVERSAL_CACHE_TTL = 30 * 6e4;
22
- let nextNavigationRenderId = 0;
23
- let activeNavigationId = 0;
24
- const pendingNavigationCommits = /* @__PURE__ */ new Map();
25
- const pendingNavigationPrePaintEffects = /* @__PURE__ */ new Map();
36
+ const browserNavigationController = createAppBrowserNavigationController();
37
+ const NavigationCommitSignal = browserNavigationController.NavigationCommitSignal;
38
+ function parseEncodedJsonHeader(value) {
39
+ if (!value) return null;
40
+ try {
41
+ return JSON.parse(decodeURIComponent(value));
42
+ } catch {
43
+ return null;
44
+ }
45
+ }
26
46
  function isRouterStatePromise(value) {
27
47
  return value instanceof Promise;
28
48
  }
29
- let setBrowserRouterState = null;
30
- let browserRouterStateRef = null;
31
- let activePendingBrowserRouterState = null;
32
49
  let latestClientParams = {};
33
50
  const visitedResponseCache = /* @__PURE__ */ new Map();
34
- let resolveBrowserRouterStateReady = null;
35
- let browserRouterStateReadyPromise = null;
36
- let browserRouterStateHasCommitted = false;
51
+ let browserRouterStateHasEverCommitted = false;
52
+ let pendingNavigationRecoveryHref = null;
37
53
  function isServerActionResult(value) {
38
54
  return !!value && typeof value === "object" && "root" in value;
39
55
  }
40
- function getBrowserRouterStateSetter() {
41
- if (!setBrowserRouterState) throw new Error("[vinext] Browser router state setter is not initialized");
42
- return setBrowserRouterState;
43
- }
44
56
  function getBrowserRouterState() {
45
- if (!browserRouterStateRef) throw new Error("[vinext] Browser router state is not initialized");
46
- return browserRouterStateRef.current;
57
+ return browserNavigationController.getBrowserRouterState();
47
58
  }
48
- function waitForBrowserRouterStateReady() {
49
- if (browserRouterStateRef || browserRouterStateHasCommitted) return Promise.resolve();
50
- if (!browserRouterStateReadyPromise) browserRouterStateReadyPromise = new Promise((resolve) => {
51
- resolveBrowserRouterStateReady = resolve;
52
- });
53
- return browserRouterStateReadyPromise;
59
+ function hasBrowserRouterState() {
60
+ return browserNavigationController.hasBrowserRouterState();
54
61
  }
55
- function markBrowserRouterStateReady() {
56
- browserRouterStateHasCommitted = true;
57
- const resolveReady = resolveBrowserRouterStateReady;
58
- resolveBrowserRouterStateReady = null;
59
- browserRouterStateReadyPromise = null;
60
- resolveReady?.();
62
+ function waitForBrowserRouterStateReady() {
63
+ return browserNavigationController.waitForBrowserRouterStateReady();
61
64
  }
62
65
  function beginPendingBrowserRouterState() {
63
- const setter = getBrowserRouterStateSetter();
64
- if (activePendingBrowserRouterState && !activePendingBrowserRouterState.settled) {
65
- activePendingBrowserRouterState.settled = true;
66
- activePendingBrowserRouterState.resolve(getBrowserRouterState());
67
- }
68
- let resolve;
69
- const promise = new Promise((resolvePromise) => {
70
- resolve = resolvePromise;
71
- });
72
- const pending = {
73
- promise,
74
- resolve,
75
- settled: false
76
- };
77
- activePendingBrowserRouterState = pending;
78
- setter(promise);
79
- return pending;
80
- }
81
- function settlePendingBrowserRouterState(pending) {
82
- if (!pending || pending.settled) return;
83
- pending.settled = true;
84
- pending.resolve(getBrowserRouterState());
85
- if (activePendingBrowserRouterState === pending) activePendingBrowserRouterState = null;
86
- }
87
- function resolvePendingBrowserRouterState(pending, action) {
88
- if (!pending || pending.settled) return;
89
- pending.settled = true;
90
- pending.resolve(routerReducer(getBrowserRouterState(), action));
91
- if (activePendingBrowserRouterState === pending) activePendingBrowserRouterState = null;
66
+ return browserNavigationController.beginPendingBrowserRouterState();
92
67
  }
93
68
  function applyClientParams(params) {
94
69
  latestClientParams = params;
@@ -109,31 +84,10 @@ function clearClientNavigationCaches() {
109
84
  clearVisitedResponseCache();
110
85
  clearPrefetchState();
111
86
  }
112
- function queuePrePaintNavigationEffect(renderId, effect) {
113
- if (!effect) return;
114
- pendingNavigationPrePaintEffects.set(renderId, effect);
115
- }
116
- /**
117
- * Run all queued pre-paint effects for renderIds up to and including the
118
- * given renderId. When React supersedes a startTransition update (rapid
119
- * clicks on same-route links), the superseded NavigationCommitSignal never
120
- * mounts, so its pre-paint effect never fires. By draining all effects
121
- * <= the committed renderId here, the winning transition cleans up after
122
- * any superseded ones, keeping the counter balanced.
123
- *
124
- * Invariant: each superseded navigation gets a commitClientNavigationState()
125
- * to balance the activateNavigationSnapshot() from its renderNavigationPayload call.
126
- */
127
- function drainPrePaintEffects(upToRenderId) {
128
- for (const [id, effect] of pendingNavigationPrePaintEffects) if (id <= upToRenderId) {
129
- pendingNavigationPrePaintEffects.delete(id);
130
- if (id === upToRenderId) effect();
131
- else commitClientNavigationState(void 0, { releaseSnapshot: true });
132
- }
133
- }
134
- function createNavigationCommitEffect(href, historyUpdateMode, navId, params, previousNextUrl) {
87
+ function createNavigationCommitEffect(options) {
88
+ const { href, historyUpdateMode, navId, params, previousNextUrl } = options;
135
89
  return () => {
136
- if (navId !== activeNavigationId) {
90
+ if (!browserNavigationController.isCurrentNavigation(navId)) {
137
91
  commitClientNavigationState(void 0, { releaseSnapshot: true });
138
92
  return;
139
93
  }
@@ -142,9 +96,38 @@ function createNavigationCommitEffect(href, historyUpdateMode, navId, params, pr
142
96
  const historyState = createHistoryStateWithPreviousNextUrl(historyUpdateMode === "replace" ? window.history.state : null, previousNextUrl);
143
97
  if (historyUpdateMode === "replace" && window.location.href !== targetHref) replaceHistoryStateWithoutNotify(historyState, "", href);
144
98
  else if (historyUpdateMode === "push" && window.location.href !== targetHref) pushHistoryStateWithoutNotify(historyState, "", href);
99
+ pendingNavigationRecoveryHref = null;
145
100
  commitClientNavigationState(navId);
146
101
  };
147
102
  }
103
+ async function renderNavigationPayload(payload, navigationSnapshot, targetHref, navId, historyUpdateMode, params, previousNextUrl, pendingRouterState, useTransition = true, actionType = "navigate", operationLane = "navigation") {
104
+ try {
105
+ return await browserNavigationController.renderNavigationPayload({
106
+ actionType,
107
+ createNavigationCommitEffect: (options) => {
108
+ pendingNavigationRecoveryHref = options.href;
109
+ return createNavigationCommitEffect(options);
110
+ },
111
+ historyUpdateMode,
112
+ navigationSnapshot,
113
+ nextElements: payload,
114
+ operationLane,
115
+ params,
116
+ pendingRouterState,
117
+ previousNextUrl,
118
+ targetHref,
119
+ navId,
120
+ useTransition
121
+ });
122
+ } catch (error) {
123
+ pendingNavigationRecoveryHref = null;
124
+ throw error;
125
+ }
126
+ }
127
+ async function commitSameUrlNavigatePayload(nextElements, returnValue, actionInitiationState) {
128
+ const navigationSnapshot = createClientNavigationRenderSnapshot(window.location.href, latestClientParams);
129
+ return browserNavigationController.commitSameUrlNavigatePayload(nextElements, navigationSnapshot, returnValue, actionInitiationState);
130
+ }
148
131
  function evictVisitedResponseCacheIfNeeded() {
149
132
  while (visitedResponseCache.size >= MAX_VISITED_RESPONSE_CACHE_SIZE) {
150
133
  const oldest = visitedResponseCache.keys().next().value;
@@ -153,7 +136,7 @@ function evictVisitedResponseCacheIfNeeded() {
153
136
  }
154
137
  }
155
138
  function getVisitedResponse(rscUrl, interceptionContext, mountedSlotsHeader, navigationKind) {
156
- const cacheKey = createAppPayloadCacheKey(rscUrl, interceptionContext);
139
+ const cacheKey = AppElementsWire.encodeCacheKey(rscUrl, interceptionContext);
157
140
  const cached = visitedResponseCache.get(cacheKey);
158
141
  if (!cached) return null;
159
142
  if ((cached.response.mountedSlotsHeader ?? null) !== mountedSlotsHeader) {
@@ -180,7 +163,7 @@ function getVisitedResponse(rscUrl, interceptionContext, mountedSlotsHeader, nav
180
163
  return null;
181
164
  }
182
165
  function storeVisitedResponseSnapshot(rscUrl, interceptionContext, snapshot, params) {
183
- const cacheKey = createAppPayloadCacheKey(rscUrl, interceptionContext);
166
+ const cacheKey = AppElementsWire.encodeCacheKey(rscUrl, interceptionContext);
184
167
  visitedResponseCache.delete(cacheKey);
185
168
  evictVisitedResponseCacheIfNeeded();
186
169
  const now = Date.now();
@@ -217,66 +200,17 @@ function getRequestState(navigationKind, previousNextUrlOverride) {
217
200
  default: throw new Error("[vinext] Unknown navigation kind: " + String(navigationKind));
218
201
  }
219
202
  }
220
- function createRscRequestHeaders(interceptionContext) {
221
- const headers = new Headers({ Accept: "text/x-component" });
222
- if (interceptionContext !== null) headers.set("X-Vinext-Interception-Context", interceptionContext);
223
- return headers;
224
- }
225
- /**
226
- * Resolve all pending navigation commits with renderId <= the committed renderId.
227
- * Note: Map iteration handles concurrent deletion safely — entries are visited in
228
- * insertion order and deletion doesn't affect the iterator's view of remaining entries.
229
- * This pattern is also used in drainPrePaintEffects with the same semantics.
230
- */
231
- function resolveCommittedNavigations(renderId) {
232
- for (const [pendingId, resolve] of pendingNavigationCommits) if (pendingId <= renderId) {
233
- pendingNavigationCommits.delete(pendingId);
234
- resolve();
235
- }
236
- }
237
- function NavigationCommitSignal({ renderId, children }) {
238
- useLayoutEffect(() => {
239
- drainPrePaintEffects(renderId);
240
- const frame = requestAnimationFrame(() => {
241
- resolveCommittedNavigations(renderId);
242
- });
243
- return () => {
244
- cancelAnimationFrame(frame);
245
- resolveCommittedNavigations(renderId);
246
- };
247
- }, [renderId]);
248
- return children;
249
- }
250
- function normalizeAppElementsPromise(payload) {
251
- return Promise.resolve(payload).then((elements) => normalizeAppElements(elements));
203
+ function handleDevRecoveryBoundaryCatch(resetKey) {
204
+ browserNavigationController.drainPrePaintEffects(resetKey);
252
205
  }
253
- async function commitSameUrlNavigatePayload(nextElements, returnValue) {
254
- const navigationSnapshot = createClientNavigationRenderSnapshot(window.location.href, latestClientParams);
255
- const currentState = getBrowserRouterState();
256
- const startedNavigationId = activeNavigationId;
257
- const { disposition, pending } = await resolveAndClassifyNavigationCommit({
258
- activeNavigationId,
259
- currentState,
260
- navigationSnapshot,
261
- nextElements,
262
- renderId: ++nextNavigationRenderId,
263
- startedNavigationId,
264
- type: "navigate"
265
- });
266
- if (disposition === "hard-navigate") {
267
- window.location.assign(window.location.href);
268
- return;
269
- }
270
- if (disposition === "dispatch") dispatchBrowserTree(pending.action.elements, navigationSnapshot, pending.action.renderId, "navigate", pending.interceptionContext, pending.action.layoutFlags, pending.previousNextUrl, pending.routeId, pending.rootLayoutTreePath, null, false);
271
- if (returnValue) {
272
- if (!returnValue.ok) throw returnValue.data;
273
- return returnValue.data;
274
- }
206
+ function decodeAppElementsPromise(payload) {
207
+ return Promise.resolve(payload).then((elements) => AppElementsWire.decode(elements));
275
208
  }
276
209
  function BrowserRoot({ initialElements, initialNavigationSnapshot }) {
277
210
  const resolvedElements = use(initialElements);
278
- const initialMetadata = readAppElementsMetadata(resolvedElements);
211
+ const initialMetadata = AppElementsWire.readMetadata(resolvedElements);
279
212
  const [treeStateValue, setTreeStateValue] = useState({
213
+ activeOperation: null,
280
214
  elements: resolvedElements,
281
215
  interceptionContext: initialMetadata.interceptionContext,
282
216
  layoutFlags: initialMetadata.layoutFlags,
@@ -284,21 +218,17 @@ function BrowserRoot({ initialElements, initialNavigationSnapshot }) {
284
218
  previousNextUrl: null,
285
219
  renderId: 0,
286
220
  rootLayoutTreePath: initialMetadata.rootLayoutTreePath,
287
- routeId: initialMetadata.routeId
221
+ routeId: initialMetadata.routeId,
222
+ visibleCommitVersion: 0
288
223
  });
289
224
  const treeState = isRouterStatePromise(treeStateValue) ? use(treeStateValue) : treeStateValue;
290
225
  const stateRef = useRef(treeState);
291
226
  stateRef.current = treeState;
292
227
  useLayoutEffect(() => {
293
- setBrowserRouterState = setTreeStateValue;
294
- browserRouterStateRef = stateRef;
295
- markBrowserRouterStateReady();
228
+ const detach = browserNavigationController.attachBrowserRouterState(setTreeStateValue, stateRef);
229
+ browserRouterStateHasEverCommitted = true;
296
230
  return () => {
297
- if (setBrowserRouterState === setTreeStateValue) setBrowserRouterState = null;
298
- if (browserRouterStateRef === stateRef) {
299
- browserRouterStateRef = null;
300
- browserRouterStateHasCommitted = false;
301
- }
231
+ detach();
302
232
  setMountedSlotsHeader(null);
303
233
  };
304
234
  }, [setTreeStateValue]);
@@ -309,84 +239,15 @@ function BrowserRoot({ initialElements, initialNavigationSnapshot }) {
309
239
  if (treeState.renderId !== 0) return;
310
240
  replaceHistoryStateWithoutNotify(createHistoryStateWithPreviousNextUrl(window.history.state, treeState.previousNextUrl), "", window.location.href);
311
241
  }, [treeState.previousNextUrl, treeState.renderId]);
312
- const committedTree = createElement(NavigationCommitSignal, { renderId: treeState.renderId }, createElement(ElementsContext.Provider, { value: treeState.elements }, createElement(Slot, { id: treeState.routeId })));
242
+ const innerTree = createElement(NavigationCommitSignal, { renderId: treeState.renderId }, createElement(ElementsContext.Provider, { value: treeState.elements }, createElement(Slot, { id: treeState.routeId })));
243
+ const committedTree = import.meta.env.DEV ? createElement(DevRecoveryBoundary, {
244
+ resetKey: treeState.renderId,
245
+ onCatch: handleDevRecoveryBoundaryCatch
246
+ }, innerTree) : innerTree;
313
247
  const ClientNavigationRenderContext = getClientNavigationRenderContext();
314
248
  if (!ClientNavigationRenderContext) return committedTree;
315
249
  return createElement(ClientNavigationRenderContext.Provider, { value: treeState.navigationSnapshot }, committedTree);
316
250
  }
317
- function dispatchBrowserTree(elements, navigationSnapshot, renderId, actionType, interceptionContext, layoutFlags, previousNextUrl, routeId, rootLayoutTreePath, pendingRouterState, useTransitionMode) {
318
- const setter = getBrowserRouterStateSetter();
319
- const action = {
320
- elements,
321
- interceptionContext,
322
- layoutFlags,
323
- navigationSnapshot,
324
- previousNextUrl,
325
- renderId,
326
- rootLayoutTreePath,
327
- routeId,
328
- type: actionType
329
- };
330
- const applyAction = () => {
331
- if (pendingRouterState) {
332
- resolvePendingBrowserRouterState(pendingRouterState, action);
333
- return;
334
- }
335
- setter(routerReducer(getBrowserRouterState(), action));
336
- };
337
- if (useTransitionMode) startTransition(applyAction);
338
- else applyAction();
339
- }
340
- async function renderNavigationPayload(payload, navigationSnapshot, targetHref, navId, historyUpdateMode, params, previousNextUrl, pendingRouterState, useTransition = true, actionType = "navigate") {
341
- const renderId = ++nextNavigationRenderId;
342
- const committed = new Promise((resolve) => {
343
- pendingNavigationCommits.set(renderId, resolve);
344
- });
345
- let snapshotActivated = false;
346
- try {
347
- const currentState = getBrowserRouterState();
348
- const pending = await createPendingNavigationCommit({
349
- currentState,
350
- nextElements: payload,
351
- navigationSnapshot,
352
- previousNextUrl,
353
- renderId,
354
- type: actionType
355
- });
356
- const disposition = resolvePendingNavigationCommitDisposition({
357
- activeNavigationId,
358
- currentRootLayoutTreePath: currentState.rootLayoutTreePath,
359
- nextRootLayoutTreePath: pending.rootLayoutTreePath,
360
- startedNavigationId: navId
361
- });
362
- if (disposition === "skip") {
363
- settlePendingBrowserRouterState(pendingRouterState);
364
- const resolve = pendingNavigationCommits.get(renderId);
365
- pendingNavigationCommits.delete(renderId);
366
- resolve?.();
367
- return;
368
- }
369
- if (disposition === "hard-navigate") {
370
- settlePendingBrowserRouterState(pendingRouterState);
371
- pendingNavigationCommits.delete(renderId);
372
- window.location.assign(targetHref);
373
- return;
374
- }
375
- queuePrePaintNavigationEffect(renderId, createNavigationCommitEffect(targetHref, historyUpdateMode, navId, params, pending.previousNextUrl));
376
- activateNavigationSnapshot();
377
- snapshotActivated = true;
378
- dispatchBrowserTree(pending.action.elements, navigationSnapshot, renderId, actionType, pending.interceptionContext, pending.action.layoutFlags, pending.previousNextUrl, pending.routeId, pending.rootLayoutTreePath, pendingRouterState, useTransition);
379
- } catch (error) {
380
- pendingNavigationPrePaintEffects.delete(renderId);
381
- const resolve = pendingNavigationCommits.get(renderId);
382
- pendingNavigationCommits.delete(renderId);
383
- if (snapshotActivated) commitClientNavigationState(navId);
384
- settlePendingBrowserRouterState(pendingRouterState);
385
- resolve?.();
386
- throw error;
387
- }
388
- return committed;
389
- }
390
251
  function restoreHydrationNavigationContext(pathname, searchParams, params) {
391
252
  setNavigationContext({
392
253
  pathname,
@@ -479,17 +340,20 @@ async function readInitialRscStream() {
479
340
  if (vinext.__VINEXT_RSC_NAV__) restoreHydrationNavigationContext(vinext.__VINEXT_RSC_NAV__.pathname, vinext.__VINEXT_RSC_NAV__.searchParams, params);
480
341
  return createProgressiveRscStream();
481
342
  }
482
- const rscResponse = await fetch(toRscUrl(window.location.pathname + window.location.search));
343
+ const rscHeaders = createRscRequestHeaders();
344
+ const rscResponse = await fetch(await createRscRequestUrl(window.location.pathname + window.location.search, rscHeaders), {
345
+ credentials: "include",
346
+ headers: rscHeaders
347
+ });
483
348
  if (!rscResponse.ok) return recoverFromBadInitialRscResponse(`returned ${rscResponse.status}`);
484
349
  const contentType = rscResponse.headers.get("content-type") ?? "";
485
350
  if (!contentType.startsWith("text/x-component")) return recoverFromBadInitialRscResponse(`returned non-RSC content-type "${contentType || "(missing)"}"`);
486
351
  if (!rscResponse.body) return recoverFromBadInitialRscResponse("returned empty body");
487
352
  clearReloadFlag();
488
- let params = {};
489
- const paramsHeader = rscResponse.headers.get("X-Vinext-Params");
490
- if (paramsHeader) try {
491
- params = JSON.parse(decodeURIComponent(paramsHeader));
492
- applyClientParams(params);
353
+ const parsedParams = parseEncodedJsonHeader(rscResponse.headers.get("X-Vinext-Params"));
354
+ const params = parsedParams ?? {};
355
+ if (parsedParams) try {
356
+ applyClientParams(parsedParams);
493
357
  } catch {}
494
358
  restoreHydrationNavigationContext(window.location.pathname, window.location.search, params);
495
359
  return rscResponse.body;
@@ -505,7 +369,7 @@ function registerServerActionCallback() {
505
369
  elements: currentState.elements,
506
370
  previousNextUrl: currentState.previousNextUrl
507
371
  });
508
- const fetchResponse = await fetch(toRscUrl(window.location.pathname + window.location.search), {
372
+ const fetchResponse = await fetch(await createRscRequestUrl(window.location.pathname + window.location.search, headers), {
509
373
  method: "POST",
510
374
  headers,
511
375
  body
@@ -529,8 +393,8 @@ function registerServerActionCallback() {
529
393
  }
530
394
  clearClientNavigationCaches();
531
395
  const result = await createFromFetch(Promise.resolve(fetchResponse), { temporaryReferences });
532
- if (isServerActionResult(result)) return commitSameUrlNavigatePayload(Promise.resolve(normalizeAppElements(result.root)), result.returnValue);
533
- return commitSameUrlNavigatePayload(Promise.resolve(normalizeAppElements(result)));
396
+ if (isServerActionResult(result)) return commitSameUrlNavigatePayload(Promise.resolve(AppElementsWire.decode(result.root)), result.returnValue, currentState);
397
+ return commitSameUrlNavigatePayload(Promise.resolve(AppElementsWire.decode(result)), void 0, currentState);
534
398
  });
535
399
  }
536
400
  async function main() {
@@ -540,27 +404,31 @@ async function main() {
540
404
  bootstrapHydration(rscStream);
541
405
  }
542
406
  function bootstrapHydration(rscStream) {
543
- const root = normalizeAppElementsPromise(createFromReadableStream(rscStream));
407
+ if (import.meta.env.DEV) installDevErrorOverlay();
408
+ const root = decodeAppElementsPromise(createFromReadableStream(rscStream));
544
409
  const initialNavigationSnapshot = createClientNavigationRenderSnapshot(window.location.href, latestClientParams);
545
410
  replaceHistoryStateWithoutNotify(createHistoryStateWithPreviousNextUrl(window.history.state, null), "", window.location.href);
411
+ const onUncaughtError = import.meta.env.DEV ? devOnUncaughtError : createOnUncaughtError(() => pendingNavigationRecoveryHref);
546
412
  window.__VINEXT_RSC_ROOT__ = hydrateRoot(document, createElement(BrowserRoot, {
547
413
  initialElements: root,
548
414
  initialNavigationSnapshot
549
- }), import.meta.env.DEV ? { onCaughtError: devOnCaughtError } : void 0);
415
+ }), import.meta.env.DEV ? {
416
+ onCaughtError: devOnCaughtError,
417
+ onUncaughtError
418
+ } : { onUncaughtError });
550
419
  window.__VINEXT_HYDRATED_AT = performance.now();
551
420
  window.__VINEXT_RSC_NAVIGATE__ = async function navigateRsc(href, redirectDepth = 0, navigationKind = "navigate", historyUpdateMode, previousNextUrlOverride, programmaticTransition = false) {
552
- let _snapshotPending = false;
553
421
  let pendingRouterState = null;
554
- const navId = ++activeNavigationId;
422
+ const navId = browserNavigationController.beginNavigation();
555
423
  let currentHref = href;
556
424
  let currentHistoryMode = historyUpdateMode;
557
425
  let currentPrevNextUrl = previousNextUrlOverride;
558
426
  let redirectCount = redirectDepth;
559
427
  try {
560
- if (programmaticTransition && browserRouterStateRef) pendingRouterState = beginPendingBrowserRouterState();
428
+ if (programmaticTransition && hasBrowserRouterState()) pendingRouterState = beginPendingBrowserRouterState();
561
429
  else {
562
430
  await waitForBrowserRouterStateReady();
563
- if (navId !== activeNavigationId) return;
431
+ if (!browserNavigationController.isCurrentNavigation(navId)) return;
564
432
  if (programmaticTransition) pendingRouterState = beginPendingBrowserRouterState();
565
433
  }
566
434
  while (true) {
@@ -570,7 +438,6 @@ function bootstrapHydration(rscStream) {
570
438
  return;
571
439
  }
572
440
  const url = new URL(currentHref, window.location.origin);
573
- const rscUrl = toRscUrl(url.pathname + url.search);
574
441
  const requestState = getRequestState(navigationKind, currentPrevNextUrl);
575
442
  const requestInterceptionContext = requestState.interceptionContext;
576
443
  const requestPreviousNextUrl = requestState.previousNextUrl;
@@ -580,19 +447,17 @@ function bootstrapHydration(rscStream) {
580
447
  setPendingPathname(url.pathname, navId);
581
448
  const elementsAtNavStart = getBrowserRouterState().elements;
582
449
  const mountedSlotsHeader = getMountedSlotIdsHeader(elementsAtNavStart);
450
+ const requestHeaders = createRscRequestHeaders({ interceptionContext: requestInterceptionContext });
451
+ if (mountedSlotsHeader) requestHeaders.set(VINEXT_RSC_MOUNTED_SLOTS_HEADER, mountedSlotsHeader);
452
+ const rscUrl = await createRscRequestUrl(url.pathname + url.search, requestHeaders);
583
453
  const cachedRoute = getVisitedResponse(rscUrl, requestInterceptionContext, mountedSlotsHeader, navigationKind);
584
454
  if (cachedRoute) {
585
- if (navId !== activeNavigationId) return;
455
+ if (!browserNavigationController.isCurrentNavigation(navId)) return;
586
456
  const cachedParams = cachedRoute.params;
587
457
  const cachedNavigationSnapshot = createClientNavigationRenderSnapshot(currentHref, cachedParams);
588
- const cachedPayload = normalizeAppElementsPromise(createFromFetch(Promise.resolve(restoreRscResponse(cachedRoute.response))));
589
- if (navId !== activeNavigationId) return;
590
- _snapshotPending = true;
591
- try {
592
- await renderNavigationPayload(cachedPayload, cachedNavigationSnapshot, currentHref, navId, currentHistoryMode, cachedParams, requestPreviousNextUrl, pendingRouterState, isSameRoute, toActionType(navigationKind));
593
- } finally {
594
- _snapshotPending = false;
595
- }
458
+ const cachedPayload = decodeAppElementsPromise(createFromFetch(Promise.resolve(restoreRscResponse(cachedRoute.response))));
459
+ if (!browserNavigationController.isCurrentNavigation(navId)) return;
460
+ await renderNavigationPayload(cachedPayload, cachedNavigationSnapshot, currentHref, navId, currentHistoryMode, cachedParams, requestPreviousNextUrl, pendingRouterState, isSameRoute, toActionType(navigationKind), toOperationLane(navigationKind));
596
461
  return;
597
462
  }
598
463
  let navResponse;
@@ -604,23 +469,20 @@ function bootstrapHydration(rscStream) {
604
469
  navResponseUrl = prefetchedResponse.url;
605
470
  }
606
471
  }
607
- if (!navResponse) {
608
- const requestHeaders = createRscRequestHeaders(requestInterceptionContext);
609
- if (mountedSlotsHeader) requestHeaders.set("X-Vinext-Mounted-Slots", mountedSlotsHeader);
610
- navResponse = await fetch(rscUrl, {
611
- headers: requestHeaders,
612
- credentials: "include"
613
- });
614
- }
615
- if (navId !== activeNavigationId) return;
472
+ if (!navResponse) navResponse = await fetch(rscUrl, {
473
+ headers: requestHeaders,
474
+ credentials: "include"
475
+ });
476
+ if (!browserNavigationController.isCurrentNavigation(navId)) return;
616
477
  const isRscResponse = (navResponse.headers.get("content-type") ?? "").startsWith("text/x-component");
617
478
  if (!navResponse.ok || !isRscResponse || !navResponse.body) {
618
479
  const responseUrl = navResponseUrl ?? navResponse.url;
619
480
  let hardNavTarget = currentHref;
620
481
  if (responseUrl) {
621
482
  const parsed = new URL(responseUrl, window.location.origin);
483
+ stripRscCacheBustingSearchParam(parsed);
622
484
  const origUrl = new URL(currentHref, window.location.origin);
623
- let pathname = parsed.pathname.replace(/\.rsc$/, "");
485
+ let pathname = stripRscSuffix(parsed.pathname);
624
486
  if (origUrl.pathname.length > 1 && origUrl.pathname.endsWith("/") && !pathname.endsWith("/")) pathname += "/";
625
487
  hardNavTarget = pathname + parsed.search;
626
488
  if (origUrl.hash) hardNavTarget += origUrl.hash;
@@ -629,9 +491,10 @@ function bootstrapHydration(rscStream) {
629
491
  return;
630
492
  }
631
493
  const finalUrl = new URL(navResponseUrl ?? navResponse.url, window.location.origin);
494
+ stripRscCacheBustingSearchParam(finalUrl);
632
495
  const requestedUrl = new URL(rscUrl, window.location.origin);
633
496
  if (finalUrl.pathname !== requestedUrl.pathname) {
634
- const destinationPath = finalUrl.pathname.replace(/\.rsc$/, "") + finalUrl.search;
497
+ const destinationPath = stripRscSuffix(finalUrl.pathname) + finalUrl.search;
635
498
  replaceHistoryStateWithoutNotify(createHistoryStateWithPreviousNextUrl(null, requestPreviousNextUrl), "", destinationPath);
636
499
  currentHref = destinationPath;
637
500
  currentHistoryMode = void 0;
@@ -639,37 +502,24 @@ function bootstrapHydration(rscStream) {
639
502
  redirectCount += 1;
640
503
  continue;
641
504
  }
642
- let navParams = {};
643
- const paramsHeader = navResponse.headers.get("X-Vinext-Params");
644
- if (paramsHeader) try {
645
- navParams = JSON.parse(decodeURIComponent(paramsHeader));
646
- } catch {}
505
+ const navParams = parseEncodedJsonHeader(navResponse.headers.get("X-Vinext-Params")) ?? {};
647
506
  const navigationSnapshot = createClientNavigationRenderSnapshot(currentHref, navParams);
648
507
  const responseSnapshot = await snapshotRscResponse(navResponse);
649
- if (navId !== activeNavigationId) return;
650
- const rscPayload = normalizeAppElementsPromise(createFromFetch(Promise.resolve(restoreRscResponse(responseSnapshot))));
651
- if (navId !== activeNavigationId) return;
652
- _snapshotPending = true;
653
- try {
654
- await renderNavigationPayload(rscPayload, navigationSnapshot, currentHref, navId, currentHistoryMode, navParams, requestPreviousNextUrl, pendingRouterState, isSameRoute, toActionType(navigationKind));
655
- } finally {
656
- _snapshotPending = false;
657
- }
658
- if (navId !== activeNavigationId) return;
659
- storeVisitedResponseSnapshot(rscUrl, resolveVisitedResponseInterceptionContext(requestInterceptionContext, readAppElementsMetadata(await rscPayload).interceptionContext), responseSnapshot, navParams);
508
+ if (!browserNavigationController.isCurrentNavigation(navId)) return;
509
+ const rscPayload = decodeAppElementsPromise(createFromFetch(Promise.resolve(restoreRscResponse(responseSnapshot))));
510
+ if (!browserNavigationController.isCurrentNavigation(navId)) return;
511
+ if (await renderNavigationPayload(rscPayload, navigationSnapshot, currentHref, navId, currentHistoryMode, navParams, requestPreviousNextUrl, pendingRouterState, isSameRoute, toActionType(navigationKind), toOperationLane(navigationKind)) !== "committed") return;
512
+ if (!browserNavigationController.isCurrentNavigation(navId)) return;
513
+ const resolvedElements = await rscPayload;
514
+ storeVisitedResponseSnapshot(rscUrl, resolveVisitedResponseInterceptionContext(requestInterceptionContext, AppElementsWire.readMetadata(resolvedElements).interceptionContext), responseSnapshot, navParams);
660
515
  return;
661
516
  }
662
517
  } catch (error) {
663
- if (_snapshotPending) {
664
- _snapshotPending = false;
665
- commitClientNavigationState(navId);
666
- }
667
- if (navId !== activeNavigationId) return;
518
+ if (!browserNavigationController.isCurrentNavigation(navId)) return;
668
519
  if (!isPageUnloading) console.error("[vinext] RSC navigation error:", error);
669
520
  window.location.href = currentHref;
670
521
  } finally {
671
- settlePendingBrowserRouterState(pendingRouterState);
672
- if (navId === activeNavigationId) clearPendingPathname(navId);
522
+ browserNavigationController.finalizeNavigation(navId, pendingRouterState);
673
523
  }
674
524
  };
675
525
  if ("scrollRestoration" in history) history.scrollRestoration = "manual";
@@ -684,16 +534,17 @@ function bootstrapHydration(rscStream) {
684
534
  });
685
535
  if (import.meta.hot) import.meta.hot.on("rsc:update", async () => {
686
536
  try {
537
+ if (browserRouterStateHasEverCommitted && !browserNavigationController.hasBrowserRouterState()) {
538
+ window.location.reload();
539
+ return;
540
+ }
541
+ await waitForBrowserRouterStateReady();
542
+ if (!browserNavigationController.hasBrowserRouterState()) return;
687
543
  clearClientNavigationCaches();
688
544
  const navigationSnapshot = createClientNavigationRenderSnapshot(window.location.href, latestClientParams);
689
- const pending = await createPendingNavigationCommit({
690
- currentState: getBrowserRouterState(),
691
- nextElements: normalizeAppElementsPromise(createFromFetch(fetch(toRscUrl(window.location.pathname + window.location.search)))),
692
- navigationSnapshot,
693
- renderId: ++nextNavigationRenderId,
694
- type: "replace"
695
- });
696
- dispatchBrowserTree(pending.action.elements, navigationSnapshot, pending.action.renderId, "replace", pending.interceptionContext, pending.action.layoutFlags, pending.previousNextUrl, pending.routeId, pending.rootLayoutTreePath, null, false);
545
+ dismissOverlay();
546
+ const hmrHeaders = createRscRequestHeaders();
547
+ await browserNavigationController.hmrReplaceTree(decodeAppElementsPromise(createFromFetch(fetch(await createRscRequestUrl(window.location.pathname + window.location.search, hmrHeaders), { headers: hmrHeaders }))), navigationSnapshot);
697
548
  } catch (error) {
698
549
  console.error("[vinext] RSC HMR error:", error);
699
550
  }