@qzsy/vinext 0.1.12 → 0.1.81

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