vinext 1.3.1 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (234) hide show
  1. package/README.md +5 -2
  2. package/THIRD_PARTY_LICENSES.md +47 -0
  3. package/dist/_virtual/_rolldown/runtime.js +3 -2
  4. package/dist/build/prerender.js +1 -1
  5. package/dist/build/report.d.ts +0 -14
  6. package/dist/build/report.js +1 -51
  7. package/dist/check.js +1 -1
  8. package/dist/cli.js +3 -0
  9. package/dist/client/dev-error-overlay.js +1 -1
  10. package/dist/client/navigation-runtime.d.ts +13 -1
  11. package/dist/client/navigation-runtime.js +1 -1
  12. package/dist/config/next-config.d.ts +19 -0
  13. package/dist/config/next-config.js +64 -1
  14. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/dbcs-codec.js +327 -0
  15. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/dbcs-data.js +123 -0
  16. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/index.js +29 -0
  17. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/internal.js +134 -0
  18. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/sbcs-codec.js +50 -0
  19. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/sbcs-data-generated.js +455 -0
  20. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/sbcs-data.js +147 -0
  21. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/big5-added.json.js +169 -0
  22. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/cp936.json.js +2584 -0
  23. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/cp949.json.js +2220 -0
  24. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/cp950.json.js +227 -0
  25. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/eucjp.json.js +425 -0
  26. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/gb18030-ranges.json.js +427 -0
  27. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/gbk-added.json.js +229 -0
  28. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/shiftjis.json.js +292 -0
  29. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/utf16.js +106 -0
  30. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/utf7.js +182 -0
  31. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/lib/bom-handling.js +42 -0
  32. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/lib/extend-node.js +147 -0
  33. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/lib/index.js +94 -0
  34. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/lib/streams.js +95 -0
  35. package/dist/deps/.pnpm/safer-buffer@2.1.2/deps/safer-buffer/safer.js +45 -0
  36. package/dist/entries/app-rsc-entry.js +17 -48
  37. package/dist/entries/app-rsc-manifest.js +3 -4
  38. package/dist/entries/app-ssr-entry.js +1 -0
  39. package/dist/entries/pages-server-entry.js +33 -8
  40. package/dist/index.js +83 -70
  41. package/dist/init-cloudflare.d.ts +1 -3
  42. package/dist/init-cloudflare.js +10 -48
  43. package/dist/init-platform.d.ts +2 -0
  44. package/dist/init-platform.js +4 -0
  45. package/dist/plugins/extensionless-dynamic-import.js +6 -2
  46. package/dist/plugins/next-intl-catalog.d.ts +12 -0
  47. package/dist/plugins/next-intl-catalog.js +85 -0
  48. package/dist/plugins/pages-node-externals.d.ts +1 -0
  49. package/dist/plugins/pages-node-externals.js +1 -1
  50. package/dist/plugins/use-cache-callable.d.ts +1 -1
  51. package/dist/plugins/use-cache-callable.js +136 -94
  52. package/dist/routing/app-route-graph.d.ts +6 -0
  53. package/dist/routing/app-route-graph.js +9 -1
  54. package/dist/server/api-handler.js +19 -4
  55. package/dist/server/app-bfcache-identity.js +1 -1
  56. package/dist/server/app-browser-entry.js +79 -63
  57. package/dist/server/app-browser-history-controller.d.ts +5 -4
  58. package/dist/server/app-browser-history-controller.js +93 -15
  59. package/dist/server/app-browser-navigation-controller.d.ts +2 -2
  60. package/dist/server/app-browser-navigation-controller.js +1 -2
  61. package/dist/server/app-browser-rsc-redirect.js +4 -4
  62. package/dist/server/app-browser-server-action-client.d.ts +2 -0
  63. package/dist/server/app-browser-server-action-client.js +4 -3
  64. package/dist/server/app-browser-state.d.ts +2 -4
  65. package/dist/server/app-browser-state.js +9 -4
  66. package/dist/server/app-browser-supplemental-refresh.js +16 -1
  67. package/dist/server/app-browser-visible-commit.d.ts +1 -1
  68. package/dist/server/app-browser-visible-commit.js +2 -12
  69. package/dist/server/app-elements-wire.d.ts +6 -38
  70. package/dist/server/app-elements-wire.js +4 -41
  71. package/dist/server/app-elements.d.ts +2 -2
  72. package/dist/server/app-elements.js +2 -2
  73. package/dist/server/app-history-state.d.ts +2 -2
  74. package/dist/server/app-history-state.js +5 -2
  75. package/dist/server/app-mounted-layouts.d.ts +21 -0
  76. package/dist/server/app-mounted-layouts.js +67 -0
  77. package/dist/server/app-optimistic-routing.d.ts +19 -1
  78. package/dist/server/app-optimistic-routing.js +42 -2
  79. package/dist/server/app-page-boundary-render.js +7 -6
  80. package/dist/server/app-page-boundary.js +2 -2
  81. package/dist/server/app-page-cache-finalizer.d.ts +12 -1
  82. package/dist/server/app-page-cache-finalizer.js +70 -29
  83. package/dist/server/app-page-cache.d.ts +13 -1
  84. package/dist/server/app-page-cache.js +31 -9
  85. package/dist/server/app-page-dispatch.d.ts +5 -10
  86. package/dist/server/app-page-dispatch.js +84 -154
  87. package/dist/server/app-page-element-builder.d.ts +2 -2
  88. package/dist/server/app-page-element-builder.js +10 -9
  89. package/dist/server/app-page-execution.d.ts +17 -52
  90. package/dist/server/app-page-execution.js +99 -95
  91. package/dist/server/app-page-head.d.ts +13 -0
  92. package/dist/server/app-page-head.js +44 -16
  93. package/dist/server/app-page-http-access-fallback-metadata.d.ts +1 -0
  94. package/dist/server/app-page-http-access-fallback-metadata.js +2 -2
  95. package/dist/server/app-page-layout-gate.d.ts +35 -0
  96. package/dist/server/app-page-layout-gate.js +50 -0
  97. package/dist/server/app-page-params.d.ts +0 -1
  98. package/dist/server/app-page-params.js +1 -14
  99. package/dist/server/app-page-probe.d.ts +3 -21
  100. package/dist/server/app-page-probe.js +4 -37
  101. package/dist/server/app-page-render.d.ts +2 -12
  102. package/dist/server/app-page-render.js +89 -220
  103. package/dist/server/app-page-request.d.ts +1 -3
  104. package/dist/server/app-page-request.js +1 -1
  105. package/dist/server/app-page-response.js +3 -3
  106. package/dist/server/app-page-route-wiring.d.ts +13 -6
  107. package/dist/server/app-page-route-wiring.js +67 -61
  108. package/dist/server/app-page-rsc-render-status.d.ts +27 -1
  109. package/dist/server/app-page-rsc-render-status.js +121 -13
  110. package/dist/server/app-page-stream.d.ts +2 -0
  111. package/dist/server/app-page-stream.js +2 -2
  112. package/dist/server/app-pages-bridge.d.ts +4 -0
  113. package/dist/server/app-pages-bridge.js +7 -3
  114. package/dist/server/app-render-dependency.d.ts +11 -4
  115. package/dist/server/app-render-dependency.js +86 -38
  116. package/dist/server/app-request-stage-dispatch.js +1 -1
  117. package/dist/server/app-route-handler-cache.js +2 -2
  118. package/dist/server/app-route-handler-dispatch.js +14 -9
  119. package/dist/server/app-route-handler-execution.js +8 -3
  120. package/dist/server/app-route-handler-policy.d.ts +1 -1
  121. package/dist/server/app-route-handler-policy.js +3 -3
  122. package/dist/server/app-route-handler-response.js +1 -1
  123. package/dist/server/app-route-handler-runtime.js +17 -4
  124. package/dist/server/app-rsc-cache-busting.d.ts +2 -2
  125. package/dist/server/app-rsc-cache-busting.js +4 -4
  126. package/dist/server/app-rsc-error-handler.d.ts +2 -1
  127. package/dist/server/app-rsc-error-handler.js +9 -1
  128. package/dist/server/app-rsc-errors.d.ts +8 -0
  129. package/dist/server/app-rsc-errors.js +8 -1
  130. package/dist/server/app-rsc-handler.d.ts +5 -5
  131. package/dist/server/app-rsc-handler.js +30 -24
  132. package/dist/server/app-rsc-request-normalization.d.ts +0 -4
  133. package/dist/server/app-rsc-request-normalization.js +1 -4
  134. package/dist/server/app-rsc-response-finalizer.js +2 -2
  135. package/dist/server/app-rsc-response-stage.js +5 -3
  136. package/dist/server/app-server-action-execution.d.ts +3 -1
  137. package/dist/server/app-server-action-execution.js +7 -4
  138. package/dist/server/app-ssr-entry.d.ts +2 -0
  139. package/dist/server/app-ssr-entry.js +9 -8
  140. package/dist/server/app-ssr-stream.js +1 -1
  141. package/dist/server/app-visited-response-cache.d.ts +36 -1
  142. package/dist/server/app-visited-response-cache.js +46 -5
  143. package/dist/server/app-worker-stages.d.ts +25 -3
  144. package/dist/server/app-worker-stages.js +45 -6
  145. package/dist/server/artifact-compatibility.d.ts +0 -1
  146. package/dist/server/artifact-compatibility.js +1 -10
  147. package/dist/server/cache-proof.d.ts +1 -115
  148. package/dist/server/cache-proof.js +1 -544
  149. package/dist/server/cacheability-request.js +13 -8
  150. package/dist/server/dev-server.js +4 -3
  151. package/dist/server/headers.d.ts +6 -3
  152. package/dist/server/headers.js +9 -5
  153. package/dist/server/isr-cache.d.ts +8 -2
  154. package/dist/server/isr-cache.js +26 -1
  155. package/dist/server/metadata-route-response.js +32 -15
  156. package/dist/server/multi-stage.d.ts +52 -11
  157. package/dist/server/multi-stage.js +13 -1
  158. package/dist/server/navigation-planner.js +1 -1
  159. package/dist/server/pages-api-route.js +28 -19
  160. package/dist/server/pages-media-type.d.ts +21 -1
  161. package/dist/server/pages-media-type.js +69 -5
  162. package/dist/server/pages-node-compat.js +52 -27
  163. package/dist/server/pages-page-handler.js +11 -20
  164. package/dist/server/pages-request-pipeline.d.ts +8 -0
  165. package/dist/server/pages-request-pipeline.js +2 -2
  166. package/dist/server/pages-request-stage-entry.js +14 -12
  167. package/dist/server/pages-response-stage-entry.js +9 -3
  168. package/dist/server/prod-server.js +5 -1
  169. package/dist/server/request-pipeline.d.ts +6 -0
  170. package/dist/server/request-pipeline.js +21 -1
  171. package/dist/server/shared-cache-identity.d.ts +23 -0
  172. package/dist/server/shared-cache-identity.js +36 -0
  173. package/dist/server/worker-stages.d.ts +16 -3
  174. package/dist/server/worker-stages.js +23 -4
  175. package/dist/shims/cache-handler.js +2 -2
  176. package/dist/shims/cache-request-state.d.ts +17 -20
  177. package/dist/shims/cache-request-state.js +16 -21
  178. package/dist/shims/cache-runtime.js +27 -11
  179. package/dist/shims/cache.d.ts +8 -7
  180. package/dist/shims/cache.js +17 -19
  181. package/dist/shims/cacheability-classification.d.ts +2 -0
  182. package/dist/shims/cdn-cache.d.ts +22 -5
  183. package/dist/shims/client-page-root.js +2 -2
  184. package/dist/shims/dynamic.js +9 -6
  185. package/dist/shims/error-boundary.js +2 -2
  186. package/dist/shims/fetch-cache-state.d.ts +5 -1
  187. package/dist/shims/fetch-cache-state.js +1 -3
  188. package/dist/shims/fetch-cache.d.ts +2 -1
  189. package/dist/shims/fetch-cache.js +34 -24
  190. package/dist/shims/form.js +2 -2
  191. package/dist/shims/headers.d.ts +8 -23
  192. package/dist/shims/headers.js +17 -67
  193. package/dist/shims/internal/navigation-untracked.js +1 -1
  194. package/dist/shims/link.js +3 -1
  195. package/dist/shims/metadata.d.ts +23 -21
  196. package/dist/shims/metadata.js +62 -24
  197. package/dist/shims/navigation-server.js +1 -1
  198. package/dist/shims/navigation.d.ts +74 -7
  199. package/dist/shims/navigation.js +183 -29
  200. package/dist/shims/navigation.react-server.js +2 -2
  201. package/dist/shims/request-state-types.d.ts +2 -2
  202. package/dist/shims/slot.d.ts +12 -0
  203. package/dist/shims/slot.js +37 -9
  204. package/dist/shims/unified-request-context.d.ts +1 -1
  205. package/dist/shims/unified-request-context.js +2 -3
  206. package/dist/utils/cache-control-metadata.d.ts +5 -0
  207. package/dist/utils/cache-control-metadata.js +9 -1
  208. package/dist/utils/project.d.ts +2 -2
  209. package/dist/utils/project.js +3 -16
  210. package/dist/utils/regex.d.ts +5 -0
  211. package/dist/utils/regex.js +11 -1
  212. package/dist/utils/text-stream.d.ts +10 -5
  213. package/dist/utils/text-stream.js +6 -6
  214. package/package.json +2 -1
  215. package/dist/build/layout-classification-types.d.ts +0 -60
  216. package/dist/build/layout-classification-types.js +0 -1
  217. package/dist/build/layout-classification.d.ts +0 -62
  218. package/dist/build/layout-classification.js +0 -98
  219. package/dist/build/route-classification-injector.d.ts +0 -33
  220. package/dist/build/route-classification-injector.js +0 -59
  221. package/dist/build/route-classification-manifest.d.ts +0 -54
  222. package/dist/build/route-classification-manifest.js +0 -143
  223. package/dist/server/app-browser-client-reuse-manifest.d.ts +0 -11
  224. package/dist/server/app-browser-client-reuse-manifest.js +0 -101
  225. package/dist/server/app-layout-param-observation.d.ts +0 -42
  226. package/dist/server/app-layout-param-observation.js +0 -168
  227. package/dist/server/client-reuse-manifest.d.ts +0 -103
  228. package/dist/server/client-reuse-manifest.js +0 -209
  229. package/dist/server/skip-cache-proof.d.ts +0 -60
  230. package/dist/server/skip-cache-proof.js +0 -168
  231. package/dist/server/static-layout-client-reuse-proof.d.ts +0 -14
  232. package/dist/server/static-layout-client-reuse-proof.js +0 -33
  233. package/dist/utils/sorted-array.d.ts +0 -8
  234. package/dist/utils/sorted-array.js +0 -20
