vinext 0.0.50 → 0.0.52

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 (462) hide show
  1. package/dist/build/google-fonts/fallback-metrics-data.js +14031 -0
  2. package/dist/build/google-fonts/fallback-metrics-data.js.map +1 -0
  3. package/dist/build/google-fonts/fallback-metrics.d.ts +13 -0
  4. package/dist/build/google-fonts/fallback-metrics.js +46 -0
  5. package/dist/build/google-fonts/fallback-metrics.js.map +1 -0
  6. package/dist/build/precompress.d.ts +13 -2
  7. package/dist/build/precompress.js +23 -13
  8. package/dist/build/precompress.js.map +1 -1
  9. package/dist/build/prerender.d.ts +4 -15
  10. package/dist/build/prerender.js +83 -53
  11. package/dist/build/prerender.js.map +1 -1
  12. package/dist/build/report.d.ts +5 -4
  13. package/dist/build/report.js +196 -348
  14. package/dist/build/report.js.map +1 -1
  15. package/dist/check.js +5 -0
  16. package/dist/check.js.map +1 -1
  17. package/dist/cli-args.d.ts +1 -0
  18. package/dist/cli-args.js +5 -0
  19. package/dist/cli-args.js.map +1 -1
  20. package/dist/cli.js +99 -3
  21. package/dist/cli.js.map +1 -1
  22. package/dist/client/navigation-runtime.d.ts +47 -0
  23. package/dist/client/navigation-runtime.js +156 -0
  24. package/dist/client/navigation-runtime.js.map +1 -0
  25. package/dist/client/pages-router-link-navigation.d.ts +26 -0
  26. package/dist/client/pages-router-link-navigation.js +14 -0
  27. package/dist/client/pages-router-link-navigation.js.map +1 -0
  28. package/dist/client/vinext-next-data.d.ts +12 -2
  29. package/dist/client/vinext-next-data.js +50 -1
  30. package/dist/client/vinext-next-data.js.map +1 -0
  31. package/dist/client/window-next.d.ts +3 -1
  32. package/dist/client/window-next.js.map +1 -1
  33. package/dist/cloudflare/kv-cache-handler.js +2 -1
  34. package/dist/cloudflare/kv-cache-handler.js.map +1 -1
  35. package/dist/config/config-matchers.d.ts +63 -16
  36. package/dist/config/config-matchers.js +143 -8
  37. package/dist/config/config-matchers.js.map +1 -1
  38. package/dist/config/dotenv.d.ts +11 -1
  39. package/dist/config/dotenv.js.map +1 -1
  40. package/dist/config/next-config.d.ts +107 -5
  41. package/dist/config/next-config.js +233 -7
  42. package/dist/config/next-config.js.map +1 -1
  43. package/dist/config/tsconfig-paths.d.ts +13 -0
  44. package/dist/config/tsconfig-paths.js +117 -0
  45. package/dist/config/tsconfig-paths.js.map +1 -0
  46. package/dist/deploy.js +104 -41
  47. package/dist/deploy.js.map +1 -1
  48. package/dist/entries/app-browser-entry.d.ts +2 -2
  49. package/dist/entries/app-browser-entry.js +34 -3
  50. package/dist/entries/app-browser-entry.js.map +1 -1
  51. package/dist/entries/app-rsc-entry.d.ts +19 -1
  52. package/dist/entries/app-rsc-entry.js +89 -23
  53. package/dist/entries/app-rsc-entry.js.map +1 -1
  54. package/dist/entries/app-rsc-manifest.d.ts +10 -0
  55. package/dist/entries/app-rsc-manifest.js +57 -7
  56. package/dist/entries/app-rsc-manifest.js.map +1 -1
  57. package/dist/entries/app-ssr-entry.d.ts +3 -3
  58. package/dist/entries/app-ssr-entry.js +4 -4
  59. package/dist/entries/app-ssr-entry.js.map +1 -1
  60. package/dist/entries/pages-client-entry.js +21 -7
  61. package/dist/entries/pages-client-entry.js.map +1 -1
  62. package/dist/entries/pages-server-entry.js +77 -9
  63. package/dist/entries/pages-server-entry.js.map +1 -1
  64. package/dist/entries/runtime-entry-module.d.ts +2 -1
  65. package/dist/entries/runtime-entry-module.js +9 -3
  66. package/dist/entries/runtime-entry-module.js.map +1 -1
  67. package/dist/index.js +260 -75
  68. package/dist/index.js.map +1 -1
  69. package/dist/plugins/client-reference-dedup.d.ts +15 -2
  70. package/dist/plugins/client-reference-dedup.js +138 -16
  71. package/dist/plugins/client-reference-dedup.js.map +1 -1
  72. package/dist/plugins/css-data-url.d.ts +7 -0
  73. package/dist/plugins/css-data-url.js +81 -0
  74. package/dist/plugins/css-data-url.js.map +1 -0
  75. package/dist/plugins/fonts.d.ts +2 -2
  76. package/dist/plugins/fonts.js +20 -9
  77. package/dist/plugins/fonts.js.map +1 -1
  78. package/dist/plugins/middleware-server-only.d.ts +54 -0
  79. package/dist/plugins/middleware-server-only.js +91 -0
  80. package/dist/plugins/middleware-server-only.js.map +1 -0
  81. package/dist/plugins/optimize-imports.js +4 -4
  82. package/dist/plugins/optimize-imports.js.map +1 -1
  83. package/dist/plugins/sass.d.ts +34 -0
  84. package/dist/plugins/sass.js +22 -0
  85. package/dist/plugins/sass.js.map +1 -0
  86. package/dist/plugins/strip-server-exports.js +5 -8
  87. package/dist/plugins/strip-server-exports.js.map +1 -1
  88. package/dist/routing/app-route-graph.d.ts +50 -2
  89. package/dist/routing/app-route-graph.js +140 -16
  90. package/dist/routing/app-route-graph.js.map +1 -1
  91. package/dist/routing/app-router.d.ts +2 -2
  92. package/dist/routing/app-router.js +2 -2
  93. package/dist/routing/app-router.js.map +1 -1
  94. package/dist/routing/route-pattern.d.ts +56 -1
  95. package/dist/routing/route-pattern.js +60 -1
  96. package/dist/routing/route-pattern.js.map +1 -1
  97. package/dist/routing/utils.d.ts +2 -1
  98. package/dist/routing/utils.js +4 -1
  99. package/dist/routing/utils.js.map +1 -1
  100. package/dist/server/api-handler.js +139 -37
  101. package/dist/server/api-handler.js.map +1 -1
  102. package/dist/server/app-browser-action-result.d.ts +27 -2
  103. package/dist/server/app-browser-action-result.js +63 -2
  104. package/dist/server/app-browser-action-result.js.map +1 -1
  105. package/dist/server/app-browser-entry.js +493 -195
  106. package/dist/server/app-browser-entry.js.map +1 -1
  107. package/dist/server/app-browser-hydration.d.ts +13 -1
  108. package/dist/server/app-browser-hydration.js +9 -1
  109. package/dist/server/app-browser-hydration.js.map +1 -1
  110. package/dist/server/app-browser-interception-context.d.ts +24 -0
  111. package/dist/server/app-browser-interception-context.js +32 -0
  112. package/dist/server/app-browser-interception-context.js.map +1 -0
  113. package/dist/server/app-browser-navigation-controller.d.ts +17 -2
  114. package/dist/server/app-browser-navigation-controller.js +33 -10
  115. package/dist/server/app-browser-navigation-controller.js.map +1 -1
  116. package/dist/server/app-browser-popstate.d.ts +16 -0
  117. package/dist/server/app-browser-popstate.js +17 -0
  118. package/dist/server/app-browser-popstate.js.map +1 -0
  119. package/dist/server/app-browser-rsc-redirect.d.ts +29 -0
  120. package/dist/server/app-browser-rsc-redirect.js +37 -0
  121. package/dist/server/app-browser-rsc-redirect.js.map +1 -0
  122. package/dist/server/app-browser-state.d.ts +28 -7
  123. package/dist/server/app-browser-state.js +63 -27
  124. package/dist/server/app-browser-state.js.map +1 -1
  125. package/dist/server/app-browser-stream.d.ts +9 -17
  126. package/dist/server/app-browser-stream.js +18 -13
  127. package/dist/server/app-browser-stream.js.map +1 -1
  128. package/dist/server/app-browser-visible-commit.d.ts +7 -1
  129. package/dist/server/app-browser-visible-commit.js +39 -5
  130. package/dist/server/app-browser-visible-commit.js.map +1 -1
  131. package/dist/server/app-elements-wire.d.ts +43 -6
  132. package/dist/server/app-elements-wire.js +189 -7
  133. package/dist/server/app-elements-wire.js.map +1 -1
  134. package/dist/server/app-elements.d.ts +3 -2
  135. package/dist/server/app-elements.js +3 -2
  136. package/dist/server/app-elements.js.map +1 -1
  137. package/dist/server/app-fallback-renderer.d.ts +10 -1
  138. package/dist/server/app-fallback-renderer.js +41 -3
  139. package/dist/server/app-fallback-renderer.js.map +1 -1
  140. package/dist/server/app-history-state.d.ts +26 -0
  141. package/dist/server/app-history-state.js +53 -0
  142. package/dist/server/app-history-state.js.map +1 -0
  143. package/dist/server/app-middleware.d.ts +13 -0
  144. package/dist/server/app-middleware.js +3 -1
  145. package/dist/server/app-middleware.js.map +1 -1
  146. package/dist/server/app-optimistic-routing.d.ts +54 -0
  147. package/dist/server/app-optimistic-routing.js +200 -0
  148. package/dist/server/app-optimistic-routing.js.map +1 -0
  149. package/dist/server/app-page-boundary-render.d.ts +10 -1
  150. package/dist/server/app-page-boundary-render.js +13 -6
  151. package/dist/server/app-page-boundary-render.js.map +1 -1
  152. package/dist/server/app-page-boundary.js +3 -2
  153. package/dist/server/app-page-boundary.js.map +1 -1
  154. package/dist/server/app-page-cache.d.ts +26 -1
  155. package/dist/server/app-page-cache.js +86 -14
  156. package/dist/server/app-page-cache.js.map +1 -1
  157. package/dist/server/app-page-dispatch.d.ts +7 -0
  158. package/dist/server/app-page-dispatch.js +96 -12
  159. package/dist/server/app-page-dispatch.js.map +1 -1
  160. package/dist/server/app-page-element-builder.d.ts +7 -0
  161. package/dist/server/app-page-element-builder.js +34 -5
  162. package/dist/server/app-page-element-builder.js.map +1 -1
  163. package/dist/server/app-page-execution.d.ts +28 -1
  164. package/dist/server/app-page-execution.js +91 -7
  165. package/dist/server/app-page-execution.js.map +1 -1
  166. package/dist/server/app-page-head.d.ts +7 -0
  167. package/dist/server/app-page-head.js +23 -3
  168. package/dist/server/app-page-head.js.map +1 -1
  169. package/dist/server/app-page-probe.d.ts +23 -1
  170. package/dist/server/app-page-probe.js +29 -1
  171. package/dist/server/app-page-probe.js.map +1 -1
  172. package/dist/server/app-page-render-observation.d.ts +35 -0
  173. package/dist/server/app-page-render-observation.js +68 -0
  174. package/dist/server/app-page-render-observation.js.map +1 -0
  175. package/dist/server/app-page-render.d.ts +7 -1
  176. package/dist/server/app-page-render.js +81 -4
  177. package/dist/server/app-page-render.js.map +1 -1
  178. package/dist/server/app-page-request.d.ts +1 -0
  179. package/dist/server/app-page-request.js.map +1 -1
  180. package/dist/server/app-page-response.js +7 -5
  181. package/dist/server/app-page-response.js.map +1 -1
  182. package/dist/server/app-page-route-wiring.d.ts +3 -1
  183. package/dist/server/app-page-route-wiring.js +59 -24
  184. package/dist/server/app-page-route-wiring.js.map +1 -1
  185. package/dist/server/app-page-stream.d.ts +5 -0
  186. package/dist/server/app-page-stream.js +2 -0
  187. package/dist/server/app-page-stream.js.map +1 -1
  188. package/dist/server/app-prerender-static-params.d.ts +2 -1
  189. package/dist/server/app-prerender-static-params.js +44 -8
  190. package/dist/server/app-prerender-static-params.js.map +1 -1
  191. package/dist/server/app-route-handler-cache.d.ts +2 -2
  192. package/dist/server/app-route-handler-cache.js +3 -2
  193. package/dist/server/app-route-handler-cache.js.map +1 -1
  194. package/dist/server/app-route-handler-dispatch.d.ts +6 -1
  195. package/dist/server/app-route-handler-dispatch.js +1 -1
  196. package/dist/server/app-route-handler-dispatch.js.map +1 -1
  197. package/dist/server/app-route-handler-execution.d.ts +17 -2
  198. package/dist/server/app-route-handler-execution.js.map +1 -1
  199. package/dist/server/app-route-handler-response.js +5 -4
  200. package/dist/server/app-route-handler-response.js.map +1 -1
  201. package/dist/server/app-router-entry.js +7 -15
  202. package/dist/server/app-router-entry.js.map +1 -1
  203. package/dist/server/app-rsc-cache-busting.d.ts +19 -1
  204. package/dist/server/app-rsc-cache-busting.js +36 -1
  205. package/dist/server/app-rsc-cache-busting.js.map +1 -1
  206. package/dist/server/app-rsc-embedded-chunks.d.ts +9 -0
  207. package/dist/server/app-rsc-embedded-chunks.js +34 -0
  208. package/dist/server/app-rsc-embedded-chunks.js.map +1 -0
  209. package/dist/server/app-rsc-errors.d.ts +4 -1
  210. package/dist/server/app-rsc-errors.js +1 -1
  211. package/dist/server/app-rsc-errors.js.map +1 -1
  212. package/dist/server/app-rsc-handler.d.ts +21 -5
  213. package/dist/server/app-rsc-handler.js +38 -15
  214. package/dist/server/app-rsc-handler.js.map +1 -1
  215. package/dist/server/app-rsc-render-mode.d.ts +4 -3
  216. package/dist/server/app-rsc-render-mode.js +7 -1
  217. package/dist/server/app-rsc-render-mode.js.map +1 -1
  218. package/dist/server/app-rsc-request-normalization.d.ts +4 -1
  219. package/dist/server/app-rsc-request-normalization.js +4 -1
  220. package/dist/server/app-rsc-request-normalization.js.map +1 -1
  221. package/dist/server/app-rsc-response-finalizer.d.ts +8 -1
  222. package/dist/server/app-rsc-response-finalizer.js +10 -3
  223. package/dist/server/app-rsc-response-finalizer.js.map +1 -1
  224. package/dist/server/app-rsc-route-matching.d.ts +23 -0
  225. package/dist/server/app-rsc-route-matching.js +47 -25
  226. package/dist/server/app-rsc-route-matching.js.map +1 -1
  227. package/dist/server/app-server-action-execution.d.ts +35 -3
  228. package/dist/server/app-server-action-execution.js +87 -33
  229. package/dist/server/app-server-action-execution.js.map +1 -1
  230. package/dist/server/app-ssr-entry.d.ts +3 -0
  231. package/dist/server/app-ssr-entry.js +83 -58
  232. package/dist/server/app-ssr-entry.js.map +1 -1
  233. package/dist/server/app-ssr-error-meta.d.ts +14 -0
  234. package/dist/server/app-ssr-error-meta.js +50 -0
  235. package/dist/server/app-ssr-error-meta.js.map +1 -0
  236. package/dist/server/app-ssr-stream.d.ts +7 -2
  237. package/dist/server/app-ssr-stream.js +26 -15
  238. package/dist/server/app-ssr-stream.js.map +1 -1
  239. package/dist/server/artifact-compatibility.d.ts +13 -3
  240. package/dist/server/artifact-compatibility.js +12 -8
  241. package/dist/server/artifact-compatibility.js.map +1 -1
  242. package/dist/server/cache-headers.d.ts +7 -0
  243. package/dist/server/cache-headers.js +19 -0
  244. package/dist/server/cache-headers.js.map +1 -0
  245. package/dist/server/cache-proof.d.ts +170 -5
  246. package/dist/server/cache-proof.js +472 -18
  247. package/dist/server/cache-proof.js.map +1 -1
  248. package/dist/server/client-reuse-manifest.d.ts +99 -0
  249. package/dist/server/client-reuse-manifest.js +212 -0
  250. package/dist/server/client-reuse-manifest.js.map +1 -0
  251. package/dist/server/default-global-error-module.d.ts +20 -0
  252. package/dist/server/default-global-error-module.js +20 -0
  253. package/dist/server/default-global-error-module.js.map +1 -0
  254. package/dist/server/dev-lockfile.d.ts +110 -0
  255. package/dist/server/dev-lockfile.js +180 -0
  256. package/dist/server/dev-lockfile.js.map +1 -0
  257. package/dist/server/dev-server.d.ts +9 -1
  258. package/dist/server/dev-server.js +76 -19
  259. package/dist/server/dev-server.js.map +1 -1
  260. package/dist/server/edge-api-runtime.d.ts +5 -0
  261. package/dist/server/edge-api-runtime.js +8 -0
  262. package/dist/server/edge-api-runtime.js.map +1 -0
  263. package/dist/server/file-based-metadata.d.ts +13 -0
  264. package/dist/server/file-based-metadata.js +49 -2
  265. package/dist/server/file-based-metadata.js.map +1 -1
  266. package/dist/server/headers.d.ts +20 -1
  267. package/dist/server/headers.js +22 -2
  268. package/dist/server/headers.js.map +1 -1
  269. package/dist/server/html.js +1 -1
  270. package/dist/server/html.js.map +1 -1
  271. package/dist/server/http-error-responses.d.ts +26 -1
  272. package/dist/server/http-error-responses.js +32 -2
  273. package/dist/server/http-error-responses.js.map +1 -1
  274. package/dist/server/isr-cache.d.ts +8 -3
  275. package/dist/server/isr-cache.js +24 -6
  276. package/dist/server/isr-cache.js.map +1 -1
  277. package/dist/server/metadata-route-response.js +22 -5
  278. package/dist/server/metadata-route-response.js.map +1 -1
  279. package/dist/server/metadata-routes.js +27 -8
  280. package/dist/server/metadata-routes.js.map +1 -1
  281. package/dist/server/middleware-runtime.d.ts +15 -0
  282. package/dist/server/middleware-runtime.js +60 -7
  283. package/dist/server/middleware-runtime.js.map +1 -1
  284. package/dist/server/middleware.d.ts +13 -1
  285. package/dist/server/middleware.js +16 -2
  286. package/dist/server/middleware.js.map +1 -1
  287. package/dist/server/navigation-planner.d.ts +26 -6
  288. package/dist/server/navigation-planner.js +358 -24
  289. package/dist/server/navigation-planner.js.map +1 -1
  290. package/dist/server/navigation-trace.d.ts +9 -1
  291. package/dist/server/navigation-trace.js +8 -0
  292. package/dist/server/navigation-trace.js.map +1 -1
  293. package/dist/server/normalize-path.d.ts +2 -1
  294. package/dist/server/normalize-path.js +4 -1
  295. package/dist/server/normalize-path.js.map +1 -1
  296. package/dist/server/pages-api-route.d.ts +27 -1
  297. package/dist/server/pages-api-route.js +25 -3
  298. package/dist/server/pages-api-route.js.map +1 -1
  299. package/dist/server/pages-data-route.d.ts +77 -0
  300. package/dist/server/pages-data-route.js +97 -0
  301. package/dist/server/pages-data-route.js.map +1 -0
  302. package/dist/server/pages-i18n.d.ts +51 -1
  303. package/dist/server/pages-i18n.js +61 -1
  304. package/dist/server/pages-i18n.js.map +1 -1
  305. package/dist/server/pages-page-data.d.ts +32 -4
  306. package/dist/server/pages-page-data.js +52 -19
  307. package/dist/server/pages-page-data.js.map +1 -1
  308. package/dist/server/pages-page-response.d.ts +11 -1
  309. package/dist/server/pages-page-response.js +6 -4
  310. package/dist/server/pages-page-response.js.map +1 -1
  311. package/dist/server/prod-server.d.ts +26 -1
  312. package/dist/server/prod-server.js +150 -44
  313. package/dist/server/prod-server.js.map +1 -1
  314. package/dist/server/request-pipeline.d.ts +11 -2
  315. package/dist/server/request-pipeline.js +28 -11
  316. package/dist/server/request-pipeline.js.map +1 -1
  317. package/dist/server/seed-cache.d.ts +12 -31
  318. package/dist/server/seed-cache.js +22 -35
  319. package/dist/server/seed-cache.js.map +1 -1
  320. package/dist/server/server-action-not-found.d.ts +16 -3
  321. package/dist/server/server-action-not-found.js +27 -4
  322. package/dist/server/server-action-not-found.js.map +1 -1
  323. package/dist/server/server-globals.d.ts +5 -0
  324. package/dist/server/server-globals.js +37 -0
  325. package/dist/server/server-globals.js.map +1 -0
  326. package/dist/server/skip-cache-proof.d.ts +41 -0
  327. package/dist/server/skip-cache-proof.js +101 -0
  328. package/dist/server/skip-cache-proof.js.map +1 -0
  329. package/dist/server/static-file-cache.d.ts +1 -1
  330. package/dist/server/static-file-cache.js +7 -6
  331. package/dist/server/static-file-cache.js.map +1 -1
  332. package/dist/shims/cache-runtime.d.ts +19 -2
  333. package/dist/shims/cache-runtime.js +67 -11
  334. package/dist/shims/cache-runtime.js.map +1 -1
  335. package/dist/shims/cache.d.ts +5 -18
  336. package/dist/shims/cache.js +2 -0
  337. package/dist/shims/cache.js.map +1 -1
  338. package/dist/shims/client-locale.d.ts +15 -0
  339. package/dist/shims/client-locale.js +13 -0
  340. package/dist/shims/client-locale.js.map +1 -0
  341. package/dist/shims/default-global-error.d.ts +32 -0
  342. package/dist/shims/default-global-error.js +181 -0
  343. package/dist/shims/default-global-error.js.map +1 -0
  344. package/dist/shims/document.d.ts +59 -3
  345. package/dist/shims/document.js +36 -5
  346. package/dist/shims/document.js.map +1 -1
  347. package/dist/shims/error-boundary.d.ts +2 -2
  348. package/dist/shims/error-boundary.js +6 -8
  349. package/dist/shims/error-boundary.js.map +1 -1
  350. package/dist/shims/error.d.ts +18 -1
  351. package/dist/shims/error.js +56 -1
  352. package/dist/shims/error.js.map +1 -1
  353. package/dist/shims/fetch-cache.d.ts +4 -1
  354. package/dist/shims/fetch-cache.js +40 -5
  355. package/dist/shims/fetch-cache.js.map +1 -1
  356. package/dist/shims/font-google-base.d.ts +22 -8
  357. package/dist/shims/font-google-base.js +41 -71
  358. package/dist/shims/font-google-base.js.map +1 -1
  359. package/dist/shims/font-local.d.ts +3 -20
  360. package/dist/shims/font-local.js +23 -75
  361. package/dist/shims/font-local.js.map +1 -1
  362. package/dist/shims/font-utils.d.ts +51 -0
  363. package/dist/shims/font-utils.js +97 -0
  364. package/dist/shims/font-utils.js.map +1 -0
  365. package/dist/shims/form.js +13 -6
  366. package/dist/shims/form.js.map +1 -1
  367. package/dist/shims/hash-scroll.d.ts +7 -0
  368. package/dist/shims/hash-scroll.js +30 -0
  369. package/dist/shims/hash-scroll.js.map +1 -0
  370. package/dist/shims/headers.d.ts +8 -11
  371. package/dist/shims/headers.js +22 -2
  372. package/dist/shims/headers.js.map +1 -1
  373. package/dist/shims/image.d.ts +1 -0
  374. package/dist/shims/image.js +144 -78
  375. package/dist/shims/image.js.map +1 -1
  376. package/dist/shims/internal/app-router-context.d.ts +6 -6
  377. package/dist/shims/internal/app-router-context.js +17 -6
  378. package/dist/shims/internal/app-router-context.js.map +1 -1
  379. package/dist/shims/link-prefetch.d.ts +9 -1
  380. package/dist/shims/link-prefetch.js +11 -6
  381. package/dist/shims/link-prefetch.js.map +1 -1
  382. package/dist/shims/link.d.ts +33 -5
  383. package/dist/shims/link.js +205 -50
  384. package/dist/shims/link.js.map +1 -1
  385. package/dist/shims/metadata.d.ts +16 -30
  386. package/dist/shims/metadata.js +91 -32
  387. package/dist/shims/metadata.js.map +1 -1
  388. package/dist/shims/navigation.d.ts +164 -17
  389. package/dist/shims/navigation.js +355 -84
  390. package/dist/shims/navigation.js.map +1 -1
  391. package/dist/shims/navigation.react-server.d.ts +3 -2
  392. package/dist/shims/navigation.react-server.js +5 -2
  393. package/dist/shims/navigation.react-server.js.map +1 -1
  394. package/dist/shims/og.d.ts +18 -2
  395. package/dist/shims/og.js +49 -1
  396. package/dist/shims/og.js.map +1 -0
  397. package/dist/shims/pages-router-runtime.d.ts +7 -0
  398. package/dist/shims/pages-router-runtime.js +16 -0
  399. package/dist/shims/pages-router-runtime.js.map +1 -0
  400. package/dist/shims/request-state-types.d.ts +1 -1
  401. package/dist/shims/root-params.d.ts +3 -1
  402. package/dist/shims/root-params.js +11 -3
  403. package/dist/shims/root-params.js.map +1 -1
  404. package/dist/shims/router-state.d.ts +1 -0
  405. package/dist/shims/router-state.js.map +1 -1
  406. package/dist/shims/router.d.ts +40 -7
  407. package/dist/shims/router.js +355 -250
  408. package/dist/shims/router.js.map +1 -1
  409. package/dist/shims/script.js +110 -32
  410. package/dist/shims/script.js.map +1 -1
  411. package/dist/shims/server.d.ts +21 -4
  412. package/dist/shims/server.js +31 -10
  413. package/dist/shims/server.js.map +1 -1
  414. package/dist/shims/slot.d.ts +1 -0
  415. package/dist/shims/slot.js +45 -1
  416. package/dist/shims/slot.js.map +1 -1
  417. package/dist/shims/unified-request-context.d.ts +1 -1
  418. package/dist/shims/unified-request-context.js +2 -0
  419. package/dist/shims/unified-request-context.js.map +1 -1
  420. package/dist/shims/unrecognized-action-error.d.ts +35 -0
  421. package/dist/shims/unrecognized-action-error.js +41 -0
  422. package/dist/shims/unrecognized-action-error.js.map +1 -0
  423. package/dist/shims/url-safety.d.ts +23 -1
  424. package/dist/shims/url-safety.js +29 -2
  425. package/dist/shims/url-safety.js.map +1 -1
  426. package/dist/shims/url-utils.d.ts +21 -1
  427. package/dist/shims/url-utils.js +67 -3
  428. package/dist/shims/url-utils.js.map +1 -1
  429. package/dist/typegen.d.ts +10 -0
  430. package/dist/typegen.js +242 -0
  431. package/dist/typegen.js.map +1 -0
  432. package/dist/utils/asset-prefix.d.ts +97 -0
  433. package/dist/utils/asset-prefix.js +124 -0
  434. package/dist/utils/asset-prefix.js.map +1 -0
  435. package/dist/utils/base-path.d.ts +7 -1
  436. package/dist/utils/base-path.js +10 -1
  437. package/dist/utils/base-path.js.map +1 -1
  438. package/dist/utils/cache-control-metadata.d.ts +2 -1
  439. package/dist/utils/cache-control-metadata.js +1 -3
  440. package/dist/utils/cache-control-metadata.js.map +1 -1
  441. package/dist/utils/domain-locale.d.ts +2 -1
  442. package/dist/utils/domain-locale.js +9 -1
  443. package/dist/utils/domain-locale.js.map +1 -1
  444. package/dist/utils/lazy-chunks.d.ts +1 -1
  445. package/dist/utils/lazy-chunks.js +1 -1
  446. package/dist/utils/lazy-chunks.js.map +1 -1
  447. package/dist/utils/navigation-signal.d.ts +1 -2
  448. package/dist/utils/navigation-signal.js +1 -1
  449. package/dist/utils/navigation-signal.js.map +1 -1
  450. package/dist/utils/prerender-output-paths.d.ts +15 -0
  451. package/dist/utils/prerender-output-paths.js +24 -0
  452. package/dist/utils/prerender-output-paths.js.map +1 -0
  453. package/dist/utils/query.d.ts +17 -1
  454. package/dist/utils/query.js +36 -1
  455. package/dist/utils/query.js.map +1 -1
  456. package/dist/utils/record.d.ts +5 -0
  457. package/dist/utils/record.js +8 -0
  458. package/dist/utils/record.js.map +1 -0
  459. package/dist/utils/sorted-array.d.ts +9 -0
  460. package/dist/utils/sorted-array.js +22 -0
  461. package/dist/utils/sorted-array.js.map +1 -0
  462. package/package.json +13 -5
