vinext 0.1.1 → 0.1.2

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 (147) hide show
  1. package/README.md +2 -5
  2. package/dist/build/client-build-config.d.ts +7 -1
  3. package/dist/build/client-build-config.js +9 -1
  4. package/dist/check.js +4 -3
  5. package/dist/client/navigation-runtime.d.ts +3 -2
  6. package/dist/client/window-next.d.ts +6 -4
  7. package/dist/config/config-matchers.d.ts +11 -4
  8. package/dist/config/config-matchers.js +15 -2
  9. package/dist/config/next-config.d.ts +13 -0
  10. package/dist/config/next-config.js +2 -0
  11. package/dist/deploy.js +9 -2
  12. package/dist/entries/app-rsc-entry.js +7 -1
  13. package/dist/entries/pages-client-entry.js +1 -1
  14. package/dist/entries/pages-server-entry.js +7 -6
  15. package/dist/index.d.ts +0 -2
  16. package/dist/index.js +86 -78
  17. package/dist/plugins/dynamic-preload-metadata.d.ts +13 -0
  18. package/dist/plugins/dynamic-preload-metadata.js +415 -0
  19. package/dist/plugins/og-assets.js +2 -2
  20. package/dist/plugins/optimize-imports.d.ts +8 -4
  21. package/dist/plugins/optimize-imports.js +16 -12
  22. package/dist/plugins/sass.d.ts +53 -24
  23. package/dist/plugins/sass.js +249 -1
  24. package/dist/plugins/wasm-module-import.d.ts +15 -0
  25. package/dist/plugins/wasm-module-import.js +50 -0
  26. package/dist/routing/app-route-graph.d.ts +23 -1
  27. package/dist/routing/app-route-graph.js +47 -8
  28. package/dist/routing/file-matcher.js +1 -1
  29. package/dist/server/app-browser-entry.js +108 -213
  30. package/dist/server/app-browser-error.d.ts +4 -1
  31. package/dist/server/app-browser-error.js +7 -1
  32. package/dist/server/app-browser-history-controller.d.ts +104 -0
  33. package/dist/server/app-browser-history-controller.js +210 -0
  34. package/dist/server/app-browser-navigation-controller.d.ts +3 -2
  35. package/dist/server/app-browser-navigation-controller.js +10 -7
  36. package/dist/server/app-browser-rsc-redirect.d.ts +11 -2
  37. package/dist/server/app-browser-rsc-redirect.js +30 -8
  38. package/dist/server/app-browser-state.js +4 -7
  39. package/dist/server/app-browser-visible-commit.js +1 -1
  40. package/dist/server/app-fallback-renderer.d.ts +2 -1
  41. package/dist/server/app-fallback-renderer.js +3 -1
  42. package/dist/server/app-middleware.js +1 -0
  43. package/dist/server/app-optimistic-routing.js +22 -1
  44. package/dist/server/app-page-boundary-render.d.ts +2 -1
  45. package/dist/server/app-page-boundary-render.js +4 -2
  46. package/dist/server/app-page-cache.js +9 -7
  47. package/dist/server/app-page-dispatch.d.ts +8 -0
  48. package/dist/server/app-page-dispatch.js +18 -5
  49. package/dist/server/app-page-element-builder.d.ts +22 -2
  50. package/dist/server/app-page-element-builder.js +37 -8
  51. package/dist/server/app-page-execution.d.ts +1 -1
  52. package/dist/server/app-page-execution.js +32 -17
  53. package/dist/server/app-page-render.d.ts +1 -1
  54. package/dist/server/app-page-render.js +7 -14
  55. package/dist/server/app-page-request.d.ts +1 -0
  56. package/dist/server/app-page-request.js +3 -2
  57. package/dist/server/app-page-response.js +1 -1
  58. package/dist/server/app-page-route-wiring.d.ts +3 -1
  59. package/dist/server/app-page-route-wiring.js +8 -7
  60. package/dist/server/app-page-stream.d.ts +1 -6
  61. package/dist/server/app-page-stream.js +1 -4
  62. package/dist/server/app-route-handler-response.js +11 -10
  63. package/dist/server/app-route-handler-runtime.js +12 -1
  64. package/dist/server/app-rsc-handler.js +1 -1
  65. package/dist/server/app-rsc-response-finalizer.js +1 -1
  66. package/dist/server/app-server-action-execution.d.ts +11 -0
  67. package/dist/server/app-server-action-execution.js +5 -2
  68. package/dist/server/app-ssr-entry.js +2 -2
  69. package/dist/server/app-ssr-stream.js +9 -1
  70. package/dist/server/dev-lockfile.js +2 -1
  71. package/dist/server/dev-server.js +43 -12
  72. package/dist/server/headers.d.ts +8 -1
  73. package/dist/server/headers.js +8 -1
  74. package/dist/server/instrumentation-runtime.d.ts +6 -0
  75. package/dist/server/instrumentation-runtime.js +8 -0
  76. package/dist/server/isr-decision.d.ts +79 -0
  77. package/dist/server/isr-decision.js +70 -0
  78. package/dist/server/metadata-route-response.js +5 -3
  79. package/dist/server/middleware-runtime.d.ts +13 -0
  80. package/dist/server/middleware-runtime.js +11 -7
  81. package/dist/server/middleware.js +1 -0
  82. package/dist/server/navigation-planner.d.ts +62 -1
  83. package/dist/server/navigation-planner.js +188 -0
  84. package/dist/server/navigation-trace.d.ts +11 -1
  85. package/dist/server/navigation-trace.js +11 -1
  86. package/dist/server/normalize-path.d.ts +0 -8
  87. package/dist/server/normalize-path.js +3 -1
  88. package/dist/server/otel-tracer-extension.d.ts +45 -0
  89. package/dist/server/otel-tracer-extension.js +89 -0
  90. package/dist/server/pages-api-route.d.ts +14 -3
  91. package/dist/server/pages-api-route.js +6 -1
  92. package/dist/server/pages-asset-tags.d.ts +15 -4
  93. package/dist/server/pages-asset-tags.js +18 -12
  94. package/dist/server/pages-data-route.js +5 -1
  95. package/dist/server/pages-node-compat.d.ts +3 -11
  96. package/dist/server/pages-node-compat.js +174 -121
  97. package/dist/server/pages-page-data.d.ts +28 -0
  98. package/dist/server/pages-page-data.js +61 -17
  99. package/dist/server/pages-page-handler.d.ts +1 -0
  100. package/dist/server/pages-page-handler.js +22 -6
  101. package/dist/server/pages-page-response.d.ts +45 -1
  102. package/dist/server/pages-page-response.js +66 -5
  103. package/dist/server/pages-readiness.d.ts +1 -1
  104. package/dist/server/pages-request-pipeline.d.ts +15 -1
  105. package/dist/server/pages-request-pipeline.js +23 -2
  106. package/dist/server/prod-server.d.ts +39 -1
  107. package/dist/server/prod-server.js +98 -34
  108. package/dist/shims/cache-runtime.js +9 -2
  109. package/dist/shims/dynamic-preload-chunks.d.ts +8 -0
  110. package/dist/shims/dynamic-preload-chunks.js +77 -0
  111. package/dist/shims/dynamic.d.ts +4 -0
  112. package/dist/shims/dynamic.js +4 -2
  113. package/dist/shims/error-boundary.d.ts +4 -4
  114. package/dist/shims/error.js +37 -11
  115. package/dist/shims/fetch-cache.d.ts +9 -1
  116. package/dist/shims/fetch-cache.js +11 -1
  117. package/dist/shims/head.js +6 -1
  118. package/dist/shims/headers.d.ts +16 -2
  119. package/dist/shims/headers.js +37 -1
  120. package/dist/shims/image-config.js +7 -1
  121. package/dist/shims/internal/app-route-detection.d.ts +6 -3
  122. package/dist/shims/internal/app-route-detection.js +10 -6
  123. package/dist/shims/internal/app-router-context.d.ts +5 -0
  124. package/dist/shims/metadata.d.ts +6 -2
  125. package/dist/shims/metadata.js +32 -14
  126. package/dist/shims/navigation.d.ts +7 -16
  127. package/dist/shims/navigation.js +33 -16
  128. package/dist/shims/router.js +28 -1
  129. package/dist/shims/script-nonce-context.d.ts +1 -1
  130. package/dist/shims/script-nonce-context.js +11 -3
  131. package/dist/shims/server.d.ts +17 -1
  132. package/dist/shims/server.js +31 -6
  133. package/dist/shims/slot.js +1 -1
  134. package/dist/shims/unified-request-context.js +1 -0
  135. package/dist/typegen.js +1 -0
  136. package/dist/utils/client-build-manifest.js +15 -5
  137. package/dist/utils/client-runtime-metadata.d.ts +45 -0
  138. package/dist/utils/client-runtime-metadata.js +63 -0
  139. package/dist/utils/hash.d.ts +17 -1
  140. package/dist/utils/hash.js +36 -1
  141. package/dist/utils/lazy-chunks.d.ts +27 -1
  142. package/dist/utils/lazy-chunks.js +65 -1
  143. package/dist/utils/manifest-paths.d.ts +20 -2
  144. package/dist/utils/manifest-paths.js +38 -3
  145. package/dist/utils/path.d.ts +2 -1
  146. package/dist/utils/path.js +5 -1
  147. package/package.json +2 -2