@@ -1,5 +1,4 @@
1
1
  import { isPromiseLike } from "../utils/promise.js";
2
- import { probeAppPageLayouts } from "./app-page-execution.js";
3
2
  import { Fragment, isValidElement } from "react";
4
3
  //#region src/server/app-page-probe.ts
5
4
  const DEFAULT_SUBTREE_PROBE_MAX_DEPTH = 32;
@@ -63,10 +62,9 @@ async function resolveReactLazyType(lazyType) {
63
62
  }
64
63
  }
65
64
  /**
66
- * Invokes server-component children returned by a layout probe so per-layout
67
- * skip eligibility observes data dependencies created below the layout's
68
- * immediate function body. The real RSC render remains authoritative; probe
69
- * failures only make static-layout skip fall back to render-and-send.
65
+ * Invokes the server components a layout renders, so the error-path layout
66
+ * probe sees an HTTP access fallback thrown below the layout's own function
67
+ * body. The real RSC render remains authoritative.
70
68
  */
71
69
  async function probeReactServerSubtree(node, options = {}) {
72
70
  const maxDepth = options.maxDepth ?? DEFAULT_SUBTREE_PROBE_MAX_DEPTH;
@@ -118,36 +116,5 @@ async function probeReactServerSubtree(node, options = {}) {
118
116
  };
119
117
  await visit(node, 0);
120
118
  }
