vinext 1.2.1 → 1.3.0

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 (212) hide show
  1. package/README.md +12 -9
  2. package/dist/build/client-build-config.d.ts +64 -3
  3. package/dist/build/client-build-config.js +131 -4
  4. package/dist/build/client-reference-groups.d.ts +163 -0
  5. package/dist/build/client-reference-groups.js +534 -0
  6. package/dist/build/module-dependency-cache.d.ts +31 -0
  7. package/dist/build/module-dependency-cache.js +51 -1
  8. package/dist/build/next-client-runtime-manifests.d.ts +10 -1
  9. package/dist/build/next-client-runtime-manifests.js +19 -4
  10. package/dist/build/nitro-public-files.d.ts +24 -0
  11. package/dist/build/nitro-public-files.js +60 -0
  12. package/dist/build/pages-client-assets-module.js +1 -1
  13. package/dist/build/prerender-paths.js +5 -2
  14. package/dist/build/server-actions-encryption-key.d.ts +23 -0
  15. package/dist/build/server-actions-encryption-key.js +101 -0
  16. package/dist/build/ssr-manifest.d.ts +3 -0
  17. package/dist/build/ssr-manifest.js +10 -1
  18. package/dist/client/client-rewrite-params.d.ts +9 -0
  19. package/dist/client/client-rewrite-params.js +20 -0
  20. package/dist/client/dev-error-overlay.js +2 -1
  21. package/dist/client/navigation-runtime.d.ts +25 -2
  22. package/dist/client/navigation-runtime.js +42 -11
  23. package/dist/client/vinext-next-data.d.ts +0 -1
  24. package/dist/config/config-matchers.d.ts +15 -40
  25. package/dist/config/config-matchers.js +183 -255
  26. package/dist/config/config-source.d.ts +34 -0
  27. package/dist/config/config-source.js +141 -0
  28. package/dist/config/header-params.d.ts +29 -0
  29. package/dist/config/header-params.js +106 -0
  30. package/dist/config/next-config.d.ts +7 -5
  31. package/dist/config/next-config.js +120 -7
  32. package/dist/entries/app-browser-entry.d.ts +14 -1
  33. package/dist/entries/app-browser-entry.js +26 -36
  34. package/dist/entries/app-rsc-entry.d.ts +2 -0
  35. package/dist/entries/app-rsc-entry.js +92 -57
  36. package/dist/entries/app-rsc-manifest.d.ts +10 -0
  37. package/dist/entries/app-rsc-manifest.js +20 -1
  38. package/dist/entries/app-ssr-entry.d.ts +4 -1
  39. package/dist/entries/app-ssr-entry.js +9 -2
  40. package/dist/entries/pages-client-entry.d.ts +1 -0
  41. package/dist/entries/pages-client-entry.js +6 -6
  42. package/dist/entries/pages-server-entry.js +17 -14
  43. package/dist/index.d.ts +11 -0
  44. package/dist/index.js +239 -83
  45. package/dist/init.js +17 -0
  46. package/dist/plugins/optimize-imports.d.ts +25 -2
  47. package/dist/plugins/optimize-imports.js +106 -20
  48. package/dist/plugins/rsc-client-reference-loaders.d.ts +45 -1
  49. package/dist/plugins/rsc-client-reference-loaders.js +336 -18
  50. package/dist/plugins/use-cache-callable.d.ts +5 -0
  51. package/dist/plugins/use-cache-callable.js +30 -8
  52. package/dist/plugins/worker-image-imports.d.ts +1 -0
  53. package/dist/plugins/worker-image-imports.js +1 -1
  54. package/dist/routing/app-route-graph.d.ts +1 -1
  55. package/dist/routing/browser-route-manifest.d.ts +43 -0
  56. package/dist/routing/browser-route-manifest.js +195 -0
  57. package/dist/routing/hashed-route-patterns.d.ts +4 -0
  58. package/dist/routing/hashed-route-patterns.js +22 -0
  59. package/dist/routing/optimistic-route-trie.d.ts +27 -0
  60. package/dist/routing/optimistic-route-trie.js +102 -0
  61. package/dist/routing/route-validation.d.ts +6 -1
  62. package/dist/routing/route-validation.js +26 -10
  63. package/dist/server/app-action-forwarding.d.ts +8 -0
  64. package/dist/server/app-action-forwarding.js +15 -1
  65. package/dist/server/app-browser-entry.js +147 -60
  66. package/dist/server/app-browser-error.d.ts +3 -1
  67. package/dist/server/app-browser-error.js +7 -2
  68. package/dist/server/app-browser-interception-context.d.ts +2 -2
  69. package/dist/server/app-browser-mpa-navigation.d.ts +1 -0
  70. package/dist/server/app-browser-mpa-navigation.js +6 -5
  71. package/dist/server/app-browser-navigation-controller.d.ts +17 -6
  72. package/dist/server/app-browser-navigation-controller.js +88 -26
  73. package/dist/server/app-browser-state.d.ts +2 -2
  74. package/dist/server/app-browser-visible-commit.d.ts +4 -4
  75. package/dist/server/app-client-reference-preloader.d.ts +23 -0
  76. package/dist/server/app-client-reference-preloader.js +30 -7
  77. package/dist/server/app-fallback-renderer.js +2 -1
  78. package/dist/server/app-middleware.d.ts +6 -0
  79. package/dist/server/app-middleware.js +8 -10
  80. package/dist/server/app-optimistic-routing.d.ts +8 -10
  81. package/dist/server/app-optimistic-routing.js +4 -95
  82. package/dist/server/app-page-boundary-render.js +8 -1
  83. package/dist/server/app-page-cache-render.js +1 -0
  84. package/dist/server/app-page-dispatch.js +2 -0
  85. package/dist/server/app-page-render.js +3 -1
  86. package/dist/server/app-page-rsc-render-status.d.ts +1 -0
  87. package/dist/server/app-page-rsc-render-status.js +1 -0
  88. package/dist/server/app-page-search-params-observation.d.ts +1 -4
  89. package/dist/server/app-page-search-params-observation.js +8 -10
  90. package/dist/server/app-page-stream.d.ts +7 -0
  91. package/dist/server/app-page-stream.js +1 -0
  92. package/dist/server/app-pages-bridge.d.ts +2 -1
  93. package/dist/server/app-pages-bridge.js +11 -7
  94. package/dist/server/app-prerender-static-params.js +3 -2
  95. package/dist/server/app-render-dependency.js +42 -2
  96. package/dist/server/app-request-stage-independent-entry.js +2 -2
  97. package/dist/server/app-response-stage-entry.js +3 -3
  98. package/dist/server/app-route-handler-dispatch.js +3 -1
  99. package/dist/server/app-route-handler-execution.d.ts +2 -0
  100. package/dist/server/app-route-handler-execution.js +9 -2
  101. package/dist/server/app-route-handler-middleware-context.d.ts +2 -1
  102. package/dist/server/app-route-handler-middleware-context.js +3 -3
  103. package/dist/server/app-route-handler-response.d.ts +2 -1
  104. package/dist/server/app-route-handler-response.js +2 -2
  105. package/dist/server/app-route-handler-runtime.d.ts +2 -0
  106. package/dist/server/app-route-handler-runtime.js +20 -3
  107. package/dist/server/app-route-module-loader.js +7 -6
  108. package/dist/server/app-route-tree.d.ts +20 -0
  109. package/dist/server/app-route-tree.js +18 -0
  110. package/dist/server/app-router-entry.js +2 -2
  111. package/dist/server/app-rsc-combined-handler.js +8 -1
  112. package/dist/server/app-rsc-errors.d.ts +7 -0
  113. package/dist/server/app-rsc-errors.js +9 -2
  114. package/dist/server/app-rsc-handler.d.ts +4 -1
  115. package/dist/server/app-rsc-handler.js +146 -130
  116. package/dist/server/app-rsc-response-finalizer.d.ts +5 -0
  117. package/dist/server/app-rsc-response-finalizer.js +4 -1
  118. package/dist/server/app-rsc-response-stage.js +3 -1
  119. package/dist/server/app-rsc-route-matching.d.ts +1 -0
  120. package/dist/server/app-rsc-route-matching.js +1 -1
  121. package/dist/server/app-server-action-execution.d.ts +23 -6
  122. package/dist/server/app-server-action-execution.js +50 -56
  123. package/dist/server/app-ssr-entry.d.ts +6 -0
  124. package/dist/server/app-ssr-entry.js +16 -7
  125. package/dist/server/app-ssr-stream.d.ts +7 -0
  126. package/dist/server/app-ssr-stream.js +13 -1
  127. package/dist/server/config-headers.js +12 -3
  128. package/dist/server/isolate-shared-promise.d.ts +10 -0
  129. package/dist/server/isolate-shared-promise.js +33 -0
  130. package/dist/server/isr-cache.js +3 -2
  131. package/dist/server/middleware-matcher-pattern.d.ts +0 -1
  132. package/dist/server/middleware-matcher-pattern.js +11 -140
  133. package/dist/server/middleware-matcher.js +5 -6
  134. package/dist/server/middleware-response-headers.d.ts +31 -0
  135. package/dist/server/middleware-response-headers.js +57 -1
  136. package/dist/server/middleware-runtime.js +26 -13
  137. package/dist/server/navigation-planner.d.ts +2 -2
  138. package/dist/server/nitro-public-files-plugin.d.ts +38 -0
  139. package/dist/server/nitro-public-files-plugin.js +106 -0
  140. package/dist/server/nitro-public-files.d.ts +21 -0
  141. package/dist/server/nitro-public-files.js +39 -0
  142. package/dist/server/pages-asset-tags.d.ts +5 -0
  143. package/dist/server/pages-asset-tags.js +9 -2
  144. package/dist/server/pages-client-assets.d.ts +4 -1
  145. package/dist/server/pages-i18n.d.ts +18 -0
  146. package/dist/server/pages-i18n.js +18 -2
  147. package/dist/server/pages-node-compat.d.ts +5 -3
  148. package/dist/server/pages-node-compat.js +35 -16
  149. package/dist/server/pages-request-pipeline.d.ts +6 -1
  150. package/dist/server/pages-request-pipeline.js +31 -35
  151. package/dist/server/pages-request-stage-entry.js +16 -6
  152. package/dist/server/pages-response-stage-entry.js +1 -1
  153. package/dist/server/pages-revalidate.js +1 -0
  154. package/dist/server/pages-router-entry.js +1 -1
  155. package/dist/server/prod-server.d.ts +2 -2
  156. package/dist/server/prod-server.js +71 -33
  157. package/dist/server/proxy-trust.d.ts +6 -0
  158. package/dist/server/proxy-trust.js +12 -6
  159. package/dist/server/request-pipeline.d.ts +5 -0
  160. package/dist/server/request-pipeline.js +12 -1
  161. package/dist/server/server-reference-loader.js +10 -1
  162. package/dist/server/static-file-cache.js +15 -3
  163. package/dist/server/worker-utils.js +1 -1
  164. package/dist/shims/cache-handler.js +3 -2
  165. package/dist/shims/cache-request-state.d.ts +40 -3
  166. package/dist/shims/cache-request-state.js +70 -5
  167. package/dist/shims/cache-runtime.js +47 -19
  168. package/dist/shims/cache.d.ts +2 -2
  169. package/dist/shims/cache.js +17 -8
  170. package/dist/shims/cdn-purge-routes.d.ts +24 -0
  171. package/dist/shims/cdn-purge-routes.js +77 -0
  172. package/dist/shims/dynamic.js +17 -4
  173. package/dist/shims/form.js +8 -3
  174. package/dist/shims/image-props.d.ts +93 -0
  175. package/dist/shims/image-props.js +323 -0
  176. package/dist/shims/image.d.ts +4 -18
  177. package/dist/shims/image.js +4 -319
  178. package/dist/shims/internal/headers-state.d.ts +7 -0
  179. package/dist/shims/internal/headers-state.js +14 -2
  180. package/dist/shims/internal/hybrid-client-route-owner-direct.d.ts +4 -1
  181. package/dist/shims/internal/hybrid-client-route-owner-direct.js +31 -14
  182. package/dist/shims/internal/hybrid-client-route-owner.js +8 -8
  183. package/dist/shims/link.js +5 -3
  184. package/dist/shims/navigation.d.ts +1 -1
  185. package/dist/shims/navigation.js +17 -5
  186. package/dist/shims/og.js +35 -10
  187. package/dist/shims/request-context.d.ts +13 -0
  188. package/dist/shims/router.js +19 -40
  189. package/dist/shims/server.d.ts +31 -4
  190. package/dist/shims/server.js +58 -10
  191. package/dist/shims/thenable-params.d.ts +6 -1
  192. package/dist/shims/thenable-params.js +11 -2
  193. package/dist/shims/unified-request-context.d.ts +5 -0
  194. package/dist/shims/unified-request-context.js +2 -0
  195. package/dist/utils/asset-prefix.d.ts +7 -0
  196. package/dist/utils/asset-prefix.js +10 -1
  197. package/dist/utils/client-build-manifest.js +12 -5
  198. package/dist/utils/client-runtime-metadata.d.ts +1 -0
  199. package/dist/utils/client-runtime-metadata.js +15 -2
  200. package/dist/utils/lazy-chunks.d.ts +4 -0
  201. package/dist/utils/manifest-paths.d.ts +14 -0
  202. package/dist/utils/manifest-paths.js +22 -1
  203. package/dist/utils/path-to-regexp.d.ts +21 -0
  204. package/dist/{server/middleware-path-to-regexp.js → utils/path-to-regexp.js} +14 -11
  205. package/dist/utils/plugin-react-version.d.ts +15 -0
  206. package/dist/utils/plugin-react-version.js +64 -0
  207. package/dist/utils/public-routes.d.ts +2 -0
  208. package/dist/utils/public-routes.js +18 -7
  209. package/package.json +1 -1
  210. package/dist/server/middleware-path-to-regexp.d.ts +0 -13
  211. package/dist/utils/regex-safety.d.ts +0 -17
  212. package/dist/utils/regex-safety.js +0 -789
