vinext 0.1.7 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +51 -30
- package/dist/build/inject-pregenerated-paths.d.ts +4 -0
- package/dist/build/inject-pregenerated-paths.js +18 -0
- package/dist/build/layout-classification.js +1 -1
- package/dist/build/nitro-route-rules.js +1 -1
- package/dist/build/pages-client-assets-module.d.ts +11 -0
- package/dist/build/pages-client-assets-module.js +27 -0
- package/dist/build/prerender.d.ts +2 -1
- package/dist/build/prerender.js +13 -6
- package/dist/build/report.d.ts +13 -2
- package/dist/build/report.js +99 -2
- package/dist/build/run-prerender.d.ts +7 -0
- package/dist/build/run-prerender.js +10 -1
- package/dist/build/standalone.js +2 -0
- package/dist/cache/cache-adapters-virtual.js +3 -3
- package/dist/check.d.ts +18 -0
- package/dist/check.js +77 -19
- package/dist/cli-args.d.ts +1 -2
- package/dist/cli-args.js +1 -1
- package/dist/cli-dev-config.d.ts +12 -0
- package/dist/cli-dev-config.js +23 -0
- package/dist/cli.js +113 -97
- package/dist/{server → client}/dev-error-overlay-store.d.ts +1 -1
- package/dist/{server → client}/dev-error-overlay-store.js +1 -1
- package/dist/{server → client}/dev-error-overlay.d.ts +1 -1
- package/dist/{server → client}/dev-error-overlay.js +2 -2
- package/dist/client/navigation-runtime.d.ts +2 -0
- package/dist/client/navigation-runtime.js +3 -1
- package/dist/client/window-next.d.ts +2 -1
- package/dist/cloudflare/index.d.ts +2 -2
- package/dist/cloudflare/index.js +2 -2
- package/dist/config/config-matchers.js +14 -10
- package/dist/config/next-config.d.ts +6 -3
- package/dist/config/next-config.js +47 -1
- package/dist/config/prerender.d.ts +34 -0
- package/dist/config/prerender.js +55 -0
- package/dist/config/server-external-packages.d.ts +4 -0
- package/dist/config/server-external-packages.js +91 -0
- package/dist/entries/app-rsc-entry.d.ts +2 -1
- package/dist/entries/app-rsc-entry.js +89 -15
- package/dist/entries/app-rsc-manifest.js +10 -0
- package/dist/entries/pages-client-entry.d.ts +3 -0
- package/dist/entries/pages-client-entry.js +16 -1
- package/dist/entries/pages-server-entry.js +6 -2
- package/dist/image/image-adapters-virtual.d.ts +59 -0
- package/dist/image/image-adapters-virtual.js +59 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +211 -118
- package/dist/init-cloudflare.d.ts +43 -0
- package/dist/init-cloudflare.js +839 -0
- package/dist/init-platform.d.ts +40 -0
- package/dist/init-platform.js +195 -0
- package/dist/init.d.ts +16 -38
- package/dist/init.js +208 -97
- package/dist/node_modules/.pnpm/am-i-vibing@0.5.0/node_modules/am-i-vibing/dist/detector-1yx2Hoe0.js +294 -0
- package/dist/node_modules/.pnpm/process-ancestry@0.1.0/node_modules/process-ancestry/dist/index.js +94 -0
- package/dist/{cloudflare → packages/cloudflare}/src/cache/cdn-adapter.runtime.js +1 -1
- package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.d.ts +2 -2
- package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.js +1 -1
- package/dist/packages/cloudflare/src/deploy-config.js +150 -0
- package/dist/packages/cloudflare/src/deploy-help.js +55 -0
- package/dist/packages/cloudflare/src/deploy.js +276 -0
- package/dist/{cloudflare → packages/cloudflare/src}/tpr.d.ts +4 -41
- package/dist/{cloudflare → packages/cloudflare/src}/tpr.js +18 -15
- package/dist/plugins/ast-scope.d.ts +16 -0
- package/dist/plugins/ast-scope.js +62 -0
- package/dist/plugins/ast-utils.d.ts +27 -1
- package/dist/plugins/ast-utils.js +32 -1
- package/dist/plugins/css-module-imports.d.ts +14 -0
- package/dist/plugins/css-module-imports.js +59 -0
- package/dist/plugins/extensionless-dynamic-import.js +2 -2
- package/dist/plugins/ignore-dynamic-requests.d.ts +11 -0
- package/dist/plugins/ignore-dynamic-requests.js +530 -0
- package/dist/plugins/middleware-server-only.d.ts +8 -6
- package/dist/plugins/middleware-server-only.js +8 -7
- package/dist/plugins/optimize-imports.js +1 -1
- package/dist/plugins/typeof-window.d.ts +1 -1
- package/dist/plugins/typeof-window.js +28 -56
- package/dist/routing/app-route-graph.d.ts +29 -4
- package/dist/routing/app-route-graph.js +182 -40
- package/dist/routing/app-router.d.ts +5 -0
- package/dist/routing/app-router.js +5 -0
- package/dist/routing/file-matcher.d.ts +8 -0
- package/dist/routing/file-matcher.js +10 -1
- package/dist/routing/pages-router.js +2 -2
- package/dist/server/api-handler.js +9 -14
- package/dist/server/app-browser-action-result.d.ts +4 -1
- package/dist/server/app-browser-action-result.js +8 -1
- package/dist/server/app-browser-entry.js +194 -190
- package/dist/server/app-browser-history-controller.d.ts +2 -1
- package/dist/server/app-browser-history-controller.js +6 -2
- package/dist/server/app-browser-interception-context.d.ts +1 -0
- package/dist/server/app-browser-interception-context.js +4 -2
- package/dist/server/app-browser-navigation-controller.d.ts +2 -0
- package/dist/server/app-browser-navigation-controller.js +60 -31
- package/dist/server/app-browser-server-action-client.d.ts +32 -0
- package/dist/server/app-browser-server-action-client.js +127 -0
- package/dist/server/app-browser-state.d.ts +11 -1
- package/dist/server/app-browser-state.js +25 -8
- package/dist/server/app-browser-visible-commit.d.ts +6 -1
- package/dist/server/app-browser-visible-commit.js +43 -25
- package/dist/server/app-elements-wire.d.ts +9 -2
- package/dist/server/app-elements-wire.js +8 -1
- package/dist/server/app-elements.d.ts +2 -2
- package/dist/server/app-elements.js +4 -3
- package/dist/server/app-fallback-renderer.d.ts +5 -2
- package/dist/server/app-fallback-renderer.js +15 -7
- package/dist/server/app-hydration-cache-publication.d.ts +11 -0
- package/dist/server/app-hydration-cache-publication.js +43 -0
- package/dist/server/app-middleware.d.ts +4 -3
- package/dist/server/app-middleware.js +8 -3
- package/dist/server/app-optimistic-routing.js +11 -4
- package/dist/server/app-page-boundary-render.d.ts +3 -0
- package/dist/server/app-page-boundary-render.js +14 -3
- package/dist/server/app-page-cache-finalizer.d.ts +1 -0
- package/dist/server/app-page-cache-finalizer.js +10 -3
- package/dist/server/app-page-cache-render.d.ts +1 -0
- package/dist/server/app-page-cache-render.js +8 -4
- package/dist/server/app-page-cache.d.ts +1 -0
- package/dist/server/app-page-cache.js +5 -2
- package/dist/server/app-page-dispatch.d.ts +33 -4
- package/dist/server/app-page-dispatch.js +63 -90
- package/dist/server/app-page-element-builder.d.ts +9 -2
- package/dist/server/app-page-element-builder.js +114 -23
- package/dist/server/app-page-head.d.ts +16 -1
- package/dist/server/app-page-head.js +44 -22
- package/dist/server/app-page-params.d.ts +2 -1
- package/dist/server/app-page-params.js +8 -1
- package/dist/server/app-page-ppr-runtime.d.ts +7 -0
- package/dist/server/app-page-ppr-runtime.js +70 -0
- package/dist/server/app-page-probe.d.ts +1 -0
- package/dist/server/app-page-probe.js +6 -1
- package/dist/server/app-page-render-identity.d.ts +1 -0
- package/dist/server/app-page-render-identity.js +1 -1
- package/dist/server/app-page-render.d.ts +4 -1
- package/dist/server/app-page-render.js +26 -3
- package/dist/server/app-page-request.d.ts +22 -1
- package/dist/server/app-page-request.js +92 -15
- package/dist/server/app-page-route-wiring.d.ts +14 -2
- package/dist/server/app-page-route-wiring.js +61 -25
- package/dist/server/app-page-search-params-observation.d.ts +4 -2
- package/dist/server/app-page-search-params-observation.js +11 -7
- package/dist/server/app-page-segment-state.d.ts +2 -1
- package/dist/server/app-page-segment-state.js +3 -1
- package/dist/server/app-page-stream.d.ts +5 -0
- package/dist/server/app-page-stream.js +3 -1
- package/dist/server/app-ppr-fallback-shell-render.d.ts +4 -3
- package/dist/server/app-route-handler-dispatch.js +1 -0
- package/dist/server/app-route-handler-execution.js +7 -2
- package/dist/server/app-route-handler-response.js +1 -0
- package/dist/server/app-route-handler-runtime.js +1 -1
- package/dist/server/app-route-module-loader.d.ts +2 -0
- package/dist/server/app-route-module-loader.js +1 -0
- package/dist/server/app-router-entry.js +16 -8
- package/dist/server/app-rsc-errors.js +7 -1
- package/dist/server/app-rsc-handler.d.ts +3 -1
- package/dist/server/app-rsc-handler.js +67 -39
- package/dist/server/app-rsc-request-normalization.d.ts +3 -2
- package/dist/server/app-rsc-request-normalization.js +6 -3
- package/dist/server/app-rsc-route-matching.d.ts +7 -0
- package/dist/server/app-rsc-route-matching.js +36 -3
- package/dist/server/app-segment-config.d.ts +12 -0
- package/dist/server/app-segment-config.js +91 -5
- package/dist/server/app-server-action-execution.d.ts +5 -0
- package/dist/server/app-server-action-execution.js +94 -33
- package/dist/server/app-ssr-entry.d.ts +3 -0
- package/dist/server/app-ssr-entry.js +19 -8
- package/dist/server/app-ssr-stream.d.ts +7 -3
- package/dist/server/app-ssr-stream.js +10 -6
- package/dist/server/app-static-generation.d.ts +1 -0
- package/dist/server/app-static-generation.js +1 -0
- package/dist/server/app-visited-response-cache.d.ts +6 -0
- package/dist/server/app-visited-response-cache.js +3 -1
- package/dist/server/client-trace-metadata.js +26 -0
- package/dist/server/default-global-not-found-module.d.ts +14 -0
- package/dist/server/default-global-not-found-module.js +14 -0
- package/dist/server/dev-route-files.js +4 -0
- package/dist/server/dev-server.js +19 -18
- package/dist/server/dev-stack-sourcemap.d.ts +1 -1
- package/dist/server/dev-stack-sourcemap.js +1 -1
- package/dist/server/fetch-handler.d.ts +2 -0
- package/dist/server/fetch-handler.js +18 -0
- package/dist/server/headers.d.ts +5 -15
- package/dist/server/headers.js +4 -15
- package/dist/server/image-optimization.d.ts +51 -1
- package/dist/server/image-optimization.js +52 -2
- package/dist/server/implicit-tags.js +1 -1
- package/dist/server/isr-cache.d.ts +1 -1
- package/dist/server/isr-cache.js +2 -2
- package/dist/server/metadata-routes.d.ts +3 -1
- package/dist/server/metadata-routes.js +12 -2
- package/dist/server/middleware-runtime.js +6 -1
- package/dist/server/navigation-planner.d.ts +1 -0
- package/dist/server/navigation-planner.js +14 -3
- package/dist/server/pages-api-route.js +2 -2
- package/dist/server/pages-asset-tags.d.ts +4 -6
- package/dist/server/pages-asset-tags.js +12 -12
- package/dist/server/pages-client-assets.d.ts +12 -0
- package/dist/server/pages-client-assets.js +10 -0
- package/dist/server/pages-node-compat.d.ts +8 -1
- package/dist/server/pages-node-compat.js +32 -4
- package/dist/server/pages-page-data.d.ts +24 -1
- package/dist/server/pages-page-data.js +45 -24
- package/dist/server/pages-page-handler.d.ts +2 -1
- package/dist/server/pages-page-handler.js +19 -12
- package/dist/server/pages-page-response.d.ts +7 -0
- package/dist/server/pages-page-response.js +4 -1
- package/dist/server/pages-request-pipeline.d.ts +2 -0
- package/dist/server/pages-request-pipeline.js +25 -1
- package/dist/server/pages-router-entry.d.ts +30 -0
- package/dist/server/pages-router-entry.js +108 -0
- package/dist/server/prerender-manifest.d.ts +3 -1
- package/dist/server/prerender-route-params.js +1 -1
- package/dist/server/prod-server.d.ts +1 -1
- package/dist/server/prod-server.js +48 -26
- package/dist/server/request-pipeline.js +1 -0
- package/dist/server/seed-cache.js +4 -4
- package/dist/server/worker-utils.d.ts +2 -1
- package/dist/server/worker-utils.js +7 -1
- package/dist/shims/app-router-scroll-state.d.ts +1 -0
- package/dist/shims/app-router-scroll-state.js +1 -0
- package/dist/shims/app-router-scroll.js +2 -1
- package/dist/shims/cache.js +19 -15
- package/dist/shims/cdn-cache.js +1 -1
- package/dist/shims/dynamic-preload-chunks.js +2 -1
- package/dist/shims/error-boundary.d.ts +19 -1
- package/dist/shims/error-boundary.js +11 -1
- package/dist/shims/form.d.ts +3 -1
- package/dist/shims/form.js +37 -43
- package/dist/shims/headers.d.ts +9 -1
- package/dist/shims/headers.js +31 -6
- package/dist/shims/image.js +75 -14
- package/dist/shims/internal/app-route-detection.d.ts +2 -17
- package/dist/shims/internal/app-route-detection.js +4 -17
- package/dist/shims/internal/hybrid-client-route-owner-direct.d.ts +23 -0
- package/dist/shims/internal/hybrid-client-route-owner-direct.js +51 -0
- package/dist/shims/internal/hybrid-client-route-owner.d.ts +2 -15
- package/dist/shims/internal/hybrid-client-route-owner.js +9 -60
- package/dist/shims/internal/pages-data-fetch-dedup.d.ts +9 -5
- package/dist/shims/internal/pages-data-fetch-dedup.js +73 -14
- package/dist/shims/internal/pages-data-target.d.ts +10 -9
- package/dist/shims/internal/pages-data-target.js +91 -12
- package/dist/shims/internal/pages-router-components.d.ts +7 -0
- package/dist/shims/internal/pages-router-components.js +13 -0
- package/dist/shims/layout-segment-context.d.ts +4 -1
- package/dist/shims/layout-segment-context.js +18 -4
- package/dist/shims/link.js +70 -37
- package/dist/shims/metadata.d.ts +3 -2
- package/dist/shims/metadata.js +8 -4
- package/dist/shims/navigation.d.ts +5 -1
- package/dist/shims/navigation.js +45 -10
- package/dist/shims/navigation.react-server.js +1 -1
- package/dist/shims/root-params.d.ts +15 -1
- package/dist/shims/root-params.js +21 -1
- package/dist/shims/router.d.ts +5 -7
- package/dist/shims/router.js +374 -94
- package/dist/shims/server.js +3 -2
- package/dist/shims/slot.js +3 -6
- package/dist/typegen.js +6 -5
- package/dist/utils/client-runtime-metadata.d.ts +2 -18
- package/dist/utils/client-runtime-metadata.js +31 -22
- package/dist/utils/dev-stack-sourcemap-endpoint.d.ts +4 -0
- package/dist/{server → utils}/dev-stack-sourcemap-endpoint.js +1 -1
- package/dist/utils/domain-locale.d.ts +6 -3
- package/dist/{server → utils}/middleware-request-headers.d.ts +1 -1
- package/dist/{server → utils}/middleware-request-headers.js +2 -2
- package/dist/utils/path.d.ts +2 -1
- package/dist/utils/path.js +1 -1
- package/dist/utils/project.d.ts +52 -2
- package/dist/utils/project.js +230 -5
- package/dist/utils/protocol-headers.d.ts +17 -0
- package/dist/utils/protocol-headers.js +17 -0
- package/dist/utils/react-version.d.ts +4 -0
- package/dist/utils/react-version.js +44 -0
- package/package.json +53 -4
- package/dist/deploy.d.ts +0 -190
- package/dist/deploy.js +0 -1033
- package/dist/server/dev-stack-sourcemap-endpoint.d.ts +0 -4
- /package/dist/{cloudflare → packages/cloudflare}/src/utils/cache-control-metadata.js +0 -0
|
@@ -2,6 +2,7 @@ import { NEVER_CACHE_CONTROL, NO_STORE_CACHE_CONTROL, applyCdnResponseHeaders }
|
|
|
2
2
|
import { createArtifactCompatibilityEnvelope, createArtifactCompatibilityGraphVersion } from "./artifact-compatibility.js";
|
|
3
3
|
import { AppElementsWire, isAppElementsRecord } from "./app-elements-wire.js";
|
|
4
4
|
import "./app-elements.js";
|
|
5
|
+
import { peekDynamicUsage } from "../shims/headers.js";
|
|
5
6
|
import { runWithFetchDedupe } from "../shims/fetch-cache.js";
|
|
6
7
|
import { buildAppPageHtmlResponse, buildAppPageRscResponse, resolveAppPageHtmlResponsePolicy, resolveAppPageRscResponsePolicy } from "./app-page-response.js";
|
|
7
8
|
import { buildAppPageFontLinkHeader, readAppPageBinaryStream, resolveAppPageSpecialError, teeAppPageRscStreamForCapture } from "./app-page-execution.js";
|
|
@@ -248,8 +249,11 @@ function wrapRscResponseForDevErrorReporting(response, consumeInvalidDynamicUsag
|
|
|
248
249
|
});
|
|
249
250
|
}
|
|
250
251
|
async function renderAppPageLifecycle(options) {
|
|
252
|
+
const configuredProbePageBeforeRender = options.probePageBeforeRender ?? options.isRscRequest;
|
|
253
|
+
const probePageBeforeRender = options.isRscRequest || configuredProbePageBeforeRender && !(options.peekDynamicUsage?.() ?? false);
|
|
251
254
|
const preRenderResult = await probeAppPageBeforeRender({
|
|
252
255
|
hasLoadingBoundary: options.hasLoadingBoundary,
|
|
256
|
+
probePageBeforeRender,
|
|
253
257
|
skipProbes: options.pprFallbackShellSignal !== void 0,
|
|
254
258
|
layoutCount: options.layoutCount,
|
|
255
259
|
probeLayoutAt(layoutIndex) {
|
|
@@ -311,6 +315,7 @@ async function renderAppPageLifecycle(options) {
|
|
|
311
315
|
const outgoingElement = AppElementsWire.encodeOutgoingPayload({
|
|
312
316
|
element: options.element,
|
|
313
317
|
layoutFlags,
|
|
318
|
+
...options.dynamicStaleTimeSeconds !== void 0 && options.isPrerender !== true && !options.isForceStatic ? { dynamicStaleTimeSeconds: options.dynamicStaleTimeSeconds } : {},
|
|
314
319
|
...artifactCompatibility ? { artifactCompatibility } : {},
|
|
315
320
|
renderObservation: payloadRenderObservation,
|
|
316
321
|
skipDisposition: options.isRscRequest ? skipDisposition : void 0
|
|
@@ -424,18 +429,33 @@ async function renderAppPageLifecycle(options) {
|
|
|
424
429
|
getStyles: options.getFontStyles
|
|
425
430
|
});
|
|
426
431
|
const fontLinkHeader = buildAppPageFontLinkHeader(fontData.preloads);
|
|
432
|
+
let dynamicUsedDuringHtmlRender = false;
|
|
427
433
|
let renderEnd;
|
|
428
434
|
const htmlRender = await renderAppPageHtmlStreamWithRecovery({
|
|
429
435
|
onShellRendered() {
|
|
430
436
|
if (!options.isProduction) renderEnd = performance.now();
|
|
431
437
|
},
|
|
432
438
|
renderErrorBoundaryResponse(error) {
|
|
433
|
-
|
|
439
|
+
const capturedRscError = rscErrorTracker.getCapturedError();
|
|
440
|
+
return options.renderErrorBoundaryResponse(capturedRscError ?? error, capturedRscError === null ? "ssr" : "rsc");
|
|
434
441
|
},
|
|
435
442
|
async renderHtmlStream() {
|
|
436
443
|
const ssrHandler = await options.loadSsrHandler();
|
|
437
444
|
return renderAppPageHtmlStream({
|
|
438
445
|
capturedRscDataRef,
|
|
446
|
+
getInitialNavigationCacheMetadata: () => {
|
|
447
|
+
let kind;
|
|
448
|
+
if (options.isForceStatic) kind = "static";
|
|
449
|
+
else if (options.isForceDynamic || dynamicUsedDuringHtmlRender || peekDynamicUsage()) kind = "dynamic";
|
|
450
|
+
else {
|
|
451
|
+
const observation = options.peekRenderObservationState?.();
|
|
452
|
+
kind = observation && (observation.dynamicFetches.length > 0 || observation.requestApis.length > 0) ? "dynamic" : "static";
|
|
453
|
+
}
|
|
454
|
+
return {
|
|
455
|
+
kind,
|
|
456
|
+
...kind === "dynamic" && options.dynamicStaleTimeSeconds !== void 0 && options.isPrerender !== true && !shouldCaptureRscForCacheMetadata ? { dynamicStaleTimeSeconds: options.dynamicStaleTimeSeconds } : {}
|
|
457
|
+
};
|
|
458
|
+
},
|
|
439
459
|
fontData,
|
|
440
460
|
hasCustomGlobalError: options.hasCustomGlobalError,
|
|
441
461
|
navigationContext: options.getNavigationContext(),
|
|
@@ -462,7 +482,7 @@ async function renderAppPageLifecycle(options) {
|
|
|
462
482
|
if (!htmlStream) throw new Error("[vinext] Expected an HTML stream when no fallback response was returned");
|
|
463
483
|
const linkHeader = buildAppPageLinkHeader(htmlRender.linkHeader, fontLinkHeader, options.reactMaxHeadersLength);
|
|
464
484
|
if (options.isPrerender === true) await htmlRender.metadataReady;
|
|
465
|
-
if (options.hasLoadingBoundary) {
|
|
485
|
+
if (options.hasLoadingBoundary || !probePageBeforeRender) {
|
|
466
486
|
const captured = rscErrorTracker.getCapturedSpecialError();
|
|
467
487
|
if (captured) {
|
|
468
488
|
const specialError = resolveAppPageSpecialError(captured);
|
|
@@ -480,11 +500,13 @@ async function renderAppPageLifecycle(options) {
|
|
|
480
500
|
revalidateSeconds
|
|
481
501
|
}));
|
|
482
502
|
}
|
|
503
|
+
let dynamicUsedDuringRender = options.consumeDynamicUsage();
|
|
504
|
+
dynamicUsedDuringHtmlRender = dynamicUsedDuringRender;
|
|
483
505
|
const draftCookie = options.getDraftModeCookieHeader();
|
|
484
|
-
const dynamicUsedDuringRender = options.consumeDynamicUsage();
|
|
485
506
|
let dynamicUsedBeforeContextCleanup = dynamicUsedDuringRender;
|
|
486
507
|
const safeHtmlStream = deferUntilStreamConsumed(htmlStream, () => {
|
|
487
508
|
dynamicUsedBeforeContextCleanup = dynamicUsedBeforeContextCleanup || options.consumeDynamicUsage();
|
|
509
|
+
dynamicUsedDuringHtmlRender = dynamicUsedBeforeContextCleanup;
|
|
488
510
|
options.clearRequestContext();
|
|
489
511
|
});
|
|
490
512
|
const htmlResponsePolicy = resolveAppPageHtmlResponsePolicy({
|
|
@@ -575,6 +597,7 @@ async function renderAppPageLifecycle(options) {
|
|
|
575
597
|
isrRscKey: options.isrRscKey,
|
|
576
598
|
isrSet: options.isrSet,
|
|
577
599
|
interceptionContext: options.interceptionContext,
|
|
600
|
+
omitPendingDynamicCacheState: options.omitPendingDynamicCacheState,
|
|
578
601
|
preserveClientResponseHeaders: !htmlResponsePolicy.shouldWriteToCache,
|
|
579
602
|
expireSeconds,
|
|
580
603
|
revalidateSeconds,
|
|
@@ -12,8 +12,20 @@ type GenerateStaticParamsModule = {
|
|
|
12
12
|
};
|
|
13
13
|
type GenerateStaticParamsSource = {
|
|
14
14
|
generateStaticParams: GenerateStaticParams;
|
|
15
|
+
paramAliases?: Readonly<Record<string, string>>;
|
|
16
|
+
paramPatternParts?: readonly string[];
|
|
17
|
+
routePatternParts?: readonly string[];
|
|
15
18
|
parentParamNames: readonly string[];
|
|
16
19
|
};
|
|
20
|
+
type ParallelGenerateStaticParamsBranch = {
|
|
21
|
+
configLayouts?: readonly (GenerateStaticParamsModule | null | undefined)[] | null;
|
|
22
|
+
configLayoutTreePositions?: readonly number[] | null;
|
|
23
|
+
layout?: GenerateStaticParamsModule | null;
|
|
24
|
+
page?: GenerateStaticParamsModule | null;
|
|
25
|
+
paramNames?: readonly string[] | null;
|
|
26
|
+
patternParts?: readonly string[] | null;
|
|
27
|
+
routeSegments?: readonly string[] | null;
|
|
28
|
+
};
|
|
17
29
|
type ValidateAppPageDynamicParamsOptions = {
|
|
18
30
|
clearRequestContext: () => void;
|
|
19
31
|
enforceStaticParamsOnly: boolean;
|
|
@@ -25,6 +37,8 @@ type ResolveAppPageGenerateStaticParamsSourcesOptions = {
|
|
|
25
37
|
layouts?: readonly (GenerateStaticParamsModule | null | undefined)[];
|
|
26
38
|
layoutTreePositions?: readonly number[];
|
|
27
39
|
page?: GenerateStaticParamsModule | null;
|
|
40
|
+
parallelBranches?: readonly (ParallelGenerateStaticParamsBranch | null | undefined)[];
|
|
41
|
+
routePatternParts?: readonly string[];
|
|
28
42
|
routeSegments: readonly string[];
|
|
29
43
|
};
|
|
30
44
|
type BuildAppPageElementOptions<TElement> = {
|
|
@@ -40,8 +54,11 @@ type BuildAppPageElementResult<TElement> = {
|
|
|
40
54
|
};
|
|
41
55
|
type AppPageInterceptMatch<TPage = unknown> = {
|
|
42
56
|
interceptLayouts?: readonly unknown[] | null;
|
|
57
|
+
interceptLayoutSegments?: readonly (readonly string[])[] | null;
|
|
58
|
+
interceptBranchSegments?: readonly string[] | null;
|
|
43
59
|
__loadInterceptLayouts?: readonly (() => Promise<unknown>)[] | null;
|
|
44
60
|
matchedParams: AppPageParams;
|
|
61
|
+
sourceMatchedParams?: AppPageParams;
|
|
45
62
|
page: TPage;
|
|
46
63
|
__pageLoader?: (() => Promise<TPage>) | null;
|
|
47
64
|
__loadState?: {
|
|
@@ -88,7 +105,10 @@ type ResolveAppPageInterceptionRerenderTargetResult<TRoute, TInterceptOpts> = {
|
|
|
88
105
|
type ResolveAppPageActionRerenderTargetOptions<TRoute, TPage, TInterceptOpts> = ResolveAppPageInterceptionRerenderTargetOptions<TRoute, TPage, TInterceptOpts>;
|
|
89
106
|
type ResolveAppPageActionRerenderTargetResult<TRoute, TInterceptOpts> = ResolveAppPageInterceptionRerenderTargetResult<TRoute, TInterceptOpts>;
|
|
90
107
|
type ResolveAppPageInterceptOptions<TRoute, TPage, TInterceptOpts, TElement> = {
|
|
91
|
-
buildPageElement: (route: TRoute, params: AppPageParams, interceptOpts: TInterceptOpts | undefined, searchParams: URLSearchParams, layoutParamAccess?: AppLayoutParamAccessTracker
|
|
108
|
+
buildPageElement: (route: TRoute, params: AppPageParams, interceptOpts: TInterceptOpts | undefined, searchParams: URLSearchParams, layoutParamAccess?: AppLayoutParamAccessTracker, buildOptions?: {
|
|
109
|
+
observeMetadataSearchParamsAccess?: boolean;
|
|
110
|
+
observePageSearchParamsAccess?: boolean;
|
|
111
|
+
}) => Promise<TElement>;
|
|
92
112
|
cleanPathname: string;
|
|
93
113
|
currentRoute: TRoute;
|
|
94
114
|
findIntercept: (pathname: string) => AppPageInterceptMatch<TPage> | null;
|
|
@@ -98,6 +118,7 @@ type ResolveAppPageInterceptOptions<TRoute, TPage, TInterceptOpts, TElement> = {
|
|
|
98
118
|
layoutParamAccess?: AppLayoutParamAccessTracker;
|
|
99
119
|
resolveNavigationParams: (route: TRoute, params: AppPageParams, pathname: string, interceptOpts: TInterceptOpts) => AppPageParams;
|
|
100
120
|
renderInterceptResponse: (route: TRoute, element: TElement) => Promise<Response> | Response;
|
|
121
|
+
resolveSearchParams?: (route: TRoute, searchParams: URLSearchParams) => Awaitable<URLSearchParams>;
|
|
101
122
|
searchParams: URLSearchParams;
|
|
102
123
|
setNavigationContext: (context: {
|
|
103
124
|
params: AppPageParams;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { notFoundResponse } from "./http-error-responses.js";
|
|
2
2
|
import { runWithFetchDedupe } from "../shims/fetch-cache.js";
|
|
3
|
+
import { matchRoutePattern } from "../routing/route-pattern.js";
|
|
3
4
|
import { getAppPageSegmentParamName } from "./app-page-params.js";
|
|
4
5
|
import { loadAppInterceptLayouts } from "./app-route-module-loader.js";
|
|
5
6
|
//#region src/server/app-page-request.ts
|
|
@@ -11,6 +12,31 @@ function pickRouteParams(matchedParams, routeParamNames) {
|
|
|
11
12
|
}
|
|
12
13
|
return params;
|
|
13
14
|
}
|
|
15
|
+
function remapRouteParams(matchedParams, source) {
|
|
16
|
+
if (source.paramPatternParts && source.routePatternParts) {
|
|
17
|
+
const urlParts = [];
|
|
18
|
+
for (const part of source.routePatternParts) {
|
|
19
|
+
if (!part.startsWith(":")) {
|
|
20
|
+
urlParts.push(part);
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
const value = matchedParams[part.slice(1).replace(/[+*]$/, "")];
|
|
24
|
+
if (Array.isArray(value)) urlParts.push(...value.map(encodeURIComponent));
|
|
25
|
+
else if (value !== void 0) urlParts.push(encodeURIComponent(value));
|
|
26
|
+
}
|
|
27
|
+
const slotParams = matchRoutePattern(urlParts, source.paramPatternParts);
|
|
28
|
+
if (slotParams) return slotParams;
|
|
29
|
+
}
|
|
30
|
+
if (!source.paramAliases) return matchedParams;
|
|
31
|
+
const params = { ...matchedParams };
|
|
32
|
+
for (const [routeParamName, sourceParamName] of Object.entries(source.paramAliases)) {
|
|
33
|
+
const value = matchedParams[routeParamName];
|
|
34
|
+
if (value === void 0) continue;
|
|
35
|
+
delete params[routeParamName];
|
|
36
|
+
params[sourceParamName] = value;
|
|
37
|
+
}
|
|
38
|
+
return params;
|
|
39
|
+
}
|
|
14
40
|
function collectParentParamNames(routeSegments, boundaryPosition) {
|
|
15
41
|
const limit = Math.max(0, Math.min(boundaryPosition, routeSegments.length));
|
|
16
42
|
const names = [];
|
|
@@ -23,6 +49,16 @@ function collectParentParamNames(routeSegments, boundaryPosition) {
|
|
|
23
49
|
function getLayoutGenerateStaticParamsBoundary(layoutTreePosition) {
|
|
24
50
|
return (layoutTreePosition ?? 0) - 1;
|
|
25
51
|
}
|
|
52
|
+
function getParallelParentParamNames(routeParamNames, branch, boundaryPosition) {
|
|
53
|
+
const slotParamNames = branch.paramNames ?? routeParamNames;
|
|
54
|
+
const branchParamNames = collectParentParamNames(branch.routeSegments ?? [], boundaryPosition);
|
|
55
|
+
const branchParamNameSet = new Set((branch.routeSegments ?? []).flatMap((segment) => {
|
|
56
|
+
const name = getAppPageSegmentParamName(segment);
|
|
57
|
+
return name ? [name] : [];
|
|
58
|
+
}));
|
|
59
|
+
const ownerParamNames = slotParamNames.filter((name) => !branchParamNameSet.has(name));
|
|
60
|
+
return [...new Set([...ownerParamNames, ...branchParamNames])];
|
|
61
|
+
}
|
|
26
62
|
function resolveAppPageGenerateStaticParamsSources(options) {
|
|
27
63
|
const sources = [];
|
|
28
64
|
options.layouts?.forEach((layout, index) => {
|
|
@@ -36,6 +72,33 @@ function resolveAppPageGenerateStaticParamsSources(options) {
|
|
|
36
72
|
generateStaticParams: options.page.generateStaticParams,
|
|
37
73
|
parentParamNames: collectParentParamNames(options.routeSegments, Math.max(0, options.routeSegments.length - 1))
|
|
38
74
|
});
|
|
75
|
+
const routeParamNames = options.routeSegments.flatMap((segment) => {
|
|
76
|
+
const name = getAppPageSegmentParamName(segment);
|
|
77
|
+
return name ? [name] : [];
|
|
78
|
+
});
|
|
79
|
+
for (const parallelBranch of options.parallelBranches ?? []) {
|
|
80
|
+
if (!parallelBranch) continue;
|
|
81
|
+
const slotParamNames = parallelBranch.paramNames ?? routeParamNames;
|
|
82
|
+
const paramAliases = Object.fromEntries(routeParamNames.flatMap((routeParamName, index) => {
|
|
83
|
+
const slotParamName = slotParamNames[index];
|
|
84
|
+
return slotParamName && slotParamName !== routeParamName ? [[routeParamName, slotParamName]] : [];
|
|
85
|
+
}));
|
|
86
|
+
const addParallelSource = (module, boundaryPosition) => {
|
|
87
|
+
if (typeof module?.generateStaticParams !== "function") return;
|
|
88
|
+
sources.push({
|
|
89
|
+
generateStaticParams: module.generateStaticParams,
|
|
90
|
+
...Object.keys(paramAliases).length > 0 ? { paramAliases } : {},
|
|
91
|
+
...parallelBranch.patternParts ? { paramPatternParts: parallelBranch.patternParts } : {},
|
|
92
|
+
...options.routePatternParts ? { routePatternParts: options.routePatternParts } : {},
|
|
93
|
+
parentParamNames: getParallelParentParamNames(routeParamNames, parallelBranch, boundaryPosition)
|
|
94
|
+
});
|
|
95
|
+
};
|
|
96
|
+
addParallelSource(parallelBranch.layout, -1);
|
|
97
|
+
parallelBranch.configLayouts?.forEach((layout, index) => {
|
|
98
|
+
addParallelSource(layout, getLayoutGenerateStaticParamsBoundary(parallelBranch.configLayoutTreePositions?.[index]));
|
|
99
|
+
});
|
|
100
|
+
addParallelSource(parallelBranch.page, Math.max(0, (parallelBranch.routeSegments?.length ?? 0) - 1));
|
|
101
|
+
}
|
|
39
102
|
return sources;
|
|
40
103
|
}
|
|
41
104
|
function areStaticParamsAllowed(params, staticParams) {
|
|
@@ -44,8 +107,9 @@ function areStaticParamsAllowed(params, staticParams) {
|
|
|
44
107
|
const value = params[key];
|
|
45
108
|
const staticValue = staticParamSet[key];
|
|
46
109
|
if (staticValue === void 0) return true;
|
|
47
|
-
if (Array.isArray(value)) return
|
|
48
|
-
if (typeof staticValue === "string"
|
|
110
|
+
if (Array.isArray(value)) return Array.isArray(staticValue) && value.length === staticValue.length && value.every((part, index) => typeof staticValue[index] === "string" ? part.toLowerCase() === staticValue[index].toLowerCase() : part === staticValue[index]);
|
|
111
|
+
if (typeof staticValue === "string") return value.toLowerCase() === staticValue.toLowerCase();
|
|
112
|
+
if (typeof staticValue === "number" || typeof staticValue === "boolean") return String(value) === String(staticValue);
|
|
49
113
|
return JSON.stringify(value) === JSON.stringify(staticValue);
|
|
50
114
|
}));
|
|
51
115
|
}
|
|
@@ -67,8 +131,9 @@ async function validateAppPageDynamicParams(options) {
|
|
|
67
131
|
return notFoundResponse();
|
|
68
132
|
}
|
|
69
133
|
for (const source of generateStaticParamsSources) {
|
|
70
|
-
const
|
|
71
|
-
|
|
134
|
+
const sourceParams = remapRouteParams(options.params, source);
|
|
135
|
+
const staticParams = await runWithFetchDedupe(() => source.generateStaticParams({ params: pickRouteParams(sourceParams, source.parentParamNames) }));
|
|
136
|
+
if (Array.isArray(staticParams) && !areStaticParamsAllowed(sourceParams, staticParams)) {
|
|
72
137
|
options.clearRequestContext();
|
|
73
138
|
return notFoundResponse();
|
|
74
139
|
}
|
|
@@ -97,7 +162,7 @@ async function resolveAppPageInterceptMatch(options) {
|
|
|
97
162
|
return {
|
|
98
163
|
interceptOpts: options.toInterceptOpts(interceptState.intercept),
|
|
99
164
|
matchedParams: interceptState.intercept.matchedParams,
|
|
100
|
-
sourceParams: pickRouteParams(interceptState.intercept.matchedParams, options.getRouteParamNames(interceptState.sourceRoute)),
|
|
165
|
+
sourceParams: pickRouteParams(interceptState.intercept.sourceMatchedParams ?? interceptState.intercept.matchedParams, options.getRouteParamNames(interceptState.sourceRoute)),
|
|
101
166
|
sourceRoute: interceptState.sourceRoute
|
|
102
167
|
};
|
|
103
168
|
}
|
|
@@ -145,12 +210,18 @@ async function resolveAppPageInterceptionRerenderTarget(options) {
|
|
|
145
210
|
isRscRequest: options.isRscRequest,
|
|
146
211
|
toInterceptOpts: options.toInterceptOpts
|
|
147
212
|
});
|
|
148
|
-
if (interceptState.kind === "source-route")
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
213
|
+
if (interceptState.kind === "source-route") {
|
|
214
|
+
const sourceMatchedParams = interceptState.intercept.sourceMatchedParams ?? interceptState.intercept.matchedParams;
|
|
215
|
+
return {
|
|
216
|
+
interceptOpts: options.toInterceptOpts(interceptState.intercept),
|
|
217
|
+
navigationParams: {
|
|
218
|
+
...sourceMatchedParams,
|
|
219
|
+
...interceptState.intercept.matchedParams
|
|
220
|
+
},
|
|
221
|
+
params: pickRouteParams(sourceMatchedParams, options.getRouteParamNames(interceptState.sourceRoute)),
|
|
222
|
+
route: interceptState.sourceRoute
|
|
223
|
+
};
|
|
224
|
+
}
|
|
154
225
|
return {
|
|
155
226
|
interceptOpts: interceptState.kind === "current-route" ? options.toInterceptOpts(interceptState.intercept) : void 0,
|
|
156
227
|
navigationParams: options.currentParams,
|
|
@@ -174,13 +245,19 @@ async function resolveAppPageIntercept(options) {
|
|
|
174
245
|
if (interceptState.kind === "source-route") {
|
|
175
246
|
const renderRoute = interceptState.sourceRoute;
|
|
176
247
|
const interceptOpts = options.toInterceptOpts(interceptState.intercept);
|
|
177
|
-
const
|
|
248
|
+
const sourceMatchedParams = interceptState.intercept.sourceMatchedParams ?? interceptState.intercept.matchedParams;
|
|
249
|
+
const navigationParams = {
|
|
250
|
+
...sourceMatchedParams,
|
|
251
|
+
...interceptState.intercept.matchedParams
|
|
252
|
+
};
|
|
253
|
+
const renderSearchParams = options.resolveSearchParams ? await options.resolveSearchParams(renderRoute, options.searchParams) : options.searchParams;
|
|
254
|
+
const renderParams = pickRouteParams(sourceMatchedParams, options.getRouteParamNames(interceptState.sourceRoute));
|
|
178
255
|
options.setNavigationContext({
|
|
179
|
-
params: options.resolveNavigationParams(renderRoute,
|
|
256
|
+
params: options.resolveNavigationParams(renderRoute, navigationParams, options.cleanPathname, interceptOpts),
|
|
180
257
|
pathname: options.cleanPathname,
|
|
181
|
-
searchParams:
|
|
258
|
+
searchParams: renderSearchParams
|
|
182
259
|
});
|
|
183
|
-
const interceptElement = await options.buildPageElement(renderRoute, renderParams, interceptOpts,
|
|
260
|
+
const interceptElement = await options.buildPageElement(renderRoute, renderParams, interceptOpts, renderSearchParams, options.layoutParamAccess);
|
|
184
261
|
return {
|
|
185
262
|
interceptOpts: void 0,
|
|
186
263
|
response: await options.renderInterceptResponse(renderRoute, interceptElement)
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { AppRouteSemanticIds } from "../routing/app-route-graph.js";
|
|
2
|
-
import { AppElements, AppElementsInterception } from "./app-elements-wire.js";
|
|
2
|
+
import { AppElements, AppElementsInterception, AppElementsSlotBinding } from "./app-elements-wire.js";
|
|
3
3
|
import { AppPageParams } from "./app-page-boundary.js";
|
|
4
4
|
import { ThenableParamsObserver } from "../shims/thenable-params.js";
|
|
5
|
+
import { Metadata, Viewport } from "../shims/metadata.js";
|
|
5
6
|
import { AppLayoutParamAccessTracker } from "./app-layout-param-observation.js";
|
|
6
7
|
import { AppRscRenderMode } from "./app-rsc-render-mode.js";
|
|
7
|
-
import { Metadata, Viewport } from "../shims/metadata.js";
|
|
8
8
|
import { AppPageRenderIdentity } from "./app-page-render-identity.js";
|
|
9
9
|
import { resolveAppPageChildSegments } from "./app-page-segment-state.js";
|
|
10
10
|
import { ComponentType, ReactNode } from "react";
|
|
@@ -31,6 +31,8 @@ type AppPageRouteWiringSlot<TModule extends AppPageModule = AppPageModule, TErro
|
|
|
31
31
|
/** Graph-owned semantic slot identity. */id?: string | null; /** Slot prop name passed to the owning layout (e.g. "modal" from @modal). */
|
|
32
32
|
name: string;
|
|
33
33
|
default?: TModule | null;
|
|
34
|
+
configLayouts?: readonly (TModule | null | undefined)[] | null;
|
|
35
|
+
configLayoutTreePositions?: readonly number[] | null;
|
|
34
36
|
error?: TErrorModule | null;
|
|
35
37
|
layout?: TModule | null;
|
|
36
38
|
layoutIndex: number;
|
|
@@ -62,10 +64,16 @@ type AppPageRouteWiringRoute<TModule extends AppPageModule = AppPageModule, TErr
|
|
|
62
64
|
unauthorized?: TModule | null;
|
|
63
65
|
unauthorizeds?: readonly (TModule | null | undefined)[] | null;
|
|
64
66
|
routeSegments?: readonly string[];
|
|
67
|
+
childrenRouteSegments?: readonly string[] | null;
|
|
65
68
|
/**
|
|
66
69
|
* Keyed by stable slot id (name + owner path), not necessarily the slot prop name.
|
|
67
70
|
*/
|
|
68
71
|
slots?: Readonly<Record<string, AppPageRouteWiringSlot<TModule, TErrorModule>>> | null;
|
|
72
|
+
childrenSlot?: {
|
|
73
|
+
id: string;
|
|
74
|
+
ownerTreePath: string;
|
|
75
|
+
state: AppElementsSlotBinding["state"];
|
|
76
|
+
} | null;
|
|
69
77
|
/**
|
|
70
78
|
* Static sibling segment names at each dynamic URL level for this route. Used
|
|
71
79
|
* by the client router to determine if a cached prefetch of the dynamic
|
|
@@ -83,6 +91,8 @@ type AppPageRouteWiringRoute<TModule extends AppPageModule = AppPageModule, TErr
|
|
|
83
91
|
templates?: readonly (TModule | null | undefined)[] | null;
|
|
84
92
|
};
|
|
85
93
|
type AppPageSlotOverride<TModule extends AppPageModule = AppPageModule> = {
|
|
94
|
+
branchSegments?: readonly string[] | null;
|
|
95
|
+
layoutSegments?: readonly (readonly string[])[] | null;
|
|
86
96
|
layoutModules?: readonly (TModule | null | undefined)[] | null;
|
|
87
97
|
/**
|
|
88
98
|
* The page module to render for this slot. Optional — when omitted, the
|
|
@@ -92,6 +102,7 @@ type AppPageSlotOverride<TModule extends AppPageModule = AppPageModule> = {
|
|
|
92
102
|
pageModule?: TModule | null;
|
|
93
103
|
params?: AppPageParams;
|
|
94
104
|
props?: Readonly<Record<string, unknown>>;
|
|
105
|
+
routeSegments?: readonly string[] | null;
|
|
95
106
|
};
|
|
96
107
|
type AppPageLayoutEntry<TModule extends AppPageModule = AppPageModule, TErrorModule extends AppPageErrorModule = AppPageErrorModule> = {
|
|
97
108
|
errorModule?: TErrorModule | null | undefined;
|
|
@@ -118,6 +129,7 @@ type BuildAppPageRouteElementOptions<TModule extends AppPageModule = AppPageModu
|
|
|
118
129
|
rootNotFoundModule?: TModule | null;
|
|
119
130
|
rootUnauthorizedModule?: TModule | null;
|
|
120
131
|
route: AppPageRouteWiringRoute<TModule, TErrorModule>;
|
|
132
|
+
createPageElement?: (component: AppPageComponent, props: Readonly<Record<string, unknown>>) => ReactNode;
|
|
121
133
|
searchParams?: unknown;
|
|
122
134
|
slotOverrides?: Readonly<Record<string, AppPageSlotOverride<TModule>>> | null;
|
|
123
135
|
};
|
|
@@ -8,14 +8,17 @@ import { AppRouterScrollTarget } from "../shims/app-router-scroll.js";
|
|
|
8
8
|
import { LayoutSegmentProvider } from "../shims/layout-segment-context.js";
|
|
9
9
|
import { MetadataHead, ViewportHead, renderMetadataToHtml } from "../shims/metadata.js";
|
|
10
10
|
import { Children as Children$1, ParallelSlot, Slot } from "../shims/slot.js";
|
|
11
|
-
import { resolveAppPageSegmentParamScopeKeys, resolveAppPageSegmentParams } from "./app-page-params.js";
|
|
11
|
+
import { resolveAppPageBranchParams, resolveAppPageSegmentParamScopeKeys, resolveAppPageSegmentParams } from "./app-page-params.js";
|
|
12
12
|
import { probeReactServerSubtree } from "./app-page-probe.js";
|
|
13
|
-
import { resolveAppPageChildSegments, resolveAppPageRouteStateKey, resolveAppPageSegmentStateKey } from "./app-page-segment-state.js";
|
|
13
|
+
import { APP_PAGE_SEGMENT_KEY, resolveAppPageChildSegments, resolveAppPageRouteStateKey, resolveAppPageSegmentStateKey } from "./app-page-segment-state.js";
|
|
14
14
|
import { Fragment, Suspense } from "react";
|
|
15
15
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
16
16
|
//#region src/server/app-page-route-wiring.tsx
|
|
17
17
|
const APP_PAGE_LAYOUT_PROBE_CHILD = /* @__PURE__ */ jsx(Fragment, {});
|
|
18
18
|
const DEFAULT_GLOBAL_ERROR_COMPONENT = DefaultGlobalError;
|
|
19
|
+
function resolveSlotLayoutParams(routeSegments, treePosition, params) {
|
|
20
|
+
return resolveAppPageBranchParams(routeSegments, treePosition, params);
|
|
21
|
+
}
|
|
19
22
|
function getDefaultExport(module) {
|
|
20
23
|
return module?.default ?? null;
|
|
21
24
|
}
|
|
@@ -90,6 +93,10 @@ function createAppPageTemplateEntries(route) {
|
|
|
90
93
|
function createAppPageSourcePage(routeSegments) {
|
|
91
94
|
return `/${[...routeSegments ?? [], "page"].join("/")}`;
|
|
92
95
|
}
|
|
96
|
+
function resolveAppPageLayoutSegmentProviderSegments(routeSegments, treePosition, params) {
|
|
97
|
+
const segments = resolveAppPageChildSegments(routeSegments, treePosition, params);
|
|
98
|
+
return segments.at(-1) === "__PAGE__" ? segments.slice(0, -1) : segments;
|
|
99
|
+
}
|
|
93
100
|
function createAppPageErrorEntries(route) {
|
|
94
101
|
return (route.errorPaths ?? route.errors ?? []).flatMap((errorModule, index) => {
|
|
95
102
|
if (!errorModule) return [];
|
|
@@ -101,7 +108,7 @@ function createAppPageErrorEntries(route) {
|
|
|
101
108
|
}];
|
|
102
109
|
});
|
|
103
110
|
}
|
|
104
|
-
function createAppPageParallelSlotEntries(layoutIndex, layoutEntries, route, getEffectiveSlotParams) {
|
|
111
|
+
function createAppPageParallelSlotEntries(layoutIndex, layoutEntries, route, getEffectiveSlotParams, resolveSlotOverride) {
|
|
105
112
|
const parallelSlots = {};
|
|
106
113
|
for (const [slotKey, slot] of Object.entries(route.slots ?? {})) {
|
|
107
114
|
const slotName = slot.name;
|
|
@@ -109,8 +116,10 @@ function createAppPageParallelSlotEntries(layoutIndex, layoutEntries, route, get
|
|
|
109
116
|
if (targetIndex !== layoutIndex) continue;
|
|
110
117
|
const slotId = resolveAppPageSlotId(slot, layoutEntries[targetIndex]?.treePath ?? "/");
|
|
111
118
|
const slotParams = getEffectiveSlotParams(slotKey, slotName);
|
|
119
|
+
const routeSegments = resolveSlotOverride(slotKey, slotName)?.routeSegments ?? slot.routeSegments;
|
|
112
120
|
parallelSlots[slotName] = /* @__PURE__ */ jsx(LayoutSegmentProvider, {
|
|
113
|
-
|
|
121
|
+
providerId: slotId,
|
|
122
|
+
segmentMap: { children: routeSegments ? resolveAppPageLayoutSegmentProviderSegments(routeSegments, 0, slotParams) : [] },
|
|
114
123
|
children: /* @__PURE__ */ jsx(Slot, { id: slotId })
|
|
115
124
|
});
|
|
116
125
|
}
|
|
@@ -128,6 +137,14 @@ function resolveAppPageSlotBindingState(slot, override) {
|
|
|
128
137
|
}
|
|
129
138
|
function createAppPageSlotBindings(route, layoutEntries, resolveSlotOverride, options) {
|
|
130
139
|
const bindings = [];
|
|
140
|
+
if (route.childrenSlot) {
|
|
141
|
+
const ownerLayoutId = layoutEntries.find((layoutEntry) => layoutEntry.treePath === route.childrenSlot?.ownerTreePath)?.id;
|
|
142
|
+
bindings.push({
|
|
143
|
+
ownerLayoutId: ownerLayoutId ?? null,
|
|
144
|
+
slotId: route.childrenSlot.id,
|
|
145
|
+
state: route.childrenSlot.state
|
|
146
|
+
});
|
|
147
|
+
}
|
|
131
148
|
for (const [slotKey, slot] of Object.entries(route.slots ?? {})) {
|
|
132
149
|
const layoutEntry = layoutEntries[slot.layoutIndex >= 0 ? slot.layoutIndex : layoutEntries.length - 1] ?? null;
|
|
133
150
|
const ownerLayoutId = layoutEntry?.id ?? null;
|
|
@@ -170,6 +187,7 @@ function buildAppPageElements(options) {
|
|
|
170
187
|
const routeResetKey = resolveAppPageRouteStateKey(routeSegments, options.matchedParams);
|
|
171
188
|
const routeId = renderIdentity?.routeId ?? AppElementsWire.encodeRouteId(options.routePath, interceptionContext);
|
|
172
189
|
const pageId = renderIdentity?.pageId ?? AppElementsWire.encodePageId(options.routePath, interceptionContext);
|
|
190
|
+
const pageElementId = options.route.childrenSlot?.id ?? pageId;
|
|
173
191
|
const layoutEntries = createAppPageLayoutEntries(options.route);
|
|
174
192
|
const templateEntries = createAppPageTemplateEntries(options.route);
|
|
175
193
|
const errorEntries = createAppPageErrorEntries(options.route);
|
|
@@ -243,19 +261,13 @@ function buildAppPageElements(options) {
|
|
|
243
261
|
const routeLoadingComponent = getDefaultExport(options.route.loading);
|
|
244
262
|
const isPrefetchLoadingShell = renderMode === APP_RSC_RENDER_MODE_PREFETCH_LOADING_SHELL;
|
|
245
263
|
if (isPrefetchLoadingShell && routeLoadingComponent !== null) elements[APP_PREFETCH_LOADING_SHELL_MARKER_KEY] = "LoadingBoundary";
|
|
246
|
-
elements[
|
|
264
|
+
elements[pageElementId] = isPrefetchLoadingShell ? null : renderAfterAppDependencies(options.element, pageDependencies);
|
|
247
265
|
for (const templateEntry of templateEntries) {
|
|
248
266
|
const templateComponent = getDefaultExport(templateEntry.templateModule);
|
|
249
267
|
if (!templateComponent) continue;
|
|
250
268
|
const TemplateComponent = templateComponent;
|
|
251
269
|
const templateDependency = templateDependenciesById.get(templateEntry.id);
|
|
252
|
-
const templateElement = templateDependency ? renderWithAppDependencyBarrier(/* @__PURE__ */ jsx(TemplateComponent, {
|
|
253
|
-
params: options.matchedParams,
|
|
254
|
-
children: /* @__PURE__ */ jsx(Children$1, {})
|
|
255
|
-
}), templateDependency) : /* @__PURE__ */ jsx(TemplateComponent, {
|
|
256
|
-
params: options.matchedParams,
|
|
257
|
-
children: /* @__PURE__ */ jsx(Children$1, {})
|
|
258
|
-
});
|
|
270
|
+
const templateElement = templateDependency ? renderWithAppDependencyBarrier(/* @__PURE__ */ jsx(TemplateComponent, { children: /* @__PURE__ */ jsx(Children$1, {}) }), templateDependency) : /* @__PURE__ */ jsx(TemplateComponent, { children: /* @__PURE__ */ jsx(Children$1, {}) });
|
|
259
271
|
elements[templateEntry.id] = renderAfterAppDependencies(templateElement, templateDependenciesBeforeById.get(templateEntry.id) ?? []);
|
|
260
272
|
}
|
|
261
273
|
for (let index = 0; index < layoutEntries.length; index++) {
|
|
@@ -293,7 +305,9 @@ function buildAppPageElements(options) {
|
|
|
293
305
|
const slotId = resolveAppPageSlotId(slot, layoutEntries[targetIndex]?.treePath ?? "/");
|
|
294
306
|
const slotOverride = resolveSlotOverride(slotKey, slotName);
|
|
295
307
|
const slotParams = getEffectiveSlotParams(slotKey, slotName);
|
|
296
|
-
const
|
|
308
|
+
const slotRouteSegments = slotOverride?.routeSegments ?? slot.routeSegments ?? [];
|
|
309
|
+
const slotOwnerParams = resolveAppPageSegmentParams(options.route.routeSegments, layoutEntries[targetIndex]?.treePosition ?? 0, options.matchedParams);
|
|
310
|
+
const slotResetKey = resolveAppPageRouteStateKey(slotRouteSegments, slotParams);
|
|
297
311
|
const overrideOrPageComponent = getDefaultExport(slotOverride?.pageModule) ?? getDefaultExport(slot.page);
|
|
298
312
|
const defaultComponent = getDefaultExport(slot.default);
|
|
299
313
|
if (!overrideOrPageComponent && defaultComponent && options.isRscRequest && options.mountedSlotIds?.has(slotId)) continue;
|
|
@@ -302,23 +316,40 @@ function buildAppPageElements(options) {
|
|
|
302
316
|
elements[slotId] = AppElementsWire.unmatchedSlotValue;
|
|
303
317
|
continue;
|
|
304
318
|
}
|
|
305
|
-
const
|
|
306
|
-
const slotProps = { params: slotThenableParams };
|
|
319
|
+
const slotProps = { params: options.makeThenableParams(slotParams) };
|
|
307
320
|
if (options.searchParams !== void 0) slotProps.searchParams = options.searchParams;
|
|
308
321
|
if (slotOverride?.props) Object.assign(slotProps, slotOverride.props);
|
|
309
|
-
let slotElement =
|
|
322
|
+
let slotElement = options.createPageElement ? options.createPageElement(slotComponent, slotProps) : (() => {
|
|
323
|
+
return /* @__PURE__ */ jsx(slotComponent, { ...slotProps });
|
|
324
|
+
})();
|
|
325
|
+
const hasSlotTreeOverride = slotOverride?.pageModule != null || slotOverride?.layoutModules !== void 0;
|
|
310
326
|
const interceptLayouts = slotOverride?.layoutModules ?? [];
|
|
311
327
|
for (let layoutIndex = interceptLayouts.length - 1; layoutIndex >= 0; layoutIndex--) {
|
|
312
328
|
const interceptLayoutComponent = getDefaultExport(interceptLayouts[layoutIndex]);
|
|
313
329
|
if (!interceptLayoutComponent) continue;
|
|
314
|
-
|
|
315
|
-
|
|
330
|
+
const InterceptLayoutComponent = interceptLayoutComponent;
|
|
331
|
+
const interceptLayoutParams = resolveSlotLayoutParams(slotOverride?.branchSegments ?? slotRouteSegments, slotOverride?.layoutSegments?.[layoutIndex]?.length ?? slotRouteSegments.length, slotParams);
|
|
332
|
+
slotElement = /* @__PURE__ */ jsx(InterceptLayoutComponent, {
|
|
333
|
+
params: options.makeThenableParams(interceptLayoutParams),
|
|
334
|
+
children: slotElement
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
if (!hasSlotTreeOverride) for (let layoutIndex = (slot.configLayouts?.length ?? 0) - 1; layoutIndex >= 0; layoutIndex--) {
|
|
338
|
+
const nestedLayoutComponent = getDefaultExport(slot.configLayouts?.[layoutIndex]);
|
|
339
|
+
if (!nestedLayoutComponent) continue;
|
|
340
|
+
const NestedLayoutComponent = nestedLayoutComponent;
|
|
341
|
+
const nestedLayoutParams = resolveSlotLayoutParams(slotRouteSegments, slot.configLayoutTreePositions?.[layoutIndex] ?? 0, slotParams);
|
|
342
|
+
slotElement = /* @__PURE__ */ jsx(NestedLayoutComponent, {
|
|
343
|
+
params: options.makeThenableParams({
|
|
344
|
+
...slotOwnerParams,
|
|
345
|
+
...nestedLayoutParams
|
|
346
|
+
}),
|
|
316
347
|
children: slotElement
|
|
317
348
|
});
|
|
318
349
|
}
|
|
319
|
-
const slotLayoutComponent = getDefaultExport(slot.layout);
|
|
350
|
+
const slotLayoutComponent = overrideOrPageComponent ? getDefaultExport(slot.layout) : null;
|
|
320
351
|
if (slotLayoutComponent) slotElement = /* @__PURE__ */ jsx(slotLayoutComponent, {
|
|
321
|
-
params:
|
|
352
|
+
params: options.makeThenableParams(slotOwnerParams),
|
|
322
353
|
children: slotElement
|
|
323
354
|
});
|
|
324
355
|
const slotLoadingComponent = getDefaultExport(slot.loading);
|
|
@@ -335,8 +366,9 @@ function buildAppPageElements(options) {
|
|
|
335
366
|
elements[slotId] = renderAfterAppDependencies(slotElement, targetIndex >= 0 ? slotDependenciesByLayoutIndex[targetIndex] ?? [] : []);
|
|
336
367
|
}
|
|
337
368
|
let routeChildren = /* @__PURE__ */ jsx(LayoutSegmentProvider, {
|
|
338
|
-
|
|
339
|
-
|
|
369
|
+
providerId: pageElementId,
|
|
370
|
+
segmentMap: { children: [APP_PAGE_SEGMENT_KEY] },
|
|
371
|
+
children: /* @__PURE__ */ jsx(Slot, { id: pageElementId })
|
|
340
372
|
});
|
|
341
373
|
if (isPrefetchLoadingShell) if (routeLoadingComponent === null) routeChildren = null;
|
|
342
374
|
else routeChildren = /* @__PURE__ */ jsx(routeLoadingComponent, {});
|
|
@@ -416,18 +448,22 @@ function buildAppPageElements(options) {
|
|
|
416
448
|
}
|
|
417
449
|
const layoutHasElement = getDefaultExport(layoutEntry.layoutModule) !== null;
|
|
418
450
|
const layoutIndex = layoutIndicesByTreePosition.get(treePosition) ?? -1;
|
|
419
|
-
const segmentMap = { children:
|
|
451
|
+
const segmentMap = { children: resolveAppPageLayoutSegmentProviderSegments(options.route.childrenRouteSegments ?? routeSegments, layoutEntry.treePosition, options.matchedParams) };
|
|
420
452
|
for (const [slotKey, slot] of Object.entries(options.route.slots ?? {})) {
|
|
421
453
|
const slotName = slot.name;
|
|
422
454
|
if ((slot.layoutIndex >= 0 ? slot.layoutIndex : layoutEntries.length - 1) !== layoutIndex) continue;
|
|
423
455
|
const slotParams = getEffectiveSlotParams(slotKey, slotName);
|
|
424
|
-
|
|
456
|
+
const slotOverride = resolveSlotOverride(slotKey, slotName);
|
|
457
|
+
if (!(getDefaultExport(slotOverride?.pageModule) !== null || getDefaultExport(slot.page) !== null) && options.isRscRequest && options.mountedSlotIds?.has(resolveAppPageSlotId(slot, layoutEntry.treePath))) continue;
|
|
458
|
+
const slotRouteSegments = slotOverride?.routeSegments ?? slot.routeSegments;
|
|
459
|
+
segmentMap[slotName] = slotRouteSegments ? resolveAppPageLayoutSegmentProviderSegments(slotRouteSegments, 0, slotParams) : [];
|
|
425
460
|
}
|
|
426
461
|
routeChildren = /* @__PURE__ */ jsx(LayoutSegmentProvider, {
|
|
462
|
+
providerId: layoutEntry.id,
|
|
427
463
|
segmentMap,
|
|
428
464
|
children: layoutHasElement ? /* @__PURE__ */ jsx(Slot, {
|
|
429
465
|
id: layoutEntry.id,
|
|
430
|
-
parallelSlots: createAppPageParallelSlotEntries(layoutIndex, layoutEntries, options.route, getEffectiveSlotParams),
|
|
466
|
+
parallelSlots: createAppPageParallelSlotEntries(layoutIndex, layoutEntries, options.route, getEffectiveSlotParams, resolveSlotOverride),
|
|
431
467
|
children: segmentChildren
|
|
432
468
|
}) : segmentChildren
|
|
433
469
|
});
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { ThenableParams } from "../shims/thenable-params.js";
|
|
1
|
+
import { ThenableParams, ThenableParamsObserver } from "../shims/thenable-params.js";
|
|
2
2
|
import { AppPageSearchParams } from "./app-page-head.js";
|
|
3
3
|
|
|
4
4
|
//#region src/server/app-page-search-params-observation.d.ts
|
|
5
5
|
type AppPageSearchParamsObservationOptions = {
|
|
6
|
+
markDynamic?: boolean;
|
|
6
7
|
observeReactPromiseStatus?: boolean;
|
|
7
8
|
};
|
|
9
|
+
declare function createAppPageSearchParamsObserver(options?: AppPageSearchParamsObservationOptions): ThenableParamsObserver;
|
|
8
10
|
declare function makeObservedAppPageSearchParamsThenable(pageSearchParams: AppPageSearchParams, options?: AppPageSearchParamsObservationOptions): ThenableParams<AppPageSearchParams>;
|
|
9
11
|
//#endregion
|
|
10
|
-
export { makeObservedAppPageSearchParamsThenable };
|
|
12
|
+
export { createAppPageSearchParamsObserver, makeObservedAppPageSearchParamsThenable };
|
|
@@ -1,15 +1,19 @@
|
|
|
1
|
-
import { markDynamicUsage, markRenderRequestApiUsage, throwIfInsideCacheScope } from "../shims/headers.js";
|
|
1
|
+
import { markDynamicUsage, markRenderRequestApiUsage, throwIfInsideCacheScope, throwIfStaticGenerationAccessError } from "../shims/headers.js";
|
|
2
2
|
import { makeThenableParams } from "../shims/thenable-params.js";
|
|
3
3
|
//#region src/server/app-page-search-params-observation.ts
|
|
4
|
-
function markAppPageSearchParamsAccess() {
|
|
4
|
+
function markAppPageSearchParamsAccess(markDynamic) {
|
|
5
|
+
throwIfStaticGenerationAccessError();
|
|
5
6
|
throwIfInsideCacheScope("searchParams");
|
|
6
|
-
markDynamicUsage();
|
|
7
|
+
if (markDynamic) markDynamicUsage();
|
|
7
8
|
markRenderRequestApiUsage("searchParams");
|
|
8
9
|
}
|
|
9
|
-
function
|
|
10
|
-
|
|
11
|
-
markAppPageSearchParamsAccess();
|
|
10
|
+
function createAppPageSearchParamsObserver(options = {}) {
|
|
11
|
+
return { observeParamAccess() {
|
|
12
|
+
markAppPageSearchParamsAccess(options.markDynamic !== false);
|
|
12
13
|
} };
|
|
14
|
+
}
|
|
15
|
+
function makeObservedAppPageSearchParamsThenable(pageSearchParams, options = {}) {
|
|
16
|
+
const observer = createAppPageSearchParamsObserver(options);
|
|
13
17
|
if (options.observeReactPromiseStatus === true) return makeThenableParams(pageSearchParams, {
|
|
14
18
|
...observer,
|
|
15
19
|
observeReactPromiseStatus: true
|
|
@@ -17,4 +21,4 @@ function makeObservedAppPageSearchParamsThenable(pageSearchParams, options = {})
|
|
|
17
21
|
return makeThenableParams(pageSearchParams, observer);
|
|
18
22
|
}
|
|
19
23
|
//#endregion
|
|
20
|
-
export { makeObservedAppPageSearchParamsThenable };
|
|
24
|
+
export { createAppPageSearchParamsObserver, makeObservedAppPageSearchParamsThenable };
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { AppPageParams } from "./app-page-boundary.js";
|
|
2
2
|
|
|
3
3
|
//#region src/server/app-page-segment-state.d.ts
|
|
4
|
+
declare const APP_PAGE_SEGMENT_KEY = "__PAGE__";
|
|
4
5
|
declare function resolveAppPageChildSegments(routeSegments: readonly string[], treePosition: number, params: AppPageParams): string[];
|
|
5
6
|
declare function resolveAppPageSegmentStateKey(routeSegments: readonly string[], treePosition: number, params: AppPageParams): string;
|
|
6
7
|
declare function resolveAppPageRouteStateKey(routeSegments: readonly string[], params: AppPageParams): string;
|
|
7
8
|
declare function resolveAppPageLeafSegmentStateKey(routeSegments: readonly string[], params: AppPageParams): string;
|
|
8
9
|
//#endregion
|
|
9
|
-
export { resolveAppPageChildSegments, resolveAppPageLeafSegmentStateKey, resolveAppPageRouteStateKey, resolveAppPageSegmentStateKey };
|
|
10
|
+
export { APP_PAGE_SEGMENT_KEY, resolveAppPageChildSegments, resolveAppPageLeafSegmentStateKey, resolveAppPageRouteStateKey, resolveAppPageSegmentStateKey };
|