vinext 0.0.45 → 0.0.47

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 (311) hide show
  1. package/README.md +7 -5
  2. package/dist/build/prerender.d.ts +2 -1
  3. package/dist/build/prerender.js +80 -17
  4. package/dist/build/prerender.js.map +1 -1
  5. package/dist/build/report.d.ts +1 -1
  6. package/dist/build/route-classification-injector.d.ts +35 -0
  7. package/dist/build/route-classification-injector.js +61 -0
  8. package/dist/build/route-classification-injector.js.map +1 -0
  9. package/dist/build/route-classification-manifest.d.ts +1 -1
  10. package/dist/build/standalone.js +4 -3
  11. package/dist/build/standalone.js.map +1 -1
  12. package/dist/build/static-export.d.ts +1 -1
  13. package/dist/check.js +30 -18
  14. package/dist/check.js.map +1 -1
  15. package/dist/cli-args.d.ts +31 -0
  16. package/dist/cli-args.js +104 -0
  17. package/dist/cli-args.js.map +1 -0
  18. package/dist/cli.js +6 -19
  19. package/dist/cli.js.map +1 -1
  20. package/dist/cloudflare/kv-cache-handler.js +29 -9
  21. package/dist/cloudflare/kv-cache-handler.js.map +1 -1
  22. package/dist/config/config-matchers.js +1 -0
  23. package/dist/config/config-matchers.js.map +1 -1
  24. package/dist/config/next-config.d.ts +42 -4
  25. package/dist/config/next-config.js +27 -0
  26. package/dist/config/next-config.js.map +1 -1
  27. package/dist/deploy.js +18 -23
  28. package/dist/deploy.js.map +1 -1
  29. package/dist/entries/app-rsc-entry.d.ts +4 -3
  30. package/dist/entries/app-rsc-entry.js +435 -2317
  31. package/dist/entries/app-rsc-entry.js.map +1 -1
  32. package/dist/entries/app-rsc-manifest.d.ts +24 -0
  33. package/dist/entries/app-rsc-manifest.js +155 -0
  34. package/dist/entries/app-rsc-manifest.js.map +1 -0
  35. package/dist/entries/pages-server-entry.js +18 -105
  36. package/dist/entries/pages-server-entry.js.map +1 -1
  37. package/dist/index.js +82 -85
  38. package/dist/index.js.map +1 -1
  39. package/dist/plugins/fonts.js +54 -32
  40. package/dist/plugins/fonts.js.map +1 -1
  41. package/dist/plugins/rsc-client-shim-excludes.d.ts +6 -0
  42. package/dist/plugins/rsc-client-shim-excludes.js +28 -0
  43. package/dist/plugins/rsc-client-shim-excludes.js.map +1 -0
  44. package/dist/routing/app-route-graph.d.ts +109 -0
  45. package/dist/routing/app-route-graph.js +819 -0
  46. package/dist/routing/app-route-graph.js.map +1 -0
  47. package/dist/routing/app-router.d.ts +2 -79
  48. package/dist/routing/app-router.js +7 -621
  49. package/dist/routing/app-router.js.map +1 -1
  50. package/dist/routing/route-pattern.d.ts +9 -0
  51. package/dist/routing/route-pattern.js +90 -0
  52. package/dist/routing/route-pattern.js.map +1 -0
  53. package/dist/routing/route-trie.js +10 -11
  54. package/dist/routing/route-trie.js.map +1 -1
  55. package/dist/server/app-browser-entry.js +94 -232
  56. package/dist/server/app-browser-entry.js.map +1 -1
  57. package/dist/server/app-browser-error.d.ts +3 -4
  58. package/dist/server/app-browser-error.js +8 -4
  59. package/dist/server/app-browser-error.js.map +1 -1
  60. package/dist/server/app-browser-navigation-controller.d.ts +73 -0
  61. package/dist/server/app-browser-navigation-controller.js +282 -0
  62. package/dist/server/app-browser-navigation-controller.js.map +1 -0
  63. package/dist/server/app-browser-state.d.ts +1 -1
  64. package/dist/server/app-browser-state.js.map +1 -1
  65. package/dist/server/app-elements.js +1 -5
  66. package/dist/server/app-elements.js.map +1 -1
  67. package/dist/server/app-fallback-renderer.d.ts +57 -0
  68. package/dist/server/app-fallback-renderer.js +79 -0
  69. package/dist/server/app-fallback-renderer.js.map +1 -0
  70. package/dist/server/app-hook-warning-suppression.d.ts +7 -0
  71. package/dist/server/app-hook-warning-suppression.js +12 -0
  72. package/dist/server/app-hook-warning-suppression.js.map +1 -0
  73. package/dist/server/app-middleware.d.ts +32 -0
  74. package/dist/server/app-middleware.js +147 -0
  75. package/dist/server/app-middleware.js.map +1 -0
  76. package/dist/server/app-mounted-slots-header.d.ts +17 -0
  77. package/dist/server/app-mounted-slots-header.js +21 -0
  78. package/dist/server/app-mounted-slots-header.js.map +1 -0
  79. package/dist/server/app-page-boundary-render.d.ts +4 -2
  80. package/dist/server/app-page-boundary-render.js +50 -30
  81. package/dist/server/app-page-boundary-render.js.map +1 -1
  82. package/dist/server/app-page-boundary.d.ts +12 -1
  83. package/dist/server/app-page-boundary.js +27 -12
  84. package/dist/server/app-page-boundary.js.map +1 -1
  85. package/dist/server/app-page-cache.d.ts +22 -5
  86. package/dist/server/app-page-cache.js +90 -11
  87. package/dist/server/app-page-cache.js.map +1 -1
  88. package/dist/server/app-page-dispatch.d.ts +123 -0
  89. package/dist/server/app-page-dispatch.js +348 -0
  90. package/dist/server/app-page-dispatch.js.map +1 -0
  91. package/dist/server/app-page-element-builder.d.ts +61 -0
  92. package/dist/server/app-page-element-builder.js +139 -0
  93. package/dist/server/app-page-element-builder.js.map +1 -0
  94. package/dist/server/app-page-execution.d.ts +4 -3
  95. package/dist/server/app-page-execution.js +5 -8
  96. package/dist/server/app-page-execution.js.map +1 -1
  97. package/dist/server/app-page-head.d.ts +55 -0
  98. package/dist/server/app-page-head.js +196 -0
  99. package/dist/server/app-page-head.js.map +1 -0
  100. package/dist/server/app-page-method.d.ts +16 -0
  101. package/dist/server/app-page-method.js +30 -0
  102. package/dist/server/app-page-method.js.map +1 -0
  103. package/dist/server/app-page-params.d.ts +8 -0
  104. package/dist/server/app-page-params.js +28 -0
  105. package/dist/server/app-page-params.js.map +1 -0
  106. package/dist/server/app-page-render.d.ts +7 -2
  107. package/dist/server/app-page-render.js +131 -32
  108. package/dist/server/app-page-render.js.map +1 -1
  109. package/dist/server/app-page-request.d.ts +23 -8
  110. package/dist/server/app-page-request.js +51 -6
  111. package/dist/server/app-page-request.js.map +1 -1
  112. package/dist/server/app-page-response.d.ts +1 -0
  113. package/dist/server/app-page-response.js +3 -7
  114. package/dist/server/app-page-response.js.map +1 -1
  115. package/dist/server/app-page-route-wiring.d.ts +29 -5
  116. package/dist/server/app-page-route-wiring.js +30 -8
  117. package/dist/server/app-page-route-wiring.js.map +1 -1
  118. package/dist/server/app-page-stream.d.ts +10 -0
  119. package/dist/server/app-page-stream.js +5 -1
  120. package/dist/server/app-page-stream.js.map +1 -1
  121. package/dist/server/app-post-middleware-context.d.ts +16 -0
  122. package/dist/server/app-post-middleware-context.js +28 -0
  123. package/dist/server/app-post-middleware-context.js.map +1 -0
  124. package/dist/server/app-prerender-endpoints.d.ts +19 -0
  125. package/dist/server/app-prerender-endpoints.js +96 -0
  126. package/dist/server/app-prerender-endpoints.js.map +1 -0
  127. package/dist/server/app-prerender-static-params.d.ts +16 -0
  128. package/dist/server/app-prerender-static-params.js +14 -0
  129. package/dist/server/app-prerender-static-params.js.map +1 -0
  130. package/dist/server/app-request-context.d.ts +22 -0
  131. package/dist/server/app-request-context.js +30 -0
  132. package/dist/server/app-request-context.js.map +1 -0
  133. package/dist/server/app-route-handler-cache.d.ts +4 -0
  134. package/dist/server/app-route-handler-cache.js +11 -3
  135. package/dist/server/app-route-handler-cache.js.map +1 -1
  136. package/dist/server/app-route-handler-dispatch.d.ts +43 -0
  137. package/dist/server/app-route-handler-dispatch.js +149 -0
  138. package/dist/server/app-route-handler-dispatch.js.map +1 -0
  139. package/dist/server/app-route-handler-execution.d.ts +8 -3
  140. package/dist/server/app-route-handler-execution.js +25 -4
  141. package/dist/server/app-route-handler-execution.js.map +1 -1
  142. package/dist/server/app-route-handler-response.d.ts +6 -3
  143. package/dist/server/app-route-handler-response.js +52 -11
  144. package/dist/server/app-route-handler-response.js.map +1 -1
  145. package/dist/server/app-route-handler-runtime.d.ts +4 -1
  146. package/dist/server/app-route-handler-runtime.js +107 -1
  147. package/dist/server/app-route-handler-runtime.js.map +1 -1
  148. package/dist/server/app-router-entry.js.map +1 -1
  149. package/dist/server/app-rsc-error-handler.d.ts +21 -0
  150. package/dist/server/app-rsc-error-handler.js +30 -0
  151. package/dist/server/app-rsc-error-handler.js.map +1 -0
  152. package/dist/server/app-rsc-errors.d.ts +27 -0
  153. package/dist/server/app-rsc-errors.js +42 -0
  154. package/dist/server/app-rsc-errors.js.map +1 -0
  155. package/dist/server/app-rsc-handler.d.ts +117 -0
  156. package/dist/server/app-rsc-handler.js +260 -0
  157. package/dist/server/app-rsc-handler.js.map +1 -0
  158. package/dist/server/app-rsc-request-normalization.d.ts +40 -0
  159. package/dist/server/app-rsc-request-normalization.js +63 -0
  160. package/dist/server/app-rsc-request-normalization.js.map +1 -0
  161. package/dist/server/app-rsc-response-finalizer.d.ts +30 -0
  162. package/dist/server/app-rsc-response-finalizer.js +38 -0
  163. package/dist/server/app-rsc-response-finalizer.js.map +1 -0
  164. package/dist/server/app-rsc-route-matching.d.ts +40 -0
  165. package/dist/server/app-rsc-route-matching.js +66 -0
  166. package/dist/server/app-rsc-route-matching.js.map +1 -0
  167. package/dist/server/app-segment-config.d.ts +33 -0
  168. package/dist/server/app-segment-config.js +86 -0
  169. package/dist/server/app-segment-config.js.map +1 -0
  170. package/dist/server/app-server-action-execution.d.ts +88 -1
  171. package/dist/server/app-server-action-execution.js +257 -5
  172. package/dist/server/app-server-action-execution.js.map +1 -1
  173. package/dist/server/app-ssr-entry.d.ts +7 -0
  174. package/dist/server/app-ssr-entry.js +30 -9
  175. package/dist/server/app-ssr-entry.js.map +1 -1
  176. package/dist/server/app-ssr-stream.d.ts +4 -2
  177. package/dist/server/app-ssr-stream.js +29 -2
  178. package/dist/server/app-ssr-stream.js.map +1 -1
  179. package/dist/server/app-static-generation.d.ts +15 -0
  180. package/dist/server/app-static-generation.js +20 -0
  181. package/dist/server/app-static-generation.js.map +1 -0
  182. package/dist/server/cache-control.d.ts +24 -0
  183. package/dist/server/cache-control.js +33 -0
  184. package/dist/server/cache-control.js.map +1 -0
  185. package/dist/server/dev-error-overlay-store.d.ts +23 -0
  186. package/dist/server/dev-error-overlay-store.js +67 -0
  187. package/dist/server/dev-error-overlay-store.js.map +1 -0
  188. package/dist/server/dev-error-overlay.d.ts +15 -0
  189. package/dist/server/dev-error-overlay.js +548 -0
  190. package/dist/server/dev-error-overlay.js.map +1 -0
  191. package/dist/server/dev-route-files.d.ts +7 -0
  192. package/dist/server/dev-route-files.js +73 -0
  193. package/dist/server/dev-route-files.js.map +1 -0
  194. package/dist/server/dev-server.js +4 -0
  195. package/dist/server/dev-server.js.map +1 -1
  196. package/dist/server/file-based-metadata.d.ts +17 -0
  197. package/dist/server/file-based-metadata.js +356 -0
  198. package/dist/server/file-based-metadata.js.map +1 -0
  199. package/dist/server/implicit-tags.d.ts +6 -0
  200. package/dist/server/implicit-tags.js +42 -0
  201. package/dist/server/implicit-tags.js.map +1 -0
  202. package/dist/server/instrumentation-runtime.d.ts +44 -0
  203. package/dist/server/instrumentation-runtime.js +29 -0
  204. package/dist/server/instrumentation-runtime.js.map +1 -0
  205. package/dist/server/instrumentation.js.map +1 -1
  206. package/dist/server/isr-cache.d.ts +16 -3
  207. package/dist/server/isr-cache.js +56 -8
  208. package/dist/server/isr-cache.js.map +1 -1
  209. package/dist/server/metadata-route-build-data.d.ts +25 -0
  210. package/dist/server/metadata-route-build-data.js +150 -0
  211. package/dist/server/metadata-route-build-data.js.map +1 -0
  212. package/dist/server/metadata-route-response.d.ts +17 -0
  213. package/dist/server/metadata-route-response.js +187 -0
  214. package/dist/server/metadata-route-response.js.map +1 -0
  215. package/dist/server/metadata-routes.d.ts +42 -4
  216. package/dist/server/metadata-routes.js +127 -11
  217. package/dist/server/metadata-routes.js.map +1 -1
  218. package/dist/server/middleware-matcher.d.ts +15 -0
  219. package/dist/server/middleware-matcher.js +102 -0
  220. package/dist/server/middleware-matcher.js.map +1 -0
  221. package/dist/server/middleware-request-headers.js +2 -1
  222. package/dist/server/middleware-request-headers.js.map +1 -1
  223. package/dist/server/middleware-runtime.d.ts +39 -0
  224. package/dist/server/middleware-runtime.js +159 -0
  225. package/dist/server/middleware-runtime.js.map +1 -0
  226. package/dist/server/middleware.d.ts +4 -36
  227. package/dist/server/middleware.js +18 -228
  228. package/dist/server/middleware.js.map +1 -1
  229. package/dist/server/pages-page-data.d.ts +7 -2
  230. package/dist/server/pages-page-data.js +10 -5
  231. package/dist/server/pages-page-data.js.map +1 -1
  232. package/dist/server/pages-page-response.d.ts +2 -1
  233. package/dist/server/pages-page-response.js +5 -3
  234. package/dist/server/pages-page-response.js.map +1 -1
  235. package/dist/server/prerender-work-unit-setup.d.ts +7 -0
  236. package/dist/server/prerender-work-unit-setup.js +30 -0
  237. package/dist/server/prerender-work-unit-setup.js.map +1 -0
  238. package/dist/server/prod-server.js +10 -14
  239. package/dist/server/prod-server.js.map +1 -1
  240. package/dist/server/request-pipeline.d.ts +46 -5
  241. package/dist/server/request-pipeline.js +84 -5
  242. package/dist/server/request-pipeline.js.map +1 -1
  243. package/dist/server/rsc-stream-hints.d.ts +7 -0
  244. package/dist/server/rsc-stream-hints.js +38 -0
  245. package/dist/server/rsc-stream-hints.js.map +1 -0
  246. package/dist/server/seed-cache.js +19 -8
  247. package/dist/server/seed-cache.js.map +1 -1
  248. package/dist/server/server-action-not-found.d.ts +9 -0
  249. package/dist/server/server-action-not-found.js +40 -0
  250. package/dist/server/server-action-not-found.js.map +1 -0
  251. package/dist/shims/cache-runtime.js +28 -11
  252. package/dist/shims/cache-runtime.js.map +1 -1
  253. package/dist/shims/cache.d.ts +39 -4
  254. package/dist/shims/cache.js +93 -16
  255. package/dist/shims/cache.js.map +1 -1
  256. package/dist/shims/error-boundary.d.ts +66 -5
  257. package/dist/shims/error-boundary.js +106 -4
  258. package/dist/shims/error-boundary.js.map +1 -1
  259. package/dist/shims/fetch-cache.d.ts +4 -1
  260. package/dist/shims/fetch-cache.js +55 -13
  261. package/dist/shims/fetch-cache.js.map +1 -1
  262. package/dist/shims/font-google-base.d.ts +5 -4
  263. package/dist/shims/font-google-base.js +61 -13
  264. package/dist/shims/font-google-base.js.map +1 -1
  265. package/dist/shims/headers.d.ts +14 -2
  266. package/dist/shims/headers.js +127 -17
  267. package/dist/shims/headers.js.map +1 -1
  268. package/dist/shims/image.js +116 -10
  269. package/dist/shims/image.js.map +1 -1
  270. package/dist/shims/internal/make-hanging-promise.d.ts +16 -0
  271. package/dist/shims/internal/make-hanging-promise.js +46 -0
  272. package/dist/shims/internal/make-hanging-promise.js.map +1 -0
  273. package/dist/shims/internal/work-unit-async-storage.d.ts +26 -3
  274. package/dist/shims/internal/work-unit-async-storage.js +6 -3
  275. package/dist/shims/internal/work-unit-async-storage.js.map +1 -1
  276. package/dist/shims/metadata.d.ts +38 -26
  277. package/dist/shims/metadata.js +75 -45
  278. package/dist/shims/metadata.js.map +1 -1
  279. package/dist/shims/navigation.d.ts +10 -1
  280. package/dist/shims/navigation.js +18 -1
  281. package/dist/shims/navigation.js.map +1 -1
  282. package/dist/shims/navigation.react-server.d.ts +2 -2
  283. package/dist/shims/navigation.react-server.js +2 -2
  284. package/dist/shims/navigation.react-server.js.map +1 -1
  285. package/dist/shims/offline.d.ts +5 -0
  286. package/dist/shims/offline.js +17 -0
  287. package/dist/shims/offline.js.map +1 -0
  288. package/dist/shims/request-state-types.d.ts +3 -2
  289. package/dist/shims/root-params.d.ts +11 -0
  290. package/dist/shims/root-params.js +24 -0
  291. package/dist/shims/root-params.js.map +1 -0
  292. package/dist/shims/router.js +1 -1
  293. package/dist/shims/server.d.ts +3 -1
  294. package/dist/shims/server.js +83 -5
  295. package/dist/shims/server.js.map +1 -1
  296. package/dist/shims/thenable-params.d.ts +5 -0
  297. package/dist/shims/thenable-params.js +37 -0
  298. package/dist/shims/thenable-params.js.map +1 -0
  299. package/dist/shims/unified-request-context.d.ts +3 -2
  300. package/dist/shims/unified-request-context.js +3 -0
  301. package/dist/shims/unified-request-context.js.map +1 -1
  302. package/dist/shims/use-merged-ref.d.ts +7 -0
  303. package/dist/shims/use-merged-ref.js +40 -0
  304. package/dist/shims/use-merged-ref.js.map +1 -0
  305. package/dist/utils/cache-control-metadata.d.ts +6 -0
  306. package/dist/utils/cache-control-metadata.js +16 -0
  307. package/dist/utils/cache-control-metadata.js.map +1 -0
  308. package/package.json +6 -1
  309. package/dist/server/middleware-codegen.d.ts +0 -54
  310. package/dist/server/middleware-codegen.js +0 -414
  311. package/dist/server/middleware-codegen.js.map +0 -1