@@ -14,11 +14,11 @@ import { clearAppNavigationFailureTarget, installAppNavigationFailureListeners }
14
14
  import { DevRecoveryBoundary, GlobalErrorBoundary, RedirectBoundary } from "../shims/error-boundary.js";
15
15
  import { beginAppRouterScrollIntent, consumeAppRouterScrollIntent } from "../shims/app-router-scroll-state.js";
16
16
  import { AppRouterScrollCommitProvider } from "../shims/app-router-scroll.js";
17
- import { BfcacheIdentityMapContext, ElementsContext, Slot, bindAppElementsRenderedSearch, setAppElementsRenderedSearch } from "../shims/slot.js";
18
- import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, createRscRequestHeaders, createRscRequestUrl, formatRscRequestPath, getVinextRscCompatibilityId } from "./app-rsc-cache-busting.js";
17
+ import { BfcacheIdentityMapContext, bindAppElementsRenderedSearch, setAppElementsRenderedSearch } from "../shims/slot.js";
18
+ import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, createRscRequestHeaders, createRscRequestUrl, formatRscRequestPath } from "./app-rsc-cache-busting.js";
19
19
  import { notifyAppRouterTransitionStart } from "../client/instrumentation-client-state.js";
20
20
  import "../client/instrumentation-client.js";
