@qzsy/vinext 0.1.12 → 0.1.80

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. package/README.md +19 -5
  2. package/dist/build/inject-pregenerated-paths.d.ts +4 -0
  3. package/dist/build/inject-pregenerated-paths.js +18 -0
  4. package/dist/build/pages-client-assets-module.d.ts +11 -0
  5. package/dist/build/pages-client-assets-module.js +27 -0
  6. package/dist/build/prerender.d.ts +2 -1
  7. package/dist/build/prerender.js +11 -4
  8. package/dist/build/report.d.ts +2 -1
  9. package/dist/build/report.js +2 -1
  10. package/dist/build/run-prerender.d.ts +7 -0
  11. package/dist/build/run-prerender.js +9 -0
  12. package/dist/build/standalone.js +2 -0
  13. package/dist/check.d.ts +18 -0
  14. package/dist/check.js +77 -19
  15. package/dist/cli-dev-config.d.ts +12 -0
  16. package/dist/cli-dev-config.js +23 -0
  17. package/dist/cli.js +64 -28
  18. package/dist/{server → client}/dev-error-overlay-store.d.ts +1 -1
  19. package/dist/{server → client}/dev-error-overlay-store.js +1 -1
  20. package/dist/{server → client}/dev-error-overlay.d.ts +1 -1
  21. package/dist/{server → client}/dev-error-overlay.js +2 -2
  22. package/dist/cloudflare/deploy-config.d.ts +51 -0
  23. package/dist/cloudflare/deploy-config.js +153 -0
  24. package/dist/cloudflare/index.d.ts +1 -1
  25. package/dist/cloudflare/index.js +1 -1
  26. package/dist/cloudflare/project.d.ts +41 -0
  27. package/dist/cloudflare/project.js +243 -0
  28. package/dist/cloudflare/tpr.js +1 -1
  29. package/dist/config/config-matchers.js +14 -10
  30. package/dist/config/next-config.d.ts +6 -3
  31. package/dist/config/next-config.js +47 -1
  32. package/dist/config/server-external-packages.d.ts +4 -0
  33. package/dist/config/server-external-packages.js +91 -0
  34. package/dist/deploy.d.ts +2 -122
  35. package/dist/deploy.js +20 -793
  36. package/dist/entries/app-rsc-entry.d.ts +2 -1
  37. package/dist/entries/app-rsc-entry.js +70 -12
  38. package/dist/entries/app-rsc-manifest.js +8 -0
  39. package/dist/entries/pages-client-entry.d.ts +1 -0
  40. package/dist/entries/pages-client-entry.js +2 -1
  41. package/dist/entries/pages-server-entry.js +6 -2
  42. package/dist/image/image-adapters-virtual.d.ts +59 -0
  43. package/dist/image/image-adapters-virtual.js +50 -0
  44. package/dist/index.d.ts +12 -0
  45. package/dist/index.js +158 -109
  46. package/dist/init-cloudflare.d.ts +43 -0
  47. package/dist/init-cloudflare.js +1000 -0
  48. package/dist/init-platform.d.ts +38 -0
  49. package/dist/init-platform.js +150 -0
  50. package/dist/init.d.ts +14 -37
  51. package/dist/init.js +205 -95
  52. package/dist/node_modules/.pnpm/am-i-vibing@0.5.0/node_modules/am-i-vibing/dist/detector-1yx2Hoe0.js +294 -0
  53. package/dist/node_modules/.pnpm/process-ancestry@0.1.0/node_modules/process-ancestry/dist/index.js +94 -0
  54. package/dist/{cloudflare → packages/cloudflare}/src/cache/cdn-adapter.runtime.js +1 -1
  55. package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.d.ts +2 -2
  56. package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.js +1 -1
  57. package/dist/plugins/ast-scope.d.ts +16 -0
  58. package/dist/plugins/ast-scope.js +62 -0
  59. package/dist/plugins/ast-utils.js +3 -0
  60. package/dist/plugins/css-module-imports.d.ts +14 -0
  61. package/dist/plugins/css-module-imports.js +59 -0
  62. package/dist/plugins/ignore-dynamic-requests.d.ts +11 -0
  63. package/dist/plugins/ignore-dynamic-requests.js +530 -0
  64. package/dist/plugins/middleware-server-only.d.ts +8 -6
  65. package/dist/plugins/middleware-server-only.js +8 -7
  66. package/dist/plugins/optimize-imports.js +1 -1
  67. package/dist/plugins/typeof-window.d.ts +1 -1
  68. package/dist/plugins/typeof-window.js +28 -56
  69. package/dist/routing/app-route-graph.d.ts +13 -2
  70. package/dist/routing/app-route-graph.js +116 -32
  71. package/dist/routing/app-router.d.ts +5 -0
  72. package/dist/routing/app-router.js +5 -0
  73. package/dist/routing/file-matcher.d.ts +8 -0
  74. package/dist/routing/file-matcher.js +10 -1
  75. package/dist/routing/pages-router.js +2 -2
  76. package/dist/server/app-browser-action-result.d.ts +2 -1
  77. package/dist/server/app-browser-action-result.js +5 -1
  78. package/dist/server/app-browser-entry.js +17 -12
  79. package/dist/server/app-browser-history-controller.d.ts +2 -1
  80. package/dist/server/app-browser-history-controller.js +6 -2
  81. package/dist/server/app-browser-interception-context.d.ts +1 -0
  82. package/dist/server/app-browser-interception-context.js +4 -2
  83. package/dist/server/app-browser-navigation-controller.js +1 -0
  84. package/dist/server/app-browser-server-action-client.js +2 -3
  85. package/dist/server/app-browser-state.d.ts +1 -0
  86. package/dist/server/app-browser-state.js +3 -2
  87. package/dist/server/app-fallback-renderer.d.ts +3 -2
  88. package/dist/server/app-fallback-renderer.js +12 -7
  89. package/dist/server/app-middleware.d.ts +2 -3
  90. package/dist/server/app-middleware.js +3 -2
  91. package/dist/server/app-optimistic-routing.js +1 -1
  92. package/dist/server/app-page-boundary-render.d.ts +1 -0
  93. package/dist/server/app-page-boundary-render.js +12 -3
  94. package/dist/server/app-page-cache-finalizer.d.ts +1 -0
  95. package/dist/server/app-page-cache-finalizer.js +10 -3
  96. package/dist/server/app-page-cache-render.d.ts +1 -0
  97. package/dist/server/app-page-cache-render.js +8 -4
  98. package/dist/server/app-page-cache.d.ts +1 -0
  99. package/dist/server/app-page-cache.js +4 -1
  100. package/dist/server/app-page-dispatch.d.ts +11 -3
  101. package/dist/server/app-page-dispatch.js +55 -15
  102. package/dist/server/app-page-element-builder.d.ts +5 -1
  103. package/dist/server/app-page-element-builder.js +57 -20
  104. package/dist/server/app-page-head.d.ts +12 -0
  105. package/dist/server/app-page-head.js +42 -19
  106. package/dist/server/app-page-params.d.ts +2 -1
  107. package/dist/server/app-page-params.js +8 -1
  108. package/dist/server/app-page-probe.d.ts +1 -0
  109. package/dist/server/app-page-probe.js +6 -1
  110. package/dist/server/app-page-render-identity.d.ts +1 -0
  111. package/dist/server/app-page-render-identity.js +1 -1
  112. package/dist/server/app-page-render.d.ts +4 -1
  113. package/dist/server/app-page-render.js +8 -3
  114. package/dist/server/app-page-request.d.ts +22 -1
  115. package/dist/server/app-page-request.js +89 -13
  116. package/dist/server/app-page-route-wiring.d.ts +6 -1
  117. package/dist/server/app-page-route-wiring.js +31 -15
  118. package/dist/server/app-page-search-params-observation.d.ts +4 -2
  119. package/dist/server/app-page-search-params-observation.js +11 -7
  120. package/dist/server/app-page-segment-state.js +2 -0
  121. package/dist/server/app-route-handler-dispatch.js +1 -0
  122. package/dist/server/app-route-handler-execution.js +7 -2
  123. package/dist/server/app-route-handler-response.js +1 -0
  124. package/dist/server/app-route-handler-runtime.js +1 -1
  125. package/dist/server/app-route-module-loader.d.ts +2 -0
  126. package/dist/server/app-route-module-loader.js +1 -0
  127. package/dist/server/app-router-entry.d.ts +12 -0
  128. package/dist/server/app-router-entry.js +22 -8
  129. package/dist/server/app-router-image-optimization.d.ts +37 -0
  130. package/dist/server/app-router-image-optimization.js +40 -0
  131. package/dist/server/app-rsc-errors.js +7 -1
  132. package/dist/server/app-rsc-handler.js +27 -14
  133. package/dist/server/app-rsc-route-matching.d.ts +7 -0
  134. package/dist/server/app-rsc-route-matching.js +36 -3
  135. package/dist/server/app-segment-config.d.ts +12 -0
  136. package/dist/server/app-segment-config.js +91 -5
  137. package/dist/server/app-server-action-execution.d.ts +5 -0
  138. package/dist/server/app-server-action-execution.js +94 -33
  139. package/dist/server/app-ssr-entry.js +12 -1
  140. package/dist/server/app-static-generation.d.ts +1 -0
  141. package/dist/server/app-static-generation.js +1 -0
  142. package/dist/server/client-trace-metadata.js +26 -0
  143. package/dist/server/default-global-not-found-module.d.ts +14 -0
  144. package/dist/server/default-global-not-found-module.js +14 -0
  145. package/dist/server/dev-server.js +8 -15
  146. package/dist/server/dev-stack-sourcemap.d.ts +1 -1
  147. package/dist/server/dev-stack-sourcemap.js +1 -1
  148. package/dist/server/headers.d.ts +5 -15
  149. package/dist/server/headers.js +4 -15
  150. package/dist/server/image-optimization.d.ts +51 -1
  151. package/dist/server/image-optimization.js +52 -2
  152. package/dist/server/isr-cache.d.ts +1 -1
  153. package/dist/server/isr-cache.js +2 -2
  154. package/dist/server/middleware-runtime.js +6 -1
  155. package/dist/server/navigation-planner.d.ts +1 -0
  156. package/dist/server/navigation-planner.js +14 -3
  157. package/dist/server/pages-asset-tags.d.ts +4 -6
  158. package/dist/server/pages-asset-tags.js +12 -12
  159. package/dist/server/pages-client-assets.d.ts +12 -0
  160. package/dist/server/pages-client-assets.js +10 -0
  161. package/dist/server/pages-page-data.d.ts +23 -1
  162. package/dist/server/pages-page-data.js +43 -24
  163. package/dist/server/pages-page-handler.d.ts +2 -1
  164. package/dist/server/pages-page-handler.js +10 -4
  165. package/dist/server/pages-request-pipeline.d.ts +2 -0
  166. package/dist/server/pages-request-pipeline.js +25 -1
  167. package/dist/server/prerender-manifest.d.ts +3 -1
  168. package/dist/server/prerender-route-params.js +1 -1
  169. package/dist/server/prod-server.d.ts +1 -1
  170. package/dist/server/prod-server.js +47 -25
  171. package/dist/server/request-pipeline.js +1 -0
  172. package/dist/server/seed-cache.js +4 -4
  173. package/dist/server/worker-utils.d.ts +2 -1
  174. package/dist/server/worker-utils.js +7 -1
  175. package/dist/shims/app-router-scroll-state.d.ts +1 -0
  176. package/dist/shims/app-router-scroll-state.js +1 -0
  177. package/dist/shims/app-router-scroll.js +2 -1
  178. package/dist/shims/cache.js +19 -15
  179. package/dist/shims/cdn-cache.js +1 -1
  180. package/dist/shims/dynamic-preload-chunks.js +2 -1
  181. package/dist/shims/error-boundary.d.ts +19 -1
  182. package/dist/shims/error-boundary.js +11 -1
  183. package/dist/shims/form.d.ts +3 -1
  184. package/dist/shims/form.js +37 -43
  185. package/dist/shims/headers.d.ts +9 -1
  186. package/dist/shims/headers.js +31 -6
  187. package/dist/shims/image-optimization-url.d.ts +4 -0
  188. package/dist/shims/image-optimization-url.js +33 -1
  189. package/dist/shims/image.js +46 -13
  190. package/dist/shims/internal/app-route-detection.d.ts +2 -17
  191. package/dist/shims/internal/app-route-detection.js +4 -17
  192. package/dist/shims/internal/hybrid-client-route-owner-direct.d.ts +23 -0
  193. package/dist/shims/internal/hybrid-client-route-owner-direct.js +51 -0
  194. package/dist/shims/internal/hybrid-client-route-owner.d.ts +2 -5
  195. package/dist/shims/internal/hybrid-client-route-owner.js +9 -60
  196. package/dist/shims/internal/pages-router-components.d.ts +7 -0
  197. package/dist/shims/internal/pages-router-components.js +13 -0
  198. package/dist/shims/link.js +23 -16
  199. package/dist/shims/metadata.d.ts +3 -2
  200. package/dist/shims/metadata.js +8 -4
  201. package/dist/shims/navigation.js +4 -2
  202. package/dist/shims/root-params.d.ts +15 -1
  203. package/dist/shims/root-params.js +21 -1
  204. package/dist/shims/router.d.ts +2 -5
  205. package/dist/shims/router.js +41 -22
  206. package/dist/shims/server.js +3 -2
  207. package/dist/typegen.js +6 -5
  208. package/dist/utils/client-runtime-metadata.d.ts +2 -18
  209. package/dist/utils/client-runtime-metadata.js +31 -22
  210. package/dist/utils/dev-stack-sourcemap-endpoint.d.ts +4 -0
  211. package/dist/{server → utils}/dev-stack-sourcemap-endpoint.js +1 -1
  212. package/dist/utils/domain-locale.d.ts +6 -3
  213. package/dist/{server → utils}/middleware-request-headers.d.ts +1 -1
  214. package/dist/{server → utils}/middleware-request-headers.js +2 -2
  215. package/dist/utils/path.d.ts +2 -1
  216. package/dist/utils/path.js +1 -1
  217. package/dist/utils/project.d.ts +9 -1
  218. package/dist/utils/project.js +21 -4
  219. package/dist/utils/protocol-headers.d.ts +17 -0
  220. package/dist/utils/protocol-headers.js +17 -0
  221. package/dist/utils/react-version.d.ts +4 -0
  222. package/dist/utils/react-version.js +44 -0
  223. package/package.json +6 -1
  224. package/dist/server/dev-stack-sourcemap-endpoint.d.ts +0 -4
  225. /package/dist/{cloudflare → packages/cloudflare}/src/utils/cache-control-metadata.js +0 -0