@@ -2,13 +2,18 @@ import { DANGEROUS_URL_BLOCK_MESSAGE, isDangerousScheme } from "../shims/url-saf
2
2
  import { stripBasePath } from "../utils/base-path.js";
3
3
  import { notifyAppRouterTransitionStart } from "../client/instrumentation-client-state.js";
4
4
  import { createAppPayloadCacheKey, getMountedSlotIdsHeader, normalizeAppElements, readAppElementsMetadata, resolveVisitedResponseInterceptionContext } from "./app-elements.js";
5
- import { __basePath, activateNavigationSnapshot, clearPendingPathname, commitClientNavigationState, consumePrefetchResponse, createClientNavigationRenderSnapshot, getClientNavigationRenderContext, getClientNavigationState, getCurrentInterceptionContext, getCurrentNextUrl, getPrefetchCache, getPrefetchedUrls, pushHistoryStateWithoutNotify, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, restoreRscResponse, setClientParams, setMountedSlotsHeader, setNavigationContext, setPendingPathname, snapshotRscResponse, toRscUrl } from "../shims/navigation.js";
5
+ import { __basePath, commitClientNavigationState, consumePrefetchResponse, createClientNavigationRenderSnapshot, getClientNavigationRenderContext, getClientNavigationState, getCurrentInterceptionContext, getCurrentNextUrl, getPrefetchCache, getPrefetchedUrls, pushHistoryStateWithoutNotify, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, restoreRscResponse, setClientParams, setMountedSlotsHeader, setNavigationContext, setPendingPathname, snapshotRscResponse, toRscUrl } from "../shims/navigation.js";
6
+ import { DevRecoveryBoundary } from "../shims/error-boundary.js";
6
7
  import { ElementsContext, Slot } from "../shims/slot.js";
