vinext 0.0.54 → 0.0.55

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 (135) hide show
  1. package/README.md +1 -0
  2. package/dist/check.js +15 -3
  3. package/dist/check.js.map +1 -1
  4. package/dist/client/navigation-runtime.d.ts +1 -0
  5. package/dist/client/navigation-runtime.js +1 -1
  6. package/dist/client/navigation-runtime.js.map +1 -1
  7. package/dist/config/next-config.d.ts +14 -1
  8. package/dist/config/next-config.js +24 -4
  9. package/dist/config/next-config.js.map +1 -1
  10. package/dist/config/tsconfig-paths.d.ts +12 -3
  11. package/dist/config/tsconfig-paths.js +55 -24
  12. package/dist/config/tsconfig-paths.js.map +1 -1
  13. package/dist/entries/app-rsc-entry.d.ts +2 -1
  14. package/dist/entries/app-rsc-entry.js +12 -0
  15. package/dist/entries/app-rsc-entry.js.map +1 -1
  16. package/dist/entries/app-rsc-manifest.js +22 -5
  17. package/dist/entries/app-rsc-manifest.js.map +1 -1
  18. package/dist/entries/pages-server-entry.js +41 -4
  19. package/dist/entries/pages-server-entry.js.map +1 -1
  20. package/dist/index.js +81 -39
  21. package/dist/index.js.map +1 -1
  22. package/dist/plugins/import-meta-url.d.ts +16 -0
  23. package/dist/plugins/import-meta-url.js +193 -0
  24. package/dist/plugins/import-meta-url.js.map +1 -0
  25. package/dist/server/app-browser-action-result.d.ts +9 -16
  26. package/dist/server/app-browser-action-result.js +25 -14
  27. package/dist/server/app-browser-action-result.js.map +1 -1
  28. package/dist/server/app-browser-entry.js +171 -45
  29. package/dist/server/app-browser-entry.js.map +1 -1
  30. package/dist/server/app-browser-mpa-navigation.d.ts +16 -0
  31. package/dist/server/app-browser-mpa-navigation.js +36 -0
  32. package/dist/server/app-browser-mpa-navigation.js.map +1 -0
  33. package/dist/server/app-browser-popstate.d.ts +3 -1
  34. package/dist/server/app-browser-popstate.js +15 -1
  35. package/dist/server/app-browser-popstate.js.map +1 -1
  36. package/dist/server/app-browser-state.js +2 -1
  37. package/dist/server/app-browser-state.js.map +1 -1
  38. package/dist/server/app-layout-param-observation.d.ts +30 -0
  39. package/dist/server/app-layout-param-observation.js +130 -0
  40. package/dist/server/app-layout-param-observation.js.map +1 -0
  41. package/dist/server/app-page-boundary-render.js +2 -2
  42. package/dist/server/app-page-boundary-render.js.map +1 -1
  43. package/dist/server/app-page-dispatch.js +1 -1
  44. package/dist/server/app-page-params.d.ts +2 -1
  45. package/dist/server/app-page-params.js +14 -1
  46. package/dist/server/app-page-params.js.map +1 -1
  47. package/dist/server/app-page-probe.d.ts +12 -1
  48. package/dist/server/app-page-probe.js +116 -1
  49. package/dist/server/app-page-probe.js.map +1 -1
  50. package/dist/server/app-route-handler-response.js +1 -1
  51. package/dist/server/app-route-handler-response.js.map +1 -1
  52. package/dist/server/app-rsc-cache-busting.d.ts +3 -2
  53. package/dist/server/app-rsc-cache-busting.js +9 -7
  54. package/dist/server/app-rsc-cache-busting.js.map +1 -1
  55. package/dist/server/app-rsc-handler.js +11 -1
  56. package/dist/server/app-rsc-handler.js.map +1 -1
  57. package/dist/server/app-segment-config.d.ts +1 -1
  58. package/dist/server/app-segment-config.js +4 -1
  59. package/dist/server/app-segment-config.js.map +1 -1
  60. package/dist/server/app-server-action-execution.d.ts +5 -0
  61. package/dist/server/app-server-action-execution.js +198 -22
  62. package/dist/server/app-server-action-execution.js.map +1 -1
  63. package/dist/server/artifact-compatibility.d.ts +2 -1
  64. package/dist/server/artifact-compatibility.js +10 -1
  65. package/dist/server/artifact-compatibility.js.map +1 -1
  66. package/dist/server/client-reuse-manifest.d.ts +9 -4
  67. package/dist/server/client-reuse-manifest.js +2 -1
  68. package/dist/server/client-reuse-manifest.js.map +1 -1
  69. package/dist/server/dev-server.js +52 -10
  70. package/dist/server/dev-server.js.map +1 -1
  71. package/dist/server/document-initial-head.d.ts +7 -0
  72. package/dist/server/document-initial-head.js +35 -0
  73. package/dist/server/document-initial-head.js.map +1 -0
  74. package/dist/server/pages-document-initial-props.d.ts +84 -2
  75. package/dist/server/pages-document-initial-props.js +127 -1
  76. package/dist/server/pages-document-initial-props.js.map +1 -1
  77. package/dist/server/pages-node-compat.js +1 -1
  78. package/dist/server/pages-page-response.d.ts +14 -0
  79. package/dist/server/pages-page-response.js +31 -8
  80. package/dist/server/pages-page-response.js.map +1 -1
  81. package/dist/server/prod-server.js +13 -6
  82. package/dist/server/prod-server.js.map +1 -1
  83. package/dist/server/skip-cache-proof.d.ts +23 -2
  84. package/dist/server/skip-cache-proof.js +81 -12
  85. package/dist/server/skip-cache-proof.js.map +1 -1
  86. package/dist/server/static-layout-client-reuse-proof.d.ts +16 -0
  87. package/dist/server/static-layout-client-reuse-proof.js +35 -0
  88. package/dist/server/static-layout-client-reuse-proof.js.map +1 -0
  89. package/dist/shims/cache.d.ts +21 -1
  90. package/dist/shims/cache.js +101 -6
  91. package/dist/shims/cache.js.map +1 -1
  92. package/dist/shims/document.d.ts +6 -0
  93. package/dist/shims/document.js +7 -8
  94. package/dist/shims/document.js.map +1 -1
  95. package/dist/shims/error-boundary.d.ts +4 -4
  96. package/dist/shims/error-boundary.js +27 -28
  97. package/dist/shims/error-boundary.js.map +1 -1
  98. package/dist/shims/fetch-cache.d.ts +3 -1
  99. package/dist/shims/fetch-cache.js +16 -5
  100. package/dist/shims/fetch-cache.js.map +1 -1
  101. package/dist/shims/hash-scroll.d.ts +4 -1
  102. package/dist/shims/hash-scroll.js +13 -1
  103. package/dist/shims/hash-scroll.js.map +1 -1
  104. package/dist/shims/head-state.d.ts +1 -0
  105. package/dist/shims/head-state.js +18 -3
  106. package/dist/shims/head-state.js.map +1 -1
  107. package/dist/shims/head.d.ts +35 -1
  108. package/dist/shims/head.js +113 -14
  109. package/dist/shims/head.js.map +1 -1
  110. package/dist/shims/internal/pages-data-fetch-dedup.d.ts +56 -0
  111. package/dist/shims/internal/pages-data-fetch-dedup.js +70 -0
  112. package/dist/shims/internal/pages-data-fetch-dedup.js.map +1 -0
  113. package/dist/shims/link.js +28 -2
  114. package/dist/shims/link.js.map +1 -1
  115. package/dist/shims/navigation.d.ts +39 -1
  116. package/dist/shims/navigation.js +61 -13
  117. package/dist/shims/navigation.js.map +1 -1
  118. package/dist/shims/router.js +37 -17
  119. package/dist/shims/router.js.map +1 -1
  120. package/dist/shims/thenable-params.d.ts +5 -2
  121. package/dist/shims/thenable-params.js +25 -1
  122. package/dist/shims/thenable-params.js.map +1 -1
  123. package/dist/shims/unified-request-context.js +3 -0
  124. package/dist/shims/unified-request-context.js.map +1 -1
  125. package/dist/utils/client-build-manifest.d.ts +15 -0
  126. package/dist/utils/client-build-manifest.js +54 -0
  127. package/dist/utils/client-build-manifest.js.map +1 -0
  128. package/dist/utils/hash.js +1 -1
  129. package/dist/utils/hash.js.map +1 -1
  130. package/dist/utils/lazy-chunks.d.ts +1 -1
  131. package/dist/utils/lazy-chunks.js.map +1 -1
  132. package/dist/utils/vite-version.d.ts +11 -0
  133. package/dist/utils/vite-version.js +36 -0
  134. package/dist/utils/vite-version.js.map +1 -0
  135. package/package.json +2 -2