21
- import { getNavigationRuntime, registerNavigationRuntimeBootstrap, registerNavigationRuntimeFunctions } from "../client/navigation-runtime.js";
21
+ import { createNavigationRuntimeRouteManifestLoader, getNavigationRuntime, loadNavigationRuntimeRouteManifest, registerNavigationRuntimeBootstrap, registerNavigationRuntimeFunctions } from "../client/navigation-runtime.js";
22
22
  import { createBfcacheSegmentIdentityMap, createInitialBfcacheIdMap } from "./app-bfcache-identity.js";
23
23
  import { createDiscardedServerActionRefreshScheduler, createServerActionInitiationSnapshot, resolveServerActionOperationLane } from "./app-browser-action-result.js";
24
24
  import { createClientReuseManifestHeaderFromVisibleAppState } from "./app-browser-client-reuse-manifest.js";
@@ -31,7 +31,8 @@ import { navigationPlanner } from "./navigation-planner.js";
31
31
  import { DYNAMIC_NAVIGATION_CACHE_TTL, PREFETCH_CACHE_TTL, __basePath, appRouterInstance, commitClientNavigationState, consumePrefetchResponse, consumePrefetchResponseForNavigation, createCachedRscResponseSnapshot, createClientNavigationRenderSnapshot, createSnapshotPathAndSearch, deletePrefetchResponseSnapshot, disableNavigationResponsePrefetchCacheReuse, getClientNavigationRenderContext, getMountedSlotsHeader, getPrefetchCache, hasPrefetchCacheEntryForNavigation, invalidatePrefetchCache, parseRenderedPathAndSearchHeader, preloadHybridClientRouteOwner, pushHistoryStateWithoutNotify, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, resolveLoadedHybridClientRewriteHref, resolvePrefetchCacheEntryMountedSlotsHeader, restoreRscResponse, saveScrollPosition, seedPrefetchResponseSnapshot, setClientParams, setMountedSlotsHeader, setPendingPathname, useRouter } from "../shims/navigation.js";
32
32
  import { chunksToReadableStream, createProgressiveRscStream, getVinextBrowserGlobal } from "./app-browser-stream.js";
33
33
  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";
34
- import { clearHardNavigationLoopGuard, createAppBrowserNavigationController, createBasePathStrippedPathAndSearch } from "./app-browser-navigation-controller.js";
34
+ import { clearHardNavigationLoopGuard, createAppBrowserNavigationController, createBasePathStrippedPathAndSearch, navigateDocumentDirectly } from "./app-browser-navigation-controller.js";
35
+ import { createAppRouteTree } from "./app-route-tree.js";
35
36
  import { shouldRecoverSamePathSearchCommitOnResponseCompletion } from "./app-browser-navigation-response.js";
36
37
  import { createSupplementalRefreshCoordinator, mergeRefreshedParallelSlot, requireCompleteSupplementalRefresh, resolvePersistedSourcePageRefreshes, resolveServerActionSupplementalRefresh, resolveSupplementalRefreshes } from "./app-browser-supplemental-refresh.js";
37
38
  import { createAppBrowserNavigationAbortCoordinator } from "./app-browser-navigation-abort.js";