7
8
  import "../client/instrumentation-client.js";
8
9
  import { chunksToReadableStream, createProgressiveRscStream, getVinextBrowserGlobal } from "./app-browser-stream.js";
9
- import { createHistoryStateWithPreviousNextUrl, createPendingNavigationCommit, readHistoryStatePreviousNextUrl, resolveAndClassifyNavigationCommit, resolveInterceptionContextFromPreviousNextUrl, resolvePendingNavigationCommitDisposition, resolveServerActionRequestState, routerReducer } from "./app-browser-state.js";
10
- import { devOnCaughtError } from "./app-browser-error.js";
11
- import { createElement, startTransition, use, useLayoutEffect, useRef, useState } from "react";
10
+ import { createHistoryStateWithPreviousNextUrl, readHistoryStatePreviousNextUrl, resolveInterceptionContextFromPreviousNextUrl, resolveServerActionRequestState } from "./app-browser-state.js";
11
+ import { createAppBrowserNavigationController } from "./app-browser-navigation-controller.js";
12
+ import { createOnUncaughtError } from "./app-browser-error.js";
13
+ import { dismissOverlay } from "./dev-error-overlay-store.js";
14
+ import { devOnCaughtError, devOnUncaughtError, installDevErrorOverlay } from "./dev-error-overlay.js";
15
+ import { getServerActionNotFoundClientMessage, isServerActionNotFoundResponse } from "./server-action-not-found.js";
16
+ import { createElement, use, useLayoutEffect, useRef, useState } from "react";
12
17
  import { createFromFetch, createFromReadableStream, createTemporaryReferenceSet, encodeReply, setServerCallback } from "@vitejs/plugin-rsc/browser";