121
- async function probeAppPageBeforeRender(options) {
122
- let layoutFlags = {};
123
- if (options.skipProbes) return {
124
- response: null,
125
- layoutFlags
126
- };
127
- if (options.layoutCount > 0) {
128
- const layoutProbeResult = await probeAppPageLayouts({
129
- layoutCount: options.layoutCount,
130
- async onLayoutError(layoutError, layoutIndex) {
131
- const specialError = options.resolveSpecialError(layoutError);
132
- if (!specialError) return null;
133
- return options.renderLayoutSpecialError(specialError, layoutIndex);
134
- },
135
- probeLayoutAt: options.probeLayoutAt,
136
- runWithSuppressedHookWarning(probe) {
137
- return options.runWithSuppressedHookWarning(probe);
138
- },
139
- classification: options.classification
140
- });
141
- layoutFlags = layoutProbeResult.layoutFlags;
142
- if (layoutProbeResult.response) return {
143
- response: layoutProbeResult.response,
144
- layoutFlags
145
- };
146
- }
147
- return {
148
- response: null,
149
- layoutFlags
150
- };
151
- }
152
119
  //#endregion
153
- export { probeAppPageBeforeRender, probeReactServerSubtree };
120
+ export { probeReactServerSubtree };
@@ -1,12 +1,10 @@
1
- import { ClientReuseManifestParseResult, ClientReuseManifestSkipDisposition } from "./client-reuse-manifest.js";
2
1
  import { AppOutgoingElements } from "./app-elements-wire.js";
3
2
  import "./app-elements.js";
4
3
  import { AppRscRenderMode } from "./app-rsc-render-mode.js";
5
4
  import { NavigationContext } from "../shims/navigation-context-state.js";
6
5
  import "../shims/navigation.js";
7
- import { AppPageFontPreload, AppPageSpecialError, LayoutClassificationOptions } from "./app-page-execution.js";
6
+ import { AppPageFontPreload, AppPageSpecialError } from "./app-page-execution.js";
8
7
  import { AppPageMiddlewareContext } from "./app-page-response.js";
9
- import { AppLayoutParamAccessTracker } from "./app-layout-param-observation.js";
10
8
  import { RootParams } from "../shims/root-params.js";
11
9
  import { AppPageSsrHandler } from "./app-page-stream.js";
12
10
  import { AppRenderErrorContextOverrides } from "./app-rsc-error-handler.js";