@@ -1,27 +1,28 @@
1
1
  import { stripBasePath } from "../utils/base-path.js";
2
- import { ACTION_REDIRECT_HEADER, VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_PARAMS_HEADER, VINEXT_RSC_REDIRECT_HEADER } from "./headers.js";
2
+ import { ACTION_REDIRECT_HEADER, ACTION_REDIRECT_STATUS_HEADER, VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_PARAMS_HEADER, VINEXT_RSC_REDIRECT_HEADER } from "./headers.js";
3
3
  import { DANGEROUS_URL_BLOCK_MESSAGE, isDangerousScheme } from "../shims/url-safety.js";
4
4
  import { AppElementsWire } from "./app-elements-wire.js";
5
5
  import { APP_RSC_RENDER_MODE_REFRESH_PRESERVE_UI } from "./app-rsc-render-mode.js";
6
6
  import { getMountedSlotIdsHeader, resolveVisitedResponseInterceptionContext } from "./app-elements.js";
7
+ import { AppRouterContext } from "../shims/internal/app-router-context.js";
7
8
  import { installWindowNext } from "../client/window-next.js";
8
- import { scrollToHashTargetOnNextFrame } from "../shims/hash-scroll.js";
9
+ import { retryScrollTo, scrollToHashTargetOnNextFrame } from "../shims/hash-scroll.js";
9
10
  import { getNavigationRuntime, registerNavigationRuntimeBootstrap, registerNavigationRuntimeFunctions } from "../client/navigation-runtime.js";
