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
@@ -0,0 +1,111 @@
1
+ import { isUnknownRecord } from "./record.js";
2
+ //#region src/utils/cache-life-profiles.ts
3
+ /** Next.js's built-in profiles (`defaultConfig.cacheLife` in config-shared.ts). */
4
+ const BUILT_IN_CACHE_LIFE_PROFILES = {
5
+ default: {
6
+ revalidate: 900,
7
+ expire: 4294967294
8
+ },
9
+ seconds: {
10
+ stale: 30,
11
+ revalidate: 1,
12
+ expire: 60
13
+ },
14
+ minutes: {
15
+ stale: 300,
16
+ revalidate: 60,
17
+ expire: 3600
18
+ },
19
+ hours: {
20
+ stale: 300,
21
+ revalidate: 3600,
22
+ expire: 86400
23
+ },
24
+ days: {
25
+ stale: 300,
26
+ revalidate: 86400,
27
+ expire: 604800
28
+ },
29
+ weeks: {
30
+ stale: 300,
31
+ revalidate: 604800,
32
+ expire: 2592e3
33
+ },
34
+ max: {
35
+ stale: 300,
36
+ revalidate: 2592e3,
37
+ expire: 31536e3
38
+ }
39
+ };
40
+ const CACHE_LIFE_FIELDS = [
41
+ "stale",
42
+ "revalidate",
43
+ "expire"
44
+ ];
45
+ function copyBuiltInProfiles() {
46
+ const profiles = {};
47
+ for (const [name, profile] of Object.entries(BUILT_IN_CACHE_LIFE_PROFILES)) profiles[name] = { ...profile };
48
+ return profiles;
49
+ }
50
+ /**
51
+ * Merge next.config `cacheLife` profiles over the built-ins, as Next.js does
52
+ * in `assignDefaultsAndValidate` (server/config.ts): a user profile replaces
53
+ * the built-in of the same name whole, and only `default` gets its missing
54
+ * fields filled: `stale` from `staleTimes.static`, `revalidate` from the
55
+ * built-in, `expire` from `expireTime`. That includes the built-in `default`,
56
+ * whose `stale` is unset in Next.js's defaults too. The other profiles keep
57
+ * their gaps, which the "use cache" store resolves from `default`.
58
+ *
59
+ * Next.js only schema-checks these profiles (fields must be numbers) and
60
+ * warns; `revalidate > expire` is checked for `cacheLife({...})` calls, not
61
+ * for config profiles.
62
+ */
63
+ function resolveCacheLifeProfiles(userProfiles, defaults, warn) {
64
+ const profiles = copyBuiltInProfiles();
65
+ for (const [name, rawProfile] of Object.entries(isUnknownRecord(userProfiles) ? userProfiles : {})) {
66
+ if (!isUnknownRecord(rawProfile)) {
67
+ warn(`[vinext] Invalid next.config option \`cacheLife.${name}\`: expected an object.`);
68
+ continue;
69
+ }
70
+ const profile = {};
71
+ for (const field of CACHE_LIFE_FIELDS) {
72
+ const value = rawProfile[field];
73
+ if (value === void 0) continue;
74
+ if (typeof value !== "number" || Number.isNaN(value)) {
75
+ warn(`[vinext] Invalid next.config option \`cacheLife.${name}.${field}\`: expected a number of seconds.`);
76
+ continue;
77
+ }
78
+ profile[field] = value;
79
+ }
80
+ profiles[name] = profile;
81
+ }
82
+ const defaultProfile = profiles.default;
83
+ defaultProfile.stale ??= defaults.staticStaleTime;
84
+ defaultProfile.revalidate ??= BUILT_IN_CACHE_LIFE_PROFILES.default.revalidate;
85
+ defaultProfile.expire ??= defaults.expireTime;
86
+ return profiles;
87
+ }
88
+ function encodeNonFiniteNumber(_key, value) {
89
+ return value === Infinity || value === -Infinity ? String(value) : value;
90
+ }
91
+ function decodeNonFiniteNumber(_key, value) {
92
+ return value === "Infinity" || value === "-Infinity" ? Number(value) : value;
93
+ }
94
+ /** Serialize resolved profiles for the `__VINEXT_CACHE_LIFE_PROFILES` define. */
95
+ function serializeCacheLifeProfiles(profiles) {
96
+ return JSON.stringify(profiles, encodeNonFiniteNumber);
97
+ }
98
+ /**
99
+ * Read the `__VINEXT_CACHE_LIFE_PROFILES` define. When absent, the profiles a
100
+ * next.config without `cacheLife` resolves to.
101
+ */
102
+ function parseCacheLifeProfiles(serialized) {
103
+ if (!serialized) {
104
+ const profiles = copyBuiltInProfiles();
105
+ profiles.default.stale = 300;
106
+ return profiles;
107
+ }
108
+ return JSON.parse(serialized, decodeNonFiniteNumber);
109
+ }
110
+ //#endregion
111
+ export { BUILT_IN_CACHE_LIFE_PROFILES, parseCacheLifeProfiles, resolveCacheLifeProfiles, serializeCacheLifeProfiles };
@@ -7,7 +7,17 @@ type MiddlewareHeaderSource = Headers | Record<string, MiddlewareHeaderValue>;
7
7
  * under their literal protocol-header names on both the request and response.
