vinext 1.4.1 → 1.4.3

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.
Files changed (143) hide show
  1. package/README.md +5 -2
  2. package/dist/build/action-owner-manifest.js +1 -0
  3. package/dist/build/prerender-paths.d.ts +11 -1
  4. package/dist/build/prerender-paths.js +36 -10
  5. package/dist/check.js +1 -1
  6. package/dist/cli.js +1 -1
  7. package/dist/client/dev-error-overlay.d.ts +2 -1
  8. package/dist/client/dev-error-overlay.js +8 -3
  9. package/dist/config/config-matchers.js +8 -4
  10. package/dist/config/destination-params.js +5 -2
  11. package/dist/config/next-config.d.ts +25 -1
  12. package/dist/config/next-config.js +31 -1
  13. package/dist/entries/app-rsc-entry.js +65 -30
  14. package/dist/entries/app-rsc-manifest.js +4 -0
  15. package/dist/entries/pages-server-entry.js +19 -4
  16. package/dist/index.js +37 -37
  17. package/dist/init-cloudflare.js +18 -2
  18. package/dist/init-platform.js +2 -2
  19. package/dist/init.js +42 -5
  20. package/dist/plugins/css-target.d.ts +18 -0
  21. package/dist/plugins/css-target.js +93 -0
  22. package/dist/routing/app-route-graph.d.ts +10 -0
  23. package/dist/routing/app-route-graph.js +15 -1
  24. package/dist/server/api-handler.d.ts +2 -0
  25. package/dist/server/api-handler.js +10 -8
  26. package/dist/server/app-action-forwarding.js +3 -1
  27. package/dist/server/app-browser-entry.js +37 -41
  28. package/dist/server/app-browser-error.d.ts +1 -1
  29. package/dist/server/app-browser-error.js +13 -4
  30. package/dist/server/app-browser-supplemental-refresh.d.ts +13 -0
  31. package/dist/server/app-browser-supplemental-refresh.js +36 -4
  32. package/dist/server/app-elements.d.ts +3 -0
  33. package/dist/server/app-elements.js +14 -1
  34. package/dist/server/app-fallback-renderer.js +2 -2
  35. package/dist/server/app-middleware.d.ts +2 -0
  36. package/dist/server/app-middleware.js +1 -0
  37. package/dist/server/app-optimistic-routing.d.ts +12 -1
  38. package/dist/server/app-optimistic-routing.js +38 -16
  39. package/dist/server/app-page-boundary-render.js +4 -2
  40. package/dist/server/app-page-cache-render.js +1 -1
  41. package/dist/server/app-page-dispatch.d.ts +11 -1
  42. package/dist/server/app-page-dispatch.js +78 -31
  43. package/dist/server/app-page-element-builder.d.ts +11 -20
  44. package/dist/server/app-page-element-builder.js +39 -50
  45. package/dist/server/app-page-intercept-segment-config.d.ts +56 -0
  46. package/dist/server/app-page-intercept-segment-config.js +90 -0
  47. package/dist/server/app-page-navigation-params.d.ts +23 -0
  48. package/dist/server/app-page-navigation-params.js +49 -0
  49. package/dist/server/app-page-render.d.ts +5 -2
  50. package/dist/server/app-page-render.js +17 -3
  51. package/dist/server/app-page-request.d.ts +24 -2
  52. package/dist/server/app-page-request.js +10 -10
  53. package/dist/server/app-page-route-wiring.d.ts +17 -5
  54. package/dist/server/app-page-route-wiring.js +19 -13
  55. package/dist/server/app-page-segment-plan.js +9 -1
  56. package/dist/server/app-page-segment-state.d.ts +9 -0
  57. package/dist/server/app-page-segment-state.js +54 -1
  58. package/dist/server/app-pages-bridge.d.ts +6 -0
  59. package/dist/server/app-pages-bridge.js +8 -3
  60. package/dist/server/app-request-stage-independent-entry.js +2 -3
  61. package/dist/server/app-response-stage-entry.js +1 -0
  62. package/dist/server/app-route-module-loader.d.ts +2 -0
  63. package/dist/server/app-route-module-loader.js +1 -0
  64. package/dist/server/app-router-entry.js +2 -3
  65. package/dist/server/app-rsc-cache-busting.d.ts +8 -0
  66. package/dist/server/app-rsc-cache-busting.js +13 -1
  67. package/dist/server/app-rsc-combined-handler.js +2 -1
  68. package/dist/server/app-rsc-handler.d.ts +14 -1
  69. package/dist/server/app-rsc-handler.js +111 -62
  70. package/dist/server/app-rsc-response-finalizer.d.ts +18 -3
  71. package/dist/server/app-rsc-response-finalizer.js +61 -7
  72. package/dist/server/app-rsc-route-matching.d.ts +14 -0
  73. package/dist/server/app-rsc-route-matching.js +42 -18
  74. package/dist/server/app-server-action-execution.js +16 -10
  75. package/dist/server/app-ssr-entry.js +8 -0
  76. package/dist/server/cache-control.d.ts +2 -0
  77. package/dist/server/cache-control.js +3 -1
  78. package/dist/server/config-headers.d.ts +7 -0
  79. package/dist/server/config-headers.js +20 -1
  80. package/dist/server/image-animation.d.ts +9 -0
  81. package/dist/server/image-animation.js +118 -0
  82. package/dist/server/image-local-patterns.d.ts +21 -0
  83. package/dist/server/image-local-patterns.js +59 -0
  84. package/dist/server/image-optimization.d.ts +48 -27
  85. package/dist/server/image-optimization.js +316 -22
  86. package/dist/server/image-source-reader.d.ts +34 -0
  87. package/dist/server/image-source-reader.js +126 -0
  88. package/dist/server/metadata-route-response.d.ts +6 -1
  89. package/dist/server/metadata-route-response.js +46 -10
  90. package/dist/server/middleware-matcher.d.ts +1 -0
  91. package/dist/server/middleware-matcher.js +1 -1
  92. package/dist/server/middleware-runtime.d.ts +5 -0
  93. package/dist/server/middleware-runtime.js +48 -15
  94. package/dist/server/middleware.d.ts +1 -1
  95. package/dist/server/middleware.js +2 -1
  96. package/dist/server/nitro-public-files-plugin.js +20 -8
  97. package/dist/server/nitro-request-target-plugin.d.ts +17 -0
  98. package/dist/server/nitro-request-target-plugin.js +22 -0
  99. package/dist/server/open-redirect.d.ts +2 -1
  100. package/dist/server/open-redirect.js +2 -1
  101. package/dist/server/pages-client-assets.d.ts +1 -0
  102. package/dist/server/pages-data-route.d.ts +5 -1
  103. package/dist/server/pages-data-route.js +14 -6
  104. package/dist/server/pages-i18n.d.ts +7 -0
  105. package/dist/server/pages-i18n.js +14 -1
  106. package/dist/server/pages-node-compat.js +7 -3
  107. package/dist/server/pages-page-handler.js +4 -4
  108. package/dist/server/pages-request-pipeline.d.ts +9 -0
  109. package/dist/server/pages-request-pipeline.js +35 -15
  110. package/dist/server/pages-request-stage-entry.js +8 -2
  111. package/dist/server/pages-router-entry.js +3 -0
  112. package/dist/server/prod-server.d.ts +1 -1
  113. package/dist/server/prod-server.js +64 -62
  114. package/dist/server/request-pipeline.d.ts +5 -0
  115. package/dist/server/request-pipeline.js +11 -1
  116. package/dist/server/response-stage-cacheability.d.ts +7 -0
  117. package/dist/server/response-stage-cacheability.js +6 -5
  118. package/dist/server/srvx-middleware-origin.d.ts +13 -0
  119. package/dist/server/srvx-middleware-origin.js +19 -0
  120. package/dist/server/srvx-request-target.d.ts +12 -0
  121. package/dist/server/srvx-request-target.js +20 -0
  122. package/dist/server/static-file-cache.js +10 -22
  123. package/dist/server/worker-image-optimization.d.ts +10 -3
  124. package/dist/server/worker-image-optimization.js +43 -9
  125. package/dist/server/worker-revalidation-context.js +1 -0
  126. package/dist/server/worker-utils.d.ts +8 -0
  127. package/dist/server/worker-utils.js +19 -2
  128. package/dist/shims/error-boundary.d.ts +6 -2
  129. package/dist/shims/error-boundary.js +4 -2
  130. package/dist/shims/image-props.d.ts +6 -0
  131. package/dist/shims/image-props.js +39 -3
  132. package/dist/shims/image.js +3 -3
  133. package/dist/shims/request-context.d.ts +3 -1
  134. package/dist/shims/slot.d.ts +3 -0
  135. package/dist/shims/slot.js +67 -9
  136. package/dist/shims/url-utils.js +6 -1
  137. package/dist/utils/base-path.d.ts +7 -0
  138. package/dist/utils/base-path.js +11 -1
  139. package/dist/utils/client-entry-manifest.d.ts +5 -0
  140. package/dist/utils/client-entry-manifest.js +1 -0
  141. package/dist/utils/client-runtime-metadata.d.ts +5 -0
  142. package/dist/utils/client-runtime-metadata.js +33 -7
  143. package/package.json +1 -1