13
18
  import { hydrateRoot } from "react-dom/client";
14
19
  //#region src/server/app-browser-entry.ts
@@ -18,59 +23,29 @@ function toActionType(kind) {
18
23
  const MAX_VISITED_RESPONSE_CACHE_SIZE = 50;
19
24
  const VISITED_RESPONSE_CACHE_TTL = 5 * 6e4;
20
25
  const MAX_TRAVERSAL_CACHE_TTL = 30 * 6e4;
21
- let nextNavigationRenderId = 0;
22
- let activeNavigationId = 0;
23
- const pendingNavigationCommits = /* @__PURE__ */ new Map();
24
- const pendingNavigationPrePaintEffects = /* @__PURE__ */ new Map();
26
+ const browserNavigationController = createAppBrowserNavigationController();
27
+ const NavigationCommitSignal = browserNavigationController.NavigationCommitSignal;
25
28
  function isRouterStatePromise(value) {
26
29
  return value instanceof Promise;
27
30
  }
28
- let setBrowserRouterState = null;
29
- let browserRouterStateRef = null;
30
- let activePendingBrowserRouterState = null;
31
31
  let latestClientParams = {};
32
32
  const visitedResponseCache = /* @__PURE__ */ new Map();
33
+ let browserRouterStateHasEverCommitted = false;
34
+ let pendingNavigationRecoveryHref = null;
33
35
  function isServerActionResult(value) {
34
36
  return !!value && typeof value === "object" && "root" in value;
35
37
  }
36
- function getBrowserRouterStateSetter() {
37
- if (!setBrowserRouterState) throw new Error("[vinext] Browser router state setter is not initialized");
38
- return setBrowserRouterState;
39
- }
40
38
  function getBrowserRouterState() {
41
- if (!browserRouterStateRef) throw new Error("[vinext] Browser router state is not initialized");
42
- return browserRouterStateRef.current;
39
+ return browserNavigationController.getBrowserRouterState();
40
+ }
41
+ function hasBrowserRouterState() {
42
+ return browserNavigationController.hasBrowserRouterState();
43
+ }
44
+ function waitForBrowserRouterStateReady() {
45
+ return browserNavigationController.waitForBrowserRouterStateReady();
43
46
  }
44
47
  function beginPendingBrowserRouterState() {
45
- const setter = getBrowserRouterStateSetter();
46
- if (activePendingBrowserRouterState && !activePendingBrowserRouterState.settled) {
47
- activePendingBrowserRouterState.settled = true;
48
- activePendingBrowserRouterState.resolve(getBrowserRouterState());
49
- }
50
- let resolve;
51
- const promise = new Promise((resolvePromise) => {
52
- resolve = resolvePromise;
53
- });
54
- const pending = {
55
- promise,
56
- resolve,
57
- settled: false
58
- };
59
- activePendingBrowserRouterState = pending;
60
- setter(promise);
61
- return pending;
62
- }
63
- function settlePendingBrowserRouterState(pending) {
64
- if (!pending || pending.settled) return;
65
- pending.settled = true;
66
- pending.resolve(getBrowserRouterState());
67
- if (activePendingBrowserRouterState === pending) activePendingBrowserRouterState = null;
68
- }
69
- function resolvePendingBrowserRouterState(pending, action) {
70
- if (!pending || pending.settled) return;
71
- pending.settled = true;
72
- pending.resolve(routerReducer(getBrowserRouterState(), action));
73
- if (activePendingBrowserRouterState === pending) activePendingBrowserRouterState = null;
48
+ return browserNavigationController.beginPendingBrowserRouterState();
74
49
  }
75
50
  function applyClientParams(params) {
76
51
  latestClientParams = params;
@@ -91,31 +66,10 @@ function clearClientNavigationCaches() {
91
66
  clearVisitedResponseCache();
92
67
  clearPrefetchState();
93
68
  }
94
- function queuePrePaintNavigationEffect(renderId, effect) {
95
- if (!effect) return;
96
- pendingNavigationPrePaintEffects.set(renderId, effect);
97
- }
98
- /**
99
- * Run all queued pre-paint effects for renderIds up to and including the
100
- * given renderId. When React supersedes a startTransition update (rapid
101
- * clicks on same-route links), the superseded NavigationCommitSignal never
102
- * mounts, so its pre-paint effect never fires. By draining all effects
103
- * <= the committed renderId here, the winning transition cleans up after
104
- * any superseded ones, keeping the counter balanced.
105
- *
106
- * Invariant: each superseded navigation gets a commitClientNavigationState()
107
- * to balance the activateNavigationSnapshot() from its renderNavigationPayload call.
108
- */
109
- function drainPrePaintEffects(upToRenderId) {
110
- for (const [id, effect] of pendingNavigationPrePaintEffects) if (id <= upToRenderId) {
111
- pendingNavigationPrePaintEffects.delete(id);
112
- if (id === upToRenderId) effect();
113
- else commitClientNavigationState(void 0, { releaseSnapshot: true });
114
- }
115
- }
116
- function createNavigationCommitEffect(href, historyUpdateMode, navId, params, previousNextUrl) {
69
+ function createNavigationCommitEffect(options) {
70
+ const { href, historyUpdateMode, navId, params, previousNextUrl } = options;
117
71
  return () => {
118
- if (navId !== activeNavigationId) {
72
+ if (!browserNavigationController.isCurrentNavigation(navId)) {
119
73
  commitClientNavigationState(void 0, { releaseSnapshot: true });
120
74
  return;
121
75
  }
@@ -124,9 +78,37 @@ function createNavigationCommitEffect(href, historyUpdateMode, navId, params, pr
124
78
  const historyState = createHistoryStateWithPreviousNextUrl(historyUpdateMode === "replace" ? window.history.state : null, previousNextUrl);
125
79
  if (historyUpdateMode === "replace" && window.location.href !== targetHref) replaceHistoryStateWithoutNotify(historyState, "", href);
126
80
  else if (historyUpdateMode === "push" && window.location.href !== targetHref) pushHistoryStateWithoutNotify(historyState, "", href);
81
+ pendingNavigationRecoveryHref = null;
127
82
  commitClientNavigationState(navId);
128
83
  };
129
84
  }
85
+ async function renderNavigationPayload(payload, navigationSnapshot, targetHref, navId, historyUpdateMode, params, previousNextUrl, pendingRouterState, useTransition = true, actionType = "navigate") {
86
+ try {
87
+ return await browserNavigationController.renderNavigationPayload({
88
+ actionType,
89
+ createNavigationCommitEffect: (options) => {
90
+ pendingNavigationRecoveryHref = options.href;
91
+ return createNavigationCommitEffect(options);
92
+ },
93
+ historyUpdateMode,
94
+ navigationSnapshot,
95
+ nextElements: payload,
96
+ params,
97
+ pendingRouterState,
98
+ previousNextUrl,
99
+ targetHref,
100
+ navId,
101
+ useTransition
102
+ });
103
+ } catch (error) {
104
+ pendingNavigationRecoveryHref = null;
105
+ throw error;
106
+ }
107
+ }
108
+ async function commitSameUrlNavigatePayload(nextElements, returnValue) {
109
+ const navigationSnapshot = createClientNavigationRenderSnapshot(window.location.href, latestClientParams);
110
+ return browserNavigationController.commitSameUrlNavigatePayload(nextElements, navigationSnapshot, returnValue);
111
+ }
130
112
  function evictVisitedResponseCacheIfNeeded() {
131
113
  while (visitedResponseCache.size >= MAX_VISITED_RESPONSE_CACHE_SIZE) {
132
114
  const oldest = visitedResponseCache.keys().next().value;
@@ -204,57 +186,12 @@ function createRscRequestHeaders(interceptionContext) {
204
186
  if (interceptionContext !== null) headers.set("X-Vinext-Interception-Context", interceptionContext);
205
187
  return headers;
206
188
  }
207
- /**
208
- * Resolve all pending navigation commits with renderId <= the committed renderId.
209
- * Note: Map iteration handles concurrent deletion safely — entries are visited in
210
- * insertion order and deletion doesn't affect the iterator's view of remaining entries.
211
- * This pattern is also used in drainPrePaintEffects with the same semantics.
212
- */
213
- function resolveCommittedNavigations(renderId) {
214
- for (const [pendingId, resolve] of pendingNavigationCommits) if (pendingId <= renderId) {
215
- pendingNavigationCommits.delete(pendingId);
216
- resolve();
217
- }
218
- }
219
- function NavigationCommitSignal({ renderId, children }) {
220
- useLayoutEffect(() => {
221
- drainPrePaintEffects(renderId);
222
- const frame = requestAnimationFrame(() => {
223
- resolveCommittedNavigations(renderId);
224
- });
225
- return () => {
226
- cancelAnimationFrame(frame);
227
- resolveCommittedNavigations(renderId);
228
- };
229
- }, [renderId]);
230
- return children;
189
+ function handleDevRecoveryBoundaryCatch(resetKey) {
190
+ browserNavigationController.drainPrePaintEffects(resetKey);
231
191
  }
232
192
  function normalizeAppElementsPromise(payload) {
233
193
  return Promise.resolve(payload).then((elements) => normalizeAppElements(elements));
234
194
  }
235
- async function commitSameUrlNavigatePayload(nextElements, returnValue) {
236
- const navigationSnapshot = createClientNavigationRenderSnapshot(window.location.href, latestClientParams);
237
- const currentState = getBrowserRouterState();
238
- const startedNavigationId = activeNavigationId;
239
- const { disposition, pending } = await resolveAndClassifyNavigationCommit({
240
- activeNavigationId,
241
- currentState,
242
- navigationSnapshot,
243
- nextElements,
244
- renderId: ++nextNavigationRenderId,
245
- startedNavigationId,
246
- type: "navigate"
247
- });
248
- if (disposition === "hard-navigate") {
249
- window.location.assign(window.location.href);
250
- return;
251
- }
252
- if (disposition === "dispatch") dispatchBrowserTree(pending.action.elements, navigationSnapshot, pending.action.renderId, "navigate", pending.interceptionContext, pending.action.layoutFlags, pending.previousNextUrl, pending.routeId, pending.rootLayoutTreePath, null, false);
253
- if (returnValue) {
254
- if (!returnValue.ok) throw returnValue.data;
255
- return returnValue.data;
256
- }
257
- }
258
195
  function BrowserRoot({ initialElements, initialNavigationSnapshot }) {
259
196
  const resolvedElements = use(initialElements);
260
197
  const initialMetadata = readAppElementsMetadata(resolvedElements);
@@ -272,11 +209,10 @@ function BrowserRoot({ initialElements, initialNavigationSnapshot }) {
272
209
  const stateRef = useRef(treeState);
273
210
  stateRef.current = treeState;
274
211
  useLayoutEffect(() => {
275
- setBrowserRouterState = setTreeStateValue;
276
- browserRouterStateRef = stateRef;
212
+ const detach = browserNavigationController.attachBrowserRouterState(setTreeStateValue, stateRef);
213
+ browserRouterStateHasEverCommitted = true;
277
214
  return () => {
278
- if (setBrowserRouterState === setTreeStateValue) setBrowserRouterState = null;
279
- if (browserRouterStateRef === stateRef) browserRouterStateRef = null;
215
+ detach();
280
216
  setMountedSlotsHeader(null);
281
217
  };
282
218
  }, [setTreeStateValue]);
@@ -287,84 +223,15 @@ function BrowserRoot({ initialElements, initialNavigationSnapshot }) {
287
223
  if (treeState.renderId !== 0) return;
288
224
  replaceHistoryStateWithoutNotify(createHistoryStateWithPreviousNextUrl(window.history.state, treeState.previousNextUrl), "", window.location.href);
289
225
  }, [treeState.previousNextUrl, treeState.renderId]);
290
- const committedTree = createElement(NavigationCommitSignal, { renderId: treeState.renderId }, createElement(ElementsContext.Provider, { value: treeState.elements }, createElement(Slot, { id: treeState.routeId })));
226
+ const innerTree = createElement(NavigationCommitSignal, { renderId: treeState.renderId }, createElement(ElementsContext.Provider, { value: treeState.elements }, createElement(Slot, { id: treeState.routeId })));
227
+ const committedTree = import.meta.env.DEV ? createElement(DevRecoveryBoundary, {
228
+ resetKey: treeState.renderId,
229
+ onCatch: handleDevRecoveryBoundaryCatch
230
+ }, innerTree) : innerTree;
291
231
  const ClientNavigationRenderContext = getClientNavigationRenderContext();
292
232
  if (!ClientNavigationRenderContext) return committedTree;
293
233
  return createElement(ClientNavigationRenderContext.Provider, { value: treeState.navigationSnapshot }, committedTree);
294
234
  }
295
- function dispatchBrowserTree(elements, navigationSnapshot, renderId, actionType, interceptionContext, layoutFlags, previousNextUrl, routeId, rootLayoutTreePath, pendingRouterState, useTransitionMode) {
296
- const setter = getBrowserRouterStateSetter();
297
- const action = {
298
- elements,
299
- interceptionContext,
300
- layoutFlags,
301
- navigationSnapshot,
302
- previousNextUrl,
303
- renderId,
304
- rootLayoutTreePath,
305
- routeId,
306
- type: actionType
307
- };
308
- const applyAction = () => {
309
- if (pendingRouterState) {
310
- resolvePendingBrowserRouterState(pendingRouterState, action);
311
- return;
312
- }
313
- setter(routerReducer(getBrowserRouterState(), action));
314
- };
315
- if (useTransitionMode) startTransition(applyAction);
316
- else applyAction();
317
- }
318
- async function renderNavigationPayload(payload, navigationSnapshot, targetHref, navId, historyUpdateMode, params, previousNextUrl, pendingRouterState, useTransition = true, actionType = "navigate") {
319
- const renderId = ++nextNavigationRenderId;
320
- const committed = new Promise((resolve) => {
321
- pendingNavigationCommits.set(renderId, resolve);
322
- });
323
- let snapshotActivated = false;
324
- try {
325
- const currentState = getBrowserRouterState();
326
- const pending = await createPendingNavigationCommit({
327
- currentState,
328
- nextElements: payload,
329
- navigationSnapshot,
330
- previousNextUrl,
331
- renderId,
332
- type: actionType
333
- });
334
- const disposition = resolvePendingNavigationCommitDisposition({
335
- activeNavigationId,
336
- currentRootLayoutTreePath: currentState.rootLayoutTreePath,
337
- nextRootLayoutTreePath: pending.rootLayoutTreePath,
338
- startedNavigationId: navId
339
- });
340
- if (disposition === "skip") {
341
- settlePendingBrowserRouterState(pendingRouterState);
342
- const resolve = pendingNavigationCommits.get(renderId);
343
- pendingNavigationCommits.delete(renderId);
344
- resolve?.();
345
- return;
346
- }
347
- if (disposition === "hard-navigate") {
348
- settlePendingBrowserRouterState(pendingRouterState);
349
- pendingNavigationCommits.delete(renderId);
350
- window.location.assign(targetHref);
351
- return;
352
- }
353
- queuePrePaintNavigationEffect(renderId, createNavigationCommitEffect(targetHref, historyUpdateMode, navId, params, pending.previousNextUrl));
354
- activateNavigationSnapshot();
355
- snapshotActivated = true;
356
- dispatchBrowserTree(pending.action.elements, navigationSnapshot, renderId, actionType, pending.interceptionContext, pending.action.layoutFlags, pending.previousNextUrl, pending.routeId, pending.rootLayoutTreePath, pendingRouterState, useTransition);
357
- } catch (error) {
358
- pendingNavigationPrePaintEffects.delete(renderId);
359
- const resolve = pendingNavigationCommits.get(renderId);
360
- pendingNavigationCommits.delete(renderId);
361
- if (snapshotActivated) commitClientNavigationState(navId);
362
- settlePendingBrowserRouterState(pendingRouterState);
363
- resolve?.();
364
- throw error;
365
- }
366
- return committed;
367
- }
368
235
  function restoreHydrationNavigationContext(pathname, searchParams, params) {
369
236
  setNavigationContext({
370
237
  pathname,
@@ -488,6 +355,7 @@ function registerServerActionCallback() {
488
355
  headers,
489
356
  body
490
357
  });
358
+ if (isServerActionNotFoundResponse(fetchResponse)) throw new Error(getServerActionNotFoundClientMessage(id));
491
359
  const actionRedirect = fetchResponse.headers.get("x-action-redirect");
492
360
  if (actionRedirect) {
493
361
  if (isDangerousScheme(actionRedirect)) {
@@ -517,24 +385,33 @@ async function main() {
517
385
  bootstrapHydration(rscStream);
518
386
  }
519
387
  function bootstrapHydration(rscStream) {
388
+ if (import.meta.env.DEV) installDevErrorOverlay();
520
389
  const root = normalizeAppElementsPromise(createFromReadableStream(rscStream));
521
390
  const initialNavigationSnapshot = createClientNavigationRenderSnapshot(window.location.href, latestClientParams);
522
391
  replaceHistoryStateWithoutNotify(createHistoryStateWithPreviousNextUrl(window.history.state, null), "", window.location.href);
392
+ const onUncaughtError = import.meta.env.DEV ? devOnUncaughtError : createOnUncaughtError(() => pendingNavigationRecoveryHref);
523
393
  window.__VINEXT_RSC_ROOT__ = hydrateRoot(document, createElement(BrowserRoot, {
524
394
  initialElements: root,
525
395
  initialNavigationSnapshot
526
- }), import.meta.env.DEV ? { onCaughtError: devOnCaughtError } : void 0);
396
+ }), import.meta.env.DEV ? {
397
+ onCaughtError: devOnCaughtError,
398
+ onUncaughtError
399
+ } : { onUncaughtError });
527
400
  window.__VINEXT_HYDRATED_AT = performance.now();
528
401
  window.__VINEXT_RSC_NAVIGATE__ = async function navigateRsc(href, redirectDepth = 0, navigationKind = "navigate", historyUpdateMode, previousNextUrlOverride, programmaticTransition = false) {
529
- let _snapshotPending = false;
530
402
  let pendingRouterState = null;
531
- const navId = ++activeNavigationId;
403
+ const navId = browserNavigationController.beginNavigation();
532
404
  let currentHref = href;
533
405
  let currentHistoryMode = historyUpdateMode;
534
406
  let currentPrevNextUrl = previousNextUrlOverride;
535
407
  let redirectCount = redirectDepth;
536
408
  try {
537
- if (programmaticTransition) pendingRouterState = beginPendingBrowserRouterState();
409
+ if (programmaticTransition && hasBrowserRouterState()) pendingRouterState = beginPendingBrowserRouterState();
410
+ else {
411
+ await waitForBrowserRouterStateReady();
412
+ if (!browserNavigationController.isCurrentNavigation(navId)) return;
413
+ if (programmaticTransition) pendingRouterState = beginPendingBrowserRouterState();
414
+ }
538
415
  while (true) {
539
416
  if (redirectCount > 10) {
540
417
  console.error("[vinext] Too many RSC redirects — aborting navigation to prevent infinite loop.");
@@ -554,17 +431,12 @@ function bootstrapHydration(rscStream) {
554
431
  const mountedSlotsHeader = getMountedSlotIdsHeader(elementsAtNavStart);
555
432
  const cachedRoute = getVisitedResponse(rscUrl, requestInterceptionContext, mountedSlotsHeader, navigationKind);
556
433
  if (cachedRoute) {
557
- if (navId !== activeNavigationId) return;
434
+ if (!browserNavigationController.isCurrentNavigation(navId)) return;
558
435
  const cachedParams = cachedRoute.params;
559
436
  const cachedNavigationSnapshot = createClientNavigationRenderSnapshot(currentHref, cachedParams);
560
437
  const cachedPayload = normalizeAppElementsPromise(createFromFetch(Promise.resolve(restoreRscResponse(cachedRoute.response))));
561
- if (navId !== activeNavigationId) return;
562
- _snapshotPending = true;
563
- try {
564
- await renderNavigationPayload(cachedPayload, cachedNavigationSnapshot, currentHref, navId, currentHistoryMode, cachedParams, requestPreviousNextUrl, pendingRouterState, isSameRoute, toActionType(navigationKind));
565
- } finally {
566
- _snapshotPending = false;
567
- }
438
+ if (!browserNavigationController.isCurrentNavigation(navId)) return;
439
+ await renderNavigationPayload(cachedPayload, cachedNavigationSnapshot, currentHref, navId, currentHistoryMode, cachedParams, requestPreviousNextUrl, pendingRouterState, isSameRoute, toActionType(navigationKind));
568
440
  return;
569
441
  }
570
442
  let navResponse;
@@ -584,7 +456,7 @@ function bootstrapHydration(rscStream) {
584
456
  credentials: "include"
585
457
  });
586
458
  }
587
- if (navId !== activeNavigationId) return;
459
+ if (!browserNavigationController.isCurrentNavigation(navId)) return;
588
460
  const isRscResponse = (navResponse.headers.get("content-type") ?? "").startsWith("text/x-component");
589
461
  if (!navResponse.ok || !isRscResponse || !navResponse.body) {
590
462
  const responseUrl = navResponseUrl ?? navResponse.url;
@@ -618,30 +490,20 @@ function bootstrapHydration(rscStream) {
618
490
  } catch {}
619
491
  const navigationSnapshot = createClientNavigationRenderSnapshot(currentHref, navParams);
620
492
  const responseSnapshot = await snapshotRscResponse(navResponse);
621
- if (navId !== activeNavigationId) return;
493
+ if (!browserNavigationController.isCurrentNavigation(navId)) return;
622
494
  const rscPayload = normalizeAppElementsPromise(createFromFetch(Promise.resolve(restoreRscResponse(responseSnapshot))));
623
- if (navId !== activeNavigationId) return;
624
- _snapshotPending = true;
625
- try {
626
- await renderNavigationPayload(rscPayload, navigationSnapshot, currentHref, navId, currentHistoryMode, navParams, requestPreviousNextUrl, pendingRouterState, isSameRoute, toActionType(navigationKind));
627
- } finally {
628
- _snapshotPending = false;
629
- }
630
- if (navId !== activeNavigationId) return;
495
+ if (!browserNavigationController.isCurrentNavigation(navId)) return;
496
+ await renderNavigationPayload(rscPayload, navigationSnapshot, currentHref, navId, currentHistoryMode, navParams, requestPreviousNextUrl, pendingRouterState, isSameRoute, toActionType(navigationKind));
497
+ if (!browserNavigationController.isCurrentNavigation(navId)) return;
631
498
  storeVisitedResponseSnapshot(rscUrl, resolveVisitedResponseInterceptionContext(requestInterceptionContext, readAppElementsMetadata(await rscPayload).interceptionContext), responseSnapshot, navParams);
632
499
  return;
633
500
  }
634
501
  } catch (error) {
635
- if (_snapshotPending) {
636
- _snapshotPending = false;
637
- commitClientNavigationState(navId);
638
- }
639
- if (navId !== activeNavigationId) return;
502
+ if (!browserNavigationController.isCurrentNavigation(navId)) return;
640
503
  if (!isPageUnloading) console.error("[vinext] RSC navigation error:", error);
641
504
  window.location.href = currentHref;
642
505
  } finally {
643
- settlePendingBrowserRouterState(pendingRouterState);
644
- if (navId === activeNavigationId) clearPendingPathname(navId);
506
+ browserNavigationController.finalizeNavigation(navId, pendingRouterState);
645
507
  }
646
508
  };
647
509
  if ("scrollRestoration" in history) history.scrollRestoration = "manual";
@@ -656,16 +518,16 @@ function bootstrapHydration(rscStream) {
656
518
  });
657
519
  if (import.meta.hot) import.meta.hot.on("rsc:update", async () => {
658
520
  try {
521
+ if (browserRouterStateHasEverCommitted && !browserNavigationController.hasBrowserRouterState()) {
522
+ window.location.reload();
523
+ return;
524
+ }
525
+ await waitForBrowserRouterStateReady();
526
+ if (!browserNavigationController.hasBrowserRouterState()) return;
659
527
  clearClientNavigationCaches();
660
528
  const navigationSnapshot = createClientNavigationRenderSnapshot(window.location.href, latestClientParams);
661
- const pending = await createPendingNavigationCommit({
662
- currentState: getBrowserRouterState(),
663
- nextElements: normalizeAppElementsPromise(createFromFetch(fetch(toRscUrl(window.location.pathname + window.location.search)))),
664
- navigationSnapshot,
665
- renderId: ++nextNavigationRenderId,
666
- type: "replace"
667
- });
668
- dispatchBrowserTree(pending.action.elements, navigationSnapshot, pending.action.renderId, "replace", pending.interceptionContext, pending.action.layoutFlags, pending.previousNextUrl, pending.routeId, pending.rootLayoutTreePath, null, false);
529
+ dismissOverlay();
530
+ await browserNavigationController.hmrReplaceTree(normalizeAppElementsPromise(createFromFetch(fetch(toRscUrl(window.location.pathname + window.location.search)))), navigationSnapshot);
669
531
  } catch (error) {
670
532
  console.error("[vinext] RSC HMR error:", error);
671
533
  }