vinext 0.0.50 → 0.0.51

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 (309) hide show
  1. package/dist/build/google-fonts/fallback-metrics-data.js +14031 -0
  2. package/dist/build/google-fonts/fallback-metrics-data.js.map +1 -0
  3. package/dist/build/google-fonts/fallback-metrics.d.ts +13 -0
  4. package/dist/build/google-fonts/fallback-metrics.js +46 -0
  5. package/dist/build/google-fonts/fallback-metrics.js.map +1 -0
  6. package/dist/build/precompress.d.ts +13 -2
  7. package/dist/build/precompress.js +12 -3
  8. package/dist/build/precompress.js.map +1 -1
  9. package/dist/build/prerender.d.ts +1 -1
  10. package/dist/build/prerender.js +44 -14
  11. package/dist/build/prerender.js.map +1 -1
  12. package/dist/build/report.d.ts +5 -4
  13. package/dist/build/report.js +196 -348
  14. package/dist/build/report.js.map +1 -1
  15. package/dist/check.js +1 -0
  16. package/dist/check.js.map +1 -1
  17. package/dist/cli.js +60 -3
  18. package/dist/cli.js.map +1 -1
  19. package/dist/client/window-next.d.ts +3 -1
  20. package/dist/client/window-next.js.map +1 -1
  21. package/dist/config/dotenv.d.ts +11 -1
  22. package/dist/config/dotenv.js.map +1 -1
  23. package/dist/config/next-config.d.ts +87 -3
  24. package/dist/config/next-config.js +222 -6
  25. package/dist/config/next-config.js.map +1 -1
  26. package/dist/config/tsconfig-paths.d.ts +13 -0
  27. package/dist/config/tsconfig-paths.js +117 -0
  28. package/dist/config/tsconfig-paths.js.map +1 -0
  29. package/dist/deploy.js +3 -2
  30. package/dist/deploy.js.map +1 -1
  31. package/dist/entries/app-browser-entry.d.ts +2 -2
  32. package/dist/entries/app-browser-entry.js +26 -1
  33. package/dist/entries/app-browser-entry.js.map +1 -1
  34. package/dist/entries/app-rsc-entry.d.ts +19 -1
  35. package/dist/entries/app-rsc-entry.js +38 -12
  36. package/dist/entries/app-rsc-entry.js.map +1 -1
  37. package/dist/entries/app-rsc-manifest.d.ts +9 -0
  38. package/dist/entries/app-rsc-manifest.js +4 -1
  39. package/dist/entries/app-rsc-manifest.js.map +1 -1
  40. package/dist/entries/pages-client-entry.js +3 -5
  41. package/dist/entries/pages-client-entry.js.map +1 -1
  42. package/dist/entries/pages-server-entry.js +19 -1
  43. package/dist/entries/pages-server-entry.js.map +1 -1
  44. package/dist/index.js +130 -37
  45. package/dist/index.js.map +1 -1
  46. package/dist/plugins/client-reference-dedup.d.ts +15 -2
  47. package/dist/plugins/client-reference-dedup.js +138 -16
  48. package/dist/plugins/client-reference-dedup.js.map +1 -1
  49. package/dist/plugins/fonts.d.ts +2 -2
  50. package/dist/plugins/fonts.js +15 -6
  51. package/dist/plugins/fonts.js.map +1 -1
  52. package/dist/plugins/sass.d.ts +34 -0
  53. package/dist/plugins/sass.js +22 -0
  54. package/dist/plugins/sass.js.map +1 -0
  55. package/dist/routing/app-route-graph.d.ts +31 -2
  56. package/dist/routing/app-route-graph.js +82 -10
  57. package/dist/routing/app-route-graph.js.map +1 -1
  58. package/dist/routing/route-pattern.d.ts +56 -1
  59. package/dist/routing/route-pattern.js +60 -1
  60. package/dist/routing/route-pattern.js.map +1 -1
  61. package/dist/server/app-browser-action-result.d.ts +27 -2
  62. package/dist/server/app-browser-action-result.js +63 -2
  63. package/dist/server/app-browser-action-result.js.map +1 -1
  64. package/dist/server/app-browser-entry.js +262 -108
  65. package/dist/server/app-browser-entry.js.map +1 -1
  66. package/dist/server/app-browser-hydration.d.ts +13 -1
  67. package/dist/server/app-browser-hydration.js +9 -1
  68. package/dist/server/app-browser-hydration.js.map +1 -1
  69. package/dist/server/app-browser-navigation-controller.d.ts +14 -1
  70. package/dist/server/app-browser-navigation-controller.js +28 -9
  71. package/dist/server/app-browser-navigation-controller.js.map +1 -1
  72. package/dist/server/app-browser-popstate.d.ts +16 -0
  73. package/dist/server/app-browser-popstate.js +17 -0
  74. package/dist/server/app-browser-popstate.js.map +1 -0
  75. package/dist/server/app-browser-rsc-redirect.d.ts +28 -0
  76. package/dist/server/app-browser-rsc-redirect.js +37 -0
  77. package/dist/server/app-browser-rsc-redirect.js.map +1 -0
  78. package/dist/server/app-browser-state.d.ts +11 -7
  79. package/dist/server/app-browser-state.js +45 -27
  80. package/dist/server/app-browser-state.js.map +1 -1
  81. package/dist/server/app-browser-stream.d.ts +5 -4
  82. package/dist/server/app-browser-stream.js +5 -6
  83. package/dist/server/app-browser-stream.js.map +1 -1
  84. package/dist/server/app-browser-visible-commit.d.ts +5 -0
  85. package/dist/server/app-browser-visible-commit.js +38 -5
  86. package/dist/server/app-browser-visible-commit.js.map +1 -1
  87. package/dist/server/app-elements-wire.d.ts +38 -6
  88. package/dist/server/app-elements-wire.js +106 -6
  89. package/dist/server/app-elements-wire.js.map +1 -1
  90. package/dist/server/app-elements.d.ts +2 -2
  91. package/dist/server/app-elements.js +2 -2
  92. package/dist/server/app-elements.js.map +1 -1
  93. package/dist/server/app-fallback-renderer.d.ts +10 -1
  94. package/dist/server/app-fallback-renderer.js +37 -1
  95. package/dist/server/app-fallback-renderer.js.map +1 -1
  96. package/dist/server/app-history-state.d.ts +26 -0
  97. package/dist/server/app-history-state.js +53 -0
  98. package/dist/server/app-history-state.js.map +1 -0
  99. package/dist/server/app-page-boundary-render.d.ts +10 -1
  100. package/dist/server/app-page-boundary-render.js +13 -6
  101. package/dist/server/app-page-boundary-render.js.map +1 -1
  102. package/dist/server/app-page-boundary.js +3 -2
  103. package/dist/server/app-page-boundary.js.map +1 -1
  104. package/dist/server/app-page-cache.d.ts +13 -0
  105. package/dist/server/app-page-cache.js +25 -8
  106. package/dist/server/app-page-cache.js.map +1 -1
  107. package/dist/server/app-page-dispatch.d.ts +5 -0
  108. package/dist/server/app-page-dispatch.js +68 -11
  109. package/dist/server/app-page-dispatch.js.map +1 -1
  110. package/dist/server/app-page-element-builder.d.ts +7 -0
  111. package/dist/server/app-page-element-builder.js +32 -4
  112. package/dist/server/app-page-element-builder.js.map +1 -1
  113. package/dist/server/app-page-execution.js +2 -3
  114. package/dist/server/app-page-execution.js.map +1 -1
  115. package/dist/server/app-page-head.d.ts +7 -0
  116. package/dist/server/app-page-head.js +2 -1
  117. package/dist/server/app-page-head.js.map +1 -1
  118. package/dist/server/app-page-probe.d.ts +23 -1
  119. package/dist/server/app-page-probe.js +29 -1
  120. package/dist/server/app-page-probe.js.map +1 -1
  121. package/dist/server/app-page-render-observation.d.ts +35 -0
  122. package/dist/server/app-page-render-observation.js +68 -0
  123. package/dist/server/app-page-render-observation.js.map +1 -0
  124. package/dist/server/app-page-render.d.ts +5 -1
  125. package/dist/server/app-page-render.js +79 -3
  126. package/dist/server/app-page-render.js.map +1 -1
  127. package/dist/server/app-page-request.d.ts +1 -0
  128. package/dist/server/app-page-request.js.map +1 -1
  129. package/dist/server/app-page-response.js +3 -2
  130. package/dist/server/app-page-response.js.map +1 -1
  131. package/dist/server/app-page-route-wiring.d.ts +3 -1
  132. package/dist/server/app-page-route-wiring.js +42 -14
  133. package/dist/server/app-page-route-wiring.js.map +1 -1
  134. package/dist/server/app-page-stream.d.ts +2 -0
  135. package/dist/server/app-page-stream.js +1 -0
  136. package/dist/server/app-page-stream.js.map +1 -1
  137. package/dist/server/app-router-entry.js +1 -13
  138. package/dist/server/app-router-entry.js.map +1 -1
  139. package/dist/server/app-rsc-cache-busting.d.ts +19 -1
  140. package/dist/server/app-rsc-cache-busting.js +36 -1
  141. package/dist/server/app-rsc-cache-busting.js.map +1 -1
  142. package/dist/server/app-rsc-embedded-chunks.d.ts +9 -0
  143. package/dist/server/app-rsc-embedded-chunks.js +34 -0
  144. package/dist/server/app-rsc-embedded-chunks.js.map +1 -0
  145. package/dist/server/app-rsc-errors.d.ts +4 -1
  146. package/dist/server/app-rsc-errors.js +1 -1
  147. package/dist/server/app-rsc-errors.js.map +1 -1
  148. package/dist/server/app-rsc-handler.d.ts +12 -4
  149. package/dist/server/app-rsc-handler.js +6 -1
  150. package/dist/server/app-rsc-handler.js.map +1 -1
  151. package/dist/server/app-rsc-route-matching.d.ts +23 -0
  152. package/dist/server/app-rsc-route-matching.js +45 -23
  153. package/dist/server/app-rsc-route-matching.js.map +1 -1
  154. package/dist/server/app-server-action-execution.d.ts +35 -3
  155. package/dist/server/app-server-action-execution.js +87 -33
  156. package/dist/server/app-server-action-execution.js.map +1 -1
  157. package/dist/server/app-ssr-entry.d.ts +1 -0
  158. package/dist/server/app-ssr-entry.js +37 -13
  159. package/dist/server/app-ssr-entry.js.map +1 -1
  160. package/dist/server/app-ssr-error-meta.d.ts +14 -0
  161. package/dist/server/app-ssr-error-meta.js +50 -0
  162. package/dist/server/app-ssr-error-meta.js.map +1 -0
  163. package/dist/server/app-ssr-stream.d.ts +1 -1
  164. package/dist/server/app-ssr-stream.js +9 -12
  165. package/dist/server/app-ssr-stream.js.map +1 -1
  166. package/dist/server/artifact-compatibility.d.ts +12 -2
  167. package/dist/server/artifact-compatibility.js +12 -8
  168. package/dist/server/artifact-compatibility.js.map +1 -1
  169. package/dist/server/cache-proof.d.ts +124 -5
  170. package/dist/server/cache-proof.js +416 -18
  171. package/dist/server/cache-proof.js.map +1 -1
  172. package/dist/server/dev-lockfile.d.ts +110 -0
  173. package/dist/server/dev-lockfile.js +180 -0
  174. package/dist/server/dev-lockfile.js.map +1 -0
  175. package/dist/server/dev-server.js +15 -5
  176. package/dist/server/dev-server.js.map +1 -1
  177. package/dist/server/file-based-metadata.d.ts +13 -0
  178. package/dist/server/file-based-metadata.js +49 -2
  179. package/dist/server/file-based-metadata.js.map +1 -1
  180. package/dist/server/headers.d.ts +3 -1
  181. package/dist/server/headers.js +5 -2
  182. package/dist/server/headers.js.map +1 -1
  183. package/dist/server/html.js +1 -1
  184. package/dist/server/html.js.map +1 -1
  185. package/dist/server/http-error-responses.d.ts +10 -0
  186. package/dist/server/http-error-responses.js +11 -1
  187. package/dist/server/http-error-responses.js.map +1 -1
  188. package/dist/server/isr-cache.d.ts +2 -1
  189. package/dist/server/isr-cache.js +4 -2
  190. package/dist/server/isr-cache.js.map +1 -1
  191. package/dist/server/metadata-route-response.js +22 -5
  192. package/dist/server/metadata-route-response.js.map +1 -1
  193. package/dist/server/metadata-routes.js +27 -8
  194. package/dist/server/metadata-routes.js.map +1 -1
  195. package/dist/server/middleware-runtime.js +1 -0
  196. package/dist/server/middleware-runtime.js.map +1 -1
  197. package/dist/server/middleware.d.ts +12 -0
  198. package/dist/server/middleware.js +12 -0
  199. package/dist/server/middleware.js.map +1 -1
  200. package/dist/server/navigation-planner.d.ts +19 -5
  201. package/dist/server/navigation-planner.js +278 -17
  202. package/dist/server/navigation-planner.js.map +1 -1
  203. package/dist/server/navigation-trace.d.ts +8 -1
  204. package/dist/server/navigation-trace.js +7 -0
  205. package/dist/server/navigation-trace.js.map +1 -1
  206. package/dist/server/normalize-path.d.ts +2 -1
  207. package/dist/server/normalize-path.js +4 -1
  208. package/dist/server/normalize-path.js.map +1 -1
  209. package/dist/server/pages-api-route.js +1 -0
  210. package/dist/server/pages-api-route.js.map +1 -1
  211. package/dist/server/pages-page-data.d.ts +3 -2
  212. package/dist/server/pages-page-data.js +22 -3
  213. package/dist/server/pages-page-data.js.map +1 -1
  214. package/dist/server/pages-page-response.js +1 -1
  215. package/dist/server/prod-server.d.ts +28 -1
  216. package/dist/server/prod-server.js +62 -9
  217. package/dist/server/prod-server.js.map +1 -1
  218. package/dist/server/server-action-not-found.d.ts +16 -3
  219. package/dist/server/server-action-not-found.js +19 -1
  220. package/dist/server/server-action-not-found.js.map +1 -1
  221. package/dist/server/server-globals.d.ts +5 -0
  222. package/dist/server/server-globals.js +37 -0
  223. package/dist/server/server-globals.js.map +1 -0
  224. package/dist/server/static-file-cache.js +1 -1
  225. package/dist/server/static-file-cache.js.map +1 -1
  226. package/dist/shims/cache-runtime.d.ts +19 -2
  227. package/dist/shims/cache-runtime.js +67 -11
  228. package/dist/shims/cache-runtime.js.map +1 -1
  229. package/dist/shims/cache.d.ts +5 -18
  230. package/dist/shims/cache.js +2 -0
  231. package/dist/shims/cache.js.map +1 -1
  232. package/dist/shims/error-boundary.js +6 -8
  233. package/dist/shims/error-boundary.js.map +1 -1
  234. package/dist/shims/error.d.ts +18 -1
  235. package/dist/shims/error.js +56 -1
  236. package/dist/shims/error.js.map +1 -1
  237. package/dist/shims/fetch-cache.d.ts +4 -1
  238. package/dist/shims/fetch-cache.js +40 -5
  239. package/dist/shims/fetch-cache.js.map +1 -1
  240. package/dist/shims/font-google-base.d.ts +22 -8
  241. package/dist/shims/font-google-base.js +41 -71
  242. package/dist/shims/font-google-base.js.map +1 -1
  243. package/dist/shims/font-local.d.ts +3 -20
  244. package/dist/shims/font-local.js +23 -75
  245. package/dist/shims/font-local.js.map +1 -1
  246. package/dist/shims/font-utils.d.ts +51 -0
  247. package/dist/shims/font-utils.js +97 -0
  248. package/dist/shims/font-utils.js.map +1 -0
  249. package/dist/shims/hash-scroll.d.ts +7 -0
  250. package/dist/shims/hash-scroll.js +30 -0
  251. package/dist/shims/hash-scroll.js.map +1 -0
  252. package/dist/shims/headers.d.ts +8 -11
  253. package/dist/shims/headers.js +22 -2
  254. package/dist/shims/headers.js.map +1 -1
  255. package/dist/shims/image.d.ts +1 -0
  256. package/dist/shims/image.js +144 -78
  257. package/dist/shims/image.js.map +1 -1
  258. package/dist/shims/internal/app-router-context.d.ts +6 -6
  259. package/dist/shims/internal/app-router-context.js +17 -6
  260. package/dist/shims/internal/app-router-context.js.map +1 -1
  261. package/dist/shims/link-prefetch.d.ts +9 -1
  262. package/dist/shims/link-prefetch.js +11 -6
  263. package/dist/shims/link-prefetch.js.map +1 -1
  264. package/dist/shims/link.d.ts +12 -2
  265. package/dist/shims/link.js +78 -32
  266. package/dist/shims/link.js.map +1 -1
  267. package/dist/shims/metadata.d.ts +16 -30
  268. package/dist/shims/metadata.js +87 -28
  269. package/dist/shims/metadata.js.map +1 -1
  270. package/dist/shims/navigation.d.ts +158 -17
  271. package/dist/shims/navigation.js +324 -74
  272. package/dist/shims/navigation.js.map +1 -1
  273. package/dist/shims/navigation.react-server.d.ts +3 -2
  274. package/dist/shims/navigation.react-server.js +5 -2
  275. package/dist/shims/navigation.react-server.js.map +1 -1
  276. package/dist/shims/pages-router-runtime.d.ts +7 -0
  277. package/dist/shims/pages-router-runtime.js +16 -0
  278. package/dist/shims/pages-router-runtime.js.map +1 -0
  279. package/dist/shims/router.d.ts +32 -6
  280. package/dist/shims/router.js +197 -242
  281. package/dist/shims/router.js.map +1 -1
  282. package/dist/shims/script.js +110 -32
  283. package/dist/shims/script.js.map +1 -1
  284. package/dist/shims/server.js +2 -1
  285. package/dist/shims/server.js.map +1 -1
  286. package/dist/shims/slot.d.ts +1 -0
  287. package/dist/shims/slot.js +41 -1
  288. package/dist/shims/slot.js.map +1 -1
  289. package/dist/shims/unified-request-context.js +2 -0
  290. package/dist/shims/unified-request-context.js.map +1 -1
  291. package/dist/shims/unrecognized-action-error.d.ts +35 -0
  292. package/dist/shims/unrecognized-action-error.js +41 -0
  293. package/dist/shims/unrecognized-action-error.js.map +1 -0
  294. package/dist/shims/url-utils.d.ts +21 -1
  295. package/dist/shims/url-utils.js +67 -3
  296. package/dist/shims/url-utils.js.map +1 -1
  297. package/dist/utils/asset-prefix.d.ts +69 -0
  298. package/dist/utils/asset-prefix.js +91 -0
  299. package/dist/utils/asset-prefix.js.map +1 -0
  300. package/dist/utils/base-path.d.ts +7 -1
  301. package/dist/utils/base-path.js +10 -1
  302. package/dist/utils/base-path.js.map +1 -1
  303. package/dist/utils/navigation-signal.d.ts +1 -2
  304. package/dist/utils/navigation-signal.js +1 -1
  305. package/dist/utils/navigation-signal.js.map +1 -1
  306. package/dist/utils/sorted-array.d.ts +9 -0
  307. package/dist/utils/sorted-array.js +22 -0
  308. package/dist/utils/sorted-array.js.map +1 -0
  309. package/package.json +3 -3