10
11
  import { notifyAppRouterTransitionStart } from "../client/instrumentation-client-state.js";
11
12
  import { resolveManifestNavigationInterceptionContext } from "./app-browser-interception-context.js";
12
13
  import { createHistoryStateWithNavigationMetadata, createHistoryStateWithPreviousNextUrl, readHistoryStatePreviousNextUrl, readHistoryStateTraversalIndex, resolveHistoryTraversalIntent } from "./app-history-state.js";
13
- import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, createRscRequestHeaders, createRscRequestUrl, getVinextRscCompatibilityId, resolveHardNavigationTargetFromRscResponse, resolveRscCompatibilityNavigationDecision } from "./app-rsc-cache-busting.js";
14
- import { AppRouterContext } from "../shims/internal/app-router-context.js";
15
- import { consumeAppRouterScrollIntent } from "../shims/app-router-scroll-state.js";
16
- import { __basePath, appRouterInstance, commitClientNavigationState, consumePrefetchResponse, createCachedRscResponseSnapshot, createClientNavigationRenderSnapshot, getClientNavigationRenderContext, getPrefetchCache, invalidatePrefetchCache, navigateClientSide, pushHistoryStateWithoutNotify, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, restoreRscResponse, setClientParams, setMountedSlotsHeader, setNavigationContext, setPendingPathname } from "../shims/navigation.js";
14
+ import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, createRscRequestHeaders, createRscRequestUrl, createServerActionRequestUrl, getVinextRscCompatibilityId, resolveHardNavigationTargetFromRscResponse, resolveRscCompatibilityNavigationDecision } from "./app-rsc-cache-busting.js";
15
+ import { beginAppRouterScrollIntent, consumeAppRouterScrollIntent } from "../shims/app-router-scroll-state.js";
16
+ import { __basePath, appRouterInstance, commitClientNavigationState, consumePrefetchResponseForNavigation, createCachedRscResponseSnapshot, createClientNavigationRenderSnapshot, decodeRedirectError, getClientNavigationRenderContext, getPrefetchCache, invalidatePrefetchCache, isRedirectError, pushHistoryStateWithoutNotify, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, restoreRscResponse, saveScrollPosition, setClientParams, setMountedSlotsHeader, setNavigationContext, setPendingPathname, useRouter } from "../shims/navigation.js";
17
17
  import { DevRecoveryBoundary, RedirectBoundary } from "../shims/error-boundary.js";
18
18
  import { AppRouterScrollCommitProvider } from "../shims/app-router-scroll.js";
19
19
  import { ElementsContext, Slot } from "../shims/slot.js";
20
20
  import "../client/instrumentation-client.js";
