vinext 0.1.1 → 0.1.3
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.
- package/README.md +2 -5
- package/dist/build/client-build-config.d.ts +7 -1
- package/dist/build/client-build-config.js +9 -1
- package/dist/build/prerender.d.ts +9 -1
- package/dist/build/prerender.js +41 -12
- package/dist/build/run-prerender.d.ts +10 -2
- package/dist/build/run-prerender.js +15 -1
- package/dist/check.js +4 -3
- package/dist/client/app-nav-failure-handler.d.ts +8 -0
- package/dist/client/app-nav-failure-handler.js +44 -0
- package/dist/client/navigation-runtime.d.ts +3 -2
- package/dist/client/vinext-next-data.d.ts +18 -1
- package/dist/client/window-next.d.ts +8 -5
- package/dist/client/window-next.js +12 -1
- package/dist/cloudflare/src/cache/cdn-adapter.runtime.js +6 -1
- package/dist/config/config-matchers.d.ts +11 -4
- package/dist/config/config-matchers.js +88 -16
- package/dist/config/next-config.d.ts +59 -4
- package/dist/config/next-config.js +149 -48
- package/dist/deploy.d.ts +30 -11
- package/dist/deploy.js +189 -101
- package/dist/entries/app-browser-entry.d.ts +9 -3
- package/dist/entries/app-browser-entry.js +21 -3
- package/dist/entries/app-rsc-entry.d.ts +2 -0
- package/dist/entries/app-rsc-entry.js +71 -6
- package/dist/entries/app-rsc-manifest.js +2 -0
- package/dist/entries/app-ssr-entry.js +1 -1
- package/dist/entries/pages-client-entry.js +54 -9
- package/dist/entries/pages-server-entry.js +48 -11
- package/dist/index.d.ts +0 -2
- package/dist/index.js +285 -139
- package/dist/plugins/dynamic-preload-metadata.d.ts +13 -0
- package/dist/plugins/dynamic-preload-metadata.js +415 -0
- package/dist/plugins/extensionless-dynamic-import.d.ts +6 -0
- package/dist/plugins/extensionless-dynamic-import.js +152 -0
- package/dist/plugins/og-assets.js +2 -2
- package/dist/plugins/optimize-imports.d.ts +10 -5
- package/dist/plugins/optimize-imports.js +27 -21
- package/dist/plugins/postcss.js +7 -7
- package/dist/plugins/sass.d.ts +53 -24
- package/dist/plugins/sass.js +249 -1
- package/dist/plugins/typeof-window.d.ts +14 -0
- package/dist/plugins/typeof-window.js +150 -0
- package/dist/plugins/wasm-module-import.d.ts +15 -0
- package/dist/plugins/wasm-module-import.js +50 -0
- package/dist/routing/app-route-graph.d.ts +25 -2
- package/dist/routing/app-route-graph.js +91 -22
- package/dist/routing/file-matcher.d.ts +10 -1
- package/dist/routing/file-matcher.js +23 -2
- package/dist/routing/pages-router.js +3 -3
- package/dist/routing/utils.d.ts +35 -6
- package/dist/routing/utils.js +59 -7
- package/dist/server/api-handler.d.ts +6 -1
- package/dist/server/api-handler.js +21 -15
- package/dist/server/app-browser-action-result.d.ts +19 -6
- package/dist/server/app-browser-action-result.js +19 -10
- package/dist/server/app-browser-entry.js +269 -297
- package/dist/server/app-browser-error.d.ts +10 -3
- package/dist/server/app-browser-error.js +47 -6
- package/dist/server/app-browser-history-controller.d.ts +104 -0
- package/dist/server/app-browser-history-controller.js +210 -0
- package/dist/server/app-browser-hydration.d.ts +2 -0
- package/dist/server/app-browser-hydration.js +1 -0
- package/dist/server/app-browser-navigation-controller.d.ts +7 -4
- package/dist/server/app-browser-navigation-controller.js +33 -9
- package/dist/server/app-browser-rsc-redirect.d.ts +11 -2
- package/dist/server/app-browser-rsc-redirect.js +30 -8
- package/dist/server/app-browser-server-action-navigation.d.ts +6 -0
- package/dist/server/app-browser-server-action-navigation.js +9 -0
- package/dist/server/app-browser-state.js +4 -7
- package/dist/server/app-browser-stream.js +86 -43
- package/dist/server/app-browser-visible-commit.js +1 -1
- package/dist/server/app-elements-wire.d.ts +6 -1
- package/dist/server/app-elements-wire.js +14 -4
- package/dist/server/app-elements.d.ts +2 -2
- package/dist/server/app-elements.js +2 -2
- package/dist/server/app-fallback-renderer.d.ts +3 -1
- package/dist/server/app-fallback-renderer.js +6 -2
- package/dist/server/app-middleware.js +1 -0
- package/dist/server/app-optimistic-routing.js +24 -3
- package/dist/server/app-page-boundary-render.d.ts +3 -1
- package/dist/server/app-page-boundary-render.js +31 -16
- package/dist/server/app-page-cache-render.d.ts +53 -0
- package/dist/server/app-page-cache-render.js +91 -0
- package/dist/server/app-page-cache.d.ts +16 -2
- package/dist/server/app-page-cache.js +71 -8
- package/dist/server/app-page-dispatch.d.ts +34 -0
- package/dist/server/app-page-dispatch.js +167 -97
- package/dist/server/app-page-element-builder.d.ts +23 -2
- package/dist/server/app-page-element-builder.js +42 -10
- package/dist/server/app-page-execution.d.ts +7 -2
- package/dist/server/app-page-execution.js +53 -18
- package/dist/server/app-page-probe.d.ts +1 -0
- package/dist/server/app-page-probe.js +4 -0
- package/dist/server/app-page-render-observation.d.ts +3 -1
- package/dist/server/app-page-render-observation.js +17 -1
- package/dist/server/app-page-render.d.ts +13 -2
- package/dist/server/app-page-render.js +48 -17
- package/dist/server/app-page-request.d.ts +3 -0
- package/dist/server/app-page-request.js +5 -3
- package/dist/server/app-page-response.js +1 -1
- package/dist/server/app-page-route-wiring.d.ts +5 -1
- package/dist/server/app-page-route-wiring.js +21 -11
- package/dist/server/app-page-stream.d.ts +16 -9
- package/dist/server/app-page-stream.js +12 -9
- package/dist/server/app-pages-bridge.d.ts +18 -0
- package/dist/server/app-pages-bridge.js +22 -5
- package/dist/server/app-ppr-fallback-shell-render.d.ts +17 -0
- package/dist/server/app-ppr-fallback-shell-render.js +26 -0
- package/dist/server/app-ppr-fallback-shell.d.ts +13 -1
- package/dist/server/app-ppr-fallback-shell.js +8 -1
- package/dist/server/app-route-handler-dispatch.js +9 -2
- package/dist/server/app-route-handler-policy.d.ts +1 -0
- package/dist/server/app-route-handler-response.js +11 -10
- package/dist/server/app-route-handler-runtime.js +12 -1
- package/dist/server/app-router-entry.js +5 -0
- package/dist/server/app-rsc-cache-busting.js +2 -0
- package/dist/server/app-rsc-handler.d.ts +25 -0
- package/dist/server/app-rsc-handler.js +153 -53
- package/dist/server/app-rsc-response-finalizer.js +1 -1
- package/dist/server/app-rsc-route-matching.d.ts +3 -0
- package/dist/server/app-rsc-route-matching.js +2 -0
- package/dist/server/app-segment-config.d.ts +9 -1
- package/dist/server/app-segment-config.js +12 -3
- package/dist/server/app-server-action-execution.d.ts +12 -0
- package/dist/server/app-server-action-execution.js +47 -15
- package/dist/server/app-ssr-entry.d.ts +2 -0
- package/dist/server/app-ssr-entry.js +81 -8
- package/dist/server/app-ssr-stream.js +9 -1
- package/dist/server/cache-control.js +4 -0
- package/dist/server/dev-lockfile.js +2 -1
- package/dist/server/dev-server.d.ts +2 -2
- package/dist/server/dev-server.js +287 -63
- package/dist/server/headers.d.ts +8 -1
- package/dist/server/headers.js +8 -1
- package/dist/server/hybrid-route-priority.d.ts +22 -0
- package/dist/server/hybrid-route-priority.js +33 -0
- package/dist/server/image-optimization.d.ts +18 -9
- package/dist/server/image-optimization.js +37 -23
- package/dist/server/implicit-tags.d.ts +2 -1
- package/dist/server/implicit-tags.js +4 -1
- package/dist/server/instrumentation-runtime.d.ts +6 -0
- package/dist/server/instrumentation-runtime.js +8 -0
- package/dist/server/isr-decision.d.ts +79 -0
- package/dist/server/isr-decision.js +70 -0
- package/dist/server/metadata-route-response.js +5 -3
- package/dist/server/middleware-runtime.d.ts +13 -0
- package/dist/server/middleware-runtime.js +11 -7
- package/dist/server/middleware.js +1 -0
- package/dist/server/navigation-planner.d.ts +186 -22
- package/dist/server/navigation-planner.js +302 -0
- package/dist/server/navigation-trace.d.ts +18 -1
- package/dist/server/navigation-trace.js +18 -1
- package/dist/server/normalize-path.d.ts +0 -8
- package/dist/server/normalize-path.js +3 -1
- package/dist/server/otel-tracer-extension.d.ts +45 -0
- package/dist/server/otel-tracer-extension.js +89 -0
- package/dist/server/pages-api-route.d.ts +20 -3
- package/dist/server/pages-api-route.js +19 -3
- package/dist/server/pages-asset-tags.d.ts +16 -4
- package/dist/server/pages-asset-tags.js +22 -12
- package/dist/server/pages-data-route.d.ts +8 -1
- package/dist/server/pages-data-route.js +16 -3
- package/dist/server/pages-get-initial-props.d.ts +54 -4
- package/dist/server/pages-get-initial-props.js +43 -1
- package/dist/server/pages-node-compat.d.ts +3 -11
- package/dist/server/pages-node-compat.js +175 -122
- package/dist/server/pages-page-data.d.ts +39 -2
- package/dist/server/pages-page-data.js +261 -46
- package/dist/server/pages-page-handler.d.ts +5 -2
- package/dist/server/pages-page-handler.js +78 -25
- package/dist/server/pages-page-response.d.ts +47 -2
- package/dist/server/pages-page-response.js +73 -9
- package/dist/server/pages-readiness.d.ts +1 -1
- package/dist/server/pages-request-pipeline.d.ts +16 -1
- package/dist/server/pages-request-pipeline.js +96 -38
- package/dist/server/pregenerated-concrete-paths.d.ts +1 -17
- package/dist/server/pregenerated-concrete-paths.js +2 -19
- package/dist/server/prerender-manifest.d.ts +33 -0
- package/dist/server/prerender-manifest.js +54 -0
- package/dist/server/prerender-route-params.d.ts +1 -2
- package/dist/server/prod-server.d.ts +39 -1
- package/dist/server/prod-server.js +107 -37
- package/dist/server/request-pipeline.d.ts +3 -15
- package/dist/server/request-pipeline.js +58 -47
- package/dist/server/rsc-stream-hints.d.ts +5 -1
- package/dist/server/rsc-stream-hints.js +6 -1
- package/dist/server/seed-cache.js +10 -18
- package/dist/shims/app-router-scroll-state.d.ts +3 -1
- package/dist/shims/app-router-scroll-state.js +14 -2
- package/dist/shims/app-router-scroll.d.ts +3 -0
- package/dist/shims/app-router-scroll.js +28 -18
- package/dist/shims/cache-runtime.js +12 -4
- package/dist/shims/cache.d.ts +1 -0
- package/dist/shims/cache.js +1 -1
- package/dist/shims/cdn-cache.d.ts +5 -5
- package/dist/shims/dynamic-preload-chunks.d.ts +8 -0
- package/dist/shims/dynamic-preload-chunks.js +79 -0
- package/dist/shims/dynamic.d.ts +4 -0
- package/dist/shims/dynamic.js +4 -2
- package/dist/shims/error-boundary.d.ts +6 -4
- package/dist/shims/error-boundary.js +7 -0
- package/dist/shims/error.js +38 -11
- package/dist/shims/error.react-server.d.ts +9 -0
- package/dist/shims/error.react-server.js +6 -0
- package/dist/shims/fetch-cache.d.ts +11 -1
- package/dist/shims/fetch-cache.js +55 -20
- package/dist/shims/hash-scroll.js +6 -1
- package/dist/shims/head.js +6 -1
- package/dist/shims/headers.d.ts +16 -2
- package/dist/shims/headers.js +66 -5
- package/dist/shims/image-config.js +7 -1
- package/dist/shims/internal/als-registry.js +28 -1
- package/dist/shims/internal/app-route-detection.d.ts +6 -3
- package/dist/shims/internal/app-route-detection.js +18 -23
- package/dist/shims/internal/app-router-context.d.ts +5 -0
- package/dist/shims/internal/hybrid-client-route-owner.d.ts +31 -0
- package/dist/shims/internal/hybrid-client-route-owner.js +143 -0
- package/dist/shims/internal/navigation-untracked.d.ts +35 -0
- package/dist/shims/internal/navigation-untracked.js +55 -0
- package/dist/shims/internal/pages-data-target.d.ts +7 -2
- package/dist/shims/internal/pages-data-target.js +17 -8
- package/dist/shims/internal/pages-router-accessor.d.ts +19 -0
- package/dist/shims/internal/pages-router-accessor.js +13 -0
- package/dist/shims/internal/router-context.d.ts +2 -1
- package/dist/shims/internal/router-context.js +3 -1
- package/dist/shims/link.js +12 -5
- package/dist/shims/metadata.d.ts +6 -2
- package/dist/shims/metadata.js +32 -14
- package/dist/shims/navigation.d.ts +14 -17
- package/dist/shims/navigation.js +93 -46
- package/dist/shims/ppr-fallback-shell.d.ts +5 -1
- package/dist/shims/ppr-fallback-shell.js +28 -7
- package/dist/shims/router.d.ts +13 -2
- package/dist/shims/router.js +434 -116
- package/dist/shims/script-nonce-context.d.ts +1 -1
- package/dist/shims/script-nonce-context.js +11 -3
- package/dist/shims/server.d.ts +33 -2
- package/dist/shims/server.js +75 -18
- package/dist/shims/slot.js +1 -1
- package/dist/shims/unified-request-context.js +2 -0
- package/dist/typegen.js +1 -0
- package/dist/utils/built-asset-url.d.ts +4 -0
- package/dist/utils/built-asset-url.js +11 -0
- package/dist/utils/client-build-manifest.js +15 -5
- package/dist/utils/client-runtime-metadata.d.ts +45 -0
- package/dist/utils/client-runtime-metadata.js +63 -0
- package/dist/utils/commonjs-loader.d.ts +16 -0
- package/dist/utils/commonjs-loader.js +100 -0
- package/dist/utils/deployment-id.d.ts +8 -0
- package/dist/utils/deployment-id.js +22 -0
- package/dist/utils/hash.d.ts +17 -1
- package/dist/utils/hash.js +36 -1
- package/dist/utils/html-limited-bots.d.ts +18 -1
- package/dist/utils/html-limited-bots.js +23 -1
- package/dist/utils/lazy-chunks.d.ts +27 -1
- package/dist/utils/lazy-chunks.js +65 -1
- package/dist/utils/manifest-paths.d.ts +20 -2
- package/dist/utils/manifest-paths.js +38 -3
- package/dist/utils/parse-cookie.d.ts +13 -0
- package/dist/utils/parse-cookie.js +52 -0
- package/dist/utils/path.d.ts +8 -1
- package/dist/utils/path.js +13 -1
- package/package.json +2 -2
- package/dist/shims/internal/parse-cookie-header.d.ts +0 -14
- package/dist/shims/internal/parse-cookie-header.js +0 -30
|
@@ -1,43 +1,46 @@
|
|
|
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";
|
|
5
4
|
import { APP_RSC_RENDER_MODE_REFRESH_PRESERVE_UI } from "./app-rsc-render-mode.js";
|
|
6
5
|
import { getMountedSlotIdsHeader, resolveVisitedResponseInterceptionContext } from "./app-elements.js";
|
|
7
6
|
import { AppRouterContext } from "../shims/internal/app-router-context.js";
|
|
8
|
-
import { installWindowNext } from "../client/window-next.js";
|
|
7
|
+
import { installWindowNext, setWindowNextInternalSourcePage } from "../client/window-next.js";
|
|
9
8
|
import { retryScrollTo, scrollToHashTargetOnNextFrame } from "../shims/hash-scroll.js";
|
|
10
9
|
import { getNavigationRuntime, registerNavigationRuntimeBootstrap, registerNavigationRuntimeFunctions } from "../client/navigation-runtime.js";
|
|
11
10
|
import { notifyAppRouterTransitionStart } from "../client/instrumentation-client-state.js";
|
|
11
|
+
import { clearAppNavigationFailureTarget, installAppNavigationFailureListeners } from "../client/app-nav-failure-handler.js";
|
|
12
12
|
import { resolveManifestNavigationInterceptionContext, resolveMiddlewareRewriteNavigationInterceptionContext } from "./app-browser-interception-context.js";
|
|
13
|
-
import {
|
|
14
|
-
import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, createRscRequestHeaders, createRscRequestUrl, createServerActionRequestUrl, getVinextRscCompatibilityId
|
|
13
|
+
import { readHistoryStatePreviousNextUrl } from "./app-history-state.js";
|
|
14
|
+
import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, createRscRequestHeaders, createRscRequestUrl, createServerActionRequestUrl, getVinextRscCompatibilityId } from "./app-rsc-cache-busting.js";
|
|
15
15
|
import { AppBrowserMpaNavigationScheduler } from "./app-browser-mpa-navigation.js";
|
|
16
|
+
import { navigationPlanner } from "./navigation-planner.js";
|
|
16
17
|
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";
|
|
18
|
-
import
|
|
18
|
+
import { __basePath, appRouterInstance, commitClientNavigationState, consumePrefetchResponseForNavigation, createCachedRscResponseSnapshot, createClientNavigationRenderSnapshot, createSnapshotPathAndSearch, decodeRedirectError, getBfcacheIdMapContext, getClientNavigationRenderContext, getPrefetchCache, hasPrefetchCacheEntryForNavigation, invalidatePrefetchCache, isRedirectError, pushHistoryStateWithoutNotify, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, resolvePrefetchCacheEntryMountedSlotsHeader, restoreRscResponse, saveScrollPosition, setClientParams, setMountedSlotsHeader, setNavigationContext, setPendingPathname, useRouter } from "../shims/navigation.js";
|
|
19
|
+
import DefaultGlobalError from "../shims/default-global-error.js";
|
|
20
|
+
import { DevRecoveryBoundary, GlobalErrorBoundary, RedirectBoundary } from "../shims/error-boundary.js";
|
|
19
21
|
import { AppRouterScrollCommitProvider } from "../shims/app-router-scroll.js";
|
|
20
22
|
import { BfcacheStateKeyMapContext, ElementsContext, Slot } from "../shims/slot.js";
|
|
21
23
|
import "../client/instrumentation-client.js";
|
|
22
|
-
import { createDiscardedServerActionRefreshScheduler, createServerActionInitiationSnapshot, isServerActionResult, normalizeServerActionThrownValue, parseServerActionRevalidationHeader, readInvalidServerActionResponseError,
|
|
24
|
+
import { createDiscardedServerActionRefreshScheduler, createServerActionInitiationSnapshot, createServerActionResultFacts, isServerActionResult, normalizeServerActionThrownValue, parseServerActionRevalidationHeader, readInvalidServerActionResponseError, shouldClearClientNavigationCachesForServerActionResult } from "./app-browser-action-result.js";
|
|
23
25
|
import { createClientReuseManifestHeaderFromVisibleAppState } from "./app-browser-client-reuse-manifest.js";
|
|
24
26
|
import { chunksToReadableStream, createProgressiveRscStream, getVinextBrowserGlobal } from "./app-browser-stream.js";
|
|
25
27
|
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
|
|
28
|
+
import { clearHardNavigationLoopGuard, createAppBrowserNavigationController, createBasePathStrippedPathAndSearch } from "./app-browser-navigation-controller.js";
|
|
29
|
+
import { applyServerActionResultDecision } from "./app-browser-server-action-navigation.js";
|
|
27
30
|
import { consumeInitialFormState, createVinextHydrateRootOptions, hydrateRootInTransition } from "./app-browser-hydration.js";
|
|
31
|
+
import { AppBrowserHistoryController } from "./app-browser-history-controller.js";
|
|
28
32
|
import { createVisitedResponseCacheEntry, isVisitedResponseCacheEntryFresh } from "./app-visited-response-cache.js";
|
|
29
33
|
import { createPopstateRestoreHandler, restoreSynchronousPopstateScrollPosition } from "./app-browser-popstate.js";
|
|
30
|
-
import { createOnUncaughtError } from "./app-browser-error.js";
|
|
34
|
+
import { createDevOnCaughtError, createOnUncaughtError, createProdOnCaughtError, prodOnRecoverableError } from "./app-browser-error.js";
|
|
31
35
|
import { dismissOverlay } from "./dev-error-overlay-store.js";
|
|
32
|
-
import { devOnCaughtError,
|
|
36
|
+
import { devOnCaughtError, installDevErrorOverlay, installViteHmrErrorHandler, reportInitialDevServerErrors } from "./dev-error-overlay.js";
|
|
33
37
|
import { throwOnServerActionNotFound } from "./server-action-not-found.js";
|
|
34
|
-
import { resolveRscRedirectLifecycleHop } from "./app-browser-rsc-redirect.js";
|
|
35
38
|
import { createOptimisticRouteTemplate, getOptimisticPrefetchSourceKey, getOptimisticRouteTemplateKey, resolveOptimisticNavigationPayload } from "./app-optimistic-routing.js";
|
|
36
39
|
import { removeStylesheetLinksCoveredByInlineCss } from "./app-inline-css-client.js";
|
|
37
40
|
import { createElement, startTransition, use, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
38
41
|
import { flushSync } from "react-dom";
|
|
39
42
|
import { createFromFetch, createFromReadableStream, createTemporaryReferenceSet, encodeReply, setServerCallback } from "@vitejs/plugin-rsc/browser";
|
|
40
|
-
import { hydrateRoot } from "react-dom/client";
|
|
43
|
+
import { createRoot, hydrateRoot } from "react-dom/client";
|
|
41
44
|
//#region src/server/app-browser-entry.ts
|
|
42
45
|
function toActionType(kind) {
|
|
43
46
|
return kind === "traverse" ? "traverse" : "navigate";
|
|
@@ -55,13 +58,37 @@ const CLIENT_RSC_COMPATIBILITY_ID = getVinextRscCompatibilityId();
|
|
|
55
58
|
const optimisticRouteTemplates = /* @__PURE__ */ new Map();
|
|
56
59
|
const optimisticRouteTemplateSources = /* @__PURE__ */ new Set();
|
|
57
60
|
const optimisticRouteTemplateLearning = /* @__PURE__ */ new Map();
|
|
61
|
+
function claimInitialAppRouterBootstrap() {
|
|
62
|
+
if (window.__VINEXT_RSC_ROOT__ || window.__VINEXT_RSC_BOOTSTRAP_STATE__) return false;
|
|
63
|
+
window.__VINEXT_RSC_BOOTSTRAP_STATE__ = "starting";
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
function markInitialAppRouterBootstrapHydrated() {
|
|
67
|
+
window.__VINEXT_RSC_BOOTSTRAP_STATE__ = "hydrated";
|
|
68
|
+
}
|
|
58
69
|
function getBrowserRouteManifest() {
|
|
59
70
|
return getNavigationRuntime()?.bootstrap.routeManifest ?? null;
|
|
60
71
|
}
|
|
72
|
+
const historyController = new AppBrowserHistoryController({
|
|
73
|
+
initialHistoryState: window.history.state,
|
|
74
|
+
maxHistoryStateSnapshots: 50,
|
|
75
|
+
readHistoryState: () => window.history.state,
|
|
76
|
+
readCurrentHref: () => window.location.href,
|
|
77
|
+
pushHistoryState: (state, href) => pushHistoryStateWithoutNotify(state, "", href),
|
|
78
|
+
replaceHistoryState: (state, href) => replaceHistoryStateWithoutNotify(state, "", href),
|
|
79
|
+
readVisibleNavigationMetadata: () => {
|
|
80
|
+
if (!hasBrowserRouterState()) return null;
|
|
81
|
+
const routerState = getBrowserRouterState();
|
|
82
|
+
return {
|
|
83
|
+
bfcacheIds: routerState.bfcacheIds,
|
|
84
|
+
previousNextUrl: routerState.previousNextUrl
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
});
|
|
61
88
|
const browserNavigationController = createAppBrowserNavigationController({
|
|
62
89
|
basePath: __basePath,
|
|
63
90
|
getRouteManifest: getBrowserRouteManifest,
|
|
64
|
-
syncHistoryStatePreviousNextUrl: syncCurrentHistoryStatePreviousNextUrl
|
|
91
|
+
syncHistoryStatePreviousNextUrl: (previousNextUrl, bfcacheIds) => historyController.syncCurrentHistoryStatePreviousNextUrl(previousNextUrl, bfcacheIds)
|
|
65
92
|
});
|
|
66
93
|
const discardedServerActionRefreshScheduler = createDiscardedServerActionRefreshScheduler({ runRefresh() {
|
|
67
94
|
clearClientNavigationCaches();
|
|
@@ -93,79 +120,30 @@ function isRouterStatePromise(value) {
|
|
|
93
120
|
let latestClientParams = {};
|
|
94
121
|
const visitedResponseCache = /* @__PURE__ */ new Map();
|
|
95
122
|
let browserRouterStateHasEverCommitted = false;
|
|
96
|
-
let pendingNavigationRecoveryHref = null;
|
|
97
123
|
const mpaNavigationScheduler = new AppBrowserMpaNavigationScheduler();
|
|
98
124
|
const unresolvedMpaNavigation = new Promise(() => {});
|
|
99
125
|
const RSC_HMR_SETTLE_DELAY_MS = 150;
|
|
126
|
+
const DEFAULT_GLOBAL_ERROR_COMPONENT = DefaultGlobalError;
|
|
100
127
|
let latestRscHmrUpdateId = 0;
|
|
101
|
-
let currentHistoryTraversalIndex = readHistoryStateTraversalIndex(window.history.state) ?? 0;
|
|
102
|
-
let nextHistoryTraversalIndex = currentHistoryTraversalIndex;
|
|
103
128
|
let synchronousPopstateScrollRestoreNavigationId = null;
|
|
104
|
-
const restorableClientState = new RestorableClientStateController({
|
|
105
|
-
initialHistoryState: window.history.state,
|
|
106
|
-
maxHistoryStateSnapshots: 50
|
|
107
|
-
});
|
|
108
129
|
function waitForRscHmrSettle(delayMs = RSC_HMR_SETTLE_DELAY_MS) {
|
|
109
130
|
return new Promise((resolve) => {
|
|
110
131
|
window.setTimeout(resolve, delayMs);
|
|
111
132
|
});
|
|
112
133
|
}
|
|
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
134
|
function restoreHistoryStateSnapshot(historyState) {
|
|
156
|
-
const decision = restorableClientState.resolveHistoryStateSnapshotRestore(historyState);
|
|
157
|
-
if (decision.kind === "skip") return false;
|
|
158
135
|
const navId = browserNavigationController.getActiveNavigationId();
|
|
159
136
|
let restored = false;
|
|
160
137
|
flushSync(() => {
|
|
161
|
-
restored =
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
138
|
+
restored = historyController.restoreHistorySnapshot({
|
|
139
|
+
historyState,
|
|
140
|
+
stageClientParams,
|
|
141
|
+
approveVisibleRestore: ({ state, beforeCommit }) => browserNavigationController.restoreHistorySnapshotVisibleState({
|
|
142
|
+
beforeCommit,
|
|
143
|
+
navId,
|
|
144
|
+
state,
|
|
145
|
+
targetHref: window.location.href
|
|
146
|
+
})
|
|
169
147
|
});
|
|
170
148
|
});
|
|
171
149
|
if (!restored) return false;
|
|
@@ -204,7 +182,7 @@ function clearPrefetchState() {
|
|
|
204
182
|
function clearClientNavigationCaches() {
|
|
205
183
|
clearVisitedResponseCache();
|
|
206
184
|
clearPrefetchState();
|
|
207
|
-
|
|
185
|
+
historyController.invalidateRestorableClientState();
|
|
208
186
|
}
|
|
209
187
|
function isSettledPrefetchCacheEntry(entry) {
|
|
210
188
|
return entry.outcome === "cache-seeded" && entry.pending === void 0 && entry.snapshot !== void 0;
|
|
@@ -272,28 +250,6 @@ async function learnOptimisticRouteTemplatesFromPrefetchCache(options) {
|
|
|
272
250
|
if (learning.length === 0) return;
|
|
273
251
|
await Promise.allSettled(learning);
|
|
274
252
|
}
|
|
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
253
|
function createActionInitiationSnapshot() {
|
|
298
254
|
const routerState = getBrowserRouterState();
|
|
299
255
|
return createServerActionInitiationSnapshot({
|
|
@@ -309,64 +265,39 @@ function createNavigationCommitEffect(options) {
|
|
|
309
265
|
commitClientNavigationState(void 0, { releaseSnapshot: true });
|
|
310
266
|
return;
|
|
311
267
|
}
|
|
312
|
-
|
|
313
|
-
const preserveExistingState = historyUpdateMode === "replace";
|
|
314
|
-
const navigationHistoryIndex = targetHistoryIndex !== void 0 ? targetHistoryIndex : allocateNavigationHistoryTraversalIndex(historyUpdateMode);
|
|
315
|
-
const historyState = createHistoryStateWithNavigationMetadata(preserveExistingState ? window.history.state : null, {
|
|
268
|
+
historyController.commitNavigationHistory({
|
|
316
269
|
bfcacheIds,
|
|
317
|
-
|
|
270
|
+
href,
|
|
271
|
+
historyUpdateMode,
|
|
318
272
|
previousNextUrl,
|
|
319
|
-
|
|
273
|
+
stageClientParams: () => stageClientParams(params),
|
|
274
|
+
targetHistoryIndex
|
|
320
275
|
});
|
|
321
|
-
|
|
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
|
-
pendingNavigationRecoveryHref = null;
|
|
276
|
+
clearAppNavigationFailureTarget(href);
|
|
339
277
|
commitClientNavigationState(navId);
|
|
340
278
|
};
|
|
341
279
|
}
|
|
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) {
|
|
280
|
+
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
281
|
syncServerActionHttpFallbackHead(null);
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
targetHref,
|
|
364
|
-
navId
|
|
365
|
-
});
|
|
366
|
-
} catch (error) {
|
|
367
|
-
pendingNavigationRecoveryHref = null;
|
|
368
|
-
throw error;
|
|
369
|
-
}
|
|
282
|
+
return browserNavigationController.renderNavigationPayload({
|
|
283
|
+
actionType,
|
|
284
|
+
createNavigationCommitEffect,
|
|
285
|
+
historyUpdateMode,
|
|
286
|
+
navigationSnapshot,
|
|
287
|
+
nextElements: payload,
|
|
288
|
+
operationLane,
|
|
289
|
+
payloadOrigin,
|
|
290
|
+
params,
|
|
291
|
+
pendingRouterState,
|
|
292
|
+
previousNextUrl,
|
|
293
|
+
scrollIntent,
|
|
294
|
+
restoredBfcacheIds,
|
|
295
|
+
reuseCurrentBfcacheIds,
|
|
296
|
+
targetHistoryIndex: traversalIntent === null ? void 0 : traversalIntent.targetHistoryIndex,
|
|
297
|
+
targetHref,
|
|
298
|
+
navId,
|
|
299
|
+
visibleCommitMode
|
|
300
|
+
});
|
|
370
301
|
}
|
|
371
302
|
function resolveActionRedirectTarget(response) {
|
|
372
303
|
const actionRedirect = response.headers.get(ACTION_REDIRECT_HEADER);
|
|
@@ -432,23 +363,39 @@ function evictVisitedResponseCacheIfNeeded() {
|
|
|
432
363
|
visitedResponseCache.delete(oldest);
|
|
433
364
|
}
|
|
434
365
|
}
|
|
435
|
-
function
|
|
366
|
+
function readVisitedResponseCacheCandidate(rscUrl, interceptionContext, mountedSlotsHeader, navigationKind) {
|
|
436
367
|
const cacheKey = AppElementsWire.encodeCacheKey(rscUrl, interceptionContext);
|
|
437
368
|
const cached = visitedResponseCache.get(cacheKey);
|
|
438
|
-
if (!cached) return
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
369
|
+
if (!cached) return {
|
|
370
|
+
cacheKey,
|
|
371
|
+
entry: null,
|
|
372
|
+
facts: {
|
|
373
|
+
candidate: "missing",
|
|
374
|
+
navigationKind
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
return {
|
|
378
|
+
cacheKey,
|
|
379
|
+
entry: cached,
|
|
380
|
+
facts: {
|
|
381
|
+
candidate: "present",
|
|
382
|
+
fresh: isVisitedResponseCacheEntryFresh(cached, {
|
|
383
|
+
navigationKind,
|
|
384
|
+
now: Date.now()
|
|
385
|
+
}),
|
|
386
|
+
mountedSlotsMatch: (cached.response.mountedSlotsHeader ?? null) === mountedSlotsHeader,
|
|
387
|
+
navigationKind
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
function applyVisitedResponseCacheCandidateDecision(candidate, decision) {
|
|
392
|
+
if (candidate.entry === null) return null;
|
|
393
|
+
if (decision.kind === "reuse") {
|
|
394
|
+
visitedResponseCache.delete(candidate.cacheKey);
|
|
395
|
+
visitedResponseCache.set(candidate.cacheKey, candidate.entry);
|
|
396
|
+
return candidate.entry;
|
|
450
397
|
}
|
|
451
|
-
visitedResponseCache.delete(cacheKey);
|
|
398
|
+
visitedResponseCache.delete(candidate.cacheKey);
|
|
452
399
|
return null;
|
|
453
400
|
}
|
|
454
401
|
function deleteVisitedResponse(rscUrl, interceptionContext) {
|
|
@@ -465,9 +412,8 @@ function storeVisitedResponseSnapshot(rscUrl, interceptionContext, snapshot, par
|
|
|
465
412
|
response: snapshot
|
|
466
413
|
}));
|
|
467
414
|
}
|
|
468
|
-
function
|
|
469
|
-
|
|
470
|
-
return targetUrl.searchParams.toString() !== currentSnapshot.searchParams.toString();
|
|
415
|
+
function clientNavigationSnapshotHref(snapshot) {
|
|
416
|
+
return `${window.location.origin}${createSnapshotPathAndSearch(snapshot)}`;
|
|
471
417
|
}
|
|
472
418
|
function getRequestState(navigationKind, targetPathname, previousNextUrlOverride, traverseHistoryState) {
|
|
473
419
|
if (previousNextUrlOverride !== void 0) return {
|
|
@@ -598,23 +544,25 @@ function BrowserRoot({ initialElements, initialNavigationSnapshot }) {
|
|
|
598
544
|
return new Promise(() => {});
|
|
599
545
|
} });
|
|
600
546
|
browserRouterStateHasEverCommitted = true;
|
|
601
|
-
const hydratedAt = performance.now();
|
|
602
|
-
window.__VINEXT_HYDRATED_AT = hydratedAt;
|
|
603
|
-
window.__NEXT_HYDRATED = true;
|
|
604
|
-
window.__NEXT_HYDRATED_AT = hydratedAt;
|
|
605
|
-
window.__NEXT_HYDRATED_CB?.();
|
|
606
547
|
return () => {
|
|
607
548
|
registerNavigationRuntimeFunctions({ navigateExternal: void 0 });
|
|
608
549
|
detach();
|
|
609
550
|
setMountedSlotsHeader(null);
|
|
610
551
|
};
|
|
611
552
|
}, [setTreeStateValue]);
|
|
553
|
+
useEffect(() => {
|
|
554
|
+
const hydratedAt = performance.now();
|
|
555
|
+
window.__VINEXT_HYDRATED_AT = hydratedAt;
|
|
556
|
+
window.__NEXT_HYDRATED = true;
|
|
557
|
+
window.__NEXT_HYDRATED_AT = hydratedAt;
|
|
558
|
+
window.__NEXT_HYDRATED_CB?.();
|
|
559
|
+
}, []);
|
|
612
560
|
useLayoutEffect(() => {
|
|
613
|
-
|
|
614
|
-
historyIndex: currentHistoryTraversalIndex,
|
|
615
|
-
state: treeState
|
|
616
|
-
});
|
|
561
|
+
historyController.rememberHistoryStateSnapshot(treeState);
|
|
617
562
|
}, [treeState]);
|
|
563
|
+
useEffect(() => {
|
|
564
|
+
setWindowNextInternalSourcePage(AppElementsWire.readMetadata(treeState.elements).sourcePage);
|
|
565
|
+
}, [treeState.elements]);
|
|
618
566
|
useLayoutEffect(() => {
|
|
619
567
|
setMountedSlotsHeader(getMountedSlotIdsHeader(stateRef.current.elements));
|
|
620
568
|
removeStylesheetLinksCoveredByInlineCss();
|
|
@@ -622,12 +570,10 @@ function BrowserRoot({ initialElements, initialNavigationSnapshot }) {
|
|
|
622
570
|
}, [treeState.elements]);
|
|
623
571
|
useLayoutEffect(() => {
|
|
624
572
|
if (treeState.renderId !== 0) return;
|
|
625
|
-
|
|
573
|
+
historyController.writeHydratedHistoryMetadata({
|
|
626
574
|
bfcacheIds: treeState.bfcacheIds,
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
traversalIndex: currentHistoryTraversalIndex
|
|
630
|
-
}), "", window.location.href);
|
|
575
|
+
previousNextUrl: treeState.previousNextUrl
|
|
576
|
+
});
|
|
631
577
|
}, [
|
|
632
578
|
treeState.bfcacheIds,
|
|
633
579
|
treeState.previousNextUrl,
|
|
@@ -642,13 +588,17 @@ function BrowserRoot({ initialElements, initialNavigationSnapshot }) {
|
|
|
642
588
|
const redirectedTree = createElement(AppRouterRedirectBridge, null, BfcacheIdMapContext ? createElement(BfcacheIdMapContext.Provider, { value: treeState.bfcacheIds }, stateKeyTree) : stateKeyTree);
|
|
643
589
|
const innerTree = AppRouterContext ? createElement(AppRouterContext.Provider, { value: appRouterInstance }, redirectedTree) : redirectedTree;
|
|
644
590
|
const committedTree = import.meta.env.DEV ? createElement(DevRecoveryBoundary, {
|
|
591
|
+
isImplicitRootErrorBoundary: true,
|
|
645
592
|
resetKey: treeState.renderId,
|
|
646
593
|
onCatch: handleDevRecoveryBoundaryCatch
|
|
647
594
|
}, innerTree) : innerTree;
|
|
648
|
-
const
|
|
595
|
+
const rootErrorTree = createElement(GlobalErrorBoundary, {
|
|
596
|
+
fallback: DEFAULT_GLOBAL_ERROR_COMPONENT,
|
|
597
|
+
children: createElement(AppRouterScrollCommitProvider, { commitId: treeState.renderId }, committedTree)
|
|
598
|
+
});
|
|
649
599
|
const ClientNavigationRenderContext = getClientNavigationRenderContext();
|
|
650
|
-
if (!ClientNavigationRenderContext) return
|
|
651
|
-
return createElement(ClientNavigationRenderContext.Provider, { value: treeState.navigationSnapshot },
|
|
600
|
+
if (!ClientNavigationRenderContext) return rootErrorTree;
|
|
601
|
+
return createElement(ClientNavigationRenderContext.Provider, { value: treeState.navigationSnapshot }, rootErrorTree);
|
|
652
602
|
}
|
|
653
603
|
function restoreHydrationNavigationContext(pathname, searchParams, params) {
|
|
654
604
|
setNavigationContext({
|
|
@@ -759,7 +709,7 @@ function registerServerActionCallback() {
|
|
|
759
709
|
syncServerActionHttpFallbackHead(null);
|
|
760
710
|
const temporaryReferences = createTemporaryReferenceSet();
|
|
761
711
|
const actionInitiation = createActionInitiationSnapshot();
|
|
762
|
-
syncCurrentHistoryStatePreviousNextUrl(actionInitiation.routerState.previousNextUrl, actionInitiation.routerState.bfcacheIds);
|
|
712
|
+
historyController.syncCurrentHistoryStatePreviousNextUrl(actionInitiation.routerState.previousNextUrl, actionInitiation.routerState.bfcacheIds);
|
|
763
713
|
const body = await encodeReply(args, { temporaryReferences });
|
|
764
714
|
const { headers } = resolveServerActionRequestState({
|
|
765
715
|
actionId: id,
|
|
@@ -776,31 +726,23 @@ function registerServerActionCallback() {
|
|
|
776
726
|
const hasActionRedirect = fetchResponse.headers.has(ACTION_REDIRECT_HEADER);
|
|
777
727
|
const actionRedirectTarget = resolveActionRedirectTarget(fetchResponse);
|
|
778
728
|
if (hasActionRedirect && !actionRedirectTarget) return;
|
|
779
|
-
const
|
|
729
|
+
const actionResultFacts = createServerActionResultFacts({
|
|
780
730
|
actionRedirectHref: actionRedirectTarget?.href ?? null,
|
|
731
|
+
actionRedirectType: actionRedirectTarget?.type ?? null,
|
|
781
732
|
clientCompatibilityId: CLIENT_RSC_COMPATIBILITY_ID,
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
if (actionRedirectCompatibilityHardNavigationTarget) {
|
|
785
|
-
clearClientNavigationCaches();
|
|
786
|
-
browserNavigationController.performHardNavigation(actionRedirectCompatibilityHardNavigationTarget, actionRedirectTarget?.type === "push" ? "assign" : "replace");
|
|
787
|
-
return;
|
|
788
|
-
}
|
|
789
|
-
if (!actionRedirectTarget && shouldCheckRscCompatibilityForServerActionResponse(fetchResponse) && resolveRscCompatibilityNavigationDecision({
|
|
790
|
-
clientCompatibilityId: CLIENT_RSC_COMPATIBILITY_ID,
|
|
733
|
+
compatibilityIdHeader: fetchResponse.headers.get(VINEXT_RSC_COMPATIBILITY_ID_HEADER),
|
|
734
|
+
contentTypeHeader: fetchResponse.headers.get("content-type"),
|
|
791
735
|
currentHref: actionInitiation.href,
|
|
792
736
|
origin: window.location.origin,
|
|
793
|
-
responseCompatibilityId: fetchResponse.headers.get("X-Vinext-RSC-Compatibility-Id"),
|
|
794
737
|
responseUrl: fetchResponse.url
|
|
795
|
-
})
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
}
|
|
738
|
+
});
|
|
739
|
+
const fetchResponseIsRsc = actionResultFacts.isRscContentType;
|
|
740
|
+
if (applyServerActionResultDecision(navigationPlanner.classifyServerActionResult(actionResultFacts), clearClientNavigationCaches, (url, historyMode) => browserNavigationController.performHardNavigation(url, historyMode))) return;
|
|
799
741
|
const revalidation = parseServerActionRevalidationHeader(fetchResponse.headers);
|
|
800
742
|
if (revalidation !== "none") clearClientNavigationCaches();
|
|
801
743
|
const invalidResponseError = await readInvalidServerActionResponseError(fetchResponse.clone(), actionRedirectTarget !== null);
|
|
802
744
|
if (invalidResponseError) throw invalidResponseError;
|
|
803
|
-
if (actionRedirectTarget && !
|
|
745
|
+
if (actionRedirectTarget && !fetchResponseIsRsc) {
|
|
804
746
|
browserNavigationController.performHardNavigation(actionRedirectTarget.href);
|
|
805
747
|
return;
|
|
806
748
|
}
|
|
@@ -843,12 +785,14 @@ function registerServerActionCallback() {
|
|
|
843
785
|
return commitSameUrlNavigatePayload(Promise.resolve(AppElementsWire.decode(result)), actionInitiation, void 0, revalidation);
|
|
844
786
|
};
|
|
845
787
|
setServerCallback((id, args) => {
|
|
846
|
-
const releaseCacheInvalidationGuard =
|
|
788
|
+
const releaseCacheInvalidationGuard = historyController.beginCacheInvalidationGuard();
|
|
847
789
|
return Promise.resolve().then(() => serverActionCallback(id, args)).finally(releaseCacheInvalidationGuard);
|
|
848
790
|
});
|
|
849
791
|
}
|
|
850
792
|
async function main() {
|
|
793
|
+
if (!claimInitialAppRouterBootstrap()) return;
|
|
851
794
|
registerServerActionCallback();
|
|
795
|
+
installAppNavigationFailureListeners();
|
|
852
796
|
if (import.meta.env.DEV) {
|
|
853
797
|
installDevErrorOverlay();
|
|
854
798
|
installViteHmrErrorHandler(import.meta.hot);
|
|
@@ -861,34 +805,44 @@ async function main() {
|
|
|
861
805
|
function bootstrapHydration(rscStream) {
|
|
862
806
|
const root = decodeAppElementsPromise(createFromReadableStream(rscStream));
|
|
863
807
|
const initialNavigationSnapshot = createClientNavigationRenderSnapshot(window.location.href, latestClientParams);
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
traversalIndex: currentHistoryTraversalIndex
|
|
867
|
-
}), "", window.location.href);
|
|
868
|
-
const onUncaughtError = import.meta.env.DEV ? devOnUncaughtError : createOnUncaughtError(() => pendingNavigationRecoveryHref);
|
|
808
|
+
historyController.writeBootstrapHistoryMetadata();
|
|
809
|
+
const onUncaughtError = createOnUncaughtError();
|
|
869
810
|
const formState = consumeInitialFormState(getVinextBrowserGlobal());
|
|
870
811
|
const hydrateRootOptions = import.meta.env.DEV ? createVinextHydrateRootOptions({
|
|
871
812
|
formState,
|
|
872
|
-
onCaughtError: devOnCaughtError,
|
|
813
|
+
onCaughtError: createDevOnCaughtError(devOnCaughtError, onUncaughtError),
|
|
873
814
|
onUncaughtError
|
|
874
815
|
}) : createVinextHydrateRootOptions({
|
|
875
816
|
formState,
|
|
817
|
+
onCaughtError: createProdOnCaughtError(onUncaughtError),
|
|
818
|
+
onRecoverableError: prodOnRecoverableError,
|
|
876
819
|
onUncaughtError
|
|
877
820
|
});
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
821
|
+
const children = createElement(BrowserRoot, {
|
|
822
|
+
initialElements: root,
|
|
823
|
+
initialNavigationSnapshot
|
|
824
|
+
});
|
|
825
|
+
const errorShellStyles = document.querySelectorAll("style[data-vinext-error-shell-style]");
|
|
826
|
+
if (document.documentElement.id === "__next_error__") {
|
|
827
|
+
const { formState: _inertFormState, ...createRootOptions } = hydrateRootOptions;
|
|
828
|
+
for (const style of errorShellStyles) style.remove();
|
|
829
|
+
startTransition(() => {
|
|
830
|
+
const clientRoot = createRoot(document, createRootOptions);
|
|
831
|
+
clientRoot.render(children);
|
|
832
|
+
window.__VINEXT_RSC_ROOT__ = clientRoot;
|
|
833
|
+
});
|
|
834
|
+
} else window.__VINEXT_RSC_ROOT__ = hydrateRootInTransition({
|
|
835
|
+
children,
|
|
883
836
|
container: document,
|
|
884
837
|
hydrateRoot,
|
|
885
838
|
options: hydrateRootOptions,
|
|
886
839
|
startTransition
|
|
887
840
|
});
|
|
841
|
+
markInitialAppRouterBootstrapHydrated();
|
|
888
842
|
registerNavigationRuntimeFunctions({
|
|
889
843
|
clearNavigationCaches: clearClientNavigationCaches,
|
|
890
|
-
commitHashNavigation: commitHashOnlyNavigation,
|
|
891
|
-
navigate: async function navigateRsc(href, redirectDepth = 0, navigationKind = "navigate", historyUpdateMode, previousNextUrlOverride, programmaticTransition = false, traversalIntent, scrollIntent) {
|
|
844
|
+
commitHashNavigation: (href, historyUpdateMode, scroll) => historyController.commitHashOnlyNavigation(href, historyUpdateMode, scroll),
|
|
845
|
+
navigate: async function navigateRsc(href, redirectDepth = 0, navigationKind = "navigate", historyUpdateMode, previousNextUrlOverride, programmaticTransition = false, traversalIntent, scrollIntent, visibleCommitMode = "transition") {
|
|
892
846
|
let pendingRouterState = null;
|
|
893
847
|
const navId = browserNavigationController.beginNavigation();
|
|
894
848
|
discardedServerActionRefreshScheduler.markNavigationStart();
|
|
@@ -897,16 +851,15 @@ function bootstrapHydration(rscStream) {
|
|
|
897
851
|
let currentPrevNextUrl = previousNextUrlOverride;
|
|
898
852
|
let redirectCount = redirectDepth;
|
|
899
853
|
let detachedNavigationCommits = false;
|
|
900
|
-
const activeTraversalIntent = navigationKind === "traverse" ? traversalIntent ??
|
|
901
|
-
currentHistoryIndex: currentHistoryTraversalIndex,
|
|
902
|
-
historyState: window.history.state
|
|
903
|
-
}) : null;
|
|
854
|
+
const activeTraversalIntent = navigationKind === "traverse" ? traversalIntent ?? historyController.resolveTraversalIntent(window.history.state) : null;
|
|
904
855
|
const performHardNavigationForScrollIntent = (targetHref) => {
|
|
905
856
|
consumeAppRouterScrollIntent(scrollIntent ?? null);
|
|
906
|
-
|
|
857
|
+
const didNavigate = browserNavigationController.performHardNavigation(targetHref);
|
|
858
|
+
if (!didNavigate) clearAppNavigationFailureTarget(targetHref);
|
|
859
|
+
return didNavigate;
|
|
907
860
|
};
|
|
908
|
-
let restoredBfcacheIds = navigationKind === "traverse" ?
|
|
909
|
-
const reuseCurrentBfcacheIds = navigationKind !== "traverse" || !
|
|
861
|
+
let restoredBfcacheIds = navigationKind === "traverse" ? historyController.readCurrentBfcacheVersionHistoryIds(activeTraversalIntent?.historyState ?? window.history.state) : null;
|
|
862
|
+
const reuseCurrentBfcacheIds = navigationKind !== "traverse" || !historyController.isCacheInvalidationGuarded() && historyController.isCurrentBfcacheVersion(activeTraversalIntent?.historyState ?? window.history.state);
|
|
910
863
|
try {
|
|
911
864
|
const shouldUsePendingRouterState = programmaticTransition;
|
|
912
865
|
if (shouldUsePendingRouterState && hasBrowserRouterState()) pendingRouterState = beginPendingBrowserRouterState();
|
|
@@ -920,50 +873,80 @@ function bootstrapHydration(rscStream) {
|
|
|
920
873
|
const requestState = getRequestState(navigationKind, url.pathname, currentPrevNextUrl, activeTraversalIntent?.historyState);
|
|
921
874
|
const requestInterceptionContext = requestState.interceptionContext;
|
|
922
875
|
const requestPreviousNextUrl = requestState.previousNextUrl;
|
|
923
|
-
if (navigationKind === "refresh") syncCurrentHistoryStatePreviousNextUrl(requestPreviousNextUrl, getBrowserRouterState().bfcacheIds);
|
|
876
|
+
if (navigationKind === "refresh") historyController.syncCurrentHistoryStatePreviousNextUrl(requestPreviousNextUrl, getBrowserRouterState().bfcacheIds);
|
|
924
877
|
setPendingPathname(url.pathname, navId);
|
|
925
878
|
const routerStateAtNavStart = getBrowserRouterState();
|
|
926
879
|
const elementsAtNavStart = routerStateAtNavStart.elements;
|
|
927
880
|
const mountedSlotsHeader = getMountedSlotIdsHeader(elementsAtNavStart);
|
|
928
|
-
const
|
|
881
|
+
const earlyIntentDecision = navigationKind === "navigate" ? navigationPlanner.classifyEarlyNavigationIntent({
|
|
882
|
+
basePath: __basePath,
|
|
883
|
+
currentHref: clientNavigationSnapshotHref(routerStateAtNavStart.navigationSnapshot),
|
|
884
|
+
mode: "push",
|
|
885
|
+
scroll: false,
|
|
886
|
+
targetHref: url.href
|
|
887
|
+
}) : null;
|
|
888
|
+
const shouldBypassNavigationCache = earlyIntentDecision?.kind === "flightNavigation" && earlyIntentDecision.bypassNavigationCache;
|
|
929
889
|
const requestHeaders = createRscRequestHeaders({
|
|
930
890
|
interceptionContext: requestInterceptionContext,
|
|
931
891
|
mountedSlotsHeader,
|
|
932
892
|
renderMode: navigationKind === "refresh" ? APP_RSC_RENDER_MODE_REFRESH_PRESERVE_UI : void 0
|
|
933
893
|
});
|
|
934
894
|
const rscUrl = await createRscRequestUrl(url.pathname + url.search, requestHeaders);
|
|
935
|
-
const
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
responseCompatibilityId: cachedRoute.response.compatibilityIdHeader,
|
|
942
|
-
responseUrl: cachedRoute.response.url
|
|
943
|
-
});
|
|
944
|
-
if (compatibilityDecision.kind === "hard-navigate") {
|
|
945
|
-
performHardNavigationForScrollIntent(compatibilityDecision.hardNavigationTarget);
|
|
946
|
-
return;
|
|
895
|
+
const visitedResponseCandidate = shouldBypassNavigationCache ? {
|
|
896
|
+
cacheKey: AppElementsWire.encodeCacheKey(rscUrl, requestInterceptionContext),
|
|
897
|
+
entry: null,
|
|
898
|
+
facts: {
|
|
899
|
+
candidate: "missing",
|
|
900
|
+
navigationKind
|
|
947
901
|
}
|
|
948
|
-
|
|
902
|
+
} : readVisitedResponseCacheCandidate(rscUrl, requestInterceptionContext, mountedSlotsHeader, navigationKind);
|
|
903
|
+
const cachedRoute = applyVisitedResponseCacheCandidateDecision(visitedResponseCandidate, navigationPlanner.classifyVisitedResponseCacheCandidate(visitedResponseCandidate.facts));
|
|
904
|
+
const visitedResponse = cachedRoute === null ? { status: "unavailable" } : { status: "available" };
|
|
905
|
+
const prefetchProbeDecision = navigationPlanner.classifyNavigationPrefetchProbe({
|
|
906
|
+
bypassNavigationCache: shouldBypassNavigationCache,
|
|
907
|
+
navigationKind,
|
|
908
|
+
visitedResponse
|
|
909
|
+
});
|
|
910
|
+
let routeManifest = navigationKind === "navigate" ? getBrowserRouteManifest() : null;
|
|
911
|
+
const hasPrefetchCandidate = prefetchProbeDecision.kind === "probe" && hasPrefetchCacheEntryForNavigation(rscUrl, requestInterceptionContext, mountedSlotsHeader, { notifyInvalidation: false });
|
|
912
|
+
const reuseDecision = navigationPlanner.classifyNavigationReuse({
|
|
913
|
+
bypassNavigationCache: shouldBypassNavigationCache,
|
|
914
|
+
navigationKind,
|
|
915
|
+
optimisticRouteShell: routeManifest === null ? {
|
|
916
|
+
reason: "routeManifestMissing",
|
|
917
|
+
status: "unavailable"
|
|
918
|
+
} : { status: "available" },
|
|
919
|
+
prefetch: hasPrefetchCandidate ? { status: "available" } : { status: "unavailable" },
|
|
920
|
+
targetHref: currentHref,
|
|
921
|
+
visitedResponse
|
|
922
|
+
});
|
|
923
|
+
if (reuseDecision.kind === "reuseVisitedResponse" && cachedRoute) {
|
|
924
|
+
const cachedFetchDecision = navigationPlanner.classifyRscFetchResult({
|
|
925
|
+
clientCompatibilityId: CLIENT_RSC_COMPATIBILITY_ID,
|
|
926
|
+
compatibilityIdHeader: cachedRoute.response.compatibilityIdHeader ?? null,
|
|
949
927
|
currentHref,
|
|
950
|
-
|
|
928
|
+
effectiveHistoryUpdateMode: currentHistoryMode ?? "replace",
|
|
929
|
+
hasBody: true,
|
|
930
|
+
isRscContentType: true,
|
|
951
931
|
origin: window.location.origin,
|
|
952
932
|
redirectDepth: redirectCount,
|
|
953
933
|
requestPreviousNextUrl,
|
|
954
|
-
|
|
934
|
+
responseOk: true,
|
|
935
|
+
responseUrl: cachedRoute.response.url,
|
|
936
|
+
source: "cached",
|
|
937
|
+
streamedRedirectTarget: null
|
|
955
938
|
});
|
|
956
|
-
if (
|
|
957
|
-
if (
|
|
958
|
-
performHardNavigationForScrollIntent(
|
|
939
|
+
if (cachedFetchDecision.kind === "hardNavigate") {
|
|
940
|
+
if (cachedFetchDecision.reason === "redirectDepthExhausted") console.error("[vinext] Too many RSC redirects — aborting navigation to prevent infinite loop.");
|
|
941
|
+
performHardNavigationForScrollIntent(cachedFetchDecision.url);
|
|
959
942
|
return;
|
|
960
943
|
}
|
|
961
|
-
if (
|
|
944
|
+
if (cachedFetchDecision.kind === "followRedirect") {
|
|
962
945
|
if (navigationKind === "traverse") restoredBfcacheIds = null;
|
|
963
|
-
currentHref =
|
|
964
|
-
currentHistoryMode =
|
|
965
|
-
currentPrevNextUrl =
|
|
966
|
-
redirectCount =
|
|
946
|
+
currentHref = cachedFetchDecision.redirect.href;
|
|
947
|
+
currentHistoryMode = cachedFetchDecision.redirect.historyUpdateMode;
|
|
948
|
+
currentPrevNextUrl = cachedFetchDecision.redirect.previousNextUrl;
|
|
949
|
+
redirectCount = cachedFetchDecision.redirect.redirectDepth;
|
|
967
950
|
continue;
|
|
968
951
|
}
|
|
969
952
|
if (!browserNavigationController.isCurrentNavigation(navId)) return;
|
|
@@ -971,7 +954,7 @@ function bootstrapHydration(rscStream) {
|
|
|
971
954
|
const cachedNavigationSnapshot = createClientNavigationRenderSnapshot(currentHref, cachedParams);
|
|
972
955
|
const cachedPayload = decodeAppElementsPromise(createFromFetch(Promise.resolve(restoreRscResponse(cachedRoute.response))));
|
|
973
956
|
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") {
|
|
957
|
+
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
958
|
deleteVisitedResponse(rscUrl, requestInterceptionContext);
|
|
976
959
|
continue;
|
|
977
960
|
}
|
|
@@ -980,7 +963,8 @@ function bootstrapHydration(rscStream) {
|
|
|
980
963
|
let navResponse;
|
|
981
964
|
let navResponseExpiresAt;
|
|
982
965
|
let navResponseUrl = null;
|
|
983
|
-
|
|
966
|
+
let fallbackReuseDecision = reuseDecision;
|
|
967
|
+
if (reuseDecision.kind === "consumePrefetch") {
|
|
984
968
|
const prefetchedResponse = await consumePrefetchResponseForNavigation(rscUrl, requestInterceptionContext, mountedSlotsHeader, { shouldConsume: () => browserNavigationController.isCurrentNavigation(navId) });
|
|
985
969
|
if (!browserNavigationController.isCurrentNavigation(navId)) return;
|
|
986
970
|
if (prefetchedResponse) {
|
|
@@ -988,9 +972,22 @@ function bootstrapHydration(rscStream) {
|
|
|
988
972
|
navResponseExpiresAt = prefetchedResponse.expiresAt;
|
|
989
973
|
navResponseUrl = prefetchedResponse.url;
|
|
990
974
|
}
|
|
975
|
+
if (!navResponse) {
|
|
976
|
+
routeManifest = navigationKind === "navigate" ? getBrowserRouteManifest() : null;
|
|
977
|
+
fallbackReuseDecision = navigationPlanner.classifyNavigationReuse({
|
|
978
|
+
bypassNavigationCache: shouldBypassNavigationCache,
|
|
979
|
+
navigationKind,
|
|
980
|
+
optimisticRouteShell: routeManifest === null ? {
|
|
981
|
+
reason: "routeManifestMissing",
|
|
982
|
+
status: "unavailable"
|
|
983
|
+
} : { status: "available" },
|
|
984
|
+
prefetch: { status: "unavailable" },
|
|
985
|
+
targetHref: currentHref,
|
|
986
|
+
visitedResponse: { status: "unavailable" }
|
|
987
|
+
});
|
|
988
|
+
}
|
|
991
989
|
}
|
|
992
|
-
if (!navResponse &&
|
|
993
|
-
const routeManifest = getBrowserRouteManifest();
|
|
990
|
+
if (!navResponse && fallbackReuseDecision.kind === "attemptOptimisticRouteShell") {
|
|
994
991
|
await learnOptimisticRouteTemplatesFromPrefetchCache({
|
|
995
992
|
interceptionContext: requestInterceptionContext,
|
|
996
993
|
mountedSlotsHeader,
|
|
@@ -1009,7 +1006,7 @@ function bootstrapHydration(rscStream) {
|
|
|
1009
1006
|
if (optimisticPayload !== null) {
|
|
1010
1007
|
detachedNavigationCommits = true;
|
|
1011
1008
|
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) => {
|
|
1009
|
+
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
1010
|
if (browserNavigationController.isCurrentNavigation(navId)) console.error("[vinext] Optimistic RSC navigation error:", error);
|
|
1014
1011
|
});
|
|
1015
1012
|
}
|
|
@@ -1026,61 +1023,36 @@ function bootstrapHydration(rscStream) {
|
|
|
1026
1023
|
});
|
|
1027
1024
|
}
|
|
1028
1025
|
if (!browserNavigationController.isCurrentNavigation(navId)) return;
|
|
1029
|
-
const
|
|
1030
|
-
|
|
1031
|
-
performHardNavigationForScrollIntent(resolveHardNavigationTargetFromRscResponse(navResponseUrl ?? navResponse.url, currentHref, window.location.origin));
|
|
1032
|
-
return;
|
|
1033
|
-
}
|
|
1034
|
-
const compatibilityDecision = resolveRscCompatibilityNavigationDecision({
|
|
1026
|
+
const navContentType = navResponse.headers.get("content-type") ?? "";
|
|
1027
|
+
const liveFetchDecision = navigationPlanner.classifyRscFetchResult({
|
|
1035
1028
|
clientCompatibilityId: CLIENT_RSC_COMPATIBILITY_ID,
|
|
1029
|
+
compatibilityIdHeader: navResponse.headers.get(VINEXT_RSC_COMPATIBILITY_ID_HEADER),
|
|
1036
1030
|
currentHref,
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
});
|
|
1041
|
-
if (compatibilityDecision.kind === "hard-navigate") {
|
|
1042
|
-
performHardNavigationForScrollIntent(compatibilityDecision.hardNavigationTarget);
|
|
1043
|
-
return;
|
|
1044
|
-
}
|
|
1045
|
-
const redirectDecision = resolveRscRedirectLifecycleHop({
|
|
1046
|
-
currentHref,
|
|
1047
|
-
historyUpdateMode: currentHistoryMode ?? "replace",
|
|
1031
|
+
effectiveHistoryUpdateMode: currentHistoryMode ?? "replace",
|
|
1032
|
+
hasBody: navResponse.body !== null,
|
|
1033
|
+
isRscContentType: navContentType.startsWith(VINEXT_RSC_CONTENT_TYPE),
|
|
1048
1034
|
origin: window.location.origin,
|
|
1049
1035
|
redirectDepth: redirectCount,
|
|
1050
1036
|
requestPreviousNextUrl,
|
|
1051
|
-
|
|
1037
|
+
responseOk: navResponse.ok,
|
|
1038
|
+
responseUrl: navResponseUrl ?? navResponse.url,
|
|
1039
|
+
source: "live",
|
|
1040
|
+
streamedRedirectTarget: navResponse.headers.get(VINEXT_RSC_REDIRECT_HEADER)
|
|
1052
1041
|
});
|
|
1053
|
-
if (
|
|
1054
|
-
if (
|
|
1055
|
-
|
|
1042
|
+
if (liveFetchDecision.kind === "hardNavigate") {
|
|
1043
|
+
if (liveFetchDecision.discardBody) navResponse.body?.cancel().catch(() => {});
|
|
1044
|
+
if (liveFetchDecision.reason === "redirectDepthExhausted") console.error("[vinext] Too many RSC redirects — aborting navigation to prevent infinite loop.");
|
|
1045
|
+
if (liveFetchDecision.reason === "streamedRedirectLoop") console.error("[vinext] RSC streamed redirect resolved to the current URL — aborting navigation to prevent infinite loop.");
|
|
1046
|
+
performHardNavigationForScrollIntent(liveFetchDecision.url);
|
|
1056
1047
|
return;
|
|
1057
1048
|
}
|
|
1058
|
-
if (
|
|
1059
|
-
if (
|
|
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
|
-
}
|
|
1049
|
+
if (liveFetchDecision.kind === "followRedirect") {
|
|
1050
|
+
if (liveFetchDecision.discardBody) navResponse.body?.cancel().catch(() => {});
|
|
1079
1051
|
if (navigationKind === "traverse") restoredBfcacheIds = null;
|
|
1080
|
-
currentHref =
|
|
1081
|
-
currentHistoryMode =
|
|
1082
|
-
currentPrevNextUrl =
|
|
1083
|
-
redirectCount
|
|
1052
|
+
currentHref = liveFetchDecision.redirect.href;
|
|
1053
|
+
currentHistoryMode = liveFetchDecision.redirect.historyUpdateMode;
|
|
1054
|
+
currentPrevNextUrl = liveFetchDecision.redirect.previousNextUrl;
|
|
1055
|
+
redirectCount = liveFetchDecision.redirect.redirectDepth;
|
|
1084
1056
|
continue;
|
|
1085
1057
|
}
|
|
1086
1058
|
const navParams = parseEncodedJsonHeader(navResponse.headers.get("X-Vinext-Params")) ?? {};
|
|
@@ -1096,7 +1068,7 @@ function bootstrapHydration(rscStream) {
|
|
|
1096
1068
|
if (!browserNavigationController.isCurrentNavigation(navId)) return;
|
|
1097
1069
|
const rscPayload = decodeAppElementsPromise(createFromFetch(Promise.resolve(reactResponse)));
|
|
1098
1070
|
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;
|
|
1071
|
+
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
1072
|
if (!browserNavigationController.isCurrentNavigation(navId)) return;
|
|
1101
1073
|
try {
|
|
1102
1074
|
const renderedElements = await rscPayload;
|
|
@@ -1117,7 +1089,7 @@ function bootstrapHydration(rscStream) {
|
|
|
1117
1089
|
} catch (error) {
|
|
1118
1090
|
if (!browserNavigationController.isCurrentNavigation(navId)) return;
|
|
1119
1091
|
if (!isPageUnloading) console.error("[vinext] RSC navigation error:", error);
|
|
1120
|
-
performHardNavigationForScrollIntent(currentHref);
|
|
1092
|
+
performHardNavigationForScrollIntent(navigationPlanner.classifyRscNavigationError({ currentHref }).url);
|
|
1121
1093
|
} finally {
|
|
1122
1094
|
browserNavigationController.finalizeNavigation(navId, pendingRouterState);
|
|
1123
1095
|
discardedServerActionRefreshScheduler.markNavigationSettled();
|
|
@@ -1142,7 +1114,7 @@ function bootstrapHydration(rscStream) {
|
|
|
1142
1114
|
const href = window.location.href;
|
|
1143
1115
|
if (isSameAppRoutePopstateTarget(href)) {
|
|
1144
1116
|
notifyAppRouterTransitionStart(href, "traverse");
|
|
1145
|
-
commitTraversalIndexFromHistoryState(event.state);
|
|
1117
|
+
historyController.commitTraversalIndexFromHistoryState(event.state);
|
|
1146
1118
|
restorePopstateScrollPosition(event.state);
|
|
1147
1119
|
return;
|
|
1148
1120
|
}
|