vinext 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -5
- package/dist/build/assets-ignore.d.ts +32 -0
- package/dist/build/assets-ignore.js +48 -0
- package/dist/build/client-build-config.d.ts +33 -1
- package/dist/build/client-build-config.js +66 -1
- package/dist/check.js +4 -3
- package/dist/cli.js +2 -0
- package/dist/client/navigation-runtime.d.ts +11 -2
- package/dist/client/navigation-runtime.js +1 -1
- package/dist/client/vinext-next-data.d.ts +2 -1
- package/dist/client/window-next.d.ts +6 -4
- package/dist/config/config-matchers.d.ts +31 -5
- package/dist/config/config-matchers.js +50 -3
- package/dist/config/next-config.d.ts +29 -3
- package/dist/config/next-config.js +32 -2
- package/dist/deploy.js +47 -304
- package/dist/entries/app-rsc-entry.d.ts +8 -2
- package/dist/entries/app-rsc-entry.js +61 -5
- package/dist/entries/app-rsc-manifest.js +20 -2
- package/dist/entries/pages-client-entry.js +1 -1
- package/dist/entries/pages-server-entry.js +16 -7
- package/dist/index.d.ts +0 -2
- package/dist/index.js +233 -280
- package/dist/plugins/dynamic-preload-metadata.d.ts +13 -0
- package/dist/plugins/dynamic-preload-metadata.js +415 -0
- package/dist/plugins/og-assets.js +2 -2
- package/dist/plugins/optimize-imports.d.ts +8 -4
- package/dist/plugins/optimize-imports.js +16 -12
- package/dist/plugins/postcss.js +18 -14
- package/dist/plugins/require-context.d.ts +6 -0
- package/dist/plugins/require-context.js +184 -0
- package/dist/plugins/sass.d.ts +53 -24
- package/dist/plugins/sass.js +249 -1
- 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 +35 -2
- package/dist/routing/app-route-graph.js +179 -8
- package/dist/routing/file-matcher.js +1 -1
- package/dist/routing/route-pattern.d.ts +2 -1
- package/dist/routing/route-pattern.js +16 -1
- package/dist/server/api-handler.js +4 -0
- package/dist/server/app-browser-entry.js +155 -215
- package/dist/server/app-browser-error.d.ts +4 -1
- package/dist/server/app-browser-error.js +7 -1
- 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-interception-context.d.ts +2 -1
- package/dist/server/app-browser-interception-context.js +15 -2
- package/dist/server/app-browser-navigation-controller.d.ts +13 -2
- package/dist/server/app-browser-navigation-controller.js +83 -4
- package/dist/server/app-browser-popstate.d.ts +12 -3
- package/dist/server/app-browser-popstate.js +19 -4
- 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-state.d.ts +3 -0
- package/dist/server/app-browser-state.js +10 -10
- package/dist/server/app-browser-visible-commit.js +10 -8
- package/dist/server/app-fallback-renderer.d.ts +2 -1
- package/dist/server/app-fallback-renderer.js +3 -1
- package/dist/server/app-history-state.d.ts +45 -1
- package/dist/server/app-history-state.js +109 -1
- package/dist/server/app-middleware.js +1 -0
- package/dist/server/app-optimistic-routing.js +22 -1
- package/dist/server/app-page-boundary-render.d.ts +2 -1
- package/dist/server/app-page-boundary-render.js +45 -21
- package/dist/server/app-page-cache.js +9 -7
- package/dist/server/app-page-dispatch.d.ts +14 -0
- package/dist/server/app-page-dispatch.js +21 -6
- package/dist/server/app-page-element-builder.d.ts +23 -2
- package/dist/server/app-page-element-builder.js +58 -17
- package/dist/server/app-page-execution.d.ts +1 -1
- package/dist/server/app-page-execution.js +32 -17
- package/dist/server/app-page-render.d.ts +7 -1
- package/dist/server/app-page-render.js +11 -16
- package/dist/server/app-page-request.d.ts +9 -6
- package/dist/server/app-page-request.js +14 -10
- package/dist/server/app-page-response.d.ts +2 -2
- package/dist/server/app-page-response.js +2 -2
- package/dist/server/app-page-route-wiring.d.ts +3 -1
- package/dist/server/app-page-route-wiring.js +10 -8
- package/dist/server/app-page-stream.d.ts +37 -7
- package/dist/server/app-page-stream.js +36 -6
- package/dist/server/app-pages-bridge.d.ts +16 -0
- package/dist/server/app-pages-bridge.js +23 -3
- package/dist/server/app-route-handler-cache.d.ts +1 -0
- package/dist/server/app-route-handler-cache.js +1 -0
- package/dist/server/app-route-handler-dispatch.d.ts +1 -0
- package/dist/server/app-route-handler-dispatch.js +2 -0
- package/dist/server/app-route-handler-execution.d.ts +1 -0
- package/dist/server/app-route-handler-execution.js +1 -0
- package/dist/server/app-route-handler-response.js +11 -10
- package/dist/server/app-route-handler-runtime.d.ts +1 -0
- package/dist/server/app-route-handler-runtime.js +15 -3
- package/dist/server/app-rsc-handler.d.ts +1 -0
- package/dist/server/app-rsc-handler.js +5 -4
- package/dist/server/app-rsc-response-finalizer.js +1 -1
- package/dist/server/app-rsc-route-matching.d.ts +20 -1
- package/dist/server/app-rsc-route-matching.js +29 -4
- package/dist/server/app-server-action-execution.d.ts +22 -1
- package/dist/server/app-server-action-execution.js +73 -12
- package/dist/server/app-ssr-entry.d.ts +6 -0
- package/dist/server/app-ssr-entry.js +19 -3
- package/dist/server/app-ssr-stream.js +9 -1
- package/dist/server/dev-lockfile.js +2 -1
- package/dist/server/dev-server.d.ts +1 -1
- package/dist/server/dev-server.js +97 -43
- package/dist/server/headers.d.ts +8 -1
- package/dist/server/headers.js +8 -1
- package/dist/server/instrumentation-runtime.d.ts +6 -0
- package/dist/server/instrumentation-runtime.js +8 -0
- package/dist/server/isr-cache.d.ts +37 -1
- package/dist/server/isr-cache.js +85 -1
- 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 +62 -1
- package/dist/server/navigation-planner.js +193 -3
- package/dist/server/navigation-trace.d.ts +12 -2
- package/dist/server/navigation-trace.js +11 -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 +14 -3
- package/dist/server/pages-api-route.js +6 -1
- package/dist/server/pages-asset-tags.d.ts +15 -4
- package/dist/server/pages-asset-tags.js +18 -12
- package/dist/server/pages-data-route.js +5 -1
- package/dist/server/pages-node-compat.d.ts +5 -11
- package/dist/server/pages-node-compat.js +175 -118
- package/dist/server/pages-page-data.d.ts +38 -7
- package/dist/server/pages-page-data.js +64 -18
- package/dist/server/pages-page-handler.d.ts +10 -2
- package/dist/server/pages-page-handler.js +49 -20
- package/dist/server/pages-page-response.d.ts +55 -2
- package/dist/server/pages-page-response.js +74 -6
- package/dist/server/pages-readiness.d.ts +36 -0
- package/dist/server/pages-readiness.js +21 -0
- package/dist/server/pages-request-pipeline.d.ts +113 -0
- package/dist/server/pages-request-pipeline.js +230 -0
- package/dist/server/pages-revalidate.d.ts +15 -0
- package/dist/server/pages-revalidate.js +19 -0
- package/dist/server/prod-server.d.ts +45 -3
- package/dist/server/prod-server.js +182 -234
- package/dist/server/socket-error-backstop.d.ts +19 -1
- package/dist/server/socket-error-backstop.js +77 -4
- package/dist/shims/app-router-scroll.js +22 -4
- package/dist/shims/cache-runtime.js +39 -2
- package/dist/shims/dynamic-preload-chunks.d.ts +8 -0
- package/dist/shims/dynamic-preload-chunks.js +77 -0
- package/dist/shims/dynamic.d.ts +4 -0
- package/dist/shims/dynamic.js +4 -2
- package/dist/shims/error-boundary.d.ts +17 -7
- package/dist/shims/error-boundary.js +8 -1
- package/dist/shims/error.js +37 -11
- package/dist/shims/fetch-cache.d.ts +22 -1
- package/dist/shims/fetch-cache.js +28 -1
- package/dist/shims/hash-scroll.d.ts +1 -0
- package/dist/shims/hash-scroll.js +3 -1
- package/dist/shims/head.js +6 -1
- package/dist/shims/headers.d.ts +16 -2
- package/dist/shims/headers.js +37 -1
- package/dist/shims/image-config.js +7 -1
- package/dist/shims/internal/app-route-detection.d.ts +6 -3
- package/dist/shims/internal/app-route-detection.js +10 -6
- package/dist/shims/internal/app-router-context.d.ts +5 -0
- package/dist/shims/internal/link-status-registry.d.ts +43 -0
- package/dist/shims/internal/link-status-registry.js +42 -0
- package/dist/shims/internal/route-pattern-for-warning.d.ts +27 -0
- package/dist/shims/internal/route-pattern-for-warning.js +40 -0
- package/dist/shims/internal/utils.d.ts +1 -0
- package/dist/shims/link.js +20 -6
- package/dist/shims/metadata.d.ts +6 -2
- package/dist/shims/metadata.js +32 -14
- package/dist/shims/navigation.d.ts +9 -18
- package/dist/shims/navigation.js +96 -23
- package/dist/shims/router-state.d.ts +1 -0
- package/dist/shims/router-state.js +2 -0
- package/dist/shims/router.d.ts +6 -3
- package/dist/shims/router.js +156 -22
- 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 +17 -1
- package/dist/shims/server.js +31 -6
- package/dist/shims/slot.js +1 -1
- package/dist/shims/unified-request-context.js +1 -0
- package/dist/typegen.js +1 -0
- package/dist/utils/client-build-manifest.d.ts +8 -1
- package/dist/utils/client-build-manifest.js +41 -6
- package/dist/utils/client-entry-manifest.d.ts +11 -0
- package/dist/utils/client-entry-manifest.js +29 -0
- package/dist/utils/client-runtime-metadata.d.ts +45 -0
- package/dist/utils/client-runtime-metadata.js +63 -0
- package/dist/utils/hash.d.ts +17 -1
- package/dist/utils/hash.js +36 -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/path.d.ts +2 -1
- package/dist/utils/path.js +5 -1
- package/package.json +6 -2
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { stripBasePath } from "../utils/base-path.js";
|
|
2
1
|
import { ACTION_REDIRECT_HEADER, ACTION_REDIRECT_STATUS_HEADER, VINEXT_CLIENT_REUSE_MANIFEST_HEADER, VINEXT_PARAMS_HEADER, VINEXT_RSC_REDIRECT_HEADER } from "./headers.js";
|
|
3
2
|
import { DANGEROUS_URL_BLOCK_MESSAGE, isDangerousScheme } from "../shims/url-safety.js";
|
|
4
3
|
import { AppElementsWire } from "./app-elements-wire.js";
|
|
@@ -9,12 +8,13 @@ import { installWindowNext } 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";
|
|
12
|
-
import { resolveManifestNavigationInterceptionContext } from "./app-browser-interception-context.js";
|
|
13
|
-
import {
|
|
14
|
-
import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, createRscRequestHeaders, createRscRequestUrl, createServerActionRequestUrl, getVinextRscCompatibilityId,
|
|
11
|
+
import { resolveManifestNavigationInterceptionContext, resolveMiddlewareRewriteNavigationInterceptionContext } from "./app-browser-interception-context.js";
|
|
12
|
+
import { readHistoryStatePreviousNextUrl } from "./app-history-state.js";
|
|
13
|
+
import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, createRscRequestHeaders, createRscRequestUrl, createServerActionRequestUrl, getVinextRscCompatibilityId, resolveRscCompatibilityNavigationDecision } from "./app-rsc-cache-busting.js";
|
|
15
14
|
import { AppBrowserMpaNavigationScheduler } from "./app-browser-mpa-navigation.js";
|
|
15
|
+
import { navigationPlanner } from "./navigation-planner.js";
|
|
16
16
|
import { beginAppRouterScrollIntent, consumeAppRouterScrollIntent } from "../shims/app-router-scroll-state.js";
|
|
17
|
-
import { __basePath, appRouterInstance, commitClientNavigationState, consumePrefetchResponseForNavigation, createCachedRscResponseSnapshot, createClientNavigationRenderSnapshot, decodeRedirectError, getBfcacheIdMapContext, getClientNavigationRenderContext, getPrefetchCache, invalidatePrefetchCache, isRedirectError, pushHistoryStateWithoutNotify, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, resolvePrefetchCacheEntryMountedSlotsHeader, restoreRscResponse, saveScrollPosition, setClientParams, setMountedSlotsHeader, setNavigationContext, setPendingPathname, useRouter } from "../shims/navigation.js";
|
|
17
|
+
import { __basePath, appRouterInstance, commitClientNavigationState, consumePrefetchResponseForNavigation, createCachedRscResponseSnapshot, createClientNavigationRenderSnapshot, createSnapshotPathAndSearch, decodeRedirectError, getBfcacheIdMapContext, getClientNavigationRenderContext, getPrefetchCache, invalidatePrefetchCache, isRedirectError, pushHistoryStateWithoutNotify, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, resolvePrefetchCacheEntryMountedSlotsHeader, restoreRscResponse, saveScrollPosition, setClientParams, setMountedSlotsHeader, setNavigationContext, setPendingPathname, useRouter } from "../shims/navigation.js";
|
|
18
18
|
import { DevRecoveryBoundary, RedirectBoundary } from "../shims/error-boundary.js";
|
|
19
19
|
import { AppRouterScrollCommitProvider } from "../shims/app-router-scroll.js";
|
|
20
20
|
import { BfcacheStateKeyMapContext, ElementsContext, Slot } from "../shims/slot.js";
|
|
@@ -23,18 +23,19 @@ import { createDiscardedServerActionRefreshScheduler, createServerActionInitiati
|
|
|
23
23
|
import { createClientReuseManifestHeaderFromVisibleAppState } from "./app-browser-client-reuse-manifest.js";
|
|
24
24
|
import { chunksToReadableStream, createProgressiveRscStream, getVinextBrowserGlobal } from "./app-browser-stream.js";
|
|
25
25
|
import { FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, VISITED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN, createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap, isCacheRestorableAppPayloadMetadata, resolveInterceptionContextFromPreviousNextUrl, resolveServerActionRequestState } from "./app-browser-state.js";
|
|
26
|
-
import { clearHardNavigationLoopGuard, createAppBrowserNavigationController } from "./app-browser-navigation-controller.js";
|
|
26
|
+
import { clearHardNavigationLoopGuard, createAppBrowserNavigationController, createBasePathStrippedPathAndSearch } from "./app-browser-navigation-controller.js";
|
|
27
27
|
import { consumeInitialFormState, createVinextHydrateRootOptions, hydrateRootInTransition } from "./app-browser-hydration.js";
|
|
28
|
+
import { AppBrowserHistoryController } from "./app-browser-history-controller.js";
|
|
28
29
|
import { createVisitedResponseCacheEntry, isVisitedResponseCacheEntryFresh } from "./app-visited-response-cache.js";
|
|
29
|
-
import { createPopstateRestoreHandler } from "./app-browser-popstate.js";
|
|
30
|
-
import { createOnUncaughtError } from "./app-browser-error.js";
|
|
30
|
+
import { createPopstateRestoreHandler, restoreSynchronousPopstateScrollPosition } from "./app-browser-popstate.js";
|
|
31
|
+
import { createOnUncaughtError, prodOnCaughtError } from "./app-browser-error.js";
|
|
31
32
|
import { dismissOverlay } from "./dev-error-overlay-store.js";
|
|
32
33
|
import { devOnCaughtError, devOnUncaughtError, installDevErrorOverlay, installViteHmrErrorHandler, reportInitialDevServerErrors } from "./dev-error-overlay.js";
|
|
33
34
|
import { throwOnServerActionNotFound } from "./server-action-not-found.js";
|
|
34
|
-
import { resolveRscRedirectLifecycleHop } from "./app-browser-rsc-redirect.js";
|
|
35
35
|
import { createOptimisticRouteTemplate, getOptimisticPrefetchSourceKey, getOptimisticRouteTemplateKey, resolveOptimisticNavigationPayload } from "./app-optimistic-routing.js";
|
|
36
36
|
import { removeStylesheetLinksCoveredByInlineCss } from "./app-inline-css-client.js";
|
|
37
37
|
import { createElement, startTransition, use, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
38
|
+
import { flushSync } from "react-dom";
|
|
38
39
|
import { createFromFetch, createFromReadableStream, createTemporaryReferenceSet, encodeReply, setServerCallback } from "@vitejs/plugin-rsc/browser";
|
|
39
40
|
import { hydrateRoot } from "react-dom/client";
|
|
40
41
|
//#region src/server/app-browser-entry.ts
|
|
@@ -57,9 +58,26 @@ const optimisticRouteTemplateLearning = /* @__PURE__ */ new Map();
|
|
|
57
58
|
function getBrowserRouteManifest() {
|
|
58
59
|
return getNavigationRuntime()?.bootstrap.routeManifest ?? null;
|
|
59
60
|
}
|
|
61
|
+
const historyController = new AppBrowserHistoryController({
|
|
62
|
+
initialHistoryState: window.history.state,
|
|
63
|
+
maxHistoryStateSnapshots: 50,
|
|
64
|
+
readHistoryState: () => window.history.state,
|
|
65
|
+
readCurrentHref: () => window.location.href,
|
|
66
|
+
pushHistoryState: (state, href) => pushHistoryStateWithoutNotify(state, "", href),
|
|
67
|
+
replaceHistoryState: (state, href) => replaceHistoryStateWithoutNotify(state, "", href),
|
|
68
|
+
readVisibleNavigationMetadata: () => {
|
|
69
|
+
if (!hasBrowserRouterState()) return null;
|
|
70
|
+
const routerState = getBrowserRouterState();
|
|
71
|
+
return {
|
|
72
|
+
bfcacheIds: routerState.bfcacheIds,
|
|
73
|
+
previousNextUrl: routerState.previousNextUrl
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
});
|
|
60
77
|
const browserNavigationController = createAppBrowserNavigationController({
|
|
78
|
+
basePath: __basePath,
|
|
61
79
|
getRouteManifest: getBrowserRouteManifest,
|
|
62
|
-
syncHistoryStatePreviousNextUrl: syncCurrentHistoryStatePreviousNextUrl
|
|
80
|
+
syncHistoryStatePreviousNextUrl: (previousNextUrl, bfcacheIds) => historyController.syncCurrentHistoryStatePreviousNextUrl(previousNextUrl, bfcacheIds)
|
|
63
81
|
});
|
|
64
82
|
const discardedServerActionRefreshScheduler = createDiscardedServerActionRefreshScheduler({ runRefresh() {
|
|
65
83
|
clearClientNavigationCaches();
|
|
@@ -96,67 +114,30 @@ const mpaNavigationScheduler = new AppBrowserMpaNavigationScheduler();
|
|
|
96
114
|
const unresolvedMpaNavigation = new Promise(() => {});
|
|
97
115
|
const RSC_HMR_SETTLE_DELAY_MS = 150;
|
|
98
116
|
let latestRscHmrUpdateId = 0;
|
|
99
|
-
|
|
100
|
-
let currentBfcacheVersion = initialHistoryBfcacheVersion === null ? 0 : initialHistoryBfcacheVersion + 1;
|
|
101
|
-
let currentHistoryTraversalIndex = readHistoryStateTraversalIndex(window.history.state) ?? 0;
|
|
102
|
-
let nextHistoryTraversalIndex = currentHistoryTraversalIndex;
|
|
103
|
-
function isCurrentBfcacheVersion(state) {
|
|
104
|
-
return isHistoryStateBfcacheVersionCurrent(state, currentBfcacheVersion);
|
|
105
|
-
}
|
|
117
|
+
let synchronousPopstateScrollRestoreNavigationId = null;
|
|
106
118
|
function waitForRscHmrSettle(delayMs = RSC_HMR_SETTLE_DELAY_MS) {
|
|
107
119
|
return new Promise((resolve) => {
|
|
108
120
|
window.setTimeout(resolve, delayMs);
|
|
109
121
|
});
|
|
110
122
|
}
|
|
111
|
-
function
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
function commitHistoryTraversalIndex(index) {
|
|
128
|
-
currentHistoryTraversalIndex = index;
|
|
129
|
-
if (index !== null) nextHistoryTraversalIndex = Math.max(nextHistoryTraversalIndex, index);
|
|
130
|
-
}
|
|
131
|
-
function commitHashOnlyNavigation(href, historyUpdateMode, scroll) {
|
|
132
|
-
const navigationHistoryIndex = allocateNavigationHistoryTraversalIndex(historyUpdateMode);
|
|
133
|
-
const previousNextUrl = hasBrowserRouterState() ? getBrowserRouterState().previousNextUrl : readHistoryStatePreviousNextUrl(window.history.state);
|
|
134
|
-
const bfcacheIds = hasBrowserRouterState() ? getBrowserRouterState().bfcacheIds : readCurrentBfcacheVersionHistoryIds(window.history.state);
|
|
135
|
-
const historyState = createHistoryStateWithNavigationMetadata(createHashOnlyNavigationBaseHistoryState(historyUpdateMode, scroll), {
|
|
136
|
-
bfcacheIds,
|
|
137
|
-
bfcacheVersion: bfcacheIds === null ? void 0 : currentBfcacheVersion,
|
|
138
|
-
previousNextUrl,
|
|
139
|
-
traversalIndex: navigationHistoryIndex
|
|
123
|
+
function restoreHistoryStateSnapshot(historyState) {
|
|
124
|
+
const navId = browserNavigationController.getActiveNavigationId();
|
|
125
|
+
let restored = false;
|
|
126
|
+
flushSync(() => {
|
|
127
|
+
restored = historyController.restoreHistorySnapshot({
|
|
128
|
+
historyState,
|
|
129
|
+
stageClientParams,
|
|
130
|
+
approveVisibleRestore: ({ state, beforeCommit }) => browserNavigationController.restoreHistorySnapshotVisibleState({
|
|
131
|
+
beforeCommit,
|
|
132
|
+
navId,
|
|
133
|
+
state,
|
|
134
|
+
targetHref: window.location.href
|
|
135
|
+
})
|
|
136
|
+
});
|
|
140
137
|
});
|
|
141
|
-
if (
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}
|
|
145
|
-
function createHashOnlyNavigationBaseHistoryState(historyUpdateMode, scroll) {
|
|
146
|
-
if (historyUpdateMode !== "replace") return null;
|
|
147
|
-
return scroll ? stripVinextScrollState(window.history.state) : window.history.state;
|
|
148
|
-
}
|
|
149
|
-
function stripVinextScrollState(state) {
|
|
150
|
-
if (!state || typeof state !== "object") return state;
|
|
151
|
-
const nextState = {};
|
|
152
|
-
for (const [key, value] of Object.entries(state)) {
|
|
153
|
-
if (key === "__vinext_scrollX" || key === "__vinext_scrollY") continue;
|
|
154
|
-
nextState[key] = value;
|
|
155
|
-
}
|
|
156
|
-
return Object.keys(nextState).length > 0 ? nextState : null;
|
|
157
|
-
}
|
|
158
|
-
function commitTraversalIndexFromHistoryState(historyState) {
|
|
159
|
-
commitHistoryTraversalIndex(readHistoryStateTraversalIndex(historyState));
|
|
138
|
+
if (!restored) return false;
|
|
139
|
+
commitClientNavigationState();
|
|
140
|
+
return true;
|
|
160
141
|
}
|
|
161
142
|
function getBrowserRouterState() {
|
|
162
143
|
return browserNavigationController.getBrowserRouterState();
|
|
@@ -190,7 +171,7 @@ function clearPrefetchState() {
|
|
|
190
171
|
function clearClientNavigationCaches() {
|
|
191
172
|
clearVisitedResponseCache();
|
|
192
173
|
clearPrefetchState();
|
|
193
|
-
|
|
174
|
+
historyController.invalidateRestorableClientState();
|
|
194
175
|
}
|
|
195
176
|
function isSettledPrefetchCacheEntry(entry) {
|
|
196
177
|
return entry.outcome === "cache-seeded" && entry.pending === void 0 && entry.snapshot !== void 0;
|
|
@@ -258,28 +239,6 @@ async function learnOptimisticRouteTemplatesFromPrefetchCache(options) {
|
|
|
258
239
|
if (learning.length === 0) return;
|
|
259
240
|
await Promise.allSettled(learning);
|
|
260
241
|
}
|
|
261
|
-
function areBfcacheIdMapsEqual(a, b) {
|
|
262
|
-
if (a === b) return true;
|
|
263
|
-
if (a === null || b === null) return false;
|
|
264
|
-
const aEntries = Object.entries(a);
|
|
265
|
-
const bEntries = Object.entries(b);
|
|
266
|
-
if (aEntries.length !== bEntries.length) return false;
|
|
267
|
-
return aEntries.every(([key, value]) => b[key] === value);
|
|
268
|
-
}
|
|
269
|
-
function isHistoryStateNavigationMetadataInSync(state, previousNextUrl, bfcacheIds) {
|
|
270
|
-
return readHistoryStatePreviousNextUrl(state) === previousNextUrl && (bfcacheIds === void 0 || areBfcacheIdMapsEqual(readHistoryStateBfcacheIds(state), bfcacheIds) && isCurrentBfcacheVersion(state));
|
|
271
|
-
}
|
|
272
|
-
function syncCurrentHistoryStatePreviousNextUrl(previousNextUrl, bfcacheIds) {
|
|
273
|
-
if (isHistoryStateNavigationMetadataInSync(window.history.state, previousNextUrl, bfcacheIds)) return;
|
|
274
|
-
const nextHistoryState = createHistoryStateWithNavigationMetadata(window.history.state, {
|
|
275
|
-
bfcacheIds,
|
|
276
|
-
bfcacheVersion: bfcacheIds === void 0 ? void 0 : currentBfcacheVersion,
|
|
277
|
-
previousNextUrl
|
|
278
|
-
});
|
|
279
|
-
replaceHistoryStateWithoutNotify(nextHistoryState, "", window.location.href);
|
|
280
|
-
if (isHistoryStateNavigationMetadataInSync(window.history.state, previousNextUrl, bfcacheIds)) return;
|
|
281
|
-
window.history.replaceState(nextHistoryState, "", window.location.href);
|
|
282
|
-
}
|
|
283
242
|
function createActionInitiationSnapshot() {
|
|
284
243
|
const routerState = getBrowserRouterState();
|
|
285
244
|
return createServerActionInitiationSnapshot({
|
|
@@ -295,37 +254,19 @@ function createNavigationCommitEffect(options) {
|
|
|
295
254
|
commitClientNavigationState(void 0, { releaseSnapshot: true });
|
|
296
255
|
return;
|
|
297
256
|
}
|
|
298
|
-
|
|
299
|
-
const preserveExistingState = historyUpdateMode === "replace";
|
|
300
|
-
const navigationHistoryIndex = targetHistoryIndex !== void 0 ? targetHistoryIndex : allocateNavigationHistoryTraversalIndex(historyUpdateMode);
|
|
301
|
-
const historyState = createHistoryStateWithNavigationMetadata(preserveExistingState ? window.history.state : null, {
|
|
257
|
+
historyController.commitNavigationHistory({
|
|
302
258
|
bfcacheIds,
|
|
303
|
-
|
|
259
|
+
href,
|
|
260
|
+
historyUpdateMode,
|
|
304
261
|
previousNextUrl,
|
|
305
|
-
|
|
262
|
+
stageClientParams: () => stageClientParams(params),
|
|
263
|
+
targetHistoryIndex
|
|
306
264
|
});
|
|
307
|
-
let wroteHistoryState = false;
|
|
308
|
-
if (historyUpdateMode === "replace" && window.location.href !== targetHref) {
|
|
309
|
-
stageClientParams(params);
|
|
310
|
-
replaceHistoryStateWithoutNotify(historyState, "", href);
|
|
311
|
-
wroteHistoryState = true;
|
|
312
|
-
commitHistoryTraversalIndex(navigationHistoryIndex);
|
|
313
|
-
} else if (historyUpdateMode === "push" && window.location.href !== targetHref) {
|
|
314
|
-
stageClientParams(params);
|
|
315
|
-
pushHistoryStateWithoutNotify(historyState, "", href);
|
|
316
|
-
wroteHistoryState = true;
|
|
317
|
-
commitHistoryTraversalIndex(navigationHistoryIndex);
|
|
318
|
-
}
|
|
319
|
-
if (!wroteHistoryState) {
|
|
320
|
-
syncCurrentHistoryStatePreviousNextUrl(previousNextUrl, bfcacheIds);
|
|
321
|
-
stageClientParams(params);
|
|
322
|
-
if (targetHistoryIndex !== void 0) commitHistoryTraversalIndex(targetHistoryIndex);
|
|
323
|
-
}
|
|
324
265
|
pendingNavigationRecoveryHref = null;
|
|
325
266
|
commitClientNavigationState(navId);
|
|
326
267
|
};
|
|
327
268
|
}
|
|
328
|
-
async function renderNavigationPayload(payload, navigationSnapshot, targetHref, navId, historyUpdateMode, params, previousNextUrl, pendingRouterState, payloadOrigin, actionType = "navigate", operationLane = "navigation", traversalIntent = null, scrollIntent = null, restoredBfcacheIds = null) {
|
|
269
|
+
async function renderNavigationPayload(payload, navigationSnapshot, targetHref, navId, historyUpdateMode, params, previousNextUrl, pendingRouterState, payloadOrigin, actionType = "navigate", operationLane = "navigation", traversalIntent = null, scrollIntent = null, restoredBfcacheIds = null, reuseCurrentBfcacheIds = true, visibleCommitMode = "transition") {
|
|
329
270
|
syncServerActionHttpFallbackHead(null);
|
|
330
271
|
try {
|
|
331
272
|
return await browserNavigationController.renderNavigationPayload({
|
|
@@ -344,9 +285,11 @@ async function renderNavigationPayload(payload, navigationSnapshot, targetHref,
|
|
|
344
285
|
previousNextUrl,
|
|
345
286
|
scrollIntent,
|
|
346
287
|
restoredBfcacheIds,
|
|
288
|
+
reuseCurrentBfcacheIds,
|
|
347
289
|
targetHistoryIndex: traversalIntent === null ? void 0 : traversalIntent.targetHistoryIndex,
|
|
348
290
|
targetHref,
|
|
349
|
-
navId
|
|
291
|
+
navId,
|
|
292
|
+
visibleCommitMode
|
|
350
293
|
});
|
|
351
294
|
} catch (error) {
|
|
352
295
|
pendingNavigationRecoveryHref = null;
|
|
@@ -450,9 +393,8 @@ function storeVisitedResponseSnapshot(rscUrl, interceptionContext, snapshot, par
|
|
|
450
393
|
response: snapshot
|
|
451
394
|
}));
|
|
452
395
|
}
|
|
453
|
-
function
|
|
454
|
-
|
|
455
|
-
return targetUrl.searchParams.toString() !== currentSnapshot.searchParams.toString();
|
|
396
|
+
function clientNavigationSnapshotHref(snapshot) {
|
|
397
|
+
return `${window.location.origin}${createSnapshotPathAndSearch(snapshot)}`;
|
|
456
398
|
}
|
|
457
399
|
function getRequestState(navigationKind, targetPathname, previousNextUrlOverride, traverseHistoryState) {
|
|
458
400
|
if (previousNextUrlOverride !== void 0) return {
|
|
@@ -476,6 +418,16 @@ function getRequestState(navigationKind, targetPathname, previousNextUrlOverride
|
|
|
476
418
|
interceptionContext: manifestInterceptionContext,
|
|
477
419
|
previousNextUrl: window.location.pathname + window.location.search
|
|
478
420
|
};
|
|
421
|
+
const middlewareRewriteInterceptionContext = resolveMiddlewareRewriteNavigationInterceptionContext({
|
|
422
|
+
basePath: __basePath,
|
|
423
|
+
currentPathname: window.location.pathname,
|
|
424
|
+
routeManifest: getBrowserRouteManifest(),
|
|
425
|
+
targetPathname
|
|
426
|
+
});
|
|
427
|
+
if (middlewareRewriteInterceptionContext !== null) return {
|
|
428
|
+
interceptionContext: middlewareRewriteInterceptionContext,
|
|
429
|
+
previousNextUrl: window.location.pathname + window.location.search
|
|
430
|
+
};
|
|
479
431
|
return {
|
|
480
432
|
interceptionContext: null,
|
|
481
433
|
previousNextUrl: null
|
|
@@ -584,6 +536,9 @@ function BrowserRoot({ initialElements, initialNavigationSnapshot }) {
|
|
|
584
536
|
setMountedSlotsHeader(null);
|
|
585
537
|
};
|
|
586
538
|
}, [setTreeStateValue]);
|
|
539
|
+
useLayoutEffect(() => {
|
|
540
|
+
historyController.rememberHistoryStateSnapshot(treeState);
|
|
541
|
+
}, [treeState]);
|
|
587
542
|
useLayoutEffect(() => {
|
|
588
543
|
setMountedSlotsHeader(getMountedSlotIdsHeader(stateRef.current.elements));
|
|
589
544
|
removeStylesheetLinksCoveredByInlineCss();
|
|
@@ -591,12 +546,10 @@ function BrowserRoot({ initialElements, initialNavigationSnapshot }) {
|
|
|
591
546
|
}, [treeState.elements]);
|
|
592
547
|
useLayoutEffect(() => {
|
|
593
548
|
if (treeState.renderId !== 0) return;
|
|
594
|
-
|
|
549
|
+
historyController.writeHydratedHistoryMetadata({
|
|
595
550
|
bfcacheIds: treeState.bfcacheIds,
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
traversalIndex: currentHistoryTraversalIndex
|
|
599
|
-
}), "", window.location.href);
|
|
551
|
+
previousNextUrl: treeState.previousNextUrl
|
|
552
|
+
});
|
|
600
553
|
}, [
|
|
601
554
|
treeState.bfcacheIds,
|
|
602
555
|
treeState.previousNextUrl,
|
|
@@ -634,16 +587,16 @@ function restorePopstateScrollPosition(state, options) {
|
|
|
634
587
|
return;
|
|
635
588
|
}
|
|
636
589
|
const y = Number(state.__vinext_scrollY);
|
|
637
|
-
retryScrollTo("__vinext_scrollX" in state ? Number(state.__vinext_scrollX) : 0, y, {
|
|
590
|
+
retryScrollTo("__vinext_scrollX" in state ? Number(state.__vinext_scrollX) : 0, y, {
|
|
591
|
+
minFrames: 1,
|
|
592
|
+
shouldContinue
|
|
593
|
+
});
|
|
638
594
|
}
|
|
639
595
|
function isSameAppRoutePopstateTarget(href) {
|
|
640
596
|
if (!hasBrowserRouterState()) return false;
|
|
641
597
|
const target = new URL(href, window.location.origin);
|
|
642
598
|
const routerState = getBrowserRouterState();
|
|
643
|
-
|
|
644
|
-
const targetSearch = new URLSearchParams(target.search).toString();
|
|
645
|
-
const currentSearch = routerState.navigationSnapshot.searchParams.toString();
|
|
646
|
-
return targetPathname === routerState.navigationSnapshot.pathname && targetSearch === currentSearch;
|
|
599
|
+
return createBasePathStrippedPathAndSearch(target, __basePath) === createSnapshotPathAndSearch(routerState.navigationSnapshot);
|
|
647
600
|
}
|
|
648
601
|
let isPageUnloading = false;
|
|
649
602
|
const RSC_RELOAD_KEY = "__vinext_rsc_initial_reload__";
|
|
@@ -724,11 +677,11 @@ function applyRuntimeRscBootstrap(rsc) {
|
|
|
724
677
|
if (rsc.nav) restoreHydrationNavigationContext(rsc.nav.pathname, rsc.nav.searchParams, params);
|
|
725
678
|
}
|
|
726
679
|
function registerServerActionCallback() {
|
|
727
|
-
|
|
680
|
+
const serverActionCallback = async (id, args) => {
|
|
728
681
|
syncServerActionHttpFallbackHead(null);
|
|
729
682
|
const temporaryReferences = createTemporaryReferenceSet();
|
|
730
683
|
const actionInitiation = createActionInitiationSnapshot();
|
|
731
|
-
syncCurrentHistoryStatePreviousNextUrl(actionInitiation.routerState.previousNextUrl, actionInitiation.routerState.bfcacheIds);
|
|
684
|
+
historyController.syncCurrentHistoryStatePreviousNextUrl(actionInitiation.routerState.previousNextUrl, actionInitiation.routerState.bfcacheIds);
|
|
732
685
|
const body = await encodeReply(args, { temporaryReferences });
|
|
733
686
|
const { headers } = resolveServerActionRequestState({
|
|
734
687
|
actionId: id,
|
|
@@ -766,6 +719,7 @@ function registerServerActionCallback() {
|
|
|
766
719
|
return;
|
|
767
720
|
}
|
|
768
721
|
const revalidation = parseServerActionRevalidationHeader(fetchResponse.headers);
|
|
722
|
+
if (revalidation !== "none") clearClientNavigationCaches();
|
|
769
723
|
const invalidResponseError = await readInvalidServerActionResponseError(fetchResponse.clone(), actionRedirectTarget !== null);
|
|
770
724
|
if (invalidResponseError) throw invalidResponseError;
|
|
771
725
|
if (actionRedirectTarget && !shouldCheckRscCompatibilityForServerActionResponse(fetchResponse)) {
|
|
@@ -778,7 +732,7 @@ function registerServerActionCallback() {
|
|
|
778
732
|
statusText: "OK"
|
|
779
733
|
}) : fetchResponse;
|
|
780
734
|
const result = await createFromFetch(Promise.resolve(flightResponse), { temporaryReferences });
|
|
781
|
-
if (shouldClearClientNavigationCachesForServerActionResult(result, revalidation)) clearClientNavigationCaches();
|
|
735
|
+
if (revalidation === "none" && shouldClearClientNavigationCachesForServerActionResult(result, revalidation)) clearClientNavigationCaches();
|
|
782
736
|
if (actionRedirectTarget) {
|
|
783
737
|
if (isServerActionResult(result) && result.root !== void 0) {
|
|
784
738
|
const decoded = AppElementsWire.decode(result.root);
|
|
@@ -809,6 +763,10 @@ function registerServerActionCallback() {
|
|
|
809
763
|
return;
|
|
810
764
|
}
|
|
811
765
|
return commitSameUrlNavigatePayload(Promise.resolve(AppElementsWire.decode(result)), actionInitiation, void 0, revalidation);
|
|
766
|
+
};
|
|
767
|
+
setServerCallback((id, args) => {
|
|
768
|
+
const releaseCacheInvalidationGuard = historyController.beginCacheInvalidationGuard();
|
|
769
|
+
return Promise.resolve().then(() => serverActionCallback(id, args)).finally(releaseCacheInvalidationGuard);
|
|
812
770
|
});
|
|
813
771
|
}
|
|
814
772
|
async function main() {
|
|
@@ -825,10 +783,7 @@ async function main() {
|
|
|
825
783
|
function bootstrapHydration(rscStream) {
|
|
826
784
|
const root = decodeAppElementsPromise(createFromReadableStream(rscStream));
|
|
827
785
|
const initialNavigationSnapshot = createClientNavigationRenderSnapshot(window.location.href, latestClientParams);
|
|
828
|
-
|
|
829
|
-
previousNextUrl: null,
|
|
830
|
-
traversalIndex: currentHistoryTraversalIndex
|
|
831
|
-
}), "", window.location.href);
|
|
786
|
+
historyController.writeBootstrapHistoryMetadata();
|
|
832
787
|
const onUncaughtError = import.meta.env.DEV ? devOnUncaughtError : createOnUncaughtError(() => pendingNavigationRecoveryHref);
|
|
833
788
|
const formState = consumeInitialFormState(getVinextBrowserGlobal());
|
|
834
789
|
const hydrateRootOptions = import.meta.env.DEV ? createVinextHydrateRootOptions({
|
|
@@ -837,6 +792,7 @@ function bootstrapHydration(rscStream) {
|
|
|
837
792
|
onUncaughtError
|
|
838
793
|
}) : createVinextHydrateRootOptions({
|
|
839
794
|
formState,
|
|
795
|
+
onCaughtError: prodOnCaughtError,
|
|
840
796
|
onUncaughtError
|
|
841
797
|
});
|
|
842
798
|
window.__VINEXT_RSC_ROOT__ = hydrateRootInTransition({
|
|
@@ -851,8 +807,8 @@ function bootstrapHydration(rscStream) {
|
|
|
851
807
|
});
|
|
852
808
|
registerNavigationRuntimeFunctions({
|
|
853
809
|
clearNavigationCaches: clearClientNavigationCaches,
|
|
854
|
-
commitHashNavigation: commitHashOnlyNavigation,
|
|
855
|
-
navigate: async function navigateRsc(href, redirectDepth = 0, navigationKind = "navigate", historyUpdateMode, previousNextUrlOverride, programmaticTransition = false, traversalIntent, scrollIntent) {
|
|
810
|
+
commitHashNavigation: (href, historyUpdateMode, scroll) => historyController.commitHashOnlyNavigation(href, historyUpdateMode, scroll),
|
|
811
|
+
navigate: async function navigateRsc(href, redirectDepth = 0, navigationKind = "navigate", historyUpdateMode, previousNextUrlOverride, programmaticTransition = false, traversalIntent, scrollIntent, visibleCommitMode = "transition") {
|
|
856
812
|
let pendingRouterState = null;
|
|
857
813
|
const navId = browserNavigationController.beginNavigation();
|
|
858
814
|
discardedServerActionRefreshScheduler.markNavigationStart();
|
|
@@ -861,15 +817,13 @@ function bootstrapHydration(rscStream) {
|
|
|
861
817
|
let currentPrevNextUrl = previousNextUrlOverride;
|
|
862
818
|
let redirectCount = redirectDepth;
|
|
863
819
|
let detachedNavigationCommits = false;
|
|
864
|
-
const activeTraversalIntent = navigationKind === "traverse" ? traversalIntent ??
|
|
865
|
-
currentHistoryIndex: currentHistoryTraversalIndex,
|
|
866
|
-
historyState: window.history.state
|
|
867
|
-
}) : null;
|
|
820
|
+
const activeTraversalIntent = navigationKind === "traverse" ? traversalIntent ?? historyController.resolveTraversalIntent(window.history.state) : null;
|
|
868
821
|
const performHardNavigationForScrollIntent = (targetHref) => {
|
|
869
822
|
consumeAppRouterScrollIntent(scrollIntent ?? null);
|
|
870
823
|
return browserNavigationController.performHardNavigation(targetHref);
|
|
871
824
|
};
|
|
872
|
-
let restoredBfcacheIds = navigationKind === "traverse" ? readCurrentBfcacheVersionHistoryIds(activeTraversalIntent?.historyState ?? window.history.state) : null;
|
|
825
|
+
let restoredBfcacheIds = navigationKind === "traverse" ? historyController.readCurrentBfcacheVersionHistoryIds(activeTraversalIntent?.historyState ?? window.history.state) : null;
|
|
826
|
+
const reuseCurrentBfcacheIds = navigationKind !== "traverse" || !historyController.isCacheInvalidationGuarded() && historyController.isCurrentBfcacheVersion(activeTraversalIntent?.historyState ?? window.history.state);
|
|
873
827
|
try {
|
|
874
828
|
const shouldUsePendingRouterState = programmaticTransition;
|
|
875
829
|
if (shouldUsePendingRouterState && hasBrowserRouterState()) pendingRouterState = beginPendingBrowserRouterState();
|
|
@@ -883,12 +837,19 @@ function bootstrapHydration(rscStream) {
|
|
|
883
837
|
const requestState = getRequestState(navigationKind, url.pathname, currentPrevNextUrl, activeTraversalIntent?.historyState);
|
|
884
838
|
const requestInterceptionContext = requestState.interceptionContext;
|
|
885
839
|
const requestPreviousNextUrl = requestState.previousNextUrl;
|
|
886
|
-
if (navigationKind === "refresh") syncCurrentHistoryStatePreviousNextUrl(requestPreviousNextUrl, getBrowserRouterState().bfcacheIds);
|
|
840
|
+
if (navigationKind === "refresh") historyController.syncCurrentHistoryStatePreviousNextUrl(requestPreviousNextUrl, getBrowserRouterState().bfcacheIds);
|
|
887
841
|
setPendingPathname(url.pathname, navId);
|
|
888
842
|
const routerStateAtNavStart = getBrowserRouterState();
|
|
889
843
|
const elementsAtNavStart = routerStateAtNavStart.elements;
|
|
890
844
|
const mountedSlotsHeader = getMountedSlotIdsHeader(elementsAtNavStart);
|
|
891
|
-
const
|
|
845
|
+
const earlyIntentDecision = navigationKind === "navigate" ? navigationPlanner.classifyEarlyNavigationIntent({
|
|
846
|
+
basePath: __basePath,
|
|
847
|
+
currentHref: clientNavigationSnapshotHref(routerStateAtNavStart.navigationSnapshot),
|
|
848
|
+
mode: "push",
|
|
849
|
+
scroll: false,
|
|
850
|
+
targetHref: url.href
|
|
851
|
+
}) : null;
|
|
852
|
+
const shouldBypassNavigationCache = earlyIntentDecision?.kind === "flightNavigation" && earlyIntentDecision.bypassNavigationCache;
|
|
892
853
|
const requestHeaders = createRscRequestHeaders({
|
|
893
854
|
interceptionContext: requestInterceptionContext,
|
|
894
855
|
mountedSlotsHeader,
|
|
@@ -897,36 +858,32 @@ function bootstrapHydration(rscStream) {
|
|
|
897
858
|
const rscUrl = await createRscRequestUrl(url.pathname + url.search, requestHeaders);
|
|
898
859
|
const cachedRoute = shouldBypassNavigationCache ? null : getVisitedResponse(rscUrl, requestInterceptionContext, mountedSlotsHeader, navigationKind);
|
|
899
860
|
if (cachedRoute) {
|
|
900
|
-
const
|
|
861
|
+
const cachedFetchDecision = navigationPlanner.classifyRscFetchResult({
|
|
901
862
|
clientCompatibilityId: CLIENT_RSC_COMPATIBILITY_ID,
|
|
863
|
+
compatibilityIdHeader: cachedRoute.response.compatibilityIdHeader ?? null,
|
|
902
864
|
currentHref,
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
});
|
|
907
|
-
if (compatibilityDecision.kind === "hard-navigate") {
|
|
908
|
-
performHardNavigationForScrollIntent(compatibilityDecision.hardNavigationTarget);
|
|
909
|
-
return;
|
|
910
|
-
}
|
|
911
|
-
const cachedRedirectDecision = resolveRscRedirectLifecycleHop({
|
|
912
|
-
currentHref,
|
|
913
|
-
historyUpdateMode: currentHistoryMode ?? "replace",
|
|
865
|
+
effectiveHistoryUpdateMode: currentHistoryMode ?? "replace",
|
|
866
|
+
hasBody: true,
|
|
867
|
+
isRscContentType: true,
|
|
914
868
|
origin: window.location.origin,
|
|
915
869
|
redirectDepth: redirectCount,
|
|
916
870
|
requestPreviousNextUrl,
|
|
917
|
-
|
|
871
|
+
responseOk: true,
|
|
872
|
+
responseUrl: cachedRoute.response.url,
|
|
873
|
+
source: "cached",
|
|
874
|
+
streamedRedirectTarget: null
|
|
918
875
|
});
|
|
919
|
-
if (
|
|
920
|
-
if (
|
|
921
|
-
performHardNavigationForScrollIntent(
|
|
876
|
+
if (cachedFetchDecision.kind === "hardNavigate") {
|
|
877
|
+
if (cachedFetchDecision.reason === "redirectDepthExhausted") console.error("[vinext] Too many RSC redirects — aborting navigation to prevent infinite loop.");
|
|
878
|
+
performHardNavigationForScrollIntent(cachedFetchDecision.url);
|
|
922
879
|
return;
|
|
923
880
|
}
|
|
924
|
-
if (
|
|
881
|
+
if (cachedFetchDecision.kind === "followRedirect") {
|
|
925
882
|
if (navigationKind === "traverse") restoredBfcacheIds = null;
|
|
926
|
-
currentHref =
|
|
927
|
-
currentHistoryMode =
|
|
928
|
-
currentPrevNextUrl =
|
|
929
|
-
redirectCount =
|
|
883
|
+
currentHref = cachedFetchDecision.redirect.href;
|
|
884
|
+
currentHistoryMode = cachedFetchDecision.redirect.historyUpdateMode;
|
|
885
|
+
currentPrevNextUrl = cachedFetchDecision.redirect.previousNextUrl;
|
|
886
|
+
redirectCount = cachedFetchDecision.redirect.redirectDepth;
|
|
930
887
|
continue;
|
|
931
888
|
}
|
|
932
889
|
if (!browserNavigationController.isCurrentNavigation(navId)) return;
|
|
@@ -934,7 +891,7 @@ function bootstrapHydration(rscStream) {
|
|
|
934
891
|
const cachedNavigationSnapshot = createClientNavigationRenderSnapshot(currentHref, cachedParams);
|
|
935
892
|
const cachedPayload = decodeAppElementsPromise(createFromFetch(Promise.resolve(restoreRscResponse(cachedRoute.response))));
|
|
936
893
|
if (!browserNavigationController.isCurrentNavigation(navId)) return;
|
|
937
|
-
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) === "no-commit") {
|
|
894
|
+
if (await renderNavigationPayload(cachedPayload, cachedNavigationSnapshot, currentHref, navId, currentHistoryMode, cachedParams, requestPreviousNextUrl, detachedNavigationCommits ? null : pendingRouterState, VISITED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN, toActionType(navigationKind), toOperationLane(navigationKind), activeTraversalIntent, scrollIntent, restoredBfcacheIds, reuseCurrentBfcacheIds, visibleCommitMode) === "no-commit") {
|
|
938
895
|
deleteVisitedResponse(rscUrl, requestInterceptionContext);
|
|
939
896
|
continue;
|
|
940
897
|
}
|
|
@@ -972,7 +929,7 @@ function bootstrapHydration(rscStream) {
|
|
|
972
929
|
if (optimisticPayload !== null) {
|
|
973
930
|
detachedNavigationCommits = true;
|
|
974
931
|
const optimisticNavigationSnapshot = createClientNavigationRenderSnapshot(currentHref, optimisticPayload.params);
|
|
975
|
-
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).catch((error) => {
|
|
932
|
+
renderNavigationPayload(Promise.resolve(optimisticPayload.elements), optimisticNavigationSnapshot, currentHref, navId, currentHistoryMode, optimisticPayload.params, requestPreviousNextUrl, null, FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, toActionType(navigationKind), toOperationLane(navigationKind), activeTraversalIntent, scrollIntent, restoredBfcacheIds, reuseCurrentBfcacheIds, visibleCommitMode).catch((error) => {
|
|
976
933
|
if (browserNavigationController.isCurrentNavigation(navId)) console.error("[vinext] Optimistic RSC navigation error:", error);
|
|
977
934
|
});
|
|
978
935
|
}
|
|
@@ -989,61 +946,36 @@ function bootstrapHydration(rscStream) {
|
|
|
989
946
|
});
|
|
990
947
|
}
|
|
991
948
|
if (!browserNavigationController.isCurrentNavigation(navId)) return;
|
|
992
|
-
const
|
|
993
|
-
|
|
994
|
-
performHardNavigationForScrollIntent(resolveHardNavigationTargetFromRscResponse(navResponseUrl ?? navResponse.url, currentHref, window.location.origin));
|
|
995
|
-
return;
|
|
996
|
-
}
|
|
997
|
-
const compatibilityDecision = resolveRscCompatibilityNavigationDecision({
|
|
949
|
+
const navContentType = navResponse.headers.get("content-type") ?? "";
|
|
950
|
+
const liveFetchDecision = navigationPlanner.classifyRscFetchResult({
|
|
998
951
|
clientCompatibilityId: CLIENT_RSC_COMPATIBILITY_ID,
|
|
952
|
+
compatibilityIdHeader: navResponse.headers.get(VINEXT_RSC_COMPATIBILITY_ID_HEADER),
|
|
999
953
|
currentHref,
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
});
|
|
1004
|
-
if (compatibilityDecision.kind === "hard-navigate") {
|
|
1005
|
-
performHardNavigationForScrollIntent(compatibilityDecision.hardNavigationTarget);
|
|
1006
|
-
return;
|
|
1007
|
-
}
|
|
1008
|
-
const redirectDecision = resolveRscRedirectLifecycleHop({
|
|
1009
|
-
currentHref,
|
|
1010
|
-
historyUpdateMode: currentHistoryMode ?? "replace",
|
|
954
|
+
effectiveHistoryUpdateMode: currentHistoryMode ?? "replace",
|
|
955
|
+
hasBody: navResponse.body !== null,
|
|
956
|
+
isRscContentType: navContentType.startsWith(VINEXT_RSC_CONTENT_TYPE),
|
|
1011
957
|
origin: window.location.origin,
|
|
1012
958
|
redirectDepth: redirectCount,
|
|
1013
959
|
requestPreviousNextUrl,
|
|
1014
|
-
|
|
960
|
+
responseOk: navResponse.ok,
|
|
961
|
+
responseUrl: navResponseUrl ?? navResponse.url,
|
|
962
|
+
source: "live",
|
|
963
|
+
streamedRedirectTarget: navResponse.headers.get(VINEXT_RSC_REDIRECT_HEADER)
|
|
1015
964
|
});
|
|
1016
|
-
if (
|
|
1017
|
-
if (
|
|
1018
|
-
|
|
965
|
+
if (liveFetchDecision.kind === "hardNavigate") {
|
|
966
|
+
if (liveFetchDecision.discardBody) navResponse.body?.cancel().catch(() => {});
|
|
967
|
+
if (liveFetchDecision.reason === "redirectDepthExhausted") console.error("[vinext] Too many RSC redirects — aborting navigation to prevent infinite loop.");
|
|
968
|
+
if (liveFetchDecision.reason === "streamedRedirectLoop") console.error("[vinext] RSC streamed redirect resolved to the current URL — aborting navigation to prevent infinite loop.");
|
|
969
|
+
performHardNavigationForScrollIntent(liveFetchDecision.url);
|
|
1019
970
|
return;
|
|
1020
971
|
}
|
|
1021
|
-
if (
|
|
1022
|
-
if (
|
|
1023
|
-
currentHref = redirectDecision.href;
|
|
1024
|
-
currentHistoryMode = redirectDecision.historyUpdateMode;
|
|
1025
|
-
currentPrevNextUrl = redirectDecision.previousNextUrl;
|
|
1026
|
-
redirectCount = redirectDecision.redirectDepth;
|
|
1027
|
-
continue;
|
|
1028
|
-
}
|
|
1029
|
-
const flightRedirectTarget = navResponse.headers.get(VINEXT_RSC_REDIRECT_HEADER);
|
|
1030
|
-
if (flightRedirectTarget) {
|
|
1031
|
-
navResponse.body?.cancel().catch(() => {});
|
|
1032
|
-
const resolvedTarget = new URL(flightRedirectTarget, window.location.origin);
|
|
1033
|
-
if (resolvedTarget.origin !== window.location.origin) {
|
|
1034
|
-
performHardNavigationForScrollIntent(resolvedTarget.href);
|
|
1035
|
-
return;
|
|
1036
|
-
}
|
|
1037
|
-
if (redirectCount >= 10) {
|
|
1038
|
-
console.error("[vinext] Too many RSC redirects — aborting navigation to prevent infinite loop.");
|
|
1039
|
-
performHardNavigationForScrollIntent(resolvedTarget.href);
|
|
1040
|
-
return;
|
|
1041
|
-
}
|
|
972
|
+
if (liveFetchDecision.kind === "followRedirect") {
|
|
973
|
+
if (liveFetchDecision.discardBody) navResponse.body?.cancel().catch(() => {});
|
|
1042
974
|
if (navigationKind === "traverse") restoredBfcacheIds = null;
|
|
1043
|
-
currentHref =
|
|
1044
|
-
currentHistoryMode =
|
|
1045
|
-
currentPrevNextUrl =
|
|
1046
|
-
redirectCount
|
|
975
|
+
currentHref = liveFetchDecision.redirect.href;
|
|
976
|
+
currentHistoryMode = liveFetchDecision.redirect.historyUpdateMode;
|
|
977
|
+
currentPrevNextUrl = liveFetchDecision.redirect.previousNextUrl;
|
|
978
|
+
redirectCount = liveFetchDecision.redirect.redirectDepth;
|
|
1047
979
|
continue;
|
|
1048
980
|
}
|
|
1049
981
|
const navParams = parseEncodedJsonHeader(navResponse.headers.get("X-Vinext-Params")) ?? {};
|
|
@@ -1059,7 +991,7 @@ function bootstrapHydration(rscStream) {
|
|
|
1059
991
|
if (!browserNavigationController.isCurrentNavigation(navId)) return;
|
|
1060
992
|
const rscPayload = decodeAppElementsPromise(createFromFetch(Promise.resolve(reactResponse)));
|
|
1061
993
|
if (!browserNavigationController.isCurrentNavigation(navId)) return;
|
|
1062
|
-
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) !== "committed") return;
|
|
994
|
+
if (await renderNavigationPayload(rscPayload, navigationSnapshot, currentHref, navId, currentHistoryMode, navParams, requestPreviousNextUrl, detachedNavigationCommits ? null : pendingRouterState, FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, toActionType(navigationKind), toOperationLane(navigationKind), activeTraversalIntent, scrollIntent, restoredBfcacheIds, reuseCurrentBfcacheIds, visibleCommitMode) !== "committed") return;
|
|
1063
995
|
if (!browserNavigationController.isCurrentNavigation(navId)) return;
|
|
1064
996
|
try {
|
|
1065
997
|
const renderedElements = await rscPayload;
|
|
@@ -1087,7 +1019,6 @@ function bootstrapHydration(rscStream) {
|
|
|
1087
1019
|
}
|
|
1088
1020
|
}
|
|
1089
1021
|
});
|
|
1090
|
-
if ("scrollRestoration" in history) history.scrollRestoration = "manual";
|
|
1091
1022
|
const handlePopstate = createPopstateRestoreHandler({
|
|
1092
1023
|
getActiveNavigationId: browserNavigationController.getActiveNavigationId.bind(browserNavigationController),
|
|
1093
1024
|
getPendingNavigation: () => window.__VINEXT_RSC_PENDING__,
|
|
@@ -1099,17 +1030,26 @@ function bootstrapHydration(rscStream) {
|
|
|
1099
1030
|
restorePopstateScrollPosition,
|
|
1100
1031
|
setPendingNavigation: (pendingNavigation) => {
|
|
1101
1032
|
window.__VINEXT_RSC_PENDING__ = pendingNavigation;
|
|
1102
|
-
}
|
|
1033
|
+
},
|
|
1034
|
+
shouldSkipScrollRestore: (navId) => synchronousPopstateScrollRestoreNavigationId === navId
|
|
1103
1035
|
});
|
|
1104
1036
|
window.addEventListener("popstate", (event) => {
|
|
1105
1037
|
const href = window.location.href;
|
|
1106
1038
|
if (isSameAppRoutePopstateTarget(href)) {
|
|
1107
1039
|
notifyAppRouterTransitionStart(href, "traverse");
|
|
1108
|
-
commitTraversalIndexFromHistoryState(event.state);
|
|
1040
|
+
historyController.commitTraversalIndexFromHistoryState(event.state);
|
|
1109
1041
|
restorePopstateScrollPosition(event.state);
|
|
1110
1042
|
return;
|
|
1111
1043
|
}
|
|
1112
1044
|
handlePopstate(event);
|
|
1045
|
+
if (restoreHistoryStateSnapshot(event.state)) restoreSynchronousPopstateScrollPosition({
|
|
1046
|
+
getActiveNavigationId: () => browserNavigationController.getActiveNavigationId(),
|
|
1047
|
+
isCurrentNavigation: (navId) => browserNavigationController.isCurrentNavigation(navId),
|
|
1048
|
+
markScrollRestoreConsumed: (navId) => {
|
|
1049
|
+
synchronousPopstateScrollRestoreNavigationId = navId;
|
|
1050
|
+
},
|
|
1051
|
+
restorePopstateScrollPosition
|
|
1052
|
+
}, event.state);
|
|
1113
1053
|
});
|
|
1114
1054
|
if (import.meta.hot) {
|
|
1115
1055
|
const applyRscHmrUpdate = async (updateId) => {
|