vinext 0.1.8 → 0.2.1

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 (285) hide show
  1. package/README.md +51 -30
  2. package/dist/build/css-url-assets.d.ts +3 -1
  3. package/dist/build/css-url-assets.js +18 -1
  4. package/dist/build/inject-pregenerated-paths.d.ts +7 -0
  5. package/dist/build/inject-pregenerated-paths.js +21 -0
  6. package/dist/build/layout-classification.js +1 -1
  7. package/dist/build/nitro-route-rules.js +1 -1
  8. package/dist/build/pages-client-assets-module.d.ts +11 -0
  9. package/dist/build/pages-client-assets-module.js +27 -0
  10. package/dist/build/prerender-server-entry.d.ts +1 -0
  11. package/dist/build/prerender-server-entry.js +49 -0
  12. package/dist/build/prerender-server-pool.d.ts +44 -0
  13. package/dist/build/prerender-server-pool.js +194 -0
  14. package/dist/build/prerender.d.ts +2 -1
  15. package/dist/build/prerender.js +98 -27
  16. package/dist/build/report.d.ts +13 -2
  17. package/dist/build/report.js +99 -2
  18. package/dist/build/run-prerender.d.ts +7 -0
  19. package/dist/build/run-prerender.js +12 -2
  20. package/dist/build/standalone.js +2 -0
  21. package/dist/cache/cache-adapters-virtual.js +3 -3
  22. package/dist/check.d.ts +4 -6
  23. package/dist/check.js +48 -11
  24. package/dist/cli-args.d.ts +1 -2
  25. package/dist/cli-args.js +1 -1
  26. package/dist/cli-dev-config.d.ts +12 -0
  27. package/dist/cli-dev-config.js +23 -0
  28. package/dist/cli.js +112 -96
  29. package/dist/{server → client}/dev-error-overlay-store.d.ts +1 -1
  30. package/dist/{server → client}/dev-error-overlay-store.js +1 -1
  31. package/dist/{server → client}/dev-error-overlay.d.ts +1 -1
  32. package/dist/{server → client}/dev-error-overlay.js +2 -2
  33. package/dist/client/navigation-runtime.d.ts +2 -0
  34. package/dist/client/navigation-runtime.js +3 -1
  35. package/dist/client/vinext-next-data.d.ts +4 -1
  36. package/dist/client/window-next.d.ts +2 -1
  37. package/dist/cloudflare/index.d.ts +2 -2
  38. package/dist/cloudflare/index.js +2 -2
  39. package/dist/config/config-matchers.js +45 -19
  40. package/dist/config/next-config.d.ts +41 -9
  41. package/dist/config/next-config.js +60 -3
  42. package/dist/config/prerender.d.ts +34 -0
  43. package/dist/config/prerender.js +55 -0
  44. package/dist/entries/app-browser-entry.js +5 -1
  45. package/dist/entries/app-rsc-entry.d.ts +5 -3
  46. package/dist/entries/app-rsc-entry.js +44 -10
  47. package/dist/entries/app-rsc-manifest.js +2 -0
  48. package/dist/entries/pages-client-entry.d.ts +3 -0
  49. package/dist/entries/pages-client-entry.js +28 -3
  50. package/dist/entries/pages-server-entry.js +23 -6
  51. package/dist/image/image-adapters-virtual.d.ts +59 -0
  52. package/dist/image/image-adapters-virtual.js +59 -0
  53. package/dist/index.d.ts +33 -0
  54. package/dist/index.js +482 -120
  55. package/dist/init-cloudflare.d.ts +43 -0
  56. package/dist/init-cloudflare.js +839 -0
  57. package/dist/init-platform.d.ts +40 -0
  58. package/dist/init-platform.js +195 -0
  59. package/dist/init.d.ts +16 -38
  60. package/dist/init.js +209 -99
  61. package/dist/node_modules/.pnpm/am-i-vibing@0.5.0/node_modules/am-i-vibing/dist/detector-1yx2Hoe0.js +294 -0
  62. package/dist/node_modules/.pnpm/process-ancestry@0.1.0/node_modules/process-ancestry/dist/index.js +94 -0
  63. package/dist/{cloudflare → packages/cloudflare}/src/cache/cdn-adapter.runtime.js +1 -1
  64. package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.d.ts +2 -2
  65. package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.js +9 -2
  66. package/dist/packages/cloudflare/src/deploy-config.js +150 -0
  67. package/dist/packages/cloudflare/src/deploy-help.js +55 -0
  68. package/dist/packages/cloudflare/src/deploy.js +272 -0
  69. package/dist/{cloudflare → packages/cloudflare/src}/tpr.d.ts +4 -41
  70. package/dist/{cloudflare → packages/cloudflare/src}/tpr.js +44 -20
  71. package/dist/plugins/ast-scope.d.ts +16 -0
  72. package/dist/plugins/ast-scope.js +62 -0
  73. package/dist/plugins/ast-utils.d.ts +27 -1
  74. package/dist/plugins/ast-utils.js +32 -1
  75. package/dist/plugins/css-module-imports.d.ts +14 -0
  76. package/dist/plugins/css-module-imports.js +59 -0
  77. package/dist/plugins/extensionless-dynamic-import.js +2 -2
  78. package/dist/plugins/fonts.js +1 -1
  79. package/dist/plugins/ignore-dynamic-requests.d.ts +11 -0
  80. package/dist/plugins/ignore-dynamic-requests.js +530 -0
  81. package/dist/plugins/og-assets.js +2 -1
  82. package/dist/plugins/optimize-imports.js +1 -1
  83. package/dist/plugins/rsc-reference-validation-normalizer.d.ts +12 -0
  84. package/dist/plugins/rsc-reference-validation-normalizer.js +48 -0
  85. package/dist/plugins/sass.d.ts +17 -1
  86. package/dist/plugins/sass.js +74 -1
  87. package/dist/plugins/styled-jsx.d.ts +16 -0
  88. package/dist/plugins/styled-jsx.js +149 -0
  89. package/dist/plugins/typeof-window.d.ts +1 -1
  90. package/dist/plugins/typeof-window.js +28 -56
  91. package/dist/routing/app-route-graph.d.ts +23 -2
  92. package/dist/routing/app-route-graph.js +138 -38
  93. package/dist/routing/file-matcher.d.ts +11 -1
  94. package/dist/routing/file-matcher.js +18 -3
  95. package/dist/routing/pages-router.js +2 -2
  96. package/dist/server/api-handler.js +9 -14
  97. package/dist/server/app-browser-action-result.d.ts +4 -1
  98. package/dist/server/app-browser-action-result.js +8 -1
  99. package/dist/server/app-browser-entry.js +198 -57
  100. package/dist/server/app-browser-interception-context.d.ts +1 -0
  101. package/dist/server/app-browser-interception-context.js +4 -2
  102. package/dist/server/app-browser-navigation-controller.d.ts +2 -0
  103. package/dist/server/app-browser-navigation-controller.js +60 -31
  104. package/dist/server/app-browser-server-action-client.d.ts +1 -1
  105. package/dist/server/app-browser-server-action-client.js +8 -7
  106. package/dist/server/app-browser-state.d.ts +12 -1
  107. package/dist/server/app-browser-state.js +25 -8
  108. package/dist/server/app-browser-visible-commit.d.ts +6 -1
  109. package/dist/server/app-browser-visible-commit.js +42 -24
  110. package/dist/server/app-elements-wire.d.ts +9 -2
  111. package/dist/server/app-elements-wire.js +8 -1
  112. package/dist/server/app-elements.d.ts +2 -2
  113. package/dist/server/app-elements.js +4 -3
  114. package/dist/server/app-fallback-renderer.d.ts +2 -1
  115. package/dist/server/app-fallback-renderer.js +10 -6
  116. package/dist/server/app-hydration-cache-publication.d.ts +11 -0
  117. package/dist/server/app-hydration-cache-publication.js +43 -0
  118. package/dist/server/app-middleware.d.ts +4 -3
  119. package/dist/server/app-middleware.js +8 -3
  120. package/dist/server/app-optimistic-routing.js +11 -4
  121. package/dist/server/app-page-boundary.js +2 -1
  122. package/dist/server/app-page-cache-finalizer.d.ts +1 -0
  123. package/dist/server/app-page-cache-finalizer.js +5 -4
  124. package/dist/server/app-page-cache-render.d.ts +1 -0
  125. package/dist/server/app-page-cache-render.js +8 -4
  126. package/dist/server/app-page-cache.d.ts +1 -0
  127. package/dist/server/app-page-cache.js +27 -7
  128. package/dist/server/app-page-dispatch.d.ts +1 -0
  129. package/dist/server/app-page-dispatch.js +26 -8
  130. package/dist/server/app-page-element-builder.d.ts +2 -1
  131. package/dist/server/app-page-element-builder.js +59 -4
  132. package/dist/server/app-page-execution.js +2 -1
  133. package/dist/server/app-page-probe.js +5 -0
  134. package/dist/server/app-page-render-identity.d.ts +2 -0
  135. package/dist/server/app-page-render-identity.js +3 -2
  136. package/dist/server/app-page-render.d.ts +2 -0
  137. package/dist/server/app-page-render.js +85 -16
  138. package/dist/server/app-page-request.d.ts +14 -0
  139. package/dist/server/app-page-request.js +69 -4
  140. package/dist/server/app-page-response.d.ts +7 -0
  141. package/dist/server/app-page-response.js +16 -4
  142. package/dist/server/app-page-route-wiring.d.ts +8 -1
  143. package/dist/server/app-page-route-wiring.js +32 -18
  144. package/dist/server/app-page-segment-state.d.ts +2 -1
  145. package/dist/server/app-page-segment-state.js +3 -1
  146. package/dist/server/app-page-stream.d.ts +7 -1
  147. package/dist/server/app-page-stream.js +3 -1
  148. package/dist/server/app-route-handler-execution.js +5 -1
  149. package/dist/server/app-route-handler-response.js +1 -0
  150. package/dist/server/app-route-handler-runtime.js +1 -1
  151. package/dist/server/app-route-tree-prefetch.d.ts +43 -0
  152. package/dist/server/app-route-tree-prefetch.js +187 -0
  153. package/dist/server/app-router-entry.js +9 -2
  154. package/dist/server/app-rsc-cache-busting.d.ts +2 -1
  155. package/dist/server/app-rsc-cache-busting.js +9 -4
  156. package/dist/server/app-rsc-handler.d.ts +7 -0
  157. package/dist/server/app-rsc-handler.js +148 -39
  158. package/dist/server/app-rsc-render-mode.d.ts +3 -2
  159. package/dist/server/app-rsc-render-mode.js +4 -1
  160. package/dist/server/app-rsc-request-normalization.d.ts +6 -6
  161. package/dist/server/app-rsc-request-normalization.js +10 -8
  162. package/dist/server/app-segment-config.d.ts +11 -0
  163. package/dist/server/app-segment-config.js +62 -6
  164. package/dist/server/app-server-action-execution.d.ts +1 -0
  165. package/dist/server/app-server-action-execution.js +61 -30
  166. package/dist/server/app-ssr-entry.d.ts +3 -0
  167. package/dist/server/app-ssr-entry.js +13 -5
  168. package/dist/server/app-ssr-stream.d.ts +7 -3
  169. package/dist/server/app-ssr-stream.js +10 -6
  170. package/dist/server/app-visited-response-cache.d.ts +6 -0
  171. package/dist/server/app-visited-response-cache.js +3 -1
  172. package/dist/server/cache-control.d.ts +3 -1
  173. package/dist/server/cache-control.js +13 -1
  174. package/dist/server/client-trace-metadata.js +26 -0
  175. package/dist/server/default-global-not-found-module.d.ts +14 -0
  176. package/dist/server/default-global-not-found-module.js +14 -0
  177. package/dist/server/dev-route-files.js +4 -0
  178. package/dist/server/dev-server.d.ts +11 -1
  179. package/dist/server/dev-server.js +94 -35
  180. package/dist/server/dev-stack-sourcemap.d.ts +1 -1
  181. package/dist/server/dev-stack-sourcemap.js +1 -1
  182. package/dist/server/fetch-handler.d.ts +2 -0
  183. package/dist/server/fetch-handler.js +18 -0
  184. package/dist/server/headers.d.ts +7 -15
  185. package/dist/server/headers.js +11 -18
  186. package/dist/server/image-optimization.d.ts +51 -1
  187. package/dist/server/image-optimization.js +52 -2
  188. package/dist/server/implicit-tags.js +1 -1
  189. package/dist/server/isr-cache.d.ts +3 -2
  190. package/dist/server/isr-cache.js +9 -5
  191. package/dist/server/metadata-routes.d.ts +3 -1
  192. package/dist/server/metadata-routes.js +12 -2
  193. package/dist/server/middleware-runtime.js +6 -1
  194. package/dist/server/navigation-planner.d.ts +1 -0
  195. package/dist/server/navigation-planner.js +14 -3
  196. package/dist/server/pages-api-route.js +2 -2
  197. package/dist/server/pages-asset-tags.d.ts +4 -6
  198. package/dist/server/pages-asset-tags.js +12 -12
  199. package/dist/server/pages-client-assets.d.ts +12 -0
  200. package/dist/server/pages-client-assets.js +10 -0
  201. package/dist/server/pages-data-route.d.ts +4 -2
  202. package/dist/server/pages-data-route.js +18 -4
  203. package/dist/server/pages-dev-module-url.d.ts +2 -1
  204. package/dist/server/pages-dev-module-url.js +6 -3
  205. package/dist/server/pages-node-compat.d.ts +19 -1
  206. package/dist/server/pages-node-compat.js +81 -4
  207. package/dist/server/pages-page-data.d.ts +33 -1
  208. package/dist/server/pages-page-data.js +62 -33
  209. package/dist/server/pages-page-handler.d.ts +2 -1
  210. package/dist/server/pages-page-handler.js +38 -19
  211. package/dist/server/pages-page-response.d.ts +8 -0
  212. package/dist/server/pages-page-response.js +7 -3
  213. package/dist/server/pages-request-pipeline.d.ts +9 -5
  214. package/dist/server/pages-request-pipeline.js +55 -7
  215. package/dist/server/pages-router-entry.d.ts +30 -0
  216. package/dist/server/pages-router-entry.js +108 -0
  217. package/dist/server/prerender-manifest.d.ts +3 -1
  218. package/dist/server/prerender-route-params.js +1 -1
  219. package/dist/server/prod-server.d.ts +5 -3
  220. package/dist/server/prod-server.js +68 -39
  221. package/dist/server/request-pipeline.js +2 -1
  222. package/dist/server/seed-cache.js +4 -4
  223. package/dist/shims/app-router-scroll-state.d.ts +1 -0
  224. package/dist/shims/app-router-scroll-state.js +1 -0
  225. package/dist/shims/app-router-scroll.js +2 -1
  226. package/dist/shims/cache-handler.js +8 -1
  227. package/dist/shims/cache.js +22 -15
  228. package/dist/shims/cdn-cache.js +1 -1
  229. package/dist/shims/dynamic-preload-chunks.js +2 -1
  230. package/dist/shims/fetch-cache.d.ts +3 -1
  231. package/dist/shims/fetch-cache.js +77 -52
  232. package/dist/shims/form.d.ts +4 -2
  233. package/dist/shims/form.js +37 -43
  234. package/dist/shims/headers.d.ts +7 -1
  235. package/dist/shims/headers.js +17 -3
  236. package/dist/shims/image.js +75 -14
  237. package/dist/shims/internal/app-prefetch-fetch-queue.d.ts +10 -0
  238. package/dist/shims/internal/app-prefetch-fetch-queue.js +61 -0
  239. package/dist/shims/internal/app-route-detection.d.ts +2 -17
  240. package/dist/shims/internal/app-route-detection.js +4 -17
  241. package/dist/shims/internal/hybrid-client-route-owner-direct.d.ts +23 -0
  242. package/dist/shims/internal/hybrid-client-route-owner-direct.js +51 -0
  243. package/dist/shims/internal/hybrid-client-route-owner.d.ts +3 -15
  244. package/dist/shims/internal/hybrid-client-route-owner.js +40 -58
  245. package/dist/shims/internal/pages-data-fetch-dedup.d.ts +10 -5
  246. package/dist/shims/internal/pages-data-fetch-dedup.js +84 -14
  247. package/dist/shims/internal/pages-data-target.d.ts +18 -12
  248. package/dist/shims/internal/pages-data-target.js +97 -13
  249. package/dist/shims/internal/pages-router-components.d.ts +7 -0
  250. package/dist/shims/internal/pages-router-components.js +13 -0
  251. package/dist/shims/layout-segment-context.d.ts +4 -1
  252. package/dist/shims/layout-segment-context.js +18 -4
  253. package/dist/shims/link.d.ts +1 -1
  254. package/dist/shims/link.js +224 -58
  255. package/dist/shims/navigation.d.ts +19 -3
  256. package/dist/shims/navigation.js +245 -47
  257. package/dist/shims/request-context.js +18 -0
  258. package/dist/shims/root-params.d.ts +15 -1
  259. package/dist/shims/root-params.js +21 -1
  260. package/dist/shims/router.d.ts +5 -7
  261. package/dist/shims/router.js +387 -102
  262. package/dist/shims/server.js +3 -2
  263. package/dist/shims/slot.js +3 -6
  264. package/dist/shims/unified-request-context.js +1 -0
  265. package/dist/typegen.js +1 -1
  266. package/dist/utils/client-runtime-metadata.d.ts +2 -18
  267. package/dist/utils/client-runtime-metadata.js +31 -22
  268. package/dist/utils/dev-stack-sourcemap-endpoint.d.ts +4 -0
  269. package/dist/{server → utils}/dev-stack-sourcemap-endpoint.js +1 -1
  270. package/dist/utils/domain-locale.d.ts +6 -3
  271. package/dist/{server → utils}/middleware-request-headers.d.ts +1 -1
  272. package/dist/{server → utils}/middleware-request-headers.js +3 -3
  273. package/dist/utils/project.d.ts +48 -2
  274. package/dist/utils/project.js +225 -4
  275. package/dist/utils/protocol-headers.d.ts +23 -0
  276. package/dist/utils/protocol-headers.js +23 -0
  277. package/dist/utils/react-version.d.ts +4 -0
  278. package/dist/utils/react-version.js +44 -0
  279. package/dist/utils/vite-version.d.ts +2 -0
  280. package/dist/utils/vite-version.js +11 -1
  281. package/package.json +47 -2
  282. package/dist/deploy.d.ts +0 -197
  283. package/dist/deploy.js +0 -1040
  284. package/dist/server/dev-stack-sourcemap-endpoint.d.ts +0 -4
  285. /package/dist/{cloudflare → packages/cloudflare}/src/utils/cache-control-metadata.js +0 -0
