@qzsy/vinext 0.1.11 → 0.1.80
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 +19 -5
- package/dist/build/inject-pregenerated-paths.d.ts +4 -0
- package/dist/build/inject-pregenerated-paths.js +18 -0
- 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 +11 -4
- package/dist/build/report.d.ts +2 -1
- package/dist/build/report.js +2 -1
- package/dist/build/run-prerender.d.ts +7 -0
- package/dist/build/run-prerender.js +9 -0
- package/dist/build/standalone.js +2 -0
- package/dist/check.d.ts +18 -0
- package/dist/check.js +77 -19
- package/dist/cli-dev-config.d.ts +12 -0
- package/dist/cli-dev-config.js +23 -0
- package/dist/cli.js +64 -28
- 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/cloudflare/deploy-config.d.ts +51 -0
- package/dist/cloudflare/deploy-config.js +153 -0
- package/dist/cloudflare/index.d.ts +1 -1
- package/dist/cloudflare/index.js +1 -1
- package/dist/cloudflare/project.d.ts +41 -0
- package/dist/cloudflare/project.js +243 -0
- package/dist/cloudflare/tpr.js +1 -1
- 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/server-external-packages.d.ts +4 -0
- package/dist/config/server-external-packages.js +91 -0
- package/dist/deploy.d.ts +2 -122
- package/dist/deploy.js +20 -793
- package/dist/entries/app-rsc-entry.d.ts +2 -1
- package/dist/entries/app-rsc-entry.js +70 -12
- package/dist/entries/app-rsc-manifest.js +8 -0
- package/dist/entries/pages-client-entry.d.ts +1 -0
- package/dist/entries/pages-client-entry.js +2 -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 +50 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +158 -109
- package/dist/init-cloudflare.d.ts +43 -0
- package/dist/init-cloudflare.js +1000 -0
- package/dist/init-platform.d.ts +38 -0
- package/dist/init-platform.js +150 -0
- package/dist/init.d.ts +14 -37
- package/dist/init.js +205 -95
- 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/plugins/ast-scope.d.ts +16 -0
- package/dist/plugins/ast-scope.js +62 -0
- package/dist/plugins/ast-utils.js +3 -0
- package/dist/plugins/css-module-imports.d.ts +14 -0
- package/dist/plugins/css-module-imports.js +59 -0
- 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 +13 -2
- package/dist/routing/app-route-graph.js +116 -32
- 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/app-browser-action-result.d.ts +2 -1
- package/dist/server/app-browser-action-result.js +5 -1
- package/dist/server/app-browser-entry.js +17 -12
- 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.js +1 -0
- package/dist/server/app-browser-server-action-client.js +2 -3
- package/dist/server/app-browser-state.d.ts +1 -0
- package/dist/server/app-browser-state.js +3 -2
- package/dist/server/app-fallback-renderer.d.ts +3 -2
- package/dist/server/app-fallback-renderer.js +12 -7
- package/dist/server/app-middleware.d.ts +2 -3
- package/dist/server/app-middleware.js +3 -2
- package/dist/server/app-optimistic-routing.js +1 -1
- package/dist/server/app-page-boundary-render.d.ts +1 -0
- package/dist/server/app-page-boundary-render.js +12 -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 +4 -1
- package/dist/server/app-page-dispatch.d.ts +11 -3
- package/dist/server/app-page-dispatch.js +55 -15
- package/dist/server/app-page-element-builder.d.ts +5 -1
- package/dist/server/app-page-element-builder.js +57 -20
- package/dist/server/app-page-head.d.ts +12 -0
- package/dist/server/app-page-head.js +42 -19
- package/dist/server/app-page-params.d.ts +2 -1
- package/dist/server/app-page-params.js +8 -1
- 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 +8 -3
- package/dist/server/app-page-request.d.ts +22 -1
- package/dist/server/app-page-request.js +89 -13
- package/dist/server/app-page-route-wiring.d.ts +6 -1
- package/dist/server/app-page-route-wiring.js +31 -15
- 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.js +2 -0
- 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.d.ts +12 -0
- package/dist/server/app-router-entry.js +22 -8
- package/dist/server/app-router-image-optimization.d.ts +37 -0
- package/dist/server/app-router-image-optimization.js +40 -0
- package/dist/server/app-rsc-errors.js +7 -1
- package/dist/server/app-rsc-handler.js +27 -14
- 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.js +12 -1
- package/dist/server/app-static-generation.d.ts +1 -0
- package/dist/server/app-static-generation.js +1 -0
- 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-server.js +8 -15
- package/dist/server/dev-stack-sourcemap.d.ts +1 -1
- package/dist/server/dev-stack-sourcemap.js +1 -1
- 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/isr-cache.d.ts +1 -1
- package/dist/server/isr-cache.js +2 -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-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-page-data.d.ts +23 -1
- package/dist/server/pages-page-data.js +43 -24
- package/dist/server/pages-page-handler.d.ts +2 -1
- package/dist/server/pages-page-handler.js +10 -4
- package/dist/server/pages-request-pipeline.d.ts +2 -0
- package/dist/server/pages-request-pipeline.js +25 -1
- 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 +47 -25
- 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-optimization-url.d.ts +4 -0
- package/dist/shims/image-optimization-url.js +33 -1
- package/dist/shims/image.js +46 -13
- 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 -5
- package/dist/shims/internal/hybrid-client-route-owner.js +9 -60
- package/dist/shims/internal/pages-router-components.d.ts +7 -0
- package/dist/shims/internal/pages-router-components.js +13 -0
- package/dist/shims/link.js +23 -16
- package/dist/shims/metadata.d.ts +3 -2
- package/dist/shims/metadata.js +8 -4
- package/dist/shims/navigation.js +4 -2
- package/dist/shims/root-params.d.ts +15 -1
- package/dist/shims/root-params.js +21 -1
- package/dist/shims/router.d.ts +2 -5
- package/dist/shims/router.js +41 -22
- package/dist/shims/server.js +3 -2
- 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 +9 -1
- package/dist/utils/project.js +21 -4
- 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 +28 -24
- package/dist/server/dev-stack-sourcemap-endpoint.d.ts +0 -4
- /package/dist/{cloudflare → packages/cloudflare}/src/utils/cache-control-metadata.js +0 -0
|
@@ -3,7 +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 { 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";
|
|
7
7
|
import { _consumeRequestScopedCacheLife, _peekRequestScopedCacheLife } from "../shims/cache-request-state.js";
|
|
8
8
|
import { ensureFetchPatch, getCollectedFetchTags, peekDynamicFetchObservations, runWithFetchDedupe, setCurrentFetchCacheMode, setCurrentFetchSoftTags, setCurrentForceDynamicFetchDefault } from "../shims/fetch-cache.js";
|
|
9
9
|
import { VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader } from "./app-rsc-cache-busting.js";
|
|
@@ -107,6 +107,7 @@ async function runAppPageRevalidationContext(options, renderFn) {
|
|
|
107
107
|
const { createStaticGenerationHeadersContext } = await import("./app-static-generation.js");
|
|
108
108
|
return runWithRequestContext(createRequestContext({
|
|
109
109
|
headersContext: createStaticGenerationHeadersContext({
|
|
110
|
+
draftModeEnabled: false,
|
|
110
111
|
draftModeSecret: options.draftModeSecret,
|
|
111
112
|
dynamicConfig: options.dynamicConfig,
|
|
112
113
|
routeKind: "page",
|
|
@@ -131,6 +132,8 @@ function toInterceptOptions(interceptionContext, intercept) {
|
|
|
131
132
|
return {
|
|
132
133
|
interceptionContext,
|
|
133
134
|
interceptLayouts: intercept.interceptLayouts,
|
|
135
|
+
interceptLayoutSegments: intercept.interceptLayoutSegments,
|
|
136
|
+
interceptBranchSegments: intercept.interceptBranchSegments,
|
|
134
137
|
interceptPage: intercept.page,
|
|
135
138
|
interceptParams: intercept.matchedParams,
|
|
136
139
|
interceptSlotId: intercept.slotId ?? null,
|
|
@@ -152,7 +155,11 @@ async function dispatchAppPageInner(options) {
|
|
|
152
155
|
const isDynamicError = dynamicConfig === "error";
|
|
153
156
|
const isForceDynamic = dynamicConfig === "force-dynamic";
|
|
154
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;
|
|
155
161
|
const layoutParamAccess = createAppLayoutParamAccessTracker();
|
|
162
|
+
const hasActiveLoadingBoundary = shouldSuppressLoadingBoundaries(options.renderMode ?? "navigation") ? false : Boolean(route.loading?.default);
|
|
156
163
|
setCurrentFetchSoftTags(buildAppPageTags(options.cleanPathname, [], route.routeSegments));
|
|
157
164
|
setCurrentFetchCacheMode(options.fetchCache ?? null);
|
|
158
165
|
setCurrentForceDynamicFetchDefault(isForceDynamic);
|
|
@@ -172,9 +179,10 @@ async function dispatchAppPageInner(options) {
|
|
|
172
179
|
options.clearRequestContext();
|
|
173
180
|
return methodResponse;
|
|
174
181
|
}
|
|
175
|
-
if (
|
|
182
|
+
if (isForceStatic || isDynamicError) {
|
|
176
183
|
const { createStaticGenerationHeadersContext } = await import("./app-static-generation.js");
|
|
177
184
|
setHeadersContext(createStaticGenerationHeadersContext({
|
|
185
|
+
draftModeEnabled: isDraftMode,
|
|
178
186
|
draftModeSecret: options.draftModeSecret,
|
|
179
187
|
dynamicConfig,
|
|
180
188
|
routeKind: "page",
|
|
@@ -200,7 +208,7 @@ async function dispatchAppPageInner(options) {
|
|
|
200
208
|
const cachedPageResponse = await readAppPageCacheResponse({
|
|
201
209
|
cleanPathname: options.cleanPathname,
|
|
202
210
|
clearRequestContext: options.clearRequestContext,
|
|
203
|
-
hasRequestSearchParams
|
|
211
|
+
hasRequestSearchParams,
|
|
204
212
|
isEdgeRuntime: options.isEdgeRuntime,
|
|
205
213
|
isRscRequest: options.isRscRequest,
|
|
206
214
|
isrDebug: options.isrDebug,
|
|
@@ -234,19 +242,23 @@ async function dispatchAppPageInner(options) {
|
|
|
234
242
|
});
|
|
235
243
|
revalidationTarget.navigationParams = resolveAppPageNavigationParams(revalidationTarget.route, revalidationTarget.navigationParams, options.cleanPathname, revalidationTarget.interceptOpts);
|
|
236
244
|
await options.ensureRouteLoaded?.(revalidationTarget.route);
|
|
245
|
+
const revalidationDynamicConfig = options.resolveRouteDynamicConfig?.(revalidationTarget.route) ?? (revalidationTarget.route === route ? dynamicConfig : void 0);
|
|
237
246
|
return runAppPageRevalidationContext({
|
|
238
247
|
cleanPathname: options.cleanPathname,
|
|
239
248
|
displayPathname: options.displayPathname,
|
|
240
249
|
currentFetchCacheMode: options.resolveRouteFetchCacheMode?.(revalidationTarget.route) ?? (revalidationTarget.route === route ? options.fetchCache ?? null : null),
|
|
241
250
|
draftModeSecret: options.draftModeSecret,
|
|
242
|
-
dynamicConfig:
|
|
251
|
+
dynamicConfig: revalidationDynamicConfig,
|
|
243
252
|
params: revalidationTarget.navigationParams,
|
|
244
253
|
routePattern: revalidationTarget.route.pattern,
|
|
245
254
|
routeSegments: revalidationTarget.route.routeSegments,
|
|
246
255
|
setNavigationContext: options.setNavigationContext
|
|
247
256
|
}, async () => {
|
|
248
257
|
const { renderAppPageCacheArtifacts } = await import("./app-page-cache-render.js");
|
|
249
|
-
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
|
+
});
|
|
250
262
|
const revalidatedOnError = options.createRscOnErrorHandler(options.cleanPathname, revalidationTarget.route.pattern);
|
|
251
263
|
const rendered = await renderAppPageCacheArtifacts({
|
|
252
264
|
basePath: options.basePath,
|
|
@@ -272,6 +284,7 @@ async function dispatchAppPageInner(options) {
|
|
|
272
284
|
return {
|
|
273
285
|
html: rendered.html,
|
|
274
286
|
htmlRenderObservation: rendered.htmlRenderObservation,
|
|
287
|
+
linkHeader: rendered.linkHeader,
|
|
275
288
|
rscData: rendered.rscData,
|
|
276
289
|
rscRenderObservation: rendered.rscRenderObservation,
|
|
277
290
|
tags: rendered.tags,
|
|
@@ -301,12 +314,27 @@ async function dispatchAppPageInner(options) {
|
|
|
301
314
|
}
|
|
302
315
|
const fallbackShellResponse = options.pprRuntime ? await options.pprRuntime.tryServe(options, currentRevalidateSeconds, isDraftMode, isForceStatic, isForceDynamic) : null;
|
|
303
316
|
if (fallbackShellResponse) return fallbackShellResponse;
|
|
317
|
+
let interceptDynamicConfig;
|
|
318
|
+
let interceptDynamicConfigResolved = false;
|
|
304
319
|
const interceptResult = await resolveAppPageIntercept({
|
|
305
320
|
async buildPageElement(interceptRoute, interceptParams, interceptOpts, interceptSearchParams, interceptLayoutParamAccess) {
|
|
306
|
-
|
|
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);
|
|
307
332
|
setCurrentFetchCacheMode(options.resolveRouteFetchCacheMode?.(interceptRoute) ?? null);
|
|
308
|
-
setCurrentForceDynamicFetchDefault(
|
|
309
|
-
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
|
+
});
|
|
310
338
|
},
|
|
311
339
|
cleanPathname: options.cleanPathname,
|
|
312
340
|
currentRoute: route,
|
|
@@ -338,6 +366,12 @@ async function dispatchAppPageInner(options) {
|
|
|
338
366
|
headers: interceptHeaders
|
|
339
367
|
});
|
|
340
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
|
+
},
|
|
341
375
|
searchParams: options.searchParams,
|
|
342
376
|
setNavigationContext: options.setNavigationContext,
|
|
343
377
|
toInterceptOpts(intercept) {
|
|
@@ -348,12 +382,15 @@ async function dispatchAppPageInner(options) {
|
|
|
348
382
|
const buildCurrentPageElement = () => buildAppPageElement({
|
|
349
383
|
buildPageElement() {
|
|
350
384
|
if (options.actionFailed) throw options.actionError;
|
|
351
|
-
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
|
+
});
|
|
352
389
|
},
|
|
353
390
|
async probePageSpecialError() {
|
|
354
391
|
if (!shouldSuppressLoadingBoundaries(options.renderMode ?? "navigation") && route.loading?.default) return null;
|
|
355
392
|
return resolveAppPageSpecialError(await probeAppPageThrownError({
|
|
356
|
-
probePage: options.probePage,
|
|
393
|
+
probePage: () => options.probePage(pageSearchParams),
|
|
357
394
|
runWithSuppressedHookWarning(probe) {
|
|
358
395
|
return options.runWithSuppressedHookWarning(probe);
|
|
359
396
|
}
|
|
@@ -384,7 +421,7 @@ async function dispatchAppPageInner(options) {
|
|
|
384
421
|
const navigationParams = resolveAppPageNavigationParams(route, options.params, options.cleanPathname, interceptResult.interceptOpts);
|
|
385
422
|
options.setNavigationContext({
|
|
386
423
|
pathname: options.displayPathname ?? options.cleanPathname,
|
|
387
|
-
searchParams:
|
|
424
|
+
searchParams: pageSearchParams,
|
|
388
425
|
params: navigationParams
|
|
389
426
|
});
|
|
390
427
|
const layoutClassifications = getEffectiveLayoutClassifications(route, options.debugClassification);
|
|
@@ -398,6 +435,7 @@ async function dispatchAppPageInner(options) {
|
|
|
398
435
|
cleanPathname: options.cleanPathname,
|
|
399
436
|
clearRequestContext: options.clearRequestContext,
|
|
400
437
|
consumeDynamicUsage,
|
|
438
|
+
peekDynamicUsage,
|
|
401
439
|
consumeInvalidDynamicUsageError,
|
|
402
440
|
consumeRenderObservationState: consumeAppPageRenderObservationState,
|
|
403
441
|
createRscOnErrorHandler(pathname, routePath) {
|
|
@@ -420,7 +458,8 @@ async function dispatchAppPageInner(options) {
|
|
|
420
458
|
return _peekRequestScopedCacheLife();
|
|
421
459
|
},
|
|
422
460
|
handlerStart: options.handlerStart,
|
|
423
|
-
hasLoadingBoundary:
|
|
461
|
+
hasLoadingBoundary: hasActiveLoadingBoundary,
|
|
462
|
+
omitPendingDynamicCacheState: !options.isRscRequest && hasRequestSearchParams,
|
|
424
463
|
formState: options.formState ?? null,
|
|
425
464
|
isProgressiveActionRender: options.isProgressiveActionRender === true,
|
|
426
465
|
isDynamicError,
|
|
@@ -459,8 +498,9 @@ async function dispatchAppPageInner(options) {
|
|
|
459
498
|
return options.probeLayoutAt(layoutIndex, layoutParamAccess);
|
|
460
499
|
},
|
|
461
500
|
probePage() {
|
|
462
|
-
return options.probePage();
|
|
501
|
+
return options.probePage(pageSearchParams);
|
|
463
502
|
},
|
|
503
|
+
probePageBeforeRender: options.isRscRequest,
|
|
464
504
|
classification: {
|
|
465
505
|
getLayoutId(index) {
|
|
466
506
|
const treePosition = route.layoutTreePositions?.[index] ?? 0;
|
|
@@ -489,8 +529,8 @@ async function dispatchAppPageInner(options) {
|
|
|
489
529
|
revalidateSeconds: currentRevalidateSeconds,
|
|
490
530
|
mountedSlotsHeader: options.mountedSlotsHeader,
|
|
491
531
|
renderMode: options.renderMode ?? "navigation",
|
|
492
|
-
renderErrorBoundaryResponse(renderError) {
|
|
493
|
-
return options.renderErrorBoundaryPage(renderError);
|
|
532
|
+
renderErrorBoundaryResponse(renderError, errorOrigin) {
|
|
533
|
+
return options.renderErrorBoundaryPage(renderError, errorOrigin);
|
|
494
534
|
},
|
|
495
535
|
renderLayoutSpecialError(specialError, layoutIndex) {
|
|
496
536
|
return renderLayoutSpecialError(options, specialError, layoutIndex);
|
|
@@ -20,6 +20,8 @@ type AppPageBuildRoute<TModule extends AppPageModule = AppPageModule, TErrorModu
|
|
|
20
20
|
type AppPageInterceptOptions<TModule extends AppPageModule = AppPageModule> = {
|
|
21
21
|
interceptionContext?: string | null;
|
|
22
22
|
interceptLayouts?: readonly (TModule | null | undefined)[] | null;
|
|
23
|
+
interceptLayoutSegments?: readonly (readonly string[])[] | null;
|
|
24
|
+
interceptBranchSegments?: readonly string[] | null;
|
|
23
25
|
interceptPage?: TModule | null;
|
|
24
26
|
interceptParams?: AppPageParams | null;
|
|
25
27
|
interceptSlotId?: string | null;
|
|
@@ -33,7 +35,9 @@ type AppPagePageRequest<TModule extends AppPageModule = AppPageModule> = {
|
|
|
33
35
|
isRscRequest: boolean; /** The incoming HTTP request (available but unused by this module). */
|
|
34
36
|
request: Request; /** Normalized x-vinext-mounted-slots header value. */
|
|
35
37
|
mountedSlotsHeader: string | null; /** Semantic RSC payload mode for this page render. */
|
|
36
|
-
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;
|
|
37
41
|
};
|
|
38
42
|
type BuildPageElementsOptions<TModule extends AppPageModule = AppPageModule, TErrorModule extends AppPageErrorModule = AppPageErrorModule> = {
|
|
39
43
|
applyFileBasedMetadata?: ApplyAppPageFileBasedMetadata;
|
|
@@ -1,17 +1,27 @@
|
|
|
1
|
-
import { matchRoutePattern } from "../routing/route-pattern.js";
|
|
2
1
|
import { AppElementsWire } from "./app-elements-wire.js";
|
|
3
|
-
import { APP_RSC_RENDER_MODE_NAVIGATION
|
|
2
|
+
import { APP_RSC_RENDER_MODE_NAVIGATION } from "./app-rsc-render-mode.js";
|
|
4
3
|
import "./app-elements.js";
|
|
5
4
|
import { createAppPageRenderIdentity } from "./app-page-render-identity.js";
|
|
5
|
+
import { matchRoutePattern } from "../routing/route-pattern.js";
|
|
6
6
|
import { makeThenableParams } from "../shims/thenable-params.js";
|
|
7
|
+
import { resolveAppPageBranchParams } from "./app-page-params.js";
|
|
7
8
|
import { resolveActiveParallelRouteHeadInputs, resolveAppPageHead } from "./app-page-head.js";
|
|
8
|
-
import { makeObservedAppPageSearchParamsThenable } from "./app-page-search-params-observation.js";
|
|
9
|
+
import { createAppPageSearchParamsObserver, makeObservedAppPageSearchParamsThenable } from "./app-page-search-params-observation.js";
|
|
9
10
|
import { buildAppPageElements, createAppPageSourcePage, createAppPageTreePath } from "./app-page-route-wiring.js";
|
|
10
11
|
import { DEFAULT_GLOBAL_ERROR_MODULE } from "./default-global-error-module.js";
|
|
11
12
|
import "./app-rsc-route-matching.js";
|
|
12
13
|
import { shouldServeStreamingMetadata } from "./streaming-metadata.js";
|
|
13
14
|
import { createElement } from "react";
|
|
14
15
|
//#region src/server/app-page-element-builder.ts
|
|
16
|
+
function resolveInterceptLayoutParams(branchSegments, layoutSegments, params) {
|
|
17
|
+
return resolveAppPageBranchParams(branchSegments, layoutSegments.length, params, layoutSegments);
|
|
18
|
+
}
|
|
19
|
+
const REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference");
|
|
20
|
+
function isReactOwnedPageComponent(component) {
|
|
21
|
+
if (typeof component !== "function") return true;
|
|
22
|
+
const candidate = component;
|
|
23
|
+
return candidate.$$typeof === REACT_CLIENT_REFERENCE || candidate.prototype?.isReactComponent != null;
|
|
24
|
+
}
|
|
15
25
|
/**
|
|
16
26
|
* Build the App Router element tree for a matched route.
|
|
17
27
|
*
|
|
@@ -30,7 +40,8 @@ import { createElement } from "react";
|
|
|
30
40
|
*/
|
|
31
41
|
async function buildPageElements(options) {
|
|
32
42
|
const { route, params, routePath, displayPathname = routePath, pageRequest, globalErrorModule, rootNotFoundModule, rootForbiddenModule, rootUnauthorizedModule, metadataRoutes } = options;
|
|
33
|
-
const
|
|
43
|
+
const slotParamOverrides = resolveSlotParamOverrides(route, routePath);
|
|
44
|
+
const { opts, searchParams, isRscRequest, mountedSlotsHeader, renderMode = APP_RSC_RENDER_MODE_NAVIGATION, observeMetadataSearchParamsAccess = false, observePageSearchParamsAccess = false } = pageRequest;
|
|
34
45
|
const pageModule = route.page;
|
|
35
46
|
const isSiblingIntercept = opts?.interceptSlotKey === "__vinext_page_intercept" && !!opts?.interceptPage;
|
|
36
47
|
const effectivePageModule = isSiblingIntercept ? opts.interceptPage : pageModule;
|
|
@@ -40,6 +51,7 @@ async function buildPageElements(options) {
|
|
|
40
51
|
const hasPageModule = !!pageModule;
|
|
41
52
|
const renderIdentity = createAppPageRenderIdentity({
|
|
42
53
|
displayPathname,
|
|
54
|
+
targetMatchedPathname: routePath,
|
|
43
55
|
interceptionContext: opts?.interceptionContext ?? null,
|
|
44
56
|
interceptSourceMatchedUrl: opts?.interceptSourceMatchedUrl ?? null,
|
|
45
57
|
interceptSlotId: isSiblingIntercept ? null : opts?.interceptSlotId ?? null
|
|
@@ -69,40 +81,63 @@ async function buildPageElements(options) {
|
|
|
69
81
|
layoutModules: route.layouts,
|
|
70
82
|
layoutTreePositions: route.layoutTreePositions,
|
|
71
83
|
metadataRoutes,
|
|
72
|
-
pageModule: effectivePageModule ?? null,
|
|
73
|
-
parallelRoutes: resolveActiveParallelRouteHeadInputs({
|
|
84
|
+
pageModule: isSiblingIntercept ? null : effectivePageModule ?? null,
|
|
85
|
+
parallelRoutes: [...resolveActiveParallelRouteHeadInputs({
|
|
86
|
+
interceptBranchSegments: opts?.interceptBranchSegments ?? null,
|
|
74
87
|
interceptLayouts: opts?.interceptLayouts ?? null,
|
|
88
|
+
interceptLayoutSegments: opts?.interceptLayoutSegments ?? null,
|
|
75
89
|
interceptPage: opts?.interceptPage ?? null,
|
|
76
90
|
interceptParams: opts?.interceptParams ?? null,
|
|
77
91
|
interceptSlotKey: opts?.interceptSlotKey ?? null,
|
|
92
|
+
layoutTreePositions: route.layoutTreePositions,
|
|
78
93
|
params,
|
|
79
94
|
routeSegments: route.routeSegments ?? [],
|
|
95
|
+
slotParams: slotParamOverrides,
|
|
80
96
|
slots: route.slots ?? null
|
|
81
|
-
}),
|
|
97
|
+
}), ...isSiblingIntercept ? [{
|
|
98
|
+
layoutModules: opts?.interceptLayouts ?? [],
|
|
99
|
+
layoutParams: (opts?.interceptLayoutSegments ?? []).map((segments) => resolveInterceptLayoutParams(opts?.interceptBranchSegments ?? segments, segments, effectiveParams)),
|
|
100
|
+
pageModule: effectivePageModule ?? null,
|
|
101
|
+
params: effectiveParams,
|
|
102
|
+
routeSegments: opts?.interceptSourcePageSegments ?? route.routeSegments ?? []
|
|
103
|
+
}] : []],
|
|
82
104
|
params: effectiveParams,
|
|
83
105
|
routePath: route.pattern,
|
|
84
106
|
routeSegments: route.routeSegments ?? null,
|
|
85
|
-
searchParams
|
|
107
|
+
searchParams,
|
|
108
|
+
searchParamsObserver: observeMetadataSearchParamsAccess ? createAppPageSearchParamsObserver() : void 0
|
|
86
109
|
});
|
|
87
110
|
const pageProps = { params: makeThenableParams(effectiveParams) };
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
111
|
+
const hasRequestSearchParams = Object.keys(pageSearchParams).length > 0;
|
|
112
|
+
const createPageElement = (PageComponent, props) => {
|
|
113
|
+
if (isReactOwnedPageComponent(PageComponent)) {
|
|
114
|
+
const invocationProps = { ...props };
|
|
115
|
+
if (searchParams) invocationProps.searchParams = observePageSearchParamsAccess ? makeObservedAppPageSearchParamsThenable(pageSearchParams, { markDynamic: hasRequestSearchParams }) : makeThenableParams(pageSearchParams);
|
|
116
|
+
return createElement(PageComponent, invocationProps);
|
|
117
|
+
}
|
|
118
|
+
const ServerPageComponent = PageComponent;
|
|
119
|
+
const PageInvoker = () => {
|
|
120
|
+
const invocationProps = { ...props };
|
|
121
|
+
if (searchParams) invocationProps.searchParams = observePageSearchParamsAccess ? makeObservedAppPageSearchParamsThenable(pageSearchParams) : makeThenableParams(pageSearchParams);
|
|
122
|
+
return ServerPageComponent(invocationProps);
|
|
123
|
+
};
|
|
124
|
+
return createElement(PageInvoker);
|
|
125
|
+
};
|
|
126
|
+
const pageSearchParamsThenable = searchParams ? makeThenableParams(pageSearchParams) : void 0;
|
|
93
127
|
const mountedSlotIds = mountedSlotsHeader ? new Set(mountedSlotsHeader.split(" ")) : null;
|
|
94
128
|
const slotOverrides = buildSlotOverrides(route, params, routePath, opts);
|
|
95
129
|
const metadataPlacement = hasDynamicMetadata && shouldServeStreamingMetadata(pageRequest.request.headers.get("user-agent") ?? "", options.htmlLimitedBots) ? "body" : "head";
|
|
96
|
-
let siblingInterceptElement = isSiblingIntercept && EffectivePageComponent ?
|
|
97
|
-
if (isSiblingIntercept && siblingInterceptElement !== null && opts?.interceptLayouts?.length) {
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
const
|
|
101
|
-
|
|
130
|
+
let siblingInterceptElement = isSiblingIntercept && EffectivePageComponent ? createPageElement(EffectivePageComponent, pageProps) : null;
|
|
131
|
+
if (isSiblingIntercept && siblingInterceptElement !== null && opts?.interceptLayouts?.length) for (let i = opts.interceptLayouts.length - 1; i >= 0; i--) {
|
|
132
|
+
const LayoutComponent = opts.interceptLayouts[i]?.default;
|
|
133
|
+
if (LayoutComponent) {
|
|
134
|
+
const interceptLayoutSegments = opts.interceptLayoutSegments?.[i] ?? [];
|
|
135
|
+
siblingInterceptElement = createElement(LayoutComponent, { params: makeThenableParams(resolveInterceptLayoutParams(opts.interceptBranchSegments ?? interceptLayoutSegments, interceptLayoutSegments, effectiveParams)) }, siblingInterceptElement);
|
|
102
136
|
}
|
|
103
137
|
}
|
|
104
138
|
return buildAppPageElements({
|
|
105
|
-
element: isSiblingIntercept ? siblingInterceptElement : EffectivePageComponent ?
|
|
139
|
+
element: isSiblingIntercept ? siblingInterceptElement : EffectivePageComponent ? createPageElement(EffectivePageComponent, pageProps) : null,
|
|
140
|
+
createPageElement,
|
|
106
141
|
globalErrorModule: globalErrorModule ?? DEFAULT_GLOBAL_ERROR_MODULE,
|
|
107
142
|
isRscRequest,
|
|
108
143
|
layoutParamAccess: options.layoutParamAccess,
|
|
@@ -143,7 +178,9 @@ async function buildPageElements(options) {
|
|
|
143
178
|
function buildSlotOverrides(route, routeParams, routePath, opts) {
|
|
144
179
|
const overrides = {};
|
|
145
180
|
if (opts && opts.interceptSlotKey && opts.interceptPage && opts.interceptSlotKey !== "__vinext_page_intercept") overrides[opts.interceptSlotKey] = {
|
|
181
|
+
branchSegments: opts.interceptBranchSegments ?? null,
|
|
146
182
|
layoutModules: opts.interceptLayouts || null,
|
|
183
|
+
layoutSegments: opts.interceptLayoutSegments ?? null,
|
|
147
184
|
pageModule: opts.interceptPage,
|
|
148
185
|
params: opts.interceptParams || routeParams
|
|
149
186
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { MetadataFileRoute } from "./metadata-routes.js";
|
|
2
2
|
import { AppPageParams } from "./app-page-boundary.js";
|
|
3
|
+
import { ThenableParamsObserver } from "../shims/thenable-params.js";
|
|
3
4
|
import { Metadata, Viewport } from "../shims/metadata.js";
|
|
4
5
|
import { applyFileBasedMetadata } from "./file-based-metadata.js";
|
|
5
6
|
|
|
@@ -8,23 +9,33 @@ type AppPageSearchParams = Record<string, string | string[]>;
|
|
|
8
9
|
type AppPageHeadModule = Record<string, unknown>;
|
|
9
10
|
type ApplyAppPageFileBasedMetadata = typeof applyFileBasedMetadata;
|
|
10
11
|
type AppPageHeadParallelRoute<TModule extends AppPageHeadModule = AppPageHeadModule> = {
|
|
12
|
+
layoutParams?: readonly AppPageParams[] | null;
|
|
11
13
|
layoutModule?: TModule | null;
|
|
12
14
|
layoutModules?: readonly (TModule | null | undefined)[] | null;
|
|
15
|
+
layoutTreePositions?: readonly number[] | null;
|
|
13
16
|
pageModule?: TModule | null;
|
|
14
17
|
params?: AppPageParams | null;
|
|
15
18
|
routeSegments?: readonly string[] | null;
|
|
16
19
|
};
|
|
17
20
|
type AppPageHeadSlot<TModule extends AppPageHeadModule = AppPageHeadModule> = {
|
|
21
|
+
configLayouts?: readonly (TModule | null | undefined)[] | null;
|
|
22
|
+
configLayoutTreePositions?: readonly number[] | null;
|
|
18
23
|
layout?: TModule | null;
|
|
24
|
+
layoutIndex?: number;
|
|
19
25
|
page?: TModule | null;
|
|
26
|
+
routeSegments?: readonly string[] | null;
|
|
20
27
|
};
|
|
21
28
|
type ResolveActiveParallelRouteHeadInputsOptions<TModule extends AppPageHeadModule = AppPageHeadModule> = {
|
|
22
29
|
interceptLayouts?: readonly (TModule | null | undefined)[] | null;
|
|
30
|
+
interceptBranchSegments?: readonly string[] | null;
|
|
31
|
+
interceptLayoutSegments?: readonly (readonly string[])[] | null;
|
|
23
32
|
interceptPage?: TModule | null;
|
|
24
33
|
interceptParams?: AppPageParams | null;
|
|
25
34
|
interceptSlotKey?: string | null;
|
|
35
|
+
layoutTreePositions?: readonly number[] | null;
|
|
26
36
|
params: AppPageParams;
|
|
27
37
|
routeSegments: readonly string[];
|
|
38
|
+
slotParams?: Readonly<Record<string, AppPageParams>> | null;
|
|
28
39
|
slots?: Record<string, AppPageHeadSlot<TModule>> | null;
|
|
29
40
|
};
|
|
30
41
|
type ResolveAppPageHeadOptions<TModule extends AppPageHeadModule = AppPageHeadModule> = {
|
|
@@ -46,6 +57,7 @@ type ResolveAppPageHeadOptions<TModule extends AppPageHeadModule = AppPageHeadMo
|
|
|
46
57
|
routePath: string;
|
|
47
58
|
routeSegments?: readonly string[] | null;
|
|
48
59
|
searchParams?: URLSearchParams | null;
|
|
60
|
+
searchParamsObserver?: ThenableParamsObserver;
|
|
49
61
|
};
|
|
50
62
|
type ResolveAppPageHeadResult = {
|
|
51
63
|
hasDynamicMetadata: boolean;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { runWithFetchDedupe } from "../shims/fetch-cache.js";
|
|
2
2
|
import { mergeMetadataEntries, mergeViewport, postProcessMetadata, resolveModuleMetadata as resolveModuleMetadata$1, resolveModuleViewport } from "../shims/metadata.js";
|
|
3
|
-
import { resolveAppPageSegmentParams } from "./app-page-params.js";
|
|
3
|
+
import { resolveAppPageBranchParams, resolveAppPageSegmentParams } from "./app-page-params.js";
|
|
4
4
|
import { tagAppPageMetadataError } from "./app-page-execution.js";
|
|
5
5
|
//#region src/server/app-page-head.ts
|
|
6
6
|
/**
|
|
@@ -24,23 +24,44 @@ async function resolveModuleMetadata(...args) {
|
|
|
24
24
|
}
|
|
25
25
|
function resolveActiveParallelRouteHeadInputs(options) {
|
|
26
26
|
return Object.entries(options.slots ?? {}).map(([slotKey, slot]) => {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
27
|
+
const ownerTreePosition = options.layoutTreePositions?.[slot.layoutIndex ?? 0] ?? 0;
|
|
28
|
+
const ownerParams = resolveAppPageSegmentParams(options.routeSegments, ownerTreePosition, options.params);
|
|
29
|
+
if (options.interceptSlotKey === slotKey && options.interceptPage) {
|
|
30
|
+
const interceptLayouts = options.interceptLayouts ?? [];
|
|
31
|
+
return {
|
|
32
|
+
layoutModules: [slot.layout, ...interceptLayouts].filter(isPresent),
|
|
33
|
+
layoutParams: [...slot.layout ? [ownerParams] : [], ...interceptLayouts.filter(isPresent).map((_, index) => {
|
|
34
|
+
const segments = options.interceptLayoutSegments?.[index] ?? [];
|
|
35
|
+
return {
|
|
36
|
+
...ownerParams,
|
|
37
|
+
...resolveParallelLayoutParams(options.interceptBranchSegments ?? segments, segments.length, options.interceptParams ?? options.params)
|
|
38
|
+
};
|
|
39
|
+
})],
|
|
40
|
+
layoutTreePositions: [...slot.layout ? [0] : [], ...interceptLayouts.filter(isPresent).map(() => options.routeSegments.length)],
|
|
41
|
+
pageModule: options.interceptPage,
|
|
42
|
+
params: options.interceptParams ?? options.params,
|
|
43
|
+
routeSegments: options.routeSegments
|
|
44
|
+
};
|
|
45
|
+
}
|
|
33
46
|
return {
|
|
34
|
-
layoutModules: slot.layout
|
|
47
|
+
layoutModules: [slot.layout, ...slot.configLayouts ?? []].filter(isPresent),
|
|
48
|
+
layoutParams: [...slot.layout ? [ownerParams] : [], ...(slot.configLayoutTreePositions ?? []).map((treePosition) => ({
|
|
49
|
+
...ownerParams,
|
|
50
|
+
...resolveParallelLayoutParams(slot.routeSegments ?? options.routeSegments, treePosition, options.slotParams?.[slotKey] ?? options.params)
|
|
51
|
+
}))],
|
|
52
|
+
layoutTreePositions: [...slot.layout ? [0] : [], ...slot.configLayoutTreePositions ?? []],
|
|
35
53
|
pageModule: slot.page,
|
|
36
|
-
params: options.params,
|
|
37
|
-
routeSegments: options.routeSegments
|
|
54
|
+
params: options.slotParams?.[slotKey] ?? options.params,
|
|
55
|
+
routeSegments: slot.routeSegments ?? options.routeSegments
|
|
38
56
|
};
|
|
39
57
|
});
|
|
40
58
|
}
|
|
41
59
|
function isPresent(value) {
|
|
42
60
|
return value !== null && value !== void 0;
|
|
43
61
|
}
|
|
62
|
+
function resolveParallelLayoutParams(routeSegments, treePosition, params) {
|
|
63
|
+
return resolveAppPageBranchParams(routeSegments, treePosition, params);
|
|
64
|
+
}
|
|
44
65
|
function hasGenerateMetadata(module) {
|
|
45
66
|
return typeof module?.generateMetadata === "function";
|
|
46
67
|
}
|
|
@@ -111,7 +132,7 @@ async function resolveLayoutViewport(layoutInputs, params, routeSegments) {
|
|
|
111
132
|
return resolveModuleViewport(layoutInput.module, layoutParams);
|
|
112
133
|
}));
|
|
113
134
|
}
|
|
114
|
-
async function resolveParallelRouteHead(parallelRoute, fallbackParams, fallbackRouteSegments, pageSearchParams, parent) {
|
|
135
|
+
async function resolveParallelRouteHead(parallelRoute, fallbackParams, fallbackRouteSegments, pageSearchParams, parent, searchParamsObserver) {
|
|
115
136
|
const params = parallelRoute.params ?? fallbackParams;
|
|
116
137
|
const routeSegments = parallelRoute.routeSegments ?? fallbackRouteSegments;
|
|
117
138
|
const metadataResults = [];
|
|
@@ -119,13 +140,15 @@ async function resolveParallelRouteHead(parallelRoute, fallbackParams, fallbackR
|
|
|
119
140
|
const metadataSources = [];
|
|
120
141
|
let accumulatedMetadata = parent;
|
|
121
142
|
const layoutModules = [...parallelRoute.layoutModules ?? [], parallelRoute.layoutModule].filter(isPresent);
|
|
143
|
+
const layoutTreePositions = parallelRoute.layoutTreePositions ?? [];
|
|
144
|
+
const layoutParams = parallelRoute.layoutParams ?? [];
|
|
122
145
|
const hasDynamicMetadata = layoutModules.some(hasGenerateMetadata) || hasGenerateMetadata(parallelRoute.pageModule);
|
|
123
|
-
const layoutViewportPromises = layoutModules.map((layoutModule) => resolveModuleViewport(layoutModule, params));
|
|
124
|
-
const pageViewportPromise = parallelRoute.pageModule ? resolveModuleViewport(parallelRoute.pageModule, params) : Promise.resolve(null);
|
|
146
|
+
const layoutViewportPromises = layoutModules.map((layoutModule, index) => resolveModuleViewport(layoutModule, layoutParams[index] ?? resolveParallelLayoutParams(routeSegments, layoutTreePositions[index] ?? 0, params)));
|
|
147
|
+
const pageViewportPromise = parallelRoute.pageModule ? resolveModuleViewport(parallelRoute.pageModule, params, pageSearchParams, searchParamsObserver) : Promise.resolve(null);
|
|
125
148
|
for (const layoutViewportPromise of layoutViewportPromises) layoutViewportPromise.catch(() => null);
|
|
126
149
|
pageViewportPromise.catch(() => null);
|
|
127
|
-
for (const layoutModule of layoutModules) {
|
|
128
|
-
const layoutMetadata = await resolveModuleMetadata(layoutModule, params, void 0, accumulatedMetadata);
|
|
150
|
+
for (const [index, layoutModule] of layoutModules.entries()) {
|
|
151
|
+
const layoutMetadata = await resolveModuleMetadata(layoutModule, layoutParams[index] ?? resolveParallelLayoutParams(routeSegments, layoutTreePositions[index] ?? 0, params), void 0, accumulatedMetadata);
|
|
129
152
|
metadataResults.push(layoutMetadata);
|
|
130
153
|
metadataSources.push({
|
|
131
154
|
metadata: layoutMetadata,
|
|
@@ -137,7 +160,7 @@ async function resolveParallelRouteHead(parallelRoute, fallbackParams, fallbackR
|
|
|
137
160
|
}
|
|
138
161
|
}
|
|
139
162
|
if (parallelRoute.pageModule) {
|
|
140
|
-
const pageMetadata = await resolveModuleMetadata(parallelRoute.pageModule, params, pageSearchParams, accumulatedMetadata);
|
|
163
|
+
const pageMetadata = await resolveModuleMetadata(parallelRoute.pageModule, params, pageSearchParams, accumulatedMetadata, searchParamsObserver);
|
|
141
164
|
metadataResults.push(pageMetadata);
|
|
142
165
|
metadataSources.push({
|
|
143
166
|
metadata: pageMetadata,
|
|
@@ -170,9 +193,9 @@ async function resolveAppPageHeadInner(options) {
|
|
|
170
193
|
layoutMetadataResultsForParent.catch(() => null);
|
|
171
194
|
const pageParentPromise = layoutMetadataResultsForParent.then((metadataResults) => metadataResults.length > 0 ? mergeMetadataEntries(metadataResults.map((metadata) => ({ metadata }))) : {});
|
|
172
195
|
pageParentPromise.catch(() => null);
|
|
173
|
-
const pageMetadataPromise = options.pageModule ? resolveModuleMetadata(options.pageModule, options.params, pageSearchParams, pageParentPromise) : Promise.resolve(null);
|
|
174
|
-
const pageViewportPromise = options.pageModule ? resolveModuleViewport(options.pageModule, options.params) : Promise.resolve(null);
|
|
175
|
-
const parallelRouteHeadPromise = Promise.all((options.parallelRoutes ?? []).map((parallelRoute) => resolveParallelRouteHead(parallelRoute, options.params, routeSegments, pageSearchParams, pageParentPromise)));
|
|
196
|
+
const pageMetadataPromise = options.pageModule ? resolveModuleMetadata(options.pageModule, options.params, pageSearchParams, pageParentPromise, options.searchParamsObserver) : Promise.resolve(null);
|
|
197
|
+
const pageViewportPromise = options.pageModule ? resolveModuleViewport(options.pageModule, options.params, pageSearchParams, options.searchParamsObserver) : Promise.resolve(null);
|
|
198
|
+
const parallelRouteHeadPromise = Promise.all((options.parallelRoutes ?? []).map((parallelRoute) => resolveParallelRouteHead(parallelRoute, options.params, routeSegments, pageSearchParams, pageParentPromise, options.searchParamsObserver)));
|
|
176
199
|
const [layoutMetadataResults, layoutViewportResults, pageMetadata, pageViewport, parallelRouteHeads] = await Promise.all([
|
|
177
200
|
layoutMetadataPromise,
|
|
178
201
|
layoutViewportPromise,
|
|
@@ -4,5 +4,6 @@ import { AppPageParams } from "./app-page-boundary.js";
|
|
|
4
4
|
declare function getAppPageSegmentParamName(segment: string): string | null;
|
|
5
5
|
declare function resolveAppPageSegmentParamScopeKeys(routeSegments: readonly string[] | null | undefined, treePosition: number): readonly string[];
|
|
6
6
|
declare function resolveAppPageSegmentParams(routeSegments: readonly string[] | null | undefined, treePosition: number, matchedParams: AppPageParams): AppPageParams;
|
|
7
|
+
declare function resolveAppPageBranchParams(branchSegments: readonly string[], treePosition: number, matchedParams: AppPageParams, scopedSegments?: readonly string[]): AppPageParams;
|
|
7
8
|
//#endregion
|
|
8
|
-
export { getAppPageSegmentParamName, resolveAppPageSegmentParamScopeKeys, resolveAppPageSegmentParams };
|
|
9
|
+
export { getAppPageSegmentParamName, resolveAppPageBranchParams, resolveAppPageSegmentParamScopeKeys, resolveAppPageSegmentParams };
|
|
@@ -35,5 +35,12 @@ function resolveAppPageSegmentParams(routeSegments, treePosition, matchedParams)
|
|
|
35
35
|
}
|
|
36
36
|
return segmentParams;
|
|
37
37
|
}
|
|
38
|
+
function resolveAppPageBranchParams(branchSegments, treePosition, matchedParams, scopedSegments = branchSegments) {
|
|
39
|
+
const branchParamNames = new Set(branchSegments.map(getAppPageSegmentParamName).filter((name) => name !== null));
|
|
40
|
+
const scopedParams = {};
|
|
41
|
+
for (const [name, value] of Object.entries(matchedParams)) if (!branchParamNames.has(name)) scopedParams[name] = value;
|
|
42
|
+
Object.assign(scopedParams, resolveAppPageSegmentParams(scopedSegments, treePosition, matchedParams));
|
|
43
|
+
return scopedParams;
|
|
44
|
+
}
|
|
38
45
|
//#endregion
|
|
39
|
-
export { getAppPageSegmentParamName, resolveAppPageSegmentParamScopeKeys, resolveAppPageSegmentParams };
|
|
46
|
+
export { getAppPageSegmentParamName, resolveAppPageBranchParams, resolveAppPageSegmentParamScopeKeys, resolveAppPageSegmentParams };
|
|
@@ -119,6 +119,7 @@ type ProbeAppPageBeforeRenderResult = {
|
|
|
119
119
|
};
|
|
120
120
|
type ProbeAppPageBeforeRenderOptions = {
|
|
121
121
|
hasLoadingBoundary: boolean;
|
|
122
|
+
probePageBeforeRender?: boolean;
|
|
122
123
|
skipProbes?: boolean;
|
|
123
124
|
layoutCount: number;
|
|
124
125
|
probeLayoutAt: (layoutIndex: number) => unknown;
|
|
@@ -12,6 +12,7 @@ const DEFAULT_SUBTREE_PROBE_MAX_NODES = 1e3;
|
|
|
12
12
|
const REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref");
|
|
13
13
|
const REACT_LAZY_TYPE = Symbol.for("react.lazy");
|
|
14
14
|
const REACT_MEMO_TYPE = Symbol.for("react.memo");
|
|
15
|
+
const REACT_CLIENT_REFERENCE_TYPE = Symbol.for("react.client.reference");
|
|
15
16
|
var AppPageSubtreeProbeLimitError = class extends Error {
|
|
16
17
|
constructor(message) {
|
|
17
18
|
super(message);
|
|
@@ -36,6 +37,9 @@ function isObjectLike(value) {
|
|
|
36
37
|
function isUnknownFunction(value) {
|
|
37
38
|
return typeof value === "function";
|
|
38
39
|
}
|
|
40
|
+
function isReactClientReference(value) {
|
|
41
|
+
return isObjectLike(value) && Reflect.get(value, "$$typeof") === REACT_CLIENT_REFERENCE_TYPE;
|
|
42
|
+
}
|
|
39
43
|
function readReactMemoType(value) {
|
|
40
44
|
if (!isObjectLike(value) || Reflect.get(value, "$$typeof") !== REACT_MEMO_TYPE) return null;
|
|
41
45
|
return { innerType: Reflect.get(value, "type") };
|
|
@@ -80,6 +84,7 @@ async function probeReactServerSubtree(node, options = {}) {
|
|
|
80
84
|
};
|
|
81
85
|
const renderElementType = async (type, props, depth, wrapperDepth = 0) => {
|
|
82
86
|
if (wrapperDepth > maxDepth) throw new AppPageSubtreeProbeLimitError("App page layout subtree probe exceeded max depth");
|
|
87
|
+
if (isReactClientReference(type)) return false;
|
|
83
88
|
if (isUnknownFunction(type)) {
|
|
84
89
|
await visit(type(props), depth + 1);
|
|
85
90
|
return true;
|
|
@@ -252,7 +257,7 @@ async function probeAppPageBeforeRender(options) {
|
|
|
252
257
|
layoutFlags
|
|
253
258
|
};
|
|
254
259
|
}
|
|
255
|
-
if (options.hasLoadingBoundary) return {
|
|
260
|
+
if (options.hasLoadingBoundary || options.probePageBeforeRender === false) return {
|
|
256
261
|
response: null,
|
|
257
262
|
layoutFlags
|
|
258
263
|
};
|
|
@@ -2,6 +2,7 @@ import { AppElementsInterception } from "./app-elements-wire.js";
|
|
|
2
2
|
//#region src/server/app-page-render-identity.d.ts
|
|
3
3
|
type AppPageRenderIdentityInput = {
|
|
4
4
|
displayPathname: string;
|
|
5
|
+
targetMatchedPathname?: string;
|
|
5
6
|
interceptionContext?: string | null;
|
|
6
7
|
interceptSourceMatchedUrl?: string | null;
|
|
7
8
|
interceptSlotId?: string | null;
|
|
@@ -13,7 +13,7 @@ function normalizeAppPageInterceptionProofPathname(pathname) {
|
|
|
13
13
|
}
|
|
14
14
|
function createAppPageRenderIdentity(input) {
|
|
15
15
|
const interceptionContext = input.interceptionContext ?? null;
|
|
16
|
-
const targetMatchedPathname = normalizeAppPageRenderMatchedPathname(input.displayPathname);
|
|
16
|
+
const targetMatchedPathname = normalizeAppPageRenderMatchedPathname(input.targetMatchedPathname ?? input.displayPathname);
|
|
17
17
|
const sourceMatchedPathname = normalizeAppPageInterceptionProofPathname(input.interceptSourceMatchedUrl ?? null);
|
|
18
18
|
const slotId = input.interceptSlotId ?? null;
|
|
19
19
|
const matchedRoutePathname = sourceMatchedPathname ?? targetMatchedPathname;
|
|
@@ -37,6 +37,7 @@ type RenderAppPageLifecycleOptions = {
|
|
|
37
37
|
cleanPathname: string;
|
|
38
38
|
clearRequestContext: () => void;
|
|
39
39
|
consumeDynamicUsage: () => boolean;
|
|
40
|
+
peekDynamicUsage?: () => boolean;
|
|
40
41
|
consumeRenderObservationState?: () => AppPageRenderObservationState; /** Read and clear any invalid dynamic usage error recorded during render (dev-only). */
|
|
41
42
|
consumeInvalidDynamicUsageError?: () => unknown;
|
|
42
43
|
createRscOnErrorHandler: (pathname: string, routePath: string) => AppPageBoundaryOnError;
|
|
@@ -60,6 +61,8 @@ type RenderAppPageLifecycleOptions = {
|
|
|
60
61
|
isProgressiveActionRender?: boolean;
|
|
61
62
|
isPrerender?: boolean;
|
|
62
63
|
isProduction: boolean;
|
|
64
|
+
probePageBeforeRender?: boolean;
|
|
65
|
+
omitPendingDynamicCacheState?: boolean;
|
|
63
66
|
isRscRequest: boolean;
|
|
64
67
|
isrDebug?: AppPageDebugLogger;
|
|
65
68
|
isrHtmlKey: (pathname: string) => string;
|
|
@@ -81,7 +84,7 @@ type RenderAppPageLifecycleOptions = {
|
|
|
81
84
|
expireSeconds?: number;
|
|
82
85
|
formState?: ReactFormState | null;
|
|
83
86
|
revalidateSeconds: number | null;
|
|
84
|
-
renderErrorBoundaryResponse: (error: unknown) => Promise<Response | null>;
|
|
87
|
+
renderErrorBoundaryResponse: (error: unknown, errorOrigin: "rsc" | "ssr") => Promise<Response | null>;
|
|
85
88
|
renderLayoutSpecialError: (specialError: AppPageSpecialError, layoutIndex: number) => Promise<Response>;
|
|
86
89
|
renderPageSpecialError: (specialError: AppPageSpecialError) => Promise<Response>;
|
|
87
90
|
renderToReadableStream: (element: ReactNode | AppOutgoingElements, options: {
|