vinext 1.3.1 → 1.4.1

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 (271) hide show
  1. package/README.md +25 -22
  2. package/THIRD_PARTY_LICENSES.md +47 -0
  3. package/dist/_virtual/_rolldown/runtime.js +3 -2
  4. package/dist/build/prerender.js +4 -3
  5. package/dist/build/report.d.ts +0 -14
  6. package/dist/build/report.js +1 -51
  7. package/dist/check.js +4 -7
  8. package/dist/cli.js +3 -0
  9. package/dist/client/dev-error-overlay-store.d.ts +1 -0
  10. package/dist/client/dev-error-overlay.d.ts +2 -0
  11. package/dist/client/dev-error-overlay.js +20 -4
  12. package/dist/client/navigation-runtime.d.ts +13 -1
  13. package/dist/client/navigation-runtime.js +1 -1
  14. package/dist/config/config-matchers.js +2 -0
  15. package/dist/config/destination-params.d.ts +2 -1
  16. package/dist/config/destination-params.js +52 -2
  17. package/dist/config/next-config.d.ts +25 -0
  18. package/dist/config/next-config.js +82 -4
  19. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/dbcs-codec.js +327 -0
  20. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/dbcs-data.js +123 -0
  21. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/index.js +29 -0
  22. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/internal.js +134 -0
  23. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/sbcs-codec.js +50 -0
  24. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/sbcs-data-generated.js +455 -0
  25. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/sbcs-data.js +147 -0
  26. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/big5-added.json.js +169 -0
  27. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/cp936.json.js +2584 -0
  28. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/cp949.json.js +2220 -0
  29. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/cp950.json.js +227 -0
  30. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/eucjp.json.js +425 -0
  31. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/gb18030-ranges.json.js +427 -0
  32. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/gbk-added.json.js +229 -0
  33. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/shiftjis.json.js +292 -0
  34. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/utf16.js +106 -0
  35. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/utf7.js +182 -0
  36. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/lib/bom-handling.js +42 -0
  37. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/lib/extend-node.js +147 -0
  38. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/lib/index.js +94 -0
  39. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/lib/streams.js +95 -0
  40. package/dist/deps/.pnpm/safer-buffer@2.1.2/deps/safer-buffer/safer.js +45 -0
  41. package/dist/entries/app-rsc-entry.js +17 -49
  42. package/dist/entries/app-rsc-manifest.js +3 -4
  43. package/dist/entries/app-ssr-entry.js +1 -0
  44. package/dist/entries/pages-server-entry.js +36 -9
  45. package/dist/index.js +112 -90
  46. package/dist/init-cloudflare.d.ts +1 -3
  47. package/dist/init-cloudflare.js +10 -48
  48. package/dist/init-platform.d.ts +2 -0
  49. package/dist/init-platform.js +4 -0
  50. package/dist/plugins/extensionless-dynamic-import.js +6 -2
  51. package/dist/plugins/next-intl-catalog.d.ts +12 -0
  52. package/dist/plugins/next-intl-catalog.js +85 -0
  53. package/dist/plugins/pages-node-externals.d.ts +1 -0
  54. package/dist/plugins/pages-node-externals.js +1 -1
  55. package/dist/plugins/strip-server-exports.js +2 -1
  56. package/dist/plugins/use-cache-callable.d.ts +1 -1
  57. package/dist/plugins/use-cache-callable.js +136 -94
  58. package/dist/routing/app-route-graph.d.ts +6 -0
  59. package/dist/routing/app-route-graph.js +9 -1
  60. package/dist/server/api-handler.js +21 -5
  61. package/dist/server/app-bfcache-identity.js +1 -1
  62. package/dist/server/app-browser-entry.js +86 -66
  63. package/dist/server/app-browser-history-controller.d.ts +5 -4
  64. package/dist/server/app-browser-history-controller.js +93 -15
  65. package/dist/server/app-browser-navigation-controller.d.ts +2 -2
  66. package/dist/server/app-browser-navigation-controller.js +1 -2
  67. package/dist/server/app-browser-rsc-redirect.js +7 -7
  68. package/dist/server/app-browser-server-action-client.d.ts +2 -0
  69. package/dist/server/app-browser-server-action-client.js +5 -4
  70. package/dist/server/app-browser-state.d.ts +2 -4
  71. package/dist/server/app-browser-state.js +9 -4
  72. package/dist/server/app-browser-supplemental-refresh.js +16 -1
  73. package/dist/server/app-browser-visible-commit.d.ts +1 -1
  74. package/dist/server/app-browser-visible-commit.js +4 -14
  75. package/dist/server/app-elements-wire.d.ts +6 -38
  76. package/dist/server/app-elements-wire.js +4 -41
  77. package/dist/server/app-elements.d.ts +2 -2
  78. package/dist/server/app-elements.js +2 -2
  79. package/dist/server/app-history-state.d.ts +2 -2
  80. package/dist/server/app-history-state.js +5 -2
  81. package/dist/server/app-mounted-layouts.d.ts +21 -0
  82. package/dist/server/app-mounted-layouts.js +67 -0
  83. package/dist/server/app-optimistic-routing.d.ts +19 -1
  84. package/dist/server/app-optimistic-routing.js +43 -4
  85. package/dist/server/app-page-boundary-render.js +10 -14
  86. package/dist/server/app-page-boundary.js +2 -2
  87. package/dist/server/app-page-cache-finalizer.d.ts +12 -1
  88. package/dist/server/app-page-cache-finalizer.js +70 -29
  89. package/dist/server/app-page-cache.d.ts +13 -1
  90. package/dist/server/app-page-cache.js +31 -9
  91. package/dist/server/app-page-dispatch.d.ts +5 -11
  92. package/dist/server/app-page-dispatch.js +84 -155
  93. package/dist/server/app-page-element-builder.d.ts +2 -2
  94. package/dist/server/app-page-element-builder.js +13 -12
  95. package/dist/server/app-page-execution.d.ts +17 -52
  96. package/dist/server/app-page-execution.js +102 -95
  97. package/dist/server/app-page-head.d.ts +13 -0
  98. package/dist/server/app-page-head.js +44 -16
  99. package/dist/server/app-page-http-access-fallback-metadata.d.ts +1 -0
  100. package/dist/server/app-page-http-access-fallback-metadata.js +2 -2
  101. package/dist/server/app-page-layout-gate.d.ts +35 -0
  102. package/dist/server/app-page-layout-gate.js +50 -0
  103. package/dist/server/app-page-params.d.ts +0 -1
  104. package/dist/server/app-page-params.js +1 -14
  105. package/dist/server/app-page-probe.d.ts +3 -21
  106. package/dist/server/app-page-probe.js +4 -37
  107. package/dist/server/app-page-render.d.ts +2 -13
  108. package/dist/server/app-page-render.js +103 -234
  109. package/dist/server/app-page-request.d.ts +1 -3
  110. package/dist/server/app-page-request.js +1 -1
  111. package/dist/server/app-page-response.js +3 -3
  112. package/dist/server/app-page-route-wiring.d.ts +13 -6
  113. package/dist/server/app-page-route-wiring.js +86 -63
  114. package/dist/server/app-page-rsc-render-status.d.ts +27 -1
  115. package/dist/server/app-page-rsc-render-status.js +121 -13
  116. package/dist/server/app-page-stream.d.ts +12 -8
  117. package/dist/server/app-page-stream.js +4 -3
  118. package/dist/server/app-pages-bridge.d.ts +4 -0
  119. package/dist/server/app-pages-bridge.js +7 -3
  120. package/dist/server/app-render-dependency.d.ts +11 -4
  121. package/dist/server/app-render-dependency.js +86 -38
  122. package/dist/server/app-request-stage-dispatch.js +1 -1
  123. package/dist/server/app-request-stage-independent-entry.js +1 -1
  124. package/dist/server/app-route-handler-cache.js +2 -2
  125. package/dist/server/app-route-handler-dispatch.js +14 -9
  126. package/dist/server/app-route-handler-execution.js +11 -5
  127. package/dist/server/app-route-handler-policy.d.ts +1 -1
  128. package/dist/server/app-route-handler-policy.js +3 -3
  129. package/dist/server/app-route-handler-response.js +1 -1
  130. package/dist/server/app-route-handler-runtime.d.ts +1 -1
  131. package/dist/server/app-route-handler-runtime.js +28 -11
  132. package/dist/server/app-router-entry.js +1 -1
  133. package/dist/server/app-rsc-cache-busting.d.ts +12 -12
  134. package/dist/server/app-rsc-cache-busting.js +31 -72
  135. package/dist/server/app-rsc-error-handler.d.ts +2 -1
  136. package/dist/server/app-rsc-error-handler.js +10 -2
  137. package/dist/server/app-rsc-errors.d.ts +8 -0
  138. package/dist/server/app-rsc-errors.js +11 -1
  139. package/dist/server/app-rsc-handler.d.ts +5 -5
  140. package/dist/server/app-rsc-handler.js +80 -83
  141. package/dist/server/app-rsc-request-normalization.d.ts +10 -16
  142. package/dist/server/app-rsc-request-normalization.js +12 -18
  143. package/dist/server/app-rsc-response-finalizer.js +2 -2
  144. package/dist/server/app-rsc-response-stage.js +9 -15
  145. package/dist/server/app-server-action-execution.d.ts +3 -1
  146. package/dist/server/app-server-action-execution.js +15 -8
  147. package/dist/server/app-ssr-entry.d.ts +8 -0
  148. package/dist/server/app-ssr-entry.js +22 -16
  149. package/dist/server/app-ssr-stream.js +1 -1
  150. package/dist/server/app-visited-response-cache.d.ts +36 -1
  151. package/dist/server/app-visited-response-cache.js +46 -5
  152. package/dist/server/app-worker-stages.d.ts +37 -6
  153. package/dist/server/app-worker-stages.js +81 -9
  154. package/dist/server/artifact-compatibility.d.ts +0 -1
  155. package/dist/server/artifact-compatibility.js +1 -10
  156. package/dist/server/bfcache-identity.d.ts +7 -0
  157. package/dist/server/bfcache-identity.js +10 -1
  158. package/dist/server/cache-proof.d.ts +1 -115
  159. package/dist/server/cache-proof.js +1 -544
  160. package/dist/server/cacheability-manifest.js +1 -2
  161. package/dist/server/cacheability-request.js +13 -8
  162. package/dist/server/dev-origin-check.d.ts +2 -1
  163. package/dist/server/dev-origin-check.js +2 -1
  164. package/dist/server/dev-server.js +6 -4
  165. package/dist/server/headers.d.ts +6 -3
  166. package/dist/server/headers.js +9 -5
  167. package/dist/server/image-optimization.d.ts +5 -0
  168. package/dist/server/image-optimization.js +6 -1
  169. package/dist/server/isr-cache.d.ts +8 -2
  170. package/dist/server/isr-cache.js +30 -2
  171. package/dist/server/metadata-route-response.js +32 -15
  172. package/dist/server/middleware-matcher.js +19 -6
  173. package/dist/server/middleware-runtime.js +6 -2
  174. package/dist/server/multi-stage.d.ts +57 -12
  175. package/dist/server/multi-stage.js +13 -1
  176. package/dist/server/navigation-planner.js +1 -1
  177. package/dist/server/pages-api-route.js +28 -19
  178. package/dist/server/pages-media-type.d.ts +21 -1
  179. package/dist/server/pages-media-type.js +69 -5
  180. package/dist/server/pages-node-compat.d.ts +1 -1
  181. package/dist/server/pages-node-compat.js +54 -27
  182. package/dist/server/pages-page-data.js +2 -1
  183. package/dist/server/pages-page-handler.js +28 -26
  184. package/dist/server/pages-page-response.d.ts +9 -0
  185. package/dist/server/pages-page-response.js +18 -4
  186. package/dist/server/pages-request-pipeline.d.ts +8 -0
  187. package/dist/server/pages-request-pipeline.js +2 -2
  188. package/dist/server/pages-request-stage-entry.js +36 -14
  189. package/dist/server/pages-response-stage-entry.js +9 -3
  190. package/dist/server/pages-router-entry.js +3 -2
  191. package/dist/server/prod-server.d.ts +2 -2
  192. package/dist/server/prod-server.js +47 -9
  193. package/dist/server/request-error-log.d.ts +9 -0
  194. package/dist/server/request-error-log.js +13 -0
  195. package/dist/server/request-pipeline.d.ts +15 -4
  196. package/dist/server/request-pipeline.js +43 -15
  197. package/dist/server/rsc-completion-metadata.js +3 -0
  198. package/dist/server/shared-cache-identity.d.ts +23 -0
  199. package/dist/server/shared-cache-identity.js +36 -0
  200. package/dist/server/static-file-cache.d.ts +9 -0
  201. package/dist/server/static-file-cache.js +13 -2
  202. package/dist/server/worker-stages.d.ts +16 -3
  203. package/dist/server/worker-stages.js +23 -4
  204. package/dist/shims/cache-handler.js +2 -2
  205. package/dist/shims/cache-request-state.d.ts +23 -26
  206. package/dist/shims/cache-request-state.js +22 -57
  207. package/dist/shims/cache-runtime.d.ts +3 -1
  208. package/dist/shims/cache-runtime.js +94 -48
  209. package/dist/shims/cache.d.ts +16 -10
  210. package/dist/shims/cache.js +47 -36
  211. package/dist/shims/cacheability-classification.d.ts +2 -0
  212. package/dist/shims/cdn-cache.d.ts +22 -5
  213. package/dist/shims/client-hook-error.d.ts +2 -0
  214. package/dist/shims/client-hook-error.js +16 -1
  215. package/dist/shims/client-page-root.js +2 -2
  216. package/dist/shims/dynamic.js +9 -6
  217. package/dist/shims/error-boundary.js +2 -2
  218. package/dist/shims/fetch-cache-state.d.ts +5 -1
  219. package/dist/shims/fetch-cache-state.js +1 -3
  220. package/dist/shims/fetch-cache.d.ts +2 -1
  221. package/dist/shims/fetch-cache.js +39 -25
  222. package/dist/shims/form.js +2 -2
  223. package/dist/shims/headers.d.ts +10 -24
  224. package/dist/shims/headers.js +22 -70
  225. package/dist/shims/internal/cache-context-accessor.d.ts +1 -1
  226. package/dist/shims/internal/navigation-untracked.js +1 -1
  227. package/dist/shims/link.js +8 -11
  228. package/dist/shims/metadata.d.ts +23 -21
  229. package/dist/shims/metadata.js +62 -24
  230. package/dist/shims/navigation-server.js +1 -1
  231. package/dist/shims/navigation.d.ts +74 -7
  232. package/dist/shims/navigation.js +184 -31
  233. package/dist/shims/navigation.react-server.js +2 -2
  234. package/dist/shims/request-state-types.d.ts +3 -2
  235. package/dist/shims/slot.d.ts +16 -0
  236. package/dist/shims/slot.js +44 -9
  237. package/dist/shims/unified-request-context.d.ts +7 -1
  238. package/dist/shims/unified-request-context.js +3 -3
  239. package/dist/utils/cache-control-metadata.d.ts +5 -0
  240. package/dist/utils/cache-control-metadata.js +9 -1
  241. package/dist/utils/cache-life-profiles.d.ts +33 -0
  242. package/dist/utils/cache-life-profiles.js +111 -0
  243. package/dist/utils/middleware-request-headers.d.ts +14 -3
  244. package/dist/utils/middleware-request-headers.js +54 -7
  245. package/dist/utils/project.d.ts +2 -2
  246. package/dist/utils/project.js +3 -16
  247. package/dist/utils/regex.d.ts +5 -0
  248. package/dist/utils/regex.js +11 -1
  249. package/dist/utils/text-stream.d.ts +10 -5
  250. package/dist/utils/text-stream.js +6 -6
  251. package/package.json +2 -1
  252. package/dist/build/layout-classification-types.d.ts +0 -60
  253. package/dist/build/layout-classification-types.js +0 -1
  254. package/dist/build/layout-classification.d.ts +0 -62
  255. package/dist/build/layout-classification.js +0 -98
  256. package/dist/build/route-classification-injector.d.ts +0 -33
  257. package/dist/build/route-classification-injector.js +0 -59
  258. package/dist/build/route-classification-manifest.d.ts +0 -54
  259. package/dist/build/route-classification-manifest.js +0 -143
  260. package/dist/server/app-browser-client-reuse-manifest.d.ts +0 -11
  261. package/dist/server/app-browser-client-reuse-manifest.js +0 -101
  262. package/dist/server/app-layout-param-observation.d.ts +0 -42
  263. package/dist/server/app-layout-param-observation.js +0 -168
  264. package/dist/server/client-reuse-manifest.d.ts +0 -103
  265. package/dist/server/client-reuse-manifest.js +0 -209
  266. package/dist/server/skip-cache-proof.d.ts +0 -60
  267. package/dist/server/skip-cache-proof.js +0 -168
  268. package/dist/server/static-layout-client-reuse-proof.d.ts +0 -14
  269. package/dist/server/static-layout-client-reuse-proof.js +0 -33
  270. package/dist/utils/sorted-array.d.ts +0 -8
  271. 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 };