@@ -4,8 +4,8 @@ import { _consumeRequestScopedCacheLife } from "../shims/cache-request-state.js"
4
4
  import { getCollectedFetchTags } from "../shims/fetch-cache.js";
5
5
  import { readStreamAsText } from "../utils/text-stream.js";
6
6
  import { buildAppPageFontLinkHeader, teeAppPageRscStreamForCapture } from "./app-page-execution.js";
7
- import { recordAppPageRenderError, traceAppPageRender } from "./app-page-tracing.js";
8
7
  import { buildAppPageLinkHeader, createAppPageSsrErrorHandler, isAppSsrRenderResult } from "./app-page-stream.js";
8
+ import { recordAppPageRenderError, traceAppPageRender } from "./app-page-tracing.js";
9
9
  import { consumeAppPageRenderObservationState, createAppPageHtmlOutputScope, createAppPageRenderObservation, createAppPageRscOutputScope } from "./app-page-render-observation.js";
10
10
  import { buildAppPageTags } from "./implicit-tags.js";
11
11
  //#region src/server/app-page-cache-render.ts
@@ -15,7 +15,7 @@ import { FetchCacheMode } from "../shims/fetch-cache-state.js";
15
15
  import "../shims/fetch-cache.js";
16
16
  import { AppPagePprFallbackCacheShell } from "./app-ppr-fallback-shell.js";
17
17
  import { WarmPprFallbackShellCachesOptions } from "./app-ppr-fallback-shell-render.js";
18
- import { ValidateAppPageDynamicParamsOptions } from "./app-page-request.js";
18
+ import { AppPageInterceptState, ValidateAppPageDynamicParamsOptions } from "./app-page-request.js";
19
19
  import { ReactNode } from "react";
20
20
  import { ReactFormState } from "react-dom/client";
21
21
  //#region src/server/app-page-dispatch.d.ts
@@ -96,10 +96,17 @@ type AppPageModule = {
96
96
  revalidate?: unknown;
97
97
  };
98
98
  type AppPageDispatchSlot = {
99
+ configLayouts?: readonly (AppPageModule | null | undefined)[] | null;
100
+ configLayoutTreePositions?: readonly number[] | null;
99
101
  default?: AppPageModule | null;
102
+ layout?: AppPageModule | null;
103
+ layoutIndex?: number;
100
104
  loading?: AppPageModule | null;
101
105
  loadings?: readonly (AppPageModule | null | undefined)[] | null;
106
+ name?: string;
107
+ ownerTreePosition?: number | null;
102
108
  page?: AppPageModule | null;
109
+ routeSegments?: readonly string[] | null;
103
110
  slotPatternParts?: readonly string[] | null;
104
111
  slotParamNames?: readonly string[] | null;
105
112
  };