@@ -42,7 +43,7 @@ import { createPopstateRestoreHandler, restoreSynchronousPopstateScrollPosition,
42
43
  import { createDevOnCaughtError, createOnUncaughtError, createProdOnCaughtError, createProdOnRecoverableError } from "./app-browser-error.js";
43
44
  import { createHydrationCachePublication } from "./app-hydration-cache-publication.js";
44
45
  import { peekSettledPrefetchResponseForNavigation, prepareConsumedPrefetchResponseForPublication, preserveCommittedPrefetchExpiry, resolvePrefetchNavigationResponseUrl } from "./app-browser-prefetch-response.js";
45
- import { canCommitOptimisticRouteTemplate, createOptimisticRouteTemplate, getOptimisticPrefetchSourceKey, getOptimisticRouteTemplateKey, matchOptimisticRouteManifestRoute, resolveOptimisticNavigationParamsForHref, resolveOptimisticNavigationPayload } from "./app-optimistic-routing.js";
46
+ import { canCommitOptimisticRouteTemplate, createOptimisticRouteTemplate, getOptimisticPrefetchSourceKey, getOptimisticRouteTemplateKey, resolveOptimisticNavigationParamsForHref, resolveOptimisticNavigationPayload } from "./app-optimistic-routing.js";
46
47
  import { removeStylesheetLinksCoveredByInlineCss } from "./app-inline-css-client.js";
47
48
  import { createElement, startTransition, use, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
48
49
  import { flushSync } from "react-dom";
@@ -64,8 +65,12 @@ function toOperationLane(kind) {
64
65
  }
65
66
  const MAX_VISITED_RESPONSE_CACHE_SIZE = 50;
66
67
  const IS_STATIC_EXPORT = process.env.NODE_ENV === "production" && process.env.__NEXT_CONFIG_OUTPUT === "export";
67
- const CLIENT_DEPLOYMENT_VERSION = process.env.__VINEXT_BUILD_ID ?? null;
68
- const CLIENT_RSC_COMPATIBILITY_ID = IS_STATIC_EXPORT ? null : getVinextRscCompatibilityId();
68
+ let clientDeploymentVersion = null;
69
+ let clientRscCompatibilityId = IS_STATIC_EXPORT ? null : "vinext:missing";
70
+ function setClientRscCompatibilityId(compatibilityId) {
71
+ if (IS_STATIC_EXPORT || !compatibilityId) return;
72
+ clientRscCompatibilityId = compatibilityId;
73
+ }
69
74
  const optimisticRouteTemplates = /* @__PURE__ */ new Map();
70
75
  const optimisticRouteTemplateSources = /* @__PURE__ */ new Set();
71
76
  const optimisticRouteTemplateLearning = /* @__PURE__ */ new Map();
@@ -77,6 +82,7 @@ function claimInitialAppRouterBootstrap() {
77
82
  function markInitialAppRouterBootstrapHydrated() {
78
83
  window.__VINEXT_RSC_BOOTSTRAP_STATE__ = "hydrated";
79
84
  }
85
+ registerNavigationRuntimeFunctions({ loadRouteManifest: createNavigationRuntimeRouteManifestLoader(() => import("virtual:vinext-app-route-manifest")) });
80
86
  function getBrowserRouteManifest() {
81
87
  return getNavigationRuntime()?.bootstrap.routeManifest ?? null;
82
88
  }
@@ -92,7 +98,7 @@ function resolveStaticExportRouteParams(href) {
92
98
  function isStaticExportPayloadDeploymentCompatible(elements) {
93
99
  if (!IS_STATIC_EXPORT) return true;
94
100
  const deploymentVersion = AppElementsWire.readMetadata(elements).artifactCompatibility.deploymentVersion;
95
- return CLIENT_DEPLOYMENT_VERSION !== null && deploymentVersion === CLIENT_DEPLOYMENT_VERSION;
101
+ return clientDeploymentVersion !== null && deploymentVersion === clientDeploymentVersion;
96
102
  }
97
103
  const historyController = new AppBrowserHistoryController({
98
104
  initialHistoryState: window.history.state,
@@ -114,6 +120,14 @@ const historyController = new AppBrowserHistoryController({
114
120
  const browserNavigationController = createAppBrowserNavigationController({
115
121
  basePath: __basePath,
116
122
  getRouteManifest: getBrowserRouteManifest,
123
+ loadRouteManifest: loadNavigationRuntimeRouteManifest,
124
+ navigateDocument: (href, mode) => {
125
+ if (mpaNavigationTree) {
126
+ mpaNavigationTree.enter(href, mode === "replace" ? "replace" : "push");
127
+ return;
128
+ }
129
+ navigateDocumentDirectly(href, mode);
130
+ },
117
131
  syncHistoryStatePreviousNextUrl: (previousNextUrl, bfcacheIds) => historyController.syncCurrentHistoryStatePreviousNextUrl(previousNextUrl, bfcacheIds)
118
132
  });
119
133
  const discardedServerActionRefreshScheduler = hasServerActions ? createDiscardedServerActionRefreshScheduler({ runRefresh() {
@@ -126,6 +140,7 @@ const discardedServerActionRefreshScheduler = hasServerActions ? createDiscarded
126
140
  };
127
141
  const serverActionSupplementalRefreshCoordinator = createSupplementalRefreshCoordinator();
128
142
  const NavigationCommitSignal = browserNavigationController.NavigationCommitSignal;
143
+ const NavigationHistoryCommit = browserNavigationController.NavigationHistoryCommit;
129
144
  const ACTION_HTTP_FALLBACK_ROBOTS_META_ATTR = "data-vinext-action-http-fallback";
130
145
  function syncServerActionHttpFallbackHead(status) {
131
146
  document.head.querySelectorAll(`meta[${ACTION_HTTP_FALLBACK_ROBOTS_META_ATTR}="robots"]`).forEach((node) => node.remove());
@@ -155,6 +170,20 @@ let browserRouterStateHasEverCommitted = false;
155
170
  let initialPrefetchRouterState = null;
156
171
  const mpaNavigationScheduler = new AppBrowserMpaNavigationScheduler();
157
172
  const unresolvedMpaNavigation = new Promise(() => {});
173
+ let mpaNavigationTree = null;
174
+ let mpaNavigationRestore = null;
175
+ function waitForMpaNavigationRestore() {
176
+ if (!mpaNavigationRestore) {
177
+ let resolve = () => {};
178
+ mpaNavigationRestore = {
179
+ promise: new Promise((resolvePromise) => {
180
+ resolve = resolvePromise;
181
+ }),
182
+ resolve
183
+ };
184
+ }
185
+ return mpaNavigationRestore.promise;
186
+ }
158
187
  const RSC_HMR_SETTLE_DELAY_MS = 150;
159
188
  const DEFAULT_GLOBAL_ERROR_COMPONENT = DefaultGlobalError;
160
189
  let latestRscHmrUpdateId = 0;
@@ -362,22 +391,29 @@ function createActionInitiationSnapshot() {
362
391
  }
363
392
  function createNavigationCommitEffect(options) {
364
393
  const { activeRoutePaths, bfcacheIds, href, historyUpdateMode, navId, params, previousNextUrl, targetHistoryIndex } = options;
365
- return ({ keepCurrentUrl, releaseSnapshot }) => {
366
- if (!browserNavigationController.isCurrentNavigation(navId)) {
367
- commitClientNavigationState(void 0, { releaseSnapshot });
368
- return;
394
+ let wroteHistory = false;
395
+ return {
396
+ writeHistory({ keepCurrentUrl }) {
397
+ if (!browserNavigationController.isCurrentNavigation(navId)) return;
398
+ historyController.commitNavigationHistory({
399
+ activeRoutePaths,
400
+ bfcacheIds,
401
+ href,
402
+ historyUpdateMode: keepCurrentUrl ? void 0 : historyUpdateMode,
403
+ previousNextUrl,
404
+ stageClientParams: () => stageClientParams(params),
405
+ targetHistoryIndex
406
+ });
407
+ wroteHistory = true;
408
+ },
409
+ publish({ releaseSnapshot }) {
410
+ if (!wroteHistory) {
411
+ commitClientNavigationState(void 0, { releaseSnapshot });
412
+ return;
413
+ }
414
+ clearAppNavigationFailureTarget(href);
415
+ commitClientNavigationState(navId, { releaseSnapshot });
369
416
  }
370
- historyController.commitNavigationHistory({
371
- activeRoutePaths,
372
- bfcacheIds,
373
- href,
374
- historyUpdateMode: keepCurrentUrl ? void 0 : historyUpdateMode,
375
- previousNextUrl,
376
- stageClientParams: () => stageClientParams(params),
377
- targetHistoryIndex
378
- });
379
- clearAppNavigationFailureTarget(href);
380
- commitClientNavigationState(navId, { releaseSnapshot });
381
417
  };
382
418
  }
383
419
  async function renderNavigationPayload(options) {
@@ -409,7 +445,16 @@ async function renderNavigationPayload(options) {
409
445
  async function commitSameUrlNavigatePayload(nextElements, actionInitiation, returnValue, revalidation = "none", renderedPathAndSearch = null) {
410
446
  let shouldRetrySupplementalRefresh = false;
411
447
  let supplementalHandle = null;
448
+ let routeManifestLoaded = true;
412
449
  if (revalidation !== "none") {
450
+ const routeManifestLoad = loadNavigationRuntimeRouteManifest();
451
+ if (routeManifestLoad !== null) routeManifestLoaded = await routeManifestLoad;
452
+ if (!routeManifestLoaded && browserNavigationController.isCurrentNavigation(actionInitiation.navigationId)) {
453
+ browserNavigationController.performHardNavigation(actionInitiation.href);
454
+ return;
455
+ }
456
+ }
457
+ if (revalidation !== "none" && routeManifestLoaded) {
413
458
  const refreshUrl = new URL(actionInitiation.href);
414
459
  const requestInterceptionContext = resolveInterceptionContextFromPreviousNextUrl(actionInitiation.routerState.previousNextUrl, __basePath);
415
460
  const persistedInterceptions = resolvePersistedRefreshInterceptions(actionInitiation.routerState, getBrowserRouteManifest(), refreshUrl, requestInterceptionContext);
@@ -656,23 +701,40 @@ function BrowserRoot({ hydrationCachePublication, initialElements, initialNaviga
656
701
  const treeState = isRouterStatePromise(treeStateValue) ? use(treeStateValue) : treeStateValue;
657
702
  const stateRef = useRef(treeState);
658
703
  stateRef.current = treeState;
704
+ const committedStateRef = useRef(treeState);
705
+ useLayoutEffect(() => {
706
+ committedStateRef.current = treeState;
707
+ }, [treeState]);
659
708
  useLayoutEffect(() => {
660
709
  const setAppRouterStateValue = (value) => {
661
710
  setTreeStateValue(value);
662
711
  };
663
712
  const detach = browserNavigationController.attachBrowserRouterState(setAppRouterStateValue, stateRef);
664
- registerNavigationRuntimeFunctions({ navigateExternal: (href, historyUpdateMode) => {
665
- setTreeStateValue({
666
- href,
667
- historyUpdateMode,
668
- kind: "mpa-navigation"
713
+ const setMpaNavigationState = (href, historyUpdateMode) => {
714
+ startTransition(() => {
715
+ setTreeStateValue({
716
+ href,
717
+ historyUpdateMode,
718
+ kind: "mpa-navigation"
719
+ });
669
720
  });
670
- return new Promise(() => {});
721
+ };
722
+ const currentMpaNavigationTree = {
723
+ enter: setMpaNavigationState,
724
+ restore() {
725
+ setTreeStateValue((current) => isMpaNavigationState(current) ? committedStateRef.current : current);
726
+ }
727
+ };
728
+ mpaNavigationTree = currentMpaNavigationTree;
729
+ registerNavigationRuntimeFunctions({ navigateExternal: (href, historyUpdateMode) => {
730
+ setMpaNavigationState(href, historyUpdateMode);
731
+ return waitForMpaNavigationRestore();
671
732
  } });
672
733
  browserRouterStateHasEverCommitted = true;
673
734
  hydrationCachePublication.commit();
674
735
  return () => {
675
736
  hydrationCachePublication.invalidate();
737
+ if (mpaNavigationTree === currentMpaNavigationTree) mpaNavigationTree = null;
676
738
  registerNavigationRuntimeFunctions({ navigateExternal: void 0 });
677
739
  detach();
678
740
  setMountedSlotsHeader(null);
@@ -718,7 +780,11 @@ function BrowserRoot({ hydrationCachePublication, initialElements, initialNaviga
718
780
  treeState.renderId,
719
781
  treeState.slotBindings
720
782
  ]);
721
- const routeTree = createElement(RedirectBoundary, null, createElement(NavigationCommitSignal, { renderId: treeState.renderId }, createElement(ElementsContext.Provider, { value: treeState.elements }, createElement(Slot, { id: treeState.routeId }))));
783
+ const routeTree = createElement(RedirectBoundary, null, createElement(NavigationCommitSignal, { renderId: treeState.renderId }, createAppRouteTree({
784
+ elements: treeState.elements,
785
+ historyCommit: createElement(NavigationHistoryCommit, { renderId: treeState.renderId }),
786
+ routeId: treeState.routeId
787
+ })));
722
788
  const bfcacheSegmentIdentities = useMemo(() => createBfcacheSegmentIdentityMap({ elements: treeState.elements }), [treeState.elements]);
723
789
  const identityMapTree = createElement(BfcacheIdentityMapContext.Provider, { value: bfcacheSegmentIdentities }, routeTree);
724
790
  const bfcacheTree = BfcacheIdMapContext ? createElement(BfcacheIdMapContext.Provider, { value: treeState.bfcacheIds }, identityMapTree) : identityMapTree;
@@ -863,6 +929,7 @@ async function readInitialRscStream() {
863
929
  if (!rscResponse.body) return recoverFromBadInitialRscResponse("returned empty body");
864
930
  clearReloadFlag();
865
931
  clearHardNavigationLoopGuard();
932
+ setClientRscCompatibilityId(rscResponse.headers.get(VINEXT_RSC_COMPATIBILITY_ID_HEADER));
866
933
  const parsedParams = parseEncodedJsonHeader(rscResponse.headers.get(VINEXT_PARAMS_HEADER));
867
934
  const params = parsedParams ?? {};
868
935
  if (parsedParams) try {
@@ -873,6 +940,7 @@ async function readInitialRscStream() {
873
940
  return rscResponse.body;
874
941
  }
875
942
  function applyRuntimeRscBootstrap(rsc) {
943
+ setClientRscCompatibilityId(rsc.compatibilityId);
876
944
  const params = rsc.params ?? {};
877
945
  if (rsc.params) applyClientParams(rsc.params);
878
946
  if (rsc.nav) restoreEmbeddedHydrationNavigationContext(rsc.nav.pathname, rsc.nav.searchParams, params, rsc.searchParamsFromBrowser === true);
@@ -884,7 +952,7 @@ function registerServerActionCallback() {
884
952
  return loadServerActionClient().then(({ invokeClientServerAction }) => invokeClientServerAction(id, args, actionInitiation, {
885
953
  basePath: __basePath,
886
954
  clearClientNavigationCaches,
887
- clientRscCompatibilityId: CLIENT_RSC_COMPATIBILITY_ID,
955
+ clientRscCompatibilityId,
888
956
  commitSameUrlNavigatePayload,
889
957
  navigationPlanner,
890
958
  performHardNavigation: (url, historyMode) => browserNavigationController.performHardNavigation(url, historyMode),
@@ -919,6 +987,7 @@ function registerServerActionCallback() {
919
987
  }
920
988
  async function main() {
921
989
  if (!claimInitialAppRouterBootstrap()) return;
990
+ loadNavigationRuntimeRouteManifest();
922
991
  if (hasServerActions) registerServerActionCallback();
923
992
  installAppNavigationFailureListeners();
924
993
  if (HAS_CLIENT_REWRITES) await preloadHybridClientRouteOwner();
@@ -939,27 +1008,28 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
939
1008
  const cacheGeneration = clientNavigationCacheGeneration;
940
1009
  const [reactBranch, cacheBranch] = rscStream.tee();
941
1010
  const initialNavigationSnapshot = withLateRenderedSearch(createClientNavigationRenderSnapshot(window.location.href, latestClientParams, getHydrationRenderedPathAndSearch()), initialRscBootstrap);
1011
+ const initialPathAndSearch = createSnapshotPathAndSearch(initialNavigationSnapshot);
942
1012
  const root = decodeAppElementsPromise(createFromReadableStream(reactBranch)).then((elements) => {
1013
+ if (IS_STATIC_EXPORT) clientDeploymentVersion = AppElementsWire.readMetadata(elements).artifactCompatibility.deploymentVersion;
943
1014
  bindAppElementsRenderedSearch(elements, initialNavigationSnapshot);
1015
+ initialPrefetchRouterState = {
1016
+ pathAndSearch: initialPathAndSearch,
1017
+ routeId: AppElementsWire.readMetadata(elements).routeId
1018
+ };
944
1019
  return elements;
945
1020
  });
946
1021
  const initialParams = initialNavigationSnapshot.params;
947
- const initialPathAndSearch = createSnapshotPathAndSearch(initialNavigationSnapshot);
948
1022
  const initialCacheBuffer = new Response(cacheBranch).arrayBuffer();
949
1023
  Promise.all([root, initialCacheBuffer]).then(async ([elements, buffer]) => {
950
1024
  if (cacheGeneration !== clientNavigationCacheGeneration) return;
951
1025
  const metadata = AppElementsWire.readMetadata(elements);
952
- initialPrefetchRouterState = {
953
- pathAndSearch: initialPathAndSearch,
954
- routeId: metadata.routeId
955
- };
956
1026
  if (!isCompleteAppPayloadMetadata(metadata)) return;
957
1027
  const mountedSlotsHeader = getMountedSlotIdsHeader(elements);
958
1028
  const headers = createRscRequestHeaders({ mountedSlotsHeader });
959
1029
  const rscUrl = await createRscRequestUrl(initialPathAndSearch, headers);
960
1030
  if (cacheGeneration !== clientNavigationCacheGeneration) return;
961
1031
  const snapshot = {
962
- compatibilityIdHeader: CLIENT_RSC_COMPATIBILITY_ID,
1032
+ compatibilityIdHeader: clientRscCompatibilityId,
963
1033
  buffer,
964
1034
  contentType: VINEXT_RSC_CONTENT_TYPE,
965
1035
  ...initialRscBootstrap?.dynamicStaleTimeSeconds !== void 0 ? { dynamicStaleTimeSeconds: initialRscBootstrap.dynamicStaleTimeSeconds } : {},
@@ -979,7 +1049,7 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
979
1049
  });
980
1050
  }).catch(() => {});
981
1051
  historyController.writeBootstrapHistoryMetadata();
982
- const reportUncaughtError = createOnUncaughtError();
1052
+ const reportUncaughtError = createOnUncaughtError({ coerceToError: import.meta.env.DEV });
983
1053
  const onUncaughtError = (...args) => {
984
1054
  hydrationCachePublication.fail();
985
1055
  reportUncaughtError(...args);
@@ -1029,19 +1099,7 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
1029
1099
  clearNavigationCaches: clearClientNavigationCaches,
1030
1100
  commitHashNavigation: (href, historyUpdateMode, scroll) => historyController.commitHashOnlyNavigation(href, historyUpdateMode, scroll),
1031
1101
  getPrefetchRouterState: () => {
1032
- if (!browserNavigationController.hasBrowserRouterState()) {
1033
- if (initialPrefetchRouterState) return initialPrefetchRouterState;
1034
- const routeManifest = getNavigationRuntime()?.bootstrap.routeManifest ?? null;
1035
- const match = routeManifest ? matchOptimisticRouteManifestRoute({
1036
- basePath: __basePath,
1037
- href: window.location.href,
1038
- routeManifest
1039
- }) : null;
1040
- return match ? {
1041
- pathAndSearch: createBasePathStrippedPathAndSearch(new URL(window.location.href), __basePath),
1042
- routeId: match.route.id
1043
- } : null;
1044
- }
1102
+ if (!browserNavigationController.hasBrowserRouterState()) return initialPrefetchRouterState;
1045
1103
  const state = browserNavigationController.getBrowserRouterState();
1046
1104
  return {
1047
1105
  pathAndSearch: createSnapshotPathAndSearch(state.navigationSnapshot),
@@ -1061,10 +1119,14 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
1061
1119
  let redirectCount = redirectDepth;
1062
1120
  let detachedNavigationCommits = false;
1063
1121
  const activeTraversalIntent = navigationKind === "traverse" ? traversalIntent ?? historyController.resolveTraversalIntent(window.history.state) : null;
1122
+ let startedHardNavigation = false;
1064
1123
  const performHardNavigationForScrollIntent = (targetHref, mode) => {
1065
1124
  consumeAppRouterScrollIntent(scrollIntent ?? null);
1066
- const didNavigate = browserNavigationController.performHardNavigation(targetHref, mode);
1067
- if (!didNavigate) clearAppNavigationFailureTarget(targetHref);
1125
+ const didNavigate = browserNavigationController.performHardNavigation(targetHref, mode ?? (currentHistoryMode === "push" ? "assign" : "replace"));
1126
+ if (didNavigate) {
1127
+ startedHardNavigation = true;
1128
+ browserNavigationController.abandonPendingBrowserRouterState(pendingRouterState);
1129
+ } else clearAppNavigationFailureTarget(targetHref);
1068
1130
  return didNavigate;
1069
1131
  };
1070
1132
  let restoredBfcacheIds = navigationKind === "traverse" ? historyController.readCurrentBfcacheVersionHistoryIds(activeTraversalIntent?.historyState ?? window.history.state) : null;
@@ -1078,6 +1140,15 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
1078
1140
  if (!browserNavigationController.isCurrentNavigation(navId)) return;
1079
1141
  if (shouldUsePendingRouterState) pendingRouterState = beginPendingBrowserRouterState();
1080
1142
  }
1143
+ const routeManifestLoad = loadNavigationRuntimeRouteManifest();
1144
+ if (routeManifestLoad !== null) {
1145
+ const routeManifestLoaded = await routeManifestLoad;
1146
+ if (!browserNavigationController.isCurrentNavigation(navId)) return;
1147
+ if (!routeManifestLoaded) {
1148
+ performHardNavigationForScrollIntent(currentHref);
1149
+ return;
1150
+ }
1151
+ }
1081
1152
  const navigationInitiationState = getBrowserRouterState();
1082
1153
  const mountedSlotsHeader = getMountedSlotIdsHeader(navigationInitiationState.elements);
1083
1154
  while (true) {
@@ -1172,7 +1243,7 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
1172
1243
  });
1173
1244
  if (reuseDecision.kind === "reuseVisitedResponse" && cachedRoute) {
1174
1245
  const cachedFetchDecision = navigationPlanner.classifyRscFetchResult({
1175
- clientCompatibilityId: CLIENT_RSC_COMPATIBILITY_ID,
1246
+ clientCompatibilityId: clientRscCompatibilityId,
1176
1247
  compatibilityIdHeader: cachedRoute.response.compatibilityIdHeader ?? null,
1177
1248
  currentHref,
1178
1249
  effectiveHistoryUpdateMode: currentHistoryMode ?? "replace",
@@ -1204,7 +1275,7 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
1204
1275
  const cachedNavigationSnapshot = createClientNavigationRenderSnapshot(currentHref, cachedParams, cachedRoute.response.renderedPathAndSearch);
1205
1276
  const cachedPayload = cachedRoute.elements ? Promise.resolve(cachedRoute.elements) : decodeAppElementsPromise(createFromFetch(Promise.resolve(restoreRscResponse(cachedRoute.response))));
1206
1277
  if (!browserNavigationController.isCurrentNavigation(navId)) return;
1207
- if (await renderNavigationPayload({
1278
+ const cachedRenderOutcome = await renderNavigationPayload({
1208
1279
  actionType: toActionType(navigationKind),
1209
1280
  historyUpdateMode: currentHistoryMode,
1210
1281
  navigationCommitKind: detachedNavigationCommits ? "authoritative" : void 0,
@@ -1223,7 +1294,12 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
1223
1294
  targetHref: currentHref,
1224
1295
  traversalIntent: activeTraversalIntent,
1225
1296
  visibleCommitMode
1226
- }) === "no-commit") {
1297
+ });
1298
+ if (cachedRenderOutcome === "hard-navigate") {
1299
+ startedHardNavigation = true;
1300
+ browserNavigationController.abandonPendingBrowserRouterState(pendingRouterState);
1301
+ }
1302
+ if (cachedRenderOutcome === "no-commit") {
1227
1303
  if (!browserNavigationController.isCurrentNavigation(navId)) return;
1228
1304
  deleteVisitedResponse(rscUrl, requestInterceptionContext);
1229
1305
  continue;
@@ -1343,7 +1419,7 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
1343
1419
  const streamedRedirectType = streamedRedirectTypeHeader === "push" || streamedRedirectTypeHeader === "replace" ? streamedRedirectTypeHeader : null;
1344
1420
  if (blockDangerousStreamedRscRedirect(navResponse, streamedRedirectTarget)) return;
1345
1421
  const liveFetchDecision = navigationPlanner.classifyRscFetchResult({
1346
- clientCompatibilityId: CLIENT_RSC_COMPATIBILITY_ID,
1422
+ clientCompatibilityId: clientRscCompatibilityId,
1347
1423
  compatibilityIdHeader: navResponse.headers.get(VINEXT_RSC_COMPATIBILITY_ID_HEADER),
1348
1424
  currentHref,
1349
1425
  effectiveHistoryUpdateMode: currentHistoryMode ?? "replace",
@@ -1422,7 +1498,7 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
1422
1498
  }
1423
1499
  if (!browserNavigationController.isCurrentNavigation(navId)) return;
1424
1500
  let committedState = null;
1425
- if (await renderNavigationPayload({
1501
+ const renderOutcome = await renderNavigationPayload({
1426
1502
  actionType: toActionType(navigationKind),
1427
1503
  historyUpdateMode: currentHistoryMode,
1428
1504
  navigationCommitKind: detachedNavigationCommits ? "authoritative" : void 0,
@@ -1452,7 +1528,12 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
1452
1528
  targetHref: currentHref,
1453
1529
  traversalIntent: activeTraversalIntent,
1454
1530
  visibleCommitMode: prefetchedElements ? "synchronous" : visibleCommitMode
1455
- }) !== "committed") return;
1531
+ });
1532
+ if (renderOutcome === "hard-navigate") {
1533
+ startedHardNavigation = true;
1534
+ browserNavigationController.abandonPendingBrowserRouterState(pendingRouterState);
1535
+ }
1536
+ if (renderOutcome !== "committed") return;
1456
1537
  if (hasSupplementalRefresh) {
1457
1538
  clearVisitedResponseCache();
1458
1539
  return;
@@ -1501,6 +1582,7 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
1501
1582
  navigationAbortHandle.release();
1502
1583
  browserNavigationController.finalizeNavigation(navId, pendingRouterState);
1503
1584
  discardedServerActionRefreshScheduler.markNavigationSettled();
1585
+ if (startedHardNavigation) await waitForMpaNavigationRestore();
1504
1586
  }
1505
1587
  },
1506
1588
  preparePrefetchResponse: (response) => decodeAppElementsPromise(createFromFetch(Promise.resolve(response))),
@@ -1609,7 +1691,12 @@ if (typeof document !== "undefined") {
1609
1691
  });
1610
1692
  window.addEventListener("pageshow", (event) => {
1611
1693
  isPageUnloading = false;
1612
- if (event.persisted) mpaNavigationScheduler.reset();
1694
+ if (event.persisted) {
1695
+ mpaNavigationScheduler.reset();
1696
+ mpaNavigationTree?.restore();
1697
+ mpaNavigationRestore?.resolve();
1698
+ mpaNavigationRestore = null;
1699
+ }
1613
1700
  });
1614
1701
  main();
1615
1702
  }
@@ -4,7 +4,9 @@ type VinextHydrateRootErrorInfo = {
4
4
  errorBoundary?: unknown;
5
5
  };
6
6
  type HydrateRootErrorHandler = (error: unknown, errorInfo: VinextHydrateRootErrorInfo) => void;
7
- export declare function createOnUncaughtError(): HydrateRootErrorHandler;
7
+ export declare function createOnUncaughtError(options?: {
8
+ coerceToError?: boolean;
9
+ }): HydrateRootErrorHandler;
8
10
  export declare function createProdOnCaughtError(onImplicitRootError: HydrateRootErrorHandler): HydrateRootErrorHandler;
9
11
  export declare function createDevOnCaughtError(onCaughtError: HydrateRootErrorHandler, onImplicitRootError: HydrateRootErrorHandler): HydrateRootErrorHandler;
10
12
  export declare function createProdOnRecoverableError(onReportedError: () => void): (error: unknown) => void;
@@ -18,9 +18,14 @@ function reportGlobalError(error) {
18
18
  }
19
19
  console.error(error);
20
20
  }
21
- function createOnUncaughtError() {
21
+ function coerceError(value) {
22
+ if (isNavigationSignalError(value)) return value;
23
+ if (typeof value === "object" && value !== null && "name" in value && "message" in value) return value;
24
+ return new Error(String(value));
25
+ }
26
+ function createOnUncaughtError(options = {}) {
22
27
  return (error) => {
23
- reportGlobalError(error);
28
+ reportGlobalError(options.coerceToError ? coerceError(error) : error);
24
29
  };
25
30
  }
26
31
  function createProdOnCaughtError(onImplicitRootError) {
@@ -1,10 +1,10 @@
1
- import { RouteManifest } from "../routing/app-route-graph.js";
1
+ import { BrowserRouteManifest } from "../routing/browser-route-manifest.js";
2
2
  //#region src/server/app-browser-interception-context.d.ts
3
3
  type ResolveManifestNavigationInterceptionContextOptions = {
4
4
  basePath: string;
5
5
  currentMatchedPathname?: string | null;
6
6
  currentPathname: string;
7
- routeManifest: RouteManifest | null;
7
+ routeManifest: BrowserRouteManifest | null;
8
8
  targetPathname: string;
9
9
  };
10
10
  /**
@@ -1,6 +1,7 @@
1
1
  import { HistoryUpdateMode } from "./app-browser-navigation-controller.js";
2
2
  //#region src/server/app-browser-mpa-navigation.d.ts
3
3
  export type AppBrowserMpaNavigationWindow = {
4
+ document?: Pick<Document, "visibilityState">;
4
5
  location: Pick<Location, "assign" | "replace">;
5
6
  requestAnimationFrame?: (callback: FrameRequestCallback) => unknown;
6
7
  setTimeout(callback: () => void, timeout: number): unknown;
@@ -14,21 +14,22 @@ var AppBrowserMpaNavigationScheduler = class {
14
14
  this.#pendingNavigation = null;
15
15
  }
16
16
  navigate(targetWindow, href, historyUpdateMode) {
17
- const pendingNavigation = this.#pendingNavigation;
18
- if (pendingNavigation?.href === href && pendingNavigation.historyUpdateMode === historyUpdateMode) return;
17
+ if (this.#pendingNavigation?.href === href) return;
19
18
  const token = this.#nextToken + 1;
20
19
  this.#nextToken = token;
21
20
  this.#pendingNavigation = {
22
21
  href,
23
- historyUpdateMode,
24
22
  token
25
23
  };
26
24
  const navigate = () => {
27
- const currentNavigation = this.#pendingNavigation;
28
- if (currentNavigation?.href !== href || currentNavigation.historyUpdateMode !== historyUpdateMode || currentNavigation.token !== token) return;
25
+ if (this.#pendingNavigation?.token !== token) return;
29
26
  if (historyUpdateMode === "replace") targetWindow.location.replace(href);
30
27
  else targetWindow.location.assign(href);
31
28
  };
29
+ if (targetWindow.document?.visibilityState === "hidden") {
30
+ navigate();
31
+ return;
32
+ }
32
33
  if (typeof targetWindow.requestAnimationFrame === "function") {
33
34
  targetWindow.requestAnimationFrame(() => {
34
35
  targetWindow.setTimeout(navigate, 0);
@@ -1,4 +1,4 @@
1
- import { RouteManifest } from "../routing/app-route-graph.js";
1
+ import { BrowserRouteManifest } from "../routing/browser-route-manifest.js";
2
2
  import { AppRouterScrollIntent } from "../shims/app-router-scroll-state.js";
3
3
  import { NavigationRuntimeVisibleCommitMode } from "../client/navigation-runtime.js";
4
4
  import { AppElements } from "./app-elements-wire.js";
@@ -17,10 +17,14 @@ export type PendingBrowserRouterState = {
17
17
  };
18
18
  export type NavigationPayloadOutcome = "committed" | "no-commit" | "hard-navigate";
19
19
  type HardNavigationMode = "assign" | "replace";
20
- type BrowserNavigationCommitEffect = (options: {
21
- keepCurrentUrl: boolean;
22
- releaseSnapshot: boolean;
23
- }) => void;
20
+ type BrowserNavigationCommitEffect = {
21
+ writeHistory(options: {
22
+ keepCurrentUrl: boolean;
23
+ }): void;
24
+ publish(options: {
25
+ releaseSnapshot: boolean;
26
+ }): void;
27
+ };
24
28
  type BrowserNavigationCommitEffectFactory = (options: {
25
29
  activeRoutePaths: readonly string[];
26
30
  bfcacheIds: Readonly<Record<string, string>>;
@@ -43,8 +47,10 @@ type SameUrlServerActionLifecycleOptions = {
43
47
  type BrowserNavigationControllerDeps = {
44
48
  basePath?: string;
45
49
  commitClientNavigationState?: typeof commitClientNavigationState;
50
+ navigateDocument?: (href: string, mode: HardNavigationMode) => void;
46
51
  performHardNavigation?: (href: string, mode?: HardNavigationMode) => boolean;
47
- getRouteManifest?: () => RouteManifest | null;
52
+ getRouteManifest?: () => BrowserRouteManifest | null;
53
+ loadRouteManifest?: () => Promise<boolean> | null;
48
54
  syncHistoryStatePreviousNextUrl?: (previousNextUrl: string | null, bfcacheIds?: Readonly<Record<string, string>> | null) => void;
49
55
  };
50
56
  type BrowserNavigationPayloadOptions = {
@@ -80,6 +86,7 @@ type BrowserNavigationController = {
80
86
  waitForBrowserRouterStateReady(): Promise<void>;
81
87
  attachBrowserRouterState(setter: Dispatch<AppRouterState | Promise<AppRouterState>>, stateRef: BrowserRouterStateRef): () => void;
82
88
  beginPendingBrowserRouterState(): PendingBrowserRouterState;
89
+ abandonPendingBrowserRouterState(pending: PendingBrowserRouterState | null | undefined): void;
83
90
  finalizeNavigation(navId: number, pending: PendingBrowserRouterState | null | undefined): void;
84
91
  discardPendingNavigation(visibleState: AppRouterState | null): boolean;
85
92
  flushCommittingNavigationUrl(): void;
@@ -112,8 +119,12 @@ type BrowserNavigationController = {
112
119
  renderId: number;
113
120
  children?: ReactNode;
114
121
  }): ReactNode;
122
+ NavigationHistoryCommit(this: void, { renderId }: {
123
+ renderId: number;
124
+ }): null;
115
125
  };
116
126
  export declare function clearHardNavigationLoopGuard(): void;
127
+ export declare function navigateDocumentDirectly(href: string, mode: HardNavigationMode): void;
117
128
  export declare function createBasePathStrippedPathAndSearch(url: URL, basePath: string): string;
118
129
  export declare function createAppBrowserNavigationController(deps?: BrowserNavigationControllerDeps): BrowserNavigationController;
119
130
  //#endregion