@@ -13,7 +13,7 @@ import { DevRecoveryBoundary, GlobalErrorBoundary, RedirectBoundary } from "../s
13
13
  import { beginAppRouterScrollIntent, consumeAppRouterScrollIntent } from "../shims/app-router-scroll-state.js";
14
14
  import { AppRouterScrollCommitProvider } from "../shims/app-router-scroll.js";
15
15
  import { BfcacheStateKeyMapContext, ElementsContext, Slot } from "../shims/slot.js";
16
- import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, createRscRequestHeaders, createRscRequestUrl, getVinextRscCompatibilityId } from "./app-rsc-cache-busting.js";
16
+ import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, createRscRequestHeaders, createRscRequestUrl, getVinextRscCompatibilityId, stripRscCacheBustingSearchParam } from "./app-rsc-cache-busting.js";
17
17
  import { getNavigationRuntime, registerNavigationRuntimeBootstrap, registerNavigationRuntimeFunctions } from "../client/navigation-runtime.js";
18
18
  import { notifyAppRouterTransitionStart } from "../client/instrumentation-client-state.js";
19
19
  import "../client/instrumentation-client.js";
@@ -22,24 +22,26 @@ import { readHistoryStatePreviousNextUrl } from "./app-history-state.js";
22
22
  import { AppBrowserMpaNavigationScheduler } from "./app-browser-mpa-navigation.js";
