vinext 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/build/css-url-assets.d.ts +1 -1
- package/dist/build/css-url-assets.js +9 -7
- package/dist/build/google-fonts/find-font-files-in-css.d.ts +16 -0
- package/dist/build/google-fonts/find-font-files-in-css.js +28 -0
- package/dist/build/prerender.js +2 -1
- package/dist/build/report.d.ts +1 -2
- package/dist/build/report.js +2 -11
- package/dist/build/run-prerender.js +1 -1
- package/dist/cache/cache-adapters-virtual.js +1 -1
- package/dist/check.js +3 -3
- package/dist/client/pages-router-link-navigation.d.ts +10 -0
- package/dist/client/pages-router-link-navigation.js +3 -3
- package/dist/cloudflare/src/cache/kv-data-adapter.runtime.d.ts +1 -1
- package/dist/deploy.js +3 -3
- package/dist/entries/app-rsc-entry.js +25 -20
- package/dist/entries/app-rsc-manifest.js +76 -46
- package/dist/entries/pages-server-entry.js +3 -1
- package/dist/index.js +254 -198
- package/dist/init.d.ts +5 -4
- package/dist/init.js +27 -8
- package/dist/plugins/css-data-url.js +30 -26
- package/dist/plugins/extensionless-dynamic-import.js +27 -24
- package/dist/plugins/fonts.js +3 -1
- package/dist/plugins/import-meta-url.js +21 -15
- package/dist/plugins/instrumentation-client.js +1 -1
- package/dist/plugins/middleware-export-validation.d.ts +5 -0
- package/dist/plugins/middleware-export-validation.js +36 -0
- package/dist/plugins/middleware-server-only.js +7 -6
- package/dist/plugins/og-asset-ownership.d.ts +27 -0
- package/dist/plugins/og-asset-ownership.js +285 -0
- package/dist/plugins/og-assets.js +66 -46
- package/dist/plugins/optimize-imports.js +9 -3
- package/dist/plugins/remove-console.d.ts +7 -1
- package/dist/plugins/remove-console.js +4 -1
- package/dist/plugins/require-context.js +21 -20
- package/dist/plugins/strip-server-exports.d.ts +7 -1
- package/dist/plugins/strip-server-exports.js +4 -1
- package/dist/server/accept-encoding.d.ts +29 -0
- package/dist/server/accept-encoding.js +95 -0
- package/dist/server/app-bfcache-identity.d.ts +26 -0
- package/dist/server/app-bfcache-identity.js +127 -0
- package/dist/server/app-browser-entry.js +17 -11
- package/dist/server/app-browser-rsc-redirect.d.ts +2 -1
- package/dist/server/app-browser-rsc-redirect.js +8 -1
- package/dist/server/app-browser-state.d.ts +2 -21
- package/dist/server/app-browser-state.js +4 -128
- package/dist/server/app-browser-stream.js +1 -1
- package/dist/server/app-browser-visible-commit.js +3 -2
- package/dist/server/app-fallback-renderer.d.ts +1 -1
- package/dist/server/app-layout-param-observation.d.ts +1 -1
- package/dist/server/app-layout-param-observation.js +1 -1
- package/dist/server/app-middleware.d.ts +1 -0
- package/dist/server/app-middleware.js +3 -1
- package/dist/server/app-page-boundary-render.d.ts +1 -1
- package/dist/server/app-page-boundary.js +1 -1
- package/dist/server/app-page-cache-finalizer.d.ts +62 -0
- package/dist/server/app-page-cache-finalizer.js +122 -0
- package/dist/server/app-page-cache-render.d.ts +2 -2
- package/dist/server/app-page-cache-render.js +1 -1
- package/dist/server/app-page-cache.d.ts +2 -53
- package/dist/server/app-page-cache.js +5 -131
- package/dist/server/app-page-dispatch.d.ts +4 -4
- package/dist/server/app-page-dispatch.js +10 -8
- package/dist/server/app-page-head.js +2 -2
- package/dist/server/app-page-probe.js +3 -2
- package/dist/server/app-page-render-observation.js +2 -2
- package/dist/server/app-page-render.d.ts +3 -3
- package/dist/server/app-page-render.js +3 -2
- package/dist/server/app-page-request.d.ts +7 -0
- package/dist/server/app-page-request.js +19 -1
- package/dist/server/app-page-stream.d.ts +2 -9
- package/dist/server/app-page-stream.js +1 -35
- package/dist/server/app-prerender-endpoints.d.ts +3 -3
- package/dist/server/app-prerender-endpoints.js +3 -4
- package/dist/server/app-request-context.d.ts +1 -2
- package/dist/server/app-request-context.js +2 -1
- package/dist/server/app-route-handler-dispatch.js +3 -2
- package/dist/server/app-route-handler-execution.d.ts +1 -1
- package/dist/server/app-route-handler-execution.js +1 -1
- package/dist/server/app-route-handler-response.d.ts +1 -1
- package/dist/server/app-route-module-loader.d.ts +62 -14
- package/dist/server/app-route-module-loader.js +61 -10
- package/dist/server/app-router-entry.js +2 -1
- package/dist/server/app-rsc-handler.d.ts +7 -6
- package/dist/server/app-rsc-handler.js +51 -40
- package/dist/server/app-rsc-response-finalizer.js +1 -1
- package/dist/server/app-rsc-route-matching.d.ts +9 -0
- package/dist/server/app-rsc-route-matching.js +13 -0
- package/dist/server/app-server-action-execution.d.ts +1 -1
- package/dist/server/app-server-action-execution.js +5 -4
- package/dist/server/app-ssr-entry.d.ts +1 -1
- package/dist/server/app-ssr-entry.js +9 -7
- package/dist/server/app-ssr-router-instance.d.ts +6 -0
- package/dist/server/app-ssr-router-instance.js +24 -0
- package/dist/server/app-ssr-stream.js +1 -1
- package/dist/server/artifact-compatibility.js +1 -1
- package/dist/server/client-reuse-manifest.js +1 -1
- package/dist/server/defer-until-stream-consumed.d.ts +7 -0
- package/dist/server/defer-until-stream-consumed.js +34 -0
- package/dist/server/dev-server.js +1 -1
- package/dist/server/headers.d.ts +5 -1
- package/dist/server/headers.js +5 -1
- package/dist/server/instrumentation.js +1 -1
- package/dist/server/isr-cache.d.ts +1 -1
- package/dist/server/isr-cache.js +1 -1
- package/dist/server/isr-decision.d.ts +1 -1
- package/dist/server/metadata-route-response.d.ts +3 -3
- package/dist/server/middleware-matcher.js +8 -6
- package/dist/server/middleware-runtime.d.ts +2 -1
- package/dist/server/middleware-runtime.js +21 -10
- package/dist/server/middleware.d.ts +2 -2
- package/dist/server/middleware.js +26 -11
- package/dist/server/open-redirect.d.ts +12 -0
- package/dist/server/open-redirect.js +21 -0
- package/dist/server/pages-page-data.d.ts +1 -1
- package/dist/server/pages-page-response.d.ts +1 -1
- package/dist/server/pages-page-response.js +2 -2
- package/dist/server/pages-request-pipeline.d.ts +3 -1
- package/dist/server/pages-request-pipeline.js +4 -2
- package/dist/server/prod-server.d.ts +1 -1
- package/dist/server/prod-server.js +87 -73
- package/dist/server/request-pipeline.d.ts +1 -24
- package/dist/server/request-pipeline.js +1 -33
- package/dist/server/seed-cache.d.ts +1 -1
- package/dist/shims/cache-handler.d.ts +106 -0
- package/dist/shims/cache-handler.js +176 -0
- package/dist/shims/cache-request-state.d.ts +47 -0
- package/dist/shims/cache-request-state.js +126 -0
- package/dist/shims/cache-runtime.d.ts +2 -2
- package/dist/shims/cache-runtime.js +3 -14
- package/dist/shims/cache.d.ts +3 -231
- package/dist/shims/cache.js +17 -383
- package/dist/shims/cdn-cache.d.ts +1 -1
- package/dist/shims/cdn-cache.js +1 -1
- package/dist/shims/error-boundary-navigation.d.ts +7 -0
- package/dist/shims/error-boundary-navigation.js +44 -0
- package/dist/shims/error-boundary.js +10 -8
- package/dist/shims/error.js +2 -1
- package/dist/shims/fetch-cache.js +1 -1
- package/dist/shims/font-google-base.d.ts +1 -0
- package/dist/shims/font-google-base.js +6 -21
- package/dist/shims/form.js +1 -1
- package/dist/shims/image.js +67 -9
- package/dist/shims/internal/app-page-props-cache-key.d.ts +5 -0
- package/dist/shims/internal/app-page-props-cache-key.js +16 -0
- package/dist/shims/internal/interpolate-as.d.ts +25 -0
- package/dist/shims/internal/interpolate-as.js +196 -0
- package/dist/shims/internal/navigation-untracked.js +2 -1
- package/dist/shims/layout-segment-context.d.ts +1 -1
- package/dist/shims/layout-segment-context.js +2 -1
- package/dist/shims/link.js +26 -3
- package/dist/shims/navigation-context-state.d.ts +40 -0
- package/dist/shims/navigation-context-state.js +116 -0
- package/dist/shims/navigation-errors.d.ts +55 -0
- package/dist/shims/navigation-errors.js +110 -0
- package/dist/shims/navigation-server.d.ts +3 -0
- package/dist/shims/navigation-server.js +3 -0
- package/dist/shims/navigation-state.d.ts +1 -2
- package/dist/shims/navigation-state.js +2 -1
- package/dist/shims/navigation.d.ts +3 -291
- package/dist/shims/navigation.js +13 -444
- package/dist/shims/navigation.react-server.d.ts +2 -2
- package/dist/shims/navigation.react-server.js +4 -2
- package/dist/shims/request-state-types.d.ts +3 -3
- package/dist/shims/router.d.ts +1 -3
- package/dist/shims/router.js +62 -18
- package/dist/shims/script.js +1 -1
- package/dist/shims/slot.js +3 -1
- package/dist/shims/unified-request-context.d.ts +2 -2
- package/dist/typegen.js +2 -10
- package/dist/utils/project.d.ts +7 -1
- package/dist/utils/project.js +16 -2
- package/dist/utils/virtual-module.d.ts +5 -0
- package/dist/utils/virtual-module.js +0 -0
- package/package.json +7 -3
|
@@ -39,9 +39,16 @@ type BuildAppPageElementResult<TElement> = {
|
|
|
39
39
|
response: Response | null;
|
|
40
40
|
};
|
|
41
41
|
type AppPageInterceptMatch<TPage = unknown> = {
|
|
42
|
+
interceptLayouts?: readonly unknown[] | null;
|
|
43
|
+
__loadInterceptLayouts?: readonly (() => Promise<unknown>)[] | null;
|
|
42
44
|
matchedParams: AppPageParams;
|
|
43
45
|
page: TPage;
|
|
44
46
|
__pageLoader?: (() => Promise<TPage>) | null;
|
|
47
|
+
__loadState?: {
|
|
48
|
+
page: TPage;
|
|
49
|
+
pageLoading: Promise<TPage> | null;
|
|
50
|
+
interceptLayoutsLoading: Promise<readonly unknown[]> | null;
|
|
51
|
+
};
|
|
45
52
|
slotId?: string | null;
|
|
46
53
|
slotKey: string;
|
|
47
54
|
sourceRouteIndex: number;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { notFoundResponse } from "./http-error-responses.js";
|
|
2
2
|
import { runWithFetchDedupe } from "../shims/fetch-cache.js";
|
|
3
3
|
import { getAppPageSegmentParamName } from "./app-page-params.js";
|
|
4
|
+
import { loadAppInterceptLayouts } from "./app-route-module-loader.js";
|
|
4
5
|
//#region src/server/app-page-request.ts
|
|
5
6
|
function pickRouteParams(matchedParams, routeParamNames) {
|
|
6
7
|
const params = {};
|
|
@@ -104,7 +105,24 @@ async function resolveAppPageInterceptState(options) {
|
|
|
104
105
|
if (!options.isRscRequest) return { kind: "none" };
|
|
105
106
|
const intercept = options.findIntercept(options.cleanPathname);
|
|
106
107
|
if (!intercept) return { kind: "none" };
|
|
107
|
-
|
|
108
|
+
const loadState = intercept.__loadState;
|
|
109
|
+
if (loadState?.page != null) intercept.page = loadState.page;
|
|
110
|
+
if (intercept.__pageLoader && intercept.page == null) {
|
|
111
|
+
const loading = loadState?.pageLoading ?? intercept.__pageLoader().then((page) => {
|
|
112
|
+
intercept.page = page;
|
|
113
|
+
if (loadState) {
|
|
114
|
+
loadState.page = page;
|
|
115
|
+
loadState.pageLoading = null;
|
|
116
|
+
}
|
|
117
|
+
return page;
|
|
118
|
+
}).catch((error) => {
|
|
119
|
+
if (loadState) loadState.pageLoading = null;
|
|
120
|
+
throw error;
|
|
121
|
+
});
|
|
122
|
+
if (loadState) loadState.pageLoading = loading;
|
|
123
|
+
await loading;
|
|
124
|
+
}
|
|
125
|
+
if (intercept.__loadInterceptLayouts) await loadAppInterceptLayouts(intercept);
|
|
108
126
|
const sourceRoute = await options.getSourceRoute(intercept.sourceRouteIndex);
|
|
109
127
|
if (!sourceRoute) return { kind: "none" };
|
|
110
128
|
if (sourceRoute === options.currentRoute) return {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { NavigationContext } from "../shims/navigation.js";
|
|
1
|
+
import { NavigationContext } from "../shims/navigation-context-state.js";
|
|
2
2
|
import { AppPageFontPreload } from "./app-page-execution.js";
|
|
3
3
|
import { RootParams } from "../shims/root-params.js";
|
|
4
|
+
import { deferUntilStreamConsumed } from "./defer-until-stream-consumed.js";
|
|
4
5
|
import { ReactFormState } from "react-dom/client";
|
|
5
6
|
|
|
6
7
|
//#region src/server/app-page-stream.d.ts
|
|
@@ -143,14 +144,6 @@ type AppPageRscErrorTracker = {
|
|
|
143
144
|
};
|
|
144
145
|
declare function createAppPageFontData(options: CreateAppPageFontDataOptions): AppPageFontData;
|
|
145
146
|
declare function renderAppPageHtmlStream(options: RenderAppPageHtmlStreamOptions): Promise<AppSsrRenderResult>;
|
|
146
|
-
/**
|
|
147
|
-
* Wraps a stream so that `onFlush` is called when the last byte has been read
|
|
148
|
-
* by the downstream consumer (i.e. when the HTTP layer finishes draining the
|
|
149
|
-
* response body). This is the correct place to clear per-request context,
|
|
150
|
-
* because the RSC/SSR pipeline is lazy — components execute while the stream
|
|
151
|
-
* is being consumed, not when the stream handle is first obtained.
|
|
152
|
-
*/
|
|
153
|
-
declare function deferUntilStreamConsumed(stream: ReadableStream<Uint8Array>, onFlush: () => void): ReadableStream<Uint8Array>;
|
|
154
147
|
declare function renderAppPageHtmlResponse(options: RenderAppPageHtmlResponseOptions): Promise<Response>;
|
|
155
148
|
declare function renderAppPageHtmlStreamWithRecovery<TSpecialError>(options: RenderAppPageHtmlStreamWithRecoveryOptions<TSpecialError>): Promise<AppPageHtmlStreamRecoveryResult>;
|
|
156
149
|
declare function createAppPageRscErrorTracker(baseOnError: (error: unknown, requestInfo: unknown, errorContext: unknown) => unknown): AppPageRscErrorTracker;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { VINEXT_RSC_VARY_HEADER } from "./app-rsc-cache-busting.js";
|
|
2
2
|
import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
|
|
3
3
|
import { applyEdgeRuntimeHeader } from "./app-page-response.js";
|
|
4
|
+
import { deferUntilStreamConsumed } from "./defer-until-stream-consumed.js";
|
|
4
5
|
//#region src/server/app-page-stream.ts
|
|
5
6
|
function isAppSsrRenderResult(value) {
|
|
6
7
|
return typeof value === "object" && value !== null && "htmlStream" in value && "metadataReady" in value;
|
|
@@ -70,41 +71,6 @@ async function renderAppPageHtmlStream(options) {
|
|
|
70
71
|
};
|
|
71
72
|
return normalizeAppSsrRenderResult(await options.ssrHandler.handleSsr(options.rscStream, options.navigationContext, options.fontData, ssrOptions), options.capturedRscDataRef?.value ?? null);
|
|
72
73
|
}
|
|
73
|
-
/**
|
|
74
|
-
* Wraps a stream so that `onFlush` is called when the last byte has been read
|
|
75
|
-
* by the downstream consumer (i.e. when the HTTP layer finishes draining the
|
|
76
|
-
* response body). This is the correct place to clear per-request context,
|
|
77
|
-
* because the RSC/SSR pipeline is lazy — components execute while the stream
|
|
78
|
-
* is being consumed, not when the stream handle is first obtained.
|
|
79
|
-
*/
|
|
80
|
-
function deferUntilStreamConsumed(stream, onFlush) {
|
|
81
|
-
let called = false;
|
|
82
|
-
const once = () => {
|
|
83
|
-
if (!called) {
|
|
84
|
-
called = true;
|
|
85
|
-
onFlush();
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
const cleanup = new TransformStream({ flush() {
|
|
89
|
-
once();
|
|
90
|
-
} });
|
|
91
|
-
const reader = stream.pipeThrough(cleanup).getReader();
|
|
92
|
-
return new ReadableStream({
|
|
93
|
-
pull(controller) {
|
|
94
|
-
return reader.read().then(({ done, value }) => {
|
|
95
|
-
if (done) controller.close();
|
|
96
|
-
else controller.enqueue(value);
|
|
97
|
-
}, (error) => {
|
|
98
|
-
once();
|
|
99
|
-
controller.error(error);
|
|
100
|
-
});
|
|
101
|
-
},
|
|
102
|
-
cancel(reason) {
|
|
103
|
-
once();
|
|
104
|
-
return reader.cancel(reason);
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
74
|
async function renderAppPageHtmlResponse(options) {
|
|
109
75
|
const { htmlStream } = await renderAppPageHtmlStream(options);
|
|
110
76
|
const safeStream = deferUntilStreamConsumed(htmlStream, () => {
|
|
@@ -5,14 +5,14 @@ type GenerateStaticParams = (args: {
|
|
|
5
5
|
params: RootParams;
|
|
6
6
|
}) => unknown;
|
|
7
7
|
type AppPrerenderStaticParamsMap = Record<string, GenerateStaticParams | null | undefined>;
|
|
8
|
-
type
|
|
8
|
+
type AppPrerenderRootParamNamesMap = Record<string, readonly string[] | undefined>;
|
|
9
9
|
type HandleAppPrerenderEndpointOptions = {
|
|
10
10
|
isPrerenderEnabled?: () => boolean;
|
|
11
11
|
loadPagesRoutes?: () => Promise<unknown>;
|
|
12
12
|
pathname: string;
|
|
13
|
-
rootParamNamesByPattern?:
|
|
13
|
+
rootParamNamesByPattern?: AppPrerenderRootParamNamesMap;
|
|
14
14
|
staticParamsMap: AppPrerenderStaticParamsMap;
|
|
15
15
|
};
|
|
16
16
|
declare function handleAppPrerenderEndpoint(request: Request, options: HandleAppPrerenderEndpointOptions): Promise<Response | null>;
|
|
17
17
|
//#endregion
|
|
18
|
-
export { handleAppPrerenderEndpoint };
|
|
18
|
+
export { AppPrerenderRootParamNamesMap, AppPrerenderStaticParamsMap, handleAppPrerenderEndpoint };
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
+
import "./headers.js";
|
|
1
2
|
import { notFoundResponse } from "./http-error-responses.js";
|
|
2
3
|
import { callAppPrerenderStaticParams } from "./app-prerender-static-params.js";
|
|
3
4
|
//#region src/server/app-prerender-endpoints.ts
|
|
4
|
-
const STATIC_PARAMS_ENDPOINT = "/__vinext/prerender/static-params";
|
|
5
|
-
const PAGES_STATIC_PATHS_ENDPOINT = "/__vinext/prerender/pages-static-paths";
|
|
6
5
|
const JSON_HEADERS = { "content-type": "application/json" };
|
|
7
6
|
async function handleAppPrerenderEndpoint(request, options) {
|
|
8
|
-
if (options.pathname ===
|
|
9
|
-
if (options.pathname ===
|
|
7
|
+
if (options.pathname === "/__vinext/prerender/static-params") return handleStaticParamsEndpoint(request, options);
|
|
8
|
+
if (options.pathname === "/__vinext/prerender/pages-static-paths") {
|
|
10
9
|
if (!options.loadPagesRoutes) return null;
|
|
11
10
|
return handlePagesStaticPathsEndpoint(request, options);
|
|
12
11
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { setHeadersContext } from "../shims/headers.js";
|
|
2
|
-
import { setNavigationContext } from "../shims/navigation.js";
|
|
2
|
+
import { setNavigationContext } from "../shims/navigation-context-state.js";
|
|
3
|
+
import "../shims/navigation-server.js";
|
|
3
4
|
import { setRootParams } from "../shims/root-params.js";
|
|
4
5
|
//#region src/server/app-request-context.ts
|
|
5
6
|
/**
|
|
@@ -3,13 +3,14 @@ import { getRequestExecutionContext } from "../shims/request-context.js";
|
|
|
3
3
|
import { reportRequestError } from "./instrumentation.js";
|
|
4
4
|
import { consumeDynamicUsage, getAndClearPendingCookies, getDraftModeCookieHeader, markDynamicUsage, setHeadersAccessPhase } from "../shims/headers.js";
|
|
5
5
|
import { ensureFetchPatch, getCollectedFetchTags, setCurrentFetchCacheMode, setCurrentFetchSoftTags, setCurrentForceDynamicFetchDefault } from "../shims/fetch-cache.js";
|
|
6
|
-
import { setNavigationContext } from "../shims/navigation.js";
|
|
6
|
+
import { setNavigationContext } from "../shims/navigation-context-state.js";
|
|
7
7
|
import { makeThenableParams } from "../shims/thenable-params.js";
|
|
8
|
+
import "../shims/navigation.js";
|
|
8
9
|
import { buildPageCacheTags } from "./implicit-tags.js";
|
|
9
10
|
import { isKnownDynamicAppRoute, isValidHTTPMethod } from "./app-route-handler-runtime.js";
|
|
10
11
|
import { getAppRouteHandlerRevalidateSeconds, hasAppRouteHandlerDefaultExport, resolveAppRouteHandlerMethod, shouldReadAppRouteHandlerCache } from "./app-route-handler-policy.js";
|
|
11
|
-
import { createStaticGenerationHeadersContext } from "./app-static-generation.js";
|
|
12
12
|
import { applyRouteHandlerMiddlewareContext } from "./app-route-handler-response.js";
|
|
13
|
+
import { createStaticGenerationHeadersContext } from "./app-static-generation.js";
|
|
13
14
|
import { executeAppRouteHandler } from "./app-route-handler-execution.js";
|
|
14
15
|
import { readAppRouteHandlerCacheResponse } from "./app-route-handler-cache.js";
|
|
15
16
|
import { resolveAppRouteHandlerFetchCacheMode } from "./app-segment-config.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NextI18nConfig } from "../config/next-config.js";
|
|
2
|
+
import { CachedRouteValue } from "../shims/cache-handler.js";
|
|
2
3
|
import { ExecutionContextLike } from "../shims/request-context.js";
|
|
3
|
-
import { CachedRouteValue } from "../shims/cache.js";
|
|
4
4
|
import { NextRequest } from "../shims/server.js";
|
|
5
5
|
import { HeadersAccessPhase } from "../shims/headers.js";
|
|
6
6
|
import { RouteHandlerMiddlewareContext } from "./app-route-handler-response.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { setHeadersContext } from "../shims/headers.js";
|
|
2
2
|
import { createTrackedAppRouteRequest, markKnownDynamicAppRoute } from "./app-route-handler-runtime.js";
|
|
3
3
|
import { isPossibleAppRouteActionRequest, resolveAppRouteHandlerSpecialError, shouldApplyAppRouteHandlerRevalidateHeader, shouldWriteAppRouteHandlerCache } from "./app-route-handler-policy.js";
|
|
4
|
-
import { createStaticGenerationHeadersContext, getAppRouteStaticGenerationErrorMessage } from "./app-static-generation.js";
|
|
5
4
|
import { applyRouteHandlerMiddlewareContext, applyRouteHandlerRevalidateHeader, assertSupportedAppRouteHandlerResponse, buildAppRouteCacheValue, finalizeRouteHandlerResponse, markRouteHandlerCacheMiss } from "./app-route-handler-response.js";
|
|
5
|
+
import { createStaticGenerationHeadersContext, getAppRouteStaticGenerationErrorMessage } from "./app-static-generation.js";
|
|
6
6
|
//#region src/server/app-route-handler-execution.ts
|
|
7
7
|
function configureAppRouteStaticGenerationContext(options) {
|
|
8
8
|
if (options.dynamicConfig === "force-static" || options.dynamicConfig === "error") {
|
|
@@ -10,34 +10,82 @@
|
|
|
10
10
|
* module at Worker startup. Only the module(s) for the matched route are
|
|
11
11
|
* evaluated, on demand.
|
|
12
12
|
*
|
|
13
|
-
* `ensureAppRouteModulesLoaded` resolves a route's lazy thunks and populates
|
|
14
|
-
* synchronous
|
|
15
|
-
*
|
|
13
|
+
* `ensureAppRouteModulesLoaded` resolves a route's lazy thunks and populates
|
|
14
|
+
* the synchronous module fields that the rest of the request pipeline reads
|
|
15
|
+
* directly (`page`, `routeHandler`, layouts, templates, boundaries, and
|
|
16
|
+
* parallel-slot modules). It is:
|
|
16
17
|
*
|
|
17
18
|
* - idempotent: once a route is loaded it returns immediately;
|
|
18
19
|
* - dedup'd: concurrent calls for the same route share one in-flight promise,
|
|
19
20
|
* so a burst of requests to the same route triggers a single import.
|
|
20
21
|
*
|
|
21
|
-
* Callers must `await` it before any synchronous read of
|
|
22
|
-
*
|
|
23
|
-
*
|
|
22
|
+
* Callers must `await` it before any synchronous read of route modules
|
|
23
|
+
* (segment config, fetch-cache mode, runtime resolution, dispatch branch,
|
|
24
|
+
* element building, etc.).
|
|
24
25
|
*/
|
|
25
26
|
type LazyModuleThunk = () => Promise<unknown>;
|
|
27
|
+
type LazyModuleLoaderArray = readonly (LazyModuleThunk | null | undefined)[];
|
|
28
|
+
type LazyLoadableIntercept = {
|
|
29
|
+
interceptLayouts?: readonly unknown[] | null;
|
|
30
|
+
__loadInterceptLayouts?: LazyModuleLoaderArray | null;
|
|
31
|
+
__loadState?: {
|
|
32
|
+
interceptLayoutsLoading: Promise<readonly unknown[]> | null;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
type LazyLoadableSlot = {
|
|
36
|
+
page?: unknown;
|
|
37
|
+
default?: unknown;
|
|
38
|
+
layout?: unknown;
|
|
39
|
+
loading?: unknown;
|
|
40
|
+
error?: unknown;
|
|
41
|
+
__loadPage?: LazyModuleThunk | null;
|
|
42
|
+
__loadDefault?: LazyModuleThunk | null;
|
|
43
|
+
__loadLayout?: LazyModuleThunk | null;
|
|
44
|
+
__loadLoading?: LazyModuleThunk | null;
|
|
45
|
+
__loadError?: LazyModuleThunk | null; /** Hydrated only after an intercept matches, not with the slot's base modules. */
|
|
46
|
+
intercepts?: LazyLoadableIntercept[];
|
|
47
|
+
};
|
|
26
48
|
type LazyLoadableRoute = {
|
|
27
49
|
page?: unknown;
|
|
28
|
-
routeHandler?: unknown;
|
|
50
|
+
routeHandler?: unknown;
|
|
51
|
+
layouts?: unknown[];
|
|
52
|
+
templates?: unknown[];
|
|
53
|
+
errors?: unknown[];
|
|
54
|
+
errorPaths?: unknown[];
|
|
55
|
+
notFounds?: unknown[];
|
|
56
|
+
forbiddens?: unknown[];
|
|
57
|
+
unauthorizeds?: unknown[];
|
|
58
|
+
loading?: unknown;
|
|
59
|
+
error?: unknown;
|
|
60
|
+
notFound?: unknown;
|
|
61
|
+
forbidden?: unknown;
|
|
62
|
+
unauthorized?: unknown;
|
|
63
|
+
slots?: Record<string, LazyLoadableSlot>;
|
|
64
|
+
siblingIntercepts?: LazyLoadableIntercept[]; /** Lazy loader for the page module; `null`/absent when the page is eager. */
|
|
29
65
|
__loadPage?: LazyModuleThunk | null; /** Lazy loader for the route-handler module; `null`/absent when none. */
|
|
30
|
-
__loadRouteHandler?: LazyModuleThunk | null;
|
|
66
|
+
__loadRouteHandler?: LazyModuleThunk | null;
|
|
67
|
+
__loadLayouts?: LazyModuleLoaderArray | null;
|
|
68
|
+
__loadTemplates?: LazyModuleLoaderArray | null;
|
|
69
|
+
__loadErrors?: LazyModuleLoaderArray | null;
|
|
70
|
+
__loadErrorPaths?: LazyModuleLoaderArray | null;
|
|
71
|
+
__loadNotFounds?: LazyModuleLoaderArray | null;
|
|
72
|
+
__loadForbiddens?: LazyModuleLoaderArray | null;
|
|
73
|
+
__loadUnauthorizeds?: LazyModuleLoaderArray | null;
|
|
74
|
+
__loadLoading?: LazyModuleThunk | null;
|
|
75
|
+
__loadError?: LazyModuleThunk | null;
|
|
76
|
+
__loadNotFound?: LazyModuleThunk | null;
|
|
77
|
+
__loadForbidden?: LazyModuleThunk | null;
|
|
78
|
+
__loadUnauthorized?: LazyModuleThunk | null; /** Set once the route's lazy module fields have been resolved. */
|
|
31
79
|
__loaded?: boolean; /** In-flight hydration promise, used to dedup concurrent loads. */
|
|
32
80
|
__loading?: Promise<unknown> | null;
|
|
33
81
|
};
|
|
82
|
+
declare function loadAppInterceptLayouts(intercept: LazyLoadableIntercept): Promise<readonly unknown[]>;
|
|
34
83
|
/**
|
|
35
|
-
* Resolve a route's lazy
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* routes that have no lazy thunks.
|
|
84
|
+
* Resolve a route's lazy modules and assign them onto the route's synchronous
|
|
85
|
+
* module fields. Returns the same route reference (synchronously when already
|
|
86
|
+
* loaded, otherwise after the in-flight import resolves). Safe to call on
|
|
87
|
+
* `null`/`undefined` routes and on eager routes that have no lazy thunks.
|
|
40
88
|
*/
|
|
41
89
|
declare function ensureAppRouteModulesLoaded<TRoute extends LazyLoadableRoute>(route: TRoute | null | undefined): TRoute | Promise<TRoute>;
|
|
42
90
|
//#endregion
|
|
43
|
-
export { LazyLoadableRoute, ensureAppRouteModulesLoaded };
|
|
91
|
+
export { LazyLoadableRoute, ensureAppRouteModulesLoaded, loadAppInterceptLayouts };
|
|
@@ -1,23 +1,74 @@
|
|
|
1
1
|
//#region src/server/app-route-module-loader.ts
|
|
2
|
+
function pushFieldLoad(loads, target, field, loader) {
|
|
3
|
+
if (!loader || target[field] != null) return;
|
|
4
|
+
loads.push(loader().then((module) => {
|
|
5
|
+
target[field] = module;
|
|
6
|
+
}));
|
|
7
|
+
}
|
|
8
|
+
function pushArrayLoads(loads, target, loaders) {
|
|
9
|
+
if (!target || !loaders) return;
|
|
10
|
+
const slots = target;
|
|
11
|
+
for (const [index, loader] of loaders.entries()) {
|
|
12
|
+
if (index >= slots.length || !loader || slots[index] != null) continue;
|
|
13
|
+
loads.push(loader().then((module) => {
|
|
14
|
+
slots[index] = module;
|
|
15
|
+
}));
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function loadAppInterceptLayouts(intercept) {
|
|
19
|
+
const loadState = intercept.__loadState;
|
|
20
|
+
if (loadState?.interceptLayoutsLoading) return loadState.interceptLayoutsLoading;
|
|
21
|
+
const loads = [];
|
|
22
|
+
pushArrayLoads(loads, intercept.interceptLayouts, intercept.__loadInterceptLayouts);
|
|
23
|
+
if (loads.length === 0) return Promise.resolve(intercept.interceptLayouts ?? []);
|
|
24
|
+
const loading = Promise.all(loads).then(() => {
|
|
25
|
+
if (loadState) loadState.interceptLayoutsLoading = null;
|
|
26
|
+
return intercept.interceptLayouts ?? [];
|
|
27
|
+
}).catch((error) => {
|
|
28
|
+
if (loadState) loadState.interceptLayoutsLoading = null;
|
|
29
|
+
throw error;
|
|
30
|
+
});
|
|
31
|
+
if (loadState) loadState.interceptLayoutsLoading = loading;
|
|
32
|
+
return loading;
|
|
33
|
+
}
|
|
2
34
|
/**
|
|
3
|
-
* Resolve a route's lazy
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* routes that have no lazy thunks.
|
|
35
|
+
* Resolve a route's lazy modules and assign them onto the route's synchronous
|
|
36
|
+
* module fields. Returns the same route reference (synchronously when already
|
|
37
|
+
* loaded, otherwise after the in-flight import resolves). Safe to call on
|
|
38
|
+
* `null`/`undefined` routes and on eager routes that have no lazy thunks.
|
|
8
39
|
*/
|
|
9
40
|
function ensureAppRouteModulesLoaded(route) {
|
|
10
41
|
if (!route || route.__loaded) return route;
|
|
11
42
|
if (route.__loading) return route.__loading;
|
|
12
43
|
const loadPage = route.__loadPage;
|
|
13
44
|
const loadRouteHandler = route.__loadRouteHandler;
|
|
14
|
-
|
|
45
|
+
const loads = [];
|
|
46
|
+
pushFieldLoad(loads, route, "page", loadPage);
|
|
47
|
+
pushFieldLoad(loads, route, "routeHandler", loadRouteHandler);
|
|
48
|
+
pushFieldLoad(loads, route, "loading", route.__loadLoading);
|
|
49
|
+
pushFieldLoad(loads, route, "error", route.__loadError);
|
|
50
|
+
pushFieldLoad(loads, route, "notFound", route.__loadNotFound);
|
|
51
|
+
pushFieldLoad(loads, route, "forbidden", route.__loadForbidden);
|
|
52
|
+
pushFieldLoad(loads, route, "unauthorized", route.__loadUnauthorized);
|
|
53
|
+
pushArrayLoads(loads, route.layouts, route.__loadLayouts);
|
|
54
|
+
pushArrayLoads(loads, route.templates, route.__loadTemplates);
|
|
55
|
+
pushArrayLoads(loads, route.errors, route.__loadErrors);
|
|
56
|
+
pushArrayLoads(loads, route.errorPaths, route.__loadErrorPaths);
|
|
57
|
+
pushArrayLoads(loads, route.notFounds, route.__loadNotFounds);
|
|
58
|
+
pushArrayLoads(loads, route.forbiddens, route.__loadForbiddens);
|
|
59
|
+
pushArrayLoads(loads, route.unauthorizeds, route.__loadUnauthorizeds);
|
|
60
|
+
for (const slot of Object.values(route.slots ?? {})) {
|
|
61
|
+
pushFieldLoad(loads, slot, "page", slot.__loadPage);
|
|
62
|
+
pushFieldLoad(loads, slot, "default", slot.__loadDefault);
|
|
63
|
+
pushFieldLoad(loads, slot, "layout", slot.__loadLayout);
|
|
64
|
+
pushFieldLoad(loads, slot, "loading", slot.__loadLoading);
|
|
65
|
+
pushFieldLoad(loads, slot, "error", slot.__loadError);
|
|
66
|
+
}
|
|
67
|
+
if (loads.length === 0) {
|
|
15
68
|
route.__loaded = true;
|
|
16
69
|
return route;
|
|
17
70
|
}
|
|
18
|
-
const loading = Promise.all(
|
|
19
|
-
if (loadPage) route.page = pageModule;
|
|
20
|
-
if (loadRouteHandler) route.routeHandler = routeHandlerModule;
|
|
71
|
+
const loading = Promise.all(loads).then(() => {
|
|
21
72
|
route.__loaded = true;
|
|
22
73
|
route.__loading = null;
|
|
23
74
|
return route;
|
|
@@ -29,4 +80,4 @@ function ensureAppRouteModulesLoaded(route) {
|
|
|
29
80
|
return loading;
|
|
30
81
|
}
|
|
31
82
|
//#endregion
|
|
32
|
-
export { ensureAppRouteModulesLoaded };
|
|
83
|
+
export { ensureAppRouteModulesLoaded, loadAppInterceptLayouts };
|
|
@@ -2,7 +2,8 @@ import "./server-globals.js";
|
|
|
2
2
|
import { runWithExecutionContext } from "../shims/request-context.js";
|
|
3
3
|
import { VINEXT_PRERENDER_ROUTE_PARAMS_HEADER } from "./headers.js";
|
|
4
4
|
import { badRequestResponse, notFoundResponse, notFoundStaticAssetResponse } from "./http-error-responses.js";
|
|
5
|
-
import {
|
|
5
|
+
import { isOpenRedirectShaped } from "./open-redirect.js";
|
|
6
|
+
import { cloneRequestWithHeaders, filterInternalHeaders } from "./request-pipeline.js";
|
|
6
7
|
import { assetPrefixPathname, isNextStaticPath } from "../utils/asset-prefix.js";
|
|
7
8
|
import { resolveStaticAssetSignal } from "./worker-utils.js";
|
|
8
9
|
import { readTrustedPrerenderRouteParams, serializePrerenderRouteParamsHeader } from "./prerender-route-params.js";
|
|
@@ -5,16 +5,16 @@ import { RootParams } from "../shims/root-params.js";
|
|
|
5
5
|
import { MiddlewareModule } from "./middleware-runtime.js";
|
|
6
6
|
import { AppMiddlewareContext } from "./app-middleware.js";
|
|
7
7
|
import { AppRscRenderMode } from "./app-rsc-render-mode.js";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
8
|
+
import { AppPrerenderRootParamNamesMap, AppPrerenderStaticParamsMap } from "./app-prerender-endpoints.js";
|
|
9
|
+
import { MetadataRouteMakeThenableParams, MetadataRuntimeRoute } from "./metadata-route-response.js";
|
|
10
10
|
import { ReactFormState } from "react-dom/client";
|
|
11
11
|
|
|
12
12
|
//#region src/server/app-rsc-handler.d.ts
|
|
13
13
|
type AppPageParams = Record<string, string | string[]>;
|
|
14
|
-
type MetadataRoutes =
|
|
15
|
-
type MakeThenableParams =
|
|
16
|
-
type StaticParamsMap =
|
|
17
|
-
type RootParamNamesMap =
|
|
14
|
+
type MetadataRoutes = readonly MetadataRuntimeRoute[];
|
|
15
|
+
type MakeThenableParams = MetadataRouteMakeThenableParams;
|
|
16
|
+
type StaticParamsMap = AppPrerenderStaticParamsMap;
|
|
17
|
+
type RootParamNamesMap = AppPrerenderRootParamNamesMap;
|
|
18
18
|
type AppRscMiddlewareContext = AppMiddlewareContext;
|
|
19
19
|
type AppRscHandlerRoute = {
|
|
20
20
|
isDynamic: boolean;
|
|
@@ -183,6 +183,7 @@ type CreateAppRscHandlerOptions<TRoute extends AppRscHandlerRoute> = {
|
|
|
183
183
|
makeThenableParams: MakeThenableParams;
|
|
184
184
|
matchRoute: (pathname: string) => AppRscRouteMatch<TRoute> | null;
|
|
185
185
|
metadataRoutes: MetadataRoutes;
|
|
186
|
+
middlewareFilePath: string | null;
|
|
186
187
|
middlewareModule: MiddlewareModule | null;
|
|
187
188
|
publicFiles: ReadonlySet<string>;
|
|
188
189
|
renderNotFound: (options: RenderNotFoundOptions<TRoute>) => Promise<Response | null>;
|
|
@@ -8,25 +8,21 @@ import { applyConfigHeadersToResponse, cloneRequestWithHeaders, cloneRequestWith
|
|
|
8
8
|
import { headersContextFromRequest } from "../shims/headers.js";
|
|
9
9
|
import { ensureFetchPatch, setCurrentFetchSoftTags } from "../shims/fetch-cache.js";
|
|
10
10
|
import { mergeRewriteQuery } from "../utils/query.js";
|
|
11
|
-
import { VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM, createRscRedirectLocation, hasRscCacheBustingSearchParam, resolveInvalidRscCacheBustingRequest, stripRscCacheBustingSearchParam, stripRscSuffix } from "./app-rsc-cache-busting.js";
|
|
12
11
|
import { getScriptNonceFromHeaderSources } from "./csp.js";
|
|
13
12
|
import { normalizeDefaultLocalePathname } from "./pages-i18n.js";
|
|
14
13
|
import { DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, isImageOptimizationPath, resolveDevImageRedirect } from "./image-optimization.js";
|
|
14
|
+
import { VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM, createRscRedirectLocation, hasRscCacheBustingSearchParam, resolveInvalidRscCacheBustingRequest, stripRscCacheBustingSearchParam, stripRscSuffix } from "./app-rsc-cache-busting.js";
|
|
15
15
|
import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
|
|
16
16
|
import "./app-page-response.js";
|
|
17
17
|
import { buildNextDataNotFoundResponse, normalizePagesDataRequest } from "./pages-data-route.js";
|
|
18
|
-
import { createAppPprFallbackShells } from "./app-ppr-fallback-shell.js";
|
|
19
18
|
import { matchPrerenderRouteParamsPayload, readTrustedPrerenderRouteParams, serializePrerenderRouteParamsHeader } from "./prerender-route-params.js";
|
|
20
19
|
import { getRenderedConcreteUrlPathsForRoute } from "./pregenerated-concrete-paths.js";
|
|
21
20
|
import { pickRootParams, setRootParams } from "../shims/root-params.js";
|
|
22
21
|
import { flattenErrorCauses } from "../utils/error-cause.js";
|
|
23
|
-
import { applyAppMiddleware } from "./app-middleware.js";
|
|
24
22
|
import { buildPageCacheTags } from "./implicit-tags.js";
|
|
25
23
|
import { buildPostMwRequestContext } from "./app-post-middleware-context.js";
|
|
26
|
-
import { handleAppPrerenderEndpoint } from "./app-prerender-endpoints.js";
|
|
27
24
|
import { finalizeAppRscResponse } from "./app-rsc-response-finalizer.js";
|
|
28
25
|
import { normalizeRscRequest } from "./app-rsc-request-normalization.js";
|
|
29
|
-
import { handleMetadataRouteRequest } from "./metadata-route-response.js";
|
|
30
26
|
import { runWithPrerenderWorkUnit } from "./prerender-work-unit-setup.js";
|
|
31
27
|
//#region src/server/app-rsc-handler.ts
|
|
32
28
|
const STATIC_METADATA_CONFIG_HEADER_OVERRIDES = new Set(["cache-control"]);
|
|
@@ -127,16 +123,19 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
|
|
|
127
123
|
basePath: options.basePath,
|
|
128
124
|
hadBasePath: true
|
|
129
125
|
};
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
126
|
+
if (pathname === "/__vinext/prerender/static-params" || pathname === "/__vinext/prerender/pages-static-paths") {
|
|
127
|
+
const { handleAppPrerenderEndpoint } = await import("./app-prerender-endpoints.js");
|
|
128
|
+
const prerenderEndpointResponse = await handleAppPrerenderEndpoint(request, {
|
|
129
|
+
isPrerenderEnabled() {
|
|
130
|
+
return process.env.VINEXT_PRERENDER === "1";
|
|
131
|
+
},
|
|
132
|
+
loadPagesRoutes: options.loadPrerenderPagesRoutes,
|
|
133
|
+
pathname,
|
|
134
|
+
rootParamNamesByPattern: options.rootParamNamesByPattern,
|
|
135
|
+
staticParamsMap: options.staticParamsMap
|
|
136
|
+
});
|
|
137
|
+
if (prerenderEndpointResponse) return prerenderEndpointResponse;
|
|
138
|
+
}
|
|
140
139
|
const trailingSlashRedirect = normalizeTrailingSlash(pathname, options.basePath, options.trailingSlash, url.search);
|
|
141
140
|
if (trailingSlashRedirect) return trailingSlashRedirect;
|
|
142
141
|
const matchPathname = (p) => normalizeDefaultLocalePathname(p, options.i18nConfig, { hostname: url.hostname });
|
|
@@ -167,10 +166,12 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
|
|
|
167
166
|
};
|
|
168
167
|
let didMiddlewareRewrite = false;
|
|
169
168
|
if (options.middlewareModule) {
|
|
169
|
+
const { applyAppMiddleware } = await import("./app-middleware.js");
|
|
170
170
|
const middlewareResult = await applyAppMiddleware({
|
|
171
171
|
basePath: options.basePath,
|
|
172
172
|
cleanPathname,
|
|
173
173
|
context: middlewareContext,
|
|
174
|
+
filePath: options.middlewareFilePath ?? void 0,
|
|
174
175
|
i18nConfig: options.i18nConfig,
|
|
175
176
|
isDataRequest,
|
|
176
177
|
isProxy: options.isMiddlewareProxy,
|
|
@@ -210,20 +211,23 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
|
|
|
210
211
|
if (!imageRedirect) return new Response("Invalid image optimization parameters", { status: 400 });
|
|
211
212
|
return Response.redirect(new URL(imageRedirect, url.origin).href, 302);
|
|
212
213
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
applyConfigHeadersToResponse(metadataRouteResponse.headers, {
|
|
220
|
-
basePathState,
|
|
221
|
-
configHeaders: options.configHeaders,
|
|
222
|
-
overwriteExisting: STATIC_METADATA_CONFIG_HEADER_OVERRIDES,
|
|
223
|
-
pathname: matchPathname(cleanPathname),
|
|
224
|
-
requestContext: preMiddlewareRequestContext
|
|
214
|
+
if (options.metadataRoutes.length > 0) {
|
|
215
|
+
const { handleMetadataRouteRequest } = await import("./metadata-route-response.js");
|
|
216
|
+
const metadataRouteResponse = await handleMetadataRouteRequest({
|
|
217
|
+
metadataRoutes: options.metadataRoutes,
|
|
218
|
+
cleanPathname,
|
|
219
|
+
makeThenableParams: options.makeThenableParams
|
|
225
220
|
});
|
|
226
|
-
|
|
221
|
+
if (metadataRouteResponse) {
|
|
222
|
+
applyConfigHeadersToResponse(metadataRouteResponse.headers, {
|
|
223
|
+
basePathState,
|
|
224
|
+
configHeaders: options.configHeaders,
|
|
225
|
+
overwriteExisting: STATIC_METADATA_CONFIG_HEADER_OVERRIDES,
|
|
226
|
+
pathname: matchPathname(cleanPathname),
|
|
227
|
+
requestContext: preMiddlewareRequestContext
|
|
228
|
+
});
|
|
229
|
+
return applyMiddlewareContextToResponse(metadataRouteResponse, middlewareContext);
|
|
230
|
+
}
|
|
227
231
|
}
|
|
228
232
|
const publicFileResponse = resolvePublicFileRoute({
|
|
229
233
|
cleanPathname,
|
|
@@ -249,7 +253,9 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
|
|
|
249
253
|
if (preActionMatch) setRootParams(pickRootParams(preActionMatch.params, preActionMatch.route.rootParamNames));
|
|
250
254
|
const actionId = request.headers.get("x-rsc-action") ?? request.headers.get("next-action");
|
|
251
255
|
const contentType = request.headers.get("content-type") || "";
|
|
252
|
-
const
|
|
256
|
+
const isPostRequest = request.method.toUpperCase() === "POST";
|
|
257
|
+
let progressiveActionResult = null;
|
|
258
|
+
if (isPostRequest && contentType.startsWith("multipart/form-data") && !actionId) progressiveActionResult = await options.handleProgressiveActionRequest({
|
|
253
259
|
actionId,
|
|
254
260
|
cleanPathname,
|
|
255
261
|
contentType,
|
|
@@ -257,12 +263,13 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
|
|
|
257
263
|
request
|
|
258
264
|
});
|
|
259
265
|
if (progressiveActionResult instanceof Response) return progressiveActionResult;
|
|
260
|
-
const
|
|
261
|
-
const
|
|
262
|
-
const
|
|
266
|
+
const progressiveActionFormState = progressiveActionResult?.kind === "form-state" ? progressiveActionResult : null;
|
|
267
|
+
const isProgressiveActionRender = progressiveActionFormState !== null;
|
|
268
|
+
const formState = progressiveActionFormState?.formState ?? null;
|
|
269
|
+
const failedProgressiveActionResult = progressiveActionFormState && "actionError" in progressiveActionFormState ? progressiveActionFormState : null;
|
|
263
270
|
const actionFailed = failedProgressiveActionResult !== null;
|
|
264
271
|
const actionError = failedProgressiveActionResult?.actionError;
|
|
265
|
-
const serverActionResponse = await options.handleServerActionRequest({
|
|
272
|
+
const serverActionResponse = isPostRequest && actionId ? await options.handleServerActionRequest({
|
|
266
273
|
actionId,
|
|
267
274
|
cleanPathname,
|
|
268
275
|
contentType,
|
|
@@ -272,7 +279,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
|
|
|
272
279
|
mountedSlotsHeader,
|
|
273
280
|
request,
|
|
274
281
|
searchParams: getResolvedSearchParams()
|
|
275
|
-
});
|
|
282
|
+
}) : null;
|
|
276
283
|
if (serverActionResponse) return serverActionResponse;
|
|
277
284
|
let match = preActionMatch;
|
|
278
285
|
const renderPagesForMatchKind = async (matchKind) => {
|
|
@@ -386,11 +393,15 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
|
|
|
386
393
|
const isPrerenderFallbackShell = prerenderRouteParamsMatch?.kind === "fallback-shell";
|
|
387
394
|
const renderParams = prerenderRouteParams ?? params;
|
|
388
395
|
const resolvedSearchParams = getResolvedSearchParams();
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
396
|
+
let runtimeFallbackShells = [];
|
|
397
|
+
if (options.cacheComponents === true && request.method === "GET" && !isRscRequest && !isPrerenderFallbackShell && route.params) {
|
|
398
|
+
const { createAppPprFallbackShells } = await import("./app-ppr-fallback-shell.js");
|
|
399
|
+
runtimeFallbackShells = createAppPprFallbackShells({
|
|
400
|
+
params: route.params,
|
|
401
|
+
pattern: route.pattern,
|
|
402
|
+
rootParamNames: route.rootParamNames
|
|
403
|
+
}, params);
|
|
404
|
+
}
|
|
394
405
|
options.setNavigationContext({
|
|
395
406
|
pathname: canonicalPathname,
|
|
396
407
|
searchParams: resolvedSearchParams,
|
|
@@ -443,7 +454,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
|
|
|
443
454
|
searchParams: resolvedSearchParams,
|
|
444
455
|
renderMode
|
|
445
456
|
});
|
|
446
|
-
if (isProgressiveActionRender) return applyProgressiveActionSideEffects(pageResponse,
|
|
457
|
+
if (isProgressiveActionRender) return applyProgressiveActionSideEffects(pageResponse, progressiveActionFormState);
|
|
447
458
|
return pageResponse;
|
|
448
459
|
}
|
|
449
460
|
/**
|
|
@@ -4,8 +4,8 @@ import "./headers.js";
|
|
|
4
4
|
import { normalizePath } from "./normalize-path.js";
|
|
5
5
|
import { applyConfigHeadersToResponse } from "./request-pipeline.js";
|
|
6
6
|
import { applyCdnResponseHeaders } from "./cache-control.js";
|
|
7
|
-
import { VINEXT_RSC_VARY_HEADER } from "./app-rsc-cache-busting.js";
|
|
8
7
|
import { normalizeDefaultLocalePathname } from "./pages-i18n.js";
|
|
8
|
+
import { VINEXT_RSC_VARY_HEADER } from "./app-rsc-cache-busting.js";
|
|
9
9
|
import { mergeVaryHeader } from "./middleware-response-headers.js";
|
|
10
10
|
//#region src/server/app-rsc-response-finalizer.ts
|
|
11
11
|
/**
|