21
- import { createDiscardedServerActionRefreshScheduler, createServerActionInitiationSnapshot, isServerActionResult, parseServerActionRevalidationHeader, resolveServerActionRedirectLocation, shouldClearClientNavigationCachesForServerActionResult } from "./app-browser-action-result.js";
21
+ import { createDiscardedServerActionRefreshScheduler, createServerActionInitiationSnapshot, isServerActionResult, normalizeServerActionThrownValue, parseServerActionRevalidationHeader, readInvalidServerActionResponseError, resolveServerActionRedirectCompatibilityHardNavigationTarget, shouldCheckRscCompatibilityForServerActionResponse, shouldClearClientNavigationCachesForServerActionResult } from "./app-browser-action-result.js";
22
22
  import { chunksToReadableStream, createProgressiveRscStream, getVinextBrowserGlobal } from "./app-browser-stream.js";
23
23
  import { FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, VISITED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN, isCacheRestorableAppPayloadMetadata, resolveInterceptionContextFromPreviousNextUrl, resolveServerActionRequestState } from "./app-browser-state.js";
24
24
  import { clearHardNavigationLoopGuard, createAppBrowserNavigationController } from "./app-browser-navigation-controller.js";
25
+ import { AppBrowserMpaNavigationScheduler } from "./app-browser-mpa-navigation.js";
25
26
  import { consumeInitialFormState, createVinextHydrateRootOptions, hydrateRootInTransition } from "./app-browser-hydration.js";
26
27
  import { createPopstateRestoreHandler } from "./app-browser-popstate.js";
27
28
  import { createOnUncaughtError } from "./app-browser-error.js";
@@ -31,7 +32,7 @@ import { throwOnServerActionNotFound } from "./server-action-not-found.js";
31
32
  import { resolveRscRedirectLifecycleHop } from "./app-browser-rsc-redirect.js";
32
33
  import { createOptimisticRouteTemplate, getOptimisticPrefetchSourceKey, getOptimisticRouteTemplateKey, resolveOptimisticNavigationPayload } from "./app-optimistic-routing.js";
33
34
  import { removeStylesheetLinksCoveredByInlineCss } from "./app-inline-css-client.js";
34
- import { createElement, startTransition, use, useLayoutEffect, useRef, useState } from "react";
35
+ import { createElement, startTransition, use, useEffect, useLayoutEffect, useRef, useState } from "react";
35
36
  import { createFromFetch, createFromReadableStream, createTemporaryReferenceSet, encodeReply, setServerCallback } from "@vitejs/plugin-rsc/browser";
36
37
  import { hydrateRoot } from "react-dom/client";
37
38
  //#region src/server/app-browser-entry.ts
@@ -65,6 +66,16 @@ const discardedServerActionRefreshScheduler = createDiscardedServerActionRefresh
65
66
  getNavigationRuntime()?.functions.navigate?.(window.location.href, 0, "refresh", void 0, void 0, true);
66
67
  } });
67
68
  const NavigationCommitSignal = browserNavigationController.NavigationCommitSignal;