8
8
  */
9
9
  export declare function getUnconsumedMiddlewareRequestHeaders(source: MiddlewareHeaderSource): Map<string, string>;
10
- /** Whether middleware changed the headers seen by downstream application code. */
10
+ /**
11
+ * `baseHeaders` with only Next.js's generic merge of ordinary middleware
12
+ * response headers applied, without the request-header protocol.
13
+ */
14
+ export declare function applyMiddlewareResponseHeadersToRequest(baseHeaders: Headers, middlewareHeaders: MiddlewareHeaderSource): Headers;
15
+ /**
16
+ * Whether middleware changed the headers seen by downstream application code
17
+ * through its request-header protocol. Ordinary response headers are copied to
18
+ * the request as well, but like a client's own headers they do not opt a
19
+ * render out of the shared response stage.
20
+ */
11
21
  export declare function hasMiddlewareRequestHeaderOverrides(source: MiddlewareHeaderSource | null): boolean;
12
22
  export declare function encodeMiddlewareRequestHeaders(targetHeaders: Headers, requestHeaders: Headers): void;
13
23
  /**
@@ -16,8 +26,9 @@ export declare function encodeMiddlewareRequestHeaders(targetHeaders: Headers, r
16
26
  * middleware. Never re-add absent headers from the base request — that would
17
27
  * resurrect credentials the app explicitly stripped before an external
18
28
  * rewrite. Next.js treats the empty value emitted for `new Headers()` as no
19
- * override. Any unconsumed `x-middleware-request-*` values are subsequently
20
- * copied to the request under their literal protocol-header names.
29
+ * override. Any unconsumed `x-middleware-request-*` values and every other
30
+ * truthy middleware response header are subsequently copied to the request
31
+ * under their literal names, replacing values the client sent.
21
32
  */
22
33
  export declare function buildRequestHeadersFromMiddlewareResponse(baseHeaders: Headers, middlewareHeaders: MiddlewareHeaderSource): Headers | null;
23
34
  export declare function shouldKeepMiddlewareHeader(key: string): boolean;
@@ -34,7 +34,52 @@ function getUnconsumedMiddlewareRequestHeaders(source) {
34
34
  for (const [key, value] of getForwardedRequestHeaders(source)) if (value && !overriddenHeaders?.has(key)) unconsumedHeaders.set(`${MIDDLEWARE_REQUEST_HEADER_PREFIX}${key}`, value);
35
35
  return unconsumedHeaders;
36
36
  }
