vinext 0.2.0 → 0.2.1
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/dist/build/css-url-assets.d.ts +3 -1
- package/dist/build/css-url-assets.js +18 -1
- package/dist/build/inject-pregenerated-paths.d.ts +3 -0
- package/dist/build/inject-pregenerated-paths.js +4 -1
- package/dist/build/prerender-server-entry.d.ts +1 -0
- package/dist/build/prerender-server-entry.js +49 -0
- package/dist/build/prerender-server-pool.d.ts +44 -0
- package/dist/build/prerender-server-pool.js +194 -0
- package/dist/build/prerender.js +86 -22
- package/dist/build/run-prerender.js +2 -1
- package/dist/check.d.ts +4 -6
- package/dist/check.js +8 -9
- package/dist/cli.js +1 -1
- package/dist/client/vinext-next-data.d.ts +4 -1
- package/dist/config/config-matchers.js +33 -11
- package/dist/config/next-config.d.ts +36 -6
- package/dist/config/next-config.js +16 -2
- package/dist/entries/app-browser-entry.js +5 -1
- package/dist/entries/app-rsc-entry.d.ts +3 -2
- package/dist/entries/app-rsc-entry.js +4 -0
- package/dist/entries/pages-client-entry.js +14 -3
- package/dist/entries/pages-server-entry.js +18 -4
- package/dist/index.js +320 -25
- package/dist/packages/cloudflare/src/cache/kv-data-adapter.runtime.js +8 -1
- package/dist/packages/cloudflare/src/deploy.js +1 -5
- package/dist/packages/cloudflare/src/tpr.js +26 -5
- package/dist/plugins/fonts.js +1 -1
- package/dist/plugins/ignore-dynamic-requests.js +1 -1
- package/dist/plugins/og-assets.js +2 -1
- package/dist/plugins/optimize-imports.js +1 -1
- package/dist/plugins/rsc-reference-validation-normalizer.d.ts +12 -0
- package/dist/plugins/rsc-reference-validation-normalizer.js +48 -0
- package/dist/plugins/sass.d.ts +17 -1
- package/dist/plugins/sass.js +74 -1
- package/dist/plugins/styled-jsx.d.ts +16 -0
- package/dist/plugins/styled-jsx.js +149 -0
- package/dist/routing/app-route-graph.js +22 -16
- package/dist/routing/file-matcher.d.ts +8 -1
- package/dist/routing/file-matcher.js +15 -3
- package/dist/server/app-browser-entry.js +46 -14
- package/dist/server/app-browser-navigation-controller.js +1 -1
- package/dist/server/app-browser-server-action-client.js +5 -3
- package/dist/server/app-browser-state.d.ts +1 -0
- package/dist/server/app-browser-state.js +2 -2
- package/dist/server/app-browser-visible-commit.js +1 -1
- package/dist/server/app-page-boundary.js +2 -1
- package/dist/server/app-page-cache-finalizer.d.ts +1 -0
- package/dist/server/app-page-cache-finalizer.js +3 -3
- package/dist/server/app-page-cache.js +23 -6
- package/dist/server/app-page-dispatch.d.ts +1 -0
- package/dist/server/app-page-dispatch.js +25 -8
- package/dist/server/app-page-element-builder.js +1 -0
- package/dist/server/app-page-execution.js +2 -1
- package/dist/server/app-page-render-identity.d.ts +1 -0
- package/dist/server/app-page-render-identity.js +2 -1
- package/dist/server/app-page-render.d.ts +2 -0
- package/dist/server/app-page-render.js +67 -16
- package/dist/server/app-page-response.d.ts +7 -0
- package/dist/server/app-page-response.js +16 -4
- package/dist/server/app-page-stream.d.ts +2 -1
- package/dist/server/app-page-stream.js +1 -1
- package/dist/server/app-route-handler-execution.js +1 -1
- package/dist/server/app-route-tree-prefetch.d.ts +43 -0
- package/dist/server/app-route-tree-prefetch.js +187 -0
- package/dist/server/app-router-entry.js +1 -1
- package/dist/server/app-rsc-cache-busting.d.ts +2 -1
- package/dist/server/app-rsc-cache-busting.js +9 -4
- package/dist/server/app-rsc-handler.d.ts +6 -0
- package/dist/server/app-rsc-handler.js +89 -11
- package/dist/server/app-rsc-render-mode.d.ts +3 -2
- package/dist/server/app-rsc-render-mode.js +4 -1
- package/dist/server/app-rsc-request-normalization.d.ts +3 -4
- package/dist/server/app-rsc-request-normalization.js +4 -5
- package/dist/server/app-server-action-execution.js +4 -3
- package/dist/server/app-ssr-entry.js +3 -3
- package/dist/server/cache-control.d.ts +3 -1
- package/dist/server/cache-control.js +13 -1
- package/dist/server/dev-server.d.ts +11 -1
- package/dist/server/dev-server.js +78 -20
- package/dist/server/headers.d.ts +6 -2
- package/dist/server/headers.js +11 -5
- package/dist/server/isr-cache.d.ts +2 -1
- package/dist/server/isr-cache.js +7 -3
- package/dist/server/pages-data-route.d.ts +4 -2
- package/dist/server/pages-data-route.js +18 -4
- package/dist/server/pages-dev-module-url.d.ts +2 -1
- package/dist/server/pages-dev-module-url.js +6 -3
- package/dist/server/pages-node-compat.d.ts +12 -1
- package/dist/server/pages-node-compat.js +50 -1
- package/dist/server/pages-page-data.d.ts +9 -0
- package/dist/server/pages-page-data.js +17 -9
- package/dist/server/pages-page-handler.js +19 -7
- package/dist/server/pages-page-response.d.ts +1 -0
- package/dist/server/pages-page-response.js +3 -2
- package/dist/server/pages-request-pipeline.d.ts +8 -6
- package/dist/server/pages-request-pipeline.js +30 -6
- package/dist/server/pages-router-entry.js +1 -1
- package/dist/server/prod-server.d.ts +4 -2
- package/dist/server/prod-server.js +38 -22
- package/dist/server/request-pipeline.js +1 -1
- package/dist/shims/cache-handler.js +8 -1
- package/dist/shims/cache.js +3 -0
- package/dist/shims/fetch-cache.d.ts +3 -1
- package/dist/shims/fetch-cache.js +77 -52
- package/dist/shims/form.d.ts +1 -1
- package/dist/shims/internal/app-prefetch-fetch-queue.d.ts +10 -0
- package/dist/shims/internal/app-prefetch-fetch-queue.js +61 -0
- package/dist/shims/internal/hybrid-client-route-owner.d.ts +2 -1
- package/dist/shims/internal/hybrid-client-route-owner.js +34 -1
- package/dist/shims/internal/pages-data-fetch-dedup.d.ts +2 -1
- package/dist/shims/internal/pages-data-fetch-dedup.js +13 -2
- package/dist/shims/internal/pages-data-target.d.ts +8 -3
- package/dist/shims/internal/pages-data-target.js +9 -4
- package/dist/shims/link.d.ts +1 -1
- package/dist/shims/link.js +179 -42
- package/dist/shims/navigation.d.ts +15 -3
- package/dist/shims/navigation.js +202 -39
- package/dist/shims/navigation.react-server.js +1 -1
- package/dist/shims/request-context.js +18 -0
- package/dist/shims/router.js +31 -15
- package/dist/shims/unified-request-context.js +1 -0
- package/dist/typegen.js +1 -1
- package/dist/utils/middleware-request-headers.js +1 -1
- package/dist/utils/protocol-headers.d.ts +7 -1
- package/dist/utils/protocol-headers.js +7 -1
- package/dist/utils/vite-version.d.ts +2 -0
- package/dist/utils/vite-version.js +11 -1
- package/package.json +2 -2
|
@@ -13,19 +13,20 @@ import { DevRecoveryBoundary, GlobalErrorBoundary, RedirectBoundary } from "../s
|
|
|
13
13
|
import { beginAppRouterScrollIntent, consumeAppRouterScrollIntent } from "../shims/app-router-scroll-state.js";
|
|
14
14
|
import { AppRouterScrollCommitProvider } from "../shims/app-router-scroll.js";
|
|
15
15
|
import { BfcacheStateKeyMapContext, ElementsContext, Slot } from "../shims/slot.js";
|
|
16
|
-
import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, createRscRequestHeaders, createRscRequestUrl, getVinextRscCompatibilityId } from "./app-rsc-cache-busting.js";
|
|
16
|
+
import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, createRscRequestHeaders, createRscRequestUrl, getVinextRscCompatibilityId, stripRscCacheBustingSearchParam } from "./app-rsc-cache-busting.js";
|
|
17
17
|
import { getNavigationRuntime, registerNavigationRuntimeBootstrap, registerNavigationRuntimeFunctions } from "../client/navigation-runtime.js";
|
|
18
18
|
import { notifyAppRouterTransitionStart } from "../client/instrumentation-client-state.js";
|
|
19
19
|
import "../client/instrumentation-client.js";
|
|
20
|
-
import { createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap } from "./app-bfcache-identity.js";
|
|
21
|
-
import { createDiscardedServerActionRefreshScheduler, createServerActionInitiationSnapshot, resolveServerActionOperationLane } from "./app-browser-action-result.js";
|
|
22
|
-
import { createClientReuseManifestHeaderFromVisibleAppState } from "./app-browser-client-reuse-manifest.js";
|
|
23
20
|
import { resolveManifestNavigationInterceptionContext, resolveMiddlewareRewriteNavigationInterceptionContext } from "./app-browser-interception-context.js";
|
|
24
21
|
import { readHistoryStatePreviousNextUrl } from "./app-history-state.js";
|
|
25
22
|
import { AppBrowserMpaNavigationScheduler } from "./app-browser-mpa-navigation.js";
|
|
26
23
|
import { blockDangerousStreamedRscRedirect } from "./app-browser-rsc-redirect.js";
|
|
27
24
|
import { navigationPlanner } from "./navigation-planner.js";
|
|
28
|
-
import {
|
|
25
|
+
import { resolveHybridClientRewriteHref } from "../shims/internal/hybrid-client-route-owner.js";
|
|
26
|
+
import { DYNAMIC_NAVIGATION_CACHE_TTL, PREFETCH_CACHE_TTL, __basePath, appRouterInstance, commitClientNavigationState, consumePrefetchResponseForNavigation, createCachedRscResponseSnapshot, createClientNavigationRenderSnapshot, createSnapshotPathAndSearch, deletePrefetchResponseSnapshot, getClientNavigationRenderContext, getMountedSlotsHeader, getPrefetchCache, hasPrefetchCacheEntryForNavigation, invalidatePrefetchCache, pushHistoryStateWithoutNotify, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, resolvePrefetchCacheEntryMountedSlotsHeader, restoreRscResponse, saveScrollPosition, seedPrefetchResponseSnapshot, setClientParams, setMountedSlotsHeader, setPendingPathname, useRouter } from "../shims/navigation.js";
|
|
27
|
+
import { createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap } from "./app-bfcache-identity.js";
|
|
28
|
+
import { createDiscardedServerActionRefreshScheduler, createServerActionInitiationSnapshot, resolveServerActionOperationLane } from "./app-browser-action-result.js";
|
|
29
|
+
import { createClientReuseManifestHeaderFromVisibleAppState } from "./app-browser-client-reuse-manifest.js";
|
|
29
30
|
import { chunksToReadableStream, createProgressiveRscStream, getVinextBrowserGlobal } from "./app-browser-stream.js";
|
|
30
31
|
import { COMMITTED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN, FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, VISITED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN, isCacheRestorableAppPayloadMetadata, isCompleteAppPayloadMetadata, resolveInterceptionContextFromPreviousNextUrl } from "./app-browser-state.js";
|
|
31
32
|
import { clearHardNavigationLoopGuard, createAppBrowserNavigationController, createBasePathStrippedPathAndSearch } from "./app-browser-navigation-controller.js";
|
|
@@ -193,6 +194,21 @@ function clearClientNavigationCaches() {
|
|
|
193
194
|
clearPrefetchState();
|
|
194
195
|
historyController.invalidateRestorableClientState();
|
|
195
196
|
}
|
|
197
|
+
function normalizeBrowserRscUrlForReuse(url) {
|
|
198
|
+
if (!url) return null;
|
|
199
|
+
try {
|
|
200
|
+
const parsed = new URL(url, window.location.origin);
|
|
201
|
+
stripRscCacheBustingSearchParam(parsed);
|
|
202
|
+
return `${parsed.pathname}${parsed.search}`;
|
|
203
|
+
} catch {
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
function isAlternatePrefetchResponseUrl(responseUrl, additionalRscUrls) {
|
|
208
|
+
const normalizedResponseUrl = normalizeBrowserRscUrlForReuse(responseUrl);
|
|
209
|
+
if (normalizedResponseUrl === null) return false;
|
|
210
|
+
return additionalRscUrls.some((additionalRscUrl) => normalizeBrowserRscUrlForReuse(additionalRscUrl) === normalizedResponseUrl);
|
|
211
|
+
}
|
|
196
212
|
function isSettledPrefetchCacheEntry(entry) {
|
|
197
213
|
return entry.outcome === "cache-seeded" && entry.pending === void 0 && entry.snapshot !== void 0;
|
|
198
214
|
}
|
|
@@ -242,6 +258,7 @@ async function learnOptimisticRouteTemplatesFromPrefetchCache(options) {
|
|
|
242
258
|
if (optimisticRouteTemplateSources.has(sourceKey)) continue;
|
|
243
259
|
if (optimisticRouteTemplateLearning.has(sourceKey)) continue;
|
|
244
260
|
if (!isSettledPrefetchCacheEntry(entry)) continue;
|
|
261
|
+
if (entry.prefetchKind === "route-tree") continue;
|
|
245
262
|
const promise = learnOptimisticRouteTemplateFromPrefetch({
|
|
246
263
|
cacheKey,
|
|
247
264
|
entry,
|
|
@@ -545,9 +562,17 @@ function BrowserRoot({ hydrationCachePublication, initialElements, initialNaviga
|
|
|
545
562
|
setWindowNextInternalSourcePage(AppElementsWire.readMetadata(treeState.elements).sourcePage);
|
|
546
563
|
}, [treeState.elements]);
|
|
547
564
|
useLayoutEffect(() => {
|
|
548
|
-
|
|
565
|
+
const previousMountedSlotsHeader = getMountedSlotsHeader();
|
|
566
|
+
const nextMountedSlotsHeader = getMountedSlotIdsHeader(stateRef.current.elements);
|
|
567
|
+
setMountedSlotsHeader(nextMountedSlotsHeader);
|
|
549
568
|
removeStylesheetLinksCoveredByInlineCss();
|
|
550
|
-
|
|
569
|
+
if (previousMountedSlotsHeader === nextMountedSlotsHeader) return;
|
|
570
|
+
const pingTimer = window.setTimeout(() => {
|
|
571
|
+
getNavigationRuntime()?.functions.pingVisibleLinks?.();
|
|
572
|
+
}, 0);
|
|
573
|
+
return () => {
|
|
574
|
+
window.clearTimeout(pingTimer);
|
|
575
|
+
};
|
|
551
576
|
}, [treeState.elements]);
|
|
552
577
|
useLayoutEffect(() => {
|
|
553
578
|
if (treeState.renderId !== 0) return;
|
|
@@ -748,14 +773,14 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
|
|
|
748
773
|
...initialRscBootstrap?.dynamicStaleTimeSeconds !== void 0 ? { dynamicStaleTimeSeconds: initialRscBootstrap.dynamicStaleTimeSeconds } : {},
|
|
749
774
|
mountedSlotsHeader,
|
|
750
775
|
paramsHeader: encodeURIComponent(JSON.stringify(initialParams)),
|
|
776
|
+
renderedPathAndSearch: null,
|
|
751
777
|
url: rscUrl
|
|
752
778
|
};
|
|
753
779
|
const fallbackTtlMs = initialRscBootstrap?.initialCacheKind === "static" ? PREFETCH_CACHE_TTL : DYNAMIC_NAVIGATION_CACHE_TTL;
|
|
754
780
|
hydrationCachePublication.publish(() => {
|
|
755
781
|
if (cacheGeneration !== clientNavigationCacheGeneration) return () => {};
|
|
756
782
|
if (isCacheRestorableAppPayloadMetadata(metadata)) return storeVisitedResponseSnapshot(rscUrl, metadata.interceptionContext, snapshot, initialParams, fallbackTtlMs, mountedSlotsHeader);
|
|
757
|
-
|
|
758
|
-
return () => deletePrefetchResponseSnapshot(rscUrl, snapshot, metadata.interceptionContext);
|
|
783
|
+
return storeVisitedResponseSnapshot(rscUrl, metadata.interceptionContext, snapshot, initialParams, fallbackTtlMs, mountedSlotsHeader, elements);
|
|
759
784
|
});
|
|
760
785
|
}).catch(() => {});
|
|
761
786
|
historyController.writeBootstrapHistoryMetadata();
|
|
@@ -867,6 +892,8 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
|
|
|
867
892
|
renderMode: navigationKind === "refresh" ? APP_RSC_RENDER_MODE_REFRESH_PRESERVE_UI : void 0
|
|
868
893
|
});
|
|
869
894
|
const rscUrl = await createRscRequestUrl(url.pathname + url.search, requestHeaders);
|
|
895
|
+
const rewrittenNavigationHref = navigationKind === "navigate" ? resolveHybridClientRewriteHref(currentHref, __basePath) : null;
|
|
896
|
+
const additionalPrefetchRscUrls = rewrittenNavigationHref && rewrittenNavigationHref !== currentHref ? [await createRscRequestUrl(rewrittenNavigationHref, requestHeaders)] : [];
|
|
870
897
|
const visitedResponseCandidate = shouldBypassNavigationCache ? {
|
|
871
898
|
cacheKey: AppElementsWire.encodeCacheKey(rscUrl, requestInterceptionContext),
|
|
872
899
|
entry: null,
|
|
@@ -883,7 +910,10 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
|
|
|
883
910
|
visitedResponse
|
|
884
911
|
});
|
|
885
912
|
let routeManifest = navigationKind === "navigate" ? getBrowserRouteManifest() : null;
|
|
886
|
-
const hasPrefetchCandidate = prefetchProbeDecision.kind === "probe" && hasPrefetchCacheEntryForNavigation(rscUrl, requestInterceptionContext, mountedSlotsHeader, {
|
|
913
|
+
const hasPrefetchCandidate = prefetchProbeDecision.kind === "probe" && hasPrefetchCacheEntryForNavigation(rscUrl, requestInterceptionContext, mountedSlotsHeader, {
|
|
914
|
+
additionalRscUrls: additionalPrefetchRscUrls,
|
|
915
|
+
notifyInvalidation: false
|
|
916
|
+
});
|
|
887
917
|
const reuseDecision = navigationPlanner.classifyNavigationReuse({
|
|
888
918
|
bypassNavigationCache: shouldBypassNavigationCache,
|
|
889
919
|
navigationKind,
|
|
@@ -941,12 +971,15 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
|
|
|
941
971
|
let navResponseUrl = null;
|
|
942
972
|
let fallbackReuseDecision = reuseDecision;
|
|
943
973
|
if (reuseDecision.kind === "consumePrefetch") {
|
|
944
|
-
const prefetchedResponse = await consumePrefetchResponseForNavigation(rscUrl, requestInterceptionContext, mountedSlotsHeader, {
|
|
974
|
+
const prefetchedResponse = await consumePrefetchResponseForNavigation(rscUrl, requestInterceptionContext, mountedSlotsHeader, {
|
|
975
|
+
additionalRscUrls: additionalPrefetchRscUrls,
|
|
976
|
+
shouldConsume: () => browserNavigationController.isCurrentNavigation(navId)
|
|
977
|
+
});
|
|
945
978
|
if (!browserNavigationController.isCurrentNavigation(navId)) return;
|
|
946
979
|
if (prefetchedResponse) {
|
|
947
980
|
navResponse = restoreRscResponse(prefetchedResponse, false);
|
|
948
981
|
navResponseExpiresAt = prefetchedResponse.expiresAt;
|
|
949
|
-
navResponseUrl = prefetchedResponse.url;
|
|
982
|
+
navResponseUrl = isAlternatePrefetchResponseUrl(prefetchedResponse.url, additionalPrefetchRscUrls) ? rscUrl : prefetchedResponse.url;
|
|
950
983
|
}
|
|
951
984
|
if (!navResponse) {
|
|
952
985
|
routeManifest = navigationKind === "navigate" ? getBrowserRouteManifest() : null;
|
|
@@ -1053,7 +1086,6 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
|
|
|
1053
1086
|
committedState = state;
|
|
1054
1087
|
if (activeNavigationAbortController === navigationAbortController) activeNavigationAbortController = null;
|
|
1055
1088
|
}, detachedNavigationCommits ? "authoritative" : void 0) !== "committed") return;
|
|
1056
|
-
if (!browserNavigationController.isCurrentNavigation(navId)) return;
|
|
1057
1089
|
try {
|
|
1058
1090
|
const renderedElements = await rscPayload;
|
|
1059
1091
|
if (navigationCacheGeneration !== clientNavigationCacheGeneration) return;
|
|
@@ -1074,7 +1106,7 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
|
|
|
1074
1106
|
if (isCacheRestorableAppPayloadMetadata(metadata)) {
|
|
1075
1107
|
if (navigationCacheGeneration !== clientNavigationCacheGeneration) return;
|
|
1076
1108
|
storeVisitedResponseSnapshot(rscUrl, interceptionContext, snapshot, navParams, PREFETCH_CACHE_TTL, mountedSlotsHeader);
|
|
1077
|
-
} else if (committedState !== null
|
|
1109
|
+
} else if (committedState !== null) {
|
|
1078
1110
|
const state = committedState;
|
|
1079
1111
|
const committedElements = {
|
|
1080
1112
|
...state.elements,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { stripBasePath } from "../utils/base-path.js";
|
|
2
2
|
import { clearAppNavigationFailureTarget, getAppNavigationFailureTarget } from "../client/app-nav-failure-handler.js";
|
|
3
3
|
import { claimAppRouterScrollIntentForCommit, consumeAppRouterScrollIntent } from "../shims/app-router-scroll-state.js";
|
|
4
|
-
import { resolveServerActionOperationLane, shouldScheduleRefreshForDiscardedServerAction } from "./app-browser-action-result.js";
|
|
5
4
|
import { activateNavigationSnapshot, clearPendingPathname, commitClientNavigationState, createSnapshotPathAndSearch } from "../shims/navigation.js";
|
|
5
|
+
import { resolveServerActionOperationLane, shouldScheduleRefreshForDiscardedServerAction } from "./app-browser-action-result.js";
|
|
6
6
|
import { FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, createPendingNavigationCommit } from "./app-browser-state.js";
|
|
7
7
|
import { applyApprovedVisibleCommit, approveHmrVisibleCommit, approvePendingNavigationCommit, resolveAndClassifyNavigationCommit } from "./app-browser-visible-commit.js";
|
|
8
8
|
import { startTransition, useInsertionEffect, useLayoutEffect } from "react";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { hasBasePath } from "../utils/base-path.js";
|
|
1
2
|
import { ACTION_REDIRECT_HEADER, ACTION_REDIRECT_STATUS_HEADER } from "./headers.js";
|
|
2
3
|
import { DANGEROUS_URL_BLOCK_MESSAGE, isDangerousScheme } from "../shims/url-safety.js";
|
|
3
4
|
import { AppElementsWire } from "./app-elements-wire.js";
|
|
@@ -9,7 +10,7 @@ import { applyServerActionResultDecision } from "./app-browser-server-action-nav
|
|
|
9
10
|
import { throwOnServerActionNotFound } from "./server-action-not-found.js";
|
|
10
11
|
import { createFromFetch, createTemporaryReferenceSet, encodeReply } from "@vitejs/plugin-rsc/browser";
|
|
11
12
|
//#region src/server/app-browser-server-action-client.ts
|
|
12
|
-
function resolveActionRedirectTarget(response, performHardNavigation) {
|
|
13
|
+
function resolveActionRedirectTarget(response, basePath, performHardNavigation) {
|
|
13
14
|
const actionRedirect = response.headers.get(ACTION_REDIRECT_HEADER);
|
|
14
15
|
if (!actionRedirect) return null;
|
|
15
16
|
if (isDangerousScheme(actionRedirect)) {
|
|
@@ -25,7 +26,7 @@ function resolveActionRedirectTarget(response, performHardNavigation) {
|
|
|
25
26
|
if (!baseDir.endsWith("/")) baseDir += "/";
|
|
26
27
|
redirectUrl = new URL(actionRedirect, `${baseParsed.origin}${baseDir}${baseParsed.search}`);
|
|
27
28
|
}
|
|
28
|
-
if (redirectUrl.origin !== window.location.origin) {
|
|
29
|
+
if (redirectUrl.origin !== window.location.origin || basePath !== "" && !hasBasePath(redirectUrl.pathname, basePath)) {
|
|
29
30
|
performHardNavigation(actionRedirect);
|
|
30
31
|
return null;
|
|
31
32
|
}
|
|
@@ -60,6 +61,7 @@ async function invokeClientServerAction(id, args, actionInitiation, deps) {
|
|
|
60
61
|
actionId: id,
|
|
61
62
|
basePath: deps.basePath,
|
|
62
63
|
elements: actionInitiation.routerState.elements,
|
|
64
|
+
interceptionContext: actionInitiation.routerState.interception !== null ? actionInitiation.routerState.interceptionContext : null,
|
|
63
65
|
previousNextUrl: actionInitiation.routerState.previousNextUrl
|
|
64
66
|
}).headers;
|
|
65
67
|
const fetchResponse = await fetch(createServerActionRequestUrl(actionInitiation.path), {
|
|
@@ -69,7 +71,7 @@ async function invokeClientServerAction(id, args, actionInitiation, deps) {
|
|
|
69
71
|
});
|
|
70
72
|
throwOnServerActionNotFound(fetchResponse, id);
|
|
71
73
|
const hasActionRedirect = fetchResponse.headers.has(ACTION_REDIRECT_HEADER);
|
|
72
|
-
const actionRedirectTarget = resolveActionRedirectTarget(fetchResponse, (url, historyMode) => deps.performHardNavigation(url, historyMode));
|
|
74
|
+
const actionRedirectTarget = resolveActionRedirectTarget(fetchResponse, deps.basePath, (url, historyMode) => deps.performHardNavigation(url, historyMode));
|
|
73
75
|
if (hasActionRedirect && !actionRedirectTarget) return void 0;
|
|
74
76
|
const actionResultFacts = createServerActionResultFacts({
|
|
75
77
|
actionRedirectHref: actionRedirectTarget?.href ?? null,
|
|
@@ -6,12 +6,12 @@ import { AppElementsWire } from "./app-elements-wire.js";
|
|
|
6
6
|
import { getMountedSlotIds, getMountedSlotIdsHeader } from "./app-elements.js";
|
|
7
7
|
import { createRscRequestHeaders } from "./app-rsc-cache-busting.js";
|
|
8
8
|
import { createCacheEntryReuseProof } from "./cache-proof.js";
|
|
9
|
-
import { createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap, createNextBfcacheIdMap, preserveBfcacheIdsForMergedElements } from "./app-bfcache-identity.js";
|
|
10
9
|
import { createHistoryStateWithNavigationMetadata, createHistoryStateWithPreviousNextUrl, isHistoryStateBfcacheVersionCurrent, readHistoryStateBfcacheIds, readHistoryStateBfcacheVersion, readHistoryStatePreviousNextUrl, readHistoryStateTraversalIndex, resolveHistoryTraversalIntent } from "./app-history-state.js";
|
|
11
10
|
import { NavigationTraceReasonCodes, createNavigationLifecycleTraceFields, createNavigationTrace } from "./navigation-trace.js";
|
|
12
11
|
import { verifyOperationTokenForCommit } from "./operation-token.js";
|
|
13
12
|
import { navigationPlanner, resolveDefaultOrUnmatchedSlotPersistenceForLayouts } from "./navigation-planner.js";
|
|
14
13
|
import { createSnapshotPathAndSearch } from "../shims/navigation.js";
|
|
14
|
+
import { createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap, createNextBfcacheIdMap, preserveBfcacheIdsForMergedElements } from "./app-bfcache-identity.js";
|
|
15
15
|
//#region src/server/app-browser-state.ts
|
|
16
16
|
const COMMITTED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN = { origin: "committed-cache" };
|
|
17
17
|
const FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN = { origin: "fresh" };
|
|
@@ -68,7 +68,7 @@ function resolveServerActionRequestState(options) {
|
|
|
68
68
|
const headers = createRscRequestHeaders();
|
|
69
69
|
headers.set(RSC_ACTION_HEADER, options.actionId);
|
|
70
70
|
headers.set(NEXT_ACTION_HEADER, options.actionId);
|
|
71
|
-
const interceptionContext = resolveInterceptionContextFromPreviousNextUrl(options.previousNextUrl, options.basePath);
|
|
71
|
+
const interceptionContext = resolveInterceptionContextFromPreviousNextUrl(options.previousNextUrl, options.basePath) ?? options.interceptionContext ?? null;
|
|
72
72
|
if (interceptionContext !== null) headers.set(VINEXT_INTERCEPTION_CONTEXT_HEADER, interceptionContext);
|
|
73
73
|
const mountedSlotsHeader = getMountedSlotIdsHeader(options.elements);
|
|
74
74
|
if (mountedSlotsHeader !== null) headers.set(VINEXT_MOUNTED_SLOTS_HEADER, mountedSlotsHeader);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { normalizeAppElementsSlotBindings } from "./app-elements-wire.js";
|
|
2
2
|
import "./app-elements.js";
|
|
3
3
|
import { mergeElements } from "../shims/slot.js";
|
|
4
|
-
import { preserveBfcacheIdsForMergedElements } from "./app-bfcache-identity.js";
|
|
5
4
|
import { NavigationTraceReasonCodes, NavigationTraceTransactionCodes, createNavigationTrace, prependNavigationTraceEntry } from "./navigation-trace.js";
|
|
5
|
+
import { preserveBfcacheIdsForMergedElements } from "./app-bfcache-identity.js";
|
|
6
6
|
import { createPendingNavigationCommit, resolvePendingNavigationCommitDispositionDecision } from "./app-browser-state.js";
|
|
7
7
|
//#region src/server/app-browser-visible-commit.ts
|
|
8
8
|
const approvedVisibleCommitBrand = Symbol("ApprovedVisibleCommit");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { runWithFetchDedupe } from "../shims/fetch-cache.js";
|
|
2
2
|
import { resolveAppPageSegmentParams } from "./app-page-params.js";
|
|
3
|
-
import { VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader } from "./app-rsc-cache-busting.js";
|
|
3
|
+
import { VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader, applyRscDeploymentIdHeader } from "./app-rsc-cache-busting.js";
|
|
4
4
|
import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
|
|
5
5
|
import { applyEdgeRuntimeHeader } from "./app-page-response.js";
|
|
6
6
|
//#region src/server/app-page-boundary.ts
|
|
@@ -109,6 +109,7 @@ async function renderAppPageBoundaryResponse(options) {
|
|
|
109
109
|
applyEdgeRuntimeHeader(headers, options.isEdgeRuntime);
|
|
110
110
|
mergeMiddlewareResponseHeaders(headers, options.middlewareHeaders ?? null);
|
|
111
111
|
applyRscCompatibilityIdHeader(headers);
|
|
112
|
+
applyRscDeploymentIdHeader(headers);
|
|
112
113
|
return new Response(rscStream, {
|
|
113
114
|
status: options.status,
|
|
114
115
|
headers
|
|
@@ -50,6 +50,7 @@ type ScheduleAppPageRscCacheWriteOptions = {
|
|
|
50
50
|
isrSet: AppPageCacheSetter;
|
|
51
51
|
interceptionContext?: string | null;
|
|
52
52
|
mountedSlotsHeader?: string | null;
|
|
53
|
+
omitPendingDynamicCacheState?: boolean;
|
|
53
54
|
renderMode?: AppRscRenderMode;
|
|
54
55
|
preserveClientResponseHeaders?: boolean;
|
|
55
56
|
expireSeconds?: number;
|
|
@@ -83,7 +83,7 @@ function finalizeAppPageRscCacheResponse(response, options) {
|
|
|
83
83
|
if (!scheduleAppPageRscCacheWrite(options)) return response;
|
|
84
84
|
if (options.preserveClientResponseHeaders === true) return response;
|
|
85
85
|
const clientHeaders = new Headers(response.headers);
|
|
86
|
-
applyPendingDynamicCdnHeaders(clientHeaders, options.getPageTags());
|
|
86
|
+
applyPendingDynamicCdnHeaders(clientHeaders, options.getPageTags(), { omitCacheState: options.omitPendingDynamicCacheState === true });
|
|
87
87
|
return new Response(response.body, {
|
|
88
88
|
status: response.status,
|
|
89
89
|
statusText: response.statusText,
|
|
@@ -92,8 +92,8 @@ function finalizeAppPageRscCacheResponse(response, options) {
|
|
|
92
92
|
}
|
|
93
93
|
function scheduleAppPageRscCacheWrite(options) {
|
|
94
94
|
const capturedRscDataPromise = options.capturedRscDataPromise;
|
|
95
|
-
if (!capturedRscDataPromise || options.dynamicUsedDuringBuild) return false;
|
|
96
|
-
const rscKey = options.isrRscKey(options.cleanPathname,
|
|
95
|
+
if (!capturedRscDataPromise || options.dynamicUsedDuringBuild || options.mountedSlotsHeader) return false;
|
|
96
|
+
const rscKey = options.isrRscKey(options.cleanPathname, null, options.renderMode, options.interceptionContext);
|
|
97
97
|
const cachePromise = (async () => {
|
|
98
98
|
try {
|
|
99
99
|
const rscData = await capturedRscDataPromise;
|
|
@@ -4,7 +4,7 @@ import { applyCdnResponseHeaders } from "./cache-control.js";
|
|
|
4
4
|
import { decideIsr } from "./isr-decision.js";
|
|
5
5
|
import { buildAppPageCacheValue } from "./isr-cache.js";
|
|
6
6
|
import { encodeCacheTag } from "../utils/encode-cache-tag.js";
|
|
7
|
-
import { VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader } from "./app-rsc-cache-busting.js";
|
|
7
|
+
import { VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader, applyRscDeploymentIdHeader } from "./app-rsc-cache-busting.js";
|
|
8
8
|
import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
|
|
9
9
|
import { applyEdgeRuntimeHeader } from "./app-page-response.js";
|
|
10
10
|
import { hasCompleteNegativeRequestApiProof } from "./cache-proof.js";
|
|
@@ -55,6 +55,15 @@ function getCachedAppPageValue(entry) {
|
|
|
55
55
|
function hasQueryInvariantAppPageProof(cachedValue) {
|
|
56
56
|
return cachedValue.renderObservation !== void 0 && hasCompleteNegativeRequestApiProof(cachedValue.renderObservation, ["searchParams"]);
|
|
57
57
|
}
|
|
58
|
+
function resolveRegeneratedAppPageCachePolicy(options) {
|
|
59
|
+
let revalidateSeconds = options.routeRevalidateSeconds;
|
|
60
|
+
const renderRevalidateSeconds = options.renderCacheControl?.revalidate;
|
|
61
|
+
if (renderRevalidateSeconds !== void 0) revalidateSeconds = revalidateSeconds > 0 ? Math.min(revalidateSeconds, renderRevalidateSeconds) : renderRevalidateSeconds;
|
|
62
|
+
return {
|
|
63
|
+
expireSeconds: options.renderCacheControl?.expire ?? options.expireSeconds,
|
|
64
|
+
revalidateSeconds
|
|
65
|
+
};
|
|
66
|
+
}
|
|
58
67
|
function buildAppPageCachedResponse(cachedValue, options) {
|
|
59
68
|
const status = options.middlewareStatus ?? (cachedValue.status || 200);
|
|
60
69
|
const { cacheControl } = decideIsr({
|
|
@@ -75,6 +84,7 @@ function buildAppPageCachedResponse(cachedValue, options) {
|
|
|
75
84
|
mountedSlotsHeader: options.mountedSlotsHeader
|
|
76
85
|
});
|
|
77
86
|
applyRscCompatibilityIdHeader(rscHeaders);
|
|
87
|
+
applyRscDeploymentIdHeader(rscHeaders);
|
|
78
88
|
return new Response(cachedValue.rscData, {
|
|
79
89
|
status,
|
|
80
90
|
headers: rscHeaders
|
|
@@ -118,7 +128,11 @@ async function serveAppPageCachedHtml(options, transformValue) {
|
|
|
118
128
|
return response;
|
|
119
129
|
}
|
|
120
130
|
async function readAppPageCacheResponse(options) {
|
|
121
|
-
|
|
131
|
+
if (options.isRscRequest && options.mountedSlotsHeader) {
|
|
132
|
+
options.isrDebug?.("MISS (mounted slots RSC variant)", options.cleanPathname);
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
const isrKey = options.isRscRequest ? options.isrRscKey(options.cleanPathname, null, options.renderMode, options.interceptionContext) : options.isrHtmlKey(options.cleanPathname);
|
|
122
136
|
const artifact = options.isRscRequest ? "rsc" : "html";
|
|
123
137
|
try {
|
|
124
138
|
const cached = await options.isrGet(isrKey);
|
|
@@ -177,10 +191,13 @@ async function readAppPageCacheResponse(options) {
|
|
|
177
191
|
if (cached?.isStale && cachedValue) {
|
|
178
192
|
options.scheduleBackgroundRegeneration(isrKey, async () => {
|
|
179
193
|
const revalidatedPage = await options.renderFreshPageForCache();
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
194
|
+
const cachePolicy = resolveRegeneratedAppPageCachePolicy({
|
|
195
|
+
expireSeconds: options.expireSeconds,
|
|
196
|
+
renderCacheControl: revalidatedPage.cacheControl,
|
|
197
|
+
routeRevalidateSeconds: options.revalidateSeconds
|
|
198
|
+
});
|
|
199
|
+
const writes = [options.isrSet(options.isRscRequest ? isrKey : options.isrRscKey(options.cleanPathname, null, options.renderMode, options.interceptionContext), buildAppPageCacheValue("", revalidatedPage.rscData, 200, revalidatedPage.rscRenderObservation), cachePolicy.revalidateSeconds, revalidatedPage.tags, cachePolicy.expireSeconds)];
|
|
200
|
+
if (!options.isRscRequest) writes.push(options.isrSet(isrKey, buildAppPageCacheValue(revalidatedPage.html, void 0, 200, revalidatedPage.htmlRenderObservation, revalidatedPage.linkHeader ? { link: revalidatedPage.linkHeader } : void 0), cachePolicy.revalidateSeconds, revalidatedPage.tags, cachePolicy.expireSeconds));
|
|
184
201
|
await Promise.all(writes);
|
|
185
202
|
options.isrDebug?.("regen complete", options.cleanPathname);
|
|
186
203
|
});
|
|
@@ -199,6 +199,7 @@ type DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {
|
|
|
199
199
|
}>;
|
|
200
200
|
request: Request;
|
|
201
201
|
revalidateSeconds: number | null;
|
|
202
|
+
renderedPathAndSearch?: string | null;
|
|
202
203
|
resolveRouteFetchCacheMode?: (route: TRoute) => FetchCacheMode | null;
|
|
203
204
|
resolveRouteDynamicConfig?: (route: TRoute) => string | null | undefined;
|
|
204
205
|
rootForbiddenModule?: AppPageModule | null;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { createRequestContext, runWithRequestContext } from "../shims/unified-request-context.js";
|
|
2
2
|
import { getRequestExecutionContext } from "../shims/request-context.js";
|
|
3
|
+
import "../utils/protocol-headers.js";
|
|
3
4
|
import { AppElementsWire } from "./app-elements-wire.js";
|
|
4
|
-
import { shouldSuppressLoadingBoundaries } from "./app-rsc-render-mode.js";
|
|
5
|
+
import { APP_RSC_RENDER_MODE_PREFETCH_DYNAMIC_SHELL, shouldSuppressLoadingBoundaries } from "./app-rsc-render-mode.js";
|
|
5
6
|
import "./app-elements.js";
|
|
6
7
|
import { consumeDynamicUsage, consumeInvalidDynamicUsageError, getAndClearPendingCookies, getDraftModeCookieHeader, getHeadersContext, isDraftModeRequest, markDynamicUsage, peekDynamicUsage, peekRenderRequestApiUsage, setHeadersContext } from "../shims/headers.js";
|
|
7
8
|
import { _consumeRequestScopedCacheLife, _peekRequestScopedCacheLife } from "../shims/cache-request-state.js";
|
|
8
|
-
import { ensureFetchPatch, getCollectedFetchTags, peekDynamicFetchObservations, runWithFetchDedupe, setCurrentFetchCacheMode, setCurrentFetchSoftTags, setCurrentForceDynamicFetchDefault } from "../shims/fetch-cache.js";
|
|
9
|
-
import { VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader } from "./app-rsc-cache-busting.js";
|
|
9
|
+
import { ensureFetchPatch, getCollectedFetchTags, peekDynamicFetchObservations, runWithFetchDedupe, setCurrentFetchCacheMode, setCurrentFetchSoftTags, setCurrentForceDynamicFetchDefault, setRefreshStaleFetchesInForeground } from "../shims/fetch-cache.js";
|
|
10
|
+
import { VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader, applyRscDeploymentIdHeader } from "./app-rsc-cache-busting.js";
|
|
10
11
|
import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
|
|
11
12
|
import "./app-page-response.js";
|
|
12
13
|
import { buildAppPageSpecialErrorResponse, probeAppPageThrownError, resolveAppPageSpecialError } from "./app-page-execution.js";
|
|
@@ -100,6 +101,10 @@ function getEffectiveLayoutClassifications(route, debugClassification) {
|
|
|
100
101
|
function shouldReadAppPageCache(options) {
|
|
101
102
|
return options.isProduction && !options.isProgressiveActionRender && !options.isDraftMode && !options.isForceDynamic && (options.isRscRequest || !options.scriptNonce) && (options.revalidateSeconds === null || options.revalidateSeconds > 0);
|
|
102
103
|
}
|
|
104
|
+
function resolveAppPageCacheReadRevalidateSeconds(options) {
|
|
105
|
+
if (options.revalidateSeconds === null && (options.isForceStatic || options.isDynamicError)) return Infinity;
|
|
106
|
+
return options.revalidateSeconds ?? 0;
|
|
107
|
+
}
|
|
103
108
|
function hasSearchParams(searchParams) {
|
|
104
109
|
return searchParams !== null && searchParams !== void 0 && searchParams.size > 0;
|
|
105
110
|
}
|
|
@@ -119,6 +124,7 @@ async function runAppPageRevalidationContext(options, renderFn) {
|
|
|
119
124
|
unstableCacheRevalidation: "foreground"
|
|
120
125
|
}), async () => {
|
|
121
126
|
ensureFetchPatch();
|
|
127
|
+
setRefreshStaleFetchesInForeground(process.env.VINEXT_PRERENDER === "1");
|
|
122
128
|
setCurrentFetchSoftTags(buildAppPageTags(options.cleanPathname, [], options.routeSegments));
|
|
123
129
|
options.setNavigationContext({
|
|
124
130
|
pathname: options.displayPathname ?? options.cleanPathname,
|
|
@@ -154,10 +160,12 @@ async function dispatchAppPageInner(options) {
|
|
|
154
160
|
const isForceStatic = dynamicConfig === "force-static";
|
|
155
161
|
const isDynamicError = dynamicConfig === "error";
|
|
156
162
|
const isForceDynamic = dynamicConfig === "force-dynamic";
|
|
163
|
+
const isPrefetchDynamicShell = options.renderMode === APP_RSC_RENDER_MODE_PREFETCH_DYNAMIC_SHELL;
|
|
157
164
|
const isDraftMode = isDraftModeRequest(options.request, options.draftModeSecret);
|
|
158
165
|
const requestHeadersContext = getHeadersContext();
|
|
159
|
-
const
|
|
160
|
-
const
|
|
166
|
+
const shouldUseEmptySearchParams = isForceStatic || isPrefetchDynamicShell;
|
|
167
|
+
const hasRequestSearchParams = !shouldUseEmptySearchParams && hasSearchParams(options.searchParams);
|
|
168
|
+
const pageSearchParams = shouldUseEmptySearchParams ? new URLSearchParams() : options.searchParams;
|
|
161
169
|
const layoutParamAccess = createAppLayoutParamAccessTracker();
|
|
162
170
|
const hasActiveLoadingBoundary = shouldSuppressLoadingBoundaries(options.renderMode ?? "navigation") ? false : Boolean(route.loading?.default);
|
|
163
171
|
setCurrentFetchSoftTags(buildAppPageTags(options.cleanPathname, [], route.routeSegments));
|
|
@@ -222,7 +230,11 @@ async function dispatchAppPageInner(options) {
|
|
|
222
230
|
mountedSlotsHeader: options.mountedSlotsHeader,
|
|
223
231
|
renderMode: options.renderMode,
|
|
224
232
|
expireSeconds: options.expireSeconds,
|
|
225
|
-
revalidateSeconds:
|
|
233
|
+
revalidateSeconds: resolveAppPageCacheReadRevalidateSeconds({
|
|
234
|
+
isDynamicError,
|
|
235
|
+
isForceStatic,
|
|
236
|
+
revalidateSeconds: currentRevalidateSeconds
|
|
237
|
+
}),
|
|
226
238
|
renderFreshPageForCache: async () => {
|
|
227
239
|
const revalidationTarget = await resolveAppPageInterceptionRerenderTarget({
|
|
228
240
|
cleanPathname: options.cleanPathname,
|
|
@@ -361,6 +373,7 @@ async function dispatchAppPageInner(options) {
|
|
|
361
373
|
});
|
|
362
374
|
mergeMiddlewareResponseHeaders(interceptHeaders, options.middlewareContext.headers);
|
|
363
375
|
applyRscCompatibilityIdHeader(interceptHeaders);
|
|
376
|
+
applyRscDeploymentIdHeader(interceptHeaders);
|
|
364
377
|
return new Response(interceptStream, {
|
|
365
378
|
status: options.middlewareContext.status ?? 200,
|
|
366
379
|
headers: interceptHeaders
|
|
@@ -428,6 +441,8 @@ async function dispatchAppPageInner(options) {
|
|
|
428
441
|
const activeFallbackShellState = options.pprRuntime?.getState() ?? null;
|
|
429
442
|
const pprFallbackShellSignal = activeFallbackShellState?.abortController.signal;
|
|
430
443
|
const pprFallbackShellReactSignal = activeFallbackShellState?.reactAbortController.signal;
|
|
444
|
+
const isPrerender = process.env.VINEXT_PRERENDER === "1";
|
|
445
|
+
const isSpeculativePrerender = isPrerender && options.request.headers.get("x-vinext-prerender-speculative") === "1";
|
|
431
446
|
return renderAppPageLifecycle({
|
|
432
447
|
basePath: options.basePath,
|
|
433
448
|
clientTraceMetadata: options.clientTraceMetadata,
|
|
@@ -459,7 +474,7 @@ async function dispatchAppPageInner(options) {
|
|
|
459
474
|
},
|
|
460
475
|
handlerStart: options.handlerStart,
|
|
461
476
|
hasLoadingBoundary: hasActiveLoadingBoundary,
|
|
462
|
-
omitPendingDynamicCacheState:
|
|
477
|
+
omitPendingDynamicCacheState: hasRequestSearchParams,
|
|
463
478
|
formState: options.formState ?? null,
|
|
464
479
|
isProgressiveActionRender: options.isProgressiveActionRender === true,
|
|
465
480
|
isDynamicError,
|
|
@@ -467,7 +482,8 @@ async function dispatchAppPageInner(options) {
|
|
|
467
482
|
isForceDynamic,
|
|
468
483
|
isForceStatic,
|
|
469
484
|
isEdgeRuntime: options.isEdgeRuntime === true,
|
|
470
|
-
isPrerender
|
|
485
|
+
isPrerender,
|
|
486
|
+
isSpeculativePrerender,
|
|
471
487
|
isProduction: options.isProduction,
|
|
472
488
|
isRscRequest: options.isRscRequest,
|
|
473
489
|
isrDebug: options.isrDebug,
|
|
@@ -483,6 +499,7 @@ async function dispatchAppPageInner(options) {
|
|
|
483
499
|
params: options.params,
|
|
484
500
|
pprFallbackShellSignal,
|
|
485
501
|
pprFallbackShellReactSignal,
|
|
502
|
+
renderedPathAndSearch: options.renderedPathAndSearch,
|
|
486
503
|
abortPprFallbackShell: activeFallbackShellState ? () => {
|
|
487
504
|
options.pprRuntime.beginFinalRender(activeFallbackShellState);
|
|
488
505
|
} : void 0,
|
|
@@ -51,6 +51,7 @@ async function buildPageElements(options) {
|
|
|
51
51
|
const hasPageModule = !!pageModule;
|
|
52
52
|
const renderIdentity = createAppPageRenderIdentity({
|
|
53
53
|
displayPathname,
|
|
54
|
+
matchedRoutePathname: routePath,
|
|
54
55
|
targetMatchedPathname: routePath,
|
|
55
56
|
interceptionContext: opts?.interceptionContext ?? null,
|
|
56
57
|
interceptSourceMatchedUrl: opts?.interceptSourceMatchedUrl ?? null,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { addBasePathToPathname } from "../utils/base-path.js";
|
|
2
2
|
import { VINEXT_RSC_REDIRECT_HEADER } from "./headers.js";
|
|
3
3
|
import { runWithConnectionProbe } from "../shims/headers.js";
|
|
4
|
-
import { VINEXT_RSC_CONTENT_TYPE, applyRscCompatibilityIdHeader, createRscRedirectLocation } from "./app-rsc-cache-busting.js";
|
|
4
|
+
import { VINEXT_RSC_CONTENT_TYPE, applyRscCompatibilityIdHeader, applyRscDeploymentIdHeader, createRscRedirectLocation } from "./app-rsc-cache-busting.js";
|
|
5
5
|
import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
|
|
6
6
|
import { applyEdgeRuntimeHeader } from "./app-page-response.js";
|
|
7
7
|
import { parseNextHttpErrorDigest, parseNextRedirectDigest } from "./next-error-digest.js";
|
|
@@ -161,6 +161,7 @@ async function buildAppPageSpecialErrorResponse(options) {
|
|
|
161
161
|
});
|
|
162
162
|
applyEdgeRuntimeHeader(headers, options.isEdgeRuntime);
|
|
163
163
|
applyRscCompatibilityIdHeader(headers);
|
|
164
|
+
applyRscDeploymentIdHeader(headers);
|
|
164
165
|
mergeMiddlewareResponseHeaders(headers, options.middlewareContext?.headers ?? null);
|
|
165
166
|
const pendingCookies = options.getAndClearPendingCookies?.() ?? [];
|
|
166
167
|
for (const cookie of pendingCookies) headers.append("Set-Cookie", cookie);
|
|
@@ -2,6 +2,7 @@ import { AppElementsInterception } from "./app-elements-wire.js";
|
|
|
2
2
|
//#region src/server/app-page-render-identity.d.ts
|
|
3
3
|
type AppPageRenderIdentityInput = {
|
|
4
4
|
displayPathname: string;
|
|
5
|
+
matchedRoutePathname?: string;
|
|
5
6
|
targetMatchedPathname?: string;
|
|
6
7
|
interceptionContext?: string | null;
|
|
7
8
|
interceptSourceMatchedUrl?: string | null;
|
|
@@ -14,9 +14,10 @@ function normalizeAppPageInterceptionProofPathname(pathname) {
|
|
|
14
14
|
function createAppPageRenderIdentity(input) {
|
|
15
15
|
const interceptionContext = input.interceptionContext ?? null;
|
|
16
16
|
const targetMatchedPathname = normalizeAppPageRenderMatchedPathname(input.targetMatchedPathname ?? input.displayPathname);
|
|
17
|
+
const requestedMatchedRoutePathname = normalizeAppPageRenderMatchedPathname(input.matchedRoutePathname ?? input.targetMatchedPathname ?? input.displayPathname);
|
|
17
18
|
const sourceMatchedPathname = normalizeAppPageInterceptionProofPathname(input.interceptSourceMatchedUrl ?? null);
|
|
18
19
|
const slotId = input.interceptSlotId ?? null;
|
|
19
|
-
const matchedRoutePathname = sourceMatchedPathname ??
|
|
20
|
+
const matchedRoutePathname = sourceMatchedPathname ?? requestedMatchedRoutePathname;
|
|
20
21
|
const routeId = AppElementsWire.encodeRouteId(matchedRoutePathname, null);
|
|
21
22
|
const pageId = AppElementsWire.encodePageId(matchedRoutePathname, null);
|
|
22
23
|
const interception = sourceMatchedPathname === null || slotId === null ? null : {
|
|
@@ -60,6 +60,7 @@ type RenderAppPageLifecycleOptions = {
|
|
|
60
60
|
isForceStatic: boolean;
|
|
61
61
|
isProgressiveActionRender?: boolean;
|
|
62
62
|
isPrerender?: boolean;
|
|
63
|
+
isSpeculativePrerender?: boolean;
|
|
63
64
|
isProduction: boolean;
|
|
64
65
|
probePageBeforeRender?: boolean;
|
|
65
66
|
omitPendingDynamicCacheState?: boolean;
|
|
@@ -103,6 +104,7 @@ type RenderAppPageLifecycleOptions = {
|
|
|
103
104
|
clientReuseManifest?: ClientReuseManifestParseResult;
|
|
104
105
|
skipDisposition?: ClientReuseManifestSkipDisposition;
|
|
105
106
|
mountedSlotsHeader?: string | null;
|
|
107
|
+
renderedPathAndSearch?: string | null;
|
|
106
108
|
renderMode?: AppRscRenderMode;
|
|
107
109
|
waitUntil?: (promise: Promise<void>) => void;
|
|
108
110
|
layoutParamAccess?: AppLayoutParamAccessTracker;
|