@@ -118,7 +118,7 @@ function cacheabilityRequestIdentity(request, trustedRepresentation) {
118
118
  representation: "pages-data",
119
119
  requestKey
120
120
  };
121
- if (!(request.headers.get("RSC") === "1" || url.pathname.endsWith(".rsc"))) return (request.headers.get("Accept")?.toLowerCase() ?? "").includes("text/html") ? {
121
+ if (!(request.headers.get("RSC") === "1")) return (request.headers.get("Accept")?.toLowerCase() ?? "").includes("text/html") ? {
122
122
  representation: "html",
123
123
  requestKey
124
124
  } : {
@@ -146,7 +146,6 @@ function normalizeCacheabilityRoutePathname(pathname) {
146
146
  }
147
147
  function cacheabilityRoutePathname(pathname, representation) {
148
148
  const normalized = new URL(pathname, "http://vinext.local").pathname;
149
- if (representation === "rsc-full" || representation === "rsc-loading-shell") return normalizeCacheabilityRoutePathname(normalized.endsWith(".rsc") ? normalized.slice(0, -4) : normalized);
150
149
  if (representation !== "pages-data") return normalizeCacheabilityRoutePathname(normalized);
151
150
  const marker = normalized.indexOf("/_next/data/");
152
151
  const restWithBuildId = marker === -1 ? "" : normalized.slice(marker + 12);
@@ -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,
@@ -41,7 +41,8 @@ export declare function isCrossSiteNoCorsRequest(secFetchSite: string | null | u
41
41
  * Validate a dev server request from a Node.js IncomingMessage.
42
42
  *
43
43
  * Returns null if the request is allowed, or a reason string if it should be blocked.
44
- * This is used by the Pages Router connect middleware.
44
+ * This is used by the vinext:dev-origin-check connect middleware and the Pages
45
+ * Router handler.
45
46
  */
46
47
  export declare function validateDevRequest(headers: {
47
48
  origin?: string;
@@ -74,7 +74,8 @@ function isCrossSiteNoCorsRequest(secFetchSite, secFetchMode) {
74
74
  * Validate a dev server request from a Node.js IncomingMessage.
75
75
  *
76
76
  * Returns null if the request is allowed, or a reason string if it should be blocked.
77
- * This is used by the Pages Router connect middleware.
77
+ * This is used by the vinext:dev-origin-check connect middleware and the Pages
78
+ * Router handler.
78
79
  */
79
80
  function validateDevRequest(headers, allowedDevOrigins) {
80
81
  if (isCrossSiteNoCorsRequest(headers["sec-fetch-site"], headers["sec-fetch-mode"])) return `cross-site no-cors request blocked`;