@@ -159,6 +166,7 @@ export type DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {
159
166
  buildPageElement: (route: TRoute, params: AppPageParams, opts: AppPageDispatchInterceptOptions | undefined, searchParams: URLSearchParams, options?: {
160
167
  isForceStatic?: boolean;
161
168
  isUncacheableRender?: boolean;
169
+ routeTreeOnlyPrefetchShell?: boolean;
162
170
  /** Layouts the navigating client holds, which the render may leave out. */
163
171
  mountedLayouts?: ReadonlySet<string> | null;
164
172
  observeMetadataSearchParamsAccess?: boolean;
@@ -184,6 +192,8 @@ export type DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {
184
192
  ensureRouteLoaded?: (route: TRoute) => unknown;
185
193
  fetchCache?: FetchCacheMode | null;
186
194
  findIntercept: (pathname: string) => AppPageDispatchIntercept | null;
195
+ /** This request's intercept, which dispatch resolves once before rendering. */
196
+ interceptState?: AppPageInterceptState<TRoute, unknown>;
187
197
  formState?: ReactFormState | null;
188
198
  actionError?: unknown;
189
199
  actionFailed?: boolean;
@@ -1,7 +1,7 @@
1
1
  import { closeAfterResponse, createRequestContext, runWithRequestContext } from "../shims/unified-request-context.js";
2
2
  import "../utils/protocol-headers.js";
3
3
  import { VINEXT_INTERCEPTION_ID_HEADER, VINEXT_RSC_VARY_HEADER } from "./app-rsc-vary.js";
4
- import { VINEXT_MOUNTED_LAYOUTS_HEADER } from "./headers.js";
4
+ import { VINEXT_MOUNTED_LAYOUTS_HEADER, VINEXT_PARAMS_HEADER } from "./headers.js";
5
5
  import { getRequestExecutionContext } from "../shims/request-context.js";
6
6
  import { runInWorkStoreScope } from "../shims/internal/work-store-scope.js";
7
7
  import { beginRouteCacheability, isRouteCacheabilityIdentityProbe, isRouteCacheabilityProbe, markRouteCacheabilityPatternDynamic, readRouteCacheabilityState } from "../shims/cacheability-classification.js";
@@ -21,16 +21,17 @@ import { resolveUncacheableCacheControl } from "./app-page-response.js";
21
21
  import { buildRscRedirectFlightStream } from "./app-rsc-redirect-flight.js";
22
22
  import { buildAppPageSpecialErrorResponse, resolveAppPageCaughtNotFoundBoundaries, resolveAppPageShellSpecialError, resolveAppPageSpecialError, resolveAppPageSpecialErrorStoredHeaders } from "./app-page-execution.js";
23
23
  import { resolveAppPageLayoutHttpAccessBoundary, resolveAppPageParentHttpAccessBoundary, resolveAppPageRootHttpAccessBoundaryTreePosition } from "./app-page-boundary.js";
24
+ import { resolveAppPageNavigationParams } from "./app-page-navigation-params.js";
25
+ import { createAppPageRscErrorTracker } from "./app-page-stream.js";
24
26
  import { isAppClientReference } from "./app-render-dependency.js";
25
27
  import { resolveAppPageTraceOperation } from "./app-page-tracing.js";
26
- import { shouldServeStreamingMetadata } from "./streaming-metadata.js";
27
- import { resolveAppPageNavigationParams } from "./app-page-element-builder.js";
28
- import { createAppPageRscErrorTracker } from "./app-page-stream.js";
29
28
  import { getDefaultHttpAccessFallbackModule } from "./default-http-access-fallback-modules.js";
29
+ import { shouldServeStreamingMetadata } from "./streaming-metadata.js";
30
30
  import { consumeAppPageRenderObservationState, discardAppPageRenderState } from "./app-page-render-observation.js";
31
31
  import { buildAppPageTags } from "./implicit-tags.js";
32
32
  import { resolveAppPageMethodResponse } from "./app-page-method.js";
33
- import { buildAppPageElement, resolveAppPageIntercept, resolveAppPageInterceptionRerenderTarget, validateAppPageDynamicParams } from "./app-page-request.js";
33
+ import { resolveAppPageInterceptSegmentConfig } from "./app-page-intercept-segment-config.js";
34
+ import { buildAppPageElement, resolveAppPageIntercept, resolveAppPageInterceptState, resolveAppPageInterceptionRerenderTarget, validateAppPageDynamicParams } from "./app-page-request.js";
34
35
  import { applyIneligibleRouteCachePolicy, renderAppPageLifecycle } from "./app-page-render.js";
35
36
  //#region src/server/app-page-dispatch.ts
36
37
  function getActiveLoadingTreePositions(route) {
@@ -146,12 +147,48 @@ function hasNoManifestAdmissionState(routePattern) {
146
147
  }, admission.representation, admission.routePathname) === null;
147
148
  }
148
149
  async function dispatchAppPage(options) {
149
- const dispatch = () => runWithFetchDedupe(() => dispatchAppPageInner(options));
150
+ const dispatch = () => runWithFetchDedupe(async () => dispatchAppPageInner(await withResolvedIntercept(options)));
150
151
  let response;
151
152
  if (!options.pprFallbackShell || !options.pprRuntime) response = await dispatch();
152
153
  else response = await options.pprRuntime.run(options.pprFallbackShell, dispatch);
153
154
  return options.isRscRequest ? response : traceResponseStart(response);
154
155
  }
156
+ /**
157
+ * Resolves the request's intercept once, for the render and its cache reads.
158
+ *
159
+ * Next.js renders an interception as its own route even when its source is the
160
+ * matched route (`app/shots/[id]` beside `app/shots/@modal/(.)[id]`, from
161
+ * `/shots/1` to `/shots/2`). vinext renders that through the matched route's
162
+ * own page render, so the interception's segment config replaces the route's
163
+ * before that render reads it.
164
+ */
165
+ async function withResolvedIntercept(options) {
166
+ const interceptState = await resolveAppPageInterceptState({
167
+ cleanPathname: options.cleanPathname,
168
+ currentRoute: options.route,
169
+ findIntercept: options.findIntercept,
170
+ getSourceRoute: options.getSourceRoute,
171
+ interceptState: options.interceptState,
172
+ isRscRequest: options.isRscRequest
173
+ });
174
+ if (interceptState.kind !== "current-route") return {
175
+ ...options,
176
+ interceptState
177
+ };
178
+ const config = resolveAppPageInterceptSegmentConfig(options.route, toInterceptOptions(options.interceptionContext, interceptState.intercept));
179
+ return {
180
+ ...options,
181
+ interceptState,
182
+ dynamicConfig: config.dynamicConfig,
183
+ dynamicStaleTimeSeconds: config.dynamicStaleTimeSeconds,
184
+ fetchCache: config.fetchCacheMode,
185
+ hasAnyGenerateStaticParams: config.hasAnyGenerateStaticParams,
186
+ hasGenerateStaticParams: config.hasGenerateStaticParams,
187
+ isEdgeRuntime: config.isEdgeRuntime,
188
+ isStaticGenerationEdgeRuntime: config.isStaticGenerationEdgeRuntime,
189
+ revalidateSeconds: config.revalidateSeconds
190
+ };
191
+ }
155
192
  async function dispatchAppPageInner(options) {
156
193
  const route = options.route;
157
194
  beginRouteCacheability("app-page", route.pattern);
@@ -206,6 +243,7 @@ async function dispatchAppPageInner(options) {
206
243
  isDynamicError,
207
244
  isForceDynamic,
208
245
  isForceStatic,
246
+ isPrerender,
209
247
  isProduction: options.isProduction,
210
248
  isProgressiveActionRender: options.isProgressiveActionRender === true,
211
249
  isRscRequest: options.isRscRequest,
@@ -255,7 +293,8 @@ async function dispatchAppPageInner(options) {
255
293
  const isOnDemandRevalidate = _isOnDemandRevalidate();
256
294
  const shouldReadCache = isStoredRender && !isOnDemandRevalidate;
257
295
  const isCacheCandidate = isCacheEligibleRender && isStaticEligible && options.pprFallbackShell === void 0 && !isNeverStoredPath;
258
- const isUncacheableRender = !(isCacheEligibleRender && isStaticEligible) && options.pprFallbackShell === void 0 && (options.pprRuntime === void 0 || !options.isProduction);
296
+ const routeTreeOnlyPrefetchShell = options.pprFallbackShell === void 0 && (options.pprRuntime === void 0 || !options.isProduction);
297
+ const isUncacheableRender = !(isCacheEligibleRender && isStaticEligible) && routeTreeOnlyPrefetchShell;
259
298
  const mountedLayouts = isUncacheableRender && options.isRscRequest && (options.renderMode ?? "navigation") === "navigation" && options.interceptionContext === null && options.isProgressiveActionRender !== true ? parseMountedLayoutsHeader(options.request.headers.get(VINEXT_MOUNTED_LAYOUTS_HEADER)) : null;
260
299
  if (shouldReadCache && isStaticEligible) {
261
300
  traceOperation = resolveAppPageTraceOperation({
@@ -280,6 +319,7 @@ async function dispatchAppPageInner(options) {
280
319
  getSourceRoute(sourceRouteIndex) {
281
320
  return options.getSourceRoute(sourceRouteIndex);
282
321
  },
322
+ interceptState: options.interceptState,
283
323
  isRscRequest: options.isRscRequest,
284
324
  toInterceptOpts(intercept) {
285
325
  return toInterceptOptions(options.interceptionContext, intercept);
@@ -320,9 +360,10 @@ async function dispatchAppPageInner(options) {
320
360
  isDynamicRscRequest: options.pprRuntime !== void 0 && options.isRscRequest && options.request.headers.get("Next-Router-Prefetch") !== "1" && options.renderedConcreteUrlPaths?.has(options.cleanPathname) !== true,
321
361
  renderFreshPageForCache: async ({ renderDocument }) => {
322
362
  const revalidationTarget = await resolveCacheRenderTarget();
323
- const revalidationDynamicConfig = options.resolveRouteDynamicConfig?.(revalidationTarget.route) ?? (revalidationTarget.route === route ? dynamicConfig : void 0);
324
- const revalidationConfigRevalidateSeconds = options.resolveRouteRevalidateSeconds?.(revalidationTarget.route) ?? (revalidationTarget.route === route ? currentRevalidateSeconds : null);
325
- const revalidationRouteRevalidateSeconds = revalidationTarget.route === route ? void 0 : revalidationConfigRevalidateSeconds ?? (revalidationDynamicConfig === "force-static" || revalidationDynamicConfig === "error" || options.isProduction && options.pprRuntime === void 0 && options.resolveRouteStaticEligible(revalidationTarget.route) ? Infinity : null);
363
+ const revalidationInterceptConfig = revalidationTarget.interceptOpts ? resolveAppPageInterceptSegmentConfig(revalidationTarget.route, revalidationTarget.interceptOpts) : null;
364
+ const revalidationDynamicConfig = revalidationInterceptConfig ? revalidationInterceptConfig.dynamicConfig : options.resolveRouteDynamicConfig?.(revalidationTarget.route) ?? (revalidationTarget.route === route ? dynamicConfig : void 0);
365
+ const revalidationConfigRevalidateSeconds = revalidationInterceptConfig ? revalidationTarget.route === route ? currentRevalidateSeconds : revalidationInterceptConfig.revalidateSeconds : options.resolveRouteRevalidateSeconds?.(revalidationTarget.route) ?? (revalidationTarget.route === route ? currentRevalidateSeconds : null);
366
+ const revalidationRouteRevalidateSeconds = revalidationTarget.route === route ? void 0 : revalidationConfigRevalidateSeconds ?? (revalidationDynamicConfig === "force-static" || revalidationDynamicConfig === "error" || options.isProduction && options.pprRuntime === void 0 && (revalidationInterceptConfig?.isStaticEligible ?? options.resolveRouteStaticEligible(revalidationTarget.route)) ? Infinity : null);
326
367
  const revalidationRouteHead = {
327
368
  observeSearchParams: revalidationDynamicConfig !== "force-static",
328
369
  searchParams: new URLSearchParams(),
@@ -332,7 +373,7 @@ async function dispatchAppPageInner(options) {
332
373
  return runAppPageRevalidationContext({
333
374
  cleanPathname: options.cleanPathname,
334
375
  displayPathname: options.displayPathname,
335
- currentFetchCacheMode: options.resolveRouteFetchCacheMode?.(revalidationTarget.route) ?? (revalidationTarget.route === route ? options.fetchCache ?? null : null),
376
+ currentFetchCacheMode: revalidationInterceptConfig ? revalidationInterceptConfig.fetchCacheMode : options.resolveRouteFetchCacheMode?.(revalidationTarget.route) ?? (revalidationTarget.route === route ? options.fetchCache ?? null : null),
336
377
  currentFetchRevalidate: revalidationConfigRevalidateSeconds,
337
378
  draftModeSecret: options.draftModeSecret,
338
379
  dynamicConfig: revalidationDynamicConfig,
@@ -347,6 +388,7 @@ async function dispatchAppPageInner(options) {
347
388
  isForceStatic: revalidationDynamicConfig === "force-static",
348
389
  observeMetadataSearchParamsAccess: revalidationDynamicConfig !== "force-static",
349
390
  observePageSearchParamsAccess: revalidationDynamicConfig !== "force-static",
391
+ routeTreeOnlyPrefetchShell,
350
392
  serveStreamingMetadata: placeGeneratedMetadataInBody,
351
393
  placeStreamedMetadataInHead: true,
352
394
  onHeadPrepared(head) {
@@ -459,6 +501,7 @@ async function dispatchAppPageInner(options) {
459
501
  isDynamicError,
460
502
  isForceDynamic,
461
503
  isForceStatic,
504
+ isPrerender,
462
505
  isProduction: options.isProduction,
463
506
  isProgressiveActionRender: options.isProgressiveActionRender === true,
464
507
  isRscRequest: options.isRscRequest,
@@ -475,9 +518,9 @@ async function dispatchAppPageInner(options) {
475
518
  }
476
519
  const fallbackShellResponse = options.pprRuntime ? await options.pprRuntime.tryServe(options, currentRevalidateSeconds, isDraftMode, isForceStatic, isForceDynamic) : null;
477
520
  if (fallbackShellResponse) return fallbackShellResponse;
478
- let interceptDynamicConfig;
479
- let interceptDynamicConfigResolved = false;
480
- let isInterceptSourceKnownDynamic = false;
521
+ let interceptConfig = null;
522
+ let isInterceptKnownDynamic = false;
523
+ let isInterceptRequestIndependent = false;
481
524
  const renderedRouteHead = {
482
525
  observeSearchParams: !isForceStatic,
483
526
  searchParams: pageSearchParams,
@@ -489,27 +532,29 @@ async function dispatchAppPageInner(options) {
489
532
  };
490
533
  const interceptResult = await resolveAppPageIntercept({
491
534
  async buildPageElement(interceptRoute, interceptParams, interceptOpts, interceptSearchParams) {
492
- const sourceDynamicConfig = interceptDynamicConfigResolved ? interceptDynamicConfig : options.resolveRouteDynamicConfig?.(interceptRoute);
493
- if (sourceDynamicConfig === "force-static" || sourceDynamicConfig === "error") {
535
+ interceptConfig ??= resolveAppPageInterceptSegmentConfig(interceptRoute, interceptOpts);
536
+ const interceptDynamicConfig = interceptConfig.dynamicConfig;
537
+ if (interceptDynamicConfig === "force-static" || interceptDynamicConfig === "error") {
494
538
  const { createStaticGenerationHeadersContext } = await import("./app-static-generation.js");
495
539
  setHeadersContext(createStaticGenerationHeadersContext({
496
540
  draftModeEnabled: isDraftMode,
497
541
  draftModeSecret: options.draftModeSecret,
498
- dynamicConfig: sourceDynamicConfig,
542
+ dynamicConfig: interceptDynamicConfig,
499
543
  routeKind: "page",
500
544
  routePattern: interceptRoute.pattern
501
545
  }));
502
546
  } else setHeadersContext(requestHeadersContext);
503
- const sourceRevalidateSeconds = options.resolveRouteRevalidateSeconds?.(interceptRoute) ?? null;
504
- isInterceptSourceKnownDynamic = sourceDynamicConfig === "force-dynamic" || sourceRevalidateSeconds === 0;
505
- setCurrentFetchCacheMode(options.resolveRouteFetchCacheMode?.(interceptRoute) ?? null);
506
- setCurrentFetchRevalidate(sourceRevalidateSeconds);
507
- setCurrentForceDynamicFetchDefault(sourceDynamicConfig === "force-dynamic");
547
+ isInterceptKnownDynamic = interceptDynamicConfig === "force-dynamic" || interceptConfig.revalidateSeconds === 0;
548
+ isInterceptRequestIndependent = interceptDynamicConfig === "force-static" || interceptDynamicConfig === "error";
549
+ setCurrentFetchCacheMode(interceptConfig.fetchCacheMode);
550
+ setCurrentFetchRevalidate(interceptConfig.revalidateSeconds);
551
+ setCurrentForceDynamicFetchDefault(interceptDynamicConfig === "force-dynamic");
508
552
  return options.buildPageElement(interceptRoute, interceptParams, interceptOpts, interceptSearchParams, {
509
- isForceStatic: sourceDynamicConfig === "force-static",
510
- observeMetadataSearchParamsAccess: sourceDynamicConfig !== "force-static",
511
- observePageSearchParamsAccess: sourceDynamicConfig !== "force-static",
553
+ isForceStatic: interceptDynamicConfig === "force-static",
554
+ observeMetadataSearchParamsAccess: interceptDynamicConfig !== "force-static",
555
+ observePageSearchParamsAccess: interceptDynamicConfig !== "force-static",
512
556
  isUncacheableRender,
557
+ routeTreeOnlyPrefetchShell,
513
558
  serveStreamingMetadata: placeGeneratedMetadataInBody,
514
559
  placeStreamedMetadataInHead: options.renderWholeDocument === true,
515
560
  onHeadPrepared
@@ -526,18 +571,20 @@ async function dispatchAppPageInner(options) {
526
571
  getSourceRoute(sourceRouteIndex) {
527
572
  return options.getSourceRoute(sourceRouteIndex);
528
573
  },
574
+ interceptState: options.interceptState,
529
575
  isRscRequest: options.isRscRequest,
530
576
  resolveNavigationParams(sourceRoute, navigationParams, pathname, interceptOpts) {
531
577
  return resolveAppPageNavigationParams(sourceRoute, navigationParams, pathname, interceptOpts);
532
578
  },
533
- renderInterceptResponse(sourceRoute, interceptElement) {
579
+ renderInterceptResponse(sourceRoute, interceptElement, navigationParams) {
534
580
  const interceptOnError = options.createRscOnErrorHandler(options.cleanPathname, sourceRoute.pattern);
535
581
  const interceptStream = options.renderToReadableStream(interceptElement, { onError: interceptOnError });
536
582
  const interceptHeaders = new Headers({
537
583
  "Content-Type": VINEXT_RSC_CONTENT_TYPE,
538
584
  Vary: VINEXT_RSC_VARY_HEADER
539
585
  });
540
- if (!(options.pprRuntime !== void 0 || options.resolveRouteStaticEligible(sourceRoute)) || isDraftMode || isInterceptSourceKnownDynamic) interceptHeaders.set("Cache-Control", resolveUncacheableCacheControl(options.isProduction));
586
+ if (Object.keys(navigationParams).length > 0) interceptHeaders.set(VINEXT_PARAMS_HEADER, encodeURIComponent(JSON.stringify(navigationParams)));
587
+ if (!(options.pprRuntime !== void 0 || interceptConfig?.isStaticEligible === true) || isDraftMode || isInterceptKnownDynamic || options.isProduction && !isInterceptRequestIndependent) interceptHeaders.set("Cache-Control", resolveUncacheableCacheControl(options.isProduction));
541
588
  mergeMiddlewareResponseHeaders(interceptHeaders, options.middlewareContext.headers);
542
589
  applyRscCompatibilityIdHeader(interceptHeaders);
543
590
  applyRscDeploymentIdHeader(interceptHeaders);
@@ -546,11 +593,10 @@ async function dispatchAppPageInner(options) {
546
593
  headers: interceptHeaders
547
594
  });
548
595
  },
549
- async resolveSearchParams(sourceRoute, searchParams) {
596
+ async resolveSearchParams(sourceRoute, searchParams, interceptOpts) {
550
597
  await options.ensureRouteLoaded?.(sourceRoute);
551
- interceptDynamicConfig = options.resolveRouteDynamicConfig?.(sourceRoute);
552
- interceptDynamicConfigResolved = true;
553
- return interceptDynamicConfig === "force-static" ? new URLSearchParams() : searchParams;
598
+ interceptConfig = resolveAppPageInterceptSegmentConfig(sourceRoute, interceptOpts);
599
+ return interceptConfig.dynamicConfig === "force-static" ? new URLSearchParams() : searchParams;
554
600
  },
555
601
  searchParams: options.searchParams,
556
602
  setNavigationContext: options.setNavigationContext,
@@ -568,6 +614,7 @@ async function dispatchAppPageInner(options) {
568
614
  observeMetadataSearchParamsAccess: !isForceStatic,
569
615
  observePageSearchParamsAccess: !isForceStatic,
570
616
  isUncacheableRender,
617
+ routeTreeOnlyPrefetchShell,
571
618
  mountedLayouts: interceptResult.interceptOpts ? null : mountedLayouts,
572
619
  serveStreamingMetadata: placeGeneratedMetadataInBody,
573
620
  placeStreamedMetadataInHead: options.renderWholeDocument === true,
@@ -66,6 +66,8 @@ export type AppPagePageRequest<TModule extends AppPageModule = AppPageModule> =
66
66
  isForceStatic?: boolean;
67
67
  /** The render can never be stored (see buildAppPageElements). */
68
68
  isUncacheableRender?: boolean;
69
+ /** A loading shell without a loading boundary is the route tree (see buildAppPageElements). */
70
+ routeTreeOnlyPrefetchShell?: boolean;
69
71
  /** Layouts the navigating client holds (see buildAppPageElements). */
70
72
  mountedLayouts?: ReadonlySet<string> | null;
71
73
  /** Observe page metadata `searchParams` access for cache-safety classification. */
@@ -116,24 +118,6 @@ export type BuildPageElementsOptions<TModule extends AppPageModule = AppPageModu
116
118
  htmlLimitedBots?: string;
117
119
  scriptNonce?: string;
118
120
  };
119
- type AppPageNavigationParamModule = {
120
- default?: unknown;
121
- };
122
- type AppPageNavigationParamSlot = {
123
- default?: AppPageNavigationParamModule | null;
124
- page?: AppPageNavigationParamModule | null;
125
- slotPatternParts?: readonly string[] | null;
126
- slotParamNames?: readonly string[] | null;
127
- };
128
- type AppPageNavigationParamRoute = {
129
- params?: readonly string[] | null;
130
- slots?: Readonly<Record<string, AppPageNavigationParamSlot>> | null;
131
- };
132
- type AppPageNavigationParamInterceptOptions = {
133
- interceptPage?: unknown;
134
- interceptParams?: AppPageParams | null;
135
- interceptSlotKey?: string | null;
136
- };
137
121
  /**
138
122
  * Build the App Router element tree for a matched route.
139
123
  *
@@ -151,6 +135,15 @@ type AppPageNavigationParamInterceptOptions = {
151
135
  * {@link https://github.com/vercel/next.js/blob/canary/packages/next/src/server/app-render/create-metadata.tsx|create-metadata.tsx}.
152
136
  */
153
137
  export declare function buildPageElements<TModule extends AppPageModule = AppPageModule, TErrorModule extends AppPageErrorModule = AppPageErrorModule>(options: BuildPageElementsOptions<TModule, TErrorModule>): Promise<AppElements>;
138
+ /**
139
+ * The state key of each segment a sibling intercept's levels retain, from the
140
+ * app root down to the segment its element renders, so its Activity lists key
141
+ * like Next.js's for the intercepting route: the marker segment carries its
142
+ * marker, and a dynamic marker segment keys per value. The intercepting
143
+ * route's own layouts and boundaries render inside its page element, so the
144
+ * levels stop above the first of them.
145
+ */
146
+ export declare function resolveSiblingInterceptSegmentKeys(sourcePageSegments: readonly string[] | null | undefined, routeSegments: readonly string[] | null | undefined, opts: AppPageInterceptOptions | null | undefined, routeParams: AppPageParams, interceptParams: AppPageParams): readonly string[] | null;
154
147
  export declare const APP_PAGE_INTERCEPTION_MARKER_TRAVERSALS: readonly [{
155
148
  readonly prefix: "(...)";
156
149
  readonly levels: number;
@@ -172,7 +165,5 @@ export declare const APP_PAGE_INTERCEPTION_MARKER_TRAVERSALS: readonly [{
172
165
  */
173
166
  export declare function resolveInterceptedSlotIdentitySegments(sourcePageSegments: readonly string[] | null | undefined, slotKey: string): readonly AppPageSemanticSegment[] | null;
174
167
  export declare function resolveInterceptedSlotSegments(sourcePageSegments: readonly string[] | null | undefined, slotKey: string): readonly string[] | null;
175
- export declare function resolveSlotParamOverrides(route: AppPageNavigationParamRoute, routePath: string): Readonly<Record<string, AppPageParams>> | null;
176
- export declare function resolveAppPageNavigationParams(route: AppPageNavigationParamRoute, routeParams: AppPageParams, routePath: string, opts?: AppPageNavigationParamInterceptOptions | null): AppPageParams;
177
168
  //#endregion
178
169
  export type { AppPageErrorModule, AppPageRouteWiringRoute };
@@ -1,9 +1,8 @@
1
1
  import { isPromiseLike } from "../utils/promise.js";
2
2
  import { APP_RSC_RENDER_MODE_NAVIGATION } from "./app-rsc-render-mode.js";
3
- import { matchRoutePattern } from "../routing/route-pattern.js";
4
3
  import { AppElementsWire } from "./app-elements-wire.js";
5
4
  import "./app-elements.js";
6
- import { APP_PAGE_SEGMENT_KEY, isAppPageRouteGroupSegment, resolveAppPagePatternStateKey, resolveAppPageRouteStateKey } from "./app-page-segment-state.js";
5
+ import { APP_PAGE_SEGMENT_KEY, isAppPageRouteGroupSegment, resolveAppPagePatternStateKey, resolveAppPageRouteStateKey, resolveAppPageSemanticSegmentStateKey } from "./app-page-segment-state.js";
7
6
  import { ErrorBoundary, ForbiddenBoundary, NotFoundBoundary, UnauthorizedBoundary } from "../shims/error-boundary.js";
8
7
  import { withUseCacheLayoutMarker, withUseCachePageMarker } from "../shims/internal/app-page-props-cache-key.js";
9
8
  import { makeThenableParams } from "../shims/thenable-params.js";
@@ -12,15 +11,16 @@ import { createAppPageMetadataSearchParamsObserver, makeObservedAppPageSearchPar
12
11
  import { resolveAppPageBranchParams } from "./app-page-params.js";
13
12
  import { collectAppPageSearchParams, hasAppPageDynamicMetadata, prepareAppPageHead, resolveActiveParallelRouteHeadInputs, resolveInterceptLayoutsBesidePage, slotInterceptKeepsSourceHead } from "./app-page-head.js";
14
13
  import { createRouteNotFoundHeadPlanOptions, recoverAppPageRouteHead } from "./app-page-http-access-fallback-metadata.js";
15
- import { ClientPageRoot } from "../shims/client-page-root.js";
16
14
  import "./app-rsc-route-matching.js";
15
+ import { resolveSlotParamOverrides } from "./app-page-navigation-params.js";
17
16
  import { createAppPageRenderDependency, invokeAppComponent, isAppClientReference, isAppRenderSuspension, isReactOwnedAppComponent, renderAfterAppDependencies } from "./app-render-dependency.js";
18
17
  import { sanitizeErrorForClient } from "./app-rsc-errors.js";
19
18
  import { resolveAppPageModuleTraceSegment, traceCreateComponentTree, traceGetLayoutOrPageModule } from "./app-page-tracing.js";
20
19
  import { buildAppPageElements, createAppPageSourcePage, createAppPageTreePath, resolveAppPageLoadingModuleAtOrAbove } from "./app-page-route-wiring.js";
21
20
  import { DEFAULT_GLOBAL_ERROR_MODULE } from "./default-global-error-module.js";
22
- import { createAppPageRenderIdentity } from "./app-page-render-identity.js";
23
21
  import { shouldServeStreamingMetadata } from "./streaming-metadata.js";
22
+ import { ClientPageRoot } from "../shims/client-page-root.js";
23
+ import { createAppPageRenderIdentity } from "./app-page-render-identity.js";
24
24
  import { Fragment, Suspense, cache, createElement } from "react";
25
25
  //#region src/server/app-page-element-builder.ts
26
26
  /**
@@ -107,7 +107,7 @@ function traceAppPageInterceptLayoutModules(modules, branchSegments, layoutSegme
107
107
  async function buildPageElements(options) {
108
108
  const { route, params, routePath, displayPathname = routePath, pageRequest, globalErrorModule, rootNotFoundModule, rootForbiddenModule, rootUnauthorizedModule, metadataRoutes } = options;
109
109
  const slotParamOverrides = resolveSlotParamOverrides(route, routePath);
110
- const { opts, searchParams, isRscRequest, mountedSlotsHeader, renderMode = APP_RSC_RENDER_MODE_NAVIGATION, observeMetadataSearchParamsAccess = false, observePageSearchParamsAccess = false, isForceStatic = false, isUncacheableRender = false, mountedLayouts = null, serveStreamingMetadata, placeStreamedMetadataInHead = false, isProduction = process.env.NODE_ENV === "production", onHeadPrepared } = pageRequest;
110
+ const { opts, searchParams, isRscRequest, mountedSlotsHeader, renderMode = APP_RSC_RENDER_MODE_NAVIGATION, observeMetadataSearchParamsAccess = false, observePageSearchParamsAccess = false, isForceStatic = false, isUncacheableRender = false, routeTreeOnlyPrefetchShell = false, mountedLayouts = null, serveStreamingMetadata, placeStreamedMetadataInHead = false, isProduction = process.env.NODE_ENV === "production", onHeadPrepared } = pageRequest;
111
111
  const pageModule = route.page;
112
112
  const isSiblingIntercept = opts?.interceptSlotKey === "__vinext_page_intercept" && !!opts?.interceptPage;
113
113
  const effectivePageModule = isSiblingIntercept ? opts.interceptPage : pageModule;
@@ -414,6 +414,7 @@ async function buildPageElements(options) {
414
414
  globalErrorModule: globalErrorModule ?? DEFAULT_GLOBAL_ERROR_MODULE,
415
415
  isRscRequest,
416
416
  isUncacheableRender,
417
+ routeTreeOnlyPrefetchShell,
417
418
  interceptionId: opts?.interceptionId ?? null,
418
419
  mountedLayouts,
419
420
  mountedSlotIds,
@@ -429,6 +430,7 @@ async function buildPageElements(options) {
429
430
  routePath,
430
431
  semanticPageIdentity,
431
432
  semanticInterceptionTargetRouteId: opts?.interceptTargetRouteGraphId ?? null,
433
+ siblingInterceptSegmentKeys: isSiblingIntercept ? resolveSiblingInterceptSegmentKeys(sourcePageSegments, route.routeSegments, opts, params, effectiveParams) : null,
432
434
  sourcePageSegments,
433
435
  rootNotFoundModule: rootNotFoundModule ?? null,
434
436
  rootForbiddenModule: rootForbiddenModule ?? null,
@@ -487,6 +489,37 @@ function buildSlotOverrides(route, routeParams, routePath, opts, interceptMetada
487
489
  }
488
490
  return Object.keys(overrides).length > 0 ? overrides : null;
489
491
  }
492
+ /**
493
+ * The state key of each segment a sibling intercept's levels retain, from the
494
+ * app root down to the segment its element renders, so its Activity lists key
495
+ * like Next.js's for the intercepting route: the marker segment carries its
496
+ * marker, and a dynamic marker segment keys per value. The intercepting
497
+ * route's own layouts and boundaries render inside its page element, so the
498
+ * levels stop above the first of them.
499
+ */
500
+ function resolveSiblingInterceptSegmentKeys(sourcePageSegments, routeSegments, opts, routeParams, interceptParams) {
501
+ if (!sourcePageSegments || !routeSegments) return null;
502
+ const markerIndex = sourcePageSegments.findIndex((segment) => APP_PAGE_INTERCEPTION_MARKER_TRAVERSALS.some(({ prefix }) => segment.startsWith(prefix)));
503
+ if (markerIndex < 0) return null;
504
+ if (routeSegments.length !== markerIndex || routeSegments.some((segment, index) => segment !== sourcePageSegments[index])) return null;
505
+ const branchTreePositions = [
506
+ ...(opts?.interceptLayouts ?? []).flatMap((layoutModule, index) => layoutModule?.default ? [opts?.interceptLayoutSegments?.[index]?.length ?? 0] : []),
507
+ ...opts?.interceptLoadingTreePositions ?? [],
508
+ ...opts?.interceptNotFoundTreePositions ?? [],
509
+ ...opts?.interceptForbiddenTreePositions ?? [],
510
+ ...opts?.interceptUnauthorizedTreePositions ?? [],
511
+ ...opts?.interceptErrorTreePositions ?? []
512
+ ];
513
+ const segmentCount = Math.max(markerIndex, Math.min(sourcePageSegments.length, markerIndex + Math.min(...branchTreePositions) - 1));
514
+ return sourcePageSegments.slice(0, segmentCount).map((segment, index) => {
515
+ const marker = index === markerIndex ? APP_PAGE_INTERCEPTION_MARKER_TRAVERSALS.find(({ prefix }) => segment.startsWith(prefix)) : void 0;
516
+ return resolveAppPageSemanticSegmentStateKey({
517
+ marker: marker?.prefix ?? null,
518
+ paramSource: "route",
519
+ segment: marker ? segment.slice(marker.prefix.length) : segment
520
+ }, index < markerIndex ? routeParams : interceptParams);
521
+ });
522
+ }
490
523
  const APP_PAGE_INTERCEPTION_MARKER_TRAVERSALS = [
491
524
  {
492
525
  prefix: "(...)",
@@ -581,49 +614,5 @@ function resolveInterceptedSlotSegments(sourcePageSegments, slotKey) {
581
614
  routeSegments.push(...sourcePageSegments.slice(markerIndex + 1).filter(isVisibleInterceptedSlotSegment));
582
615
  return routeSegments;
583
616
  }
584
- function resolveSlotParamOverrides(route, routePath) {
585
- const overrides = {};
586
- const slots = route.slots;
587
- if (slots) {
588
- let urlParts = null;
589
- const routeParamSet = collectParamNameSet(route.params);
590
- for (const [slotKey, slot] of Object.entries(slots)) {
591
- const patternParts = slot.slotPatternParts;
592
- const paramNames = slot.slotParamNames;
593
- if (!patternParts || patternParts.length === 0) continue;
594
- if (paramNames && paramNames.every((name) => routeParamSet.has(name))) continue;
595
- if (urlParts === null) urlParts = routePath.split("/").filter(Boolean);
596
- const matched = matchRoutePattern(urlParts, patternParts);
597
- if (!matched) continue;
598
- overrides[slotKey] = matched;
599
- }
600
- }
601
- return Object.keys(overrides).length > 0 ? overrides : null;
602
- }
603
- function mergeAppPageParams(target, source) {
604
- for (const [key, value] of Object.entries(source)) target[key] = value;
605
- }
606
- function isDefaultExportModule(module) {
607
- return typeof module === "object" && module !== null;
608
- }
609
- function hasDefaultExport(module) {
610
- if (!isDefaultExportModule(module)) return false;
611
- return module?.default !== null && module?.default !== void 0;
612
- }
613
- function resolveAppPageNavigationParams(route, routeParams, routePath, opts) {
614
- const navigationParams = { ...routeParams };
615
- const slotParamOverrides = resolveSlotParamOverrides(route, routePath);
616
- for (const [slotKey, slot] of Object.entries(route.slots ?? {})) {
617
- const isInterceptedSlot = opts?.interceptSlotKey === slotKey && opts.interceptSlotKey !== "__vinext_page_intercept" && hasDefaultExport(opts.interceptPage);
618
- if (!isInterceptedSlot && !hasDefaultExport(slot.page) && !hasDefaultExport(slot.default)) continue;
619
- mergeAppPageParams(navigationParams, isInterceptedSlot ? opts?.interceptParams ?? routeParams : slotParamOverrides?.[slotKey] ?? routeParams);
620
- }
621
- return navigationParams;
622
- }
623
- function collectParamNameSet(params) {
624
- const set = /* @__PURE__ */ new Set();
625
- if (params) for (const name of params) set.add(name);
626
- return set;
627
- }
628
617
  //#endregion
629
- export { APP_PAGE_INTERCEPTION_MARKER_TRAVERSALS, buildPageElements, resolveAppPageNavigationParams, resolveInterceptedSlotIdentitySegments, resolveInterceptedSlotSegments, resolveSlotParamOverrides };
618
+ export { APP_PAGE_INTERCEPTION_MARKER_TRAVERSALS, buildPageElements, resolveInterceptedSlotIdentitySegments, resolveInterceptedSlotSegments, resolveSiblingInterceptSegmentKeys };
@@ -0,0 +1,56 @@
1
+ import { FetchCacheMode } from "../shims/fetch-cache-state.js";
2
+ import "../shims/fetch-cache.js";
3
+ //#region src/server/app-page-intercept-segment-config.d.ts
4
+ type SegmentModule = Record<string, unknown>;
5
+ type AppPageInterceptSegmentConfigSlot = {
6
+ configLayouts?: readonly (SegmentModule | null | undefined)[] | null;
7
+ configLayoutTreePositions?: readonly number[] | null;
8
+ default?: SegmentModule | null;
9
+ layout?: SegmentModule | null;
10
+ layoutIndex?: number;
11
+ name?: string;
12
+ ownerTreePosition?: number | null;
13
+ page?: SegmentModule | null;
14
+ routeSegments?: readonly string[] | null;
15
+ };
16
+ /** The parts of the route an interception renders under that its config reads. */
17
+ export type AppPageInterceptSegmentConfigRoute = {
18
+ layouts?: readonly (SegmentModule | null | undefined)[];
19
+ layoutTreePositions?: readonly number[];
20
+ routeSegments?: readonly string[];
21
+ slots?: Readonly<Record<string, AppPageInterceptSegmentConfigSlot>> | null;
22
+ };
23
+ /** The parts of the interception's options its config reads. */
24
+ export type AppPageInterceptSegmentConfigOptions = {
25
+ interceptBranchSegments?: readonly string[] | null;
26
+ interceptLayoutSegments?: readonly (readonly string[])[] | null;
27
+ interceptLayouts?: readonly unknown[] | null;
28
+ interceptPage?: unknown;
29
+ interceptSlotKey: string;
30
+ interceptSourcePageSegments?: readonly string[] | null;
31
+ };
32
+ export type AppPageInterceptSegmentConfig = {
33
+ dynamicConfig: string | undefined;
34
+ dynamicStaleTimeSeconds: number | undefined;
35
+ fetchCacheMode: FetchCacheMode | null;
36
+ /** Whether any segment of the interception exports `generateStaticParams`. */
37
+ hasAnyGenerateStaticParams: boolean;
38
+ /** Whether one sits at or below the interception's last dynamic segment. */
39
+ hasGenerateStaticParams: boolean;
40
+ /** Whether the interception's own segments choose the edge runtime. */
41
+ isEdgeRuntime: boolean;
42
+ isStaticEligible: boolean;
43
+ isStaticGenerationEdgeRuntime: boolean;
44
+ revalidateSeconds: number | null;
45
+ };
46
+ /**
47
+ * Next.js renders an interception as its own route, whose loader tree holds
48
+ * the owner's layouts and the intercepting page, never the source's page, so
49
+ * its segment config comes from those modules alone. A sibling intercept's
50
+ * branch takes the children position below its owner folder; a slot
51
+ * intercept's branch takes its slot, beside the other slots of the owner's
52
+ * layouts, and children renders the owner's default.
53
+ */
54
+ export declare function resolveAppPageInterceptSegmentConfig(route: AppPageInterceptSegmentConfigRoute, interceptOpts: AppPageInterceptSegmentConfigOptions): AppPageInterceptSegmentConfig;
55
+ //#endregion
56
+ export {};