23
23
  import { blockDangerousStreamedRscRedirect } from "./app-browser-rsc-redirect.js";
24
24
  import { navigationPlanner } from "./navigation-planner.js";
25
- import { __basePath, appRouterInstance, commitClientNavigationState, consumePrefetchResponseForNavigation, createCachedRscResponseSnapshot, createClientNavigationRenderSnapshot, createSnapshotPathAndSearch, getClientNavigationRenderContext, getPrefetchCache, hasPrefetchCacheEntryForNavigation, invalidatePrefetchCache, pushHistoryStateWithoutNotify, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, resolvePrefetchCacheEntryMountedSlotsHeader, restoreRscResponse, saveScrollPosition, setClientParams, setMountedSlotsHeader, setPendingPathname, useRouter } from "../shims/navigation.js";
25
+ import { resolveHybridClientRewriteHref } from "../shims/internal/hybrid-client-route-owner.js";
26
+ import { DYNAMIC_NAVIGATION_CACHE_TTL, PREFETCH_CACHE_TTL, __basePath, appRouterInstance, commitClientNavigationState, consumePrefetchResponseForNavigation, createCachedRscResponseSnapshot, createClientNavigationRenderSnapshot, createSnapshotPathAndSearch, deletePrefetchResponseSnapshot, getClientNavigationRenderContext, getMountedSlotsHeader, getPrefetchCache, hasPrefetchCacheEntryForNavigation, invalidatePrefetchCache, pushHistoryStateWithoutNotify, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, resolvePrefetchCacheEntryMountedSlotsHeader, restoreRscResponse, saveScrollPosition, seedPrefetchResponseSnapshot, setClientParams, setMountedSlotsHeader, setPendingPathname, useRouter } from "../shims/navigation.js";
26
27
  import { createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap } from "./app-bfcache-identity.js";
27
- import { createDiscardedServerActionRefreshScheduler, createServerActionInitiationSnapshot } from "./app-browser-action-result.js";
28
+ import { createDiscardedServerActionRefreshScheduler, createServerActionInitiationSnapshot, resolveServerActionOperationLane } from "./app-browser-action-result.js";
28
29
  import { createClientReuseManifestHeaderFromVisibleAppState } from "./app-browser-client-reuse-manifest.js";
29
30
  import { chunksToReadableStream, createProgressiveRscStream, getVinextBrowserGlobal } from "./app-browser-stream.js";
30
- import { FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, VISITED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN, isCacheRestorableAppPayloadMetadata, resolveInterceptionContextFromPreviousNextUrl } from "./app-browser-state.js";
31
+ import { COMMITTED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN, FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, VISITED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN, isCacheRestorableAppPayloadMetadata, isCompleteAppPayloadMetadata, resolveInterceptionContextFromPreviousNextUrl } from "./app-browser-state.js";
31
32
  import { clearHardNavigationLoopGuard, createAppBrowserNavigationController, createBasePathStrippedPathAndSearch } from "./app-browser-navigation-controller.js";
32
33
  import { consumeInitialFormState, createVinextHydrateRootOptions, hydrateRootInTransition } from "./app-browser-hydration.js";
33
34
  import { AppBrowserHistoryController } from "./app-browser-history-controller.js";
34
35
  import { createVisitedResponseCacheEntry, isVisitedResponseCacheEntryFresh } from "./app-visited-response-cache.js";
35
36
  import { createPopstateRestoreHandler, restoreSynchronousPopstateScrollPosition } from "./app-browser-popstate.js";