@@ -1,4 +1,3 @@
1
- import { stripBasePath } from "../utils/base-path.js";
2
1
  import { ACTION_REDIRECT_HEADER, ACTION_REDIRECT_STATUS_HEADER, VINEXT_CLIENT_REUSE_MANIFEST_HEADER, VINEXT_PARAMS_HEADER, VINEXT_RSC_REDIRECT_HEADER } from "./headers.js";
3
2
  import { DANGEROUS_URL_BLOCK_MESSAGE, isDangerousScheme } from "../shims/url-safety.js";
4
3
  import { AppElementsWire } from "./app-elements-wire.js";
@@ -10,11 +9,12 @@ import { retryScrollTo, scrollToHashTargetOnNextFrame } from "../shims/hash-scro
10
9
  import { getNavigationRuntime, registerNavigationRuntimeBootstrap, registerNavigationRuntimeFunctions } from "../client/navigation-runtime.js";
11
10
  import { notifyAppRouterTransitionStart } from "../client/instrumentation-client-state.js";
12
11
  import { resolveManifestNavigationInterceptionContext, resolveMiddlewareRewriteNavigationInterceptionContext } from "./app-browser-interception-context.js";
13
- import { RestorableClientStateController, createHistoryStateWithNavigationMetadata, readHistoryStateBfcacheIds, readHistoryStatePreviousNextUrl, readHistoryStateTraversalIndex, resolveHistoryTraversalIntent } from "./app-history-state.js";
14
- import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, createRscRequestHeaders, createRscRequestUrl, createServerActionRequestUrl, getVinextRscCompatibilityId, resolveHardNavigationTargetFromRscResponse, resolveRscCompatibilityNavigationDecision } from "./app-rsc-cache-busting.js";
12
+ import { readHistoryStatePreviousNextUrl } from "./app-history-state.js";
13
+ import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, createRscRequestHeaders, createRscRequestUrl, createServerActionRequestUrl, getVinextRscCompatibilityId, resolveRscCompatibilityNavigationDecision } from "./app-rsc-cache-busting.js";
15
14
  import { AppBrowserMpaNavigationScheduler } from "./app-browser-mpa-navigation.js";
15
+ import { navigationPlanner } from "./navigation-planner.js";
16
16
  import { beginAppRouterScrollIntent, consumeAppRouterScrollIntent } from "../shims/app-router-scroll-state.js";
17
- import { __basePath, appRouterInstance, commitClientNavigationState, consumePrefetchResponseForNavigation, createCachedRscResponseSnapshot, createClientNavigationRenderSnapshot, decodeRedirectError, getBfcacheIdMapContext, getClientNavigationRenderContext, getPrefetchCache, invalidatePrefetchCache, isRedirectError, pushHistoryStateWithoutNotify, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, resolvePrefetchCacheEntryMountedSlotsHeader, restoreRscResponse, saveScrollPosition, setClientParams, setMountedSlotsHeader, setNavigationContext, setPendingPathname, useRouter } from "../shims/navigation.js";
17
+ import { __basePath, appRouterInstance, commitClientNavigationState, consumePrefetchResponseForNavigation, createCachedRscResponseSnapshot, createClientNavigationRenderSnapshot, createSnapshotPathAndSearch, decodeRedirectError, getBfcacheIdMapContext, getClientNavigationRenderContext, getPrefetchCache, invalidatePrefetchCache, isRedirectError, pushHistoryStateWithoutNotify, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, resolvePrefetchCacheEntryMountedSlotsHeader, restoreRscResponse, saveScrollPosition, setClientParams, setMountedSlotsHeader, setNavigationContext, setPendingPathname, useRouter } from "../shims/navigation.js";
18
18
  import { DevRecoveryBoundary, RedirectBoundary } from "../shims/error-boundary.js";
