vinext 0.1.7 → 0.2.0
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 +51 -30
- package/dist/build/inject-pregenerated-paths.d.ts +4 -0
- package/dist/build/inject-pregenerated-paths.js +18 -0
- package/dist/build/layout-classification.js +1 -1
- package/dist/build/nitro-route-rules.js +1 -1
- package/dist/build/pages-client-assets-module.d.ts +11 -0
- package/dist/build/pages-client-assets-module.js +27 -0
- package/dist/build/prerender.d.ts +2 -1
- package/dist/build/prerender.js +13 -6
- package/dist/build/report.d.ts +13 -2
- package/dist/build/report.js +99 -2
- package/dist/build/run-prerender.d.ts +7 -0
- package/dist/build/run-prerender.js +10 -1
- package/dist/build/standalone.js +2 -0
- package/dist/cache/cache-adapters-virtual.js +3 -3
- package/dist/check.d.ts +18 -0
- package/dist/check.js +77 -19
- package/dist/cli-args.d.ts +1 -2
- package/dist/cli-args.js +1 -1
- package/dist/cli-dev-config.d.ts +12 -0
- package/dist/cli-dev-config.js +23 -0
- package/dist/cli.js +113 -97
- package/dist/{server → client}/dev-error-overlay-store.d.ts +1 -1
- package/dist/{server → client}/dev-error-overlay-store.js +1 -1
- package/dist/{server → client}/dev-error-overlay.d.ts +1 -1
- package/dist/{server → client}/dev-error-overlay.js +2 -2
- package/dist/client/navigation-runtime.d.ts +2 -0
- package/dist/client/navigation-runtime.js +3 -1
- package/dist/client/window-next.d.ts +2 -1
- package/dist/cloudflare/index.d.ts +2 -2
- package/dist/cloudflare/index.js +2 -2
- package/dist/config/config-matchers.js +14 -10
- package/dist/config/next-config.d.ts +6 -3
- package/dist/config/next-config.js +47 -1
- package/dist/config/prerender.d.ts +34 -0
- package/dist/config/prerender.js +55 -0
- package/dist/config/server-external-packages.d.ts +4 -0
- package/dist/config/server-external-packages.js +91 -0
- package/dist/entries/app-rsc-entry.d.ts +2 -1
- package/dist/entries/app-rsc-entry.js +89 -15
- package/dist/entries/app-rsc-manifest.js +10 -0
- package/dist/entries/pages-client-entry.d.ts +3 -0
- package/dist/entries/pages-client-entry.js +16 -1
- package/dist/entries/pages-server-entry.js +6 -2
- package/dist/image/image-adapters-virtual.d.ts +59 -0
- package/dist/image/image-adapters-virtual.js +59 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +211 -118
- package/dist/init-cloudflare.d.ts +43 -0
- package/dist/init-cloudflare.js +839 -0
- package/dist/init-platform.d.ts +40 -0
- package/dist/init-platform.js +195 -0
- package/dist/init.d.ts +16 -38
- package/dist/init.js +208 -97
- package/dist/node_modules/.pnpm/am-i-vibing@0.5.0/node_modules/am-i-vibing/dist/detector-1yx2Hoe0.js +294 -0
- package/dist/node_modules/.pnpm/process-ancestry@0.1.0/node_modules/process-ancestry/dist/index.js +94 -0
- package/dist/{cloudflare → packages/cloudflare}/src/cache/cdn-adapter.runtime.js +1 -1
- package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.d.ts +2 -2
- package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.js +1 -1
- package/dist/packages/cloudflare/src/deploy-config.js +150 -0
- package/dist/packages/cloudflare/src/deploy-help.js +55 -0
- package/dist/packages/cloudflare/src/deploy.js +276 -0
- package/dist/{cloudflare → packages/cloudflare/src}/tpr.d.ts +4 -41
- package/dist/{cloudflare → packages/cloudflare/src}/tpr.js +18 -15
- package/dist/plugins/ast-scope.d.ts +16 -0
- package/dist/plugins/ast-scope.js +62 -0
- package/dist/plugins/ast-utils.d.ts +27 -1
- package/dist/plugins/ast-utils.js +32 -1
- package/dist/plugins/css-module-imports.d.ts +14 -0
- package/dist/plugins/css-module-imports.js +59 -0
- package/dist/plugins/extensionless-dynamic-import.js +2 -2
- package/dist/plugins/ignore-dynamic-requests.d.ts +11 -0
- package/dist/plugins/ignore-dynamic-requests.js +530 -0
- package/dist/plugins/middleware-server-only.d.ts +8 -6
- package/dist/plugins/middleware-server-only.js +8 -7
- package/dist/plugins/optimize-imports.js +1 -1
- package/dist/plugins/typeof-window.d.ts +1 -1
- package/dist/plugins/typeof-window.js +28 -56
- package/dist/routing/app-route-graph.d.ts +29 -4
- package/dist/routing/app-route-graph.js +182 -40
- package/dist/routing/app-router.d.ts +5 -0
- package/dist/routing/app-router.js +5 -0
- package/dist/routing/file-matcher.d.ts +8 -0
- package/dist/routing/file-matcher.js +10 -1
- package/dist/routing/pages-router.js +2 -2
- package/dist/server/api-handler.js +9 -14
- package/dist/server/app-browser-action-result.d.ts +4 -1
- package/dist/server/app-browser-action-result.js +8 -1
- package/dist/server/app-browser-entry.js +194 -190
- package/dist/server/app-browser-history-controller.d.ts +2 -1
- package/dist/server/app-browser-history-controller.js +6 -2
- package/dist/server/app-browser-interception-context.d.ts +1 -0
- package/dist/server/app-browser-interception-context.js +4 -2
- package/dist/server/app-browser-navigation-controller.d.ts +2 -0
- package/dist/server/app-browser-navigation-controller.js +60 -31
- package/dist/server/app-browser-server-action-client.d.ts +32 -0
- package/dist/server/app-browser-server-action-client.js +127 -0
- package/dist/server/app-browser-state.d.ts +11 -1
- package/dist/server/app-browser-state.js +25 -8
- package/dist/server/app-browser-visible-commit.d.ts +6 -1
- package/dist/server/app-browser-visible-commit.js +43 -25
- package/dist/server/app-elements-wire.d.ts +9 -2
- package/dist/server/app-elements-wire.js +8 -1
- package/dist/server/app-elements.d.ts +2 -2
- package/dist/server/app-elements.js +4 -3
- package/dist/server/app-fallback-renderer.d.ts +5 -2
- package/dist/server/app-fallback-renderer.js +15 -7
- package/dist/server/app-hydration-cache-publication.d.ts +11 -0
- package/dist/server/app-hydration-cache-publication.js +43 -0
- package/dist/server/app-middleware.d.ts +4 -3
- package/dist/server/app-middleware.js +8 -3
- package/dist/server/app-optimistic-routing.js +11 -4
- package/dist/server/app-page-boundary-render.d.ts +3 -0
- package/dist/server/app-page-boundary-render.js +14 -3
- package/dist/server/app-page-cache-finalizer.d.ts +1 -0
- package/dist/server/app-page-cache-finalizer.js +10 -3
- package/dist/server/app-page-cache-render.d.ts +1 -0
- package/dist/server/app-page-cache-render.js +8 -4
- package/dist/server/app-page-cache.d.ts +1 -0
- package/dist/server/app-page-cache.js +5 -2
- package/dist/server/app-page-dispatch.d.ts +33 -4
- package/dist/server/app-page-dispatch.js +63 -90
- package/dist/server/app-page-element-builder.d.ts +9 -2
- package/dist/server/app-page-element-builder.js +114 -23
- package/dist/server/app-page-head.d.ts +16 -1
- package/dist/server/app-page-head.js +44 -22
- package/dist/server/app-page-params.d.ts +2 -1
- package/dist/server/app-page-params.js +8 -1
- package/dist/server/app-page-ppr-runtime.d.ts +7 -0
- package/dist/server/app-page-ppr-runtime.js +70 -0
- package/dist/server/app-page-probe.d.ts +1 -0
- package/dist/server/app-page-probe.js +6 -1
- package/dist/server/app-page-render-identity.d.ts +1 -0
- package/dist/server/app-page-render-identity.js +1 -1
- package/dist/server/app-page-render.d.ts +4 -1
- package/dist/server/app-page-render.js +26 -3
- package/dist/server/app-page-request.d.ts +22 -1
- package/dist/server/app-page-request.js +92 -15
- package/dist/server/app-page-route-wiring.d.ts +14 -2
- package/dist/server/app-page-route-wiring.js +61 -25
- package/dist/server/app-page-search-params-observation.d.ts +4 -2
- package/dist/server/app-page-search-params-observation.js +11 -7
- package/dist/server/app-page-segment-state.d.ts +2 -1
- package/dist/server/app-page-segment-state.js +3 -1
- package/dist/server/app-page-stream.d.ts +5 -0
- package/dist/server/app-page-stream.js +3 -1
- package/dist/server/app-ppr-fallback-shell-render.d.ts +4 -3
- package/dist/server/app-route-handler-dispatch.js +1 -0
- package/dist/server/app-route-handler-execution.js +7 -2
- package/dist/server/app-route-handler-response.js +1 -0
- package/dist/server/app-route-handler-runtime.js +1 -1
- package/dist/server/app-route-module-loader.d.ts +2 -0
- package/dist/server/app-route-module-loader.js +1 -0
- package/dist/server/app-router-entry.js +16 -8
- package/dist/server/app-rsc-errors.js +7 -1
- package/dist/server/app-rsc-handler.d.ts +3 -1
- package/dist/server/app-rsc-handler.js +67 -39
- package/dist/server/app-rsc-request-normalization.d.ts +3 -2
- package/dist/server/app-rsc-request-normalization.js +6 -3
- package/dist/server/app-rsc-route-matching.d.ts +7 -0
- package/dist/server/app-rsc-route-matching.js +36 -3
- package/dist/server/app-segment-config.d.ts +12 -0
- package/dist/server/app-segment-config.js +91 -5
- package/dist/server/app-server-action-execution.d.ts +5 -0
- package/dist/server/app-server-action-execution.js +94 -33
- package/dist/server/app-ssr-entry.d.ts +3 -0
- package/dist/server/app-ssr-entry.js +19 -8
- package/dist/server/app-ssr-stream.d.ts +7 -3
- package/dist/server/app-ssr-stream.js +10 -6
- package/dist/server/app-static-generation.d.ts +1 -0
- package/dist/server/app-static-generation.js +1 -0
- package/dist/server/app-visited-response-cache.d.ts +6 -0
- package/dist/server/app-visited-response-cache.js +3 -1
- package/dist/server/client-trace-metadata.js +26 -0
- package/dist/server/default-global-not-found-module.d.ts +14 -0
- package/dist/server/default-global-not-found-module.js +14 -0
- package/dist/server/dev-route-files.js +4 -0
- package/dist/server/dev-server.js +19 -18
- package/dist/server/dev-stack-sourcemap.d.ts +1 -1
- package/dist/server/dev-stack-sourcemap.js +1 -1
- package/dist/server/fetch-handler.d.ts +2 -0
- package/dist/server/fetch-handler.js +18 -0
- package/dist/server/headers.d.ts +5 -15
- package/dist/server/headers.js +4 -15
- package/dist/server/image-optimization.d.ts +51 -1
- package/dist/server/image-optimization.js +52 -2
- package/dist/server/implicit-tags.js +1 -1
- package/dist/server/isr-cache.d.ts +1 -1
- package/dist/server/isr-cache.js +2 -2
- package/dist/server/metadata-routes.d.ts +3 -1
- package/dist/server/metadata-routes.js +12 -2
- package/dist/server/middleware-runtime.js +6 -1
- package/dist/server/navigation-planner.d.ts +1 -0
- package/dist/server/navigation-planner.js +14 -3
- package/dist/server/pages-api-route.js +2 -2
- package/dist/server/pages-asset-tags.d.ts +4 -6
- package/dist/server/pages-asset-tags.js +12 -12
- package/dist/server/pages-client-assets.d.ts +12 -0
- package/dist/server/pages-client-assets.js +10 -0
- package/dist/server/pages-node-compat.d.ts +8 -1
- package/dist/server/pages-node-compat.js +32 -4
- package/dist/server/pages-page-data.d.ts +24 -1
- package/dist/server/pages-page-data.js +45 -24
- package/dist/server/pages-page-handler.d.ts +2 -1
- package/dist/server/pages-page-handler.js +19 -12
- package/dist/server/pages-page-response.d.ts +7 -0
- package/dist/server/pages-page-response.js +4 -1
- package/dist/server/pages-request-pipeline.d.ts +2 -0
- package/dist/server/pages-request-pipeline.js +25 -1
- package/dist/server/pages-router-entry.d.ts +30 -0
- package/dist/server/pages-router-entry.js +108 -0
- package/dist/server/prerender-manifest.d.ts +3 -1
- package/dist/server/prerender-route-params.js +1 -1
- package/dist/server/prod-server.d.ts +1 -1
- package/dist/server/prod-server.js +48 -26
- package/dist/server/request-pipeline.js +1 -0
- package/dist/server/seed-cache.js +4 -4
- package/dist/server/worker-utils.d.ts +2 -1
- package/dist/server/worker-utils.js +7 -1
- package/dist/shims/app-router-scroll-state.d.ts +1 -0
- package/dist/shims/app-router-scroll-state.js +1 -0
- package/dist/shims/app-router-scroll.js +2 -1
- package/dist/shims/cache.js +19 -15
- package/dist/shims/cdn-cache.js +1 -1
- package/dist/shims/dynamic-preload-chunks.js +2 -1
- package/dist/shims/error-boundary.d.ts +19 -1
- package/dist/shims/error-boundary.js +11 -1
- package/dist/shims/form.d.ts +3 -1
- package/dist/shims/form.js +37 -43
- package/dist/shims/headers.d.ts +9 -1
- package/dist/shims/headers.js +31 -6
- package/dist/shims/image.js +75 -14
- package/dist/shims/internal/app-route-detection.d.ts +2 -17
- package/dist/shims/internal/app-route-detection.js +4 -17
- package/dist/shims/internal/hybrid-client-route-owner-direct.d.ts +23 -0
- package/dist/shims/internal/hybrid-client-route-owner-direct.js +51 -0
- package/dist/shims/internal/hybrid-client-route-owner.d.ts +2 -15
- package/dist/shims/internal/hybrid-client-route-owner.js +9 -60
- package/dist/shims/internal/pages-data-fetch-dedup.d.ts +9 -5
- package/dist/shims/internal/pages-data-fetch-dedup.js +73 -14
- package/dist/shims/internal/pages-data-target.d.ts +10 -9
- package/dist/shims/internal/pages-data-target.js +91 -12
- package/dist/shims/internal/pages-router-components.d.ts +7 -0
- package/dist/shims/internal/pages-router-components.js +13 -0
- package/dist/shims/layout-segment-context.d.ts +4 -1
- package/dist/shims/layout-segment-context.js +18 -4
- package/dist/shims/link.js +70 -37
- package/dist/shims/metadata.d.ts +3 -2
- package/dist/shims/metadata.js +8 -4
- package/dist/shims/navigation.d.ts +5 -1
- package/dist/shims/navigation.js +45 -10
- package/dist/shims/navigation.react-server.js +1 -1
- package/dist/shims/root-params.d.ts +15 -1
- package/dist/shims/root-params.js +21 -1
- package/dist/shims/router.d.ts +5 -7
- package/dist/shims/router.js +374 -94
- package/dist/shims/server.js +3 -2
- package/dist/shims/slot.js +3 -6
- package/dist/typegen.js +6 -5
- package/dist/utils/client-runtime-metadata.d.ts +2 -18
- package/dist/utils/client-runtime-metadata.js +31 -22
- package/dist/utils/dev-stack-sourcemap-endpoint.d.ts +4 -0
- package/dist/{server → utils}/dev-stack-sourcemap-endpoint.js +1 -1
- package/dist/utils/domain-locale.d.ts +6 -3
- package/dist/{server → utils}/middleware-request-headers.d.ts +1 -1
- package/dist/{server → utils}/middleware-request-headers.js +2 -2
- package/dist/utils/path.d.ts +2 -1
- package/dist/utils/path.js +1 -1
- package/dist/utils/project.d.ts +52 -2
- package/dist/utils/project.js +230 -5
- package/dist/utils/protocol-headers.d.ts +17 -0
- package/dist/utils/protocol-headers.js +17 -0
- package/dist/utils/react-version.d.ts +4 -0
- package/dist/utils/react-version.js +44 -0
- package/package.json +53 -4
- package/dist/deploy.d.ts +0 -190
- package/dist/deploy.js +0 -1033
- package/dist/server/dev-stack-sourcemap-endpoint.d.ts +0 -4
- /package/dist/{cloudflare → packages/cloudflare}/src/utils/cache-control-metadata.js +0 -0
|
@@ -1,15 +1,21 @@
|
|
|
1
|
+
import { NEXTJS_CACHE_HEADER, VINEXT_CACHE_HEADER } from "./headers.js";
|
|
1
2
|
import { setCacheStateHeaders } from "./cache-headers.js";
|
|
2
3
|
import { applyCdnResponseHeaders } from "./cache-control.js";
|
|
3
4
|
import { buildAppPageCacheValue } from "./isr-cache.js";
|
|
4
5
|
import { readStreamAsText } from "../utils/text-stream.js";
|
|
5
6
|
import { createEmptyAppPageRenderObservationState } from "./app-page-render-observation.js";
|
|
6
7
|
//#region src/server/app-page-cache-finalizer.ts
|
|
7
|
-
function applyPendingDynamicCdnHeaders(headers, tags) {
|
|
8
|
+
function applyPendingDynamicCdnHeaders(headers, tags, options = {}) {
|
|
8
9
|
applyCdnResponseHeaders(headers, {
|
|
9
10
|
cacheControl: headers.get("Cache-Control") ?? "",
|
|
10
11
|
pendingDynamicCheck: true,
|
|
11
12
|
tags
|
|
12
13
|
});
|
|
14
|
+
if (options.omitCacheState === true) {
|
|
15
|
+
headers.delete(VINEXT_CACHE_HEADER);
|
|
16
|
+
headers.delete(NEXTJS_CACHE_HEADER);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
13
19
|
setCacheStateHeaders(headers, "MISS");
|
|
14
20
|
}
|
|
15
21
|
function resolveAppPageCacheWritePolicy(options) {
|
|
@@ -30,7 +36,7 @@ function finalizeAppPageHtmlCacheResponse(response, options) {
|
|
|
30
36
|
const htmlKey = options.isrHtmlKey(options.cleanPathname);
|
|
31
37
|
const rscKey = options.isrRscKey(options.cleanPathname, null, void 0, options.interceptionContext);
|
|
32
38
|
const clientHeaders = new Headers(response.headers);
|
|
33
|
-
if (options.preserveClientResponseHeaders !== true) applyPendingDynamicCdnHeaders(clientHeaders, options.getPageTags());
|
|
39
|
+
if (options.preserveClientResponseHeaders !== true) applyPendingDynamicCdnHeaders(clientHeaders, options.getPageTags(), { omitCacheState: options.omitPendingDynamicCacheState === true });
|
|
34
40
|
const cachePromise = (async () => {
|
|
35
41
|
try {
|
|
36
42
|
const cachedHtml = await readStreamAsText(streamForCache);
|
|
@@ -57,7 +63,8 @@ function finalizeAppPageHtmlCacheResponse(response, options) {
|
|
|
57
63
|
cacheTags: pageTags,
|
|
58
64
|
state: observationState
|
|
59
65
|
});
|
|
60
|
-
const
|
|
66
|
+
const linkHeader = response.headers.get("link");
|
|
67
|
+
const writes = [options.isrSet(htmlKey, buildAppPageCacheValue(cachedHtml, void 0, 200, htmlRenderObservation, linkHeader ? { link: linkHeader } : void 0), cachePolicy.revalidateSeconds, pageTags, cachePolicy.expireSeconds)];
|
|
61
68
|
if (options.capturedRscDataPromise) writes.push(options.capturedRscDataPromise.then((rscData) => options.isrSet(rscKey, buildAppPageCacheValue("", rscData, 200, rscRenderObservation), cachePolicy.revalidateSeconds, pageTags, cachePolicy.expireSeconds)));
|
|
62
69
|
await Promise.all(writes);
|
|
63
70
|
options.isrDebug?.("HTML cache written", htmlKey);
|
|
@@ -38,6 +38,7 @@ type RenderAppPageCacheArtifactsResult = {
|
|
|
38
38
|
cacheControl?: CacheControlMetadata;
|
|
39
39
|
html: string;
|
|
40
40
|
htmlRenderObservation: ReturnType<typeof createAppPageRenderObservation>;
|
|
41
|
+
linkHeader?: string;
|
|
41
42
|
rscData?: ArrayBuffer;
|
|
42
43
|
rscRenderObservation?: ReturnType<typeof createAppPageRenderObservation>;
|
|
43
44
|
tags: string[];
|
|
@@ -2,9 +2,9 @@ import { consumeDynamicUsage, consumeInvalidDynamicUsageError } from "../shims/h
|
|
|
2
2
|
import { _consumeRequestScopedCacheLife } from "../shims/cache-request-state.js";
|
|
3
3
|
import { getCollectedFetchTags } from "../shims/fetch-cache.js";
|
|
4
4
|
import { readStreamAsText } from "../utils/text-stream.js";
|
|
5
|
-
import { teeAppPageRscStreamForCapture } from "./app-page-execution.js";
|
|
5
|
+
import { buildAppPageFontLinkHeader, teeAppPageRscStreamForCapture } from "./app-page-execution.js";
|
|
6
6
|
import { consumeAppPageRenderObservationState, createAppPageHtmlOutputScope, createAppPageRenderObservation, createAppPageRscOutputScope } from "./app-page-render-observation.js";
|
|
7
|
-
import { isAppSsrRenderResult } from "./app-page-stream.js";
|
|
7
|
+
import { buildAppPageLinkHeader, isAppSsrRenderResult } from "./app-page-stream.js";
|
|
8
8
|
import { buildAppPageTags } from "./implicit-tags.js";
|
|
9
9
|
//#region src/server/app-page-cache-render.ts
|
|
10
10
|
/**
|
|
@@ -16,10 +16,11 @@ import { buildAppPageTags } from "./implicit-tags.js";
|
|
|
16
16
|
async function renderAppPageCacheArtifacts(options) {
|
|
17
17
|
const rscCapture = teeAppPageRscStreamForCapture(options.renderToReadableStream(options.element, { onError: options.onError }), options.captureRscData);
|
|
18
18
|
const capturedRscDataRef = { value: null };
|
|
19
|
+
const fontPreloads = options.getFontPreloads();
|
|
19
20
|
const htmlResult = await (await options.loadSsrHandler()).handleSsr(rscCapture.ssrStream, options.getNavigationContext(), {
|
|
20
21
|
links: options.getFontLinks(),
|
|
21
22
|
styles: options.getFontStyles(),
|
|
22
|
-
preloads:
|
|
23
|
+
preloads: fontPreloads
|
|
23
24
|
}, {
|
|
24
25
|
basePath: options.basePath,
|
|
25
26
|
clientTraceMetadata: options.clientTraceMetadata,
|
|
@@ -31,7 +32,9 @@ async function renderAppPageCacheArtifacts(options) {
|
|
|
31
32
|
capturedRscDataRef
|
|
32
33
|
} : {}
|
|
33
34
|
});
|
|
34
|
-
const
|
|
35
|
+
const htmlStream = isAppSsrRenderResult(htmlResult) ? htmlResult.htmlStream : htmlResult;
|
|
36
|
+
const linkHeader = buildAppPageLinkHeader(isAppSsrRenderResult(htmlResult) ? htmlResult.linkHeader : void 0, buildAppPageFontLinkHeader(fontPreloads), options.reactMaxHeadersLength);
|
|
37
|
+
const html = await readStreamAsText(htmlStream);
|
|
35
38
|
let rscData;
|
|
36
39
|
if (options.captureRscData) {
|
|
37
40
|
const capturedPromise = capturedRscDataRef.value;
|
|
@@ -60,6 +63,7 @@ async function renderAppPageCacheArtifacts(options) {
|
|
|
60
63
|
params: options.navigationParams,
|
|
61
64
|
state: observationState
|
|
62
65
|
}),
|
|
66
|
+
...linkHeader ? { linkHeader } : {},
|
|
63
67
|
tags,
|
|
64
68
|
cacheControl: typeof cacheLife?.revalidate === "number" ? {
|
|
65
69
|
revalidate: cacheLife.revalidate,
|
|
@@ -19,7 +19,7 @@ function recordAppPageCacheOutcome(recordCacheOutcome, input) {
|
|
|
19
19
|
function buildAppPageCacheTags(pathname, extraTags) {
|
|
20
20
|
const tags = [
|
|
21
21
|
pathname,
|
|
22
|
-
`_N_T_${pathname}`,
|
|
22
|
+
`_N_T_${pathname.length > 1 && pathname.endsWith("/") ? pathname.slice(0, -1) : pathname}`,
|
|
23
23
|
"_N_T_/layout"
|
|
24
24
|
];
|
|
25
25
|
const segments = pathname.split("/");
|
|
@@ -43,6 +43,8 @@ function buildAppPageCachedHeaders(options) {
|
|
|
43
43
|
applyCdnResponseHeaders(headers, { cacheControl: options.cacheControl });
|
|
44
44
|
setCacheStateHeaders(headers, options.cacheState);
|
|
45
45
|
applyEdgeRuntimeHeader(headers, options.isEdgeRuntime);
|
|
46
|
+
if (options.linkHeader) if (Array.isArray(options.linkHeader)) for (const value of options.linkHeader) headers.append("Link", value);
|
|
47
|
+
else headers.set("Link", options.linkHeader);
|
|
46
48
|
if (options.mountedSlotsHeader) headers.set(VINEXT_MOUNTED_SLOTS_HEADER, options.mountedSlotsHeader);
|
|
47
49
|
mergeMiddlewareResponseHeaders(headers, options.middlewareHeaders ?? null);
|
|
48
50
|
return headers;
|
|
@@ -84,6 +86,7 @@ function buildAppPageCachedResponse(cachedValue, options) {
|
|
|
84
86
|
cacheState: options.cacheState,
|
|
85
87
|
contentType: "text/html; charset=utf-8",
|
|
86
88
|
isEdgeRuntime: options.isEdgeRuntime,
|
|
89
|
+
linkHeader: cachedValue.headers?.link,
|
|
87
90
|
middlewareHeaders: options.middlewareHeaders
|
|
88
91
|
});
|
|
89
92
|
return new Response(cachedValue.html, {
|
|
@@ -177,7 +180,7 @@ async function readAppPageCacheResponse(options) {
|
|
|
177
180
|
const revalidateSeconds = revalidatedPage.cacheControl?.revalidate ?? options.revalidateSeconds;
|
|
178
181
|
const expireSeconds = revalidatedPage.cacheControl?.expire ?? options.expireSeconds;
|
|
179
182
|
const writes = [options.isrSet(options.isRscRequest ? isrKey : options.isrRscKey(options.cleanPathname, options.mountedSlotsHeader, options.renderMode, options.interceptionContext), buildAppPageCacheValue("", revalidatedPage.rscData, 200, revalidatedPage.rscRenderObservation), revalidateSeconds, revalidatedPage.tags, expireSeconds)];
|
|
180
|
-
if (!options.isRscRequest) writes.push(options.isrSet(isrKey, buildAppPageCacheValue(revalidatedPage.html, void 0, 200, revalidatedPage.htmlRenderObservation), revalidateSeconds, revalidatedPage.tags, expireSeconds));
|
|
183
|
+
if (!options.isRscRequest) writes.push(options.isrSet(isrKey, buildAppPageCacheValue(revalidatedPage.html, void 0, 200, revalidatedPage.htmlRenderObservation, revalidatedPage.linkHeader ? { link: revalidatedPage.linkHeader } : void 0), revalidateSeconds, revalidatedPage.tags, expireSeconds));
|
|
181
184
|
await Promise.all(writes);
|
|
182
185
|
options.isrDebug?.("regen complete", options.cleanPathname);
|
|
183
186
|
});
|
|
@@ -10,8 +10,10 @@ import { AppPageSsrHandler } from "./app-page-stream.js";
|
|
|
10
10
|
import { AppLayoutParamAccessTracker } from "./app-layout-param-observation.js";
|
|
11
11
|
import { AppRscRenderMode } from "./app-rsc-render-mode.js";
|
|
12
12
|
import { ISRCacheEntry } from "./isr-cache.js";
|
|
13
|
+
import { PprFallbackShellState } from "../shims/ppr-fallback-shell.js";
|
|
13
14
|
import { FetchCacheMode } from "../shims/fetch-cache.js";
|
|
14
15
|
import { AppPagePprFallbackCacheShell } from "./app-ppr-fallback-shell.js";
|
|
16
|
+
import { WarmPprFallbackShellCachesOptions } from "./app-ppr-fallback-shell-render.js";
|
|
15
17
|
import { ValidateAppPageDynamicParamsOptions } from "./app-page-request.js";
|
|
16
18
|
import { ReactNode } from "react";
|
|
17
19
|
import { ReactFormState } from "react-dom/client";
|
|
@@ -32,7 +34,10 @@ type AppPageBackgroundRegenerationErrorContext = {
|
|
|
32
34
|
type AppPageBackgroundRegenerator = (key: string, renderFn: () => Promise<void>, errorContext?: AppPageBackgroundRegenerationErrorContext) => void;
|
|
33
35
|
type AppPageDispatchIntercept<TPage = unknown> = {
|
|
34
36
|
interceptLayouts?: readonly unknown[] | null;
|
|
37
|
+
interceptLayoutSegments?: readonly (readonly string[])[] | null;
|
|
38
|
+
interceptBranchSegments?: readonly string[] | null;
|
|
35
39
|
matchedParams: AppPageParams;
|
|
40
|
+
sourceMatchedParams?: AppPageParams;
|
|
36
41
|
page: TPage;
|
|
37
42
|
slotId?: string | null;
|
|
38
43
|
slotKey: string;
|
|
@@ -42,6 +47,8 @@ type AppPageDispatchIntercept<TPage = unknown> = {
|
|
|
42
47
|
type AppPageDispatchInterceptOptions<TPage = unknown> = {
|
|
43
48
|
interceptionContext: string | null;
|
|
44
49
|
interceptLayouts?: readonly unknown[] | null;
|
|
50
|
+
interceptLayoutSegments?: readonly (readonly string[])[] | null;
|
|
51
|
+
interceptBranchSegments?: readonly string[] | null;
|
|
45
52
|
interceptPage: TPage;
|
|
46
53
|
interceptParams: AppPageParams;
|
|
47
54
|
interceptSlotId?: string | null;
|
|
@@ -80,6 +87,14 @@ type AppPageDispatchRoute = {
|
|
|
80
87
|
unauthorized?: AppPageModule | null;
|
|
81
88
|
unauthorizeds?: readonly (AppPageModule | null | undefined)[];
|
|
82
89
|
};
|
|
90
|
+
type AppPagePprRuntime<TRoute extends AppPageDispatchRoute> = {
|
|
91
|
+
beginFinalRender(state: AppPagePprState): void;
|
|
92
|
+
getState(): AppPagePprState | null;
|
|
93
|
+
run<T>(shell: NonNullable<DispatchAppPageOptions<TRoute>["pprFallbackShell"]>, fn: () => T): T;
|
|
94
|
+
tryServe(options: DispatchAppPageOptions<TRoute>, currentRevalidateSeconds: number | null, isDraftMode: boolean, isForceStatic: boolean, isForceDynamic: boolean): Promise<Response | null>;
|
|
95
|
+
warm(options: WarmPprFallbackShellCachesOptions): Promise<void>;
|
|
96
|
+
};
|
|
97
|
+
type AppPagePprState = PprFallbackShellState;
|
|
83
98
|
type DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {
|
|
84
99
|
/** Configured basePath (e.g. "/blog"). Used to prefix redirect Locations. */basePath?: string;
|
|
85
100
|
/**
|
|
@@ -94,7 +109,10 @@ type DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {
|
|
|
94
109
|
* `next.config`. Undefined falls back to the React default downstream.
|
|
95
110
|
*/
|
|
96
111
|
reactMaxHeadersLength?: number;
|
|
97
|
-
buildPageElement: (route: TRoute, params: AppPageParams, opts: AppPageDispatchInterceptOptions | undefined, searchParams: URLSearchParams, layoutParamAccess?: AppLayoutParamAccessTracker
|
|
112
|
+
buildPageElement: (route: TRoute, params: AppPageParams, opts: AppPageDispatchInterceptOptions | undefined, searchParams: URLSearchParams, layoutParamAccess?: AppLayoutParamAccessTracker, options?: {
|
|
113
|
+
observeMetadataSearchParamsAccess?: boolean;
|
|
114
|
+
observePageSearchParamsAccess?: boolean;
|
|
115
|
+
}) => Promise<AppPageElement>;
|
|
98
116
|
clientReuseManifest?: ClientReuseManifestParseResult;
|
|
99
117
|
cleanPathname: string;
|
|
100
118
|
displayPathname?: string;
|
|
@@ -147,6 +165,7 @@ type DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {
|
|
|
147
165
|
fallbackParamNames: readonly string[];
|
|
148
166
|
routePattern: string;
|
|
149
167
|
};
|
|
168
|
+
pprRuntime?: AppPagePprRuntime<TRoute>;
|
|
150
169
|
/**
|
|
151
170
|
* Set of concrete URL paths that were pre-rendered at build time for this
|
|
152
171
|
* route. When the exact cache entry for a known pregenerated path is absent
|
|
@@ -159,9 +178,9 @@ type DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {
|
|
|
159
178
|
staticParamsValidationParams?: AppPageParams;
|
|
160
179
|
rootParams?: RootParams;
|
|
161
180
|
probeLayoutAt: (layoutIndex: number, layoutParamAccess?: AppLayoutParamAccessTracker) => unknown;
|
|
162
|
-
probePage: () => unknown;
|
|
181
|
+
probePage: (searchParams?: URLSearchParams) => unknown;
|
|
163
182
|
expireSeconds?: number;
|
|
164
|
-
renderErrorBoundaryPage: (error: unknown) => Promise<Response | null>;
|
|
183
|
+
renderErrorBoundaryPage: (error: unknown, errorOrigin?: "rsc" | "ssr") => Promise<Response | null>;
|
|
165
184
|
renderHttpAccessFallbackPage: (statusCode: number, opts: {
|
|
166
185
|
boundaryComponent?: unknown;
|
|
167
186
|
boundaryModule?: AppPageModule | null;
|
|
@@ -197,6 +216,16 @@ type DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {
|
|
|
197
216
|
}) => void;
|
|
198
217
|
renderMode?: AppRscRenderMode;
|
|
199
218
|
};
|
|
219
|
+
declare function shouldReadAppPageCache(options: {
|
|
220
|
+
isProgressiveActionRender: boolean;
|
|
221
|
+
isDraftMode: boolean;
|
|
222
|
+
isForceDynamic: boolean;
|
|
223
|
+
isProduction: boolean;
|
|
224
|
+
isRscRequest: boolean;
|
|
225
|
+
revalidateSeconds: number | null;
|
|
226
|
+
scriptNonce?: string;
|
|
227
|
+
}): boolean;
|
|
228
|
+
declare function hasSearchParams(searchParams: URLSearchParams | null | undefined): boolean;
|
|
200
229
|
declare function dispatchAppPage<TRoute extends AppPageDispatchRoute>(options: DispatchAppPageOptions<TRoute>): Promise<Response>;
|
|
201
230
|
//#endregion
|
|
202
|
-
export { dispatchAppPage };
|
|
231
|
+
export { AppPageBoundaryOnError, AppPageDispatchRoute, AppPagePprRuntime, AppPagePprState, AppPageRenderableElement, DispatchAppPageOptions, dispatchAppPage, hasSearchParams, shouldReadAppPageCache };
|
|
@@ -3,8 +3,7 @@ import { getRequestExecutionContext } from "../shims/request-context.js";
|
|
|
3
3
|
import { AppElementsWire } from "./app-elements-wire.js";
|
|
4
4
|
import { shouldSuppressLoadingBoundaries } from "./app-rsc-render-mode.js";
|
|
5
5
|
import "./app-elements.js";
|
|
6
|
-
import {
|
|
7
|
-
import { consumeDynamicUsage, consumeInvalidDynamicUsageError, getAndClearPendingCookies, getDraftModeCookieHeader, isDraftModeRequest, markDynamicUsage, peekRenderRequestApiUsage, setHeadersContext } from "../shims/headers.js";
|
|
6
|
+
import { consumeDynamicUsage, consumeInvalidDynamicUsageError, getAndClearPendingCookies, getDraftModeCookieHeader, getHeadersContext, isDraftModeRequest, markDynamicUsage, peekDynamicUsage, peekRenderRequestApiUsage, setHeadersContext } from "../shims/headers.js";
|
|
8
7
|
import { _consumeRequestScopedCacheLife, _peekRequestScopedCacheLife } from "../shims/cache-request-state.js";
|
|
9
8
|
import { ensureFetchPatch, getCollectedFetchTags, peekDynamicFetchObservations, runWithFetchDedupe, setCurrentFetchCacheMode, setCurrentFetchSoftTags, setCurrentForceDynamicFetchDefault } from "../shims/fetch-cache.js";
|
|
10
9
|
import { VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader } from "./app-rsc-cache-busting.js";
|
|
@@ -108,6 +107,7 @@ async function runAppPageRevalidationContext(options, renderFn) {
|
|
|
108
107
|
const { createStaticGenerationHeadersContext } = await import("./app-static-generation.js");
|
|
109
108
|
return runWithRequestContext(createRequestContext({
|
|
110
109
|
headersContext: createStaticGenerationHeadersContext({
|
|
110
|
+
draftModeEnabled: false,
|
|
111
111
|
draftModeSecret: options.draftModeSecret,
|
|
112
112
|
dynamicConfig: options.dynamicConfig,
|
|
113
113
|
routeKind: "page",
|
|
@@ -132,6 +132,8 @@ function toInterceptOptions(interceptionContext, intercept) {
|
|
|
132
132
|
return {
|
|
133
133
|
interceptionContext,
|
|
134
134
|
interceptLayouts: intercept.interceptLayouts,
|
|
135
|
+
interceptLayoutSegments: intercept.interceptLayoutSegments,
|
|
136
|
+
interceptBranchSegments: intercept.interceptBranchSegments,
|
|
135
137
|
interceptPage: intercept.page,
|
|
136
138
|
interceptParams: intercept.matchedParams,
|
|
137
139
|
interceptSlotId: intercept.slotId ?? null,
|
|
@@ -140,75 +142,10 @@ function toInterceptOptions(interceptionContext, intercept) {
|
|
|
140
142
|
interceptSourcePageSegments: intercept.sourcePageSegments ?? null
|
|
141
143
|
};
|
|
142
144
|
}
|
|
143
|
-
/**
|
|
144
|
-
* Request-phase fallback-shell gate. Callers must run the exact cache read and
|
|
145
|
-
* static-param validation before this classification step.
|
|
146
|
-
*/
|
|
147
|
-
function classifyPprFallbackShellEligibility(options, currentRevalidateSeconds, isDraftMode, isForceStatic, isForceDynamic) {
|
|
148
|
-
if (options.renderedConcreteUrlPaths?.has(options.cleanPathname) === true) return { kind: "skip-known-pregenerated-route" };
|
|
149
|
-
const fallbackShells = options.pprFallbackCacheShells;
|
|
150
|
-
if (!fallbackShells || fallbackShells.length === 0) return { kind: "skip-no-fallback-shells" };
|
|
151
|
-
if (options.isRscRequest) return { kind: "skip-rsc-request" };
|
|
152
|
-
if (options.request.method !== "GET") return { kind: "skip-non-get" };
|
|
153
|
-
if (!isForceStatic && hasSearchParams(options.searchParams)) return { kind: "skip-search-params" };
|
|
154
|
-
if (!shouldReadAppPageCache({
|
|
155
|
-
isDraftMode,
|
|
156
|
-
isForceDynamic,
|
|
157
|
-
isProgressiveActionRender: options.isProgressiveActionRender === true,
|
|
158
|
-
isProduction: options.isProduction,
|
|
159
|
-
isRscRequest: false,
|
|
160
|
-
revalidateSeconds: currentRevalidateSeconds,
|
|
161
|
-
scriptNonce: options.scriptNonce
|
|
162
|
-
})) return { kind: "skip-cache-disabled" };
|
|
163
|
-
return {
|
|
164
|
-
kind: "probe-fallback-shells",
|
|
165
|
-
fallbackShells
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
async function probePprFallbackShellCache(options, route, fallbackShells, currentRevalidateSeconds) {
|
|
169
|
-
const { readAppPageFallbackShellCacheResponse } = await import("./app-page-cache.js");
|
|
170
|
-
const { rewriteAppPprFallbackShellHtmlNavigation } = await import("./app-ppr-fallback-shell.js");
|
|
171
|
-
for (const fallbackShell of fallbackShells) {
|
|
172
|
-
const fallbackShellResponse = await readAppPageFallbackShellCacheResponse({
|
|
173
|
-
clearRequestContext: options.clearRequestContext,
|
|
174
|
-
expireSeconds: options.expireSeconds,
|
|
175
|
-
fallbackPathname: fallbackShell.pathname,
|
|
176
|
-
isEdgeRuntime: options.isEdgeRuntime,
|
|
177
|
-
isrDebug: options.isrDebug,
|
|
178
|
-
isrGet: options.isrGet,
|
|
179
|
-
isrHtmlKey: options.isrHtmlKey,
|
|
180
|
-
middlewareHeaders: options.middlewareContext.headers,
|
|
181
|
-
middlewareStatus: options.middlewareContext.status,
|
|
182
|
-
revalidateSeconds: currentRevalidateSeconds ?? 0,
|
|
183
|
-
rewriteHtml(html) {
|
|
184
|
-
return rewriteAppPprFallbackShellHtmlNavigation({
|
|
185
|
-
html,
|
|
186
|
-
params: options.params,
|
|
187
|
-
pathname: options.cleanPathname,
|
|
188
|
-
searchParams: options.searchParams
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
});
|
|
192
|
-
if (fallbackShellResponse) return fallbackShellResponse;
|
|
193
|
-
}
|
|
194
|
-
return null;
|
|
195
|
-
}
|
|
196
|
-
async function tryServePprFallbackShell(options, route, currentRevalidateSeconds, isDraftMode, isForceStatic, isForceDynamic) {
|
|
197
|
-
const decision = classifyPprFallbackShellEligibility(options, currentRevalidateSeconds, isDraftMode, isForceStatic, isForceDynamic);
|
|
198
|
-
switch (decision.kind) {
|
|
199
|
-
case "skip-known-pregenerated-route":
|
|
200
|
-
case "skip-no-fallback-shells":
|
|
201
|
-
case "skip-rsc-request":
|
|
202
|
-
case "skip-non-get":
|
|
203
|
-
case "skip-search-params":
|
|
204
|
-
case "skip-cache-disabled": return null;
|
|
205
|
-
case "probe-fallback-shells": return await probePprFallbackShellCache(options, route, decision.fallbackShells, currentRevalidateSeconds);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
145
|
async function dispatchAppPage(options) {
|
|
209
146
|
const dispatch = () => runWithFetchDedupe(() => dispatchAppPageInner(options));
|
|
210
|
-
if (!options.pprFallbackShell) return await dispatch();
|
|
211
|
-
return await
|
|
147
|
+
if (!options.pprFallbackShell || !options.pprRuntime) return await dispatch();
|
|
148
|
+
return await options.pprRuntime.run(options.pprFallbackShell, dispatch);
|
|
212
149
|
}
|
|
213
150
|
async function dispatchAppPageInner(options) {
|
|
214
151
|
const route = options.route;
|
|
@@ -218,7 +155,11 @@ async function dispatchAppPageInner(options) {
|
|
|
218
155
|
const isDynamicError = dynamicConfig === "error";
|
|
219
156
|
const isForceDynamic = dynamicConfig === "force-dynamic";
|
|
220
157
|
const isDraftMode = isDraftModeRequest(options.request, options.draftModeSecret);
|
|
158
|
+
const requestHeadersContext = getHeadersContext();
|
|
159
|
+
const hasRequestSearchParams = !isForceStatic && hasSearchParams(options.searchParams);
|
|
160
|
+
const pageSearchParams = isForceStatic ? new URLSearchParams() : options.searchParams;
|
|
221
161
|
const layoutParamAccess = createAppLayoutParamAccessTracker();
|
|
162
|
+
const hasActiveLoadingBoundary = shouldSuppressLoadingBoundaries(options.renderMode ?? "navigation") ? false : Boolean(route.loading?.default);
|
|
222
163
|
setCurrentFetchSoftTags(buildAppPageTags(options.cleanPathname, [], route.routeSegments));
|
|
223
164
|
setCurrentFetchCacheMode(options.fetchCache ?? null);
|
|
224
165
|
setCurrentForceDynamicFetchDefault(isForceDynamic);
|
|
@@ -238,9 +179,10 @@ async function dispatchAppPageInner(options) {
|
|
|
238
179
|
options.clearRequestContext();
|
|
239
180
|
return methodResponse;
|
|
240
181
|
}
|
|
241
|
-
if (
|
|
182
|
+
if (isForceStatic || isDynamicError) {
|
|
242
183
|
const { createStaticGenerationHeadersContext } = await import("./app-static-generation.js");
|
|
243
184
|
setHeadersContext(createStaticGenerationHeadersContext({
|
|
185
|
+
draftModeEnabled: isDraftMode,
|
|
244
186
|
draftModeSecret: options.draftModeSecret,
|
|
245
187
|
dynamicConfig,
|
|
246
188
|
routeKind: "page",
|
|
@@ -266,7 +208,7 @@ async function dispatchAppPageInner(options) {
|
|
|
266
208
|
const cachedPageResponse = await readAppPageCacheResponse({
|
|
267
209
|
cleanPathname: options.cleanPathname,
|
|
268
210
|
clearRequestContext: options.clearRequestContext,
|
|
269
|
-
hasRequestSearchParams
|
|
211
|
+
hasRequestSearchParams,
|
|
270
212
|
isEdgeRuntime: options.isEdgeRuntime,
|
|
271
213
|
isRscRequest: options.isRscRequest,
|
|
272
214
|
isrDebug: options.isrDebug,
|
|
@@ -300,19 +242,23 @@ async function dispatchAppPageInner(options) {
|
|
|
300
242
|
});
|
|
301
243
|
revalidationTarget.navigationParams = resolveAppPageNavigationParams(revalidationTarget.route, revalidationTarget.navigationParams, options.cleanPathname, revalidationTarget.interceptOpts);
|
|
302
244
|
await options.ensureRouteLoaded?.(revalidationTarget.route);
|
|
245
|
+
const revalidationDynamicConfig = options.resolveRouteDynamicConfig?.(revalidationTarget.route) ?? (revalidationTarget.route === route ? dynamicConfig : void 0);
|
|
303
246
|
return runAppPageRevalidationContext({
|
|
304
247
|
cleanPathname: options.cleanPathname,
|
|
305
248
|
displayPathname: options.displayPathname,
|
|
306
249
|
currentFetchCacheMode: options.resolveRouteFetchCacheMode?.(revalidationTarget.route) ?? (revalidationTarget.route === route ? options.fetchCache ?? null : null),
|
|
307
250
|
draftModeSecret: options.draftModeSecret,
|
|
308
|
-
dynamicConfig:
|
|
251
|
+
dynamicConfig: revalidationDynamicConfig,
|
|
309
252
|
params: revalidationTarget.navigationParams,
|
|
310
253
|
routePattern: revalidationTarget.route.pattern,
|
|
311
254
|
routeSegments: revalidationTarget.route.routeSegments,
|
|
312
255
|
setNavigationContext: options.setNavigationContext
|
|
313
256
|
}, async () => {
|
|
314
257
|
const { renderAppPageCacheArtifacts } = await import("./app-page-cache-render.js");
|
|
315
|
-
const revalidatedElement = await options.buildPageElement(revalidationTarget.route, revalidationTarget.params, revalidationTarget.interceptOpts, new URLSearchParams()
|
|
258
|
+
const revalidatedElement = await options.buildPageElement(revalidationTarget.route, revalidationTarget.params, revalidationTarget.interceptOpts, new URLSearchParams(), void 0, {
|
|
259
|
+
observeMetadataSearchParamsAccess: revalidationDynamicConfig !== "force-static",
|
|
260
|
+
observePageSearchParamsAccess: revalidationDynamicConfig !== "force-static"
|
|
261
|
+
});
|
|
316
262
|
const revalidatedOnError = options.createRscOnErrorHandler(options.cleanPathname, revalidationTarget.route.pattern);
|
|
317
263
|
const rendered = await renderAppPageCacheArtifacts({
|
|
318
264
|
basePath: options.basePath,
|
|
@@ -338,6 +284,7 @@ async function dispatchAppPageInner(options) {
|
|
|
338
284
|
return {
|
|
339
285
|
html: rendered.html,
|
|
340
286
|
htmlRenderObservation: rendered.htmlRenderObservation,
|
|
287
|
+
linkHeader: rendered.linkHeader,
|
|
341
288
|
rscData: rendered.rscData,
|
|
342
289
|
rscRenderObservation: rendered.rscRenderObservation,
|
|
343
290
|
tags: rendered.tags,
|
|
@@ -365,14 +312,29 @@ async function dispatchAppPageInner(options) {
|
|
|
365
312
|
});
|
|
366
313
|
if (dynamicParamsResponse) return dynamicParamsResponse;
|
|
367
314
|
}
|
|
368
|
-
const fallbackShellResponse = await
|
|
315
|
+
const fallbackShellResponse = options.pprRuntime ? await options.pprRuntime.tryServe(options, currentRevalidateSeconds, isDraftMode, isForceStatic, isForceDynamic) : null;
|
|
369
316
|
if (fallbackShellResponse) return fallbackShellResponse;
|
|
317
|
+
let interceptDynamicConfig;
|
|
318
|
+
let interceptDynamicConfigResolved = false;
|
|
370
319
|
const interceptResult = await resolveAppPageIntercept({
|
|
371
320
|
async buildPageElement(interceptRoute, interceptParams, interceptOpts, interceptSearchParams, interceptLayoutParamAccess) {
|
|
372
|
-
|
|
321
|
+
const sourceDynamicConfig = interceptDynamicConfigResolved ? interceptDynamicConfig : options.resolveRouteDynamicConfig?.(interceptRoute);
|
|
322
|
+
if (sourceDynamicConfig === "force-static" || sourceDynamicConfig === "error") {
|
|
323
|
+
const { createStaticGenerationHeadersContext } = await import("./app-static-generation.js");
|
|
324
|
+
setHeadersContext(createStaticGenerationHeadersContext({
|
|
325
|
+
draftModeEnabled: isDraftMode,
|
|
326
|
+
draftModeSecret: options.draftModeSecret,
|
|
327
|
+
dynamicConfig: sourceDynamicConfig,
|
|
328
|
+
routeKind: "page",
|
|
329
|
+
routePattern: interceptRoute.pattern
|
|
330
|
+
}));
|
|
331
|
+
} else setHeadersContext(requestHeadersContext);
|
|
373
332
|
setCurrentFetchCacheMode(options.resolveRouteFetchCacheMode?.(interceptRoute) ?? null);
|
|
374
|
-
setCurrentForceDynamicFetchDefault(
|
|
375
|
-
return options.buildPageElement(interceptRoute, interceptParams, interceptOpts, interceptSearchParams, interceptLayoutParamAccess
|
|
333
|
+
setCurrentForceDynamicFetchDefault(sourceDynamicConfig === "force-dynamic");
|
|
334
|
+
return options.buildPageElement(interceptRoute, interceptParams, interceptOpts, interceptSearchParams, interceptLayoutParamAccess, {
|
|
335
|
+
observeMetadataSearchParamsAccess: sourceDynamicConfig !== "force-static",
|
|
336
|
+
observePageSearchParamsAccess: sourceDynamicConfig !== "force-static"
|
|
337
|
+
});
|
|
376
338
|
},
|
|
377
339
|
cleanPathname: options.cleanPathname,
|
|
378
340
|
currentRoute: route,
|
|
@@ -404,6 +366,12 @@ async function dispatchAppPageInner(options) {
|
|
|
404
366
|
headers: interceptHeaders
|
|
405
367
|
});
|
|
406
368
|
},
|
|
369
|
+
async resolveSearchParams(sourceRoute, searchParams) {
|
|
370
|
+
await options.ensureRouteLoaded?.(sourceRoute);
|
|
371
|
+
interceptDynamicConfig = options.resolveRouteDynamicConfig?.(sourceRoute);
|
|
372
|
+
interceptDynamicConfigResolved = true;
|
|
373
|
+
return interceptDynamicConfig === "force-static" ? new URLSearchParams() : searchParams;
|
|
374
|
+
},
|
|
407
375
|
searchParams: options.searchParams,
|
|
408
376
|
setNavigationContext: options.setNavigationContext,
|
|
409
377
|
toInterceptOpts(intercept) {
|
|
@@ -414,12 +382,15 @@ async function dispatchAppPageInner(options) {
|
|
|
414
382
|
const buildCurrentPageElement = () => buildAppPageElement({
|
|
415
383
|
buildPageElement() {
|
|
416
384
|
if (options.actionFailed) throw options.actionError;
|
|
417
|
-
return options.buildPageElement(route, options.params, interceptResult.interceptOpts,
|
|
385
|
+
return options.buildPageElement(route, options.params, interceptResult.interceptOpts, pageSearchParams, layoutParamAccess, {
|
|
386
|
+
observeMetadataSearchParamsAccess: !isForceStatic,
|
|
387
|
+
observePageSearchParamsAccess: !isForceStatic
|
|
388
|
+
});
|
|
418
389
|
},
|
|
419
390
|
async probePageSpecialError() {
|
|
420
391
|
if (!shouldSuppressLoadingBoundaries(options.renderMode ?? "navigation") && route.loading?.default) return null;
|
|
421
392
|
return resolveAppPageSpecialError(await probeAppPageThrownError({
|
|
422
|
-
probePage: options.probePage,
|
|
393
|
+
probePage: () => options.probePage(pageSearchParams),
|
|
423
394
|
runWithSuppressedHookWarning(probe) {
|
|
424
395
|
return options.runWithSuppressedHookWarning(probe);
|
|
425
396
|
}
|
|
@@ -433,12 +404,11 @@ async function dispatchAppPageInner(options) {
|
|
|
433
404
|
},
|
|
434
405
|
resolveSpecialError: resolveAppPageSpecialError
|
|
435
406
|
});
|
|
436
|
-
const fallbackShellState =
|
|
407
|
+
const fallbackShellState = options.pprRuntime?.getState() ?? null;
|
|
437
408
|
if (fallbackShellState && process.env.VINEXT_PRERENDER === "1" && !options.isRscRequest) {
|
|
438
409
|
const warmupBuildResult = await buildCurrentPageElement();
|
|
439
410
|
if (warmupBuildResult.response) return warmupBuildResult.response;
|
|
440
|
-
|
|
441
|
-
await warmPprFallbackShellCaches({
|
|
411
|
+
await options.pprRuntime.warm({
|
|
442
412
|
element: warmupBuildResult.element,
|
|
443
413
|
onError: options.createRscOnErrorHandler(options.cleanPathname, route.pattern),
|
|
444
414
|
renderToReadableStream: options.renderToReadableStream,
|
|
@@ -451,11 +421,11 @@ async function dispatchAppPageInner(options) {
|
|
|
451
421
|
const navigationParams = resolveAppPageNavigationParams(route, options.params, options.cleanPathname, interceptResult.interceptOpts);
|
|
452
422
|
options.setNavigationContext({
|
|
453
423
|
pathname: options.displayPathname ?? options.cleanPathname,
|
|
454
|
-
searchParams:
|
|
424
|
+
searchParams: pageSearchParams,
|
|
455
425
|
params: navigationParams
|
|
456
426
|
});
|
|
457
427
|
const layoutClassifications = getEffectiveLayoutClassifications(route, options.debugClassification);
|
|
458
|
-
const activeFallbackShellState =
|
|
428
|
+
const activeFallbackShellState = options.pprRuntime?.getState() ?? null;
|
|
459
429
|
const pprFallbackShellSignal = activeFallbackShellState?.abortController.signal;
|
|
460
430
|
const pprFallbackShellReactSignal = activeFallbackShellState?.reactAbortController.signal;
|
|
461
431
|
return renderAppPageLifecycle({
|
|
@@ -465,6 +435,7 @@ async function dispatchAppPageInner(options) {
|
|
|
465
435
|
cleanPathname: options.cleanPathname,
|
|
466
436
|
clearRequestContext: options.clearRequestContext,
|
|
467
437
|
consumeDynamicUsage,
|
|
438
|
+
peekDynamicUsage,
|
|
468
439
|
consumeInvalidDynamicUsageError,
|
|
469
440
|
consumeRenderObservationState: consumeAppPageRenderObservationState,
|
|
470
441
|
createRscOnErrorHandler(pathname, routePath) {
|
|
@@ -487,7 +458,8 @@ async function dispatchAppPageInner(options) {
|
|
|
487
458
|
return _peekRequestScopedCacheLife();
|
|
488
459
|
},
|
|
489
460
|
handlerStart: options.handlerStart,
|
|
490
|
-
hasLoadingBoundary:
|
|
461
|
+
hasLoadingBoundary: hasActiveLoadingBoundary,
|
|
462
|
+
omitPendingDynamicCacheState: !options.isRscRequest && hasRequestSearchParams,
|
|
491
463
|
formState: options.formState ?? null,
|
|
492
464
|
isProgressiveActionRender: options.isProgressiveActionRender === true,
|
|
493
465
|
isDynamicError,
|
|
@@ -512,7 +484,7 @@ async function dispatchAppPageInner(options) {
|
|
|
512
484
|
pprFallbackShellSignal,
|
|
513
485
|
pprFallbackShellReactSignal,
|
|
514
486
|
abortPprFallbackShell: activeFallbackShellState ? () => {
|
|
515
|
-
|
|
487
|
+
options.pprRuntime.beginFinalRender(activeFallbackShellState);
|
|
516
488
|
} : void 0,
|
|
517
489
|
layoutParamAccess,
|
|
518
490
|
rootParams: options.rootParams,
|
|
@@ -526,8 +498,9 @@ async function dispatchAppPageInner(options) {
|
|
|
526
498
|
return options.probeLayoutAt(layoutIndex, layoutParamAccess);
|
|
527
499
|
},
|
|
528
500
|
probePage() {
|
|
529
|
-
return options.probePage();
|
|
501
|
+
return options.probePage(pageSearchParams);
|
|
530
502
|
},
|
|
503
|
+
probePageBeforeRender: options.isRscRequest,
|
|
531
504
|
classification: {
|
|
532
505
|
getLayoutId(index) {
|
|
533
506
|
const treePosition = route.layoutTreePositions?.[index] ?? 0;
|
|
@@ -556,8 +529,8 @@ async function dispatchAppPageInner(options) {
|
|
|
556
529
|
revalidateSeconds: currentRevalidateSeconds,
|
|
557
530
|
mountedSlotsHeader: options.mountedSlotsHeader,
|
|
558
531
|
renderMode: options.renderMode ?? "navigation",
|
|
559
|
-
renderErrorBoundaryResponse(renderError) {
|
|
560
|
-
return options.renderErrorBoundaryPage(renderError);
|
|
532
|
+
renderErrorBoundaryResponse(renderError, errorOrigin) {
|
|
533
|
+
return options.renderErrorBoundaryPage(renderError, errorOrigin);
|
|
561
534
|
},
|
|
562
535
|
renderLayoutSpecialError(specialError, layoutIndex) {
|
|
563
536
|
return renderLayoutSpecialError(options, specialError, layoutIndex);
|
|
@@ -674,4 +647,4 @@ async function renderPageSpecialError(options, specialError) {
|
|
|
674
647
|
});
|
|
675
648
|
}
|
|
676
649
|
//#endregion
|
|
677
|
-
export { dispatchAppPage };
|
|
650
|
+
export { dispatchAppPage, hasSearchParams, shouldReadAppPageCache };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { MetadataFileRoute } from "./metadata-routes.js";
|
|
2
2
|
import { AppElements } from "./app-elements-wire.js";
|
|
3
3
|
import { AppPageParams } from "./app-page-boundary.js";
|
|
4
|
+
import { ApplyAppPageFileBasedMetadata } from "./app-page-head.js";
|
|
4
5
|
import { AppLayoutParamAccessTracker } from "./app-layout-param-observation.js";
|
|
5
6
|
import { AppRscRenderMode } from "./app-rsc-render-mode.js";
|
|
6
7
|
import { AppPageErrorModule, AppPageModule, AppPageRouteWiringRoute } from "./app-page-route-wiring.js";
|
|
@@ -19,6 +20,8 @@ type AppPageBuildRoute<TModule extends AppPageModule = AppPageModule, TErrorModu
|
|
|
19
20
|
type AppPageInterceptOptions<TModule extends AppPageModule = AppPageModule> = {
|
|
20
21
|
interceptionContext?: string | null;
|
|
21
22
|
interceptLayouts?: readonly (TModule | null | undefined)[] | null;
|
|
23
|
+
interceptLayoutSegments?: readonly (readonly string[])[] | null;
|
|
24
|
+
interceptBranchSegments?: readonly string[] | null;
|
|
22
25
|
interceptPage?: TModule | null;
|
|
23
26
|
interceptParams?: AppPageParams | null;
|
|
24
27
|
interceptSlotId?: string | null;
|
|
@@ -32,9 +35,12 @@ type AppPagePageRequest<TModule extends AppPageModule = AppPageModule> = {
|
|
|
32
35
|
isRscRequest: boolean; /** The incoming HTTP request (available but unused by this module). */
|
|
33
36
|
request: Request; /** Normalized x-vinext-mounted-slots header value. */
|
|
34
37
|
mountedSlotsHeader: string | null; /** Semantic RSC payload mode for this page render. */
|
|
35
|
-
renderMode?: AppRscRenderMode;
|
|
38
|
+
renderMode?: AppRscRenderMode; /** Observe page `searchParams` access for cache-safety classification. */
|
|
39
|
+
observePageSearchParamsAccess?: boolean; /** Observe page metadata `searchParams` access for cache-safety classification. */
|
|
40
|
+
observeMetadataSearchParamsAccess?: boolean;
|
|
36
41
|
};
|
|
37
42
|
type BuildPageElementsOptions<TModule extends AppPageModule = AppPageModule, TErrorModule extends AppPageErrorModule = AppPageErrorModule> = {
|
|
43
|
+
applyFileBasedMetadata?: ApplyAppPageFileBasedMetadata;
|
|
38
44
|
route: AppPageBuildRoute<TModule, TErrorModule>;
|
|
39
45
|
params: AppPageParams;
|
|
40
46
|
routePath: string;
|
|
@@ -89,6 +95,7 @@ type AppPageNavigationParamInterceptOptions = {
|
|
|
89
95
|
* {@link https://github.com/vercel/next.js/blob/canary/packages/next/src/server/app-render/create-metadata.tsx|create-metadata.tsx}.
|
|
90
96
|
*/
|
|
91
97
|
declare function buildPageElements<TModule extends AppPageModule = AppPageModule, TErrorModule extends AppPageErrorModule = AppPageErrorModule>(options: BuildPageElementsOptions<TModule, TErrorModule>): Promise<AppElements>;
|
|
98
|
+
declare function resolveInterceptedSlotSegments(sourcePageSegments: readonly string[] | null | undefined, slotKey: string): readonly string[] | null;
|
|
92
99
|
declare function resolveAppPageNavigationParams(route: AppPageNavigationParamRoute, routeParams: AppPageParams, routePath: string, opts?: AppPageNavigationParamInterceptOptions | null): AppPageParams;
|
|
93
100
|
//#endregion
|
|
94
|
-
export { AppPageBuildRoute, type AppPageErrorModule, AppPageInterceptOptions, AppPagePageRequest, type AppPageRouteWiringRoute, BuildPageElementsOptions, buildPageElements, resolveAppPageNavigationParams };
|
|
101
|
+
export { AppPageBuildRoute, type AppPageErrorModule, AppPageInterceptOptions, AppPagePageRequest, type AppPageRouteWiringRoute, BuildPageElementsOptions, buildPageElements, resolveAppPageNavigationParams, resolveInterceptedSlotSegments };
|