@@ -248,8 +248,11 @@ function wrapRscResponseForDevErrorReporting(response, consumeInvalidDynamicUsag
248
248
  });
249
249
  }
250
250
  async function renderAppPageLifecycle(options) {
251
+ const configuredProbePageBeforeRender = options.probePageBeforeRender ?? options.isRscRequest;
252
+ const probePageBeforeRender = options.isRscRequest || configuredProbePageBeforeRender && !(options.peekDynamicUsage?.() ?? false);
251
253
  const preRenderResult = await probeAppPageBeforeRender({
252
254
  hasLoadingBoundary: options.hasLoadingBoundary,
255
+ probePageBeforeRender,
253
256
  skipProbes: options.pprFallbackShellSignal !== void 0,
254
257
  layoutCount: options.layoutCount,
255
258
  probeLayoutAt(layoutIndex) {
@@ -430,7 +433,8 @@ async function renderAppPageLifecycle(options) {
430
433
  if (!options.isProduction) renderEnd = performance.now();
431
434
  },
432
435
  renderErrorBoundaryResponse(error) {
433
- return options.renderErrorBoundaryResponse(rscErrorTracker.getCapturedError() ?? error);
436
+ const capturedRscError = rscErrorTracker.getCapturedError();
437
+ return options.renderErrorBoundaryResponse(capturedRscError ?? error, capturedRscError === null ? "ssr" : "rsc");
434
438
  },
435
439
  async renderHtmlStream() {
436
440
  const ssrHandler = await options.loadSsrHandler();
@@ -462,7 +466,7 @@ async function renderAppPageLifecycle(options) {
462
466
  if (!htmlStream) throw new Error("[vinext] Expected an HTML stream when no fallback response was returned");
463
467
  const linkHeader = buildAppPageLinkHeader(htmlRender.linkHeader, fontLinkHeader, options.reactMaxHeadersLength);
464
468
  if (options.isPrerender === true) await htmlRender.metadataReady;
465
- if (options.hasLoadingBoundary) {
469
+ if (options.hasLoadingBoundary || !probePageBeforeRender) {
466
470
  const captured = rscErrorTracker.getCapturedSpecialError();
467
471
  if (captured) {
468
472
  const specialError = resolveAppPageSpecialError(captured);
@@ -480,8 +484,8 @@ async function renderAppPageLifecycle(options) {
480
484
  revalidateSeconds
481
485
  }));
482
486
  }
487
+ let dynamicUsedDuringRender = options.consumeDynamicUsage();
483
488
  const draftCookie = options.getDraftModeCookieHeader();
484
- const dynamicUsedDuringRender = options.consumeDynamicUsage();
485
489
  let dynamicUsedBeforeContextCleanup = dynamicUsedDuringRender;
486
490
  const safeHtmlStream = deferUntilStreamConsumed(htmlStream, () => {
487
491
  dynamicUsedBeforeContextCleanup = dynamicUsedBeforeContextCleanup || options.consumeDynamicUsage();
@@ -575,6 +579,7 @@ async function renderAppPageLifecycle(options) {
575
579
  isrRscKey: options.isrRscKey,
576
580
  isrSet: options.isrSet,
577
581
  interceptionContext: options.interceptionContext,
582
+ omitPendingDynamicCacheState: options.omitPendingDynamicCacheState,
578
583
  preserveClientResponseHeaders: !htmlResponsePolicy.shouldWriteToCache,
579
584
  expireSeconds,
580
585
  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) => Promise<TElement>;
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) {
@@ -67,8 +130,9 @@ async function validateAppPageDynamicParams(options) {
67
130
  return notFoundResponse();
68
131
  }
69
132
  for (const source of generateStaticParamsSources) {
70
- const staticParams = await runWithFetchDedupe(() => source.generateStaticParams({ params: pickRouteParams(options.params, source.parentParamNames) }));
71
- if (Array.isArray(staticParams) && !areStaticParamsAllowed(options.params, staticParams)) {
133
+ const sourceParams = remapRouteParams(options.params, source);
134
+ const staticParams = await runWithFetchDedupe(() => source.generateStaticParams({ params: pickRouteParams(sourceParams, source.parentParamNames) }));
135
+ if (Array.isArray(staticParams) && !areStaticParamsAllowed(sourceParams, staticParams)) {
72
136
  options.clearRequestContext();
73
137
  return notFoundResponse();
74
138
  }
@@ -97,7 +161,7 @@ async function resolveAppPageInterceptMatch(options) {
97
161
  return {
98
162
  interceptOpts: options.toInterceptOpts(interceptState.intercept),
99
163
  matchedParams: interceptState.intercept.matchedParams,
100
- sourceParams: pickRouteParams(interceptState.intercept.matchedParams, options.getRouteParamNames(interceptState.sourceRoute)),
164
+ sourceParams: pickRouteParams(interceptState.intercept.sourceMatchedParams ?? interceptState.intercept.matchedParams, options.getRouteParamNames(interceptState.sourceRoute)),
101
165
  sourceRoute: interceptState.sourceRoute
102
166
  };
103
167
  }
@@ -145,12 +209,18 @@ async function resolveAppPageInterceptionRerenderTarget(options) {
145
209
  isRscRequest: options.isRscRequest,
146
210
  toInterceptOpts: options.toInterceptOpts
147
211
  });
148
- if (interceptState.kind === "source-route") return {
149
- interceptOpts: options.toInterceptOpts(interceptState.intercept),
150
- navigationParams: interceptState.intercept.matchedParams,
151
- params: pickRouteParams(interceptState.intercept.matchedParams, options.getRouteParamNames(interceptState.sourceRoute)),
152
- route: interceptState.sourceRoute
153
- };
212
+ if (interceptState.kind === "source-route") {
213
+ const sourceMatchedParams = interceptState.intercept.sourceMatchedParams ?? interceptState.intercept.matchedParams;
214
+ return {
215
+ interceptOpts: options.toInterceptOpts(interceptState.intercept),
216
+ navigationParams: {
217
+ ...sourceMatchedParams,
218
+ ...interceptState.intercept.matchedParams
219
+ },
220
+ params: pickRouteParams(sourceMatchedParams, options.getRouteParamNames(interceptState.sourceRoute)),
221
+ route: interceptState.sourceRoute
222
+ };
223
+ }
154
224
  return {
155
225
  interceptOpts: interceptState.kind === "current-route" ? options.toInterceptOpts(interceptState.intercept) : void 0,
156
226
  navigationParams: options.currentParams,
@@ -174,13 +244,19 @@ async function resolveAppPageIntercept(options) {
174
244
  if (interceptState.kind === "source-route") {
175
245
  const renderRoute = interceptState.sourceRoute;
176
246
  const interceptOpts = options.toInterceptOpts(interceptState.intercept);
177
- const renderParams = pickRouteParams(interceptState.intercept.matchedParams, options.getRouteParamNames(interceptState.sourceRoute));
247
+ const sourceMatchedParams = interceptState.intercept.sourceMatchedParams ?? interceptState.intercept.matchedParams;
248
+ const navigationParams = {
249
+ ...sourceMatchedParams,
250
+ ...interceptState.intercept.matchedParams
251
+ };
252
+ const renderSearchParams = options.resolveSearchParams ? await options.resolveSearchParams(renderRoute, options.searchParams) : options.searchParams;
253
+ const renderParams = pickRouteParams(sourceMatchedParams, options.getRouteParamNames(interceptState.sourceRoute));
178
254
  options.setNavigationContext({
179
- params: options.resolveNavigationParams(renderRoute, interceptState.intercept.matchedParams, options.cleanPathname, interceptOpts),
255
+ params: options.resolveNavigationParams(renderRoute, navigationParams, options.cleanPathname, interceptOpts),
180
256
  pathname: options.cleanPathname,
181
- searchParams: options.searchParams
257
+ searchParams: renderSearchParams
182
258
  });
183
- const interceptElement = await options.buildPageElement(renderRoute, renderParams, interceptOpts, options.searchParams, options.layoutParamAccess);
259
+ const interceptElement = await options.buildPageElement(renderRoute, renderParams, interceptOpts, renderSearchParams, options.layoutParamAccess);
184
260
  return {
185
261
  interceptOpts: void 0,
186
262
  response: await options.renderInterceptResponse(renderRoute, interceptElement)
@@ -1,8 +1,8 @@
1
1
  import { AppRouteSemanticIds } from "../routing/app-route-graph.js";
2
2
  import { AppElements, AppElementsInterception } from "./app-elements-wire.js";
3
3
  import { AppPageParams } from "./app-page-boundary.js";
4
- import { Metadata, Viewport } from "../shims/metadata.js";
5
4
  import { ThenableParamsObserver } from "../shims/thenable-params.js";
5
+ import { Metadata, Viewport } from "../shims/metadata.js";
6
6
  import { AppLayoutParamAccessTracker } from "./app-layout-param-observation.js";
7
7
  import { AppRscRenderMode } from "./app-rsc-render-mode.js";
8
8
  import { AppPageRenderIdentity } from "./app-page-render-identity.js";
@@ -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;
@@ -83,6 +85,8 @@ type AppPageRouteWiringRoute<TModule extends AppPageModule = AppPageModule, TErr
83
85
  templates?: readonly (TModule | null | undefined)[] | null;
84
86
  };
85
87
  type AppPageSlotOverride<TModule extends AppPageModule = AppPageModule> = {
88
+ branchSegments?: readonly string[] | null;
89
+ layoutSegments?: readonly (readonly string[])[] | null;
86
90
  layoutModules?: readonly (TModule | null | undefined)[] | null;
87
91
  /**
88
92
  * The page module to render for this slot. Optional — when omitted, the
@@ -118,6 +122,7 @@ type BuildAppPageRouteElementOptions<TModule extends AppPageModule = AppPageModu
118
122
  rootNotFoundModule?: TModule | null;
119
123
  rootUnauthorizedModule?: TModule | null;
120
124
  route: AppPageRouteWiringRoute<TModule, TErrorModule>;
125
+ createPageElement?: (component: AppPageComponent, props: Readonly<Record<string, unknown>>) => ReactNode;
121
126
  searchParams?: unknown;
122
127
  slotOverrides?: Readonly<Record<string, AppPageSlotOverride<TModule>>> | null;
123
128
  };
@@ -8,7 +8,7 @@ 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
13
  import { resolveAppPageChildSegments, resolveAppPageRouteStateKey, resolveAppPageSegmentStateKey } from "./app-page-segment-state.js";
14
14
  import { Fragment, Suspense } from "react";
@@ -16,6 +16,9 @@ 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
  }
@@ -249,13 +252,7 @@ function buildAppPageElements(options) {
249
252
  if (!templateComponent) continue;
250
253
  const TemplateComponent = templateComponent;
251
254
  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
- });
255
+ const templateElement = templateDependency ? renderWithAppDependencyBarrier(/* @__PURE__ */ jsx(TemplateComponent, { children: /* @__PURE__ */ jsx(Children$1, {}) }), templateDependency) : /* @__PURE__ */ jsx(TemplateComponent, { children: /* @__PURE__ */ jsx(Children$1, {}) });
259
256
  elements[templateEntry.id] = renderAfterAppDependencies(templateElement, templateDependenciesBeforeById.get(templateEntry.id) ?? []);
260
257
  }
261
258
  for (let index = 0; index < layoutEntries.length; index++) {
@@ -293,7 +290,9 @@ function buildAppPageElements(options) {
293
290
  const slotId = resolveAppPageSlotId(slot, layoutEntries[targetIndex]?.treePath ?? "/");
294
291
  const slotOverride = resolveSlotOverride(slotKey, slotName);
295
292
  const slotParams = getEffectiveSlotParams(slotKey, slotName);
296
- const slotResetKey = resolveAppPageRouteStateKey(slot.routeSegments ?? [], slotParams);
293
+ const slotRouteSegments = slot.routeSegments ?? [];
294
+ const slotOwnerParams = resolveAppPageSegmentParams(options.route.routeSegments, layoutEntries[targetIndex]?.treePosition ?? 0, options.matchedParams);
295
+ const slotResetKey = resolveAppPageRouteStateKey(slotRouteSegments, slotParams);
297
296
  const overrideOrPageComponent = getDefaultExport(slotOverride?.pageModule) ?? getDefaultExport(slot.page);
298
297
  const defaultComponent = getDefaultExport(slot.default);
299
298
  if (!overrideOrPageComponent && defaultComponent && options.isRscRequest && options.mountedSlotIds?.has(slotId)) continue;
@@ -302,23 +301,40 @@ function buildAppPageElements(options) {
302
301
  elements[slotId] = AppElementsWire.unmatchedSlotValue;
303
302
  continue;
304
303
  }
305
- const slotThenableParams = options.makeThenableParams(slotParams);
306
- const slotProps = { params: slotThenableParams };
304
+ const slotProps = { params: options.makeThenableParams(slotParams) };
307
305
  if (options.searchParams !== void 0) slotProps.searchParams = options.searchParams;
308
306
  if (slotOverride?.props) Object.assign(slotProps, slotOverride.props);
309
- let slotElement = /* @__PURE__ */ jsx(slotComponent, { ...slotProps });
307
+ let slotElement = options.createPageElement ? options.createPageElement(slotComponent, slotProps) : (() => {
308
+ return /* @__PURE__ */ jsx(slotComponent, { ...slotProps });
309
+ })();
310
+ const hasSlotTreeOverride = slotOverride?.pageModule != null || slotOverride?.layoutModules !== void 0;
310
311
  const interceptLayouts = slotOverride?.layoutModules ?? [];
311
312
  for (let layoutIndex = interceptLayouts.length - 1; layoutIndex >= 0; layoutIndex--) {
312
313
  const interceptLayoutComponent = getDefaultExport(interceptLayouts[layoutIndex]);
313
314
  if (!interceptLayoutComponent) continue;
314
- slotElement = /* @__PURE__ */ jsx(interceptLayoutComponent, {
315
- params: slotThenableParams,
315
+ const InterceptLayoutComponent = interceptLayoutComponent;
316
+ const interceptLayoutParams = resolveSlotLayoutParams(slotOverride?.branchSegments ?? slotRouteSegments, slotOverride?.layoutSegments?.[layoutIndex]?.length ?? slotRouteSegments.length, slotParams);
317
+ slotElement = /* @__PURE__ */ jsx(InterceptLayoutComponent, {
318
+ params: options.makeThenableParams(interceptLayoutParams),
319
+ children: slotElement
320
+ });
321
+ }
322
+ if (!hasSlotTreeOverride) for (let layoutIndex = (slot.configLayouts?.length ?? 0) - 1; layoutIndex >= 0; layoutIndex--) {
323
+ const nestedLayoutComponent = getDefaultExport(slot.configLayouts?.[layoutIndex]);
324
+ if (!nestedLayoutComponent) continue;
325
+ const NestedLayoutComponent = nestedLayoutComponent;
326
+ const nestedLayoutParams = resolveSlotLayoutParams(slotRouteSegments, slot.configLayoutTreePositions?.[layoutIndex] ?? 0, slotParams);
327
+ slotElement = /* @__PURE__ */ jsx(NestedLayoutComponent, {
328
+ params: options.makeThenableParams({
329
+ ...slotOwnerParams,
330
+ ...nestedLayoutParams
331
+ }),
316
332
  children: slotElement
317
333
  });
318
334
  }
319
335
  const slotLayoutComponent = getDefaultExport(slot.layout);
320
336
  if (slotLayoutComponent) slotElement = /* @__PURE__ */ jsx(slotLayoutComponent, {
321
- params: slotThenableParams,
337
+ params: options.makeThenableParams(slotOwnerParams),
322
338
  children: slotElement
323
339
  });
324
340
  const slotLoadingComponent = getDefaultExport(slot.loading);
@@ -1,10 +1,12 @@
1
+ import { ThenableParams, ThenableParamsObserver } from "../shims/thenable-params.js";
1
2
  import { AppPageSearchParams } from "./app-page-head.js";
2
- import { ThenableParams } from "../shims/thenable-params.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 makeObservedAppPageSearchParamsThenable(pageSearchParams, options = {}) {
10
- const observer = { observeParamAccess() {
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,5 +1,6 @@
1
1
  import { isCatchAllSegment, isOptionalCatchAllSegment } from "../routing/utils.js";
2
2
  //#region src/server/app-page-segment-state.ts
3
+ const APP_PAGE_SEGMENT_KEY = "__PAGE__";
3
4
  function isDynamicSegment(segment) {
4
5
  return segment.startsWith("[") && segment.endsWith("]") && !segment.includes(".");
5
6
  }
@@ -58,6 +59,7 @@ function resolveAppPageChildSegments(routeSegments, treePosition, params) {
58
59
  }
59
60
  resolvedSegments.push(segment);
60
61
  }
62
+ resolvedSegments.push(APP_PAGE_SEGMENT_KEY);
61
63
  return resolvedSegments;
62
64
  }
63
65
  function resolveAppPageSegmentStateKey(routeSegments, treePosition, params) {
@@ -24,6 +24,7 @@ function buildRouteHandlerPageCacheTags(pathname, extraTags, routeSegments) {
24
24
  async function runInRouteHandlerRevalidationContext(options, renderFn) {
25
25
  await runWithRequestContext(createRequestContext({
26
26
  headersContext: createStaticGenerationHeadersContext({
27
+ draftModeEnabled: false,
27
28
  draftModeSecret: options.draftModeSecret,
28
29
  dynamicConfig: options.dynamicConfig,
29
30
  routeKind: "route",
@@ -1,4 +1,5 @@
1
- import { setHeadersContext } from "../shims/headers.js";
1
+ import { isDraftModeRequest, setHeadersContext } from "../shims/headers.js";
2
+ import { runWithRootParamsUsage } from "../shims/root-params.js";
2
3
  import { isPossibleAppRouteActionRequest } from "./app-action-request.js";
3
4
  import { applyRouteHandlerMiddlewareContext, applyRouteHandlerRevalidateHeader, assertSupportedAppRouteHandlerResponse, buildAppRouteCacheValue, finalizeRouteHandlerResponse, markRouteHandlerCacheMiss } from "./app-route-handler-response.js";
4
5
  import { createTrackedAppRouteRequest, markKnownDynamicAppRoute } from "./app-route-handler-runtime.js";
@@ -8,6 +9,7 @@ import { resolveAppRouteHandlerSpecialError, shouldApplyAppRouteHandlerRevalidat
8
9
  function configureAppRouteStaticGenerationContext(options) {
9
10
  if (options.dynamicConfig === "force-static" || options.dynamicConfig === "error") {
10
11
  setHeadersContext(createStaticGenerationHeadersContext({
12
+ draftModeEnabled: options.draftModeSecret !== void 0 && isDraftModeRequest(options.request, options.draftModeSecret),
11
13
  draftModeSecret: options.draftModeSecret,
12
14
  dynamicConfig: options.dynamicConfig,
13
15
  routeKind: "route",
@@ -32,7 +34,10 @@ async function runAppRouteHandler(options) {
32
34
  return getAppRouteStaticGenerationErrorMessage(options.routePattern, expression);
33
35
  }
34
36
  });
35
- const response = await options.handlerFn(trackedRequest.request, { params: options.params });
37
+ const response = await runWithRootParamsUsage({
38
+ kind: "route-handler",
39
+ routePattern: options.routePattern ?? new URL(options.request.url).pathname
40
+ }, () => options.handlerFn(trackedRequest.request, { params: options.params }));
36
41
  return {
37
42
  dynamicUsedInHandler: options.consumeDynamicUsage(),
38
43
  response
@@ -1,3 +1,4 @@
1
+ import "../utils/protocol-headers.js";
1
2
  import "./headers.js";
2
3
  import { processMiddlewareHeaders } from "./request-pipeline.js";
3
4
  import { setCacheStateHeaders } from "./cache-headers.js";
@@ -1,5 +1,5 @@
1
1
  import { addBasePathToPathname } from "../utils/base-path.js";
2
- import { buildRequestHeadersFromMiddlewareResponse } from "./middleware-request-headers.js";
2
+ import { buildRequestHeadersFromMiddlewareResponse } from "../utils/middleware-request-headers.js";
3
3
  import { NextRequest, RequestCookies, sealRequestCookies, sealRequestHeaders } from "../shims/server.js";
4
4
  //#region src/server/app-route-handler-runtime.ts
5
5
  const ROUTE_HANDLER_HTTP_METHODS = [
@@ -36,11 +36,13 @@ type LazyLoadableSlot = {
36
36
  page?: unknown;
37
37
  default?: unknown;
38
38
  layout?: unknown;
39
+ configLayouts?: readonly unknown[];
39
40
  loading?: unknown;
40
41
  error?: unknown;
41
42
  __loadPage?: LazyModuleThunk | null;
42
43
  __loadDefault?: LazyModuleThunk | null;
43
44
  __loadLayout?: LazyModuleThunk | null;
45
+ __loadConfigLayouts?: LazyModuleLoaderArray | null;
44
46
  __loadLoading?: LazyModuleThunk | null;
45
47
  __loadError?: LazyModuleThunk | null; /** Hydrated only after an intercept matches, not with the slot's base modules. */
46
48
  intercepts?: LazyLoadableIntercept[];
@@ -61,6 +61,7 @@ function ensureAppRouteModulesLoaded(route) {
61
61
  pushFieldLoad(loads, slot, "page", slot.__loadPage);
62
62
  pushFieldLoad(loads, slot, "default", slot.__loadDefault);
63
63
  pushFieldLoad(loads, slot, "layout", slot.__loadLayout);
64
+ pushArrayLoads(loads, slot.configLayouts, slot.__loadConfigLayouts);
64
65
  pushFieldLoad(loads, slot, "loading", slot.__loadLoading);
65
66
  pushFieldLoad(loads, slot, "error", slot.__loadError);
66
67
  }
@@ -5,6 +5,18 @@ type WorkerAssetEnv = {
5
5
  ASSETS?: {
6
6
  fetch(request: Request): Promise<Response> | Response;
7
7
  };
8
+ IMAGES?: {
9
+ input(stream: ReadableStream): {
10
+ transform(options: Record<string, unknown>): {
11
+ output(options: {
12
+ format: string;
13
+ quality: number;
14
+ }): Promise<{
15
+ response(): Response;
16
+ }>;
17
+ };
18
+ };
19
+ };
8
20
  };
9
21
  declare const _default: {
10
22
  fetch(request: Request, env?: WorkerAssetEnv, ctx?: ExecutionContextLike): Promise<Response>;
@@ -1,14 +1,17 @@
1
1
  import "./server-globals.js";
2
2
  import { runWithExecutionContext } from "../shims/request-context.js";
3
- import { VINEXT_PRERENDER_ROUTE_PARAMS_HEADER } from "./headers.js";
3
+ import { VINEXT_PRERENDER_ROUTE_PARAMS_HEADER } from "../utils/protocol-headers.js";
4
4
  import { badRequestResponse, notFoundResponse, notFoundStaticAssetResponse } from "./http-error-responses.js";
5
5
  import { isOpenRedirectShaped } from "./open-redirect.js";
6
6
  import { bufferRequestBodyForHeaderClone, cloneRequestWithHeaders, filterInternalHeaders } from "./request-pipeline.js";
7
+ import { getImageOptimizer, handleConfiguredImageOptimization, isImageOptimizationPath } from "./image-optimization.js";
7
8
  import { assetPrefixPathname, isNextStaticPath } from "../utils/asset-prefix.js";
8
- import { resolveStaticAssetSignal } from "./worker-utils.js";
9
+ import { finalizeMissingStaticAssetResponse, resolveStaticAssetSignal } from "./worker-utils.js";
9
10
  import { readTrustedPrerenderRouteParams, serializePrerenderRouteParamsHeader } from "./prerender-route-params.js";
10
- import rscHandler, { __assetPrefix, __basePath } from "virtual:vinext-rsc-entry";
11
+ import { handleAppRouterImageOptimizationRequest } from "./app-router-image-optimization.js";
12
+ import rscHandler, { __assetPrefix, __basePath, __imageAllowedWidths, __imageConfig } from "virtual:vinext-rsc-entry";
11
13
  import { registerConfiguredCacheAdapters } from "virtual:vinext-cache-adapters";
14
+ import { registerConfiguredImageOptimizer } from "virtual:vinext-image-adapters";
12
15
  //#region src/server/app-router-entry.ts
13
16
  const __workerBasePath = typeof __basePath === "string" ? __basePath : "";
14
17
  const __workerAssetPathPrefix = assetPrefixPathname(typeof __assetPrefix === "string" ? __assetPrefix : "");
@@ -17,14 +20,19 @@ var app_router_entry_default = { async fetch(request, env, ctx) {
17
20
  } };
18
21
  async function handleRequest(request, env, ctx) {
19
22
  registerConfiguredCacheAdapters(env);
23
+ registerConfiguredImageOptimizer(env);
20
24
  const url = new URL(request.url);
25
+ if (isImageOptimizationPath(url.pathname) && env?.ASSETS && getImageOptimizer()) {
26
+ const assetFetcher = env.ASSETS;
27
+ return handleConfiguredImageOptimization(request, (assetPath) => Promise.resolve(assetFetcher.fetch(new Request(new URL(assetPath, request.url)))), __imageAllowedWidths, __imageConfig);
28
+ }
21
29
  if (isOpenRedirectShaped(url.pathname)) return notFoundResponse();
22
30
  try {
23
31
  decodeURIComponent(url.pathname);
24
32
  } catch {
25
33
  return badRequestResponse();
26
34
  }
27
- if (isNextStaticPath(url.pathname, __workerBasePath, __workerAssetPathPrefix)) return notFoundStaticAssetResponse();
35
+ const missingBuildAsset = isNextStaticPath(url.pathname, __workerBasePath, __workerAssetPathPrefix);
28
36
  {
29
37
  request = await bufferRequestBodyForHeaderClone(request);
30
38
  const prerenderRouteParamsPayload = readTrustedPrerenderRouteParams(request);
@@ -33,17 +41,23 @@ async function handleRequest(request, env, ctx) {
33
41
  if (prerenderRouteParamsHeader !== null) filteredHeaders.set(VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, prerenderRouteParamsHeader);
34
42
  request = cloneRequestWithHeaders(request, filteredHeaders);
35
43
  }
44
+ const imageResponse = await handleAppRouterImageOptimizationRequest(request, {
45
+ basePath: __workerBasePath,
46
+ env: env ?? {}
47
+ });
48
+ if (imageResponse) return imageResponse;
36
49
  const handleFn = () => rscHandler(request, ctx);
37
50
  const result = await (ctx ? runWithExecutionContext(ctx, handleFn) : handleFn());
38
51
  if (result instanceof Response) {
52
+ let response = result;
39
53
  if (env?.ASSETS) {
40
54
  const assetFetcher = env.ASSETS;
41
- const assetResponse = await resolveStaticAssetSignal(result, { fetchAsset: (path) => Promise.resolve(assetFetcher.fetch(new Request(new URL(path, request.url)))) });
42
- if (assetResponse) return assetResponse;
55
+ const assetResponse = await resolveStaticAssetSignal(response, { fetchAsset: (path) => Promise.resolve(assetFetcher.fetch(new Request(new URL(path, request.url)))) });
56
+ if (assetResponse) response = assetResponse;
43
57
  }
44
- return result;
58
+ return finalizeMissingStaticAssetResponse(response, missingBuildAsset);
45
59
  }
46
- if (result === null || result === void 0) return notFoundResponse();
60
+ if (result === null || result === void 0) return missingBuildAsset ? notFoundStaticAssetResponse() : notFoundResponse();
47
61
  return new Response(String(result), { status: 200 });
48
62
  }
49
63
  //#endregion