36
37
  import { createDevOnCaughtError, createOnUncaughtError, createProdOnCaughtError, prodOnRecoverableError } from "./app-browser-error.js";
38
+ import { createHydrationCachePublication } from "./app-hydration-cache-publication.js";
37
39
  import { createOptimisticRouteTemplate, getOptimisticPrefetchSourceKey, getOptimisticRouteTemplateKey, resolveOptimisticNavigationPayload } from "./app-optimistic-routing.js";
38
40
  import { removeStylesheetLinksCoveredByInlineCss } from "./app-inline-css-client.js";
39
41
  import { createElement, startTransition, use, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
40
42
  import { flushSync } from "react-dom";
41
- import { createFromFetch, createFromReadableStream, setServerCallback } from "@vitejs/plugin-rsc/browser";
42
43
  import { createRoot, hydrateRoot } from "react-dom/client";
44
+ import { createFromFetch, createFromReadableStream, setServerCallback } from "@vitejs/plugin-rsc/browser";
43
45
  import { hasServerActions, loadServerActionClient } from "virtual:vinext-app-capabilities";
44
46
  //#region src/server/app-browser-entry.ts
45
47
  function toActionType(kind) {
@@ -123,6 +125,7 @@ function isRouterStatePromise(value) {
123
125
  }
124
126
  let latestClientParams = {};
125
127
  const visitedResponseCache = /* @__PURE__ */ new Map();
128
+ let clientNavigationCacheGeneration = 0;
126
129
  let browserRouterStateHasEverCommitted = false;
127
130
  const mpaNavigationScheduler = new AppBrowserMpaNavigationScheduler();
128
131
  const unresolvedMpaNavigation = new Promise(() => {});
@@ -135,15 +138,17 @@ function waitForRscHmrSettle(delayMs = RSC_HMR_SETTLE_DELAY_MS) {
135
138
  window.setTimeout(resolve, delayMs);
136
139
  });
137
140
  }
