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,16 +1,6 @@
1
1
  import { fnv1a64 } from "../utils/hash.js";
2
- import { evaluateArtifactCompatibility } from "./artifact-compatibility.js";
3
- import { findSortedStringPosition } from "../utils/sorted-array.js";
4
2
  //#region src/server/cache-proof.ts
5
3
  const CACHE_PROOF_MODEL_SCHEMA_VERSION = 1;
6
- const DEFAULT_CACHE_VARIANT_BUDGET = {
7
- maxDimensionCount: 8,
8
- maxDimensionNameLength: 64,
9
- maxDimensionValueLength: 256,
10
- maxEncodedLength: 1024,
11
- maxValuesPerDimension: 8,
12
- maxVariantsPerRoute: 64
13
- };
14
4
  const ALL_RENDER_REQUEST_API_KINDS = [
15
5
  "connection",
16
6
  "cookies",
@@ -19,13 +9,6 @@ const ALL_RENDER_REQUEST_API_KINDS = [
19
9
  "params",
20
10
  "searchParams"
21
11
  ];
22
- const PUBLIC_UNSAFE_DIMENSION_SOURCES = /* @__PURE__ */ new Set([
23
- "auth",
24
- "cookie",
25
- "draft-mode",
26
- "header",
27
- "session"
28
- ]);
29
12
  function buildBreakerFallback(code, fields = {}, mode = "renderFresh", scope = "affectedOutput") {
30
13
  return {
31
14
  kind: "breakerFallback",
@@ -38,332 +21,15 @@ function buildBreakerFallback(code, fields = {}, mode = "renderFresh", scope = "
38
21
  function sortedUnique(values) {
39
22
  return [...new Set(values)].sort();
40
23
  }
41
- function normalizeDimensionName(name) {
42
- return name.trim().toLowerCase();
43
- }
44
24
  function redactValue(value) {
45
25
  return `h:${fnv1a64(value)}`;
46
26
  }
47
27
  function sortedUniqueRedacted(values) {
48
28
  return sortedUnique(sortedUnique(values).map(redactValue));
49
29
  }
50
- function encodeParts(parts) {
51
- return JSON.stringify(parts);
52
- }
53
- function compareDimensions(a, b) {
54
- return a.source.localeCompare(b.source) || a.name.localeCompare(b.name) || a.privacy.localeCompare(b.privacy);
55
- }
56
- function encodeNullable(value) {
57
- return value;
58
- }
59
30
  function assertNever(value) {
60
31
  throw new Error(`Unhandled cache proof variant: ${String(value)}`);
61
32
  }
62
- function encodeOutputScope(output) {
63
- switch (output.kind) {
64
- case "app-html": return encodeParts([
65
- output.kind,
66
- output.routeId,
67
- encodeNullable(output.rootBoundaryId),
68
- encodeNullable(output.renderEpoch)
69
- ]);
70
- case "app-rsc": return encodeParts([
71
- output.kind,
72
- output.routeId,
73
- encodeNullable(output.rootBoundaryId),
74
- encodeNullable(output.renderEpoch),
75
- encodeNullable(output.mountedSlotsFingerprint)
76
- ]);
77
- case "layout": return encodeParts([
78
- output.kind,
79
- output.routeId,
80
- output.layoutId,
81
- encodeNullable(output.rootBoundaryId)
82
- ]);
83
- case "page": return encodeParts([
84
- output.kind,
85
- output.routeId,
86
- output.pageId,
87
- encodeNullable(output.rootBoundaryId)
88
- ]);
89
- case "route-handler": return encodeParts([
90
- output.kind,
91
- output.routeId,
92
- output.routeHandlerId
93
- ]);
94
- case "slot": return encodeParts([
95
- output.kind,
96
- output.routeId,
97
- output.slotId,
98
- encodeNullable(output.rootBoundaryId)
99
- ]);
100
- case "template": return encodeParts([
101
- output.kind,
102
- output.routeId,
103
- output.templateId,
104
- encodeNullable(output.rootBoundaryId)
105
- ]);
106
- default: return assertNever(output);
107
- }
108
- }
109
- function validateBudgetNumber(name, value) {
110
- if (Number.isInteger(value) && value >= 0) return null;
111
- return buildBreakerFallback("CP_INVALID_VARIANT_BUDGET", { budgetField: name });
112
- }
113
- function validateBudget(budget) {
114
- return validateBudgetNumber("maxDimensionCount", budget.maxDimensionCount) ?? validateBudgetNumber("maxDimensionNameLength", budget.maxDimensionNameLength) ?? validateBudgetNumber("maxDimensionValueLength", budget.maxDimensionValueLength) ?? validateBudgetNumber("maxEncodedLength", budget.maxEncodedLength) ?? validateBudgetNumber("maxValuesPerDimension", budget.maxValuesPerDimension) ?? validateBudgetNumber("maxVariantsPerRoute", budget.maxVariantsPerRoute);
115
- }
116
- function buildDimension(input, budget) {
117
- const name = normalizeDimensionName(input.name);
118
- if (name.length === 0) return buildBreakerFallback("CP_DIMENSION_NAME_MISSING", { source: input.source });
119
- if (name.length > budget.maxDimensionNameLength) return buildBreakerFallback("CP_DIMENSION_NAME_TOO_LONG", {
120
- maxLength: budget.maxDimensionNameLength,
121
- nameHash: redactValue(name),
122
- source: input.source
123
- });
124
- if (input.privacy === "public" && PUBLIC_UNSAFE_DIMENSION_SOURCES.has(input.source)) return buildBreakerFallback("CP_UNSAFE_PUBLIC_DIMENSION", {
125
- name,
126
- source: input.source
127
- }, "privateUncacheable");
128
- const values = sortedUnique(input.values);
129
- if (values.length === 0) return buildBreakerFallback("CP_DIMENSION_VALUES_MISSING", {
130
- name,
131
- source: input.source
132
- });
133
- if (values.length > budget.maxValuesPerDimension) return buildBreakerFallback("CP_DIMENSION_VALUE_COUNT_EXCEEDED", {
134
- maxValues: budget.maxValuesPerDimension,
135
- name,
136
- source: input.source,
137
- valueCount: values.length
138
- });
139
- for (const value of values) if (value.length > budget.maxDimensionValueLength) return buildBreakerFallback("CP_DIMENSION_VALUE_TOO_LONG", {
140
- maxLength: budget.maxDimensionValueLength,
141
- name,
142
- source: input.source,
143
- valueHash: redactValue(value)
144
- });
145
- const valueHashes = values.map(redactValue);
146
- return {
147
- encoded: encodeParts([
148
- input.source,
149
- input.privacy,
150
- name,
151
- valueHashes
152
- ]),
153
- name,
154
- privacy: input.privacy,
155
- source: input.source,
156
- valueCount: valueHashes.length,
157
- valueHashes
158
- };
159
- }
160
- function isCacheProofBreakerFallback(value) {
161
- return "code" in value;
162
- }
163
- function getDimensionBucket(bySource, source, privacy) {
164
- const existingByPrivacy = bySource.get(source);
165
- const byPrivacy = existingByPrivacy ?? /* @__PURE__ */ new Map();
166
- if (!existingByPrivacy) bySource.set(source, byPrivacy);
167
- const existingByName = byPrivacy.get(privacy);
168
- const byName = existingByName ?? /* @__PURE__ */ new Map();
169
- if (!existingByName) byPrivacy.set(privacy, byName);
170
- return byName;
171
- }
172
- function mergeDimensionInputs(dimensions) {
173
- const bySource = /* @__PURE__ */ new Map();
174
- const orderedDimensions = [];
175
- for (const dimension of dimensions) {
176
- const name = normalizeDimensionName(dimension.name);
177
- const bucket = getDimensionBucket(bySource, dimension.source, dimension.privacy);
178
- const existing = bucket.get(name);
179
- if (existing) {
180
- existing.values.push(...dimension.values);
181
- continue;
182
- }
183
- const accumulator = {
184
- name,
185
- privacy: dimension.privacy,
186
- source: dimension.source,
187
- values: [...dimension.values]
188
- };
189
- bucket.set(name, accumulator);
190
- orderedDimensions.push(accumulator);
191
- }
192
- return orderedDimensions;
193
- }
194
- function createAppRouteCacheProofGraphScope(route) {
195
- return {
196
- routeId: route.ids.route,
197
- pageId: route.ids.page,
198
- routeHandlerId: route.ids.routeHandler,
199
- layoutIds: [...route.ids.layouts],
200
- templateIds: [...route.ids.templates],
201
- slotIds: sortedUnique(Object.values(route.ids.slots))
202
- };
203
- }
204
- function buildCacheVariant(input) {
205
- const budgetFallback = validateBudget(input.budget);
206
- if (budgetFallback) return {
207
- kind: "breakerFallback",
208
- fallback: budgetFallback
209
- };
210
- const dimensionInputs = mergeDimensionInputs(input.dimensions);
211
- if (dimensionInputs.length > input.budget.maxDimensionCount) return {
212
- kind: "breakerFallback",
213
- fallback: buildBreakerFallback("CP_DIMENSION_COUNT_EXCEEDED", {
214
- dimensionCount: dimensionInputs.length,
215
- maxDimensionCount: input.budget.maxDimensionCount,
216
- routeId: input.output.routeId
217
- })
218
- };
219
- const dimensions = [];
220
- for (const dimensionInput of dimensionInputs) {
221
- const dimension = buildDimension(dimensionInput, input.budget);
222
- if (isCacheProofBreakerFallback(dimension)) return {
223
- kind: "breakerFallback",
224
- fallback: dimension
225
- };
226
- dimensions.push(dimension);
227
- }
228
- dimensions.sort(compareDimensions);
229
- const encoded = [
230
- `schema:1`,
231
- encodeOutputScope(input.output),
232
- ...dimensions.map((dimension) => dimension.encoded)
233
- ].join("|");
234
- if (encoded.length > input.budget.maxEncodedLength) return {
235
- kind: "breakerFallback",
236
- fallback: buildBreakerFallback("CP_ENCODED_VARIANT_TOO_LONG", {
237
- encodedHash: redactValue(encoded),
238
- encodedLength: encoded.length,
239
- maxEncodedLength: input.budget.maxEncodedLength,
240
- routeId: input.output.routeId
241
- })
242
- };
243
- return {
244
- kind: "variant",
245
- variant: {
246
- schemaVersion: 1,
247
- cacheKey: `cp1:${fnv1a64(encoded)}`,
248
- output: input.output,
249
- dimensions,
250
- encodedLength: encoded.length,
251
- budget: { ...input.budget }
252
- }
253
- };
254
- }
255
- function normalizeRouteBudget(input) {
256
- return {
257
- routeId: input.routeId,
258
- variantCacheKeys: sortedUnique(input.variantCacheKeys)
259
- };
260
- }
261
- function buildRouteVariantCeilingFallback(variant, existingVariantCount) {
262
- return buildBreakerFallback("CP_ROUTE_VARIANT_CEILING_EXCEEDED", {
263
- existingVariantCount,
264
- maxVariantsPerRoute: variant.budget.maxVariantsPerRoute,
265
- routeId: variant.output.routeId
266
- }, "privateUncacheable", "route");
267
- }
268
- function enforceCacheVariantRouteBudget(input) {
269
- if (input.routeBudget && input.routeBudget.routeId !== input.variant.output.routeId) return {
270
- kind: "breakerFallback",
271
- routeBudget: normalizeRouteBudget(input.routeBudget),
272
- fallback: buildBreakerFallback("CP_ROUTE_VARIANT_BUDGET_ROUTE_MISMATCH", {
273
- budgetRouteId: input.routeBudget.routeId,
274
- routeId: input.variant.output.routeId
275
- }, "privateUncacheable", "route")
276
- };
277
- const routeBudget = normalizeRouteBudget(input.routeBudget ?? {
278
- routeId: input.variant.output.routeId,
279
- variantCacheKeys: []
280
- });
281
- const existingVariantCount = routeBudget.variantCacheKeys.length;
282
- const variantKeyPosition = findSortedStringPosition(routeBudget.variantCacheKeys, input.variant.cacheKey);
283
- if (existingVariantCount > input.variant.budget.maxVariantsPerRoute) return {
284
- kind: "breakerFallback",
285
- routeBudget,
286
- fallback: buildRouteVariantCeilingFallback(input.variant, existingVariantCount)
287
- };
288
- if (variantKeyPosition.found) return {
289
- kind: "variant",
290
- variant: input.variant,
291
- routeBudget,
292
- didConsumeRouteVariantBudget: false
293
- };
294
- if (existingVariantCount >= input.variant.budget.maxVariantsPerRoute) return {
295
- kind: "breakerFallback",
296
- routeBudget,
297
- fallback: buildRouteVariantCeilingFallback(input.variant, existingVariantCount)
298
- };
299
- return {
300
- kind: "variant",
301
- variant: input.variant,
302
- routeBudget: {
303
- routeId: routeBudget.routeId,
304
- variantCacheKeys: [
305
- ...routeBudget.variantCacheKeys.slice(0, variantKeyPosition.index),
306
- input.variant.cacheKey,
307
- ...routeBudget.variantCacheKeys.slice(variantKeyPosition.index)
308
- ]
309
- },
310
- didConsumeRouteVariantBudget: true
311
- };
312
- }
313
- function buildCacheVariantWithRouteBudget(input) {
314
- const variantResult = buildCacheVariant({
315
- budget: input.budget,
316
- dimensions: input.dimensions,
317
- output: input.output
318
- });
319
- if (variantResult.kind === "breakerFallback") return {
320
- kind: "breakerFallback",
321
- routeBudget: input.routeBudget ? normalizeRouteBudget(input.routeBudget) : null,
322
- fallback: variantResult.fallback
323
- };
324
- return enforceCacheVariantRouteBudget({
325
- routeBudget: input.routeBudget,
326
- variant: variantResult.variant
327
- });
328
- }
329
- function boundaryOutcomesMatch(expected, candidate) {
330
- switch (expected.kind) {
331
- case "error": return candidate.kind === "error" && (expected.digest ?? "") === (candidate.digest ?? "");
332
- case "forbidden": return candidate.kind === "forbidden";
333
- case "globalError": return candidate.kind === "globalError" && (expected.digest ?? "") === (candidate.digest ?? "");
334
- case "notFound": return candidate.kind === "notFound";
335
- case "redirect": return candidate.kind === "redirect" && expected.status === candidate.status && expected.location === candidate.location;
336
- case "success": return candidate.kind === "success";
337
- case "unauthorized": return candidate.kind === "unauthorized";
338
- case "unknown": return false;
339
- default: return assertNever(expected);
340
- }
341
- }
342
- function buildBoundaryOutcomeCompatibility(input) {
343
- if (input.expected.kind === "unknown" || input.candidate.kind === "unknown") return {
344
- kind: "incompatible",
345
- expected: input.expected,
346
- candidate: input.candidate,
347
- fallback: buildBreakerFallback("CP_BOUNDARY_OUTCOME_UNKNOWN", {
348
- candidateKind: input.candidate.kind,
349
- expectedKind: input.expected.kind
350
- })
351
- };
352
- if (boundaryOutcomesMatch(input.expected, input.candidate)) return {
353
- kind: "compatible",
354
- outcome: input.candidate,
355
- reason: "CP_BOUNDARY_OUTCOME_MATCH"
356
- };
357
- return {
358
- kind: "incompatible",
359
- expected: input.expected,
360
- candidate: input.candidate,
361
- fallback: buildBreakerFallback("CP_BOUNDARY_OUTCOME_MISMATCH", {
362
- candidateKind: input.candidate.kind,
363
- expectedKind: input.expected.kind
364
- })
365
- };
366
- }
367
33
  function requestApiStatusRank(status) {
368
34
  switch (status) {
369
35
  case "notObserved": return 0;
@@ -447,47 +113,6 @@ function classifyObservedRequestApiDowngrade(kind) {
447
113
  default: return assertNever(kind);
448
114
  }
449
115
  }
450
- function classifyCacheVariantDimensionDowngrade(input) {
451
- switch (input.source) {
452
- case "auth": return {
453
- code: "CP_DOWNGRADE_PRIVATE_DIMENSION",
454
- inputClass: "auth",
455
- source: "auth",
456
- target: "private"
457
- };
458
- case "cookie": return {
459
- code: "CP_DOWNGRADE_PRIVATE_DIMENSION",
460
- inputClass: "private",
461
- source: "cookie",
462
- target: "private"
463
- };
464
- case "draft-mode": return {
465
- code: "CP_DOWNGRADE_PRIVATE_DIMENSION",
466
- inputClass: "draft",
467
- source: "draft-mode",
468
- target: "privateUncacheable"
469
- };
470
- case "header": return {
471
- code: "CP_DOWNGRADE_PRIVATE_DIMENSION",
472
- inputClass: "private",
473
- source: "header",
474
- target: "private"
475
- };
476
- case "session": return {
477
- code: "CP_DOWNGRADE_PRIVATE_DIMENSION",
478
- inputClass: "session",
479
- source: "session",
480
- target: "private"
481
- };
482
- case "custom":
483
- case "interception":
484
- case "mounted-slots":
485
- case "params":
486
- case "route":
487
- case "search": return null;
488
- default: return assertNever(input.source);
489
- }
490
- }
491
116
  function classifyRenderObservationDowngrade(input) {
492
117
  const reasons = [];
493
118
  let target = "public";
@@ -602,164 +227,6 @@ function hasCompleteNegativeRequestApiProof(observation, requiredApis) {
602
227
  function hasQueryInvariantRenderProof(observation) {
603
228
  return observation !== void 0 && hasCompleteNegativeRequestApiProof(observation, ["searchParams"]);
604
229
  }
605
- function isStaticLayoutOutputScope(output) {
606
- return output.kind === "layout";
607
- }
608
- function rejectStaticLayoutReuseProof(code, fields, mode = "renderFresh") {
609
- return {
610
- kind: "rejected",
611
- fallback: buildBreakerFallback(code, fields, mode)
612
- };
613
- }
614
- function getRequestApiStatus(observations, kind) {
615
- let status = null;
616
- for (const requestApi of observations) {
617
- if (requestApi.kind !== kind) continue;
618
- if (status === null || requestApiStatusRank(requestApi.status) > requestApiStatusRank(status)) status = requestApi.status;
619
- }
620
- return status ?? "missing";
621
- }
622
- function createStaticLayoutDowngradeFallback(downgrade) {
623
- const mode = downgrade.target === "privateUncacheable" ? "privateUncacheable" : "renderFresh";
624
- return buildBreakerFallback("CP_STATIC_LAYOUT_PRIVATE_DYNAMIC_DOWNGRADE", {
625
- reasonCodes: downgrade.reasons.map((reason) => reason.code),
626
- target: downgrade.target
627
- }, mode);
628
- }
629
- function outputFieldMismatch(candidate, observation) {
630
- if (candidate.layoutId !== observation.layoutId) return "layoutId";
631
- if (candidate.rootBoundaryId !== observation.rootBoundaryId) return "rootBoundaryId";
632
- if (candidate.routeId !== observation.routeId) return "routeId";
633
- return null;
634
- }
635
- function buildStaticLayoutReuseProof(input) {
636
- if (!isStaticLayoutOutputScope(input.currentOutput)) return rejectStaticLayoutReuseProof("CP_STATIC_LAYOUT_CURRENT_OUTPUT_KIND", { currentOutputKind: input.currentOutput.kind });
637
- if (!isStaticLayoutOutputScope(input.candidateVariant.output)) return rejectStaticLayoutReuseProof("CP_STATIC_LAYOUT_CANDIDATE_OUTPUT_KIND", { candidateOutputKind: input.candidateVariant.output.kind });
638
- if (!isStaticLayoutOutputScope(input.candidateObservation.output)) return rejectStaticLayoutReuseProof("CP_STATIC_LAYOUT_OBSERVATION_OUTPUT_KIND", { observationOutputKind: input.candidateObservation.output.kind });
639
- const currentOutput = input.currentOutput;
640
- const candidateOutput = input.candidateVariant.output;
641
- const observationOutput = input.candidateObservation.output;
642
- const requestApis = normalizeRequestApiObservations(input.candidateObservation.requestApis);
643
- const candidateObservation = {
644
- ...input.candidateObservation,
645
- requestApis,
646
- downgrade: classifyRenderObservationDowngrade({
647
- cacheability: input.candidateObservation.cacheability,
648
- completeness: input.candidateObservation.completeness,
649
- dynamicFetches: input.candidateObservation.dynamicFetches,
650
- requestApis
651
- })
652
- };
653
- const observedOutputMismatch = outputFieldMismatch(candidateOutput, observationOutput);
654
- if (observedOutputMismatch) return rejectStaticLayoutReuseProof("CP_STATIC_LAYOUT_OBSERVATION_OUTPUT_MISMATCH", {
655
- candidateLayoutId: candidateOutput.layoutId,
656
- candidateRootBoundaryId: candidateOutput.rootBoundaryId,
657
- candidateRouteId: candidateOutput.routeId,
658
- field: observedOutputMismatch,
659
- observationLayoutId: observationOutput.layoutId,
660
- observationRootBoundaryId: observationOutput.rootBoundaryId,
661
- observationRouteId: observationOutput.routeId
662
- });
663
- if (currentOutput.layoutId !== candidateOutput.layoutId) return rejectStaticLayoutReuseProof("CP_STATIC_LAYOUT_ID_MISMATCH", {
664
- candidateLayoutId: candidateOutput.layoutId,
665
- currentLayoutId: currentOutput.layoutId
666
- });
667
- if (currentOutput.rootBoundaryId === null || candidateOutput.rootBoundaryId === null) return rejectStaticLayoutReuseProof("CP_STATIC_LAYOUT_ROOT_BOUNDARY_UNKNOWN", {
668
- candidateRootBoundaryId: candidateOutput.rootBoundaryId,
669
- currentRootBoundaryId: currentOutput.rootBoundaryId
670
- });
671
- if (currentOutput.rootBoundaryId !== candidateOutput.rootBoundaryId) return rejectStaticLayoutReuseProof("CP_STATIC_LAYOUT_ROOT_BOUNDARY_MISMATCH", {
672
- candidateRootBoundaryId: candidateOutput.rootBoundaryId,
673
- currentRootBoundaryId: currentOutput.rootBoundaryId
674
- });
675
- const boundaryCompatibility = buildBoundaryOutcomeCompatibility({
676
- candidate: candidateObservation.boundaryOutcome,
677
- expected: { kind: "success" }
678
- });
679
- if (boundaryCompatibility.kind === "incompatible") return {
680
- kind: "rejected",
681
- fallback: boundaryCompatibility.fallback
682
- };
683
- if (input.candidateVariant.dimensions.length > 0) return rejectStaticLayoutReuseProof("CP_STATIC_LAYOUT_VARIANT_DIMENSION_UNPROVEN", {
684
- dimensionCount: input.candidateVariant.dimensions.length,
685
- sources: sortedUnique(input.candidateVariant.dimensions.map((dimension) => dimension.source))
686
- });
687
- if (!candidateObservation.downgrade.isPublicCacheCandidate) return {
688
- kind: "rejected",
689
- fallback: createStaticLayoutDowngradeFallback(candidateObservation.downgrade)
690
- };
691
- const requiredNegativeRequestApis = ALL_RENDER_REQUEST_API_KINDS;
692
- for (const api of requiredNegativeRequestApis) {
693
- const status = getRequestApiStatus(candidateObservation.requestApis, api);
694
- if (status === "notObserved") continue;
695
- return rejectStaticLayoutReuseProof(status === "missing" ? "CP_STATIC_LAYOUT_REQUEST_API_UNKNOWN" : "CP_STATIC_LAYOUT_REQUEST_API_OBSERVED", {
696
- requestApi: api,
697
- status
698
- });
699
- }
700
- return {
701
- kind: "proof",
702
- proof: {
703
- authorizesRuntimeReuse: true,
704
- candidateOutput,
705
- code: "CP_STATIC_LAYOUT_REUSE_PROVEN",
706
- currentOutput,
707
- fields: {
708
- candidateRouteId: candidateOutput.routeId,
709
- currentRouteId: currentOutput.routeId,
710
- layoutId: currentOutput.layoutId,
711
- rootBoundaryId: currentOutput.rootBoundaryId
712
- },
713
- observation: candidateObservation,
714
- requiredNegativeRequestApis: [...requiredNegativeRequestApis],
715
- reuseClass: "static-layout",
716
- variant: input.candidateVariant
717
- }
718
- };
719
- }
720
- function createCacheProofHotPathMetric(outcome, code, fields) {
721
- return {
722
- name: "vinext.cache.static_layout_artifact_reuse",
723
- outcome,
724
- code,
725
- fields
726
- };
727
- }
728
- function createStaticLayoutArtifactReuseFallback(fallback) {
729
- return {
730
- kind: "fallback",
731
- canReuse: false,
732
- fallback,
733
- metric: createCacheProofHotPathMetric("fallback", fallback.code, fallback.fields)
734
- };
735
- }
736
- function createStaticLayoutArtifactReuseDecision(input) {
737
- if (input.candidateVariant.kind === "breakerFallback") return createStaticLayoutArtifactReuseFallback(input.candidateVariant.fallback);
738
- const artifactCompatibility = evaluateArtifactCompatibility(input.currentArtifactCompatibility, input.candidateArtifactCompatibility, { compatibilityMap: input.compatibilityMap });
739
- if (artifactCompatibility.kind === "unknown") return createStaticLayoutArtifactReuseFallback(buildBreakerFallback("CP_ARTIFACT_COMPATIBILITY_UNKNOWN", {
740
- compatibilityFallback: artifactCompatibility.fallback,
741
- reason: artifactCompatibility.reason
742
- }));
743
- if (artifactCompatibility.kind === "incompatible") return createStaticLayoutArtifactReuseFallback(buildBreakerFallback("CP_ARTIFACT_COMPATIBILITY_INCOMPATIBLE", {
744
- compatibilityFallback: artifactCompatibility.fallback,
745
- reason: artifactCompatibility.reason
746
- }));
747
- const proof = buildStaticLayoutReuseProof({
748
- candidateObservation: input.candidateObservation,
749
- candidateVariant: input.candidateVariant.variant,
750
- currentOutput: input.currentOutput
751
- });
752
- if (proof.kind === "rejected") return createStaticLayoutArtifactReuseFallback(proof.fallback);
753
- return {
754
- kind: "reuse",
755
- canReuse: true,
756
- proof: {
757
- ...proof.proof,
758
- candidateArtifactCompatibility: { ...input.candidateArtifactCompatibility }
759
- },
760
- metric: createCacheProofHotPathMetric("reuse", proof.proof.code, proof.proof.fields)
761
- };
762
- }
763
230
  function createCacheEntryReuseProof(decision) {
764
231
  if (decision === null) return {
765
232
  kind: "runtime-cache-entry",
@@ -788,15 +255,5 @@ function createCacheEntryReuseProof(decision) {
788
255
  default: return assertNever(decision);
789
256
  }
790
257
  }
791
- function createDisabledCacheProofDecision(input) {
792
- return {
793
- kind: "disabled",
794
- canReuse: false,
795
- variant: input.variant,
796
- observation: input.observation,
797
- ...input.staticLayoutProof ? { staticLayoutProof: input.staticLayoutProof } : {},
798
- fallback: buildBreakerFallback("CP_MODEL_DISABLED")
799
- };
800
- }
801
258
  //#endregion
802
- export { ALL_RENDER_REQUEST_API_KINDS, CACHE_PROOF_MODEL_SCHEMA_VERSION, DEFAULT_CACHE_VARIANT_BUDGET, buildBoundaryOutcomeCompatibility, buildCacheVariant, buildCacheVariantWithRouteBudget, buildRenderObservation, buildRenderRequestApiObservations, buildStaticLayoutReuseProof, classifyCacheVariantDimensionDowngrade, classifyRenderObservationDowngrade, createAppRouteCacheProofGraphScope, createCacheEntryReuseProof, createDisabledCacheProofDecision, createStaticLayoutArtifactReuseDecision, enforceCacheVariantRouteBudget, hasCompleteNegativeRequestApiProof, hasQueryInvariantRenderProof };
259
+ export { ALL_RENDER_REQUEST_API_KINDS, CACHE_PROOF_MODEL_SCHEMA_VERSION, buildRenderObservation, buildRenderRequestApiObservations, classifyRenderObservationDowngrade, createCacheEntryReuseProof, hasCompleteNegativeRequestApiProof, hasQueryInvariantRenderProof };
@@ -1,6 +1,6 @@
1
1
  import "../utils/protocol-headers.js";
2
2
  import { isVinextRscVaryField } from "./app-rsc-vary.js";
3
- import { VINEXT_CACHEABILITY_PROBE_HEADER, VINEXT_CACHEABILITY_PROBE_ROUTE_HEADER, VINEXT_SPECIAL_ERROR_STATUS_HEADER } from "./headers.js";
3
+ import { NEXT_ROUTER_STALE_TIME_HEADER, VINEXT_CACHEABILITY_PROBE_HEADER, VINEXT_CACHEABILITY_PROBE_ROUTE_HEADER, VINEXT_SPECIAL_ERROR_STATUS_HEADER, VINEXT_STALE_TIME_PENDING_HEADER } from "./headers.js";
4
4
  import { hasSharedCacheCredentials, isNonCacheableCacheControl } from "../shims/cdn-cache.js";
5
5
  import { CACHEABILITY_REQUEST_STATE, recordConfigCdnCachePolicyHeader } from "../shims/cacheability-classification.js";
6
6
  import { NO_STORE_CACHE_CONTROL, applyCdnResponseBuildIdentityHeaders, applyCdnResponseHeaders, hasExplicitNonCacheableResponsePolicy, isCdnResponsePolicyHeader, readCdnResponseCacheControl, readCdnResponsePolicyHeaderName } from "./cache-control.js";
@@ -348,20 +348,25 @@ async function captureCacheabilityAdmissionBody(body, deadlineAt, limit = CACHEA
348
348
  throw error;
349
349
  }
350
350
  }
351
- function responseWithCachePolicy(response, body, outcome, browserCacheControl, completedStatus) {
351
+ function responseWithCachePolicy(response, body, outcome, browserCacheControl, completedRender) {
352
352
  const headers = new Headers(response.headers);
353
353
  if (typeof body === "string") headers.delete("Content-Length");
354
- for (const [name, value] of Object.entries(completedStatus?.headers ?? {})) if (!headers.has(name)) headers.set(name, value);
355
- applyCdnResponseHeaders(headers, outcome?.cacheable === true && outcome.cacheControl ? {
356
- cacheControl: outcome.cacheControl,
357
- tags: outcome.tags,
354
+ for (const [name, value] of Object.entries(completedRender?.headers ?? {})) if (!headers.has(name)) headers.set(name, value);
355
+ const cacheControl = outcome?.cacheable === true ? outcome.cacheControl : void 0;
356
+ applyCdnResponseHeaders(headers, cacheControl ? {
357
+ cacheControl,
358
+ tags: outcome?.tags,
358
359
  browserCacheControl
359
360
  } : {
360
361
  cacheControl: NO_STORE_CACHE_CONTROL,
361
362
  browserCacheControl
362
363
  });
363
- const status = completedStatus?.status ?? response.status;
364
- const completed = completedStatus?.status;
364
+ if (cacheControl && completedRender) {
365
+ headers.delete(VINEXT_STALE_TIME_PENDING_HEADER);
366
+ if (completedRender.staleTimeSeconds !== void 0 && !headers.has("x-nextjs-stale-time")) headers.set(NEXT_ROUTER_STALE_TIME_HEADER, String(Math.floor(completedRender.staleTimeSeconds)));
367
+ }
368
+ const status = completedRender?.status ?? response.status;
369
+ const completed = completedRender?.status;
365
370
  if (completed === 401 || completed === 403 || completed === 404) headers.set(VINEXT_SPECIAL_ERROR_STATUS_HEADER, String(completed));
366
371
  return new Response(body, {
367
372
  headers,
@@ -13,7 +13,7 @@ import { NEVER_CACHE_CONTROL } from "./cache-control.js";
13
13
  import { buildMissIsrCacheControl } from "./isr-decision.js";
14
14
  import { isOnDemandRevalidateRequest } from "./revalidation-request.js";
15
15
  import "./isr-cache.js";
16
- import { ensureFetchPatch } from "../shims/fetch-cache.js";
16
+ import { ensureFetchPatch, setCurrentFetchDraftMode } from "../shims/fetch-cache.js";
17
17
  import { mergeRouteParamsIntoQuery, parseQueryString } from "../utils/query.js";
18
18
  import "../shims/router-state.js";
19
19
  import { withScriptNonce } from "../shims/script-nonce-context.js";
@@ -405,7 +405,7 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
405
405
  res.end("{}");
406
406
  return;
407
407
  }
408
- const requestContext = createRequestContext();
408
+ const requestContext = createRequestContext({ isOnDemandRevalidate: isOnDemandRevalidateRequest(req.headers[PRERENDER_REVALIDATE_HEADER]) });
409
409
  const closeRequest = () => void closeAfterResponse(requestContext);
410
410
  res.on("finish", closeRequest);
411
411
  res.on("close", closeRequest);
@@ -423,7 +423,7 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
423
423
  let requestAsPath = isDataReq ? gsspResolvedUrl : i18nConfig ? extractLocaleFromUrl$1(originalUrl, i18nConfig, locale).url : originalUrl;
424
424
  const userFacingParams = route.isDynamic ? params : null;
425
425
  let query = mergeRouteParamsIntoQuery(parseQueryString(url), params);
426
- const requestContext = createRequestContext();
426
+ const requestContext = createRequestContext({ isOnDemandRevalidate: isOnDemandRevalidateRequest(req.headers[PRERENDER_REVALIDATE_HEADER]) });
427
427
  let isStaticPropsRender = false;
428
428
  const closeRequest = () => void closeAfterResponse(requestContext);
429
429
  res.on("finish", closeRequest);
@@ -468,6 +468,7 @@ function createSSRHandler(server, runner, routes, pagesDir, i18nConfig, fileMatc
468
468
  shouldClear: false
469
469
  };
470
470
  const requestPreviewData = requestPreview.data;
471
+ setCurrentFetchDraftMode(requestPreviewData !== false);
471
472
  const pagesNextData = {
472
473
  ...buildPagesReadinessNextData({
473
474
  pageModule,
@@ -17,7 +17,7 @@ export declare const VINEXT_CACHE_HEADER = "X-Vinext-Cache";
17
17
  export declare const NEXTJS_CACHE_HEADER = "x-nextjs-cache";
18
18
  /** Next.js cache-tag metadata carried by prerendered App Router responses. */
19
19
  export declare const NEXT_CACHE_TAGS_HEADER = "x-next-cache-tags";
20
- /** Timing metrics: `handlerStart,compileMs,renderMs`. */
20
+ /** Timing metrics: `handlerStart,compileMs,renderMs` (handlerStart is wall-clock ms). */
21
21
  export declare const VINEXT_TIMING_HEADER = "x-vinext-timing";
22
22
  /** Matched route returned from an independently hosted response stage. */
23
23
  export declare const VINEXT_TRACE_ROUTE_HEADER = "X-Vinext-Trace-Route";
@@ -85,8 +85,11 @@ export declare const VINEXT_PRERENDER_RENDER_ERROR_HEADER = "x-vinext-prerender-
85
85
  export declare const VINEXT_PRERENDER_SPECIAL_ERROR_HEADER = "x-vinext-prerender-special-error";
86
86
  /** Internal marker persisted only inside metadata-route APP_ROUTE cache values. */
87
87
  export declare const VINEXT_METADATA_ROUTE_CACHE_HEADER = "x-vinext-metadata-route-cache";
88
- /** Disabled-by-default client hint describing already-held App Router payload entries. */
89
- export declare const VINEXT_CLIENT_REUSE_MANIFEST_HEADER = "X-Vinext-Client-Reuse-Manifest";
88
+ /**
89
+ * Hashed identities of the layouts a client navigation already holds, so a
90
+ * render that's never stored can leave them out. Not part of the RSC cache key.
91
+ */
92
+ export declare const VINEXT_MOUNTED_LAYOUTS_HEADER = "X-Vinext-Mounted-Layouts";
90
93
  /**
91
94
  * Side-channel signal that an RSC response (HTTP 200) encodes a `redirect()`
92
95
  * thrown during render. The header value is the redirect target (path-only