@@ -0,0 +1,50 @@
1
+ import { addBasePathToPathname } from "../utils/base-path.js";
2
+ import { escapeHtmlAttr } from "./html.js";
3
+ import { getNextErrorDigest, parseNextHttpErrorDigest, parseNextRedirectDigest } from "./next-error-digest.js";
4
+ //#region src/server/app-ssr-error-meta.ts
5
+ const PERMANENT_REDIRECT_STATUS = 308;
6
+ function prefixRedirectLocation(location, basePath) {
7
+ if (!basePath || !location.startsWith("/")) return location;
8
+ const hashIndex = location.indexOf("#");
9
+ const queryIndex = location.indexOf("?");
10
+ const pathnameEnd = queryIndex === -1 ? hashIndex === -1 ? location.length : hashIndex : hashIndex === -1 ? queryIndex : Math.min(queryIndex, hashIndex);
11
+ return addBasePathToPathname(location.slice(0, pathnameEnd), basePath) + location.slice(pathnameEnd);
12
+ }
13
+ function renderSsrErrorMetaTag(error, options) {
14
+ const digest = getNextErrorDigest(error);
15
+ if (!digest) return "";
16
+ if (parseNextHttpErrorDigest(digest)) {
17
+ let html = "<meta name=\"robots\" content=\"noindex\" />";
18
+ if ((options.nodeEnv ?? process.env.NODE_ENV) === "development") html += "<meta name=\"next-error\" content=\"not-found\" />";
19
+ return html;
20
+ }
21
+ const redirect = parseNextRedirectDigest(digest);
22
+ if (!redirect) return "";
23
+ const delay = redirect.status === PERMANENT_REDIRECT_STATUS ? 0 : 1;
24
+ const location = prefixRedirectLocation(redirect.url, options.basePath);
25
+ return "<meta id=\"__next-page-redirect\" http-equiv=\"refresh\" content=\"" + delay + ";url=" + escapeHtmlAttr(location) + "\" />";
26
+ }
27
+ function renderSsrErrorMetaTags(errors, options = {}) {
28
+ let html = "";
29
+ for (const error of errors) html += renderSsrErrorMetaTag(error, options);
30
+ return html;
31
+ }
32
+ function createSsrErrorMetaRenderer(options = {}) {
33
+ const capturedErrors = [];
34
+ let flushedUntil = 0;
35
+ return {
36
+ capture(error) {
37
+ capturedErrors.push(error);
38
+ },
39
+ flush() {
40
+ if (flushedUntil >= capturedErrors.length) return "";
41
+ const html = renderSsrErrorMetaTags(capturedErrors.slice(flushedUntil), options);
42
+ flushedUntil = capturedErrors.length;
43
+ return html;
44
+ }
45
+ };
46
+ }
47
+ //#endregion
48
+ export { createSsrErrorMetaRenderer, renderSsrErrorMetaTags };
49
+
50
+ //# sourceMappingURL=app-ssr-error-meta.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-ssr-error-meta.js","names":[],"sources":["../../src/server/app-ssr-error-meta.ts"],"sourcesContent":["import { addBasePathToPathname } from \"../utils/base-path.js\";\nimport { escapeHtmlAttr } from \"./html.js\";\nimport {\n getNextErrorDigest,\n parseNextHttpErrorDigest,\n parseNextRedirectDigest,\n} from \"./next-error-digest.js\";\n\ntype SsrErrorMetaRenderOptions = {\n basePath?: string;\n nodeEnv?: string;\n};\n\ntype SsrErrorMetaRenderer = {\n capture: (error: unknown) => void;\n flush: () => string;\n};\n\nconst PERMANENT_REDIRECT_STATUS = 308;\n\nfunction prefixRedirectLocation(location: string, basePath?: string): string {\n if (!basePath || !location.startsWith(\"/\")) {\n return location;\n }\n\n const hashIndex = location.indexOf(\"#\");\n const queryIndex = location.indexOf(\"?\");\n const pathnameEnd =\n queryIndex === -1\n ? hashIndex === -1\n ? location.length\n : hashIndex\n : hashIndex === -1\n ? queryIndex\n : Math.min(queryIndex, hashIndex);\n const pathname = location.slice(0, pathnameEnd);\n\n return addBasePathToPathname(pathname, basePath) + location.slice(pathnameEnd);\n}\n\nfunction renderSsrErrorMetaTag(error: unknown, options: SsrErrorMetaRenderOptions): string {\n const digest = getNextErrorDigest(error);\n if (!digest) return \"\";\n\n const httpError = parseNextHttpErrorDigest(digest);\n if (httpError) {\n let html = '<meta name=\"robots\" content=\"noindex\" />';\n if ((options.nodeEnv ?? process.env.NODE_ENV) === \"development\") {\n html += '<meta name=\"next-error\" content=\"not-found\" />';\n }\n return html;\n }\n\n const redirect = parseNextRedirectDigest(digest);\n if (!redirect) return \"\";\n\n const delay = redirect.status === PERMANENT_REDIRECT_STATUS ? 0 : 1;\n const location = prefixRedirectLocation(redirect.url, options.basePath);\n return (\n '<meta id=\"__next-page-redirect\" http-equiv=\"refresh\" content=\"' +\n delay +\n \";url=\" +\n escapeHtmlAttr(location) +\n '\" />'\n );\n}\n\nexport function renderSsrErrorMetaTags(\n errors: readonly unknown[],\n options: SsrErrorMetaRenderOptions = {},\n): string {\n let html = \"\";\n\n for (const error of errors) {\n html += renderSsrErrorMetaTag(error, options);\n }\n\n return html;\n}\n\nexport function createSsrErrorMetaRenderer(\n options: SsrErrorMetaRenderOptions = {},\n): SsrErrorMetaRenderer {\n const capturedErrors: unknown[] = [];\n let flushedUntil = 0;\n\n return {\n capture(error) {\n capturedErrors.push(error);\n },\n flush() {\n if (flushedUntil >= capturedErrors.length) return \"\";\n\n const html = renderSsrErrorMetaTags(capturedErrors.slice(flushedUntil), options);\n flushedUntil = capturedErrors.length;\n return html;\n },\n };\n}\n"],"mappings":";;;;AAkBA,MAAM,4BAA4B;AAElC,SAAS,uBAAuB,UAAkB,UAA2B;CAC3E,IAAI,CAAC,YAAY,CAAC,SAAS,WAAW,IAAI,EACxC,OAAO;CAGT,MAAM,YAAY,SAAS,QAAQ,IAAI;CACvC,MAAM,aAAa,SAAS,QAAQ,IAAI;CACxC,MAAM,cACJ,eAAe,KACX,cAAc,KACZ,SAAS,SACT,YACF,cAAc,KACZ,aACA,KAAK,IAAI,YAAY,UAAU;CAGvC,OAAO,sBAFU,SAAS,MAAM,GAAG,YAEE,EAAE,SAAS,GAAG,SAAS,MAAM,YAAY;;AAGhF,SAAS,sBAAsB,OAAgB,SAA4C;CACzF,MAAM,SAAS,mBAAmB,MAAM;CACxC,IAAI,CAAC,QAAQ,OAAO;CAGpB,IADkB,yBAAyB,OAC9B,EAAE;EACb,IAAI,OAAO;EACX,KAAK,QAAQ,WAAW,QAAQ,IAAI,cAAc,eAChD,QAAQ;EAEV,OAAO;;CAGT,MAAM,WAAW,wBAAwB,OAAO;CAChD,IAAI,CAAC,UAAU,OAAO;CAEtB,MAAM,QAAQ,SAAS,WAAW,4BAA4B,IAAI;CAClE,MAAM,WAAW,uBAAuB,SAAS,KAAK,QAAQ,SAAS;CACvE,OACE,wEACA,QACA,UACA,eAAe,SAAS,GACxB;;AAIJ,SAAgB,uBACd,QACA,UAAqC,EAAE,EAC/B;CACR,IAAI,OAAO;CAEX,KAAK,MAAM,SAAS,QAClB,QAAQ,sBAAsB,OAAO,QAAQ;CAG/C,OAAO;;AAGT,SAAgB,2BACd,UAAqC,EAAE,EACjB;CACtB,MAAM,iBAA4B,EAAE;CACpC,IAAI,eAAe;CAEnB,OAAO;EACL,QAAQ,OAAO;GACb,eAAe,KAAK,MAAM;;EAE5B,QAAQ;GACN,IAAI,gBAAgB,eAAe,QAAQ,OAAO;GAElD,MAAM,OAAO,uBAAuB,eAAe,MAAM,aAAa,EAAE,QAAQ;GAChF,eAAe,eAAe;GAC9B,OAAO;;EAEV"}
@@ -13,7 +13,7 @@ type HtmlInsertion = string | (() => string);
13
13
  declare function fixFlightHints(text: string): string;