@@ -110,7 +108,6 @@ type RenderAppPageLifecycleOptionsBase = {
110
108
  isrSet: AppPageCacheSetter;
111
109
  interceptionContext?: string | null;
112
110
  interceptionId?: string | null;
113
- layoutCount: number;
114
111
  loadSsrHandler: () => Promise<AppPageSsrHandler>;
115
112
  middlewareContext: AppPageMiddlewareContext;
116
113
  navigationParams: Record<string, unknown>;
@@ -120,12 +117,10 @@ type RenderAppPageLifecycleOptionsBase = {
120
117
  abortPprFallbackShell?: () => void;
121
118
  rootParams?: RootParams;
122
119
  peekRenderObservationState?: () => AppPageRenderObservationState;
123
- probeLayoutAt: (layoutIndex: number) => unknown;
124
120
  expireSeconds?: number;
125
121
  formState?: ReactFormState | null;
126
122
  revalidateSeconds: number | null;
127
123
  renderErrorBoundaryResponse: (error: unknown, errorOrigin: "rsc" | "ssr") => Promise<Response | null>;
128
- renderLayoutSpecialError: (specialError: AppPageSpecialError, layoutIndex: number) => Promise<Response>;
129
124
  renderPageSpecialError: (specialError: AppPageSpecialError, renderOptions?: AppPageSpecialErrorRenderOptions) => Promise<Response>;
130
125
  renderToReadableStream: (element: ReactNode | AppOutgoingElements, options: {
131
126
  onError: AppPageBoundaryOnError;
@@ -138,16 +133,11 @@ type RenderAppPageLifecycleOptionsBase = {
138
133
  prelude: ReadableStream<Uint8Array>;
139
134
  }>;
140
135
  routePattern: string;
141
- runWithSuppressedHookWarning<T>(probe: () => Promise<T>): Promise<T>;
142
136
  scriptNonce?: string;
143
- clientReuseManifest?: ClientReuseManifestParseResult;
144
- skipDisposition?: ClientReuseManifestSkipDisposition;
145
137
  mountedSlotsHeader?: string | null;
146
138
  renderedPathAndSearch?: string | null;
147
139
  renderMode?: AppRscRenderMode;
148
140
  waitUntil?: (promise: Promise<void>) => void;
149
- layoutParamAccess?: AppLayoutParamAccessTracker;
150
- classification?: LayoutClassificationOptions | null;
151
141
  };
152
142
  type RenderAppPageLifecycleOptions = RenderAppPageLifecycleOptionsBase & ({
153
143
  element: AppPageRenderableElement;
@@ -163,7 +153,7 @@ type RenderAppPageLifecycleOptions = RenderAppPageLifecycleOptionsBase & ({
163
153
  * its response policy, such as error boundaries and special errors, get the
164
154
  * same header as the normal render.
165
155
  */
166
- export declare function applyIneligibleRouteCachePolicy(response: Response, options: Pick<RenderAppPageLifecycleOptions, "dynamicStaleTimeSeconds" | "isDraftMode" | "isDynamicError" | "isForceDynamic" | "isForceStatic" | "isProduction" | "isProgressiveActionRender" | "isRscRequest" | "isStaticEligible" | "middlewareContext" | "peekDynamicUsage" | "revalidateSeconds" | "scriptNonce">, probeCacheLife?: AppPageRequestCacheLife | null): Response;
156
+ export declare function applyIneligibleRouteCachePolicy(response: Response, options: Pick<RenderAppPageLifecycleOptions, "dynamicStaleTimeSeconds" | "isDraftMode" | "isDynamicError" | "isForceDynamic" | "isForceStatic" | "isProduction" | "isProgressiveActionRender" | "isRscRequest" | "isStaticEligible" | "middlewareContext" | "peekDynamicUsage" | "revalidateSeconds" | "scriptNonce">, requestCacheLife?: AppPageRequestCacheLife | null): Response;
167
157
  export declare function renderAppPageLifecycle(options: RenderAppPageLifecycleOptions): Promise<Response>;
168
158
  //#endregion
169
159
  export {};
@@ -4,36 +4,33 @@ import { bindRequestContext } from "../shims/unified-request-context.js";
4
4
  import { VINEXT_DYNAMIC_STALE_TIME_HEADER, VINEXT_RSC_COMPLETION_METADATA_HEADER } from "./headers.js";
5
5
  import { internalServerErrorResponse } from "./http-error-responses.js";
6
6
  import { getRequestExecutionContext } from "../shims/request-context.js";
7
- import { isRouteCacheabilityEvaluation, recordRouteCacheabilityClientTraceMetadataMarker } from "../shims/cacheability-classification.js";
7
+ import { getCdnCacheAdapter } from "../shims/cdn-cache.js";
8
+ import { getRouteCacheabilityCaptureOptions, isRouteCacheabilityEvaluation, recordRouteCacheabilityClientTraceMetadataMarker } from "../shims/cacheability-classification.js";
8
9
  import { NEVER_CACHE_CONTROL, NO_STORE_CACHE_CONTROL, applyCdnResponseHeaders, isCdnResponsePolicyHeader } from "./cache-control.js";
9
10
  import "./app-rsc-render-mode.js";
10
11
  import { resolveClientStaleTimeSeconds } from "../utils/cache-control-metadata.js";
11
- import { isRenderDynamicLatched, markDynamicUsage } from "../shims/internal/headers-state.js";
12
- import { peekDynamicUsage, runWithDetachedDynamicUsage } from "../shims/headers.js";
12
+ import { isRenderDynamicLatched } from "../shims/internal/headers-state.js";
13
+ import { peekDynamicUsage } from "../shims/headers.js";
13
14
  import { runWithFetchDedupe } from "../shims/fetch-cache.js";
14
15
  import { setCacheStateHeaders } from "./cache-headers.js";
16
+ import { copyLinkHeaderProvenance, getFrameworkLinkHeader } from "./app-response-header-provenance.js";
17
+ import { traceResponseStartWithCompletion } from "./response-start-tracing.js";
18
+ import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
15
19
  import { createArtifactCompatibilityEnvelope, createArtifactCompatibilityGraphVersion } from "./artifact-compatibility.js";
16
20
  import { AppElementsWire, isAppElementsRecord } from "./app-elements-wire.js";
17
21
  import "./app-elements.js";
22
+ import { appendRscCompletionMetadata } from "./rsc-completion-metadata.js";
18
23
  import { isBailoutToCSRError } from "../shims/navigation-errors.js";
19
- import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
20
24
  import { applyPrerenderCacheLifeHeader, applyPrerenderCacheTagsHeader } from "./prerender-cache-life-header.js";
21
- import { copyLinkHeaderProvenance, getFrameworkLinkHeader } from "./app-response-header-provenance.js";
22
25
  import { applyClientStaleTimeHeader, applyEdgeRuntimeHeader, buildAppPageHtmlResponse, buildAppPageRscResponse, resolveAppPageHtmlResponsePolicy, resolveAppPageRscResponsePolicy, resolveUncacheableCacheControl } from "./app-page-response.js";
23
26
  import { buildAppPageFontLinkHeader, readAppPageBinaryStream, resolveAppPageCaughtNotFoundBoundaries, resolveAppPageShellSpecialError, resolveAppPageSpecialError, resolveAppPageSpecialErrorStoredHeaders, teeAppPageRscStreamForCapture } from "./app-page-execution.js";
24
- import { probeAppPageBeforeRender } from "./app-page-probe.js";
27
+ import { getAppPageLayoutGate } from "./app-page-layout-gate.js";
25
28
  import { hasDigest } from "./app-rsc-errors.js";
26
29
  import { recordAppPageRenderError, traceAppPageRender } from "./app-page-tracing.js";
27
- import { traceResponseStartWithCompletion } from "./response-start-tracing.js";
28
- import { DEFAULT_CACHE_VARIANT_BUDGET, buildCacheVariantWithRouteBudget, buildRenderObservation, buildRenderRequestApiObservations, createStaticLayoutArtifactReuseDecision } from "./cache-proof.js";
29
- import { createStaticLayoutClientReuseArtifactCompatibility, createStaticLayoutClientReusePayloadHash, createStaticLayoutClientReuseRouteId } from "./static-layout-client-reuse-proof.js";
30
- import { appendRscCompletionMetadata } from "./rsc-completion-metadata.js";
31
30
  import { buildAppPageHtmlDocumentResponse, buildAppPageLinkHeader, createAppPageFontData, createAppPageRscErrorTracker, createAppPageSsrErrorHandler, renderAppPageHtmlStream, renderAppPageHtmlStreamWithRecovery } from "./app-page-stream.js";
32
- import { getStaticLayoutObservationSkipRejection } from "./app-layout-param-observation.js";
33
31
  import { createAppPageHtmlOutputScope, createAppPageRenderObservation, createAppPageRscOutputScope } from "./app-page-render-observation.js";
34
32
  import { createAppPageRscRenderStatusResolver } from "./app-page-rsc-render-status.js";
35
33
  import { finalizeAppPageCacheabilityEvaluationResponse, finalizeAppPageHtmlCacheResponse, finalizeAppPageRscCacheResponse } from "./app-page-cache-finalizer.js";
36
- import { createClientReuseSkipTransportPlan, crossCheckClientReuseManifestEntryWithCache } from "./skip-cache-proof.js";
37
34
  //#region src/server/app-page-render.ts
38
35
  function buildResponseTiming(options) {
39
36
  if (options.isProduction) return;
@@ -75,11 +72,11 @@ function applyRequestCacheLife(options) {
75
72
  * its response policy, such as error boundaries and special errors, get the
76
73
  * same header as the normal render.
77
74
  */
78
- function applyIneligibleRouteCachePolicy(response, options, probeCacheLife = null) {
75
+ function applyIneligibleRouteCachePolicy(response, options, requestCacheLife = null) {
79
76
  const cacheControl = resolveEarlyResponseCacheControl(options);
80
77
  const isRscRedirect = options.isRscRequest && response.headers.has("X-Vinext-Rsc-Redirect");
81
78
  if (!cacheControl) {
82
- const staleTimeSeconds = isRscRedirect ? resolveClientStaleTimeSeconds(probeCacheLife) : void 0;
79
+ const staleTimeSeconds = isRscRedirect ? resolveClientStaleTimeSeconds(requestCacheLife) : void 0;
83
80
  if (staleTimeSeconds === void 0) return response;
84
81
  const stamped = cloneForStamping(response);
85
82
  applyClientStaleTimeHeader(stamped.headers, staleTimeSeconds);
@@ -116,18 +113,6 @@ function resolveAppPageCacheWriteRevalidateSeconds(options) {
116
113
  if (options.revalidateSeconds === null && (options.isForceStatic || options.isDynamicError)) return Infinity;
117
114
  return options.revalidateSeconds;
118
115
  }
119
- /**
120
- * A loading-shell prefetch without a loading boundary that can never be stored
121
- * renders only the route tree (see buildAppPageElements), so no layout runs and
122
- * none is probed. Next.js runs no layout for its no-loading prefetch either.
123
- */
124
- function isRouteTreeOnlyLoadingShell(options) {
125
- if (options.renderMode !== "prefetch-loading-shell") return false;
126
- if (options.isCacheCandidate === true) return false;
127
- if (!isAppElementsRecord(options.element)) return false;
128
- const routeId = options.element[AppElementsWire.keys.route];
129
- return typeof routeId === "string" && options.element[routeId] === null;
130
- }
131
116
  function readRootBoundaryId(element) {
132
117
  const rootLayoutTreePath = element[AppElementsWire.keys.rootLayout];
133
118
  return typeof rootLayoutTreePath === "string" ? rootLayoutTreePath : null;
@@ -144,146 +129,6 @@ function createAppPageArtifactCompatibility(element, routePattern) {
144
129
  rootBoundaryId
145
130
  });
146
131
  }
147
- function readStringMetadata(element, key) {
148
- const value = element[key];
149
- return typeof value === "string" ? value : null;
150
- }
151
- function createStaticLayoutOutputScope(input) {
152
- const routeId = readStringMetadata(input.element, AppElementsWire.keys.route);
153
- if (routeId === null) return null;
154
- return {
155
- kind: "layout",
156
- layoutId: input.layoutId,
157
- rootBoundaryId: input.artifactCompatibility.rootBoundaryId,
158
- routeId
159
- };
160
- }
161
- function createRenderAndSendSkipDisposition() {
162
- return {
163
- code: "SKIP_MODEL_DISABLED",
164
- enabled: false,
165
- mode: "renderAndSend"
166
- };
167
- }
168
- function rejectStaticLayoutObservation(entry, code, fields = {}) {
169
- return {
170
- kind: "rejected",
171
- rejection: {
172
- code,
173
- entryId: entry.id,
174
- fields
175
- },
176
- skipDisposition: createRenderAndSendSkipDisposition()
177
- };
178
- }
179
- function rejectUnsafeStaticLayoutObservation(entry, layoutParamAccess) {
180
- const observation = layoutParamAccess?.getLayoutObservation(entry.id);
181
- if (!observation) return rejectStaticLayoutObservation(entry, "SKIP_LAYOUT_PARAMS_OBSERVATION_INCOMPLETE");
182
- const observationRejection = getStaticLayoutObservationSkipRejection(observation);
183
- if (observationRejection) return rejectStaticLayoutObservation(entry, observationRejection.code, observationRejection.fields);
184
- return null;
185
- }
186
- function createRenderLifecycleSkipDisposition(input) {
187
- if (!input.isRscRequest || input.clientReuseManifest === void 0) return;
188
- const clientReuseManifest = input.clientReuseManifest;
189
- if (clientReuseManifest.kind !== "parsed" || clientReuseManifest.manifest.entries.length === 0) return;
190
- if (!isAppElementsRecord(input.element) || input.artifactCompatibility === void 0) return {
191
- code: "SKIP_MODEL_DISABLED",
192
- enabled: false,
193
- mode: "renderAndSend"
194
- };
195
- const element = input.element;
196
- const artifactCompatibility = input.artifactCompatibility;
197
- const staticLayoutIds = new Set(Object.entries(input.layoutFlags).filter(([, flag]) => flag === "s").map(([layoutId]) => layoutId));
198
- return createClientReuseSkipTransportPlan({
199
- manifest: clientReuseManifest,
200
- verifyEntry(entry) {
201
- if (entry.kind !== "layout" || !staticLayoutIds.has(entry.id) || AppElementsWire.parseElementKey(entry.id)?.kind !== "layout") return crossCheckClientReuseManifestEntryWithCache({
202
- artifact: {
203
- compatibility: artifactCompatibility,
204
- invalidation: { kind: "unknown" },
205
- payloadHash: null
206
- },
207
- cacheDecision: null,
208
- entry
209
- });
210
- const currentOutput = createStaticLayoutOutputScope({
211
- artifactCompatibility,
212
- element,
213
- layoutId: entry.id
214
- });
215
- if (currentOutput === null) return crossCheckClientReuseManifestEntryWithCache({
216
- artifact: {
217
- compatibility: artifactCompatibility,
218
- invalidation: { kind: "unknown" },
219
- payloadHash: null
220
- },
221
- cacheDecision: null,
222
- entry
223
- });
224
- const observationRejection = rejectUnsafeStaticLayoutObservation(entry, input.layoutParamAccess);
225
- if (observationRejection) return observationRejection;
226
- const candidateRouteId = createStaticLayoutClientReuseRouteId(entry.id);
227
- const candidateOutput = {
228
- ...currentOutput,
229
- routeId: candidateRouteId
230
- };
231
- const candidateVariant = buildCacheVariantWithRouteBudget({
232
- budget: DEFAULT_CACHE_VARIANT_BUDGET,
233
- dimensions: [],
234
- output: candidateOutput,
235
- routeBudget: {
236
- routeId: candidateRouteId,
237
- variantCacheKeys: []
238
- }
239
- });
240
- const skipArtifactCompatibility = candidateVariant.kind === "variant" ? createStaticLayoutClientReuseArtifactCompatibility({
241
- artifactCompatibility,
242
- layoutId: entry.id,
243
- rootBoundaryId: candidateOutput.rootBoundaryId,
244
- routeId: candidateOutput.routeId,
245
- variantCacheKey: candidateVariant.variant.cacheKey
246
- }) : artifactCompatibility;
247
- const cacheDecision = createStaticLayoutArtifactReuseDecision({
248
- candidateArtifactCompatibility: skipArtifactCompatibility,
249
- candidateObservation: buildRenderObservation({
250
- boundaryOutcome: { kind: "success" },
251
- cacheability: "public",
252
- cacheTags: [],
253
- completeness: "complete",
254
- dynamicFetches: [],
255
- output: candidateOutput,
256
- pathTags: [input.cleanPathname],
257
- requestApis: buildRenderRequestApiObservations({
258
- completeness: "complete",
259
- observed: []
260
- })
261
- }),
262
- candidateVariant,
263
- currentArtifactCompatibility: skipArtifactCompatibility,
264
- currentOutput
265
- });
266
- return crossCheckClientReuseManifestEntryWithCache({
267
- artifact: {
268
- compatibility: skipArtifactCompatibility,
269
- invalidation: { kind: "valid" },
270
- payloadHash: candidateVariant.kind === "variant" ? createStaticLayoutClientReusePayloadHash({
271
- artifactCompatibility: skipArtifactCompatibility,
272
- layoutId: entry.id,
273
- rootBoundaryId: candidateOutput.rootBoundaryId,
274
- routeId: candidateOutput.routeId,
275
- variantCacheKey: candidateVariant.variant.cacheKey
276
- }) : null
277
- },
278
- cacheDecision,
279
- entry
280
- });
281
- }
282
- }).skipDisposition;
283
- }
284
- function isSkipTransportEnabled(skipDisposition) {
285
- return skipDisposition?.enabled === true;
286
- }
287
132
  /**
288
133
  * Wraps an RSC response body to report invalid dynamic usage errors after the
289
134
  * stream is fully consumed. In dev mode, errors from cookies()/headers() inside
@@ -402,27 +247,6 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
402
247
  }
403
248
  return dynamicUsageObserved;
404
249
  };
405
- const probeOutcome = await runWithDetachedDynamicUsage(() => probeAppPageBeforeRender({
406
- skipProbes: options.pprFallbackShellSignal !== void 0 || isRouteTreeOnlyLoadingShell(options),
407
- layoutCount: options.layoutCount,
408
- probeLayoutAt(layoutIndex) {
409
- return options.probeLayoutAt(layoutIndex);
410
- },
411
- renderLayoutSpecialError(specialError, layoutIndex) {
412
- return options.renderLayoutSpecialError(specialError, layoutIndex);
413
- },
414
- resolveSpecialError: resolveAppPageSpecialError,
415
- runWithSuppressedHookWarning(probe) {
416
- return options.runWithSuppressedHookWarning(probe);
417
- },
418
- classification: options.classification
419
- }));
420
- const preRenderResult = probeOutcome.result;
421
- if (preRenderResult.response) {
422
- if (probeOutcome.dynamicDetected) markDynamicUsage();
423
- return applyIneligibleRouteCachePolicy(preRenderResult.response, options, probeOutcome.cacheLife);
424
- }
425
- const layoutFlags = preRenderResult.layoutFlags;
426
250
  const artifactCompatibility = createAppPageArtifactCompatibility(options.element, options.routePattern);
427
251
  const rootBoundaryId = artifactCompatibility?.rootBoundaryId ?? null;
428
252
  const renderEpoch = artifactCompatibility?.renderEpoch ?? null;
@@ -439,23 +263,13 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
439
263
  rootBoundaryId,
440
264
  routePattern: options.routePattern
441
265
  });
442
- const skipDisposition = options.skipDisposition ?? createRenderLifecycleSkipDisposition({
443
- artifactCompatibility,
444
- cleanPathname: options.cleanPathname,
445
- clientReuseManifest: options.clientReuseManifest,
446
- element: options.element,
447
- isRscRequest: options.isRscRequest,
448
- layoutFlags,
449
- layoutParamAccess: options.layoutParamAccess
450
- });
451
- const shouldBypassRscCache = options.isRscRequest && isSkipTransportEnabled(skipDisposition) || options.bypassInterceptionContextCache === true;
266
+ const isPartialPayload = options.isRscRequest && isAppElementsRecord(options.element) && Object.hasOwn(options.element, AppElementsWire.keys.skippedLayoutIds);
267
+ const shouldBypassRscCache = options.bypassInterceptionContextCache === true || isPartialPayload;
452
268
  const dynamicStaleTimeSeconds = options.dynamicStaleTimeSeconds ?? resolveConfiguredDynamicStaleTimeSeconds();
453
269
  const outgoingElement = AppElementsWire.encodeOutgoingPayload({
454
270
  element: options.element,
455
- layoutFlags,
456
271
  ...dynamicStaleTimeSeconds !== void 0 && options.isPrerender !== true && !options.isForceStatic ? { dynamicStaleTimeSeconds } : {},
457
- ...artifactCompatibility ? { artifactCompatibility } : {},
458
- skipDisposition: options.isRscRequest ? skipDisposition : void 0
272
+ ...artifactCompatibility ? { artifactCompatibility } : {}
459
273
  });
460
274
  const compileEnd = options.isProduction ? void 0 : performance.now();
461
275
  const errorContextOverrides = {
@@ -466,6 +280,7 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
466
280
  ...options.isPrerender ? { revalidateReason: "stale" } : {}
467
281
  };
468
282
  const baseOnError = options.createRscOnErrorHandler(options.cleanPathname, options.routePattern, errorContextOverrides);
283
+ const layoutGate = options.isRscRequest && options.isPrerender !== true && options.pprFallbackShellSignal === void 0 ? getAppPageLayoutGate(options.element) : null;
469
284
  const rscErrorTracker = createAppPageRscErrorTracker((error, requestInfo, errorContext) => {
470
285
  if (renderSpan) recordAppPageRenderError(renderSpan, error);
471
286
  return baseOnError(error, requestInfo, errorContext);
@@ -484,6 +299,24 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
484
299
  });
485
300
  let pprFallbackShellRsc = null;
486
301
  if (options.pprFallbackShellSignal) pprFallbackShellRsc = new Uint8Array(await readAppPageBinaryStream(rscStream));
302
+ if (layoutGate) {
303
+ const [heldStream, watchedStream] = rscStream.tee();
304
+ rscStream = heldStream;
305
+ const watchedReader = watchedStream.getReader();
306
+ const renderEnded = (async () => {
307
+ while (!(await watchedReader.read()).done);
308
+ })();
309
+ const layoutFailure = await layoutGate.wait((layoutId) => isAppElementsRecord(outgoingElement) && Object.hasOwn(outgoingElement, layoutId), renderEnded);
310
+ watchedReader.cancel().catch(() => {});
311
+ const layoutSpecialError = layoutFailure ? resolveAppPageSpecialError(layoutFailure.error) : null;
312
+ if (layoutFailure && layoutSpecialError) {
313
+ rscStream.cancel().catch(() => {});
314
+ return applyIneligibleRouteCachePolicy(await options.renderPageSpecialError(layoutSpecialError.kind === "http-access-fallback" ? {
315
+ ...layoutSpecialError,
316
+ layoutIndex: layoutFailure.layoutIndex
317
+ } : layoutSpecialError), options, options.peekRequestCacheLife?.() ?? options.getRequestCacheLife());
318
+ }
319
+ }
487
320
  let revalidateSeconds = options.revalidateSeconds;
488
321
  let expireSeconds = options.expireSeconds;
489
322
  const shouldWaitForAllReady = options.isPrerender === true && options.isSpeculativePrerender !== true || options.renderWholeDocument === true;
@@ -501,10 +334,47 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
501
334
  const rscForResponse = rscCapture.ssrStream;
502
335
  const capturedRscDataRef = { value: null };
503
336
  if (rscCapture.sideStream && options.isRscRequest) capturedRscDataRef.value = readAppPageBinaryStream(rscCapture.sideStream);
337
+ const resolveInitialNavigationCacheMetadata = (dynamicUsed, requestCacheLife) => {
338
+ let kind;
339
+ if (options.isForceStatic) kind = "static";
340
+ else if (options.isForceDynamic || dynamicUsed) kind = "dynamic";
341
+ else {
342
+ const observation = options.peekRenderObservationState?.();
343
+ kind = observation && (observation.dynamicFetches.length > 0 || observation.requestApis.length > 0) ? "dynamic" : "static";
344
+ }
345
+ const staleTimeSeconds = resolveClientStaleTimeSeconds(requestCacheLife);
346
+ return {
347
+ kind,
348
+ ...kind === "dynamic" && dynamicStaleTimeSeconds !== void 0 && options.isPrerender !== true ? { dynamicStaleTimeSeconds } : {},
349
+ ...staleTimeSeconds === void 0 ? {} : { staleTimeSeconds: Math.floor(staleTimeSeconds) }
350
+ };
351
+ };
504
352
  if (options.isRscRequest) {
505
- const resolveRscRenderStatus = options.isProduction && shouldCaptureRscForCacheMetadata && capturedRscDataRef.value !== null && options.isPrerender !== true && options.isRoutePPREnabled !== true ? createAppPageRscRenderStatusResolver({
353
+ const capturedRscData = capturedRscDataRef.value;
354
+ const resolvesRscRenderStatus = options.isProduction && shouldCaptureRscForCacheMetadata && capturedRscData !== null && options.isPrerender !== true && options.isRoutePPREnabled !== true;
355
+ const isPageDocumentRender = options.isCacheCandidate === true && !options.scriptNonce && !options.mountedSlotsHeader && !options.interceptionContext && !options.interceptionId && (options.renderMode === void 0 || options.renderMode === "navigation");
356
+ const cdnCacheAdapter = getCdnCacheAdapter();
357
+ const captureAdmittedDocument = resolvesRscRenderStatus && isPageDocumentRender && !cdnCacheAdapter.ownsBackgroundRevalidation ? cdnCacheAdapter.captureAppPageDocument?.() : void 0;
358
+ const rendersDocument = isPageDocumentRender && (cdnCacheAdapter.ownsBackgroundRevalidation || captureAdmittedDocument !== void 0);
359
+ const resolveRscRenderStatus = resolvesRscRenderStatus ? createAppPageRscRenderStatusResolver({
506
360
  basePath: options.basePath,
507
- capturedRscData: capturedRscDataRef.value,
361
+ capturedRscData,
362
+ ...rendersDocument ? { document: {
363
+ clientTraceMetadata: options.clientTraceMetadata,
364
+ ...captureAdmittedDocument ? { deadlineAt: getRouteCacheabilityCaptureOptions()?.captureDeadlineAt } : {},
365
+ getFontData: () => createAppPageFontData({
366
+ getLinks: options.getFontLinks,
367
+ getPreloads: options.getFontPreloads,
368
+ getStyles: options.getFontStyles
369
+ }),
370
+ getInitialNavigationCacheMetadata: () => resolveInitialNavigationCacheMetadata(peekDynamicUsage(), options.peekRequestCacheLife?.()),
371
+ mirrorNextFlight: () => rscErrorTracker.getCapturedSpecialError() !== null,
372
+ onSsrError: createAppPageSsrErrorHandler(options.createRscOnErrorHandler(options.cleanPathname, options.routePattern, {
373
+ ...errorContextOverrides,
374
+ renderSource: "server-rendering"
375
+ }), rscErrorTracker.isCapturedError),
376
+ reactMaxHeadersLength: options.reactMaxHeadersLength
377
+ } } : {},
508
378
  getCapturedSpecialError: rscErrorTracker.getCapturedSpecialError,
509
379
  getCapturedSpecialErrors: rscErrorTracker.getCapturedSpecialErrors,
510
380
  isForceStatic: options.isForceStatic,
@@ -524,7 +394,7 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
524
394
  }));
525
395
  }
526
396
  const dynamicUsedDuringBuild = consumeRenderDynamicUsage();
527
- const rscResponsePolicy = shouldBypassRscCache ? { cacheControl: NO_STORE_CACHE_CONTROL } : resolveAppPageRscResponsePolicy({
397
+ const rscResponsePolicy = isPartialPayload ? { cacheControl: resolveUncacheableCacheControl(options.isProduction) } : shouldBypassRscCache ? { cacheControl: NO_STORE_CACHE_CONTROL } : resolveAppPageRscResponsePolicy({
528
398
  dynamicUsedDuringBuild,
529
399
  isDraftMode: options.isDraftMode,
530
400
  isDynamicError: options.isDynamicError,
@@ -535,7 +405,7 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
535
405
  expireSeconds,
536
406
  revalidateSeconds
537
407
  });
538
- if (shouldBypassRscCache) options.isrDebug?.(options.bypassInterceptionContextCache === true ? "RSC cache write skipped (unverified interception context)" : "RSC cache write skipped (skip transport payload)", options.cleanPathname);
408
+ if (shouldBypassRscCache) options.isrDebug?.(isPartialPayload ? "RSC cache write skipped (partial payload)" : "RSC cache write skipped (unverified interception context)", options.cleanPathname);
539
409
  const shouldEmitDynamicStaleTime = dynamicStaleTimeSeconds !== void 0 && options.isPrerender !== true && !options.isForceStatic && (dynamicUsedDuringBuild || options.isForceDynamic);
540
410
  const staleTimePending = options.isPrerender !== true && mayResolveCacheLifeAfterHeaders && !dynamicUsedDuringBuild;
541
411
  const rscResponse = buildAppPageRscResponse(rscForResponse, {
@@ -575,9 +445,22 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
575
445
  return finalizeAppPageRscCacheResponse(devRscResponse, {
576
446
  capturedRscDataPromise: options.isProduction && shouldCaptureRscForCacheMetadata ? capturedRscDataRef.value : null,
577
447
  bypassInterceptionContextCache: options.bypassInterceptionContextCache,
448
+ captureAdmittedDocument,
578
449
  cleanPathname: options.cleanPathname,
579
450
  consumeDynamicUsage: finalizeRenderDynamicUsage,
580
451
  consumeRenderObservationState,
452
+ createHtmlRenderObservation(input) {
453
+ return createAppPageRenderObservation({
454
+ boundaryOutcome: { kind: "success" },
455
+ cacheability: "public",
456
+ cacheTags: input.cacheTags,
457
+ cleanPathname: options.cleanPathname,
458
+ completeness: "complete",
459
+ output: htmlOutputScope,
460
+ params: options.navigationParams,
461
+ state: input.state
462
+ });
463
+ },
581
464
  createRscRenderObservation(input) {
582
465
  return createAppPageRenderObservation({
583
466
  boundaryOutcome: { kind: "success" },
@@ -598,6 +481,7 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
598
481
  return readRequestCacheLifeForCachePolicy(options);
599
482
  },
600
483
  isrDebug: options.isrDebug,
484
+ isrHtmlKey: options.isrHtmlKey,
601
485
  isrRscKey: options.isrRscKey,
602
486
  isrSet: options.isrSet,
603
487
  interceptionContext: options.interceptionContext,
@@ -801,22 +685,7 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
801
685
  };
802
686
  return renderAppPageHtmlStream({
803
687
  capturedRscDataRef,
804
- getInitialNavigationCacheMetadata: () => {
805
- let kind;
806
- if (options.isForceStatic) kind = "static";
807
- else if (options.isForceDynamic || dynamicUsedDuringHtmlRender || peekDynamicUsage()) kind = "dynamic";
808
- else {
809
- const observation = options.peekRenderObservationState?.();
810
- kind = observation && (observation.dynamicFetches.length > 0 || observation.requestApis.length > 0) ? "dynamic" : "static";
811
- }
812
- const requestCacheLife = options.isPrerender === true ? requestCacheLifeForPrerender ?? options.peekRequestCacheLife?.() : options.peekRequestCacheLife?.();
813
- const staleTimeSeconds = resolveClientStaleTimeSeconds(requestCacheLife);
814
- return {
815
- kind,
816
- ...kind === "dynamic" && dynamicStaleTimeSeconds !== void 0 && options.isPrerender !== true ? { dynamicStaleTimeSeconds } : {},
817
- ...staleTimeSeconds === void 0 ? {} : { staleTimeSeconds: Math.floor(staleTimeSeconds) }
818
- };
819
- },
688
+ getInitialNavigationCacheMetadata: () => resolveInitialNavigationCacheMetadata(dynamicUsedDuringHtmlRender || peekDynamicUsage(), options.isPrerender === true ? requestCacheLifeForPrerender ?? options.peekRequestCacheLife?.() : options.peekRequestCacheLife?.()),
820
689
  fontData,
821
690
  hasCustomGlobalError: options.hasCustomGlobalError,
822
691
  navigationContext: options.getNavigationContext(),
@@ -1,5 +1,4 @@
1
1
  import { AppPageSpecialError } from "./app-page-execution.js";
2
- import { AppLayoutParamAccessTracker } from "./app-layout-param-observation.js";
3
2
  //#region src/server/app-page-request.d.ts
4
3
  type AppPageParams = Record<string, string | string[]>;
5
4
  type GenerateStaticParams = (args: {
@@ -120,7 +119,7 @@ type ResolveAppPageInterceptionRerenderTargetResult<TRoute, TInterceptOpts> = {
120
119
  type ResolveAppPageActionRerenderTargetOptions<TRoute, TPage, TInterceptOpts> = ResolveAppPageInterceptionRerenderTargetOptions<TRoute, TPage, TInterceptOpts>;
121
120
  type ResolveAppPageActionRerenderTargetResult<TRoute, TInterceptOpts> = ResolveAppPageInterceptionRerenderTargetResult<TRoute, TInterceptOpts>;
122
121
  type ResolveAppPageInterceptOptions<TRoute, TPage, TInterceptOpts, TElement> = {
123
- buildPageElement: (route: TRoute, params: AppPageParams, interceptOpts: TInterceptOpts | undefined, searchParams: URLSearchParams, layoutParamAccess?: AppLayoutParamAccessTracker, buildOptions?: {
122
+ buildPageElement: (route: TRoute, params: AppPageParams, interceptOpts: TInterceptOpts | undefined, searchParams: URLSearchParams, buildOptions?: {
124
123
  observeMetadataSearchParamsAccess?: boolean;
125
124
  observePageSearchParamsAccess?: boolean;
126
125
  }) => Promise<TElement>;
@@ -130,7 +129,6 @@ type ResolveAppPageInterceptOptions<TRoute, TPage, TInterceptOpts, TElement> = {
130
129
  getRouteParamNames: (route: TRoute) => readonly string[];
131
130
  getSourceRoute: (sourceRouteIndex: number) => Awaitable<TRoute | undefined>;
132
131
  isRscRequest: boolean;
133
- layoutParamAccess?: AppLayoutParamAccessTracker;
134
132
  resolveNavigationParams: (route: TRoute, params: AppPageParams, pathname: string, interceptOpts: TInterceptOpts) => AppPageParams;
135
133
  renderInterceptResponse: (route: TRoute, element: TElement) => Promise<Response> | Response;
136
134
  resolveSearchParams?: (route: TRoute, searchParams: URLSearchParams) => Awaitable<URLSearchParams>;
@@ -353,7 +353,7 @@ async function resolveAppPageIntercept(options) {
353
353
  pathname: options.cleanPathname,
354
354
  searchParams: renderSearchParams
355
355
  });
356
- const interceptElement = await options.buildPageElement(renderRoute, renderParams, interceptOpts, renderSearchParams, options.layoutParamAccess);
356
+ const interceptElement = await options.buildPageElement(renderRoute, renderParams, interceptOpts, renderSearchParams);
357
357
  return {
358
358
  interceptOpts: void 0,
359
359
  response: await options.renderInterceptResponse(renderRoute, interceptElement)
@@ -2,14 +2,14 @@ import { VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_RSC_VARY_HEADER } from "./app-rsc-v
2
2
  import { NEXT_CACHE_TAGS_HEADER, NEXT_ROUTER_STALE_TIME_HEADER, VINEXT_DYNAMIC_STALE_TIME_HEADER, VINEXT_PARAMS_HEADER, VINEXT_RENDERED_PATH_AND_SEARCH_HEADER, VINEXT_STALE_TIME_PENDING_HEADER, VINEXT_TIMING_HEADER } from "./headers.js";
3
3
  import { NEVER_CACHE_CONTROL, NO_STORE_CACHE_CONTROL, STATIC_CACHE_CONTROL, buildRevalidateCacheControl } from "./cache-control.js";
4
4
  import { setCacheStateHeaders } from "./cache-headers.js";
5
- import { VINEXT_RSC_CONTENT_TYPE, applyRscCompatibilityIdHeader, applyRscDeploymentIdHeader } from "./app-rsc-cache-busting.js";
5
+ import { markFrameworkLinkHeaders } from "./app-response-header-provenance.js";
6
6
  import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
7
+ import { VINEXT_RSC_CONTENT_TYPE, applyRscCompatibilityIdHeader, applyRscDeploymentIdHeader } from "./app-rsc-cache-busting.js";
7
8
  import { applyPrerenderCacheLifeHeader } from "./prerender-cache-life-header.js";
8
- import { markFrameworkLinkHeaders } from "./app-response-header-provenance.js";
9
9
  //#region src/server/app-page-response.ts
10
10
  function applyTimingHeader(headers, timing) {
11
11
  if (!timing) return;
12
- const handlerStart = Math.round(timing.handlerStart);
12
+ const handlerStart = Math.round(Date.now() - (performance.now() - timing.handlerStart));
13
13
  const compileMs = timing.compileEnd !== void 0 ? Math.round(timing.compileEnd - timing.handlerStart) : -1;
14
14
  const renderMs = timing.responseKind === "html" && timing.renderEnd !== void 0 && timing.compileEnd !== void 0 ? Math.round(timing.renderEnd - timing.compileEnd) : -1;
15
15
  headers.set(VINEXT_TIMING_HEADER, `${handlerStart},${compileMs},${renderMs}`);