69
+ const ACTION_HTTP_FALLBACK_ROBOTS_META_ATTR = "data-vinext-action-http-fallback";
70
+ function syncServerActionHttpFallbackHead(status) {
71
+ document.head.querySelectorAll(`meta[${ACTION_HTTP_FALLBACK_ROBOTS_META_ATTR}="robots"]`).forEach((node) => node.remove());
72
+ if (status !== 404) return;
73
+ const robots = document.createElement("meta");
74
+ robots.name = "robots";
75
+ robots.content = "noindex";
76
+ robots.setAttribute(ACTION_HTTP_FALLBACK_ROBOTS_META_ATTR, "robots");
77
+ document.head.appendChild(robots);
78
+ }
68
79
  function parseEncodedJsonHeader(value) {
69
80
  if (!value) return null;
70
81
  try {
@@ -80,6 +91,8 @@ let latestClientParams = {};
80
91
  const visitedResponseCache = /* @__PURE__ */ new Map();
81
92
  let browserRouterStateHasEverCommitted = false;
82
93
  let pendingNavigationRecoveryHref = null;
94
+ const mpaNavigationScheduler = new AppBrowserMpaNavigationScheduler();
95
+ const unresolvedMpaNavigation = new Promise(() => {});
83
96
  let currentHistoryTraversalIndex = readHistoryStateTraversalIndex(window.history.state) ?? 0;
84
97
  let nextHistoryTraversalIndex = currentHistoryTraversalIndex;
85
98
  function allocateNavigationHistoryTraversalIndex(historyUpdateMode) {
@@ -271,6 +284,7 @@ function createNavigationCommitEffect(options) {
271
284
  };
272
285
  }
273
286
  async function renderNavigationPayload(payload, navigationSnapshot, targetHref, navId, historyUpdateMode, params, previousNextUrl, pendingRouterState, payloadOrigin, actionType = "navigate", operationLane = "navigation", traversalIntent = null, scrollIntent = null) {
287
+ syncServerActionHttpFallbackHead(null);
274
288
  try {
275
289
  return await browserNavigationController.renderNavigationPayload({
276
290
  actionType,
@@ -296,6 +310,52 @@ async function renderNavigationPayload(payload, navigationSnapshot, targetHref,
296
310
  throw error;
297
311
  }
298
312
  }
313
+ function resolveActionRedirectTarget(response) {
314
+ const actionRedirect = response.headers.get(ACTION_REDIRECT_HEADER);
315
+ if (!actionRedirect) return null;
316
+ if (isDangerousScheme(actionRedirect)) {
317
+ console.error(DANGEROUS_URL_BLOCK_MESSAGE);
318
+ return null;
319
+ }
320
+ try {
321
+ let redirectUrl;
322
+ if (actionRedirect.startsWith("/") || /^[a-z]+:/i.test(actionRedirect)) redirectUrl = new URL(actionRedirect, window.location.href);
323
+ else {
324
+ const baseParsed = new URL(window.location.href);
325
+ let baseDir = baseParsed.pathname;
326
+ if (!baseDir.endsWith("/")) baseDir = baseDir + "/";
327
+ redirectUrl = new URL(actionRedirect, `${baseParsed.origin}${baseDir}${baseParsed.search}`);
328
+ }
329
+ if (redirectUrl.origin !== window.location.origin) {
330
+ browserNavigationController.performHardNavigation(actionRedirect);
331
+ return null;
332
+ }
333
+ const statusHeader = response.headers.get(ACTION_REDIRECT_STATUS_HEADER);
334
+ const status = statusHeader ? parseInt(statusHeader, 10) : 307;
335
+ return {
336
+ href: redirectUrl.href,
337
+ type: response.headers.get("x-action-redirect-type") ?? "push",
338
+ status
339
+ };
340
+ } catch {
341
+ browserNavigationController.performHardNavigation(actionRedirect);
342
+ return null;
343
+ }
344
+ }
345
+ var ServerActionRedirectError = class extends Error {
346
+ digest;
347
+ handled = true;
348
+ constructor(target) {
349
+ super("NEXT_REDIRECT");
350
+ const redirectUrl = new URL(target.href, window.location.href);
351
+ const redirectHref = redirectUrl.pathname + redirectUrl.search + redirectUrl.hash;
352
+ const redirectType = target.type === "push" ? "push" : "replace";
353
+ this.digest = `NEXT_REDIRECT;${redirectType};${encodeURIComponent(redirectHref)};${target.status};`;
354
+ }
355
+ };
356
+ function createServerActionRedirectError(target) {
357
+ return new ServerActionRedirectError(target);
358
+ }
299
359
  async function commitSameUrlNavigatePayload(nextElements, actionInitiation, returnValue, revalidation = "none") {
300
360
  const navigationSnapshot = createClientNavigationRenderSnapshot(actionInitiation.href, actionInitiation.routerState.navigationSnapshot.params);
301
361
  return browserNavigationController.commitSameUrlNavigatePayload(nextElements, navigationSnapshot, returnValue, actionInitiation.routerState, {
@@ -399,6 +459,35 @@ function getRequestState(navigationKind, targetPathname, previousNextUrlOverride
399
459
  function handleDevRecoveryBoundaryCatch(resetKey) {
400
460
  browserNavigationController.drainPrePaintEffects(resetKey);
401
461
  }
462
+ function isMpaNavigationState(value) {
463
+ return value !== null && typeof value === "object" && "kind" in value && value.kind === "mpa-navigation";
464
+ }
465
+ function performMpaNavigation(href, historyUpdateMode) {
466
+ mpaNavigationScheduler.navigate(window, href, historyUpdateMode);
467
+ }
468
+ function AppRouterRedirectBridge({ children }) {
469
+ const router = useRouter();
470
+ useEffect(() => {
471
+ const handleUnhandledRedirect = (event) => {
472
+ const error = "reason" in event ? event.reason : event.error;
473
+ if (!isRedirectError(error)) return;
474
+ const result = decodeRedirectError(error.digest);
475
+ if (!result) return;
476
+ event.preventDefault();
477
+ startTransition(() => {
478
+ if (result.type === "push") router.push(result.url);
479
+ else router.replace(result.url);
480
+ });
481
+ };
482
+ window.addEventListener("error", handleUnhandledRedirect);
483
+ window.addEventListener("unhandledrejection", handleUnhandledRedirect);
484
+ return () => {
485
+ window.removeEventListener("error", handleUnhandledRedirect);
486
+ window.removeEventListener("unhandledrejection", handleUnhandledRedirect);
487
+ };
488
+ }, [router]);
489
+ return children ?? null;
490
+ }
402
491
  function decodeAppElementsPromise(payload) {
403
492
  return Promise.resolve(payload).then((elements) => AppElementsWire.decode(elements));
404
493
  }
@@ -420,11 +509,26 @@ function BrowserRoot({ initialElements, initialNavigationSnapshot }) {
420
509
  slotBindings: initialMetadata.slotBindings,
421
510
  visibleCommitVersion: 0
422
511
  });
512
+ if (isMpaNavigationState(treeStateValue)) {
513
+ performMpaNavigation(treeStateValue.href, treeStateValue.historyUpdateMode);
514
+ throw unresolvedMpaNavigation;
515
+ }
423
516
  const treeState = isRouterStatePromise(treeStateValue) ? use(treeStateValue) : treeStateValue;
424
517
  const stateRef = useRef(treeState);
425
518
  stateRef.current = treeState;
426
519
  useLayoutEffect(() => {
427
- const detach = browserNavigationController.attachBrowserRouterState(setTreeStateValue, stateRef);
520
+ const setAppRouterStateValue = (value) => {
521
+ setTreeStateValue(value);
522
+ };
523
+ const detach = browserNavigationController.attachBrowserRouterState(setAppRouterStateValue, stateRef);
524
+ registerNavigationRuntimeFunctions({ navigateExternal: (href, historyUpdateMode) => {
525
+ setTreeStateValue({
526
+ href,
527
+ historyUpdateMode,
528
+ kind: "mpa-navigation"
529
+ });
530
+ return new Promise(() => {});
531
+ } });
428
532
  browserRouterStateHasEverCommitted = true;
429
533
  const hydratedAt = performance.now();
430
534
  window.__VINEXT_HYDRATED_AT = hydratedAt;
@@ -432,6 +536,7 @@ function BrowserRoot({ initialElements, initialNavigationSnapshot }) {
432
536
  window.__NEXT_HYDRATED_AT = hydratedAt;
433
537
  window.__NEXT_HYDRATED_CB?.();
434
538
  return () => {
539
+ registerNavigationRuntimeFunctions({ navigateExternal: void 0 });
435
540
  detach();
436
541
  setMountedSlotsHeader(null);
437
542
  };
@@ -449,7 +554,7 @@ function BrowserRoot({ initialElements, initialNavigationSnapshot }) {
449
554
  }), "", window.location.href);
450
555
  }, [treeState.previousNextUrl, treeState.renderId]);
451
556
  const routeTree = createElement(RedirectBoundary, null, createElement(NavigationCommitSignal, { renderId: treeState.renderId }, createElement(ElementsContext.Provider, { value: treeState.elements }, createElement(Slot, { id: treeState.routeId }))));
452
- const innerTree = AppRouterContext ? createElement(AppRouterContext.Provider, { value: appRouterInstance }, routeTree) : routeTree;
557
+ const innerTree = AppRouterContext ? createElement(AppRouterContext.Provider, { value: appRouterInstance }, createElement(AppRouterRedirectBridge, null, routeTree)) : routeTree;
453
558
  const committedTree = import.meta.env.DEV ? createElement(DevRecoveryBoundary, {
454
559
  resetKey: treeState.renderId,
455
560
  onCatch: handleDevRecoveryBoundaryCatch
@@ -466,16 +571,15 @@ function restoreHydrationNavigationContext(pathname, searchParams, params) {
466
571
  params
467
572
  });
468
573
  }
469
- function restorePopstateScrollPosition(state) {
574
+ function restorePopstateScrollPosition(state, options) {
575
+ const shouldContinue = options?.shouldContinue ?? (() => true);
576
+ if (!shouldContinue()) return;
470
577
  if (!(state && typeof state === "object" && "__vinext_scrollY" in state)) {
471
578
  if (window.location.hash) scrollToHashTargetOnNextFrame(window.location.hash);
472
579
  return;
473
580
  }
474
581
  const y = Number(state.__vinext_scrollY);
475
- const x = "__vinext_scrollX" in state ? Number(state.__vinext_scrollX) : 0;
476
- requestAnimationFrame(() => {
477
- window.scrollTo(x, y);
478
- });
582
+ retryScrollTo("__vinext_scrollX" in state ? Number(state.__vinext_scrollX) : 0, y, { shouldContinue });
479
583
  }
480
584
  function isSameAppRoutePopstateTarget(href) {
481
585
  if (!hasBrowserRouterState()) return false;
@@ -566,6 +670,7 @@ function applyRuntimeRscBootstrap(rsc) {
566
670
  }
567
671
  function registerServerActionCallback() {
568
672
  setServerCallback(async (id, args) => {
673
+ syncServerActionHttpFallbackHead(null);
569
674
  const temporaryReferences = createTemporaryReferenceSet();
570
675
  const actionInitiation = createActionInitiationSnapshot();
571
676
  syncCurrentHistoryStatePreviousNextUrl(actionInitiation.routerState.previousNextUrl);
@@ -576,39 +681,26 @@ function registerServerActionCallback() {
576
681
  elements: actionInitiation.routerState.elements,
577
682
  previousNextUrl: actionInitiation.routerState.previousNextUrl
578
683
  });
579
- const fetchResponse = await fetch(await createRscRequestUrl(actionInitiation.path, headers), {
684
+ const fetchResponse = await fetch(createServerActionRequestUrl(actionInitiation.path), {
580
685
  method: "POST",
581
686
  headers,
582
687
  body
583
688
  });
584
689
  throwOnServerActionNotFound(fetchResponse, id);
585
- const actionRedirect = fetchResponse.headers.get(ACTION_REDIRECT_HEADER);
586
- if (actionRedirect) {
587
- if (isDangerousScheme(actionRedirect)) {
588
- console.error(DANGEROUS_URL_BLOCK_MESSAGE);
589
- return;
590
- }
591
- const historyUpdateMode = (fetchResponse.headers.get("x-action-redirect-type") ?? "push") === "push" ? "push" : "replace";
592
- const hardNavigationMode = historyUpdateMode === "push" ? "assign" : "replace";
593
- let redirectLocation;
594
- try {
595
- redirectLocation = resolveServerActionRedirectLocation({
596
- currentHref: actionInitiation.href,
597
- location: actionRedirect,
598
- origin: window.location.origin
599
- });
600
- } catch {
601
- clearClientNavigationCaches();
602
- browserNavigationController.performHardNavigation(actionRedirect, hardNavigationMode);
603
- return;
604
- }
690
+ const hasActionRedirect = fetchResponse.headers.has(ACTION_REDIRECT_HEADER);
691
+ const actionRedirectTarget = resolveActionRedirectTarget(fetchResponse);
692
+ if (hasActionRedirect && !actionRedirectTarget) return;
693
+ const actionRedirectCompatibilityHardNavigationTarget = resolveServerActionRedirectCompatibilityHardNavigationTarget({
694
+ actionRedirectHref: actionRedirectTarget?.href ?? null,
695
+ clientCompatibilityId: CLIENT_RSC_COMPATIBILITY_ID,
696
+ response: fetchResponse
697
+ });
698
+ if (actionRedirectCompatibilityHardNavigationTarget) {
605
699
  clearClientNavigationCaches();
606
- startTransition(() => {
607
- navigateClientSide(redirectLocation.href, historyUpdateMode, true, true);
608
- });
700
+ browserNavigationController.performHardNavigation(actionRedirectCompatibilityHardNavigationTarget, actionRedirectTarget?.type === "push" ? "assign" : "replace");
609
701
  return;
610
702
  }
611
- if (resolveRscCompatibilityNavigationDecision({
703
+ if (!actionRedirectTarget && shouldCheckRscCompatibilityForServerActionResponse(fetchResponse) && resolveRscCompatibilityNavigationDecision({
612
704
  clientCompatibilityId: CLIENT_RSC_COMPATIBILITY_ID,
613
705
  currentHref: actionInitiation.href,
614
706
  origin: window.location.origin,
@@ -619,12 +711,44 @@ function registerServerActionCallback() {
619
711
  return;
620
712
  }
621
713
  const revalidation = parseServerActionRevalidationHeader(fetchResponse.headers);
622
- const result = await createFromFetch(Promise.resolve(fetchResponse), { temporaryReferences });
714
+ const invalidResponseError = await readInvalidServerActionResponseError(fetchResponse.clone(), actionRedirectTarget !== null);
715
+ if (invalidResponseError) throw invalidResponseError;
716
+ if (actionRedirectTarget && !shouldCheckRscCompatibilityForServerActionResponse(fetchResponse)) {
717
+ browserNavigationController.performHardNavigation(actionRedirectTarget.href);
718
+ return;
719
+ }
720
+ const flightResponse = fetchResponse.status === 303 ? new Response(fetchResponse.body, {
721
+ headers: fetchResponse.headers,
722
+ status: 200,
723
+ statusText: "OK"
724
+ }) : fetchResponse;
725
+ const result = await createFromFetch(Promise.resolve(flightResponse), { temporaryReferences });
623
726
  if (shouldClearClientNavigationCachesForServerActionResult(result, revalidation)) clearClientNavigationCaches();
727
+ if (actionRedirectTarget) {
728
+ if (isServerActionResult(result) && result.root !== void 0) {
729
+ const decoded = AppElementsWire.decode(result.root);
730
+ const hashIdx = actionRedirectTarget.href.indexOf("#");
731
+ const actionScrollIntent = beginAppRouterScrollIntent((hashIdx !== -1 ? actionRedirectTarget.href.slice(hashIdx) : "") || null);
732
+ if (actionRedirectTarget.type === "push") saveScrollPosition();
733
+ renderNavigationPayload(Promise.resolve(decoded), createClientNavigationRenderSnapshot(actionRedirectTarget.href, actionInitiation.routerState.navigationSnapshot.params), actionRedirectTarget.href, actionInitiation.navigationId, actionRedirectTarget.type === "push" ? "push" : "replace", {}, null, null, FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, actionRedirectTarget.type === "push" ? "navigate" : "replace", "server-action", null, actionScrollIntent).catch(() => {
734
+ browserNavigationController.performHardNavigation(actionRedirectTarget.href);
735
+ });
736
+ throw createServerActionRedirectError(actionRedirectTarget);
737
+ }
738
+ browserNavigationController.performHardNavigation(actionRedirectTarget.href);
739
+ return;
740
+ }
741
+ syncServerActionHttpFallbackHead(isServerActionResult(result) && result.root !== void 0 ? null : fetchResponse.status);
624
742
  if (isServerActionResult(result)) {
625
- if (result.root !== void 0) return commitSameUrlNavigatePayload(Promise.resolve(AppElementsWire.decode(result.root)), actionInitiation, result.returnValue, revalidation);
743
+ if (result.root !== void 0) {
744
+ const returnValue = result.returnValue && !result.returnValue.ok ? {
745
+ ok: false,
746
+ data: normalizeServerActionThrownValue(result.returnValue.data, fetchResponse.status)
747
+ } : result.returnValue;
748
+ return commitSameUrlNavigatePayload(Promise.resolve(AppElementsWire.decode(result.root)), actionInitiation, returnValue, revalidation);
749
+ }
626
750
  if (result.returnValue) {
627
- if (!result.returnValue.ok) throw result.returnValue.data;
751
+ if (!result.returnValue.ok) throw normalizeServerActionThrownValue(result.returnValue.data, fetchResponse.status);
628
752
  return result.returnValue.data;
629
753
  }
630
754
  return;
@@ -733,7 +857,8 @@ function bootstrapHydration(rscStream) {
733
857
  let navResponse;
734
858
  let navResponseUrl = null;
735
859
  if (navigationKind !== "refresh") {
736
- const prefetchedResponse = consumePrefetchResponse(rscUrl, requestInterceptionContext, mountedSlotsHeader);
860
+ const prefetchedResponse = await consumePrefetchResponseForNavigation(rscUrl, requestInterceptionContext, mountedSlotsHeader, { shouldConsume: () => browserNavigationController.isCurrentNavigation(navId) });
861
+ if (!browserNavigationController.isCurrentNavigation(navId)) return;
737
862
  if (prefetchedResponse) {
738
863
  navResponse = restoreRscResponse(prefetchedResponse, false);
739
864
  navResponseUrl = prefetchedResponse.url;
@@ -914,8 +1039,9 @@ if (typeof document !== "undefined") {
914
1039
  window.addEventListener("pagehide", () => {
915
1040
  isPageUnloading = true;
916
1041
  });
917
- window.addEventListener("pageshow", () => {
1042
+ window.addEventListener("pageshow", (event) => {
918
1043
  isPageUnloading = false;
1044
+ if (event.persisted) mpaNavigationScheduler.reset();
919
1045
  });
920
1046
  main();
921
1047
  }