14
14
  /**
15
15
  * Create a helper that progressively embeds RSC chunks as inline <script> tags.
16
- * The browser entry turns the embedded text chunks back into Uint8Array data.
16
+ * The browser entry turns the embedded chunks back into Uint8Array data.
17
17
  */
18
18
  declare function createRscEmbedTransform(embedStream: ReadableStream<Uint8Array>, scriptNonce?: string): RscEmbedTransform;
19
19
  /**
@@ -1,4 +1,5 @@
1
1
  import { createInlineScriptTag, safeJsonStringify } from "./html.js";
2
+ import { bytesToBase64, concatUint8Arrays } from "./app-rsc-embedded-chunks.js";
2
3
  //#region src/server/app-ssr-stream.ts
3
4
  /**
4
5
  * Fix invalid preload "as" values in RSC Flight hint lines before they reach
@@ -10,11 +11,10 @@ function fixFlightHints(text) {
10
11
  }
11
12
  /**
12
13
  * Create a helper that progressively embeds RSC chunks as inline <script> tags.
13
- * The browser entry turns the embedded text chunks back into Uint8Array data.
14
+ * The browser entry turns the embedded chunks back into Uint8Array data.
14
15
  */
15
16
  function createRscEmbedTransform(embedStream, scriptNonce) {
16
17
  const reader = embedStream.getReader();
17
- const decoder = new TextDecoder();
18
18
  let pendingChunks = [];
19
19
  const rawChunks = [];
20
20
  let reading = false;
@@ -26,8 +26,12 @@ function createRscEmbedTransform(embedStream, scriptNonce) {
26
26
  const result = await reader.read();
27
27
  if (result.done) break;
28
28
  rawChunks.push(result.value);
29
- const text = decoder.decode(result.value, { stream: true });
30
- pendingChunks.push(fixFlightHints(text));
29
+ try {
30
+ const text = new TextDecoder("utf-8", { fatal: true }).decode(result.value);
31
+ pendingChunks.push(fixFlightHints(text));
32
+ } catch {
33
+ pendingChunks.push([3, bytesToBase64(result.value)]);
34
+ }
31
35
  }
32
36
  } catch (error) {
33
37
  if (process.env.NODE_ENV !== "production") console.warn("[vinext] RSC embed stream read error:", error);
@@ -54,14 +58,7 @@ function createRscEmbedTransform(embedStream, scriptNonce) {
54
58
  },
55
59
  async getRawBuffer() {
56
60
  await pumpPromise;
57
- let totalLength = 0;
58
- for (const chunk of rawChunks) totalLength += chunk.byteLength;
59
- const buffer = new Uint8Array(totalLength);
60
- let offset = 0;
61
- for (const chunk of rawChunks) {
62
- buffer.set(chunk, offset);
63
- offset += chunk.byteLength;
64
- }
61
+ const buffer = concatUint8Arrays(rawChunks);
65
62
  rawChunks.length = 0;
66
63
  return buffer.buffer;
67
64
  }
@@ -1 +1 @@
1
- {"version":3,"file":"app-ssr-stream.js","names":[],"sources":["../../src/server/app-ssr-stream.ts"],"sourcesContent":["import { createInlineScriptTag, safeJsonStringify } from \"./html.js\";\n\ntype RscEmbedTransform = {\n flush(): string;\n finalize(): Promise<string>;\n /** Resolves when all raw bytes from the embed stream have been read. */\n getRawBuffer(): Promise<ArrayBuffer>;\n};\n\ntype HtmlInsertion = string | (() => string);\n\n/**\n * Fix invalid preload \"as\" values in RSC Flight hint lines before they reach\n * the client. React Flight emits HL hints with as=\"stylesheet\" for CSS, but\n * the HTML spec requires as=\"style\" for <link rel=\"preload\">.\n */\nexport function fixFlightHints(text: string): string {\n return text.replace(/(\\d*:HL\\[.*?),\"stylesheet\"(\\]|,)/g, '$1,\"style\"$2');\n}\n\n/**\n * Create a helper that progressively embeds RSC chunks as inline <script> tags.\n * The browser entry turns the embedded text chunks back into Uint8Array data.\n */\nexport function createRscEmbedTransform(\n embedStream: ReadableStream<Uint8Array>,\n scriptNonce?: string,\n): RscEmbedTransform {\n const reader = embedStream.getReader();\n const decoder = new TextDecoder();\n let pendingChunks: string[] = [];\n const rawChunks: Uint8Array[] = [];\n let reading = false;\n\n async function pumpReader(): Promise<void> {\n if (reading) return;\n reading = true;\n try {\n while (true) {\n const result = await reader.read();\n if (result.done) break;\n // Accumulate raw bytes BEFORE fixFlightHints so the cache stores\n // unmodified RSC data. The embed script path below applies fixes.\n rawChunks.push(result.value);\n const text = decoder.decode(result.value, { stream: true });\n // The RSC entry already fixes HL hints at the source. Keep this second\n // pass as defense in depth for any embed stream that bypasses that\n // wrapper; the rewrite is idempotent, so double-application is safe.\n pendingChunks.push(fixFlightHints(text));\n }\n } catch (error) {\n if (process.env.NODE_ENV !== \"production\") {\n console.warn(\"[vinext] RSC embed stream read error:\", error);\n }\n throw error;\n } finally {\n reading = false;\n }\n }\n\n const pumpPromise = pumpReader();\n\n return {\n flush(): string {\n if (pendingChunks.length === 0) return \"\";\n\n const chunks = pendingChunks;\n pendingChunks = [];\n\n let scripts = \"\";\n for (const chunk of chunks) {\n scripts += createInlineScriptTag(\n \"self.__VINEXT_RSC_CHUNKS__=self.__VINEXT_RSC_CHUNKS__||[];self.__VINEXT_RSC_CHUNKS__.push(\" +\n safeJsonStringify(chunk) +\n \")\",\n scriptNonce,\n );\n }\n return scripts;\n },\n\n async finalize(): Promise<string> {\n await pumpPromise;\n let scripts = this.flush();\n scripts += createInlineScriptTag(\"self.__VINEXT_RSC_DONE__=true\", scriptNonce);\n return scripts;\n },\n\n async getRawBuffer(): Promise<ArrayBuffer> {\n await pumpPromise;\n let totalLength = 0;\n for (const chunk of rawChunks) {\n totalLength += chunk.byteLength;\n }\n const buffer = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of rawChunks) {\n buffer.set(chunk, offset);\n offset += chunk.byteLength;\n }\n rawChunks.length = 0;\n return buffer.buffer;\n },\n };\n}\n\n/**\n * Fix invalid preload \"as\" values in server-rendered HTML.\n * React Fizz emits <link rel=\"preload\" as=\"stylesheet\"> for CSS, but the\n * HTML spec requires as=\"style\" for <link rel=\"preload\">.\n */\nexport function fixPreloadAs(html: string): string {\n return html.replace(/<link(?=[^>]*\\srel=\"preload\")[^>]*>/g, (tag) =>\n tag.replace(' as=\"stylesheet\"', ' as=\"style\"'),\n );\n}\n\n/**\n * Create the tick-buffered HTML transform that injects RSC scripts between\n * React Fizz flush cycles without corrupting split HTML chunks.\n */\nexport function createTickBufferedTransform(\n rscEmbed: RscEmbedTransform,\n injectHTML: HtmlInsertion = \"\",\n): TransformStream<Uint8Array, Uint8Array> {\n const decoder = new TextDecoder();\n const encoder = new TextEncoder();\n const insertsPerFlush = typeof injectHTML === \"function\";\n let injected = false;\n let buffered: string[] = [];\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n const readInsertion = (): string =>\n typeof injectHTML === \"function\" ? injectHTML() : injectHTML;\n const emitInsertion = (controller: TransformStreamDefaultController<Uint8Array>): void => {\n const insertion = readInsertion();\n if (insertion) {\n controller.enqueue(encoder.encode(insertion));\n }\n };\n\n const flushBuffered = (controller: TransformStreamDefaultController<Uint8Array>): void => {\n if (buffered.length === 0) return;\n\n if (injected && insertsPerFlush) {\n // Emit newly collected server-inserted HTML before the next Fizz HTML\n // batch so CSS-in-JS styles precede the elements they style.\n emitInsertion(controller);\n }\n\n for (const chunk of buffered) {\n if (!injected) {\n const headEnd = chunk.indexOf(\"</head>\");\n if (headEnd !== -1) {\n const before = chunk.slice(0, headEnd);\n const after = chunk.slice(headEnd);\n controller.enqueue(encoder.encode(before + readInsertion() + after));\n injected = true;\n continue;\n }\n }\n controller.enqueue(encoder.encode(chunk));\n }\n buffered = [];\n };\n\n return new TransformStream<Uint8Array, Uint8Array>({\n transform(chunk, controller) {\n buffered.push(fixPreloadAs(decoder.decode(chunk, { stream: true })));\n\n if (timeoutId !== null) return;\n\n timeoutId = setTimeout(() => {\n try {\n flushBuffered(controller);\n\n const rscScripts = rscEmbed.flush();\n if (rscScripts) {\n controller.enqueue(encoder.encode(rscScripts));\n }\n } catch {\n // Stream was cancelled between when the timeout was registered and\n // when it fired (e.g. client disconnected, health-check cancelled\n // the response body). Ignore — the stream is already closed.\n }\n\n timeoutId = null;\n }, 0);\n },\n\n async flush(controller) {\n if (timeoutId !== null) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n\n flushBuffered(controller);\n\n if (!injected) {\n emitInsertion(controller);\n injected = true;\n } else if (insertsPerFlush) {\n emitInsertion(controller);\n }\n\n const finalScripts = await rscEmbed.finalize();\n if (finalScripts) {\n controller.enqueue(encoder.encode(finalScripts));\n }\n },\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"app-ssr-stream.js","names":[],"sources":["../../src/server/app-ssr-stream.ts"],"sourcesContent":["import { createInlineScriptTag, safeJsonStringify } from \"./html.js\";\nimport {\n bytesToBase64,\n concatUint8Arrays,\n RSC_EMBEDDED_BINARY_CHUNK,\n type RscEmbeddedChunk,\n} from \"./app-rsc-embedded-chunks.js\";\n\ntype RscEmbedTransform = {\n flush(): string;\n finalize(): Promise<string>;\n /** Resolves when all raw bytes from the embed stream have been read. */\n getRawBuffer(): Promise<ArrayBuffer>;\n};\n\ntype HtmlInsertion = string | (() => string);\n\n/**\n * Fix invalid preload \"as\" values in RSC Flight hint lines before they reach\n * the client. React Flight emits HL hints with as=\"stylesheet\" for CSS, but\n * the HTML spec requires as=\"style\" for <link rel=\"preload\">.\n */\nexport function fixFlightHints(text: string): string {\n return text.replace(/(\\d*:HL\\[.*?),\"stylesheet\"(\\]|,)/g, '$1,\"style\"$2');\n}\n\n/**\n * Create a helper that progressively embeds RSC chunks as inline <script> tags.\n * The browser entry turns the embedded chunks back into Uint8Array data.\n */\nexport function createRscEmbedTransform(\n embedStream: ReadableStream<Uint8Array>,\n scriptNonce?: string,\n): RscEmbedTransform {\n const reader = embedStream.getReader();\n let pendingChunks: RscEmbeddedChunk[] = [];\n const rawChunks: Uint8Array[] = [];\n let reading = false;\n\n async function pumpReader(): Promise<void> {\n if (reading) return;\n reading = true;\n try {\n while (true) {\n const result = await reader.read();\n if (result.done) break;\n // Accumulate raw bytes BEFORE fixFlightHints so the cache stores\n // unmodified RSC data. The embed script path below applies fixes.\n rawChunks.push(result.value);\n try {\n const decoder = new TextDecoder(\"utf-8\", { fatal: true });\n const text = decoder.decode(result.value);\n // The RSC entry already fixes HL hints at the source. Keep this second\n // pass as defense in depth for any embed stream that bypasses that\n // wrapper; the rewrite is idempotent, so double-application is safe.\n pendingChunks.push(fixFlightHints(text));\n } catch {\n pendingChunks.push([RSC_EMBEDDED_BINARY_CHUNK, bytesToBase64(result.value)]);\n }\n }\n } catch (error) {\n if (process.env.NODE_ENV !== \"production\") {\n console.warn(\"[vinext] RSC embed stream read error:\", error);\n }\n throw error;\n } finally {\n reading = false;\n }\n }\n\n const pumpPromise = pumpReader();\n\n return {\n flush(): string {\n if (pendingChunks.length === 0) return \"\";\n\n const chunks = pendingChunks;\n pendingChunks = [];\n\n let scripts = \"\";\n for (const chunk of chunks) {\n scripts += createInlineScriptTag(\n \"self.__VINEXT_RSC_CHUNKS__=self.__VINEXT_RSC_CHUNKS__||[];self.__VINEXT_RSC_CHUNKS__.push(\" +\n safeJsonStringify(chunk) +\n \")\",\n scriptNonce,\n );\n }\n return scripts;\n },\n\n async finalize(): Promise<string> {\n await pumpPromise;\n let scripts = this.flush();\n scripts += createInlineScriptTag(\"self.__VINEXT_RSC_DONE__=true\", scriptNonce);\n return scripts;\n },\n\n async getRawBuffer(): Promise<ArrayBuffer> {\n await pumpPromise;\n const buffer = concatUint8Arrays(rawChunks);\n rawChunks.length = 0;\n return buffer.buffer;\n },\n };\n}\n\n/**\n * Fix invalid preload \"as\" values in server-rendered HTML.\n * React Fizz emits <link rel=\"preload\" as=\"stylesheet\"> for CSS, but the\n * HTML spec requires as=\"style\" for <link rel=\"preload\">.\n */\nexport function fixPreloadAs(html: string): string {\n return html.replace(/<link(?=[^>]*\\srel=\"preload\")[^>]*>/g, (tag) =>\n tag.replace(' as=\"stylesheet\"', ' as=\"style\"'),\n );\n}\n\n/**\n * Create the tick-buffered HTML transform that injects RSC scripts between\n * React Fizz flush cycles without corrupting split HTML chunks.\n */\nexport function createTickBufferedTransform(\n rscEmbed: RscEmbedTransform,\n injectHTML: HtmlInsertion = \"\",\n): TransformStream<Uint8Array, Uint8Array> {\n const decoder = new TextDecoder();\n const encoder = new TextEncoder();\n const insertsPerFlush = typeof injectHTML === \"function\";\n let injected = false;\n let buffered: string[] = [];\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n const readInsertion = (): string =>\n typeof injectHTML === \"function\" ? injectHTML() : injectHTML;\n const emitInsertion = (controller: TransformStreamDefaultController<Uint8Array>): void => {\n const insertion = readInsertion();\n if (insertion) {\n controller.enqueue(encoder.encode(insertion));\n }\n };\n\n const flushBuffered = (controller: TransformStreamDefaultController<Uint8Array>): void => {\n if (buffered.length === 0) return;\n\n if (injected && insertsPerFlush) {\n // Emit newly collected server-inserted HTML before the next Fizz HTML\n // batch so CSS-in-JS styles precede the elements they style.\n emitInsertion(controller);\n }\n\n for (const chunk of buffered) {\n if (!injected) {\n const headEnd = chunk.indexOf(\"</head>\");\n if (headEnd !== -1) {\n const before = chunk.slice(0, headEnd);\n const after = chunk.slice(headEnd);\n controller.enqueue(encoder.encode(before + readInsertion() + after));\n injected = true;\n continue;\n }\n }\n controller.enqueue(encoder.encode(chunk));\n }\n buffered = [];\n };\n\n return new TransformStream<Uint8Array, Uint8Array>({\n transform(chunk, controller) {\n buffered.push(fixPreloadAs(decoder.decode(chunk, { stream: true })));\n\n if (timeoutId !== null) return;\n\n timeoutId = setTimeout(() => {\n try {\n flushBuffered(controller);\n\n const rscScripts = rscEmbed.flush();\n if (rscScripts) {\n controller.enqueue(encoder.encode(rscScripts));\n }\n } catch {\n // Stream was cancelled between when the timeout was registered and\n // when it fired (e.g. client disconnected, health-check cancelled\n // the response body). Ignore — the stream is already closed.\n }\n\n timeoutId = null;\n }, 0);\n },\n\n async flush(controller) {\n if (timeoutId !== null) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n\n flushBuffered(controller);\n\n if (!injected) {\n emitInsertion(controller);\n injected = true;\n } else if (insertsPerFlush) {\n emitInsertion(controller);\n }\n\n const finalScripts = await rscEmbed.finalize();\n if (finalScripts) {\n controller.enqueue(encoder.encode(finalScripts));\n }\n },\n });\n}\n"],"mappings":"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"}
@@ -17,9 +17,19 @@ type ArtifactCompatibilityEnvelopeInput = Readonly<{
17
17
  rootBoundaryId?: string | null;
18
18
  renderEpoch?: string | null;
19
19
  }>;
20
+ type ArtifactCompatibilitySet = readonly [string, string, ...string[]];
21
+ type ArtifactCompatibilityMap = Readonly<{
22
+ graphVersions?: readonly ArtifactCompatibilitySet[];
23
+ deploymentVersions?: readonly ArtifactCompatibilitySet[];
24
+ rootBoundaryIds?: readonly ArtifactCompatibilitySet[];
25
+ renderEpochs?: readonly ArtifactCompatibilitySet[];
26
+ }>;
27
+ type ArtifactCompatibilityEvaluationOptions = Readonly<{
28
+ compatibilityMap?: ArtifactCompatibilityMap;
29
+ }>;
20
30
  type ArtifactCompatibilityFallback = "renderFresh";
21
31
  type ArtifactCompatibilityUnknownReason = "graphVersionUnknown" | "deploymentVersionUnknown" | "rootBoundaryIdUnknown" | "renderEpochUnknown";
22
- type ArtifactCompatibilityIncompatibleReason = "appElementsSchemaVersionMismatch" | "deploymentVersionMismatch" | "graphVersionMismatch" | "renderEpochMismatch" | "rootBoundaryIdMismatch" | "rscPayloadSchemaVersionMismatch" | "schemaVersionMismatch";
32
+ type ArtifactCompatibilityIncompatibleReason = "appElementsSchemaVersionMismatch" | "deploymentVersionNotDeclaredCompatible" | "deploymentVersionMismatch" | "graphVersionNotDeclaredCompatible" | "graphVersionMismatch" | "renderEpochNotDeclaredCompatible" | "renderEpochMismatch" | "rootBoundaryIdNotDeclaredCompatible" | "rootBoundaryIdMismatch" | "rscPayloadSchemaVersionMismatch" | "schemaVersionMismatch";
23
33
  type ArtifactCompatibilityDecision = Readonly<{
24
34
  kind: "compatible";
25
35
  } | {
@@ -38,7 +48,7 @@ type ArtifactCompatibilityGraphVersionInput = Readonly<{
38
48
  declare function createArtifactCompatibilityEnvelope(input?: ArtifactCompatibilityEnvelopeInput): ArtifactCompatibilityEnvelope;
39
49
  declare function createArtifactCompatibilityGraphVersion(input: ArtifactCompatibilityGraphVersionInput): string;
40
50
  declare function parseArtifactCompatibilityEnvelope(value: unknown): ArtifactCompatibilityEnvelope | null;
41
- declare function evaluateArtifactCompatibility(current: ArtifactCompatibilityEnvelope, candidate: ArtifactCompatibilityEnvelope): ArtifactCompatibilityDecision;
51
+ declare function evaluateArtifactCompatibility(current: ArtifactCompatibilityEnvelope, candidate: ArtifactCompatibilityEnvelope, options?: ArtifactCompatibilityEvaluationOptions): ArtifactCompatibilityDecision;
42
52
  //#endregion
43
53
  export { APP_ELEMENTS_SCHEMA_VERSION, ARTIFACT_COMPATIBILITY_SCHEMA_VERSION, ArtifactCompatibilityEnvelope, RSC_PAYLOAD_SCHEMA_VERSION, createArtifactCompatibilityEnvelope, createArtifactCompatibilityGraphVersion, evaluateArtifactCompatibility, parseArtifactCompatibilityEnvelope };
44
54
  //# sourceMappingURL=artifact-compatibility.d.ts.map
@@ -57,22 +57,26 @@ function unknown(reason) {
57
57
  reason
58
58
  };
59
59
  }
60
- function compareKnownField(currentValue, candidateValue, unknownReason, mismatchReason) {
60
+ function compareKnownField(currentValue, candidateValue, unknownReason, mismatchReason, notDeclaredCompatibleReason, compatibilitySets) {
61
61
  if (currentValue === null || candidateValue === null) return unknown(unknownReason);
62
- if (currentValue !== candidateValue) return incompatible(mismatchReason);
63
- return null;
62
+ if (currentValue === candidateValue) return null;
63
+ if (compatibilitySets === void 0) return incompatible(mismatchReason);
64
+ return isDeclaredCompatible(currentValue, candidateValue, compatibilitySets) ? null : incompatible(notDeclaredCompatibleReason);
64
65
  }
65
- function evaluateArtifactCompatibility(current, candidate) {
66
+ function isDeclaredCompatible(currentValue, candidateValue, compatibilitySets) {
67
+ return compatibilitySets.some((compatibilitySet) => compatibilitySet.includes(currentValue) && compatibilitySet.includes(candidateValue));
68
+ }
69
+ function evaluateArtifactCompatibility(current, candidate, options = {}) {
66
70
  if (current.schemaVersion !== candidate.schemaVersion) return incompatible("schemaVersionMismatch");
67
71
  if (current.appElementsSchemaVersion !== candidate.appElementsSchemaVersion) return incompatible("appElementsSchemaVersionMismatch");
68
72
  if (current.rscPayloadSchemaVersion !== candidate.rscPayloadSchemaVersion) return incompatible("rscPayloadSchemaVersionMismatch");
69
- const graphDecision = compareKnownField(current.graphVersion, candidate.graphVersion, "graphVersionUnknown", "graphVersionMismatch");
73
+ const graphDecision = compareKnownField(current.graphVersion, candidate.graphVersion, "graphVersionUnknown", "graphVersionMismatch", "graphVersionNotDeclaredCompatible", options.compatibilityMap?.graphVersions);
70
74
  if (graphDecision) return graphDecision;
71
- const deploymentDecision = compareKnownField(current.deploymentVersion, candidate.deploymentVersion, "deploymentVersionUnknown", "deploymentVersionMismatch");
75
+ const deploymentDecision = compareKnownField(current.deploymentVersion, candidate.deploymentVersion, "deploymentVersionUnknown", "deploymentVersionMismatch", "deploymentVersionNotDeclaredCompatible", options.compatibilityMap?.deploymentVersions);
72
76
  if (deploymentDecision) return deploymentDecision;
73
- const rootBoundaryDecision = compareKnownField(current.rootBoundaryId, candidate.rootBoundaryId, "rootBoundaryIdUnknown", "rootBoundaryIdMismatch");
77
+ const rootBoundaryDecision = compareKnownField(current.rootBoundaryId, candidate.rootBoundaryId, "rootBoundaryIdUnknown", "rootBoundaryIdMismatch", "rootBoundaryIdNotDeclaredCompatible", options.compatibilityMap?.rootBoundaryIds);
74
78
  if (rootBoundaryDecision) return rootBoundaryDecision;
75
- const renderEpochDecision = compareKnownField(current.renderEpoch, candidate.renderEpoch, "renderEpochUnknown", "renderEpochMismatch");
79
+ const renderEpochDecision = compareKnownField(current.renderEpoch, candidate.renderEpoch, "renderEpochUnknown", "renderEpochMismatch", "renderEpochNotDeclaredCompatible", options.compatibilityMap?.renderEpochs);
76
80
  if (renderEpochDecision) return renderEpochDecision;
77
81
  return { kind: "compatible" };
78
82
  }
@@ -1 +1 @@
1
- {"version":3,"file":"artifact-compatibility.js","names":[],"sources":["../../src/server/artifact-compatibility.ts"],"sourcesContent":["import { fnv1a64 } from \"../utils/hash.js\";\n\nexport const ARTIFACT_COMPATIBILITY_SCHEMA_VERSION = 1;\n\n// These versions describe separate protocol layers. For example, a future\n// rolling deploy can bump the flat AppElements row shape while keeping the\n// envelope object and serialized RSC transport version stable.\nexport const APP_ELEMENTS_SCHEMA_VERSION = 1;\nexport const RSC_PAYLOAD_SCHEMA_VERSION = 1;\n\nexport type ArtifactCompatibilityEnvelope = Readonly<{\n schemaVersion: typeof ARTIFACT_COMPATIBILITY_SCHEMA_VERSION;\n graphVersion: string | null;\n deploymentVersion: string | null;\n appElementsSchemaVersion: typeof APP_ELEMENTS_SCHEMA_VERSION;\n rscPayloadSchemaVersion: typeof RSC_PAYLOAD_SCHEMA_VERSION;\n rootBoundaryId: string | null;\n renderEpoch: string | null;\n}>;\n\ntype ArtifactCompatibilityEnvelopeInput = Readonly<{\n graphVersion?: string | null;\n deploymentVersion?: string | null;\n rootBoundaryId?: string | null;\n renderEpoch?: string | null;\n}>;\n\ntype ArtifactCompatibilityFallback = \"renderFresh\";\n\ntype ArtifactCompatibilityUnknownReason =\n | \"graphVersionUnknown\"\n | \"deploymentVersionUnknown\"\n | \"rootBoundaryIdUnknown\"\n | \"renderEpochUnknown\";\n\ntype ArtifactCompatibilityIncompatibleReason =\n | \"appElementsSchemaVersionMismatch\"\n | \"deploymentVersionMismatch\"\n | \"graphVersionMismatch\"\n | \"renderEpochMismatch\"\n | \"rootBoundaryIdMismatch\"\n | \"rscPayloadSchemaVersionMismatch\"\n | \"schemaVersionMismatch\";\n\ntype ArtifactCompatibilityDecision = Readonly<\n | { kind: \"compatible\" }\n | {\n kind: \"unknown\";\n fallback: ArtifactCompatibilityFallback;\n reason: ArtifactCompatibilityUnknownReason;\n }\n | {\n kind: \"incompatible\";\n fallback: ArtifactCompatibilityFallback;\n reason: ArtifactCompatibilityIncompatibleReason;\n }\n>;\n\ntype ArtifactCompatibilityGraphVersionInput = Readonly<{\n routePattern: string;\n rootBoundaryId: string | null;\n}>;\n\nexport function createArtifactCompatibilityEnvelope(\n input: ArtifactCompatibilityEnvelopeInput = {},\n): ArtifactCompatibilityEnvelope {\n return {\n schemaVersion: ARTIFACT_COMPATIBILITY_SCHEMA_VERSION,\n graphVersion: input.graphVersion ?? null,\n deploymentVersion: input.deploymentVersion ?? null,\n appElementsSchemaVersion: APP_ELEMENTS_SCHEMA_VERSION,\n rscPayloadSchemaVersion: RSC_PAYLOAD_SCHEMA_VERSION,\n rootBoundaryId: input.rootBoundaryId ?? null,\n renderEpoch: input.renderEpoch ?? null,\n };\n}\n\nexport function createArtifactCompatibilityGraphVersion(\n input: ArtifactCompatibilityGraphVersionInput,\n): string {\n const fingerprint = fnv1a64(JSON.stringify([input.routePattern, input.rootBoundaryId]));\n return `app-route-graph:${fingerprint}`;\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isStringOrNull(value: unknown): value is string | null {\n return typeof value === \"string\" || value === null;\n}\n\nfunction hasCurrentSchemaVersions(record: Readonly<Record<string, unknown>>): boolean {\n return (\n record.schemaVersion === ARTIFACT_COMPATIBILITY_SCHEMA_VERSION &&\n record.appElementsSchemaVersion === APP_ELEMENTS_SCHEMA_VERSION &&\n record.rscPayloadSchemaVersion === RSC_PAYLOAD_SCHEMA_VERSION\n );\n}\n\nexport function parseArtifactCompatibilityEnvelope(\n value: unknown,\n): ArtifactCompatibilityEnvelope | null {\n if (!isRecord(value)) return null;\n // The Wave01 skeleton intentionally collapses version mismatch and malformed\n // metadata into \"not current\". Cache/skip callers must split those cases\n // before treating unknown compatibility as anything other than a miss/reject.\n if (!hasCurrentSchemaVersions(value)) return null;\n if (!isStringOrNull(value.graphVersion)) return null;\n if (!isStringOrNull(value.deploymentVersion)) return null;\n if (!isStringOrNull(value.rootBoundaryId)) return null;\n if (!isStringOrNull(value.renderEpoch)) return null;\n\n // This parser intentionally returns a normalized current-version proof. A\n // future-compatible reader should introduce a separate parsed type instead of\n // widening this Wave01 envelope after the current-version checks above.\n return {\n schemaVersion: ARTIFACT_COMPATIBILITY_SCHEMA_VERSION,\n graphVersion: value.graphVersion,\n deploymentVersion: value.deploymentVersion,\n appElementsSchemaVersion: APP_ELEMENTS_SCHEMA_VERSION,\n rscPayloadSchemaVersion: RSC_PAYLOAD_SCHEMA_VERSION,\n rootBoundaryId: value.rootBoundaryId,\n renderEpoch: value.renderEpoch,\n };\n}\n\nfunction incompatible(\n reason: ArtifactCompatibilityIncompatibleReason,\n): ArtifactCompatibilityDecision {\n return { kind: \"incompatible\", fallback: \"renderFresh\", reason };\n}\n\nfunction unknown(reason: ArtifactCompatibilityUnknownReason): ArtifactCompatibilityDecision {\n return { kind: \"unknown\", fallback: \"renderFresh\", reason };\n}\n\nfunction compareKnownField(\n currentValue: string | null,\n candidateValue: string | null,\n unknownReason: ArtifactCompatibilityUnknownReason,\n mismatchReason: ArtifactCompatibilityIncompatibleReason,\n): ArtifactCompatibilityDecision | null {\n if (currentValue === null || candidateValue === null) {\n return unknown(unknownReason);\n }\n if (currentValue !== candidateValue) {\n return incompatible(mismatchReason);\n }\n return null;\n}\n\nexport function evaluateArtifactCompatibility(\n current: ArtifactCompatibilityEnvelope,\n candidate: ArtifactCompatibilityEnvelope,\n): ArtifactCompatibilityDecision {\n // Pre-positioned for #726-COMPAT-04/05, where cache and visited-response\n // reuse paths will compare the current render proof with a candidate payload.\n if (current.schemaVersion !== candidate.schemaVersion) {\n return incompatible(\"schemaVersionMismatch\");\n }\n if (current.appElementsSchemaVersion !== candidate.appElementsSchemaVersion) {\n return incompatible(\"appElementsSchemaVersionMismatch\");\n }\n if (current.rscPayloadSchemaVersion !== candidate.rscPayloadSchemaVersion) {\n return incompatible(\"rscPayloadSchemaVersionMismatch\");\n }\n\n const graphDecision = compareKnownField(\n current.graphVersion,\n candidate.graphVersion,\n \"graphVersionUnknown\",\n \"graphVersionMismatch\",\n );\n if (graphDecision) return graphDecision;\n\n const deploymentDecision = compareKnownField(\n current.deploymentVersion,\n candidate.deploymentVersion,\n \"deploymentVersionUnknown\",\n \"deploymentVersionMismatch\",\n );\n if (deploymentDecision) return deploymentDecision;\n\n const rootBoundaryDecision = compareKnownField(\n current.rootBoundaryId,\n candidate.rootBoundaryId,\n \"rootBoundaryIdUnknown\",\n \"rootBoundaryIdMismatch\",\n );\n if (rootBoundaryDecision) return rootBoundaryDecision;\n\n const renderEpochDecision = compareKnownField(\n current.renderEpoch,\n candidate.renderEpoch,\n \"renderEpochUnknown\",\n \"renderEpochMismatch\",\n );\n if (renderEpochDecision) return renderEpochDecision;\n\n return { kind: \"compatible\" };\n}\n"],"mappings":";;AAEA,MAAa,wCAAwC;AAKrD,MAAa,8BAA8B;AAC3C,MAAa,6BAA6B;AAuD1C,SAAgB,oCACd,QAA4C,EAAE,EACf;CAC/B,OAAO;EACL,eAAA;EACA,cAAc,MAAM,gBAAgB;EACpC,mBAAmB,MAAM,qBAAqB;EAC9C,0BAAA;EACA,yBAAA;EACA,gBAAgB,MAAM,kBAAkB;EACxC,aAAa,MAAM,eAAe;EACnC;;AAGH,SAAgB,wCACd,OACQ;CAER,OAAO,mBADa,QAAQ,KAAK,UAAU,CAAC,MAAM,cAAc,MAAM,eAAe,CAAC,CACjD;;AAGvC,SAAS,SAAS,OAA4D;CAC5E,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM;;AAG7E,SAAS,eAAe,OAAwC;CAC9D,OAAO,OAAO,UAAU,YAAY,UAAU;;AAGhD,SAAS,yBAAyB,QAAoD;CACpF,OACE,OAAO,kBAAA,KACP,OAAO,6BAAA,KACP,OAAO,4BAAA;;AAIX,SAAgB,mCACd,OACsC;CACtC,IAAI,CAAC,SAAS,MAAM,EAAE,OAAO;CAI7B,IAAI,CAAC,yBAAyB,MAAM,EAAE,OAAO;CAC7C,IAAI,CAAC,eAAe,MAAM,aAAa,EAAE,OAAO;CAChD,IAAI,CAAC,eAAe,MAAM,kBAAkB,EAAE,OAAO;CACrD,IAAI,CAAC,eAAe,MAAM,eAAe,EAAE,OAAO;CAClD,IAAI,CAAC,eAAe,MAAM,YAAY,EAAE,OAAO;CAK/C,OAAO;EACL,eAAA;EACA,cAAc,MAAM;EACpB,mBAAmB,MAAM;EACzB,0BAAA;EACA,yBAAA;EACA,gBAAgB,MAAM;EACtB,aAAa,MAAM;EACpB;;AAGH,SAAS,aACP,QAC+B;CAC/B,OAAO;EAAE,MAAM;EAAgB,UAAU;EAAe;EAAQ;;AAGlE,SAAS,QAAQ,QAA2E;CAC1F,OAAO;EAAE,MAAM;EAAW,UAAU;EAAe;EAAQ;;AAG7D,SAAS,kBACP,cACA,gBACA,eACA,gBACsC;CACtC,IAAI,iBAAiB,QAAQ,mBAAmB,MAC9C,OAAO,QAAQ,cAAc;CAE/B,IAAI,iBAAiB,gBACnB,OAAO,aAAa,eAAe;CAErC,OAAO;;AAGT,SAAgB,8BACd,SACA,WAC+B;CAG/B,IAAI,QAAQ,kBAAkB,UAAU,eACtC,OAAO,aAAa,wBAAwB;CAE9C,IAAI,QAAQ,6BAA6B,UAAU,0BACjD,OAAO,aAAa,mCAAmC;CAEzD,IAAI,QAAQ,4BAA4B,UAAU,yBAChD,OAAO,aAAa,kCAAkC;CAGxD,MAAM,gBAAgB,kBACpB,QAAQ,cACR,UAAU,cACV,uBACA,uBACD;CACD,IAAI,eAAe,OAAO;CAE1B,MAAM,qBAAqB,kBACzB,QAAQ,mBACR,UAAU,mBACV,4BACA,4BACD;CACD,IAAI,oBAAoB,OAAO;CAE/B,MAAM,uBAAuB,kBAC3B,QAAQ,gBACR,UAAU,gBACV,yBACA,yBACD;CACD,IAAI,sBAAsB,OAAO;CAEjC,MAAM,sBAAsB,kBAC1B,QAAQ,aACR,UAAU,aACV,sBACA,sBACD;CACD,IAAI,qBAAqB,OAAO;CAEhC,OAAO,EAAE,MAAM,cAAc"}
1
+ {"version":3,"file":"artifact-compatibility.js","names":[],"sources":["../../src/server/artifact-compatibility.ts"],"sourcesContent":["import { fnv1a64 } from \"../utils/hash.js\";\n\nexport const ARTIFACT_COMPATIBILITY_SCHEMA_VERSION = 1;\n\n// These versions describe separate protocol layers. For example, a future\n// rolling deploy can bump the flat AppElements row shape while keeping the\n// envelope object and serialized RSC transport version stable.\nexport const APP_ELEMENTS_SCHEMA_VERSION = 1;\nexport const RSC_PAYLOAD_SCHEMA_VERSION = 1;\n\nexport type ArtifactCompatibilityEnvelope = Readonly<{\n schemaVersion: typeof ARTIFACT_COMPATIBILITY_SCHEMA_VERSION;\n graphVersion: string | null;\n deploymentVersion: string | null;\n appElementsSchemaVersion: typeof APP_ELEMENTS_SCHEMA_VERSION;\n rscPayloadSchemaVersion: typeof RSC_PAYLOAD_SCHEMA_VERSION;\n rootBoundaryId: string | null;\n renderEpoch: string | null;\n}>;\n\ntype ArtifactCompatibilityEnvelopeInput = Readonly<{\n graphVersion?: string | null;\n deploymentVersion?: string | null;\n rootBoundaryId?: string | null;\n renderEpoch?: string | null;\n}>;\n\ntype ArtifactCompatibilitySet = readonly [string, string, ...string[]];\n\ntype ArtifactCompatibilityMap = Readonly<{\n graphVersions?: readonly ArtifactCompatibilitySet[];\n deploymentVersions?: readonly ArtifactCompatibilitySet[];\n rootBoundaryIds?: readonly ArtifactCompatibilitySet[];\n renderEpochs?: readonly ArtifactCompatibilitySet[];\n}>;\n\ntype ArtifactCompatibilityEvaluationOptions = Readonly<{\n compatibilityMap?: ArtifactCompatibilityMap;\n}>;\n\ntype ArtifactCompatibilityFallback = \"renderFresh\";\n\ntype ArtifactCompatibilityUnknownReason =\n | \"graphVersionUnknown\"\n | \"deploymentVersionUnknown\"\n | \"rootBoundaryIdUnknown\"\n | \"renderEpochUnknown\";\n\ntype ArtifactCompatibilityIncompatibleReason =\n | \"appElementsSchemaVersionMismatch\"\n | \"deploymentVersionNotDeclaredCompatible\"\n | \"deploymentVersionMismatch\"\n | \"graphVersionNotDeclaredCompatible\"\n | \"graphVersionMismatch\"\n | \"renderEpochNotDeclaredCompatible\"\n | \"renderEpochMismatch\"\n | \"rootBoundaryIdNotDeclaredCompatible\"\n | \"rootBoundaryIdMismatch\"\n | \"rscPayloadSchemaVersionMismatch\"\n | \"schemaVersionMismatch\";\n\ntype ArtifactCompatibilityDecision = Readonly<\n | { kind: \"compatible\" }\n | {\n kind: \"unknown\";\n fallback: ArtifactCompatibilityFallback;\n reason: ArtifactCompatibilityUnknownReason;\n }\n | {\n kind: \"incompatible\";\n fallback: ArtifactCompatibilityFallback;\n reason: ArtifactCompatibilityIncompatibleReason;\n }\n>;\n\ntype ArtifactCompatibilityGraphVersionInput = Readonly<{\n routePattern: string;\n rootBoundaryId: string | null;\n}>;\n\nexport function createArtifactCompatibilityEnvelope(\n input: ArtifactCompatibilityEnvelopeInput = {},\n): ArtifactCompatibilityEnvelope {\n return {\n schemaVersion: ARTIFACT_COMPATIBILITY_SCHEMA_VERSION,\n graphVersion: input.graphVersion ?? null,\n deploymentVersion: input.deploymentVersion ?? null,\n appElementsSchemaVersion: APP_ELEMENTS_SCHEMA_VERSION,\n rscPayloadSchemaVersion: RSC_PAYLOAD_SCHEMA_VERSION,\n rootBoundaryId: input.rootBoundaryId ?? null,\n renderEpoch: input.renderEpoch ?? null,\n };\n}\n\nexport function createArtifactCompatibilityGraphVersion(\n input: ArtifactCompatibilityGraphVersionInput,\n): string {\n const fingerprint = fnv1a64(JSON.stringify([input.routePattern, input.rootBoundaryId]));\n return `app-route-graph:${fingerprint}`;\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isStringOrNull(value: unknown): value is string | null {\n return typeof value === \"string\" || value === null;\n}\n\nfunction hasCurrentSchemaVersions(record: Readonly<Record<string, unknown>>): boolean {\n return (\n record.schemaVersion === ARTIFACT_COMPATIBILITY_SCHEMA_VERSION &&\n record.appElementsSchemaVersion === APP_ELEMENTS_SCHEMA_VERSION &&\n record.rscPayloadSchemaVersion === RSC_PAYLOAD_SCHEMA_VERSION\n );\n}\n\nexport function parseArtifactCompatibilityEnvelope(\n value: unknown,\n): ArtifactCompatibilityEnvelope | null {\n if (!isRecord(value)) return null;\n // The Wave01 skeleton intentionally collapses version mismatch and malformed\n // metadata into \"not current\". Cache/skip callers must split those cases\n // before treating unknown compatibility as anything other than a miss/reject.\n if (!hasCurrentSchemaVersions(value)) return null;\n if (!isStringOrNull(value.graphVersion)) return null;\n if (!isStringOrNull(value.deploymentVersion)) return null;\n if (!isStringOrNull(value.rootBoundaryId)) return null;\n if (!isStringOrNull(value.renderEpoch)) return null;\n\n // This parser intentionally returns a normalized current-version proof. A\n // future-compatible reader should introduce a separate parsed type instead of\n // widening this Wave01 envelope after the current-version checks above.\n return {\n schemaVersion: ARTIFACT_COMPATIBILITY_SCHEMA_VERSION,\n graphVersion: value.graphVersion,\n deploymentVersion: value.deploymentVersion,\n appElementsSchemaVersion: APP_ELEMENTS_SCHEMA_VERSION,\n rscPayloadSchemaVersion: RSC_PAYLOAD_SCHEMA_VERSION,\n rootBoundaryId: value.rootBoundaryId,\n renderEpoch: value.renderEpoch,\n };\n}\n\nfunction incompatible(\n reason: ArtifactCompatibilityIncompatibleReason,\n): ArtifactCompatibilityDecision {\n return { kind: \"incompatible\", fallback: \"renderFresh\", reason };\n}\n\nfunction unknown(reason: ArtifactCompatibilityUnknownReason): ArtifactCompatibilityDecision {\n return { kind: \"unknown\", fallback: \"renderFresh\", reason };\n}\n\nfunction compareKnownField(\n currentValue: string | null,\n candidateValue: string | null,\n unknownReason: ArtifactCompatibilityUnknownReason,\n mismatchReason: ArtifactCompatibilityIncompatibleReason,\n notDeclaredCompatibleReason: ArtifactCompatibilityIncompatibleReason,\n compatibilitySets: readonly ArtifactCompatibilitySet[] | undefined,\n): ArtifactCompatibilityDecision | null {\n if (currentValue === null || candidateValue === null) {\n return unknown(unknownReason);\n }\n if (currentValue === candidateValue) {\n return null;\n }\n if (compatibilitySets === undefined) {\n return incompatible(mismatchReason);\n }\n return isDeclaredCompatible(currentValue, candidateValue, compatibilitySets)\n ? null\n : incompatible(notDeclaredCompatibleReason);\n}\n\nfunction isDeclaredCompatible(\n currentValue: string,\n candidateValue: string,\n compatibilitySets: readonly ArtifactCompatibilitySet[],\n): boolean {\n // Compatibility is intentionally scoped to one declared set. Overlapping\n // pair sets like [a,b] and [b,c] must not silently make a compatible with c.\n return compatibilitySets.some(\n (compatibilitySet) =>\n compatibilitySet.includes(currentValue) && compatibilitySet.includes(candidateValue),\n );\n}\n\nexport function evaluateArtifactCompatibility(\n current: ArtifactCompatibilityEnvelope,\n candidate: ArtifactCompatibilityEnvelope,\n options: ArtifactCompatibilityEvaluationOptions = {},\n): ArtifactCompatibilityDecision {\n // This remains a proof evaluator: mismatched fields are compatible only when\n // the current build's compatibility map explicitly declares that relationship.\n if (current.schemaVersion !== candidate.schemaVersion) {\n return incompatible(\"schemaVersionMismatch\");\n }\n if (current.appElementsSchemaVersion !== candidate.appElementsSchemaVersion) {\n return incompatible(\"appElementsSchemaVersionMismatch\");\n }\n if (current.rscPayloadSchemaVersion !== candidate.rscPayloadSchemaVersion) {\n return incompatible(\"rscPayloadSchemaVersionMismatch\");\n }\n\n const graphDecision = compareKnownField(\n current.graphVersion,\n candidate.graphVersion,\n \"graphVersionUnknown\",\n \"graphVersionMismatch\",\n \"graphVersionNotDeclaredCompatible\",\n options.compatibilityMap?.graphVersions,\n );\n if (graphDecision) return graphDecision;\n\n const deploymentDecision = compareKnownField(\n current.deploymentVersion,\n candidate.deploymentVersion,\n \"deploymentVersionUnknown\",\n \"deploymentVersionMismatch\",\n \"deploymentVersionNotDeclaredCompatible\",\n options.compatibilityMap?.deploymentVersions,\n );\n if (deploymentDecision) return deploymentDecision;\n\n const rootBoundaryDecision = compareKnownField(\n current.rootBoundaryId,\n candidate.rootBoundaryId,\n \"rootBoundaryIdUnknown\",\n \"rootBoundaryIdMismatch\",\n \"rootBoundaryIdNotDeclaredCompatible\",\n options.compatibilityMap?.rootBoundaryIds,\n );\n if (rootBoundaryDecision) return rootBoundaryDecision;\n\n const renderEpochDecision = compareKnownField(\n current.renderEpoch,\n candidate.renderEpoch,\n \"renderEpochUnknown\",\n \"renderEpochMismatch\",\n \"renderEpochNotDeclaredCompatible\",\n options.compatibilityMap?.renderEpochs,\n );\n if (renderEpochDecision) return renderEpochDecision;\n\n return { kind: \"compatible\" };\n}\n"],"mappings":"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"}
@@ -1,9 +1,11 @@
1
1
  import { AppRouteSemanticIds } from "../routing/app-route-graph.js";
2
2
 
3
3
  //#region src/server/cache-proof.d.ts
4
- declare const CACHE_PROOF_MODEL_SCHEMA_VERSION = 0;
5
- type CacheProofModelSchemaVersion = 0;
6
- type CacheProofRejectionCode = "CP_MODEL_DISABLED" | "CP_DIMENSION_COUNT_EXCEEDED" | "CP_DIMENSION_NAME_MISSING" | "CP_DIMENSION_NAME_TOO_LONG" | "CP_DIMENSION_VALUE_COUNT_EXCEEDED" | "CP_DIMENSION_VALUE_TOO_LONG" | "CP_DIMENSION_VALUES_MISSING" | "CP_ENCODED_VARIANT_TOO_LONG" | "CP_INVALID_VARIANT_BUDGET" | "CP_ROUTE_VARIANT_CEILING_EXCEEDED" | "CP_UNSAFE_PUBLIC_DIMENSION" | "CP_BOUNDARY_OUTCOME_MISMATCH" | "CP_BOUNDARY_OUTCOME_UNKNOWN";
4
+ declare const CACHE_PROOF_MODEL_SCHEMA_VERSION = 1;
5
+ type CacheProofModelSchemaVersion = 1;
6
+ type CacheProofRejectionCode = "CP_MODEL_DISABLED" | "CP_DIMENSION_COUNT_EXCEEDED" | "CP_DIMENSION_NAME_MISSING" | "CP_DIMENSION_NAME_TOO_LONG" | "CP_DIMENSION_VALUE_COUNT_EXCEEDED" | "CP_DIMENSION_VALUE_TOO_LONG" | "CP_DIMENSION_VALUES_MISSING" | "CP_ENCODED_VARIANT_TOO_LONG" | "CP_INVALID_VARIANT_BUDGET" | "CP_ROUTE_VARIANT_BUDGET_ROUTE_MISMATCH" | "CP_ROUTE_VARIANT_CEILING_EXCEEDED" | "CP_UNSAFE_PUBLIC_DIMENSION" | "CP_BOUNDARY_OUTCOME_MISMATCH" | "CP_BOUNDARY_OUTCOME_UNKNOWN" | "CP_PRIVATE_DYNAMIC_DOWNGRADE" | "CP_STATIC_LAYOUT_CANDIDATE_OUTPUT_KIND" | "CP_STATIC_LAYOUT_CURRENT_OUTPUT_KIND" | "CP_STATIC_LAYOUT_ID_MISMATCH" | "CP_STATIC_LAYOUT_OBSERVATION_OUTPUT_KIND" | "CP_STATIC_LAYOUT_OBSERVATION_OUTPUT_MISMATCH" | "CP_STATIC_LAYOUT_PRIVATE_DYNAMIC_DOWNGRADE" | "CP_STATIC_LAYOUT_PRIVATE_VARIANT_DIMENSION" | "CP_STATIC_LAYOUT_REQUEST_API_OBSERVED" | "CP_STATIC_LAYOUT_REQUEST_API_UNKNOWN" | "CP_STATIC_LAYOUT_ROOT_BOUNDARY_MISMATCH" | "CP_STATIC_LAYOUT_ROOT_BOUNDARY_UNKNOWN";
7
+ type CacheProofAcceptanceCode = "CP_STATIC_LAYOUT_REUSE_PROVEN";
8
+ type CacheProofTraceCode = CacheProofAcceptanceCode | CacheProofRejectionCode;
7
9
  type CacheProofTraceFieldValue = string | number | boolean | null | readonly string[];
8
10
  type CacheProofTraceFields = Readonly<Record<string, CacheProofTraceFieldValue>>;
9
11
  type CacheProofBreakerFallbackMode = "renderFresh" | "privateUncacheable";
@@ -83,6 +85,9 @@ type CacheProofOutputScope = Readonly<{
83
85
  routeId: string;
84
86
  templateId: string;
85
87
  }>;
88
+ type StaticLayoutCacheProofOutputScope = Extract<CacheProofOutputScope, {
89
+ kind: "layout";
90
+ }>;
86
91
  type CacheVariant = Readonly<{
87
92
  budget: CacheVariantBudget;
88
93
  cacheKey: string;
@@ -94,7 +99,6 @@ type CacheVariant = Readonly<{
94
99
  type BuildCacheVariantInput = Readonly<{
95
100
  budget: CacheVariantBudget;
96
101
  dimensions: readonly CacheVariantDimensionInput[];
97
- existingVariantCount: number;
98
102
  output: CacheProofOutputScope;
99
103
  }>;
100
104
  type BuildCacheVariantResult = Readonly<{
@@ -104,6 +108,24 @@ type BuildCacheVariantResult = Readonly<{
104
108
  kind: "breakerFallback";
105
109
  fallback: CacheProofBreakerFallback;
106
110
  }>;
111
+ type CacheVariantRouteBudget = Readonly<{
112
+ routeId: string;
113
+ variantCacheKeys: readonly string[];
114
+ }>;
115
+ type CacheVariantRouteBudgetAdmission = Readonly<{
116
+ didConsumeRouteVariantBudget: boolean;
117
+ kind: "variant";
118
+ routeBudget: CacheVariantRouteBudget;
119
+ variant: CacheVariant;
120
+ }> | Readonly<{
121
+ fallback: CacheProofBreakerFallback;
122
+ kind: "breakerFallback";
123
+ routeBudget: CacheVariantRouteBudget | null;
124
+ }>;
125
+ type BuildCacheVariantWithRouteBudgetInput = BuildCacheVariantInput & Readonly<{
126
+ routeBudget: CacheVariantRouteBudget | null;
127
+ }>;
128
+ type BuildCacheVariantWithRouteBudgetResult = CacheVariantRouteBudgetAdmission;
107
129
  type AppRouteCacheProofGraphScopeInput = Readonly<{
108
130
  ids: AppRouteSemanticIds;
109
131
  }>;
@@ -150,21 +172,103 @@ type RenderObservationCompleteness = "complete" | "partial" | "unknown";
150
172
  type RenderCacheability = "private" | "public" | "uncacheable" | "unknown";
151
173
  type RenderRequestApiKind = "connection" | "cookies" | "draftMode" | "headers" | "params" | "searchParams";
152
174
  type RenderRequestApiStatus = "notObserved" | "observed" | "unknown";
175
+ declare const ALL_RENDER_REQUEST_API_KINDS: readonly RenderRequestApiKind[];
153
176
  type RenderRequestApiObservation = Readonly<{
154
177
  kind: RenderRequestApiKind;
155
178
  status: RenderRequestApiStatus;
156
179
  }>;
180
+ type CacheProofDowngradeTarget = "freshRender" | "private" | "privateUncacheable" | "public" | "publicVariant";
181
+ type CacheProofDowngradeReason = Readonly<{
182
+ code: "CP_DOWNGRADE_CACHEABILITY_PRIVATE";
183
+ target: "private";
184
+ }> | Readonly<{
185
+ code: "CP_DOWNGRADE_CACHEABILITY_UNCACHEABLE";
186
+ target: "privateUncacheable";
187
+ }> | Readonly<{
188
+ code: "CP_DOWNGRADE_CACHEABILITY_UNKNOWN";
189
+ target: "freshRender";
190
+ }> | Readonly<{
191
+ code: "CP_DOWNGRADE_DYNAMIC_FETCH";
192
+ dynamicFetchCount: number;
193
+ target: "freshRender";
194
+ }> | Readonly<{
195
+ code: "CP_DOWNGRADE_DYNAMIC_REQUEST_API";
196
+ requestApi: "connection";
197
+ target: "freshRender";
198
+ }> | Readonly<{
199
+ code: "CP_DOWNGRADE_DRAFT_MODE";
200
+ requestApi: "draftMode";
201
+ target: "privateUncacheable";
202
+ }> | Readonly<{
203
+ code: "CP_DOWNGRADE_INCOMPLETE_OBSERVATION";
204
+ completeness: Exclude<RenderObservationCompleteness, "complete">;
205
+ target: "freshRender";
206
+ }> | Readonly<{
207
+ code: "CP_DOWNGRADE_PRIVATE_DIMENSION";
208
+ inputClass: "auth" | "draft" | "private" | "session";
209
+ source: "auth" | "cookie" | "draft-mode" | "header" | "session";
210
+ target: "private" | "privateUncacheable";
211
+ }> | Readonly<{
212
+ code: "CP_DOWNGRADE_PRIVATE_REQUEST_API";
213
+ requestApi: "cookies" | "headers";
214
+ target: "private";
215
+ }> | Readonly<{
216
+ code: "CP_DOWNGRADE_PUBLIC_REQUEST_API";
217
+ requestApi: "params" | "searchParams";
218
+ target: "publicVariant";
219
+ }> | Readonly<{
220
+ code: "CP_DOWNGRADE_UNKNOWN_REQUEST_API";
221
+ requestApi: RenderRequestApiKind;
222
+ target: "freshRender";
223
+ }>;
224
+ type CacheProofDowngradeClassification = Readonly<{
225
+ fallback: CacheProofBreakerFallback | null;
226
+ isPublicCacheCandidate: boolean;
227
+ reasons: readonly CacheProofDowngradeReason[];
228
+ target: CacheProofDowngradeTarget;
229
+ }>;
230
+ type ClassifyRenderObservationDowngradeInput = Readonly<{
231
+ cacheability: RenderCacheability;
232
+ completeness: RenderObservationCompleteness;
233
+ dynamicFetches: readonly string[];
234
+ requestApis: readonly RenderRequestApiObservation[];
235
+ }>;
236
+ type ClassifyCacheVariantDimensionDowngradeInput = Pick<CacheVariantDimensionInput, "source">;
157
237
  type RenderObservation = Readonly<{
158
238
  boundaryOutcome: BoundaryOutcome;
159
239
  cacheTags: readonly string[];
160
240
  cacheability: RenderCacheability;
161
241
  completeness: RenderObservationCompleteness;
242
+ downgrade: CacheProofDowngradeClassification;
162
243
  dynamicFetches: readonly string[];
163
244
  output: CacheProofOutputScope;
164
245
  pathTags: readonly string[];
165
246
  requestApis: readonly RenderRequestApiObservation[];
166
247
  schemaVersion: CacheProofModelSchemaVersion;
167
248
  }>;
249
+ type StaticLayoutReuseProof = Readonly<{
250
+ authorizesRuntimeReuse: false;
251
+ candidateOutput: StaticLayoutCacheProofOutputScope;
252
+ code: "CP_STATIC_LAYOUT_REUSE_PROVEN";
253
+ currentOutput: StaticLayoutCacheProofOutputScope;
254
+ fields: CacheProofTraceFields;
255
+ observation: RenderObservation;
256
+ requiredNegativeRequestApis: readonly RenderRequestApiKind[];
257
+ reuseClass: "static-layout";
258
+ variant: CacheVariant;
259
+ }>;
260
+ type BuildStaticLayoutReuseProofInput = Readonly<{
261
+ candidateObservation: RenderObservation;
262
+ candidateVariant: CacheVariant;
263
+ currentOutput: CacheProofOutputScope;
264
+ }>;
265
+ type BuildStaticLayoutReuseProofResult = Readonly<{
266
+ kind: "proof";
267
+ proof: StaticLayoutReuseProof;
268
+ }> | Readonly<{
269
+ kind: "rejected";
270
+ fallback: CacheProofBreakerFallback;
271
+ }>;
168
272
  type BuildRenderObservationInput = Readonly<{
169
273
  boundaryOutcome: BoundaryOutcome;
170
274
  cacheTags: readonly string[];
@@ -175,26 +279,41 @@ type BuildRenderObservationInput = Readonly<{
175
279
  pathTags: readonly string[];
176
280
  requestApis: readonly RenderRequestApiObservation[];
177
281
  }>;
282
+ type BuildRenderRequestApiObservationsInput = Readonly<{
283
+ completeness: RenderObservationCompleteness;
284
+ observed: readonly RenderRequestApiKind[];
285
+ }>;
178
286
  type DisabledCacheProofDecision = Readonly<{
179
287
  canReuse: false;
180
288
  fallback: CacheProofBreakerFallback;
181
289
  kind: "disabled";
182
290
  observation: RenderObservation;
291
+ staticLayoutProof?: StaticLayoutReuseProof;
183
292
  variant: CacheVariant;
184
293
  }>;
185
294
  type CreateDisabledCacheProofDecisionInput = Readonly<{
186
295
  observation: RenderObservation;
296
+ staticLayoutProof?: StaticLayoutReuseProof;
187
297
  variant: CacheVariant;
188
298
  }>;
189
299
  declare function createAppRouteCacheProofGraphScope(route: AppRouteCacheProofGraphScopeInput): AppRouteCacheProofGraphScope;
190
300
  declare function buildCacheVariant(input: BuildCacheVariantInput): BuildCacheVariantResult;
301
+ declare function enforceCacheVariantRouteBudget(input: {
302
+ routeBudget: CacheVariantRouteBudget | null;
303
+ variant: CacheVariant;
304
+ }): CacheVariantRouteBudgetAdmission;
305
+ declare function buildCacheVariantWithRouteBudget(input: BuildCacheVariantWithRouteBudgetInput): BuildCacheVariantWithRouteBudgetResult;
191
306
  declare function buildBoundaryOutcomeCompatibility(input: {
192
307
  candidate: BoundaryOutcome;
193
308
  expected: BoundaryOutcome;
194
309
  }): BoundaryOutcomeCompatibility;
310
+ declare function classifyCacheVariantDimensionDowngrade(input: ClassifyCacheVariantDimensionDowngradeInput): CacheProofDowngradeReason | null;
311
+ declare function classifyRenderObservationDowngrade(input: ClassifyRenderObservationDowngradeInput): CacheProofDowngradeClassification;
312
+ declare function buildRenderRequestApiObservations(input: BuildRenderRequestApiObservationsInput): RenderRequestApiObservation[];
195
313
  declare function buildRenderObservation(input: BuildRenderObservationInput): RenderObservation;
196
314
  declare function hasCompleteNegativeRequestApiProof(observation: RenderObservation, requiredApis: readonly RenderRequestApiKind[]): boolean;
315
+ declare function buildStaticLayoutReuseProof(input: BuildStaticLayoutReuseProofInput): BuildStaticLayoutReuseProofResult;
197
316
  declare function createDisabledCacheProofDecision(input: CreateDisabledCacheProofDecisionInput): DisabledCacheProofDecision;
198
317
  //#endregion
199
- export { AppRouteCacheProofGraphScope, AppRouteCacheProofGraphScopeInput, BoundaryOutcome, BoundaryOutcomeCompatibility, BuildCacheVariantInput, BuildCacheVariantResult, BuildRenderObservationInput, CACHE_PROOF_MODEL_SCHEMA_VERSION, CacheProofBreakerFallback, CacheProofBreakerFallbackMode, CacheProofFallbackScope, CacheProofModelSchemaVersion, CacheProofOutputScope, CacheProofRejectionCode, CacheProofTraceFieldValue, CacheProofTraceFields, CacheVariant, CacheVariantBudget, CacheVariantDimension, CacheVariantDimensionInput, CacheVariantDimensionPrivacy, CacheVariantDimensionSource, CreateDisabledCacheProofDecisionInput, DEFAULT_CACHE_VARIANT_BUDGET, DisabledCacheProofDecision, RenderCacheability, RenderObservation, RenderObservationCompleteness, RenderRequestApiKind, RenderRequestApiObservation, RenderRequestApiStatus, buildBoundaryOutcomeCompatibility, buildCacheVariant, buildRenderObservation, createAppRouteCacheProofGraphScope, createDisabledCacheProofDecision, hasCompleteNegativeRequestApiProof };
318
+ export { ALL_RENDER_REQUEST_API_KINDS, AppRouteCacheProofGraphScope, AppRouteCacheProofGraphScopeInput, BoundaryOutcome, BoundaryOutcomeCompatibility, BuildCacheVariantInput, BuildCacheVariantResult, BuildCacheVariantWithRouteBudgetInput, BuildCacheVariantWithRouteBudgetResult, BuildRenderObservationInput, BuildRenderRequestApiObservationsInput, BuildStaticLayoutReuseProofInput, BuildStaticLayoutReuseProofResult, CACHE_PROOF_MODEL_SCHEMA_VERSION, CacheProofAcceptanceCode, CacheProofBreakerFallback, CacheProofBreakerFallbackMode, CacheProofDowngradeClassification, CacheProofDowngradeReason, CacheProofDowngradeTarget, CacheProofFallbackScope, CacheProofModelSchemaVersion, CacheProofOutputScope, CacheProofRejectionCode, CacheProofTraceCode, CacheProofTraceFieldValue, CacheProofTraceFields, CacheVariant, CacheVariantBudget, CacheVariantDimension, CacheVariantDimensionInput, CacheVariantDimensionPrivacy, CacheVariantDimensionSource, CacheVariantRouteBudget, CacheVariantRouteBudgetAdmission, ClassifyCacheVariantDimensionDowngradeInput, ClassifyRenderObservationDowngradeInput, CreateDisabledCacheProofDecisionInput, DEFAULT_CACHE_VARIANT_BUDGET, DisabledCacheProofDecision, RenderCacheability, RenderObservation, RenderObservationCompleteness, RenderRequestApiKind, RenderRequestApiObservation, RenderRequestApiStatus, StaticLayoutCacheProofOutputScope, StaticLayoutReuseProof, buildBoundaryOutcomeCompatibility, buildCacheVariant, buildCacheVariantWithRouteBudget, buildRenderObservation, buildRenderRequestApiObservations, buildStaticLayoutReuseProof, classifyCacheVariantDimensionDowngrade, classifyRenderObservationDowngrade, createAppRouteCacheProofGraphScope, createDisabledCacheProofDecision, enforceCacheVariantRouteBudget, hasCompleteNegativeRequestApiProof };
200
319
  //# sourceMappingURL=cache-proof.d.ts.map