19
19
  import { AppRouterScrollCommitProvider } from "../shims/app-router-scroll.js";
20
20
  import { BfcacheStateKeyMapContext, ElementsContext, Slot } from "../shims/slot.js";
@@ -23,15 +23,15 @@ import { createDiscardedServerActionRefreshScheduler, createServerActionInitiati
23
23
  import { createClientReuseManifestHeaderFromVisibleAppState } from "./app-browser-client-reuse-manifest.js";
24
24
  import { chunksToReadableStream, createProgressiveRscStream, getVinextBrowserGlobal } from "./app-browser-stream.js";
25
25
  import { FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, VISITED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN, createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap, isCacheRestorableAppPayloadMetadata, resolveInterceptionContextFromPreviousNextUrl, resolveServerActionRequestState } from "./app-browser-state.js";
26
- import { clearHardNavigationLoopGuard, createAppBrowserNavigationController, createBasePathStrippedPathAndSearch, createSnapshotPathAndSearch } from "./app-browser-navigation-controller.js";
26
+ import { clearHardNavigationLoopGuard, createAppBrowserNavigationController, createBasePathStrippedPathAndSearch } from "./app-browser-navigation-controller.js";
27
27
  import { consumeInitialFormState, createVinextHydrateRootOptions, hydrateRootInTransition } from "./app-browser-hydration.js";
28
+ import { AppBrowserHistoryController } from "./app-browser-history-controller.js";
28
29
  import { createVisitedResponseCacheEntry, isVisitedResponseCacheEntryFresh } from "./app-visited-response-cache.js";
29
30
  import { createPopstateRestoreHandler, restoreSynchronousPopstateScrollPosition } from "./app-browser-popstate.js";
30
- import { createOnUncaughtError } from "./app-browser-error.js";
31
+ import { createOnUncaughtError, prodOnCaughtError } from "./app-browser-error.js";
31
32
  import { dismissOverlay } from "./dev-error-overlay-store.js";
32
33
  import { devOnCaughtError, devOnUncaughtError, installDevErrorOverlay, installViteHmrErrorHandler, reportInitialDevServerErrors } from "./dev-error-overlay.js";
33
34
  import { throwOnServerActionNotFound } from "./server-action-not-found.js";
34
- import { resolveRscRedirectLifecycleHop } from "./app-browser-rsc-redirect.js";
35
35
  import { createOptimisticRouteTemplate, getOptimisticPrefetchSourceKey, getOptimisticRouteTemplateKey, resolveOptimisticNavigationPayload } from "./app-optimistic-routing.js";
36
36
  import { removeStylesheetLinksCoveredByInlineCss } from "./app-inline-css-client.js";
37
37
  import { createElement, startTransition, use, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
@@ -58,10 +58,26 @@ const optimisticRouteTemplateLearning = /* @__PURE__ */ new Map();
58
58
  function getBrowserRouteManifest() {
59
59
  return getNavigationRuntime()?.bootstrap.routeManifest ?? null;
60
60
  }
61
+ const historyController = new AppBrowserHistoryController({
62
+ initialHistoryState: window.history.state,
63
+ maxHistoryStateSnapshots: 50,
64
+ readHistoryState: () => window.history.state,
65
+ readCurrentHref: () => window.location.href,
66
+ pushHistoryState: (state, href) => pushHistoryStateWithoutNotify(state, "", href),
67
+ replaceHistoryState: (state, href) => replaceHistoryStateWithoutNotify(state, "", href),
68
+ readVisibleNavigationMetadata: () => {
69
+ if (!hasBrowserRouterState()) return null;
70
+ const routerState = getBrowserRouterState();
71
+ return {
72
+ bfcacheIds: routerState.bfcacheIds,
73
+ previousNextUrl: routerState.previousNextUrl
74
+ };
75
+ }
76
+ });
61
77
  const browserNavigationController = createAppBrowserNavigationController({
62
78
  basePath: __basePath,
63
79
  getRouteManifest: getBrowserRouteManifest,
64
- syncHistoryStatePreviousNextUrl: syncCurrentHistoryStatePreviousNextUrl
80
+ syncHistoryStatePreviousNextUrl: (previousNextUrl, bfcacheIds) => historyController.syncCurrentHistoryStatePreviousNextUrl(previousNextUrl, bfcacheIds)
65
81
  });
66
82
  const discardedServerActionRefreshScheduler = createDiscardedServerActionRefreshScheduler({ runRefresh() {
67
83
  clearClientNavigationCaches();
@@ -98,74 +114,25 @@ const mpaNavigationScheduler = new AppBrowserMpaNavigationScheduler();
98
114
  const unresolvedMpaNavigation = new Promise(() => {});
99
115
  const RSC_HMR_SETTLE_DELAY_MS = 150;
100
116
  let latestRscHmrUpdateId = 0;
101
- let currentHistoryTraversalIndex = readHistoryStateTraversalIndex(window.history.state) ?? 0;
102
- let nextHistoryTraversalIndex = currentHistoryTraversalIndex;
103
117
  let synchronousPopstateScrollRestoreNavigationId = null;
104
- const restorableClientState = new RestorableClientStateController({
105
- initialHistoryState: window.history.state,
106
- maxHistoryStateSnapshots: 50
107
- });
108
118
  function waitForRscHmrSettle(delayMs = RSC_HMR_SETTLE_DELAY_MS) {
109
119
  return new Promise((resolve) => {
110
120
  window.setTimeout(resolve, delayMs);
111
121
  });
112
122
  }
113
- function allocateNavigationHistoryTraversalIndex(historyUpdateMode) {
114
- switch (historyUpdateMode) {
115
- case "push": return nextHistoryTraversalIndex + 1;
116
- case "replace": return currentHistoryTraversalIndex;
117
- case void 0: return null;
118
- default: throw new Error("[vinext] Unknown history update mode: " + String(historyUpdateMode));
119
- }
120
- }
121
- function commitHistoryTraversalIndex(index) {
122
- currentHistoryTraversalIndex = index;
123
- if (index !== null) nextHistoryTraversalIndex = Math.max(nextHistoryTraversalIndex, index);
124
- }
125
- function commitHashOnlyNavigation(href, historyUpdateMode, scroll) {
126
- const navigationHistoryIndex = allocateNavigationHistoryTraversalIndex(historyUpdateMode);
127
- const previousNextUrl = hasBrowserRouterState() ? getBrowserRouterState().previousNextUrl : readHistoryStatePreviousNextUrl(window.history.state);
128
- const bfcacheIds = hasBrowserRouterState() ? getBrowserRouterState().bfcacheIds : restorableClientState.readCurrentBfcacheVersionHistoryIds(window.history.state);
129
- const historyState = createHistoryStateWithNavigationMetadata(createHashOnlyNavigationBaseHistoryState(historyUpdateMode, scroll), {
130
- bfcacheIds,
131
- bfcacheVersion: bfcacheIds === null ? void 0 : restorableClientState.currentBfcacheVersion,
132
- previousNextUrl,
133
- traversalIndex: navigationHistoryIndex
134
- });
135
- if (historyUpdateMode === "replace") replaceHistoryStateWithoutNotify(historyState, "", href);
136
- else pushHistoryStateWithoutNotify(historyState, "", href);
137
- commitHistoryTraversalIndex(navigationHistoryIndex);
138
- }
139
- function createHashOnlyNavigationBaseHistoryState(historyUpdateMode, scroll) {
140
- if (historyUpdateMode !== "replace") return null;
141
- return scroll ? stripVinextScrollState(window.history.state) : window.history.state;
142
- }
143
- function stripVinextScrollState(state) {
144
- if (!state || typeof state !== "object") return state;
145
- const nextState = {};
146
- for (const [key, value] of Object.entries(state)) {
147
- if (key === "__vinext_scrollX" || key === "__vinext_scrollY") continue;
148
- nextState[key] = value;
149
- }
150
- return Object.keys(nextState).length > 0 ? nextState : null;
151
- }
152
- function commitTraversalIndexFromHistoryState(historyState) {
153
- commitHistoryTraversalIndex(readHistoryStateTraversalIndex(historyState));
154
- }
155
123
  function restoreHistoryStateSnapshot(historyState) {
156
- const decision = restorableClientState.resolveHistoryStateSnapshotRestore(historyState);
157
- if (decision.kind === "skip") return false;
158
124
  const navId = browserNavigationController.getActiveNavigationId();
159
125
  let restored = false;
160
126
  flushSync(() => {
161
- restored = browserNavigationController.restoreHistorySnapshotVisibleState({
162
- beforeCommit: () => {
163
- commitHistoryTraversalIndex(decision.targetHistoryIndex);
164
- stageClientParams(decision.state.navigationSnapshot.params);
165
- },
166
- navId,
167
- state: decision.state,
168
- targetHref: window.location.href
127
+ restored = historyController.restoreHistorySnapshot({
128
+ historyState,
129
+ stageClientParams,
130
+ approveVisibleRestore: ({ state, beforeCommit }) => browserNavigationController.restoreHistorySnapshotVisibleState({
131
+ beforeCommit,
132
+ navId,
133
+ state,
134
+ targetHref: window.location.href
135
+ })
169
136
  });
170
137
  });
171
138
  if (!restored) return false;
@@ -204,7 +171,7 @@ function clearPrefetchState() {
204
171
  function clearClientNavigationCaches() {
205
172
  clearVisitedResponseCache();
206
173
  clearPrefetchState();
207
- restorableClientState.invalidateClientState();
174
+ historyController.invalidateRestorableClientState();
208
175
  }
209
176
  function isSettledPrefetchCacheEntry(entry) {
210
177
  return entry.outcome === "cache-seeded" && entry.pending === void 0 && entry.snapshot !== void 0;
@@ -272,28 +239,6 @@ async function learnOptimisticRouteTemplatesFromPrefetchCache(options) {
272
239
  if (learning.length === 0) return;
273
240
  await Promise.allSettled(learning);
274
241
  }
275
- function areBfcacheIdMapsEqual(a, b) {
276
- if (a === b) return true;
277
- if (a === null || b === null) return false;
278
- const aEntries = Object.entries(a);
279
- const bEntries = Object.entries(b);
280
- if (aEntries.length !== bEntries.length) return false;
281
- return aEntries.every(([key, value]) => b[key] === value);
282
- }
283
- function isHistoryStateNavigationMetadataInSync(state, previousNextUrl, bfcacheIds) {
284
- return readHistoryStatePreviousNextUrl(state) === previousNextUrl && (bfcacheIds === void 0 || areBfcacheIdMapsEqual(readHistoryStateBfcacheIds(state), bfcacheIds) && restorableClientState.isCurrentBfcacheVersion(state));
285
- }
286
- function syncCurrentHistoryStatePreviousNextUrl(previousNextUrl, bfcacheIds) {
287
- if (isHistoryStateNavigationMetadataInSync(window.history.state, previousNextUrl, bfcacheIds)) return;
288
- const nextHistoryState = createHistoryStateWithNavigationMetadata(window.history.state, {
289
- bfcacheIds,
290
- bfcacheVersion: bfcacheIds === void 0 ? void 0 : restorableClientState.currentBfcacheVersion,
291
- previousNextUrl
292
- });
293
- replaceHistoryStateWithoutNotify(nextHistoryState, "", window.location.href);
294
- if (isHistoryStateNavigationMetadataInSync(window.history.state, previousNextUrl, bfcacheIds)) return;
295
- replaceHistoryStateWithoutNotify(nextHistoryState, "", window.location.href);
296
- }
297
242
  function createActionInitiationSnapshot() {
298
243
  const routerState = getBrowserRouterState();
299
244
  return createServerActionInitiationSnapshot({
@@ -309,37 +254,19 @@ function createNavigationCommitEffect(options) {
309
254
  commitClientNavigationState(void 0, { releaseSnapshot: true });
310
255
  return;
311
256
  }
312
- const targetHref = new URL(href, window.location.origin).href;
313
- const preserveExistingState = historyUpdateMode === "replace";
314
- const navigationHistoryIndex = targetHistoryIndex !== void 0 ? targetHistoryIndex : allocateNavigationHistoryTraversalIndex(historyUpdateMode);
315
- const historyState = createHistoryStateWithNavigationMetadata(preserveExistingState ? window.history.state : null, {
257
+ historyController.commitNavigationHistory({
316
258
  bfcacheIds,
317
- bfcacheVersion: restorableClientState.currentBfcacheVersion,
259
+ href,
260
+ historyUpdateMode,
318
261
  previousNextUrl,
319
- traversalIndex: navigationHistoryIndex
262
+ stageClientParams: () => stageClientParams(params),
263
+ targetHistoryIndex
320
264
  });
321
- let wroteHistoryState = false;
322
- if (historyUpdateMode === "replace" && window.location.href !== targetHref) {
323
- stageClientParams(params);
324
- replaceHistoryStateWithoutNotify(historyState, "", href);
325
- wroteHistoryState = true;
326
- commitHistoryTraversalIndex(navigationHistoryIndex);
327
- } else if (historyUpdateMode === "push" && window.location.href !== targetHref) {
328
- stageClientParams(params);
329
- pushHistoryStateWithoutNotify(historyState, "", href);
330
- wroteHistoryState = true;
331
- commitHistoryTraversalIndex(navigationHistoryIndex);
332
- }
333
- if (!wroteHistoryState) {
334
- syncCurrentHistoryStatePreviousNextUrl(previousNextUrl, bfcacheIds);
335
- stageClientParams(params);
336
- if (targetHistoryIndex !== void 0) commitHistoryTraversalIndex(targetHistoryIndex);
337
- }
338
265
  pendingNavigationRecoveryHref = null;
339
266
  commitClientNavigationState(navId);
340
267
  };
341
268
  }
342
- async function renderNavigationPayload(payload, navigationSnapshot, targetHref, navId, historyUpdateMode, params, previousNextUrl, pendingRouterState, payloadOrigin, actionType = "navigate", operationLane = "navigation", traversalIntent = null, scrollIntent = null, restoredBfcacheIds = null, reuseCurrentBfcacheIds = true) {
269
+ 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") {
343
270
  syncServerActionHttpFallbackHead(null);
344
271
  try {
345
272
  return await browserNavigationController.renderNavigationPayload({
@@ -361,7 +288,8 @@ async function renderNavigationPayload(payload, navigationSnapshot, targetHref,
361
288
  reuseCurrentBfcacheIds,
362
289
  targetHistoryIndex: traversalIntent === null ? void 0 : traversalIntent.targetHistoryIndex,
363
290
  targetHref,
364
- navId
291
+ navId,
292
+ visibleCommitMode
365
293
  });
366
294
  } catch (error) {
367
295
  pendingNavigationRecoveryHref = null;
@@ -465,9 +393,8 @@ function storeVisitedResponseSnapshot(rscUrl, interceptionContext, snapshot, par
465
393
  response: snapshot
466
394
  }));
467
395
  }
468
- function isSamePageSearchNavigation(currentSnapshot, targetUrl) {
469
- if (stripBasePath(targetUrl.pathname, __basePath) !== currentSnapshot.pathname) return false;
470
- return targetUrl.searchParams.toString() !== currentSnapshot.searchParams.toString();
396
+ function clientNavigationSnapshotHref(snapshot) {
397
+ return `${window.location.origin}${createSnapshotPathAndSearch(snapshot)}`;
471
398
  }
472
399
  function getRequestState(navigationKind, targetPathname, previousNextUrlOverride, traverseHistoryState) {
473
400
  if (previousNextUrlOverride !== void 0) return {
@@ -610,10 +537,7 @@ function BrowserRoot({ initialElements, initialNavigationSnapshot }) {
610
537
  };
611
538
  }, [setTreeStateValue]);
612
539
  useLayoutEffect(() => {
613
- restorableClientState.rememberHistoryStateSnapshot({
614
- historyIndex: currentHistoryTraversalIndex,
615
- state: treeState
616
- });
540
+ historyController.rememberHistoryStateSnapshot(treeState);
617
541
  }, [treeState]);
618
542
  useLayoutEffect(() => {
619
543
  setMountedSlotsHeader(getMountedSlotIdsHeader(stateRef.current.elements));
@@ -622,12 +546,10 @@ function BrowserRoot({ initialElements, initialNavigationSnapshot }) {
622
546
  }, [treeState.elements]);
623
547
  useLayoutEffect(() => {
624
548
  if (treeState.renderId !== 0) return;
625
- replaceHistoryStateWithoutNotify(createHistoryStateWithNavigationMetadata(window.history.state, {
549
+ historyController.writeHydratedHistoryMetadata({
626
550
  bfcacheIds: treeState.bfcacheIds,
627
- bfcacheVersion: restorableClientState.currentBfcacheVersion,
628
- previousNextUrl: treeState.previousNextUrl,
629
- traversalIndex: currentHistoryTraversalIndex
630
- }), "", window.location.href);
551
+ previousNextUrl: treeState.previousNextUrl
552
+ });
631
553
  }, [
632
554
  treeState.bfcacheIds,
633
555
  treeState.previousNextUrl,
@@ -759,7 +681,7 @@ function registerServerActionCallback() {
759
681
  syncServerActionHttpFallbackHead(null);
760
682
  const temporaryReferences = createTemporaryReferenceSet();
761
683
  const actionInitiation = createActionInitiationSnapshot();
762
- syncCurrentHistoryStatePreviousNextUrl(actionInitiation.routerState.previousNextUrl, actionInitiation.routerState.bfcacheIds);
684
+ historyController.syncCurrentHistoryStatePreviousNextUrl(actionInitiation.routerState.previousNextUrl, actionInitiation.routerState.bfcacheIds);
763
685
  const body = await encodeReply(args, { temporaryReferences });
764
686
  const { headers } = resolveServerActionRequestState({
765
687
  actionId: id,
@@ -843,7 +765,7 @@ function registerServerActionCallback() {
843
765
  return commitSameUrlNavigatePayload(Promise.resolve(AppElementsWire.decode(result)), actionInitiation, void 0, revalidation);
844
766
  };
845
767
  setServerCallback((id, args) => {
846
- const releaseCacheInvalidationGuard = restorableClientState.beginCacheInvalidationGuard();
768
+ const releaseCacheInvalidationGuard = historyController.beginCacheInvalidationGuard();
847
769
  return Promise.resolve().then(() => serverActionCallback(id, args)).finally(releaseCacheInvalidationGuard);
848
770
  });
849
771
  }
@@ -861,10 +783,7 @@ async function main() {
861
783
  function bootstrapHydration(rscStream) {
862
784
  const root = decodeAppElementsPromise(createFromReadableStream(rscStream));
863
785
  const initialNavigationSnapshot = createClientNavigationRenderSnapshot(window.location.href, latestClientParams);
864
- replaceHistoryStateWithoutNotify(createHistoryStateWithNavigationMetadata(window.history.state, {
865
- previousNextUrl: null,
866
- traversalIndex: currentHistoryTraversalIndex
867
- }), "", window.location.href);
786
+ historyController.writeBootstrapHistoryMetadata();
868
787
  const onUncaughtError = import.meta.env.DEV ? devOnUncaughtError : createOnUncaughtError(() => pendingNavigationRecoveryHref);
869
788
  const formState = consumeInitialFormState(getVinextBrowserGlobal());
870
789
  const hydrateRootOptions = import.meta.env.DEV ? createVinextHydrateRootOptions({
@@ -873,6 +792,7 @@ function bootstrapHydration(rscStream) {
873
792
  onUncaughtError
874
793
  }) : createVinextHydrateRootOptions({
875
794
  formState,
795
+ onCaughtError: prodOnCaughtError,
876
796
  onUncaughtError
877
797
  });
878
798
  window.__VINEXT_RSC_ROOT__ = hydrateRootInTransition({
@@ -887,8 +807,8 @@ function bootstrapHydration(rscStream) {
887
807
  });
888
808
  registerNavigationRuntimeFunctions({
889
809
  clearNavigationCaches: clearClientNavigationCaches,
890
- commitHashNavigation: commitHashOnlyNavigation,
891
- navigate: async function navigateRsc(href, redirectDepth = 0, navigationKind = "navigate", historyUpdateMode, previousNextUrlOverride, programmaticTransition = false, traversalIntent, scrollIntent) {
810
+ commitHashNavigation: (href, historyUpdateMode, scroll) => historyController.commitHashOnlyNavigation(href, historyUpdateMode, scroll),
811
+ navigate: async function navigateRsc(href, redirectDepth = 0, navigationKind = "navigate", historyUpdateMode, previousNextUrlOverride, programmaticTransition = false, traversalIntent, scrollIntent, visibleCommitMode = "transition") {
892
812
  let pendingRouterState = null;
893
813
  const navId = browserNavigationController.beginNavigation();
894
814
  discardedServerActionRefreshScheduler.markNavigationStart();
@@ -897,16 +817,13 @@ function bootstrapHydration(rscStream) {
897
817
  let currentPrevNextUrl = previousNextUrlOverride;
898
818
  let redirectCount = redirectDepth;
899
819
  let detachedNavigationCommits = false;
900
- const activeTraversalIntent = navigationKind === "traverse" ? traversalIntent ?? resolveHistoryTraversalIntent({
901
- currentHistoryIndex: currentHistoryTraversalIndex,
902
- historyState: window.history.state
903
- }) : null;
820
+ const activeTraversalIntent = navigationKind === "traverse" ? traversalIntent ?? historyController.resolveTraversalIntent(window.history.state) : null;
904
821
  const performHardNavigationForScrollIntent = (targetHref) => {
905
822
  consumeAppRouterScrollIntent(scrollIntent ?? null);
906
823
  return browserNavigationController.performHardNavigation(targetHref);
907
824
  };
908
- let restoredBfcacheIds = navigationKind === "traverse" ? restorableClientState.readCurrentBfcacheVersionHistoryIds(activeTraversalIntent?.historyState ?? window.history.state) : null;
909
- const reuseCurrentBfcacheIds = navigationKind !== "traverse" || !restorableClientState.isCacheInvalidationGuarded() && restorableClientState.isCurrentBfcacheVersion(activeTraversalIntent?.historyState ?? window.history.state);
825
+ let restoredBfcacheIds = navigationKind === "traverse" ? historyController.readCurrentBfcacheVersionHistoryIds(activeTraversalIntent?.historyState ?? window.history.state) : null;
826
+ const reuseCurrentBfcacheIds = navigationKind !== "traverse" || !historyController.isCacheInvalidationGuarded() && historyController.isCurrentBfcacheVersion(activeTraversalIntent?.historyState ?? window.history.state);
910
827
  try {
911
828
  const shouldUsePendingRouterState = programmaticTransition;
912
829
  if (shouldUsePendingRouterState && hasBrowserRouterState()) pendingRouterState = beginPendingBrowserRouterState();
@@ -920,12 +837,19 @@ function bootstrapHydration(rscStream) {
920
837
  const requestState = getRequestState(navigationKind, url.pathname, currentPrevNextUrl, activeTraversalIntent?.historyState);
921
838
  const requestInterceptionContext = requestState.interceptionContext;
922
839
  const requestPreviousNextUrl = requestState.previousNextUrl;
923
- if (navigationKind === "refresh") syncCurrentHistoryStatePreviousNextUrl(requestPreviousNextUrl, getBrowserRouterState().bfcacheIds);
840
+ if (navigationKind === "refresh") historyController.syncCurrentHistoryStatePreviousNextUrl(requestPreviousNextUrl, getBrowserRouterState().bfcacheIds);
924
841
  setPendingPathname(url.pathname, navId);
925
842
  const routerStateAtNavStart = getBrowserRouterState();
926
843
  const elementsAtNavStart = routerStateAtNavStart.elements;
927
844
  const mountedSlotsHeader = getMountedSlotIdsHeader(elementsAtNavStart);
928
- const shouldBypassNavigationCache = navigationKind === "navigate" && isSamePageSearchNavigation(routerStateAtNavStart.navigationSnapshot, url);
845
+ const earlyIntentDecision = navigationKind === "navigate" ? navigationPlanner.classifyEarlyNavigationIntent({
846
+ basePath: __basePath,
847
+ currentHref: clientNavigationSnapshotHref(routerStateAtNavStart.navigationSnapshot),
848
+ mode: "push",
849
+ scroll: false,
850
+ targetHref: url.href
851
+ }) : null;
852
+ const shouldBypassNavigationCache = earlyIntentDecision?.kind === "flightNavigation" && earlyIntentDecision.bypassNavigationCache;
929
853
  const requestHeaders = createRscRequestHeaders({
930
854
  interceptionContext: requestInterceptionContext,
931
855
  mountedSlotsHeader,
@@ -934,36 +858,32 @@ function bootstrapHydration(rscStream) {
934
858
  const rscUrl = await createRscRequestUrl(url.pathname + url.search, requestHeaders);
935
859
  const cachedRoute = shouldBypassNavigationCache ? null : getVisitedResponse(rscUrl, requestInterceptionContext, mountedSlotsHeader, navigationKind);
936
860
  if (cachedRoute) {
937
- const compatibilityDecision = resolveRscCompatibilityNavigationDecision({
861
+ const cachedFetchDecision = navigationPlanner.classifyRscFetchResult({
938
862
  clientCompatibilityId: CLIENT_RSC_COMPATIBILITY_ID,
863
+ compatibilityIdHeader: cachedRoute.response.compatibilityIdHeader ?? null,
939
864
  currentHref,
940
- origin: window.location.origin,
941
- responseCompatibilityId: cachedRoute.response.compatibilityIdHeader,
942
- responseUrl: cachedRoute.response.url
943
- });
944
- if (compatibilityDecision.kind === "hard-navigate") {
945
- performHardNavigationForScrollIntent(compatibilityDecision.hardNavigationTarget);
946
- return;
947
- }
948
- const cachedRedirectDecision = resolveRscRedirectLifecycleHop({
949
- currentHref,
950
- historyUpdateMode: currentHistoryMode ?? "replace",
865
+ effectiveHistoryUpdateMode: currentHistoryMode ?? "replace",
866
+ hasBody: true,
867
+ isRscContentType: true,
951
868
  origin: window.location.origin,
952
869
  redirectDepth: redirectCount,
953
870
  requestPreviousNextUrl,
954
- responseUrl: cachedRoute.response.url
871
+ responseOk: true,
872
+ responseUrl: cachedRoute.response.url,
873
+ source: "cached",
874
+ streamedRedirectTarget: null
955
875
  });
956
- if (cachedRedirectDecision.kind === "terminal-hard-navigation") {
957
- if (cachedRedirectDecision.reason === "maxRedirectsExceeded") console.error("[vinext] Too many RSC redirects — aborting navigation to prevent infinite loop.");
958
- performHardNavigationForScrollIntent(cachedRedirectDecision.href);
876
+ if (cachedFetchDecision.kind === "hardNavigate") {
877
+ if (cachedFetchDecision.reason === "redirectDepthExhausted") console.error("[vinext] Too many RSC redirects — aborting navigation to prevent infinite loop.");
878
+ performHardNavigationForScrollIntent(cachedFetchDecision.url);
959
879
  return;
960
880
  }
961
- if (cachedRedirectDecision.kind === "follow") {
881
+ if (cachedFetchDecision.kind === "followRedirect") {
962
882
  if (navigationKind === "traverse") restoredBfcacheIds = null;
963
- currentHref = cachedRedirectDecision.href;
964
- currentHistoryMode = cachedRedirectDecision.historyUpdateMode;
965
- currentPrevNextUrl = cachedRedirectDecision.previousNextUrl;
966
- redirectCount = cachedRedirectDecision.redirectDepth;
883
+ currentHref = cachedFetchDecision.redirect.href;
884
+ currentHistoryMode = cachedFetchDecision.redirect.historyUpdateMode;
885
+ currentPrevNextUrl = cachedFetchDecision.redirect.previousNextUrl;
886
+ redirectCount = cachedFetchDecision.redirect.redirectDepth;
967
887
  continue;
968
888
  }
969
889
  if (!browserNavigationController.isCurrentNavigation(navId)) return;
@@ -971,7 +891,7 @@ function bootstrapHydration(rscStream) {
971
891
  const cachedNavigationSnapshot = createClientNavigationRenderSnapshot(currentHref, cachedParams);
972
892
  const cachedPayload = decodeAppElementsPromise(createFromFetch(Promise.resolve(restoreRscResponse(cachedRoute.response))));
973
893
  if (!browserNavigationController.isCurrentNavigation(navId)) return;
974
- 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) === "no-commit") {
894
+ 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") {
975
895
  deleteVisitedResponse(rscUrl, requestInterceptionContext);
976
896
  continue;
977
897
  }
@@ -1009,7 +929,7 @@ function bootstrapHydration(rscStream) {
1009
929
  if (optimisticPayload !== null) {
1010
930
  detachedNavigationCommits = true;
1011
931
  const optimisticNavigationSnapshot = createClientNavigationRenderSnapshot(currentHref, optimisticPayload.params);
1012
- 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).catch((error) => {
932
+ 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) => {
1013
933
  if (browserNavigationController.isCurrentNavigation(navId)) console.error("[vinext] Optimistic RSC navigation error:", error);
1014
934
  });
1015
935
  }
@@ -1026,61 +946,36 @@ function bootstrapHydration(rscStream) {
1026
946
  });
1027
947
  }
1028
948
  if (!browserNavigationController.isCurrentNavigation(navId)) return;
1029
- const isRscResponse = (navResponse.headers.get("content-type") ?? "").startsWith("text/x-component");
1030
- if (!navResponse.ok || !isRscResponse || !navResponse.body) {
1031
- performHardNavigationForScrollIntent(resolveHardNavigationTargetFromRscResponse(navResponseUrl ?? navResponse.url, currentHref, window.location.origin));
1032
- return;
1033
- }
1034
- const compatibilityDecision = resolveRscCompatibilityNavigationDecision({
949
+ const navContentType = navResponse.headers.get("content-type") ?? "";
950
+ const liveFetchDecision = navigationPlanner.classifyRscFetchResult({
1035
951
  clientCompatibilityId: CLIENT_RSC_COMPATIBILITY_ID,
952
+ compatibilityIdHeader: navResponse.headers.get(VINEXT_RSC_COMPATIBILITY_ID_HEADER),
1036
953
  currentHref,
1037
- origin: window.location.origin,
1038
- responseCompatibilityId: navResponse.headers.get(VINEXT_RSC_COMPATIBILITY_ID_HEADER),
1039
- responseUrl: navResponseUrl ?? navResponse.url
1040
- });
1041
- if (compatibilityDecision.kind === "hard-navigate") {
1042
- performHardNavigationForScrollIntent(compatibilityDecision.hardNavigationTarget);
1043
- return;
1044
- }
1045
- const redirectDecision = resolveRscRedirectLifecycleHop({
1046
- currentHref,
1047
- historyUpdateMode: currentHistoryMode ?? "replace",
954
+ effectiveHistoryUpdateMode: currentHistoryMode ?? "replace",
955
+ hasBody: navResponse.body !== null,
956
+ isRscContentType: navContentType.startsWith(VINEXT_RSC_CONTENT_TYPE),
1048
957
  origin: window.location.origin,
1049
958
  redirectDepth: redirectCount,
1050
959
  requestPreviousNextUrl,
1051
- responseUrl: navResponseUrl ?? navResponse.url
960
+ responseOk: navResponse.ok,
961
+ responseUrl: navResponseUrl ?? navResponse.url,
962
+ source: "live",
963
+ streamedRedirectTarget: navResponse.headers.get(VINEXT_RSC_REDIRECT_HEADER)
1052
964
  });
1053
- if (redirectDecision.kind === "terminal-hard-navigation") {
1054
- if (redirectDecision.reason === "maxRedirectsExceeded") console.error("[vinext] Too many RSC redirects — aborting navigation to prevent infinite loop.");
1055
- performHardNavigationForScrollIntent(redirectDecision.href);
965
+ if (liveFetchDecision.kind === "hardNavigate") {
966
+ if (liveFetchDecision.discardBody) navResponse.body?.cancel().catch(() => {});
967
+ if (liveFetchDecision.reason === "redirectDepthExhausted") console.error("[vinext] Too many RSC redirects — aborting navigation to prevent infinite loop.");
968
+ if (liveFetchDecision.reason === "streamedRedirectLoop") console.error("[vinext] RSC streamed redirect resolved to the current URL — aborting navigation to prevent infinite loop.");
969
+ performHardNavigationForScrollIntent(liveFetchDecision.url);
1056
970
  return;
1057
971
  }
1058
- if (redirectDecision.kind === "follow") {
1059
- if (navigationKind === "traverse") restoredBfcacheIds = null;
1060
- currentHref = redirectDecision.href;
1061
- currentHistoryMode = redirectDecision.historyUpdateMode;
1062
- currentPrevNextUrl = redirectDecision.previousNextUrl;
1063
- redirectCount = redirectDecision.redirectDepth;
1064
- continue;
1065
- }
1066
- const flightRedirectTarget = navResponse.headers.get(VINEXT_RSC_REDIRECT_HEADER);
1067
- if (flightRedirectTarget) {
1068
- navResponse.body?.cancel().catch(() => {});
1069
- const resolvedTarget = new URL(flightRedirectTarget, window.location.origin);
1070
- if (resolvedTarget.origin !== window.location.origin) {
1071
- performHardNavigationForScrollIntent(resolvedTarget.href);
1072
- return;
1073
- }
1074
- if (redirectCount >= 10) {
1075
- console.error("[vinext] Too many RSC redirects — aborting navigation to prevent infinite loop.");
1076
- performHardNavigationForScrollIntent(resolvedTarget.href);
1077
- return;
1078
- }
972
+ if (liveFetchDecision.kind === "followRedirect") {
973
+ if (liveFetchDecision.discardBody) navResponse.body?.cancel().catch(() => {});
1079
974
  if (navigationKind === "traverse") restoredBfcacheIds = null;
1080
- currentHref = `${resolvedTarget.pathname}${resolvedTarget.search}${resolvedTarget.hash}`;
1081
- currentHistoryMode = currentHistoryMode ?? "replace";
1082
- currentPrevNextUrl = requestPreviousNextUrl;
1083
- redirectCount += 1;
975
+ currentHref = liveFetchDecision.redirect.href;
976
+ currentHistoryMode = liveFetchDecision.redirect.historyUpdateMode;
977
+ currentPrevNextUrl = liveFetchDecision.redirect.previousNextUrl;
978
+ redirectCount = liveFetchDecision.redirect.redirectDepth;
1084
979
  continue;
1085
980
  }
1086
981
  const navParams = parseEncodedJsonHeader(navResponse.headers.get("X-Vinext-Params")) ?? {};
@@ -1096,7 +991,7 @@ function bootstrapHydration(rscStream) {
1096
991
  if (!browserNavigationController.isCurrentNavigation(navId)) return;
1097
992
  const rscPayload = decodeAppElementsPromise(createFromFetch(Promise.resolve(reactResponse)));
1098
993
  if (!browserNavigationController.isCurrentNavigation(navId)) return;
1099
- 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) !== "committed") return;
994
+ 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;
1100
995
  if (!browserNavigationController.isCurrentNavigation(navId)) return;
1101
996
  try {
1102
997
  const renderedElements = await rscPayload;
@@ -1142,7 +1037,7 @@ function bootstrapHydration(rscStream) {
1142
1037
  const href = window.location.href;
1143
1038
  if (isSameAppRoutePopstateTarget(href)) {
1144
1039
  notifyAppRouterTransitionStart(href, "traverse");
1145
- commitTraversalIndexFromHistoryState(event.state);
1040
+ historyController.commitTraversalIndexFromHistoryState(event.state);
1146
1041
  restorePopstateScrollPosition(event.state);
1147
1042
  return;
1148
1043
  }
@@ -2,5 +2,8 @@
2
2
  declare function createOnUncaughtError(getRecoveryHref: () => string | null): (error: unknown, errorInfo: {
3
3
  componentStack?: string;
4
4
  }) => void;
5
+ declare function prodOnCaughtError(error: unknown, errorInfo: {
6
+ componentStack?: string;
7
+ }): void;
5
8
  //#endregion
6
- export { createOnUncaughtError };
9
+ export { createOnUncaughtError, prodOnCaughtError };
@@ -1,3 +1,4 @@
1
+ import { isNavigationSignalError } from "../utils/navigation-signal.js";
1
2
  //#region src/server/app-browser-error.ts
2
3
  function createOnUncaughtError(getRecoveryHref) {
3
4
  return (error, errorInfo) => {
@@ -7,5 +8,10 @@ function createOnUncaughtError(getRecoveryHref) {
7
8
  if (recoveryHref !== null) window.location.assign(recoveryHref);
8
9
  };
9
10
  }
11
+ function prodOnCaughtError(error, errorInfo) {
12
+ if (isNavigationSignalError(error)) return;
13
+ console.error(error);
14
+ if (errorInfo?.componentStack) console.error("The above error occurred in a React component:\n" + errorInfo.componentStack);
15
+ }
10
16
  //#endregion
11
- export { createOnUncaughtError };
17
+ export { createOnUncaughtError, prodOnCaughtError };