@@ -1,5 +1,6 @@
1
1
  import { activateNavigationSnapshot, clearPendingPathname, commitClientNavigationState } from "../shims/navigation.js";
2
- import { createPendingNavigationCommit } from "./app-browser-state.js";
2
+ import { shouldScheduleRefreshForDiscardedServerAction } from "./app-browser-action-result.js";
3
+ import { FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, createPendingNavigationCommit } from "./app-browser-state.js";
3
4
  import { applyApprovedVisibleCommit, approveHmrVisibleCommit, approvePendingNavigationCommit, resolveAndClassifyNavigationCommit } from "./app-browser-visible-commit.js";
4
5
  import { startTransition, useLayoutEffect } from "react";
5
6
  //#region src/server/app-browser-navigation-controller.ts
@@ -50,6 +51,8 @@ function performHardNavigationWithLoopGuard(href, mode = "assign") {
50
51
  function createAppBrowserNavigationController(deps = {}) {
51
52
  const commitClientNavigationStateImpl = deps.commitClientNavigationState ?? commitClientNavigationState;
52
53
  const performHardNavigation = deps.performHardNavigation ?? performHardNavigationWithLoopGuard;
54
+ const getRouteManifest = deps.getRouteManifest ?? (() => null);
55
+ const syncHistoryStatePreviousNextUrl = deps.syncHistoryStatePreviousNextUrl ?? (() => {});
53
56
  let nextNavigationRenderId = 0;
54
57
  let activeNavigationId = 0;
55
58
  const pendingNavigationCommits = /* @__PURE__ */ new Map();
@@ -86,6 +89,9 @@ function createAppBrowserNavigationController(deps = {}) {
86
89
  activeNavigationId += 1;
87
90
  return activeNavigationId;
88
91
  }
92
+ function getActiveNavigationId() {
93
+ return activeNavigationId;
94
+ }
89
95
  function allocateRenderId() {
90
96
  nextNavigationRenderId += 1;
91
97
  return nextNavigationRenderId;
@@ -175,6 +181,7 @@ function createAppBrowserNavigationController(deps = {}) {
175
181
  nextElements,
176
182
  navigationSnapshot,
177
183
  operationLane: "hmr",
184
+ payloadOrigin: FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN,
178
185
  renderId: allocateRenderId(),
179
186
  type: "replace"
180
187
  });
@@ -207,6 +214,10 @@ function createAppBrowserNavigationController(deps = {}) {
207
214
  function dispatchSynchronousVisibleCommit(commit) {
208
215
  getBrowserRouterStateSetter()(applyApprovedVisibleCommit(getBrowserRouterState(), commit));
209
216
  }
217
+ function notifyDiscardedServerActionRevalidation(lifecycleOptions) {
218
+ if (!shouldScheduleRefreshForDiscardedServerAction(lifecycleOptions?.revalidation ?? "none")) return;
219
+ lifecycleOptions?.onDiscardedRevalidation?.();
220
+ }
210
221
  async function renderNavigationPayload(options) {
211
222
  const renderId = allocateRenderId();
212
223
  let resolveCommitted;
@@ -221,6 +232,7 @@ function createAppBrowserNavigationController(deps = {}) {
221
232
  nextElements: options.nextElements,
222
233
  navigationSnapshot: options.navigationSnapshot,
223
234
  operationLane: options.operationLane,
235
+ payloadOrigin: options.payloadOrigin,
224
236
  previousNextUrl: options.previousNextUrl,
225
237
  renderId,
226
238
  type: options.actionType
@@ -229,6 +241,7 @@ function createAppBrowserNavigationController(deps = {}) {
229
241
  activeNavigationId,
230
242
  currentState: getBrowserRouterState(),
231
243
  pending,
244
+ routeManifest: getRouteManifest(),
232
245
  startedNavigationId: options.navId,
233
246
  targetHref: options.targetHref
234
247
  });
@@ -250,7 +263,8 @@ function createAppBrowserNavigationController(deps = {}) {
250
263
  historyUpdateMode: options.historyUpdateMode,
251
264
  navId: options.navId,
252
265
  params: options.params,
253
- previousNextUrl: approvedCommit.previousNextUrl
266
+ previousNextUrl: approvedCommit.previousNextUrl,
267
+ targetHistoryIndex: options.targetHistoryIndex
254
268
  }));
255
269
  activateNavigationSnapshot();
256
270
  snapshotActivated = true;
@@ -265,9 +279,10 @@ function createAppBrowserNavigationController(deps = {}) {
265
279
  }
266
280
  return committed.then(() => "committed");
267
281
  }
268
- async function commitSameUrlNavigatePayload(nextElements, navigationSnapshot, returnValue, actionInitiationState) {
282
+ async function commitSameUrlNavigatePayload(nextElements, navigationSnapshot, returnValue, actionInitiationState, lifecycleOptions) {
269
283
  const currentState = actionInitiationState ?? getBrowserRouterState();
270
- const startedNavigationId = activeNavigationId;
284
+ const startedNavigationId = lifecycleOptions?.startedNavigationId ?? activeNavigationId;
285
+ const targetHref = lifecycleOptions?.targetHref ?? window.location.href;
271
286
  const { approvedCommit, decision, pending, trace: _navigationTrace } = await resolveAndClassifyNavigationCommit({
272
287
  activeNavigationId,
273
288
  currentState,
@@ -277,12 +292,14 @@ function createAppBrowserNavigationController(deps = {}) {
277
292
  nextElements,
278
293
  renderId: allocateRenderId(),
279
294
  operationLane: "server-action",
295
+ payloadOrigin: FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN,
280
296
  startedNavigationId,
281
- targetHref: window.location.href,
297
+ routeManifest: getRouteManifest(),
298
+ targetHref,
282
299
  type: "navigate"
283
300
  });
284
301
  if (decision.disposition === "hard-navigate") {
285
- performHardNavigation(window.location.href);
302
+ performHardNavigation(targetHref);
286
303
  return;
287
304
  }
288
305
  if (approvedCommit) {
@@ -290,15 +307,19 @@ function createAppBrowserNavigationController(deps = {}) {
290
307
  activeNavigationId,
291
308
  currentState: getBrowserRouterState(),
292
309
  pending,
310
+ routeManifest: getRouteManifest(),
293
311
  startedNavigationId,
294
- targetHref: window.location.href
312
+ targetHref
295
313
  });
296
314
  if (latestApproval.decision.disposition === "hard-navigate") {
297
- performHardNavigation(window.location.href);
315
+ performHardNavigation(targetHref);
298
316
  return;
299
317
  }
300
- if (latestApproval.approvedCommit) dispatchSynchronousVisibleCommit(latestApproval.approvedCommit);
301
- }
318
+ if (latestApproval.approvedCommit) {
319
+ dispatchSynchronousVisibleCommit(latestApproval.approvedCommit);
320
+ syncHistoryStatePreviousNextUrl(latestApproval.approvedCommit.previousNextUrl);
321
+ } else notifyDiscardedServerActionRevalidation(lifecycleOptions);
322
+ } else if (decision.disposition === "no-commit") notifyDiscardedServerActionRevalidation(lifecycleOptions);
302
323
  if (returnValue) {
303
324
  if (!returnValue.ok) throw returnValue.data;
304
325
  return returnValue.data;
@@ -318,9 +339,11 @@ function createAppBrowserNavigationController(deps = {}) {
318
339
  }
319
340
  return {
320
341
  beginNavigation,
342
+ getActiveNavigationId,
321
343
  hasBrowserRouterState,
322
344
  getBrowserRouterState,
323
345
  isCurrentNavigation,
346
+ performHardNavigation,
324
347
  waitForBrowserRouterStateReady,
325
348
  attachBrowserRouterState,
326
349
  beginPendingBrowserRouterState,
@@ -1 +1 @@
1
- {"version":3,"file":"app-browser-navigation-controller.js","names":[],"sources":["../../src/server/app-browser-navigation-controller.ts"],"sourcesContent":["import { startTransition, useLayoutEffect, type Dispatch, type ReactNode } from \"react\";\nimport {\n activateNavigationSnapshot,\n clearPendingPathname,\n commitClientNavigationState,\n} from \"vinext/shims/navigation\";\nimport type { ClientNavigationRenderSnapshot } from \"vinext/shims/navigation\";\nimport {\n createPendingNavigationCommit,\n type AppRouterState,\n type OperationLane,\n} from \"./app-browser-state.js\";\nimport {\n applyApprovedVisibleCommit,\n approveHmrVisibleCommit,\n approvePendingNavigationCommit,\n resolveAndClassifyNavigationCommit,\n type ApprovedVisibleCommit,\n} from \"./app-browser-visible-commit.js\";\nimport type { AppElements } from \"./app-elements.js\";\n\nexport type HistoryUpdateMode = \"push\" | \"replace\";\n\nexport type PendingBrowserRouterState = {\n promise: Promise<AppRouterState>;\n resolve: (state: AppRouterState) => void;\n settled: boolean;\n};\nexport type NavigationPayloadOutcome = \"committed\" | \"no-commit\" | \"hard-navigate\";\ntype HardNavigationMode = \"assign\" | \"replace\";\n\ntype BrowserNavigationCommitEffectFactory = (options: {\n href: string;\n historyUpdateMode: HistoryUpdateMode | undefined;\n navId: number;\n params: Record<string, string | string[]>;\n previousNextUrl: string | null;\n}) => () => void;\n\ntype BrowserRouterStateRef = {\n current: AppRouterState;\n};\n\ntype BrowserNavigationControllerDeps = {\n commitClientNavigationState?: typeof commitClientNavigationState;\n performHardNavigation?: (href: string, mode?: HardNavigationMode) => boolean;\n};\n\ntype BrowserNavigationController = {\n beginNavigation(): number;\n hasBrowserRouterState(): boolean;\n getBrowserRouterState(): AppRouterState;\n isCurrentNavigation(navId: number): boolean;\n waitForBrowserRouterStateReady(): Promise<void>;\n attachBrowserRouterState(\n setter: Dispatch<AppRouterState | Promise<AppRouterState>>,\n stateRef: BrowserRouterStateRef,\n ): () => void;\n beginPendingBrowserRouterState(): PendingBrowserRouterState;\n finalizeNavigation(navId: number, pending: PendingBrowserRouterState | null | undefined): void;\n renderNavigationPayload(options: {\n actionType: \"navigate\" | \"replace\" | \"traverse\";\n createNavigationCommitEffect: BrowserNavigationCommitEffectFactory;\n historyUpdateMode: HistoryUpdateMode | undefined;\n navigationSnapshot: ClientNavigationRenderSnapshot;\n nextElements: Promise<AppElements>;\n operationLane: OperationLane;\n params: Record<string, string | string[]>;\n pendingRouterState: PendingBrowserRouterState | null;\n previousNextUrl: string | null;\n targetHref: string;\n navId: number;\n }): Promise<NavigationPayloadOutcome>;\n commitSameUrlNavigatePayload(\n nextElements: Promise<AppElements>,\n navigationSnapshot: ClientNavigationRenderSnapshot,\n returnValue?: { ok: boolean; data: unknown },\n actionInitiationState?: AppRouterState,\n ): Promise<unknown>;\n hmrReplaceTree(\n nextElements: Promise<AppElements>,\n navigationSnapshot: ClientNavigationRenderSnapshot,\n ): Promise<void>;\n /**\n * Force-drain the queued pre-paint effect for the given renderId without\n * waiting for NavigationCommitSignal to commit. Used by the dev recovery\n * boundary in app-browser-entry.ts: when a render error replaces\n * NavigationCommitSignal with the boundary's null fallback, its\n * useLayoutEffect never fires, so the URL update for the in-flight\n * navigation would otherwise be lost.\n */\n drainPrePaintEffects(renderId: number): void;\n NavigationCommitSignal(\n this: void,\n {\n renderId,\n children,\n }: {\n renderId: number;\n children?: ReactNode;\n },\n ): ReactNode;\n};\n\nconst HARD_NAVIGATION_LOOP_GUARD_KEY = \"__vinext_hard_navigation_target__\";\n\nfunction normalizeBrowserHref(href: string): string {\n try {\n return new URL(href, window.location.href).href;\n } catch {\n return href;\n }\n}\n\nfunction readHardNavigationLoopGuard(): string | null {\n try {\n return window.sessionStorage.getItem(HARD_NAVIGATION_LOOP_GUARD_KEY);\n } catch {\n return null;\n }\n}\n\nfunction writeHardNavigationLoopGuard(targetHref: string): boolean {\n try {\n window.sessionStorage.setItem(HARD_NAVIGATION_LOOP_GUARD_KEY, targetHref);\n return window.sessionStorage.getItem(HARD_NAVIGATION_LOOP_GUARD_KEY) === targetHref;\n } catch {\n return false;\n }\n}\n\nexport function clearHardNavigationLoopGuard(): void {\n try {\n window.sessionStorage.removeItem(HARD_NAVIGATION_LOOP_GUARD_KEY);\n } catch {}\n}\n\nfunction performHardNavigationWithLoopGuard(\n href: string,\n mode: HardNavigationMode = \"assign\",\n): boolean {\n const targetHref = normalizeBrowserHref(href);\n const currentHref = normalizeBrowserHref(window.location.href);\n\n if (readHardNavigationLoopGuard() === targetHref && currentHref === targetHref) {\n clearHardNavigationLoopGuard();\n console.error(\n `[vinext] Prevented repeated hard navigation to ${targetHref}; ` +\n \"leaving the current document in place to avoid a reload loop.\",\n );\n return false;\n }\n\n const guardPersisted = writeHardNavigationLoopGuard(targetHref);\n if (!guardPersisted && currentHref === targetHref) {\n console.error(\n `[vinext] Hard navigation to ${targetHref} requires a reload-loop guard, ` +\n \"but sessionStorage is unavailable; leaving the current document in place.\",\n );\n return false;\n }\n // If storage is unavailable but the target is a different URL, the browser\n // can still make forward progress. Only same-target reloads need a persisted\n // guard because they can re-enter this exact recovery path indefinitely.\n\n if (mode === \"replace\") {\n window.location.replace(href);\n } else {\n window.location.assign(href);\n }\n return true;\n}\n\nexport function createAppBrowserNavigationController(\n deps: BrowserNavigationControllerDeps = {},\n): BrowserNavigationController {\n const commitClientNavigationStateImpl =\n deps.commitClientNavigationState ?? commitClientNavigationState;\n const performHardNavigation = deps.performHardNavigation ?? performHardNavigationWithLoopGuard;\n\n // These are plain module-level variables (inside the controller closure),\n // unlike ClientNavigationState which uses Symbol.for to survive multiple\n // Vite module instances. The browser entry is loaded exactly once (via the\n // RSC plugin's generated bootstrap), so the controller running in a single\n // module instance is safe. If that assumption ever changes, these should be\n // migrated to a Symbol.for-backed global.\n //\n // The most severe consequence of multiple instances would be Map fragmentation:\n // pendingNavigationCommits and pendingNavigationPrePaintEffects would split\n // across instances, so drainPrePaintEffects in one instance could never drain\n // effects queued by the other, permanently leaking navigationSnapshotActiveCount\n // and causing hooks to prefer stale snapshot values indefinitely.\n let nextNavigationRenderId = 0;\n let activeNavigationId = 0;\n const pendingNavigationCommits = new Map<number, () => void>();\n const pendingNavigationPrePaintEffects = new Map<number, () => void>();\n\n let setBrowserRouterState: Dispatch<AppRouterState | Promise<AppRouterState>> | null = null;\n let browserRouterStateRef: BrowserRouterStateRef | null = null;\n let activePendingBrowserRouterState: PendingBrowserRouterState | null = null;\n let resolveBrowserRouterStateReady: (() => void) | null = null;\n let browserRouterStateReadyPromise: Promise<void> | null = null;\n let browserRouterStateHasCommitted = false;\n\n function getBrowserRouterStateSetter(): Dispatch<AppRouterState | Promise<AppRouterState>> {\n if (!setBrowserRouterState) {\n throw new Error(\"[vinext] Browser router state setter is not initialized\");\n }\n return setBrowserRouterState;\n }\n\n function getBrowserRouterState(): AppRouterState {\n if (!browserRouterStateRef) {\n throw new Error(\"[vinext] Browser router state is not initialized\");\n }\n return browserRouterStateRef.current;\n }\n\n function waitForBrowserRouterStateReady(): Promise<void> {\n if (browserRouterStateRef || browserRouterStateHasCommitted) {\n return Promise.resolve();\n }\n\n if (!browserRouterStateReadyPromise) {\n browserRouterStateReadyPromise = new Promise((resolve) => {\n resolveBrowserRouterStateReady = resolve;\n });\n }\n\n return browserRouterStateReadyPromise;\n }\n\n function markBrowserRouterStateReady(): void {\n browserRouterStateHasCommitted = true;\n const resolveReady = resolveBrowserRouterStateReady;\n resolveBrowserRouterStateReady = null;\n browserRouterStateReadyPromise = null;\n resolveReady?.();\n }\n\n function beginNavigation(): number {\n activeNavigationId += 1;\n return activeNavigationId;\n }\n\n function allocateRenderId(): number {\n nextNavigationRenderId += 1;\n return nextNavigationRenderId;\n }\n\n function hasBrowserRouterState(): boolean {\n return browserRouterStateRef !== null;\n }\n\n function isCurrentNavigation(navId: number): boolean {\n return navId === activeNavigationId;\n }\n\n function beginPendingBrowserRouterState(): PendingBrowserRouterState {\n const setter = getBrowserRouterStateSetter();\n\n if (activePendingBrowserRouterState && !activePendingBrowserRouterState.settled) {\n activePendingBrowserRouterState.settled = true;\n activePendingBrowserRouterState.resolve(getBrowserRouterState());\n }\n\n let resolvePending: ((state: AppRouterState) => void) | undefined;\n const promise = new Promise<AppRouterState>((resolve) => {\n resolvePending = resolve;\n });\n\n if (!resolvePending) {\n throw new Error(\"[vinext] Failed to initialize browser router promise\");\n }\n\n const pending: PendingBrowserRouterState = {\n promise,\n resolve: resolvePending,\n settled: false,\n };\n\n activePendingBrowserRouterState = pending;\n setter(promise);\n\n return pending;\n }\n\n function settlePendingBrowserRouterState(\n pending: PendingBrowserRouterState | null | undefined,\n ): void {\n if (!pending || pending.settled) return;\n\n pending.settled = true;\n pending.resolve(getBrowserRouterState());\n\n if (activePendingBrowserRouterState === pending) {\n activePendingBrowserRouterState = null;\n }\n }\n\n function finalizeNavigation(\n navId: number,\n pending: PendingBrowserRouterState | null | undefined,\n ): void {\n settlePendingBrowserRouterState(pending);\n\n if (isCurrentNavigation(navId)) {\n clearPendingPathname(navId);\n }\n }\n\n function resolvePendingBrowserRouterState(\n pending: PendingBrowserRouterState | null | undefined,\n commit: ApprovedVisibleCommit,\n ): void {\n if (!pending || pending.settled) return;\n\n pending.settled = true;\n pending.resolve(applyApprovedVisibleCommit(getBrowserRouterState(), commit));\n\n if (activePendingBrowserRouterState === pending) {\n activePendingBrowserRouterState = null;\n }\n }\n\n function queuePrePaintNavigationEffect(renderId: number, effect: (() => void) | null): void {\n if (!effect) {\n return;\n }\n pendingNavigationPrePaintEffects.set(renderId, effect);\n }\n\n /**\n * Run all queued pre-paint effects for renderIds up to and including the\n * given renderId. When React supersedes a startTransition update (rapid\n * clicks on same-route links), the superseded NavigationCommitSignal never\n * mounts, so its pre-paint effect never fires. By draining all effects\n * <= the committed renderId here, the winning transition cleans up after\n * any superseded ones, keeping the counter balanced.\n *\n * Invariant: each superseded navigation gets a commitClientNavigationState()\n * to balance the activateNavigationSnapshot() from its renderNavigationPayload call.\n */\n function drainPrePaintEffects(upToRenderId: number): void {\n for (const [id, effect] of pendingNavigationPrePaintEffects) {\n if (id > upToRenderId) {\n continue;\n }\n\n pendingNavigationPrePaintEffects.delete(id);\n if (id === upToRenderId) {\n effect();\n } else {\n // Superseded navigations still need to balance the snapshot counter.\n commitClientNavigationStateImpl(undefined, { releaseSnapshot: true });\n }\n }\n }\n\n /**\n * Resolve all pending navigation commits with renderId <= the committed renderId.\n * Note: Map iteration handles concurrent deletion safely — entries are visited in\n * insertion order and deletion doesn't affect the iterator's view of remaining entries.\n * This pattern is also used in drainPrePaintEffects with the same semantics.\n */\n function resolveCommittedNavigations(renderId: number): void {\n for (const [pendingId, resolve] of pendingNavigationCommits) {\n if (pendingId > renderId) {\n continue;\n }\n\n pendingNavigationCommits.delete(pendingId);\n resolve();\n }\n }\n\n async function hmrReplaceTree(\n nextElements: Promise<AppElements>,\n navigationSnapshot: ClientNavigationRenderSnapshot,\n ): Promise<void> {\n if (!hasBrowserRouterState()) return;\n\n const currentState = getBrowserRouterState();\n const renderId = allocateRenderId();\n const pending = await createPendingNavigationCommit({\n currentState,\n nextElements,\n navigationSnapshot,\n operationLane: \"hmr\",\n renderId,\n type: \"replace\",\n });\n\n // createPendingNavigationCommit awaits the new RSC payload. While\n // suspended, the prior broken render can unmount BrowserRoot. Re-check\n // before dispatching so a racing unmount doesn't surface as an\n // initialized-setter error.\n if (!hasBrowserRouterState()) return;\n\n dispatchSynchronousVisibleCommit(approveHmrVisibleCommit(pending));\n }\n\n function NavigationCommitSignal(\n this: void,\n {\n renderId,\n children,\n }: {\n renderId: number;\n children?: ReactNode;\n },\n ): ReactNode {\n useLayoutEffect(() => {\n drainPrePaintEffects(renderId);\n\n const frame = requestAnimationFrame(() => {\n resolveCommittedNavigations(renderId);\n });\n\n return () => {\n cancelAnimationFrame(frame);\n // Resolve pending commits to prevent callers from hanging if React\n // unmounts this component without committing (e.g., error boundary).\n resolveCommittedNavigations(renderId);\n };\n }, [renderId]);\n\n return children;\n }\n\n function dispatchApprovedVisibleCommit(\n commit: ApprovedVisibleCommit,\n pendingRouterState: PendingBrowserRouterState | null,\n ): void {\n const setter = getBrowserRouterStateSetter();\n\n if (pendingRouterState) {\n // The programmatic navigation is already running inside React.startTransition\n // (from router.push/replace/refresh/Link), so resolving the deferred promise\n // is sufficient.\n resolvePendingBrowserRouterState(pendingRouterState, commit);\n return;\n }\n\n startTransition(() => {\n setter(applyApprovedVisibleCommit(getBrowserRouterState(), commit));\n });\n }\n\n function dispatchSynchronousVisibleCommit(commit: ApprovedVisibleCommit): void {\n const setter = getBrowserRouterStateSetter();\n setter(applyApprovedVisibleCommit(getBrowserRouterState(), commit));\n }\n\n async function renderNavigationPayload(options: {\n actionType: \"navigate\" | \"replace\" | \"traverse\";\n createNavigationCommitEffect: BrowserNavigationCommitEffectFactory;\n historyUpdateMode: HistoryUpdateMode | undefined;\n navigationSnapshot: ClientNavigationRenderSnapshot;\n nextElements: Promise<AppElements>;\n operationLane: OperationLane;\n params: Record<string, string | string[]>;\n pendingRouterState: PendingBrowserRouterState | null;\n previousNextUrl: string | null;\n targetHref: string;\n navId: number;\n }): Promise<NavigationPayloadOutcome> {\n const renderId = allocateRenderId();\n let resolveCommitted: (() => void) | undefined;\n const committed = new Promise<void>((resolve) => {\n resolveCommitted = resolve;\n pendingNavigationCommits.set(renderId, resolve);\n });\n\n let snapshotActivated = false;\n try {\n const startedState = getBrowserRouterState();\n const pending = await createPendingNavigationCommit({\n currentState: startedState,\n nextElements: options.nextElements,\n navigationSnapshot: options.navigationSnapshot,\n operationLane: options.operationLane,\n previousNextUrl: options.previousNextUrl,\n renderId,\n type: options.actionType,\n });\n\n const approval = approvePendingNavigationCommit({\n activeNavigationId,\n currentState: getBrowserRouterState(),\n pending,\n startedNavigationId: options.navId,\n targetHref: options.targetHref,\n });\n\n if (approval.decision.disposition === \"no-commit\") {\n settlePendingBrowserRouterState(options.pendingRouterState);\n pendingNavigationCommits.delete(renderId);\n resolveCommitted?.();\n return \"no-commit\";\n }\n\n if (approval.decision.disposition === \"hard-navigate\") {\n settlePendingBrowserRouterState(options.pendingRouterState);\n pendingNavigationCommits.delete(renderId);\n return performHardNavigation(options.targetHref) ? \"hard-navigate\" : \"no-commit\";\n }\n\n const approvedCommit = approval.approvedCommit;\n if (approvedCommit === null) {\n throw new Error(\"[vinext] Commit decision did not approve a visible commit\");\n }\n\n queuePrePaintNavigationEffect(\n renderId,\n options.createNavigationCommitEffect({\n href: options.targetHref,\n historyUpdateMode: options.historyUpdateMode,\n navId: options.navId,\n params: options.params,\n previousNextUrl: approvedCommit.previousNextUrl,\n }),\n );\n activateNavigationSnapshot();\n snapshotActivated = true;\n dispatchApprovedVisibleCommit(approvedCommit, options.pendingRouterState);\n } catch (error) {\n pendingNavigationPrePaintEffects.delete(renderId);\n pendingNavigationCommits.delete(renderId);\n if (snapshotActivated) {\n commitClientNavigationStateImpl(options.navId);\n }\n settlePendingBrowserRouterState(options.pendingRouterState);\n resolveCommitted?.();\n throw error;\n }\n\n return committed.then(() => \"committed\");\n }\n\n async function commitSameUrlNavigatePayload(\n nextElements: Promise<AppElements>,\n navigationSnapshot: ClientNavigationRenderSnapshot,\n returnValue?: { ok: boolean; data: unknown },\n actionInitiationState?: AppRouterState,\n ): Promise<unknown> {\n const currentState = actionInitiationState ?? getBrowserRouterState();\n const startedNavigationId = activeNavigationId;\n const {\n approvedCommit,\n decision,\n pending,\n // Intentionally retained as #726-OPS-01 trace-shell scaffolding. The\n // same-URL action path can consume this trace once later lifecycle gates\n // need an observable commit explanation.\n trace: _navigationTrace,\n } = await resolveAndClassifyNavigationCommit({\n activeNavigationId,\n currentState,\n getActiveNavigationId: () => activeNavigationId,\n getCurrentStateForApproval: getBrowserRouterState,\n navigationSnapshot,\n nextElements,\n renderId: allocateRenderId(),\n operationLane: \"server-action\",\n startedNavigationId,\n targetHref: window.location.href,\n type: \"navigate\",\n });\n\n if (decision.disposition === \"hard-navigate\") {\n // Same-URL action hard navigations do not expose a navigation outcome to\n // callers. If the loop guard blocks, the degraded state is still the\n // existing return contract: no visible commit and no action value.\n performHardNavigation(window.location.href);\n return undefined;\n }\n\n if (approvedCommit) {\n // The helper approval and this continuation are separated by a microtask\n // boundary, so re-check lifecycle authority before mutating visible UI.\n const latestApproval = approvePendingNavigationCommit({\n activeNavigationId,\n currentState: getBrowserRouterState(),\n pending,\n startedNavigationId,\n targetHref: window.location.href,\n });\n\n if (latestApproval.decision.disposition === \"hard-navigate\") {\n // See the same-URL hard-navigation note above. The guard result is\n // deliberately not surfaced through the server-action return channel.\n performHardNavigation(window.location.href);\n return undefined;\n }\n\n if (latestApproval.approvedCommit) {\n dispatchSynchronousVisibleCommit(latestApproval.approvedCommit);\n }\n }\n\n // Same-URL server actions still return their action value even if the UI\n // update was skipped due to a superseding navigation. That preserves the\n // existing caller contract; a future Phase 2 router state model could make\n // skipped UI updates observable to the caller without conflating them here.\n if (returnValue) {\n if (!returnValue.ok) {\n throw returnValue.data;\n }\n return returnValue.data;\n }\n\n return undefined;\n }\n\n function attachBrowserRouterState(\n setter: Dispatch<AppRouterState | Promise<AppRouterState>>,\n stateRef: BrowserRouterStateRef,\n ): () => void {\n setBrowserRouterState = setter;\n browserRouterStateRef = stateRef;\n markBrowserRouterStateReady();\n\n return () => {\n if (setBrowserRouterState === setter) {\n setBrowserRouterState = null;\n }\n if (browserRouterStateRef === stateRef) {\n browserRouterStateRef = null;\n browserRouterStateHasCommitted = false;\n }\n };\n }\n\n return {\n beginNavigation,\n hasBrowserRouterState,\n getBrowserRouterState,\n isCurrentNavigation,\n waitForBrowserRouterStateReady,\n attachBrowserRouterState,\n beginPendingBrowserRouterState,\n finalizeNavigation,\n renderNavigationPayload,\n commitSameUrlNavigatePayload,\n hmrReplaceTree,\n drainPrePaintEffects,\n NavigationCommitSignal,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"app-browser-navigation-controller.js","names":[],"sources":["../../src/server/app-browser-navigation-controller.ts"],"sourcesContent":["import { startTransition, useLayoutEffect, type Dispatch, type ReactNode } from \"react\";\nimport {\n activateNavigationSnapshot,\n clearPendingPathname,\n commitClientNavigationState,\n} from \"vinext/shims/navigation\";\nimport type { ClientNavigationRenderSnapshot } from \"vinext/shims/navigation\";\nimport type { RouteManifest } from \"../routing/app-route-graph.js\";\nimport {\n FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN,\n createPendingNavigationCommit,\n type AppNavigationPayloadOrigin,\n type AppRouterState,\n type OperationLane,\n} from \"./app-browser-state.js\";\nimport {\n applyApprovedVisibleCommit,\n approveHmrVisibleCommit,\n approvePendingNavigationCommit,\n resolveAndClassifyNavigationCommit,\n type ApprovedVisibleCommit,\n} from \"./app-browser-visible-commit.js\";\nimport {\n shouldScheduleRefreshForDiscardedServerAction,\n type ServerActionRevalidationKind,\n} from \"./app-browser-action-result.js\";\nimport type { AppElements } from \"./app-elements.js\";\n\nexport type HistoryUpdateMode = \"push\" | \"replace\";\n\nexport type PendingBrowserRouterState = {\n promise: Promise<AppRouterState>;\n resolve: (state: AppRouterState) => void;\n settled: boolean;\n};\nexport type NavigationPayloadOutcome = \"committed\" | \"no-commit\" | \"hard-navigate\";\ntype HardNavigationMode = \"assign\" | \"replace\";\n\ntype BrowserNavigationCommitEffectFactory = (options: {\n href: string;\n historyUpdateMode: HistoryUpdateMode | undefined;\n navId: number;\n params: Record<string, string | string[]>;\n previousNextUrl: string | null;\n targetHistoryIndex?: number | null;\n}) => () => void;\n\ntype BrowserRouterStateRef = {\n current: AppRouterState;\n};\n\ntype SameUrlServerActionLifecycleOptions = {\n onDiscardedRevalidation?: () => void;\n revalidation?: ServerActionRevalidationKind;\n startedNavigationId?: number;\n targetHref?: string;\n};\n\ntype BrowserNavigationControllerDeps = {\n commitClientNavigationState?: typeof commitClientNavigationState;\n performHardNavigation?: (href: string, mode?: HardNavigationMode) => boolean;\n getRouteManifest?: () => RouteManifest | null;\n syncHistoryStatePreviousNextUrl?: (previousNextUrl: string | null) => void;\n};\n\ntype BrowserNavigationController = {\n beginNavigation(): number;\n getActiveNavigationId(): number;\n hasBrowserRouterState(): boolean;\n getBrowserRouterState(): AppRouterState;\n isCurrentNavigation(navId: number): boolean;\n performHardNavigation(href: string, mode?: HardNavigationMode): boolean;\n waitForBrowserRouterStateReady(): Promise<void>;\n attachBrowserRouterState(\n setter: Dispatch<AppRouterState | Promise<AppRouterState>>,\n stateRef: BrowserRouterStateRef,\n ): () => void;\n beginPendingBrowserRouterState(): PendingBrowserRouterState;\n finalizeNavigation(navId: number, pending: PendingBrowserRouterState | null | undefined): void;\n renderNavigationPayload(options: {\n actionType: \"navigate\" | \"replace\" | \"traverse\";\n createNavigationCommitEffect: BrowserNavigationCommitEffectFactory;\n historyUpdateMode: HistoryUpdateMode | undefined;\n navigationSnapshot: ClientNavigationRenderSnapshot;\n nextElements: Promise<AppElements>;\n operationLane: OperationLane;\n payloadOrigin: AppNavigationPayloadOrigin;\n params: Record<string, string | string[]>;\n pendingRouterState: PendingBrowserRouterState | null;\n previousNextUrl: string | null;\n targetHistoryIndex?: number | null;\n targetHref: string;\n navId: number;\n }): Promise<NavigationPayloadOutcome>;\n commitSameUrlNavigatePayload(\n nextElements: Promise<AppElements>,\n navigationSnapshot: ClientNavigationRenderSnapshot,\n returnValue?: { ok: boolean; data: unknown },\n actionInitiationState?: AppRouterState,\n lifecycleOptions?: SameUrlServerActionLifecycleOptions,\n ): Promise<unknown>;\n hmrReplaceTree(\n nextElements: Promise<AppElements>,\n navigationSnapshot: ClientNavigationRenderSnapshot,\n ): Promise<void>;\n /**\n * Force-drain the queued pre-paint effect for the given renderId without\n * waiting for NavigationCommitSignal to commit. Used by the dev recovery\n * boundary in app-browser-entry.ts: when a render error replaces\n * NavigationCommitSignal with the boundary's null fallback, its\n * useLayoutEffect never fires, so the URL update for the in-flight\n * navigation would otherwise be lost.\n */\n drainPrePaintEffects(renderId: number): void;\n NavigationCommitSignal(\n this: void,\n {\n renderId,\n children,\n }: {\n renderId: number;\n children?: ReactNode;\n },\n ): ReactNode;\n};\n\nconst HARD_NAVIGATION_LOOP_GUARD_KEY = \"__vinext_hard_navigation_target__\";\n\nfunction normalizeBrowserHref(href: string): string {\n try {\n return new URL(href, window.location.href).href;\n } catch {\n return href;\n }\n}\n\nfunction readHardNavigationLoopGuard(): string | null {\n try {\n return window.sessionStorage.getItem(HARD_NAVIGATION_LOOP_GUARD_KEY);\n } catch {\n return null;\n }\n}\n\nfunction writeHardNavigationLoopGuard(targetHref: string): boolean {\n try {\n window.sessionStorage.setItem(HARD_NAVIGATION_LOOP_GUARD_KEY, targetHref);\n return window.sessionStorage.getItem(HARD_NAVIGATION_LOOP_GUARD_KEY) === targetHref;\n } catch {\n return false;\n }\n}\n\nexport function clearHardNavigationLoopGuard(): void {\n try {\n window.sessionStorage.removeItem(HARD_NAVIGATION_LOOP_GUARD_KEY);\n } catch {}\n}\n\nfunction performHardNavigationWithLoopGuard(\n href: string,\n mode: HardNavigationMode = \"assign\",\n): boolean {\n const targetHref = normalizeBrowserHref(href);\n const currentHref = normalizeBrowserHref(window.location.href);\n\n if (readHardNavigationLoopGuard() === targetHref && currentHref === targetHref) {\n clearHardNavigationLoopGuard();\n console.error(\n `[vinext] Prevented repeated hard navigation to ${targetHref}; ` +\n \"leaving the current document in place to avoid a reload loop.\",\n );\n return false;\n }\n\n const guardPersisted = writeHardNavigationLoopGuard(targetHref);\n if (!guardPersisted && currentHref === targetHref) {\n console.error(\n `[vinext] Hard navigation to ${targetHref} requires a reload-loop guard, ` +\n \"but sessionStorage is unavailable; leaving the current document in place.\",\n );\n return false;\n }\n // If storage is unavailable but the target is a different URL, the browser\n // can still make forward progress. Only same-target reloads need a persisted\n // guard because they can re-enter this exact recovery path indefinitely.\n\n if (mode === \"replace\") {\n window.location.replace(href);\n } else {\n window.location.assign(href);\n }\n return true;\n}\n\nexport function createAppBrowserNavigationController(\n deps: BrowserNavigationControllerDeps = {},\n): BrowserNavigationController {\n const commitClientNavigationStateImpl =\n deps.commitClientNavigationState ?? commitClientNavigationState;\n const performHardNavigation = deps.performHardNavigation ?? performHardNavigationWithLoopGuard;\n const getRouteManifest = deps.getRouteManifest ?? (() => null);\n const syncHistoryStatePreviousNextUrl = deps.syncHistoryStatePreviousNextUrl ?? (() => {});\n\n // These are plain module-level variables (inside the controller closure),\n // unlike ClientNavigationState which uses Symbol.for to survive multiple\n // Vite module instances. The browser entry is loaded exactly once (via the\n // RSC plugin's generated bootstrap), so the controller running in a single\n // module instance is safe. If that assumption ever changes, these should be\n // migrated to a Symbol.for-backed global.\n //\n // The most severe consequence of multiple instances would be Map fragmentation:\n // pendingNavigationCommits and pendingNavigationPrePaintEffects would split\n // across instances, so drainPrePaintEffects in one instance could never drain\n // effects queued by the other, permanently leaking navigationSnapshotActiveCount\n // and causing hooks to prefer stale snapshot values indefinitely.\n let nextNavigationRenderId = 0;\n let activeNavigationId = 0;\n const pendingNavigationCommits = new Map<number, () => void>();\n const pendingNavigationPrePaintEffects = new Map<number, () => void>();\n\n let setBrowserRouterState: Dispatch<AppRouterState | Promise<AppRouterState>> | null = null;\n let browserRouterStateRef: BrowserRouterStateRef | null = null;\n let activePendingBrowserRouterState: PendingBrowserRouterState | null = null;\n let resolveBrowserRouterStateReady: (() => void) | null = null;\n let browserRouterStateReadyPromise: Promise<void> | null = null;\n let browserRouterStateHasCommitted = false;\n\n function getBrowserRouterStateSetter(): Dispatch<AppRouterState | Promise<AppRouterState>> {\n if (!setBrowserRouterState) {\n throw new Error(\"[vinext] Browser router state setter is not initialized\");\n }\n return setBrowserRouterState;\n }\n\n function getBrowserRouterState(): AppRouterState {\n if (!browserRouterStateRef) {\n throw new Error(\"[vinext] Browser router state is not initialized\");\n }\n return browserRouterStateRef.current;\n }\n\n function waitForBrowserRouterStateReady(): Promise<void> {\n if (browserRouterStateRef || browserRouterStateHasCommitted) {\n return Promise.resolve();\n }\n\n if (!browserRouterStateReadyPromise) {\n browserRouterStateReadyPromise = new Promise((resolve) => {\n resolveBrowserRouterStateReady = resolve;\n });\n }\n\n return browserRouterStateReadyPromise;\n }\n\n function markBrowserRouterStateReady(): void {\n browserRouterStateHasCommitted = true;\n const resolveReady = resolveBrowserRouterStateReady;\n resolveBrowserRouterStateReady = null;\n browserRouterStateReadyPromise = null;\n resolveReady?.();\n }\n\n function beginNavigation(): number {\n activeNavigationId += 1;\n return activeNavigationId;\n }\n\n function getActiveNavigationId(): number {\n return activeNavigationId;\n }\n\n function allocateRenderId(): number {\n nextNavigationRenderId += 1;\n return nextNavigationRenderId;\n }\n\n function hasBrowserRouterState(): boolean {\n return browserRouterStateRef !== null;\n }\n\n function isCurrentNavigation(navId: number): boolean {\n return navId === activeNavigationId;\n }\n\n function beginPendingBrowserRouterState(): PendingBrowserRouterState {\n const setter = getBrowserRouterStateSetter();\n\n if (activePendingBrowserRouterState && !activePendingBrowserRouterState.settled) {\n activePendingBrowserRouterState.settled = true;\n activePendingBrowserRouterState.resolve(getBrowserRouterState());\n }\n\n let resolvePending: ((state: AppRouterState) => void) | undefined;\n const promise = new Promise<AppRouterState>((resolve) => {\n resolvePending = resolve;\n });\n\n if (!resolvePending) {\n throw new Error(\"[vinext] Failed to initialize browser router promise\");\n }\n\n const pending: PendingBrowserRouterState = {\n promise,\n resolve: resolvePending,\n settled: false,\n };\n\n activePendingBrowserRouterState = pending;\n setter(promise);\n\n return pending;\n }\n\n function settlePendingBrowserRouterState(\n pending: PendingBrowserRouterState | null | undefined,\n ): void {\n if (!pending || pending.settled) return;\n\n pending.settled = true;\n pending.resolve(getBrowserRouterState());\n\n if (activePendingBrowserRouterState === pending) {\n activePendingBrowserRouterState = null;\n }\n }\n\n function finalizeNavigation(\n navId: number,\n pending: PendingBrowserRouterState | null | undefined,\n ): void {\n settlePendingBrowserRouterState(pending);\n\n if (isCurrentNavigation(navId)) {\n clearPendingPathname(navId);\n }\n }\n\n function resolvePendingBrowserRouterState(\n pending: PendingBrowserRouterState | null | undefined,\n commit: ApprovedVisibleCommit,\n ): void {\n if (!pending || pending.settled) return;\n\n pending.settled = true;\n pending.resolve(applyApprovedVisibleCommit(getBrowserRouterState(), commit));\n\n if (activePendingBrowserRouterState === pending) {\n activePendingBrowserRouterState = null;\n }\n }\n\n function queuePrePaintNavigationEffect(renderId: number, effect: (() => void) | null): void {\n if (!effect) {\n return;\n }\n pendingNavigationPrePaintEffects.set(renderId, effect);\n }\n\n /**\n * Run all queued pre-paint effects for renderIds up to and including the\n * given renderId. When React supersedes a startTransition update (rapid\n * clicks on same-route links), the superseded NavigationCommitSignal never\n * mounts, so its pre-paint effect never fires. By draining all effects\n * <= the committed renderId here, the winning transition cleans up after\n * any superseded ones, keeping the counter balanced.\n *\n * Invariant: each superseded navigation gets a commitClientNavigationState()\n * to balance the activateNavigationSnapshot() from its renderNavigationPayload call.\n */\n function drainPrePaintEffects(upToRenderId: number): void {\n for (const [id, effect] of pendingNavigationPrePaintEffects) {\n if (id > upToRenderId) {\n continue;\n }\n\n pendingNavigationPrePaintEffects.delete(id);\n if (id === upToRenderId) {\n effect();\n } else {\n // Superseded navigations still need to balance the snapshot counter.\n commitClientNavigationStateImpl(undefined, { releaseSnapshot: true });\n }\n }\n }\n\n /**\n * Resolve all pending navigation commits with renderId <= the committed renderId.\n * Note: Map iteration handles concurrent deletion safely — entries are visited in\n * insertion order and deletion doesn't affect the iterator's view of remaining entries.\n * This pattern is also used in drainPrePaintEffects with the same semantics.\n */\n function resolveCommittedNavigations(renderId: number): void {\n for (const [pendingId, resolve] of pendingNavigationCommits) {\n if (pendingId > renderId) {\n continue;\n }\n\n pendingNavigationCommits.delete(pendingId);\n resolve();\n }\n }\n\n async function hmrReplaceTree(\n nextElements: Promise<AppElements>,\n navigationSnapshot: ClientNavigationRenderSnapshot,\n ): Promise<void> {\n if (!hasBrowserRouterState()) return;\n\n const currentState = getBrowserRouterState();\n const renderId = allocateRenderId();\n const pending = await createPendingNavigationCommit({\n currentState,\n nextElements,\n navigationSnapshot,\n operationLane: \"hmr\",\n payloadOrigin: FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN,\n renderId,\n type: \"replace\",\n });\n\n // createPendingNavigationCommit awaits the new RSC payload. While\n // suspended, the prior broken render can unmount BrowserRoot. Re-check\n // before dispatching so a racing unmount doesn't surface as an\n // initialized-setter error.\n if (!hasBrowserRouterState()) return;\n\n dispatchSynchronousVisibleCommit(approveHmrVisibleCommit(pending));\n }\n\n function NavigationCommitSignal(\n this: void,\n {\n renderId,\n children,\n }: {\n renderId: number;\n children?: ReactNode;\n },\n ): ReactNode {\n useLayoutEffect(() => {\n drainPrePaintEffects(renderId);\n\n const frame = requestAnimationFrame(() => {\n resolveCommittedNavigations(renderId);\n });\n\n return () => {\n cancelAnimationFrame(frame);\n // Resolve pending commits to prevent callers from hanging if React\n // unmounts this component without committing (e.g., error boundary).\n resolveCommittedNavigations(renderId);\n };\n }, [renderId]);\n\n return children;\n }\n\n function dispatchApprovedVisibleCommit(\n commit: ApprovedVisibleCommit,\n pendingRouterState: PendingBrowserRouterState | null,\n ): void {\n const setter = getBrowserRouterStateSetter();\n\n if (pendingRouterState) {\n // The programmatic navigation is already running inside React.startTransition\n // (from router.push/replace/refresh/Link), so resolving the deferred promise\n // is sufficient.\n resolvePendingBrowserRouterState(pendingRouterState, commit);\n return;\n }\n\n startTransition(() => {\n setter(applyApprovedVisibleCommit(getBrowserRouterState(), commit));\n });\n }\n\n function dispatchSynchronousVisibleCommit(commit: ApprovedVisibleCommit): void {\n const setter = getBrowserRouterStateSetter();\n setter(applyApprovedVisibleCommit(getBrowserRouterState(), commit));\n }\n\n function notifyDiscardedServerActionRevalidation(\n lifecycleOptions: SameUrlServerActionLifecycleOptions | undefined,\n ): void {\n const revalidation = lifecycleOptions?.revalidation ?? \"none\";\n if (!shouldScheduleRefreshForDiscardedServerAction(revalidation)) return;\n\n lifecycleOptions?.onDiscardedRevalidation?.();\n }\n\n async function renderNavigationPayload(options: {\n actionType: \"navigate\" | \"replace\" | \"traverse\";\n createNavigationCommitEffect: BrowserNavigationCommitEffectFactory;\n historyUpdateMode: HistoryUpdateMode | undefined;\n navigationSnapshot: ClientNavigationRenderSnapshot;\n nextElements: Promise<AppElements>;\n operationLane: OperationLane;\n payloadOrigin: AppNavigationPayloadOrigin;\n params: Record<string, string | string[]>;\n pendingRouterState: PendingBrowserRouterState | null;\n previousNextUrl: string | null;\n targetHistoryIndex?: number | null;\n targetHref: string;\n navId: number;\n }): Promise<NavigationPayloadOutcome> {\n const renderId = allocateRenderId();\n let resolveCommitted: (() => void) | undefined;\n const committed = new Promise<void>((resolve) => {\n resolveCommitted = resolve;\n pendingNavigationCommits.set(renderId, resolve);\n });\n\n let snapshotActivated = false;\n try {\n const startedState = getBrowserRouterState();\n const pending = await createPendingNavigationCommit({\n currentState: startedState,\n nextElements: options.nextElements,\n navigationSnapshot: options.navigationSnapshot,\n operationLane: options.operationLane,\n payloadOrigin: options.payloadOrigin,\n previousNextUrl: options.previousNextUrl,\n renderId,\n type: options.actionType,\n });\n\n const approval = approvePendingNavigationCommit({\n activeNavigationId,\n currentState: getBrowserRouterState(),\n pending,\n routeManifest: getRouteManifest(),\n startedNavigationId: options.navId,\n targetHref: options.targetHref,\n });\n\n if (approval.decision.disposition === \"no-commit\") {\n settlePendingBrowserRouterState(options.pendingRouterState);\n pendingNavigationCommits.delete(renderId);\n resolveCommitted?.();\n return \"no-commit\";\n }\n\n if (approval.decision.disposition === \"hard-navigate\") {\n settlePendingBrowserRouterState(options.pendingRouterState);\n pendingNavigationCommits.delete(renderId);\n return performHardNavigation(options.targetHref) ? \"hard-navigate\" : \"no-commit\";\n }\n\n const approvedCommit = approval.approvedCommit;\n if (approvedCommit === null) {\n throw new Error(\"[vinext] Commit decision did not approve a visible commit\");\n }\n\n queuePrePaintNavigationEffect(\n renderId,\n options.createNavigationCommitEffect({\n href: options.targetHref,\n historyUpdateMode: options.historyUpdateMode,\n navId: options.navId,\n params: options.params,\n previousNextUrl: approvedCommit.previousNextUrl,\n targetHistoryIndex: options.targetHistoryIndex,\n }),\n );\n activateNavigationSnapshot();\n snapshotActivated = true;\n dispatchApprovedVisibleCommit(approvedCommit, options.pendingRouterState);\n } catch (error) {\n pendingNavigationPrePaintEffects.delete(renderId);\n pendingNavigationCommits.delete(renderId);\n if (snapshotActivated) {\n commitClientNavigationStateImpl(options.navId);\n }\n settlePendingBrowserRouterState(options.pendingRouterState);\n resolveCommitted?.();\n throw error;\n }\n\n return committed.then(() => \"committed\");\n }\n\n async function commitSameUrlNavigatePayload(\n nextElements: Promise<AppElements>,\n navigationSnapshot: ClientNavigationRenderSnapshot,\n returnValue?: { ok: boolean; data: unknown },\n actionInitiationState?: AppRouterState,\n lifecycleOptions?: SameUrlServerActionLifecycleOptions,\n ): Promise<unknown> {\n const currentState = actionInitiationState ?? getBrowserRouterState();\n const startedNavigationId = lifecycleOptions?.startedNavigationId ?? activeNavigationId;\n const targetHref = lifecycleOptions?.targetHref ?? window.location.href;\n const {\n approvedCommit,\n decision,\n pending,\n // Intentionally retained as #726-OPS-01 trace-shell scaffolding. The\n // same-URL action path can consume this trace once later lifecycle gates\n // need an observable commit explanation.\n trace: _navigationTrace,\n } = await resolveAndClassifyNavigationCommit({\n activeNavigationId,\n currentState,\n getActiveNavigationId: () => activeNavigationId,\n getCurrentStateForApproval: getBrowserRouterState,\n navigationSnapshot,\n nextElements,\n renderId: allocateRenderId(),\n operationLane: \"server-action\",\n payloadOrigin: FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN,\n startedNavigationId,\n routeManifest: getRouteManifest(),\n targetHref,\n type: \"navigate\",\n });\n\n if (decision.disposition === \"hard-navigate\") {\n // Same-URL action hard navigations do not expose a navigation outcome to\n // callers. If the loop guard blocks, the degraded state is still the\n // existing return contract: no visible commit and no action value.\n performHardNavigation(targetHref);\n return undefined;\n }\n\n if (approvedCommit) {\n // The helper approval and this continuation are separated by a microtask\n // boundary, so re-check lifecycle authority before mutating visible UI.\n const latestApproval = approvePendingNavigationCommit({\n activeNavigationId,\n currentState: getBrowserRouterState(),\n pending,\n routeManifest: getRouteManifest(),\n startedNavigationId,\n targetHref,\n });\n\n if (latestApproval.decision.disposition === \"hard-navigate\") {\n // See the same-URL hard-navigation note above. The guard result is\n // deliberately not surfaced through the server-action return channel.\n performHardNavigation(targetHref);\n return undefined;\n }\n\n if (latestApproval.approvedCommit) {\n dispatchSynchronousVisibleCommit(latestApproval.approvedCommit);\n syncHistoryStatePreviousNextUrl(latestApproval.approvedCommit.previousNextUrl);\n } else {\n notifyDiscardedServerActionRevalidation(lifecycleOptions);\n }\n } else if (decision.disposition === \"no-commit\") {\n notifyDiscardedServerActionRevalidation(lifecycleOptions);\n }\n\n // Same-URL server actions still return their action value even if the UI\n // update was skipped due to a superseding navigation. That preserves the\n // existing caller contract; a future Phase 2 router state model could make\n // skipped UI updates observable to the caller without conflating them here.\n if (returnValue) {\n if (!returnValue.ok) {\n throw returnValue.data;\n }\n return returnValue.data;\n }\n\n return undefined;\n }\n\n function attachBrowserRouterState(\n setter: Dispatch<AppRouterState | Promise<AppRouterState>>,\n stateRef: BrowserRouterStateRef,\n ): () => void {\n setBrowserRouterState = setter;\n browserRouterStateRef = stateRef;\n markBrowserRouterStateReady();\n\n return () => {\n if (setBrowserRouterState === setter) {\n setBrowserRouterState = null;\n }\n if (browserRouterStateRef === stateRef) {\n browserRouterStateRef = null;\n browserRouterStateHasCommitted = false;\n }\n };\n }\n\n return {\n beginNavigation,\n getActiveNavigationId,\n hasBrowserRouterState,\n getBrowserRouterState,\n isCurrentNavigation,\n performHardNavigation,\n waitForBrowserRouterStateReady,\n attachBrowserRouterState,\n beginPendingBrowserRouterState,\n finalizeNavigation,\n renderNavigationPayload,\n commitSameUrlNavigatePayload,\n hmrReplaceTree,\n drainPrePaintEffects,\n NavigationCommitSignal,\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ //#region src/server/app-browser-popstate.d.ts
2
+ type RestoreScrollPosition = (state: unknown) => void;
3
+ type NavigateRsc = (href: string, redirectDepth?: number, navigationKind?: "navigate" | "traverse" | "refresh") => Promise<void>;
4
+ type BrowserPopstateRestoreDeps = {
5
+ getActiveNavigationId: () => number;
6
+ getPendingNavigation: () => Promise<void> | null | undefined;
7
+ getNavigate: () => NavigateRsc | undefined;
8
+ isCurrentNavigation: (navId: number) => boolean;
9
+ notifyAppRouterTransitionStart: (href: string) => void;
10
+ restorePopstateScrollPosition: RestoreScrollPosition;
11
+ setPendingNavigation: (pendingNavigation: Promise<void> | null) => void;
12
+ };
13
+ declare function createPopstateRestoreHandler(deps: BrowserPopstateRestoreDeps): (event: PopStateEvent) => void;
14
+ //#endregion
15
+ export { createPopstateRestoreHandler };
16
+ //# sourceMappingURL=app-browser-popstate.d.ts.map
@@ -0,0 +1,17 @@
1
+ //#region src/server/app-browser-popstate.ts
2
+ function createPopstateRestoreHandler(deps) {
3
+ return (event) => {
4
+ deps.notifyAppRouterTransitionStart(window.location.href);
5
+ const pendingNavigation = deps.getNavigate()?.(window.location.href, 0, "traverse") ?? Promise.resolve();
6
+ const popstateNavId = deps.getActiveNavigationId();
7
+ deps.setPendingNavigation(pendingNavigation);
8
+ pendingNavigation.finally(() => {
9
+ if (deps.isCurrentNavigation(popstateNavId)) deps.restorePopstateScrollPosition(event.state);
10
+ if (deps.getPendingNavigation() === pendingNavigation) deps.setPendingNavigation(null);
11
+ });
12
+ };
13
+ }
14
+ //#endregion
15
+ export { createPopstateRestoreHandler };
16
+
17
+ //# sourceMappingURL=app-browser-popstate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-browser-popstate.js","names":[],"sources":["../../src/server/app-browser-popstate.ts"],"sourcesContent":["type RestoreScrollPosition = (state: unknown) => void;\ntype NavigateRsc = (\n href: string,\n redirectDepth?: number,\n navigationKind?: \"navigate\" | \"traverse\" | \"refresh\",\n) => Promise<void>;\n\ntype BrowserPopstateRestoreDeps = {\n getActiveNavigationId: () => number;\n getPendingNavigation: () => Promise<void> | null | undefined;\n getNavigate: () => NavigateRsc | undefined;\n isCurrentNavigation: (navId: number) => boolean;\n notifyAppRouterTransitionStart: (href: string) => void;\n restorePopstateScrollPosition: RestoreScrollPosition;\n setPendingNavigation: (pendingNavigation: Promise<void> | null) => void;\n};\n\nexport function createPopstateRestoreHandler(\n deps: BrowserPopstateRestoreDeps,\n): (event: PopStateEvent) => void {\n return (event) => {\n deps.notifyAppRouterTransitionStart(window.location.href);\n const navigate = deps.getNavigate();\n const pendingNavigation = navigate?.(window.location.href, 0, \"traverse\") ?? Promise.resolve();\n const popstateNavId = deps.getActiveNavigationId();\n\n deps.setPendingNavigation(pendingNavigation);\n\n void pendingNavigation.finally(() => {\n if (deps.isCurrentNavigation(popstateNavId)) {\n deps.restorePopstateScrollPosition(event.state);\n }\n\n if (deps.getPendingNavigation() === pendingNavigation) {\n deps.setPendingNavigation(null);\n }\n });\n };\n}\n"],"mappings":";AAiBA,SAAgB,6BACd,MACgC;CAChC,QAAQ,UAAU;EAChB,KAAK,+BAA+B,OAAO,SAAS,KAAK;EAEzD,MAAM,oBADW,KAAK,aACY,GAAG,OAAO,SAAS,MAAM,GAAG,WAAW,IAAI,QAAQ,SAAS;EAC9F,MAAM,gBAAgB,KAAK,uBAAuB;EAElD,KAAK,qBAAqB,kBAAkB;EAE5C,kBAAuB,cAAc;GACnC,IAAI,KAAK,oBAAoB,cAAc,EACzC,KAAK,8BAA8B,MAAM,MAAM;GAGjD,IAAI,KAAK,sBAAsB,KAAK,mBAClC,KAAK,qBAAqB,KAAK;IAEjC"}
@@ -0,0 +1,29 @@
1
+ //#region src/server/app-browser-rsc-redirect.d.ts
2
+ declare const MAX_RSC_REDIRECT_DEPTH = 10;
3
+ type RscRedirectHistoryUpdateMode = "push" | "replace" | undefined;
4
+ type RscRedirectLifecycleDecision = {
5
+ kind: "no-redirect";
6
+ } | {
7
+ href: string;
8
+ historyUpdateMode: RscRedirectHistoryUpdateMode;
9
+ kind: "follow";
10
+ previousNextUrl: string | null;
11
+ redirectDepth: number;
12
+ } | {
13
+ href: string;
14
+ kind: "terminal-hard-navigation";
15
+ reason: "externalRedirect" | "maxRedirectsExceeded";
16
+ redirectDepth: number;
17
+ };
18
+ declare function resolveRscRedirectLifecycleHop(options: {
19
+ currentHref: string;
20
+ historyUpdateMode: RscRedirectHistoryUpdateMode;
21
+ maxRedirectDepth?: number;
22
+ origin: string;
23
+ redirectDepth: number;
24
+ requestPreviousNextUrl: string | null;
25
+ responseUrl: string;
26
+ }): RscRedirectLifecycleDecision;
27
+ //#endregion
28
+ export { MAX_RSC_REDIRECT_DEPTH, resolveRscRedirectLifecycleHop };
29
+ //# sourceMappingURL=app-browser-rsc-redirect.d.ts.map
@@ -0,0 +1,37 @@
1
+ import { resolveHardNavigationTargetFromRscResponse, stripRscCacheBustingSearchParam, stripRscSuffix } from "./app-rsc-cache-busting.js";
2
+ //#region src/server/app-browser-rsc-redirect.ts
3
+ const MAX_RSC_REDIRECT_DEPTH = 10;
4
+ function toVisibleAppHref(href, origin) {
5
+ const url = new URL(href, origin);
6
+ stripRscCacheBustingSearchParam(url);
7
+ return `${stripRscSuffix(url.pathname)}${url.search}${url.hash}`;
8
+ }
9
+ function resolveRscRedirectLifecycleHop(options) {
10
+ const responseUrl = new URL(options.responseUrl, options.origin);
11
+ if (responseUrl.origin !== options.origin) return {
12
+ href: responseUrl.href,
13
+ kind: "terminal-hard-navigation",
14
+ reason: "externalRedirect",
15
+ redirectDepth: options.redirectDepth
16
+ };
17
+ const redirectedHref = resolveHardNavigationTargetFromRscResponse(responseUrl.href, options.currentHref, options.origin);
18
+ if (redirectedHref === toVisibleAppHref(options.currentHref, options.origin)) return { kind: "no-redirect" };
19
+ const maxRedirectDepth = options.maxRedirectDepth ?? 10;
20
+ if (options.redirectDepth >= maxRedirectDepth) return {
21
+ href: redirectedHref,
22
+ kind: "terminal-hard-navigation",
23
+ reason: "maxRedirectsExceeded",
24
+ redirectDepth: options.redirectDepth
25
+ };
26
+ return {
27
+ href: redirectedHref,
28
+ historyUpdateMode: options.historyUpdateMode,
29
+ kind: "follow",
30
+ previousNextUrl: options.requestPreviousNextUrl,
31
+ redirectDepth: options.redirectDepth + 1
32
+ };
33
+ }
34
+ //#endregion
35
+ export { MAX_RSC_REDIRECT_DEPTH, resolveRscRedirectLifecycleHop };
36
+
37
+ //# sourceMappingURL=app-browser-rsc-redirect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-browser-rsc-redirect.js","names":[],"sources":["../../src/server/app-browser-rsc-redirect.ts"],"sourcesContent":["import {\n resolveHardNavigationTargetFromRscResponse,\n stripRscCacheBustingSearchParam,\n stripRscSuffix,\n} from \"./app-rsc-cache-busting.js\";\n\nexport const MAX_RSC_REDIRECT_DEPTH = 10;\n\ntype RscRedirectHistoryUpdateMode = \"push\" | \"replace\" | undefined;\n\ntype RscRedirectLifecycleDecision =\n | { kind: \"no-redirect\" }\n | {\n href: string;\n historyUpdateMode: RscRedirectHistoryUpdateMode;\n kind: \"follow\";\n previousNextUrl: string | null;\n redirectDepth: number;\n }\n | {\n href: string;\n kind: \"terminal-hard-navigation\";\n reason: \"externalRedirect\" | \"maxRedirectsExceeded\";\n redirectDepth: number;\n };\n\nfunction toVisibleAppHref(href: string, origin: string): string {\n const url = new URL(href, origin);\n stripRscCacheBustingSearchParam(url);\n return `${stripRscSuffix(url.pathname)}${url.search}${url.hash}`;\n}\n\nexport function resolveRscRedirectLifecycleHop(options: {\n currentHref: string;\n historyUpdateMode: RscRedirectHistoryUpdateMode;\n maxRedirectDepth?: number;\n origin: string;\n redirectDepth: number;\n requestPreviousNextUrl: string | null;\n responseUrl: string;\n}): RscRedirectLifecycleDecision {\n const responseUrl = new URL(options.responseUrl, options.origin);\n\n if (responseUrl.origin !== options.origin) {\n return {\n href: responseUrl.href,\n kind: \"terminal-hard-navigation\",\n reason: \"externalRedirect\",\n redirectDepth: options.redirectDepth,\n };\n }\n\n const redirectedHref = resolveHardNavigationTargetFromRscResponse(\n responseUrl.href,\n options.currentHref,\n options.origin,\n );\n if (redirectedHref === toVisibleAppHref(options.currentHref, options.origin)) {\n return { kind: \"no-redirect\" };\n }\n\n const maxRedirectDepth = options.maxRedirectDepth ?? MAX_RSC_REDIRECT_DEPTH;\n if (options.redirectDepth >= maxRedirectDepth) {\n return {\n href: redirectedHref,\n kind: \"terminal-hard-navigation\",\n reason: \"maxRedirectsExceeded\",\n redirectDepth: options.redirectDepth,\n };\n }\n\n return {\n href: redirectedHref,\n historyUpdateMode: options.historyUpdateMode,\n kind: \"follow\",\n previousNextUrl: options.requestPreviousNextUrl,\n redirectDepth: options.redirectDepth + 1,\n };\n}\n"],"mappings":";;AAMA,MAAa,yBAAyB;AAoBtC,SAAS,iBAAiB,MAAc,QAAwB;CAC9D,MAAM,MAAM,IAAI,IAAI,MAAM,OAAO;CACjC,gCAAgC,IAAI;CACpC,OAAO,GAAG,eAAe,IAAI,SAAS,GAAG,IAAI,SAAS,IAAI;;AAG5D,SAAgB,+BAA+B,SAQd;CAC/B,MAAM,cAAc,IAAI,IAAI,QAAQ,aAAa,QAAQ,OAAO;CAEhE,IAAI,YAAY,WAAW,QAAQ,QACjC,OAAO;EACL,MAAM,YAAY;EAClB,MAAM;EACN,QAAQ;EACR,eAAe,QAAQ;EACxB;CAGH,MAAM,iBAAiB,2CACrB,YAAY,MACZ,QAAQ,aACR,QAAQ,OACT;CACD,IAAI,mBAAmB,iBAAiB,QAAQ,aAAa,QAAQ,OAAO,EAC1E,OAAO,EAAE,MAAM,eAAe;CAGhC,MAAM,mBAAmB,QAAQ,oBAAA;CACjC,IAAI,QAAQ,iBAAiB,kBAC3B,OAAO;EACL,MAAM;EACN,MAAM;EACN,QAAQ;EACR,eAAe,QAAQ;EACxB;CAGH,OAAO;EACL,MAAM;EACN,mBAAmB,QAAQ;EAC3B,MAAM;EACN,iBAAiB,QAAQ;EACzB,eAAe,QAAQ,gBAAgB;EACxC"}
@@ -1,12 +1,12 @@
1
+ import { RouteManifest } from "../routing/app-route-graph.js";
2
+ import { CacheEntryReuseProof } from "./cache-proof.js";
1
3
  import { ClientNavigationRenderSnapshot } from "../shims/navigation.js";
2
- import { AppElements, LayoutFlags } from "./app-elements-wire.js";
4
+ import { AppElements, AppElementsInterception, AppElementsSlotBinding, LayoutFlags } from "./app-elements-wire.js";
3
5
  import { NavigationTrace } from "./navigation-trace.js";
4
6
  import { OperationLane } from "./navigation-planner.js";
7
+ import { HistoryTraversalIntent, createHistoryStateWithNavigationMetadata, createHistoryStateWithPreviousNextUrl, readHistoryStatePreviousNextUrl, readHistoryStateTraversalIndex, resolveHistoryTraversalIntent } from "./app-history-state.js";
5
8
 
6
9
  //#region src/server/app-browser-state.d.ts
7
- type HistoryStateRecord = {
8
- [key: string]: unknown;
9
- };
10
10
  type OperationRecordBase = {
11
11
  id: number;
12
12
  lane: OperationLane;
@@ -23,6 +23,7 @@ type OperationRecord = PendingOperationRecord | CommittedOperationRecord;
23
23
  type AppRouterState = {
24
24
  activeOperation: OperationRecord | null;
25
25
  elements: AppElements;
26
+ interception: AppElementsInterception | null;
26
27
  interceptionContext: string | null;
27
28
  layoutFlags: LayoutFlags;
28
29
  layoutIds: readonly string[];
@@ -31,10 +32,13 @@ type AppRouterState = {
31
32
  navigationSnapshot: ClientNavigationRenderSnapshot;
32
33
  rootLayoutTreePath: string | null;
33
34
  routeId: string;
35
+ slotBindings: readonly AppElementsSlotBinding[];
34
36
  visibleCommitVersion: number;
35
37
  };
36
38
  type AppRouterAction = {
39
+ cacheEntryReuseProof?: CacheEntryReuseProof;
37
40
  elements: AppElements;
41
+ interception: AppElementsInterception | null;
38
42
  interceptionContext: string | null;
39
43
  layoutFlags: LayoutFlags;
40
44
  layoutIds: readonly string[];
@@ -44,20 +48,34 @@ type AppRouterAction = {
44
48
  renderId: number;
45
49
  rootLayoutTreePath: string | null;
46
50
  routeId: string;
51
+ slotBindings: readonly AppElementsSlotBinding[];
47
52
  type: "navigate" | "replace" | "traverse";
48
53
  };
49
54
  type PendingNavigationCommit = {
50
55
  action: AppRouterAction;
56
+ cacheEntryReuseProof?: CacheEntryReuseProof;
57
+ interception: AppElementsInterception | null;
51
58
  interceptionContext: string | null;
52
59
  previousNextUrl: string | null;
53
60
  rootLayoutTreePath: string | null;
54
61
  routeId: string;
55
62
  };
63
+ type AppNavigationPayloadOrigin = Readonly<{
64
+ origin: "fresh";
65
+ } | {
66
+ origin: "visited-cache";
67
+ }>;
68
+ declare const FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN: AppNavigationPayloadOrigin;
69
+ declare const VISITED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN: AppNavigationPayloadOrigin;
56
70
  type PendingNavigationCommitDisposition = "dispatch" | "hard-navigate" | "skip";
71
+ type CacheRestorableAppPayloadMetadata = Readonly<{
72
+ cacheEntryReuseProof?: CacheEntryReuseProof;
73
+ }>;
57
74
  type DispatchPendingNavigationCommitDispositionDecision = {
58
75
  disposition: "dispatch";
59
76
  preserveAbsentSlots: boolean;
60
77
  preserveElementIds: readonly string[];
78
+ preservePreviousSlotIds: readonly string[];
61
79
  trace: NavigationTrace;
62
80
  };
63
81
  type NonDispatchPendingNavigationCommitDispositionDecision = {
@@ -66,8 +84,9 @@ type NonDispatchPendingNavigationCommitDispositionDecision = {
66
84
  trace: NavigationTrace;
67
85
  };
68
86
  type PendingNavigationCommitDispositionDecision = DispatchPendingNavigationCommitDispositionDecision | NonDispatchPendingNavigationCommitDispositionDecision;
69
- declare function createHistoryStateWithPreviousNextUrl(state: unknown, previousNextUrl: string | null): HistoryStateRecord | null;
70
- declare function readHistoryStatePreviousNextUrl(state: unknown): string | null;
87
+ declare function isCacheRestorableAppPayloadMetadata(metadata: CacheRestorableAppPayloadMetadata): metadata is CacheRestorableAppPayloadMetadata & {
88
+ cacheEntryReuseProof: CacheEntryReuseProof;
89
+ };
71
90
  declare function resolveInterceptionContextFromPreviousNextUrl(previousNextUrl: string | null, basePath?: string): string | null;
72
91
  type ResolveServerActionRequestStateOptions = {
73
92
  actionId: string;
@@ -94,6 +113,7 @@ declare function resolvePendingNavigationCommitDispositionDecision(options: {
94
113
  activeNavigationId: number;
95
114
  currentState: AppRouterState;
96
115
  pending: PendingNavigationCommit;
116
+ routeManifest?: RouteManifest | null;
97
117
  startedNavigationId: number;
98
118
  targetHref?: string;
99
119
  }): PendingNavigationCommitDispositionDecision;
@@ -102,10 +122,11 @@ declare function createPendingNavigationCommit(options: {
102
122
  nextElements: Promise<AppElements>;
103
123
  navigationSnapshot: ClientNavigationRenderSnapshot;
104
124
  operationLane: OperationLane;
125
+ payloadOrigin: AppNavigationPayloadOrigin;
105
126
  previousNextUrl?: string | null;
106
127
  renderId: number;
107
128
  type: "navigate" | "replace" | "traverse";
108
129
  }): Promise<PendingNavigationCommit>;
109
130
  //#endregion
110
- export { AppRouterAction, AppRouterState, CommittedOperationRecord, type OperationLane, OperationRecord, PendingNavigationCommit, PendingOperationRecord, createHistoryStateWithPreviousNextUrl, createPendingNavigationCommit, readHistoryStatePreviousNextUrl, resolveInterceptionContextFromPreviousNextUrl, resolvePendingNavigationCommitDispositionDecision, resolveServerActionRequestState };
131
+ export { AppNavigationPayloadOrigin, AppRouterAction, AppRouterState, CommittedOperationRecord, FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, type HistoryTraversalIntent, type OperationLane, OperationRecord, PendingNavigationCommit, PendingOperationRecord, VISITED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN, createHistoryStateWithNavigationMetadata, createHistoryStateWithPreviousNextUrl, createPendingNavigationCommit, isCacheRestorableAppPayloadMetadata, readHistoryStatePreviousNextUrl, readHistoryStateTraversalIndex, resolveHistoryTraversalIntent, resolveInterceptionContextFromPreviousNextUrl, resolvePendingNavigationCommitDispositionDecision, resolveServerActionRequestState };
111
132
  //# sourceMappingURL=app-browser-state.d.ts.map