138
- function restoreHistoryStateSnapshot(historyState) {
139
- const navId = browserNavigationController.getActiveNavigationId();
141
+ function restoreHistoryStateSnapshot(historyState, navId, onApprovedBeforeCommit) {
140
142
  let restored = false;
141
143
  flushSync(() => {
142
144
  restored = historyController.restoreHistorySnapshot({
143
145
  historyState,
144
146
  stageClientParams,
145
147
  approveVisibleRestore: ({ state, beforeCommit }) => browserNavigationController.restoreHistorySnapshotVisibleState({
146
- beforeCommit,
148
+ beforeCommit: () => {
149
+ onApprovedBeforeCommit?.();
150
+ beforeCommit();
151
+ },
147
152
  navId,
148
153
  state,
149
154
  targetHref: window.location.href
@@ -151,7 +156,7 @@ function restoreHistoryStateSnapshot(historyState) {
151
156
  });
152
157
  });
153
158
  if (!restored) return false;
154
- commitClientNavigationState();
159
+ commitClientNavigationState(navId, { releaseSnapshot: false });
155
160
  return true;
156
161
  }
157
162
  function getBrowserRouterState() {
@@ -184,10 +189,26 @@ function clearPrefetchState() {
184
189
  optimisticRouteTemplateLearning.clear();
185
190
  }
186
191
  function clearClientNavigationCaches() {
192
+ clientNavigationCacheGeneration += 1;
187
193
  clearVisitedResponseCache();
188
194
  clearPrefetchState();
189
195
  historyController.invalidateRestorableClientState();
190
196
  }
197
+ function normalizeBrowserRscUrlForReuse(url) {
198
+ if (!url) return null;
199
+ try {
200
+ const parsed = new URL(url, window.location.origin);
201
+ stripRscCacheBustingSearchParam(parsed);
202
+ return `${parsed.pathname}${parsed.search}`;
203
+ } catch {
204
+ return null;
205
+ }
206
+ }
207
+ function isAlternatePrefetchResponseUrl(responseUrl, additionalRscUrls) {
208
+ const normalizedResponseUrl = normalizeBrowserRscUrlForReuse(responseUrl);
209
+ if (normalizedResponseUrl === null) return false;
210
+ return additionalRscUrls.some((additionalRscUrl) => normalizeBrowserRscUrlForReuse(additionalRscUrl) === normalizedResponseUrl);
211
+ }
191
212
  function isSettledPrefetchCacheEntry(entry) {
192
213
  return entry.outcome === "cache-seeded" && entry.pending === void 0 && entry.snapshot !== void 0;
193
214
  }
@@ -237,6 +258,7 @@ async function learnOptimisticRouteTemplatesFromPrefetchCache(options) {
237
258
  if (optimisticRouteTemplateSources.has(sourceKey)) continue;
238
259
  if (optimisticRouteTemplateLearning.has(sourceKey)) continue;
239
260
  if (!isSettledPrefetchCacheEntry(entry)) continue;
261
+ if (entry.prefetchKind === "route-tree") continue;
240
262
  const promise = learnOptimisticRouteTemplateFromPrefetch({
241
263
  cacheKey,
242
264
  entry,
@@ -281,7 +303,7 @@ function createNavigationCommitEffect(options) {
281
303
  commitClientNavigationState(navId);
282
304
  };
283
305
  }
284
- async function renderNavigationPayload(payload, navigationSnapshot, targetHref, navId, historyUpdateMode, params, previousNextUrl, pendingRouterState, payloadOrigin, actionType = "navigate", operationLane = "navigation", traversalIntent = null, scrollIntent = null, restoredBfcacheIds = null, reuseCurrentBfcacheIds = true, visibleCommitMode = "transition") {
306
+ async function renderNavigationPayload(payload, navigationSnapshot, targetHref, navId, historyUpdateMode, params, previousNextUrl, pendingRouterState, payloadOrigin, actionType = "navigate", operationLane = "navigation", traversalIntent = null, scrollIntent = null, restoredBfcacheIds = null, reuseCurrentBfcacheIds = true, visibleCommitMode = "transition", onCommittedState, navigationCommitKind) {
285
307
  syncServerActionHttpFallbackHead(null);
286
308
  return browserNavigationController.renderNavigationPayload({
287
309
  actionType,
@@ -300,7 +322,9 @@ async function renderNavigationPayload(payload, navigationSnapshot, targetHref,
300
322
  targetHistoryIndex: traversalIntent === null ? void 0 : traversalIntent.targetHistoryIndex,
301
323
  targetHref,
302
324
  navId,
303
- visibleCommitMode
325
+ navigationCommitKind,
326
+ visibleCommitMode,
327
+ onCommittedState
304
328
  });
305
329
  }
306
330
  async function commitSameUrlNavigatePayload(nextElements, actionInitiation, returnValue, revalidation = "none") {
@@ -341,7 +365,7 @@ function readVisitedResponseCacheCandidate(rscUrl, interceptionContext, mountedS
341
365
  navigationKind,
342
366
  now: Date.now()
343
367
  }),
344
- mountedSlotsMatch: (cached.response.mountedSlotsHeader ?? null) === mountedSlotsHeader,
368
+ mountedSlotsMatch: cached.mountedSlotsHeader === mountedSlotsHeader,
345
369
  navigationKind
346
370
  }
347
371
  };
@@ -359,20 +383,32 @@ function applyVisitedResponseCacheCandidateDecision(candidate, decision) {
359
383
  function deleteVisitedResponse(rscUrl, interceptionContext) {
360
384
  visitedResponseCache.delete(AppElementsWire.encodeCacheKey(rscUrl, interceptionContext));
361
385
  }
362
- function storeVisitedResponseSnapshot(rscUrl, interceptionContext, snapshot, params) {
386
+ function storeVisitedResponseSnapshot(rscUrl, interceptionContext, snapshot, params, prefetchFallbackTtlMs = DYNAMIC_NAVIGATION_CACHE_TTL, requestMountedSlotsHeader = snapshot.mountedSlotsHeader ?? null, elements) {
363
387
  const cacheKey = AppElementsWire.encodeCacheKey(rscUrl, interceptionContext);
364
388
  visitedResponseCache.delete(cacheKey);
365
389
  evictVisitedResponseCacheIfNeeded();
366
- const now = Date.now();
367
- visitedResponseCache.set(cacheKey, createVisitedResponseCacheEntry({
368
- now,
390
+ const entry = createVisitedResponseCacheEntry({
391
+ fallbackTtlMs: prefetchFallbackTtlMs,
392
+ elements,
393
+ now: Date.now(),
394
+ mountedSlotsHeader: requestMountedSlotsHeader,
369
395
  params,
370
396
  response: snapshot
371
- }));
397
+ });
398
+ visitedResponseCache.set(cacheKey, entry);
399
+ seedPrefetchResponseSnapshot(rscUrl, snapshot, interceptionContext, requestMountedSlotsHeader, prefetchFallbackTtlMs);
400
+ return () => {
401
+ if (visitedResponseCache.get(cacheKey) === entry) visitedResponseCache.delete(cacheKey);
402
+ deletePrefetchResponseSnapshot(rscUrl, snapshot, interceptionContext);
403
+ };
372
404
  }
373
405
  function clientNavigationSnapshotHref(snapshot) {
374
406
  return `${window.location.origin}${createSnapshotPathAndSearch(snapshot)}`;
375
407
  }
408
+ function getCurrentMatchedRoutePathname() {
409
+ const routeKey = AppElementsWire.parseElementKey(getBrowserRouterState().routeId);
410
+ return routeKey?.kind === "route" ? routeKey.path : null;
411
+ }
376
412
  function getRequestState(navigationKind, targetPathname, previousNextUrlOverride, traverseHistoryState) {
377
413
  if (previousNextUrlOverride !== void 0) return {
378
414
  interceptionContext: resolveInterceptionContextFromPreviousNextUrl(previousNextUrlOverride, __basePath),
@@ -397,6 +433,7 @@ function getRequestState(navigationKind, targetPathname, previousNextUrlOverride
397
433
  };
398
434
  const middlewareRewriteInterceptionContext = resolveMiddlewareRewriteNavigationInterceptionContext({
399
435
  basePath: __basePath,
436
+ currentMatchedPathname: getCurrentMatchedRoutePathname(),
400
437
  currentPathname: window.location.pathname,
401
438
  routeManifest: getBrowserRouteManifest(),
402
439
  targetPathname
@@ -462,7 +499,7 @@ function AppRouterRedirectBridge({ children }) {
462
499
  function decodeAppElementsPromise(payload) {
463
500
  return Promise.resolve(payload).then((elements) => AppElementsWire.decode(elements));
464
501
  }
465
- function BrowserRoot({ initialElements, initialNavigationSnapshot }) {
502
+ function BrowserRoot({ hydrationCachePublication, initialElements, initialNavigationSnapshot }) {
466
503
  const resolvedElements = use(initialElements);
467
504
  const initialMetadata = AppElementsWire.readMetadata(resolvedElements);
468
505
  const [treeStateValue, setTreeStateValue] = useState(() => ({
@@ -502,19 +539,22 @@ function BrowserRoot({ initialElements, initialNavigationSnapshot }) {
502
539
  return new Promise(() => {});
503
540
  } });
504
541
  browserRouterStateHasEverCommitted = true;
542
+ hydrationCachePublication.commit();
505
543
  return () => {
544
+ hydrationCachePublication.invalidate();
506
545
  registerNavigationRuntimeFunctions({ navigateExternal: void 0 });
507
546
  detach();
508
547
  setMountedSlotsHeader(null);
509
548
  };
510
- }, [setTreeStateValue]);
549
+ }, [hydrationCachePublication, setTreeStateValue]);
511
550
  useEffect(() => {
551
+ hydrationCachePublication.complete();
512
552
  const hydratedAt = performance.now();
513
553
  window.__VINEXT_HYDRATED_AT = hydratedAt;
514
554
  window.__NEXT_HYDRATED = true;
515
555
  window.__NEXT_HYDRATED_AT = hydratedAt;
516
556
  window.__NEXT_HYDRATED_CB?.();
517
- }, []);
557
+ }, [hydrationCachePublication]);
518
558
  useLayoutEffect(() => {
519
559
  historyController.rememberHistoryStateSnapshot(treeState);
520
560
  }, [treeState]);
@@ -522,9 +562,17 @@ function BrowserRoot({ initialElements, initialNavigationSnapshot }) {
522
562
  setWindowNextInternalSourcePage(AppElementsWire.readMetadata(treeState.elements).sourcePage);
523
563
  }, [treeState.elements]);
524
564
  useLayoutEffect(() => {
525
- setMountedSlotsHeader(getMountedSlotIdsHeader(stateRef.current.elements));
565
+ const previousMountedSlotsHeader = getMountedSlotsHeader();
566
+ const nextMountedSlotsHeader = getMountedSlotIdsHeader(stateRef.current.elements);
567
+ setMountedSlotsHeader(nextMountedSlotsHeader);
526
568
  removeStylesheetLinksCoveredByInlineCss();
527
- getNavigationRuntime()?.functions.pingVisibleLinks?.();
569
+ if (previousMountedSlotsHeader === nextMountedSlotsHeader) return;
570
+ const pingTimer = window.setTimeout(() => {
571
+ getNavigationRuntime()?.functions.pingVisibleLinks?.();
572
+ }, 0);
573
+ return () => {
574
+ window.clearTimeout(pingTimer);
575
+ };
528
576
  }, [treeState.elements]);
529
577
  useLayoutEffect(() => {
530
578
  if (treeState.renderId !== 0) return;
@@ -673,11 +721,11 @@ function registerServerActionCallback() {
673
721
  commitSameUrlNavigatePayload,
674
722
  navigationPlanner,
675
723
  performHardNavigation: (url, historyMode) => browserNavigationController.performHardNavigation(url, historyMode),
676
- renderRedirectPayload(elements, target, actionInitiation) {
724
+ renderRedirectPayload(elements, target, actionInitiation, revalidation) {
677
725
  const hashIdx = target.href.indexOf("#");
678
726
  const actionScrollIntent = beginAppRouterScrollIntent((hashIdx !== -1 ? target.href.slice(hashIdx) : "") || null);
679
727
  if (target.type === "push") saveScrollPosition();
680
- renderNavigationPayload(Promise.resolve(elements), createClientNavigationRenderSnapshot(target.href, actionInitiation.routerState.navigationSnapshot.params), target.href, actionInitiation.navigationId, target.type === "push" ? "push" : "replace", {}, null, null, FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, target.type === "push" ? "navigate" : "replace", "server-action", null, actionScrollIntent).catch(() => {
728
+ renderNavigationPayload(Promise.resolve(elements), createClientNavigationRenderSnapshot(target.href, actionInitiation.routerState.navigationSnapshot.params), target.href, actionInitiation.navigationId, target.type === "push" ? "push" : "replace", {}, null, null, FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, target.type === "push" ? "navigate" : "replace", resolveServerActionOperationLane(revalidation), null, actionScrollIntent).catch(() => {
681
729
  browserNavigationController.performHardNavigation(target.href);
682
730
  });
683
731
  },
@@ -692,32 +740,76 @@ async function main() {
692
740
  installAppNavigationFailureListeners();
693
741
  let devErrorOverlay = null;
694
742
  if (import.meta.env.DEV) {
695
- devErrorOverlay = await import("./dev-error-overlay.js");
743
+ devErrorOverlay = await import("../client/dev-error-overlay.js");
696
744
  devErrorOverlay.installDevErrorOverlay();
697
745
  devErrorOverlay.installViteHmrErrorHandler(import.meta.hot);
698
746
  devErrorOverlay.reportInitialDevServerErrors();
699
747
  }
748
+ const initialRscBootstrap = getNavigationRuntime()?.bootstrap.rsc;
700
749
  const rscStream = await readInitialRscStream();
701
750
  if (rscStream === null) return;
702
- bootstrapHydration(rscStream, devErrorOverlay);
751
+ bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap);
703
752
  }
704
- function bootstrapHydration(rscStream, devErrorOverlay) {
705
- const root = decodeAppElementsPromise(createFromReadableStream(rscStream));
753
+ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
754
+ const hydrationCachePublication = createHydrationCachePublication();
755
+ const cacheGeneration = clientNavigationCacheGeneration;
756
+ const [reactBranch, cacheBranch] = rscStream.tee();
757
+ const root = decodeAppElementsPromise(createFromReadableStream(reactBranch));
706
758
  const initialNavigationSnapshot = createClientNavigationRenderSnapshot(window.location.href, latestClientParams);
759
+ const initialParams = initialNavigationSnapshot.params;
760
+ const initialPathAndSearch = createSnapshotPathAndSearch(initialNavigationSnapshot);
761
+ const initialCacheBuffer = new Response(cacheBranch).arrayBuffer();
762
+ Promise.all([root, initialCacheBuffer]).then(async ([elements, buffer]) => {
763
+ if (cacheGeneration !== clientNavigationCacheGeneration) return;
764
+ const metadata = AppElementsWire.readMetadata(elements);
765
+ if (!isCompleteAppPayloadMetadata(metadata)) return;
766
+ const mountedSlotsHeader = getMountedSlotIdsHeader(elements);
767
+ const rscUrl = await createRscRequestUrl(initialPathAndSearch, createRscRequestHeaders({ mountedSlotsHeader }));
768
+ if (cacheGeneration !== clientNavigationCacheGeneration) return;
769
+ const snapshot = {
770
+ compatibilityIdHeader: CLIENT_RSC_COMPATIBILITY_ID,
771
+ buffer,
772
+ contentType: VINEXT_RSC_CONTENT_TYPE,
773
+ ...initialRscBootstrap?.dynamicStaleTimeSeconds !== void 0 ? { dynamicStaleTimeSeconds: initialRscBootstrap.dynamicStaleTimeSeconds } : {},
774
+ mountedSlotsHeader,
775
+ paramsHeader: encodeURIComponent(JSON.stringify(initialParams)),
776
+ renderedPathAndSearch: null,
777
+ url: rscUrl
778
+ };
779
+ const fallbackTtlMs = initialRscBootstrap?.initialCacheKind === "static" ? PREFETCH_CACHE_TTL : DYNAMIC_NAVIGATION_CACHE_TTL;
780
+ hydrationCachePublication.publish(() => {
781
+ if (cacheGeneration !== clientNavigationCacheGeneration) return () => {};
782
+ if (isCacheRestorableAppPayloadMetadata(metadata)) return storeVisitedResponseSnapshot(rscUrl, metadata.interceptionContext, snapshot, initialParams, fallbackTtlMs, mountedSlotsHeader);
783
+ return storeVisitedResponseSnapshot(rscUrl, metadata.interceptionContext, snapshot, initialParams, fallbackTtlMs, mountedSlotsHeader, elements);
784
+ });
785
+ }).catch(() => {});
707
786
  historyController.writeBootstrapHistoryMetadata();
708
- const onUncaughtError = createOnUncaughtError();
787
+ const reportUncaughtError = createOnUncaughtError();
788
+ const onUncaughtError = (...args) => {
789
+ hydrationCachePublication.fail();
790
+ reportUncaughtError(...args);
791
+ };
792
+ const onRecoverableError = (...args) => {
793
+ hydrationCachePublication.fail();
794
+ prodOnRecoverableError(...args);
795
+ };
796
+ const invalidateOnCaughtError = (handler) => ((...args) => {
797
+ hydrationCachePublication.fail();
798
+ handler(...args);
799
+ });
709
800
  const formState = consumeInitialFormState(getVinextBrowserGlobal());
710
801
  const hydrateRootOptions = import.meta.env.DEV && devErrorOverlay ? createVinextHydrateRootOptions({
711
802
  formState,
712
- onCaughtError: createDevOnCaughtError(devErrorOverlay.devOnCaughtError, onUncaughtError),
803
+ onCaughtError: invalidateOnCaughtError(createDevOnCaughtError(devErrorOverlay.devOnCaughtError, onUncaughtError)),
713
804
  onUncaughtError
714
805
  }) : createVinextHydrateRootOptions({
715
806
  formState,
716
- onCaughtError: createProdOnCaughtError(onUncaughtError),
717
- onRecoverableError: prodOnRecoverableError,
807
+ onCaughtError: invalidateOnCaughtError(createProdOnCaughtError(onUncaughtError)),
808
+ onRecoverableError,
718
809
  onUncaughtError
719
810
  });
720
811
  const children = createElement(BrowserRoot, {
812
+ hydrationCachePublication,
721
813
  initialElements: root,
722
814
  initialNavigationSnapshot
723
815
  });
@@ -739,15 +831,20 @@ function bootstrapHydration(rscStream, devErrorOverlay) {
739
831
  });
740
832
  markInitialAppRouterBootstrapHydrated();
741
833
  let activeNavigationAbortController = null;
834
+ function abortSupersededNavigation() {
835
+ activeNavigationAbortController?.abort();
836
+ activeNavigationAbortController = null;
837
+ }
742
838
  registerNavigationRuntimeFunctions({
743
839
  clearNavigationCaches: clearClientNavigationCaches,
744
840
  commitHashNavigation: (href, historyUpdateMode, scroll) => historyController.commitHashOnlyNavigation(href, historyUpdateMode, scroll),
745
841
  navigate: async function navigateRsc(href, redirectDepth = 0, navigationKind = "navigate", historyUpdateMode, previousNextUrlOverride, programmaticTransition = false, traversalIntent, scrollIntent, visibleCommitMode = "transition") {
746
- activeNavigationAbortController?.abort();
842
+ abortSupersededNavigation();
747
843
  const navigationAbortController = new AbortController();
748
844
  activeNavigationAbortController = navigationAbortController;
749
845
  let pendingRouterState = null;
750
846
  const navId = browserNavigationController.beginNavigation();
847
+ const navigationCacheGeneration = clientNavigationCacheGeneration;
751
848
  discardedServerActionRefreshScheduler.markNavigationStart();
752
849
  let currentHref = href;
753
850
  let currentHistoryMode = historyUpdateMode;
@@ -795,6 +892,8 @@ function bootstrapHydration(rscStream, devErrorOverlay) {
795
892
  renderMode: navigationKind === "refresh" ? APP_RSC_RENDER_MODE_REFRESH_PRESERVE_UI : void 0
796
893
  });
797
894
  const rscUrl = await createRscRequestUrl(url.pathname + url.search, requestHeaders);
895
+ const rewrittenNavigationHref = navigationKind === "navigate" ? resolveHybridClientRewriteHref(currentHref, __basePath) : null;
896
+ const additionalPrefetchRscUrls = rewrittenNavigationHref && rewrittenNavigationHref !== currentHref ? [await createRscRequestUrl(rewrittenNavigationHref, requestHeaders)] : [];
798
897
  const visitedResponseCandidate = shouldBypassNavigationCache ? {
799
898
  cacheKey: AppElementsWire.encodeCacheKey(rscUrl, requestInterceptionContext),
800
899
  entry: null,
@@ -811,7 +910,10 @@ function bootstrapHydration(rscStream, devErrorOverlay) {
811
910
  visitedResponse
812
911
  });
813
912
  let routeManifest = navigationKind === "navigate" ? getBrowserRouteManifest() : null;
814
- const hasPrefetchCandidate = prefetchProbeDecision.kind === "probe" && hasPrefetchCacheEntryForNavigation(rscUrl, requestInterceptionContext, mountedSlotsHeader, { notifyInvalidation: false });
913
+ const hasPrefetchCandidate = prefetchProbeDecision.kind === "probe" && hasPrefetchCacheEntryForNavigation(rscUrl, requestInterceptionContext, mountedSlotsHeader, {
914
+ additionalRscUrls: additionalPrefetchRscUrls,
915
+ notifyInvalidation: false
916
+ });
815
917
  const reuseDecision = navigationPlanner.classifyNavigationReuse({
816
918
  bypassNavigationCache: shouldBypassNavigationCache,
817
919
  navigationKind,
@@ -855,9 +957,10 @@ function bootstrapHydration(rscStream, devErrorOverlay) {
855
957
  if (!browserNavigationController.isCurrentNavigation(navId)) return;
856
958
  const cachedParams = cachedRoute.params;
857
959
  const cachedNavigationSnapshot = createClientNavigationRenderSnapshot(currentHref, cachedParams);
858
- const cachedPayload = decodeAppElementsPromise(createFromFetch(Promise.resolve(restoreRscResponse(cachedRoute.response))));
960
+ const cachedPayload = cachedRoute.elements ? Promise.resolve(cachedRoute.elements) : decodeAppElementsPromise(createFromFetch(Promise.resolve(restoreRscResponse(cachedRoute.response))));
859
961
  if (!browserNavigationController.isCurrentNavigation(navId)) return;
860
- if (await renderNavigationPayload(cachedPayload, cachedNavigationSnapshot, currentHref, navId, currentHistoryMode, cachedParams, requestPreviousNextUrl, detachedNavigationCommits ? null : pendingRouterState, VISITED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN, toActionType(navigationKind), toOperationLane(navigationKind), activeTraversalIntent, scrollIntent, restoredBfcacheIds, reuseCurrentBfcacheIds, visibleCommitMode) === "no-commit") {
962
+ if (await renderNavigationPayload(cachedPayload, cachedNavigationSnapshot, currentHref, navId, currentHistoryMode, cachedParams, requestPreviousNextUrl, detachedNavigationCommits ? null : pendingRouterState, cachedRoute.elements ? COMMITTED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN : VISITED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN, toActionType(navigationKind), toOperationLane(navigationKind), activeTraversalIntent, scrollIntent, restoredBfcacheIds, reuseCurrentBfcacheIds, visibleCommitMode) === "no-commit") {
963
+ if (!browserNavigationController.isCurrentNavigation(navId)) return;
861
964
  deleteVisitedResponse(rscUrl, requestInterceptionContext);
862
965
  continue;
863
966
  }
@@ -868,12 +971,15 @@ function bootstrapHydration(rscStream, devErrorOverlay) {
868
971
  let navResponseUrl = null;
869
972
  let fallbackReuseDecision = reuseDecision;
870
973
  if (reuseDecision.kind === "consumePrefetch") {
871
- const prefetchedResponse = await consumePrefetchResponseForNavigation(rscUrl, requestInterceptionContext, mountedSlotsHeader, { shouldConsume: () => browserNavigationController.isCurrentNavigation(navId) });
974
+ const prefetchedResponse = await consumePrefetchResponseForNavigation(rscUrl, requestInterceptionContext, mountedSlotsHeader, {
975
+ additionalRscUrls: additionalPrefetchRscUrls,
976
+ shouldConsume: () => browserNavigationController.isCurrentNavigation(navId)
977
+ });
872
978
  if (!browserNavigationController.isCurrentNavigation(navId)) return;
873
979
  if (prefetchedResponse) {
874
980
  navResponse = restoreRscResponse(prefetchedResponse, false);
875
981
  navResponseExpiresAt = prefetchedResponse.expiresAt;
876
- navResponseUrl = prefetchedResponse.url;
982
+ navResponseUrl = isAlternatePrefetchResponseUrl(prefetchedResponse.url, additionalPrefetchRscUrls) ? rscUrl : prefetchedResponse.url;
877
983
  }
878
984
  if (!navResponse) {
879
985
  routeManifest = navigationKind === "navigate" ? getBrowserRouteManifest() : null;
@@ -909,7 +1015,7 @@ function bootstrapHydration(rscStream, devErrorOverlay) {
909
1015
  if (optimisticPayload !== null) {
910
1016
  detachedNavigationCommits = true;
911
1017
  const optimisticNavigationSnapshot = createClientNavigationRenderSnapshot(currentHref, optimisticPayload.params);
912
- renderNavigationPayload(Promise.resolve(optimisticPayload.elements), optimisticNavigationSnapshot, currentHref, navId, currentHistoryMode, optimisticPayload.params, requestPreviousNextUrl, null, FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, toActionType(navigationKind), toOperationLane(navigationKind), activeTraversalIntent, scrollIntent, restoredBfcacheIds, reuseCurrentBfcacheIds, visibleCommitMode).catch((error) => {
1018
+ renderNavigationPayload(Promise.resolve(optimisticPayload.elements), optimisticNavigationSnapshot, currentHref, navId, currentHistoryMode, optimisticPayload.params, requestPreviousNextUrl, null, FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, toActionType(navigationKind), toOperationLane(navigationKind), activeTraversalIntent, scrollIntent, restoredBfcacheIds, reuseCurrentBfcacheIds, visibleCommitMode, void 0, "detached").catch((error) => {
913
1019
  if (browserNavigationController.isCurrentNavigation(navId)) console.error("[vinext] Optimistic RSC navigation error:", error);
914
1020
  });
915
1021
  }
@@ -975,21 +1081,46 @@ function bootstrapHydration(rscStream, devErrorOverlay) {
975
1081
  if (!browserNavigationController.isCurrentNavigation(navId)) return;
976
1082
  const rscPayload = decodeAppElementsPromise(createFromFetch(Promise.resolve(reactResponse)));
977
1083
  if (!browserNavigationController.isCurrentNavigation(navId)) return;
978
- if (await renderNavigationPayload(rscPayload, navigationSnapshot, currentHref, navId, currentHistoryMode, navParams, requestPreviousNextUrl, detachedNavigationCommits ? null : pendingRouterState, FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, toActionType(navigationKind), toOperationLane(navigationKind), activeTraversalIntent, scrollIntent, restoredBfcacheIds, reuseCurrentBfcacheIds, visibleCommitMode) !== "committed") return;
979
- if (!browserNavigationController.isCurrentNavigation(navId)) return;
1084
+ let committedState = null;
1085
+ if (await renderNavigationPayload(rscPayload, navigationSnapshot, currentHref, navId, currentHistoryMode, navParams, requestPreviousNextUrl, detachedNavigationCommits ? null : pendingRouterState, FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, toActionType(navigationKind), toOperationLane(navigationKind), activeTraversalIntent, scrollIntent, restoredBfcacheIds, reuseCurrentBfcacheIds, visibleCommitMode, (state) => {
1086
+ committedState = state;
1087
+ if (activeNavigationAbortController === navigationAbortController) activeNavigationAbortController = null;
1088
+ }, detachedNavigationCommits ? "authoritative" : void 0) !== "committed") return;
980
1089
  try {
981
1090
  const renderedElements = await rscPayload;
1091
+ if (navigationCacheGeneration !== clientNavigationCacheGeneration) return;
982
1092
  const metadata = AppElementsWire.readMetadata(renderedElements);
983
- if (!isCacheRestorableAppPayloadMetadata(metadata)) {
984
- cacheBufferPromise.catch(() => {});
985
- return;
986
- }
987
1093
  const cacheBuffer = await cacheBufferPromise;
988
- storeVisitedResponseSnapshot(rscUrl, resolveVisitedResponseInterceptionContext(requestInterceptionContext, metadata.interceptionContext), {
989
- ...createCachedRscResponseSnapshot(navResponse, cacheBuffer, navResponseUrl),
1094
+ if (navigationCacheGeneration !== clientNavigationCacheGeneration) return;
1095
+ const responseSnapshot = createCachedRscResponseSnapshot(navResponse, cacheBuffer, navResponseUrl);
1096
+ const { dynamicStaleTimeSeconds: _staticDynamicStaleTime, ...staticResponseSnapshot } = responseSnapshot;
1097
+ const snapshot = {
1098
+ ...isCacheRestorableAppPayloadMetadata(metadata) ? staticResponseSnapshot : {
1099
+ ...responseSnapshot,
1100
+ ...responseSnapshot.dynamicStaleTimeSeconds === void 0 && metadata.dynamicStaleTimeSeconds !== void 0 ? { dynamicStaleTimeSeconds: metadata.dynamicStaleTimeSeconds } : {}
1101
+ },
990
1102
  ...navResponseExpiresAt !== void 0 ? { expiresAt: navResponseExpiresAt } : {},
991
1103
  mountedSlotsHeader: getMountedSlotIdsHeader(renderedElements)
992
- }, navParams);
1104
+ };
1105
+ const interceptionContext = resolveVisitedResponseInterceptionContext(requestInterceptionContext, metadata.interceptionContext);
1106
+ if (isCacheRestorableAppPayloadMetadata(metadata)) {
1107
+ if (navigationCacheGeneration !== clientNavigationCacheGeneration) return;
1108
+ storeVisitedResponseSnapshot(rscUrl, interceptionContext, snapshot, navParams, PREFETCH_CACHE_TTL, mountedSlotsHeader);
1109
+ } else if (committedState !== null) {
1110
+ const state = committedState;
1111
+ const committedElements = {
1112
+ ...state.elements,
1113
+ [AppElementsWire.keys.layoutFlags]: state.layoutFlags,
1114
+ [AppElementsWire.keys.layoutIds]: state.layoutIds,
1115
+ [AppElementsWire.keys.skippedLayoutIds]: [],
1116
+ [AppElementsWire.keys.slotBindings]: state.slotBindings
1117
+ };
1118
+ if (navigationCacheGeneration !== clientNavigationCacheGeneration) return;
1119
+ storeVisitedResponseSnapshot(rscUrl, interceptionContext, snapshot, navParams, DYNAMIC_NAVIGATION_CACHE_TTL, mountedSlotsHeader, committedElements);
1120
+ } else {
1121
+ if (navigationCacheGeneration !== clientNavigationCacheGeneration) return;
1122
+ seedPrefetchResponseSnapshot(rscUrl, snapshot, interceptionContext, mountedSlotsHeader, DYNAMIC_NAVIGATION_CACHE_TTL);
1123
+ }
993
1124
  } catch {}
994
1125
  return;
995
1126
  }
@@ -1026,15 +1157,25 @@ function bootstrapHydration(rscStream, devErrorOverlay) {
1026
1157
  restorePopstateScrollPosition(event.state);
1027
1158
  return;
1028
1159
  }
1160
+ const snapshotNavigationId = browserNavigationController.beginNavigation();
1161
+ if (restoreHistoryStateSnapshot(event.state, snapshotNavigationId, () => {
1162
+ abortSupersededNavigation();
1163
+ notifyAppRouterTransitionStart(href, "traverse");
1164
+ })) {
1165
+ window.__VINEXT_RSC_PENDING__ = null;
1166
+ restoreSynchronousPopstateScrollPosition({
1167
+ getActiveNavigationId: () => browserNavigationController.getActiveNavigationId(),
1168
+ isCurrentNavigation: (navId) => browserNavigationController.isCurrentNavigation(navId),
1169
+ markScrollRestoreConsumed: (navId) => {
1170
+ synchronousPopstateScrollRestoreNavigationId = navId;
1171
+ },
1172
+ restorePopstateScrollPosition
1173
+ }, event.state);
1174
+ browserNavigationController.finalizeNavigation(snapshotNavigationId, null);
1175
+ return;
1176
+ }
1177
+ browserNavigationController.finalizeNavigation(snapshotNavigationId, null);
1029
1178
  handlePopstate(event);
1030
- if (restoreHistoryStateSnapshot(event.state)) restoreSynchronousPopstateScrollPosition({
1031
- getActiveNavigationId: () => browserNavigationController.getActiveNavigationId(),
1032
- isCurrentNavigation: (navId) => browserNavigationController.isCurrentNavigation(navId),
1033
- markScrollRestoreConsumed: (navId) => {
1034
- synchronousPopstateScrollRestoreNavigationId = navId;
1035
- },
1036
- restorePopstateScrollPosition
1037
- }, event.state);
1038
1179
  });
1039
1180
  if (import.meta.env.DEV && import.meta.hot) {
1040
1181
  const applyRscHmrUpdate = async (updateId) => {
@@ -1053,7 +1194,7 @@ function bootstrapHydration(rscStream, devErrorOverlay) {
1053
1194
  clearClientNavigationCaches();
1054
1195
  const navigationSnapshot = createClientNavigationRenderSnapshot(window.location.href, latestClientParams);
1055
1196
  devErrorOverlay?.dismissOverlay();
1056
- const hmrHeaders = createRscRequestHeaders();
1197
+ const hmrHeaders = createRscRequestHeaders({ mountedSlotsHeader: getMountedSlotIdsHeader(browserNavigationController.getBrowserRouterState().elements) });
1057
1198
  await browserNavigationController.hmrReplaceTree(decodeAppElementsPromise(createFromFetch(fetch(await createRscRequestUrl(window.location.pathname + window.location.search, hmrHeaders), { headers: hmrHeaders }))), navigationSnapshot);
1058
1199
  };
1059
1200
  const handleRscUpdate = async (updateId) => {
@@ -3,6 +3,7 @@ import { RouteManifest } from "../routing/app-route-graph.js";
3
3
  //#region src/server/app-browser-interception-context.d.ts
4
4
  type ResolveManifestNavigationInterceptionContextOptions = {
5
5
  basePath: string;
6
+ currentMatchedPathname?: string | null;
6
7
  currentPathname: string;
7
8
  routeManifest: RouteManifest | null;
8
9
  targetPathname: string;
@@ -29,13 +29,15 @@ function resolveManifestNavigationInterceptionContext(options) {
29
29
  function resolveMiddlewareRewriteNavigationInterceptionContext(options) {
30
30
  if (options.routeManifest === null) return null;
31
31
  const currentPathname = stripBasePath(options.currentPathname, options.basePath);
32
+ const currentMatchedPathname = options.currentMatchedPathname ? stripBasePath(options.currentMatchedPathname, options.basePath) : null;
32
33
  const targetPathname = stripBasePath(options.targetPathname, options.basePath);
33
34
  const sourceParts = splitPathnameForRouteMatch(currentPathname);
35
+ const matchedSourceParts = currentMatchedPathname ? splitPathnameForRouteMatch(currentMatchedPathname) : null;
34
36
  const targetParts = splitPathnameForRouteMatch(targetPathname);
35
37
  for (const interception of options.routeManifest.segmentGraph.interceptions.values()) {
36
- if (!matchRoutePatternPrefix(sourceParts, interception.sourcePatternParts)) continue;
37
38
  if (!matchRoutePatternWithOptionalDynamicSegments(targetParts, interception.targetPatternParts)) continue;
38
- return currentPathname;
39
+ if (matchRoutePatternPrefix(sourceParts, interception.sourcePatternParts)) return currentPathname;
40
+ if (currentMatchedPathname !== null && matchedSourceParts !== null && matchRoutePatternPrefix(matchedSourceParts, interception.sourcePatternParts)) return currentMatchedPathname;
39
41
  }
40
42
  return null;
41
43
  }
@@ -77,7 +77,9 @@ type BrowserNavigationController = {
77
77
  targetHistoryIndex?: number | null;
78
78
  targetHref: string;
79
79
  navId: number;
80
+ navigationCommitKind?: "authoritative" | "detached";
80
81
  visibleCommitMode?: NavigationRuntimeVisibleCommitMode;
82
+ onCommittedState?: (state: AppRouterState) => void;
81
83
  }): Promise<NavigationPayloadOutcome>;
82
84
  commitSameUrlNavigatePayload(nextElements: Promise<AppElements>, navigationSnapshot: ClientNavigationRenderSnapshot, returnValue?: {
83
85
  ok: boolean;