37
- /** Whether middleware changed the headers seen by downstream application code. */
37
+ const UNMERGED_MIDDLEWARE_RESPONSE_HEADERS = /* @__PURE__ */ new Set([
38
+ "accept-encoding",
39
+ "connection",
40
+ "content-encoding",
41
+ "content-length",
42
+ "expect",
43
+ "keep-alive",
44
+ "keepalive",
45
+ "transfer-encoding"
46
+ ]);
47
+ /**
48
+ * Return the truthy ordinary middleware response headers. Next.js's generic
49
+ * middleware-header merge writes each of them to the request too, so a value
50
+ * middleware sets replaces one the client sent under the same name. The
51
+ * `x-middleware-*` namespace carries vinext's middleware protocol and is
52
+ * handled separately.
53
+ */
54
+ function getMergedMiddlewareResponseHeaders(source) {
55
+ const mergedHeaders = new Headers();
56
+ const entries = source instanceof Headers ? source : Object.entries(source).flatMap(([key, value]) => Array.isArray(value) ? value.map((item) => [key, item]) : [[key, value]]);
57
+ for (const [key, value] of entries) {
58
+ const lowerKey = key.toLowerCase();
59
+ if (value && !lowerKey.startsWith("x-middleware-") && !UNMERGED_MIDDLEWARE_RESPONSE_HEADERS.has(lowerKey)) mergedHeaders.append(lowerKey, value);
60
+ }
61
+ return mergedHeaders;
62
+ }
63
+ function applyMergedMiddlewareHeaders(targetHeaders, unconsumedHeaders, mergedHeaders) {
64
+ for (const [key, value] of unconsumedHeaders) targetHeaders.set(key, value);
65
+ for (const key of new Set(mergedHeaders.keys())) targetHeaders.delete(key);
66
+ for (const [key, value] of mergedHeaders) targetHeaders.append(key, value);
67
+ }
68
+ /**
69
+ * `baseHeaders` with only Next.js's generic merge of ordinary middleware
70
+ * response headers applied, without the request-header protocol.
71
+ */
72
+ function applyMiddlewareResponseHeadersToRequest(baseHeaders, middlewareHeaders) {
73
+ const nextHeaders = new Headers(baseHeaders);
74
+ applyMergedMiddlewareHeaders(nextHeaders, /* @__PURE__ */ new Map(), getMergedMiddlewareResponseHeaders(middlewareHeaders));
75
+ return nextHeaders;
76
+ }
77
+ /**
78
+ * Whether middleware changed the headers seen by downstream application code
79
+ * through its request-header protocol. Ordinary response headers are copied to
80
+ * the request as well, but like a client's own headers they do not opt a
81
+ * render out of the shared response stage.
82
+ */
38
83
  function hasMiddlewareRequestHeaderOverrides(source) {
39
84
  if (!source) return false;
40
85
  return Boolean(getMiddlewareHeaderValue(source, "x-middleware-override-headers")) || getUnconsumedMiddlewareRequestHeaders(source).size > 0;
@@ -50,17 +95,19 @@ function encodeMiddlewareRequestHeaders(targetHeaders, requestHeaders) {
50
95
  * middleware. Never re-add absent headers from the base request — that would
51
96
  * resurrect credentials the app explicitly stripped before an external
52
97
  * rewrite. Next.js treats the empty value emitted for `new Headers()` as no
53
- * override. Any unconsumed `x-middleware-request-*` values are subsequently
54
- * copied to the request under their literal protocol-header names.
98
+ * override. Any unconsumed `x-middleware-request-*` values and every other
99
+ * truthy middleware response header are subsequently copied to the request
100
+ * under their literal names, replacing values the client sent.
55
101
  */
56
102
  function buildRequestHeadersFromMiddlewareResponse(baseHeaders, middlewareHeaders) {
57
103
  const forwardedHeaders = getForwardedRequestHeaders(middlewareHeaders);
58
104
  const unconsumedHeaders = getUnconsumedMiddlewareRequestHeaders(middlewareHeaders);
105
+ const mergedHeaders = getMergedMiddlewareResponseHeaders(middlewareHeaders);
59
106
  const rawOverrideHeader = getMiddlewareHeaderValue(middlewareHeaders, MIDDLEWARE_OVERRIDE_HEADERS);
60
107
  if (!rawOverrideHeader) {
61
- if (unconsumedHeaders.size === 0) return null;
108
+ if (unconsumedHeaders.size === 0 && mergedHeaders.keys().next().done) return null;
62
109
  const nextHeaders = new Headers(baseHeaders);
63
- for (const [key, value] of unconsumedHeaders) nextHeaders.set(key, value);
110
+ applyMergedMiddlewareHeaders(nextHeaders, unconsumedHeaders, mergedHeaders);
64
111
  return nextHeaders;
65
112
  }
66
113
  const overrideHeaderNames = parseOverrideHeaderNames(rawOverrideHeader);
@@ -69,11 +116,11 @@ function buildRequestHeadersFromMiddlewareResponse(baseHeaders, middlewareHeader
69
116
  const value = forwardedHeaders.get(key);
70
117
  if (value !== void 0) nextHeaders.set(key, value);
71
118
  }
72
- for (const [key, value] of unconsumedHeaders) nextHeaders.set(key, value);
119
+ applyMergedMiddlewareHeaders(nextHeaders, unconsumedHeaders, mergedHeaders);
73
120
  return nextHeaders;
74
121
  }
75
122
  function shouldKeepMiddlewareHeader(key) {
76
123
  return key === "x-middleware-override-headers" || key === "x-middleware-cache" || key === "x-middleware-set-cookie" || key.startsWith("x-middleware-request-");
77
124
  }
78
125
  //#endregion
79
- export { buildRequestHeadersFromMiddlewareResponse, encodeMiddlewareRequestHeaders, getUnconsumedMiddlewareRequestHeaders, hasMiddlewareRequestHeaderOverrides, shouldKeepMiddlewareHeader };
126
+ export { applyMiddlewareResponseHeadersToRequest, buildRequestHeadersFromMiddlewareResponse, encodeMiddlewareRequestHeaders, getUnconsumedMiddlewareRequestHeaders, hasMiddlewareRequestHeaderOverrides, shouldKeepMiddlewareHeader };
@@ -58,6 +58,8 @@ export declare function findViteConfigPath(root: string): string | undefined;
58
58
  export declare function formatMissingCloudflarePluginError(options: {
59
59
  isAppRouter: boolean;
60
60
  configFile?: string;
61
+ /** False when configFile is not the root vite.config.* that `vinext init` updates. */
62
+ initUpdatesConfig?: boolean;
61
63
  }): string;
62
64
  export type ProjectInfo = {
63
65
  root: string;
@@ -78,8 +80,6 @@ export type ProjectInfo = {
78
80
  hasMDX: boolean;
79
81
  /** CodeHike is a dependency */
80
82
  hasCodeHike: boolean;
81
- /** Native Node modules that need stubbing for Workers */
82
- nativeModulesToStub: string[];
83
83
  };
84
84
  /** Check whether a wrangler config file exists in the given directory. */
85
85
  export declare function hasWranglerConfig(root: string): boolean;
@@ -196,7 +196,7 @@ function findViteConfigPath(root) {
196
196
  function formatMissingCloudflarePluginError(options) {
197
197
  const cfArg = options.isAppRouter ? "{\n viteEnvironment: { name: \"rsc\", childEnvironments: [\"ssr\"] },\n }" : "";
198
198
  const configRef = options.configFile ? options.configFile : "your Vite config";
199
- return `[vinext] Missing @cloudflare/vite-plugin in ${configRef}.\n\n Cloudflare Workers builds require the cloudflare() plugin.\n Run \`vinext init --platform=cloudflare\` to update ${configRef}.\n\n Expected plugin shape:\n\n cloudflare(${cfArg})`;
199
+ return `[vinext] Missing @cloudflare/vite-plugin in ${configRef}.\n\n Cloudflare Workers builds require the cloudflare() plugin.\n ${options.initUpdatesConfig === false ? `Add it to ${configRef}.` : `Run \`vinext init --platform=cloudflare\` to update ${configRef}.`}\n\n Expected plugin shape:\n\n cloudflare(${cfArg})`;
200
200
  }
201
201
  /** Check whether a wrangler config file exists in the given directory. */
202
202
  function hasWranglerConfig(root) {
@@ -251,12 +251,10 @@ function detectProject(root) {
251
251
  }
252
252
  }
253
253
  hasISR = hasISR || detectCacheComponents(root);
254
- const allDeps = {
254
+ const hasCodeHike = "codehike" in {
255
255
  ...pkg?.dependencies,
256
256
  ...pkg?.devDependencies
257
257
  };
258
- const hasCodeHike = "codehike" in allDeps;
259
- const nativeModulesToStub = detectNativeModules(allDeps);
260
258
  return {
261
259
  root,
262
260
  isAppRouter,
@@ -271,8 +269,7 @@ function detectProject(root) {
271
269
  hasISR,
272
270
  hasTypeModule,
273
271
  hasMDX,
274
- hasCodeHike,
275
- nativeModulesToStub
272
+ hasCodeHike
276
273
  };
277
274
  }
278
275
  const ISR_PATTERN = /export\s+(?:const\s+revalidate\s*=|(?:async\s+)?function\s+getStaticProps\b|const\s+getStaticProps\s*=|\{[^}]*\bgetStaticProps\b[^}]*\})/;
@@ -357,16 +354,6 @@ function detectCacheComponents(root) {
357
354
  }
358
355
  return false;
359
356
  }
360
- const NATIVE_MODULES_TO_STUB = [
361
- "@resvg/resvg-js",
362
- "satori",
363
- "lightningcss",
364
- "@napi-rs/canvas",
365
- "sharp"
366
- ];
367
- function detectNativeModules(allDeps) {
368
- return NATIVE_MODULES_TO_STUB.filter((mod) => mod in allDeps);
369
- }
370
357
  /**
371
358
  * Check if a package is resolvable from a given root directory using Node's
372
359
  * module resolution. Handles hoisting, pnpm symlinks, monorepos, and Yarn PnP.
@@ -1,3 +1,8 @@
1
1
  //#region src/utils/regex.d.ts
2
2
  export declare function escapeRegExp(value: string): string;
3
+ /**
4
+ * Return the literal a RegExp matches when it is just `^literal$` (as built
5
+ * from `escapeRegExp`), or null for any other pattern.
6
+ */
7
+ export declare function exactRegExpLiteral(pattern: RegExp): string | null;
3
8
  //#endregion
@@ -2,5 +2,15 @@
2
2
  function escapeRegExp(value) {
3
3
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
4
4
  }
5
+ const EXACT_REGEXP_SOURCE_RE = /^\^((?:\\[.*+?^${}()|[\]\\/]|[^.*+?^${}()|[\]\\])*)\$$/;
6
+ /**
7
+ * Return the literal a RegExp matches when it is just `^literal$` (as built
8
+ * from `escapeRegExp`), or null for any other pattern.
9
+ */
10
+ function exactRegExpLiteral(pattern) {
11
+ if (pattern.flags !== "") return null;
12
+ const body = EXACT_REGEXP_SOURCE_RE.exec(pattern.source)?.[1];
13
+ return body === void 0 ? null : body.replace(/\\(.)/g, "$1");
14
+ }
5
15
  //#endregion
6
- export { escapeRegExp };
16
+ export { escapeRegExp, exactRegExpLiteral };
@@ -15,13 +15,18 @@
15
15
  */
16
16
  export declare function readStreamAsText(stream: ReadableStream<Uint8Array>): Promise<string>;
17
17
  /**
18
- * Drain a UTF-8 byte stream up to `maxBytes` of *raw* input, returning the
19
- * decoded text. If the raw size limit is exceeded, cancellation is signalled
20
- * and `onLimitExceeded` is invoked; it MUST throw — its return type is
21
- * `never` to enforce that. Each caller passes its own error type.
18
+ * Drain a byte stream up to `maxBytes` of *raw* input, returning the decoded
19
+ * text (UTF-8 unless the caller passes its own `decoder`). If the raw size
20
+ * limit is exceeded, cancellation is signalled and `onLimitExceeded` is
21
+ * invoked; it MUST throw — its return type is `never` to enforce that. Each
22
+ * caller passes its own error type.
22
23
  *
23
24
  * The size check is on raw bytes (pre-decode) to bound memory before
24
25
  * paying the decoder cost.
25
26
  */
26
- export declare function readStreamAsTextWithLimit(stream: ReadableStream<Uint8Array>, maxBytes: number, onLimitExceeded: () => never): Promise<string>;
27
+ export declare function readStreamAsTextWithLimit(stream: ReadableStream<Uint8Array>, maxBytes: number, onLimitExceeded: () => never, decoder?: {
28
+ decode(input?: Uint8Array, options?: {
29
+ stream?: boolean;
30
+ }): string;
31
+ }): Promise<string>;
27
32
  //#endregion
@@ -30,17 +30,17 @@ async function readStreamAsText(stream) {
30
30
  }
31
31
  }
32
32
  /**
33
- * Drain a UTF-8 byte stream up to `maxBytes` of *raw* input, returning the
34
- * decoded text. If the raw size limit is exceeded, cancellation is signalled
35
- * and `onLimitExceeded` is invoked; it MUST throw — its return type is
36
- * `never` to enforce that. Each caller passes its own error type.
33
+ * Drain a byte stream up to `maxBytes` of *raw* input, returning the decoded
34
+ * text (UTF-8 unless the caller passes its own `decoder`). If the raw size
35
+ * limit is exceeded, cancellation is signalled and `onLimitExceeded` is
36
+ * invoked; it MUST throw — its return type is `never` to enforce that. Each
37
+ * caller passes its own error type.
37
38
  *
38
39
  * The size check is on raw bytes (pre-decode) to bound memory before
39
40
  * paying the decoder cost.
40
41
  */
41
- async function readStreamAsTextWithLimit(stream, maxBytes, onLimitExceeded) {
42
+ async function readStreamAsTextWithLimit(stream, maxBytes, onLimitExceeded, decoder = new TextDecoder()) {
42
43
  const reader = stream.getReader();
43
- const decoder = new TextDecoder();
44
44
  const chunks = [];
45
45
  let totalSize = 0;
46
46
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vinext",
3
- "version": "1.3.1",
3
+ "version": "1.4.1",
4
4
  "description": "Run Next.js apps on Vite. Drop-in replacement for the next CLI.",
5
5
  "homepage": "https://vinext.dev/",
6
6
  "license": "MIT",
@@ -240,6 +240,7 @@
240
240
  "@vitejs/plugin-react": "^6.1.0",
241
241
  "@vitejs/plugin-rsc": "^0.5.38",
242
242
  "am-i-vibing": "^0.5.0",
243
+ "iconv-lite": "0.4.24",
243
244
  "ignore": "5.3.2",
244
245
  "image-size": "2.0.4",
245
246
  "pathslash": "^0.1.0",
@@ -1,60 +0,0 @@
1
- //#region src/build/layout-classification-types.d.ts
2
- /**
3
- * Shared types for the layout classification pipeline.
4
- *
5
- * Kept in a leaf module so both `report.ts` (which implements segment-config
6
- * classification) and `layout-classification.ts` (which composes the full
7
- * pipeline) can import them without forming a cycle.
8
- *
9
- * The wire contract between build and runtime is intentionally narrow: the
10
- * runtime only cares about the `"static" | "dynamic"` decision for a layout.
11
- * Reasons live in a sidecar structure so operators can trace how each
12
- * decision was made without bloating the hot-path payload.
13
- */
14
- /**
15
- * Structured record of which classifier layer produced a decision and what
16
- * evidence it used. Kept as a discriminated union so each layer can carry
17
- * its own diagnostic shape without the consumer having to fall back to
18
- * stringly-typed `reason` fields.
19
- */
20
- export type ClassificationReason = {
21
- layer: "segment-config";
22
- key: "dynamic" | "revalidate";
23
- value: string | number;
24
- } | {
25
- layer: "module-graph";
26
- result: "static" | "needs-probe";
27
- firstShimMatch?: string;
28
- } | {
29
- layer: "runtime-probe";
30
- outcome: "static" | "dynamic";
31
- error?: string;
32
- } | {
33
- layer: "no-classifier";
34
- };
35
- export type ModuleGraphStaticReason = {
36
- layer: "module-graph";
37
- result: "static";
38
- firstShimMatch?: string;
39
- };
40
- /**
41
- * Build-time classification outcome for a single layout. Tagged with `kind`
42
- * so callers can branch exhaustively and carry diagnostic reasons alongside
43
- * the decision.
44
- *
45
- * `absent` means no classifier layer had anything to say — the caller should
46
- * defer to the next layer (or to the runtime probe).
47
- */
48
- export type LayoutBuildClassification = {
49
- kind: "absent";
50
- } | {
51
- kind: "static";
52
- reason: ClassificationReason;
53
- } | {
54
- kind: "dynamic";
55
- reason: ClassificationReason;
56
- } | {
57
- kind: "needs-probe";
58
- reason: ClassificationReason;
59
- };
60
- //#endregion
@@ -1 +0,0 @@
1
- export {};
@@ -1,62 +0,0 @@
1
- import { ClassificationReason, LayoutBuildClassification, ModuleGraphStaticReason } from "./layout-classification-types.js";
2
- //#region src/build/layout-classification.d.ts
3
- type ModuleGraphClassification = "static" | "needs-probe";
4
- type ModuleGraphClassificationResult = {
5
- result: ModuleGraphClassification;
6
- /** First dynamic shim module ID encountered during BFS, when any. */
7
- firstShimMatch?: string;
8
- };
9
- export type ModuleInfoProvider = {
10
- getModuleInfo(id: string): {
11
- importedIds: string[];
12
- dynamicImportedIds: string[];
13
- } | null;
14
- };
15
- type LayoutEntry = {
16
- /** Rollup/Vite module ID for the layout file. */
17
- moduleId: string;
18
- /** Directory depth from the app root, used to build the stable layout ID. */
19
- treePosition: number;
20
- /** Segment config source code extracted at build time, or null when absent. */
21
- segmentConfig?: {
22
- code: string;
23
- } | null;
24
- };
25
- type RouteForClassification = {
26
- layouts: readonly LayoutEntry[];
27
- routeSegments: string[];
28
- };
29
- /**
30
- * BFS traversal of a layout's dependency tree. If any transitive import
31
- * resolves to a dynamic shim path (headers, cache, server), the layout
32
- * cannot be proven static at build time and needs a runtime probe.
33
- *
34
- * The returned object carries the classification plus the first matching
35
- * shim module ID (when any). Operators use the shim ID via the debug
36
- * channel to trace why a layout was flagged for probing.
37
- */
38
- export declare function classifyLayoutByModuleGraph(layoutModuleId: string, dynamicShimPaths: ReadonlySet<string>, moduleInfo: ModuleInfoProvider): ModuleGraphClassificationResult;
39
- export declare function moduleGraphReason(graphResult: ModuleGraphClassificationResult & {
40
- result: "static";
41
- }): ModuleGraphStaticReason;
42
- export declare function moduleGraphReason(graphResult: ModuleGraphClassificationResult): ClassificationReason;
43
- export declare function isStaticModuleGraphResult(graphResult: ModuleGraphClassificationResult): graphResult is ModuleGraphClassificationResult & {
44
- result: "static";
45
- };
46
- /**
47
- * Classifies all layouts across all routes using a two-layer strategy:
48
- *
49
- * 1. Segment config (Layer 1) — short-circuits to "static" or "dynamic"
50
- * 2. Module graph (Layer 2) — BFS for dynamic shim imports → "static" or "needs-probe"
51
- *
52
- * Shared layouts (same file appearing in multiple routes) are classified once
53
- * and deduplicated by layout ID.
54
- *
55
- * @internal Not called by production code. The `renderChunk` hook in
56
- * `index.ts` calls `classifyLayoutByModuleGraph` directly and composes
57
- * via the numeric-index manifest in `route-classification-manifest.ts`.
58
- * Used only by `tests/layout-classification.test.ts`.
59
- */
60
- export declare function classifyAllRouteLayouts(routes: readonly RouteForClassification[], dynamicShimPaths: ReadonlySet<string>, moduleInfo: ModuleInfoProvider): Map<string, LayoutBuildClassification>;
61
- //#endregion
62
- export {};
@@ -1,98 +0,0 @@
1
- import { classifyLayoutSegmentConfig } from "./report.js";
2
- import { AppElementsWire } from "../server/app-elements-wire.js";
3
- import "../server/app-elements.js";
4
- import { createAppPageTreePath } from "../server/app-page-route-wiring.js";
5
- //#region src/build/layout-classification.ts
6
- /**
7
- * Layout classification — determines whether each layout in an App Router
8
- * route tree is static or dynamic via two complementary detection layers:
9
- *
10
- * Layer 1: Segment config (`export const dynamic`, `export const revalidate`)
11
- * Layer 2: Module graph traversal (checks for transitive dynamic shim imports)
12
- *
13
- * Layer 3 (probe-based runtime detection) is handled separately in
14
- * `app-page-execution.ts` at request time.
15
- *
16
- * Every result is carried as a `LayoutBuildClassification` tagged variant so
17
- * operators can trace which layer produced a decision via the structured
18
- * `ClassificationReason` sidecar without that metadata leaking onto the wire.
19
- */
20
- /**
21
- * BFS traversal of a layout's dependency tree. If any transitive import
22
- * resolves to a dynamic shim path (headers, cache, server), the layout
23
- * cannot be proven static at build time and needs a runtime probe.
24
- *
25
- * The returned object carries the classification plus the first matching
26
- * shim module ID (when any). Operators use the shim ID via the debug
27
- * channel to trace why a layout was flagged for probing.
28
- */
29
- function classifyLayoutByModuleGraph(layoutModuleId, dynamicShimPaths, moduleInfo) {
30
- const visited = /* @__PURE__ */ new Set();
31
- const queue = [layoutModuleId];
32
- let head = 0;
33
- while (head < queue.length) {
34
- const currentId = queue[head++];
35
- if (visited.has(currentId)) continue;
36
- visited.add(currentId);
37
- if (dynamicShimPaths.has(currentId)) return {
38
- result: "needs-probe",
39
- firstShimMatch: currentId
40
- };
41
- const info = moduleInfo.getModuleInfo(currentId);
42
- if (!info) continue;
43
- for (const importedId of info.importedIds) if (!visited.has(importedId)) queue.push(importedId);
44
- for (const dynamicId of info.dynamicImportedIds) if (!visited.has(dynamicId)) queue.push(dynamicId);
45
- }
46
- return { result: "static" };
47
- }
48
- function moduleGraphReason(graphResult) {
49
- if (graphResult.firstShimMatch === void 0) return {
50
- layer: "module-graph",
51
- result: graphResult.result
52
- };
53
- return {
54
- layer: "module-graph",
55
- result: graphResult.result,
56
- firstShimMatch: graphResult.firstShimMatch
57
- };
58
- }
59
- function isStaticModuleGraphResult(graphResult) {
60
- return graphResult.result === "static";
61
- }
62
- /**
63
- * Classifies all layouts across all routes using a two-layer strategy:
64
- *
65
- * 1. Segment config (Layer 1) — short-circuits to "static" or "dynamic"
66
- * 2. Module graph (Layer 2) — BFS for dynamic shim imports → "static" or "needs-probe"
67
- *
68
- * Shared layouts (same file appearing in multiple routes) are classified once
69
- * and deduplicated by layout ID.
70
- *
71
- * @internal Not called by production code. The `renderChunk` hook in
72
- * `index.ts` calls `classifyLayoutByModuleGraph` directly and composes
73
- * via the numeric-index manifest in `route-classification-manifest.ts`.
74
- * Used only by `tests/layout-classification.test.ts`.
75
- */
76
- function classifyAllRouteLayouts(routes, dynamicShimPaths, moduleInfo) {
77
- const result = /* @__PURE__ */ new Map();
78
- for (const route of routes) for (const layout of route.layouts) {
79
- const layoutId = AppElementsWire.encodeLayoutId(createAppPageTreePath(route.routeSegments, layout.treePosition));
80
- if (result.has(layoutId)) continue;
81
- if (layout.segmentConfig) {
82
- const configResult = classifyLayoutSegmentConfig(layout.segmentConfig.code);
83
- if (configResult.kind !== "absent") {
84
- result.set(layoutId, configResult);
85
- continue;
86
- }
87
- }
88
- const graphResult = classifyLayoutByModuleGraph(layout.moduleId, dynamicShimPaths, moduleInfo);
89
- const reason = moduleGraphReason(graphResult);
90
- result.set(layoutId, {
91
- kind: graphResult.result,
92
- reason
93
- });
94
- }
95
- return result;
96
- }
97
- //#endregion
98
- export { classifyAllRouteLayouts, classifyLayoutByModuleGraph, isStaticModuleGraphResult, moduleGraphReason };
@@ -1,33 +0,0 @@
1
- import { ModuleInfoProvider } from "./layout-classification.js";
2
- import { RouteClassificationManifest } from "./route-classification-manifest.js";
3
- //#region src/build/route-classification-injector.d.ts
4
- /**
5
- * Build-time route classification injection.
6
- *
7
- * Codegen describes route shape by emitting stable `__VINEXT_CLASS` stubs and
8
- * per-route call sites. This module owns the behavioral side of replacing
9
- * those stubs with build-time decisions once the final RSC module graph exists.
10
- */
11
- type RouteClassificationChunk = {
12
- code: string;
13
- fileName: string;
14
- };
15
- type RouteClassificationInjectionPlan = {
16
- kind: "skip";
17
- } | {
18
- code: string;
19
- fileName: string;
20
- kind: "patch";
21
- map: null;
22
- };
23
- type PlanRouteClassificationInjectionOptions = {
24
- canonicalizeLayoutPath?: (path: string) => string;
25
- chunks: readonly RouteClassificationChunk[];
26
- dynamicShimPaths: ReadonlySet<string>;
27
- enableDebugReasons: boolean;
28
- manifest: RouteClassificationManifest;
29
- moduleInfo: ModuleInfoProvider;
30
- };
31
- export declare function planRouteClassificationInjection(options: PlanRouteClassificationInjectionOptions): RouteClassificationInjectionPlan;
32
- //#endregion
33
- export {};