@wular/pnext 0.1.5 → 0.1.7

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 (302) hide show
  1. package/bin/pnext +9 -2
  2. package/dist/server/_chunks/aliases-j47a10ce.js +44 -0
  3. package/dist/server/_chunks/analyze-arswqe6s.js +445 -0
  4. package/dist/server/_chunks/boot-af0mv3dy.js +36 -0
  5. package/dist/server/_chunks/build-spy3dxp4.js +84 -0
  6. package/dist/server/_chunks/build-t9h0hec3.js +3550 -0
  7. package/dist/server/_chunks/build-tier-m7yvqz61.js +2472 -0
  8. package/dist/server/_chunks/compile-53j02j27.js +22 -0
  9. package/dist/server/_chunks/config-1yzwexq6.js +27 -0
  10. package/dist/server/_chunks/config-n2z7yxps.js +22 -0
  11. package/dist/server/_chunks/create-meec9hs6.js +134 -0
  12. package/dist/server/_chunks/dev-fjmqg6en.js +220 -0
  13. package/dist/server/_chunks/esbuild-yyktfrtt.js +15 -0
  14. package/dist/server/_chunks/generate-n9sh6hzt.js +21 -0
  15. package/dist/server/_chunks/index-0374j2b9.js +66 -0
  16. package/dist/server/_chunks/index-06nyqntx.js +213 -0
  17. package/dist/server/_chunks/index-1011cscr.js +5263 -0
  18. package/dist/server/_chunks/index-11sfk4hb.js +170 -0
  19. package/dist/server/_chunks/index-20ppawv7.js +297 -0
  20. package/dist/server/_chunks/index-2dv4y4wd.js +1065 -0
  21. package/dist/server/_chunks/index-2vz0wzdn.js +59 -0
  22. package/dist/server/_chunks/index-2wfv4kvx.js +182 -0
  23. package/dist/server/_chunks/index-357na4a8.js +109 -0
  24. package/dist/server/_chunks/index-3b3at80h.js +109 -0
  25. package/dist/server/_chunks/index-3tf1xjsp.js +6166 -0
  26. package/dist/server/_chunks/index-3xbr4eyv.js +105 -0
  27. package/dist/server/_chunks/index-4399bvd2.js +18 -0
  28. package/dist/server/_chunks/index-4hgjrqh7.js +851 -0
  29. package/dist/server/_chunks/index-4q2gbfwk.js +2530 -0
  30. package/dist/server/_chunks/index-4t92hdxd.js +172 -0
  31. package/dist/server/_chunks/index-4zzebszd.js +10 -0
  32. package/dist/server/_chunks/index-5gyr4emz.js +107 -0
  33. package/dist/server/_chunks/index-5hr4062s.js +70 -0
  34. package/dist/server/_chunks/index-68m3mwbd.js +84 -0
  35. package/dist/server/_chunks/index-6b009mt0.js +56 -0
  36. package/dist/server/_chunks/index-6e4fqv30.js +588 -0
  37. package/dist/server/_chunks/index-6gex3pfa.js +15 -0
  38. package/dist/server/_chunks/index-6kp9r0d9.js +11 -0
  39. package/dist/server/_chunks/index-6q7zvrap.js +134 -0
  40. package/dist/server/_chunks/index-73z4esab.js +38 -0
  41. package/dist/server/_chunks/index-79ngvam8.js +60 -0
  42. package/dist/server/_chunks/index-7wc9n8be.js +25 -0
  43. package/dist/server/_chunks/index-8k7pfejn.js +1599 -0
  44. package/dist/server/_chunks/index-8kcxdfya.js +206 -0
  45. package/dist/server/_chunks/index-91x12ykq.js +274 -0
  46. package/dist/server/_chunks/index-9ch50vtq.js +18 -0
  47. package/dist/server/_chunks/index-9hx2641q.js +28 -0
  48. package/dist/server/_chunks/index-9n2914ww.js +535 -0
  49. package/dist/server/_chunks/index-9ych9ma8.js +207 -0
  50. package/dist/server/_chunks/index-b6wtkdp4.js +24 -0
  51. package/dist/server/_chunks/index-bcws5eh2.js +35 -0
  52. package/dist/server/_chunks/index-c0g2wf3z.js +92 -0
  53. package/dist/server/_chunks/index-cf4rvxv6.js +95 -0
  54. package/dist/server/_chunks/index-cjgqs13g.js +65 -0
  55. package/dist/server/_chunks/index-ckkdpht5.js +41 -0
  56. package/dist/server/_chunks/index-cyfednwb.js +87 -0
  57. package/dist/server/_chunks/index-danncfhy.js +311 -0
  58. package/dist/server/_chunks/index-dg0f05zs.js +199 -0
  59. package/dist/server/_chunks/index-e3a6yx84.js +18 -0
  60. package/dist/server/_chunks/index-e88tyv35.js +45 -0
  61. package/dist/server/_chunks/index-eajaspjk.js +1253 -0
  62. package/dist/server/_chunks/index-eeaanp2e.js +483 -0
  63. package/dist/server/_chunks/index-egykcqg3.js +101 -0
  64. package/dist/server/_chunks/index-en7n9f7m.js +22 -0
  65. package/dist/server/_chunks/index-ezgj0tr1.js +88 -0
  66. package/dist/server/_chunks/index-fkp000p1.js +590 -0
  67. package/dist/server/_chunks/index-fn1chkkd.js +214 -0
  68. package/dist/server/_chunks/index-fp8r0sqs.js +64 -0
  69. package/dist/server/_chunks/index-ggk2j965.js +9432 -0
  70. package/dist/server/_chunks/index-grta8ap3.js +238 -0
  71. package/dist/server/_chunks/index-h2a70tg4.js +7 -0
  72. package/dist/server/_chunks/index-h4xy648y.js +51 -0
  73. package/dist/server/_chunks/index-hkdfj58q.js +92 -0
  74. package/dist/server/_chunks/index-j2zrcp1k.js +66 -0
  75. package/dist/server/_chunks/index-jcsjq3d1.js +20 -0
  76. package/dist/server/_chunks/index-jepjvcrf.js +198 -0
  77. package/dist/server/_chunks/index-jks0x0a1.js +14 -0
  78. package/dist/server/_chunks/index-jx7bqvw1.js +57 -0
  79. package/dist/server/_chunks/index-k1g3epw0.js +1299 -0
  80. package/dist/server/_chunks/index-knp0s912.js +7 -0
  81. package/dist/server/_chunks/index-kq8kpzye.js +472 -0
  82. package/dist/server/_chunks/index-kqyy1d4f.js +50 -0
  83. package/dist/server/_chunks/index-kresp2n8.js +445 -0
  84. package/dist/server/_chunks/index-ms9v9tnx.js +31 -0
  85. package/dist/server/_chunks/index-n4hxpng2.js +11 -0
  86. package/dist/server/_chunks/index-ncnes8c6.js +17 -0
  87. package/dist/server/_chunks/index-nqh3xhdc.js +57 -0
  88. package/dist/server/_chunks/index-nyrba2kr.js +4130 -0
  89. package/dist/server/_chunks/index-p77b4kcx.js +296 -0
  90. package/dist/server/_chunks/index-pym1cezq.js +39 -0
  91. package/dist/server/_chunks/index-q738kkhj.js +100 -0
  92. package/dist/server/_chunks/index-qjj6gddn.js +54 -0
  93. package/dist/server/_chunks/index-qm6kmhqs.js +110 -0
  94. package/dist/server/_chunks/index-qn4z5s3c.js +819 -0
  95. package/dist/server/_chunks/index-qpwsgt3a.js +158 -0
  96. package/dist/server/_chunks/index-r97ptz1q.js +97 -0
  97. package/dist/server/_chunks/index-ras0sdab.js +26 -0
  98. package/dist/server/_chunks/index-rcs322t1.js +19 -0
  99. package/dist/server/_chunks/index-rn8dyr1f.js +126 -0
  100. package/dist/server/_chunks/index-rt9qq1va.js +4 -0
  101. package/dist/server/_chunks/index-rthrsed5.js +356 -0
  102. package/dist/server/_chunks/index-sctcgyvv.js +185 -0
  103. package/dist/server/_chunks/index-sjpckxqn.js +213 -0
  104. package/dist/server/_chunks/index-sq3kvz3g.js +200 -0
  105. package/dist/server/_chunks/index-stbk3jhn.js +31 -0
  106. package/dist/server/_chunks/index-sv8m6789.js +266 -0
  107. package/dist/server/_chunks/index-tgcakdxc.js +125 -0
  108. package/dist/server/_chunks/index-tgsfjmep.js +74 -0
  109. package/dist/server/_chunks/index-tq0pc7eg.js +154 -0
  110. package/dist/server/_chunks/index-tq1f96v7.js +51 -0
  111. package/dist/server/_chunks/index-tqn2qnnn.js +241 -0
  112. package/dist/server/_chunks/index-tvqkq6e6.js +128 -0
  113. package/dist/server/_chunks/index-v1ags1na.js +132 -0
  114. package/dist/server/_chunks/index-vvmmknm1.js +1431 -0
  115. package/dist/server/_chunks/index-vvq7rqtn.js +329 -0
  116. package/dist/server/_chunks/index-vz0km5qk.js +33 -0
  117. package/dist/server/_chunks/index-w6h8m6vp.js +138 -0
  118. package/dist/server/_chunks/index-web361b8.js +138 -0
  119. package/dist/server/_chunks/index-wpfhfbs4.js +194 -0
  120. package/dist/server/_chunks/index-x0y005nh.js +283 -0
  121. package/dist/server/_chunks/index-x3yn4ywm.js +22 -0
  122. package/dist/server/_chunks/index-x93hv0sc.js +271 -0
  123. package/dist/server/_chunks/index-xvj80c3a.js +30 -0
  124. package/dist/server/_chunks/index-xywjg2vc.js +100 -0
  125. package/dist/server/_chunks/index-y2jr2n72.js +152 -0
  126. package/dist/server/_chunks/index-y36a0ybw.js +57 -0
  127. package/dist/server/_chunks/index-ye9hmsvf.js +47 -0
  128. package/dist/server/_chunks/index-yhxkxghe.js +56 -0
  129. package/dist/server/_chunks/index-ym67zqxp.js +130 -0
  130. package/dist/server/_chunks/index-ytjvpbm2.js +736 -0
  131. package/dist/server/_chunks/index-yz54pxrh.js +960 -0
  132. package/dist/server/_chunks/index-z4z9zv3b.js +733 -0
  133. package/dist/server/_chunks/index-z84ab1w0.js +1270 -0
  134. package/dist/server/_chunks/index-z88qv16t.js +11 -0
  135. package/dist/server/_chunks/index-zqpqyg8p.js +666 -0
  136. package/dist/server/_chunks/loader-7yw0j98z.js +78 -0
  137. package/dist/server/_chunks/modules-jn8bmbn8.js +74 -0
  138. package/dist/server/_chunks/pipeline-yy9jhydf.js +832 -0
  139. package/dist/server/_chunks/production-jar9ztm3.js +44 -0
  140. package/dist/server/_chunks/proxy-config-j84dgksn.js +21 -0
  141. package/dist/server/_chunks/proxy-w1d0wmsn.js +33 -0
  142. package/dist/server/_chunks/router-k1reahfn.js +498 -0
  143. package/dist/server/_chunks/routes-2s277fc6.js +64 -0
  144. package/dist/server/_chunks/run-pvd8bs1t.js +696 -0
  145. package/dist/server/_chunks/server-mt4a994c.js +1835 -0
  146. package/dist/server/_chunks/tsconfig-defaults-1nb3308g.js +20 -0
  147. package/dist/server/_chunks/typegen-0qr0459b.js +35 -0
  148. package/dist/server/api/client-cache.js +14 -0
  149. package/dist/server/cli/index.js +378 -0
  150. package/dist/server/cli/start.js +137 -0
  151. package/dist/server/client/reference.js +16 -0
  152. package/dist/server/compat/next/cache.js +56 -0
  153. package/dist/server/compat/next/canonical-url.js +13 -0
  154. package/dist/server/compat/next/client-cache.js +57 -0
  155. package/dist/server/compat/next/client-navigation.js +232 -0
  156. package/dist/server/compat/next/client-only.js +1 -0
  157. package/dist/server/compat/next/client-script.js +178 -0
  158. package/dist/server/compat/next/client-server.js +34 -0
  159. package/dist/server/compat/next/config-headers.js +32 -0
  160. package/dist/server/compat/next/config-loader.js +25 -0
  161. package/dist/server/compat/next/config.js +10 -0
  162. package/dist/server/compat/next/constants.js +18 -0
  163. package/dist/server/compat/next/custom-server.js +10 -0
  164. package/dist/server/compat/next/dist/client/components/app-router-headers.js +48 -0
  165. package/dist/server/compat/next/dist/server/web/spec-extension/revalidate.js +27 -0
  166. package/dist/server/compat/next/dist/server/web/spec-extension/unstable-cache.js +25 -0
  167. package/dist/server/compat/next/dist/server/web/spec-extension/unstable-no-store.js +25 -0
  168. package/dist/server/compat/next/dynamic.js +32 -0
  169. package/dist/server/compat/next/error.js +112 -0
  170. package/dist/server/compat/next/font/cache.js +14 -0
  171. package/dist/server/compat/next/font/google.js +3 -0
  172. package/dist/server/compat/next/font/index.js +1 -0
  173. package/dist/server/compat/next/font/local.js +22 -0
  174. package/dist/server/compat/next/font/runtime-client.js +33 -0
  175. package/dist/server/compat/next/font/runtime.js +41 -0
  176. package/dist/server/compat/next/font/shared.js +22 -0
  177. package/dist/server/compat/next/form.js +129 -0
  178. package/dist/server/compat/next/head.js +10 -0
  179. package/dist/server/compat/next/headers.js +30 -0
  180. package/dist/server/compat/next/image/client.js +11 -0
  181. package/dist/server/compat/next/image/config.js +18 -0
  182. package/dist/server/compat/next/image/optimizer.js +25 -0
  183. package/dist/server/compat/next/image/patterns.js +12 -0
  184. package/dist/server/compat/next/image/props.js +16 -0
  185. package/dist/server/compat/next/image/shared.js +86 -0
  186. package/dist/server/compat/next/image/static-metadata.js +32 -0
  187. package/dist/server/compat/next/image/validate.js +8 -0
  188. package/dist/server/compat/next/image.js +59 -0
  189. package/dist/server/compat/next/index.js +1 -0
  190. package/dist/server/compat/next/legacy-image.js +78 -0
  191. package/dist/server/compat/next/legacy-request-apis.js +24 -0
  192. package/dist/server/compat/next/link-transform.js +14 -0
  193. package/dist/server/compat/next/link.js +14 -0
  194. package/dist/server/compat/next/navigation.js +190 -0
  195. package/dist/server/compat/next/offline.js +45 -0
  196. package/dist/server/compat/next/og.js +8 -0
  197. package/dist/server/compat/next/preferred-region.js +8 -0
  198. package/dist/server/compat/next/redirects.js +30 -0
  199. package/dist/server/compat/next/resource-hints.js +30 -0
  200. package/dist/server/compat/next/rewrites.js +41 -0
  201. package/dist/server/compat/next/root-params.js +121 -0
  202. package/dist/server/compat/next/route-state.js +23 -0
  203. package/dist/server/compat/next/router.js +103 -0
  204. package/dist/server/compat/next/script.js +37 -0
  205. package/dist/server/compat/next/server-only.js +1 -0
  206. package/dist/server/compat/next/server.js +131 -0
  207. package/dist/server/compat/next/svgr.js +14 -0
  208. package/dist/server/compat/next/telemetry.js +10 -0
  209. package/dist/server/compat/next/usage.js +13 -0
  210. package/dist/server/compat/next/user-agent.js +12 -0
  211. package/dist/server/compat/next/web-vitals.js +35 -0
  212. package/dist/server/compat/react/action-state.js +11 -0
  213. package/dist/server/compat/react/client-lite.js +83 -0
  214. package/dist/server/compat/react/client.js +131 -0
  215. package/dist/server/compat/react/compiler-runtime.js +42 -0
  216. package/dist/server/compat/react/dom-client.js +106 -0
  217. package/dist/server/compat/react/dom-react-server.js +37 -0
  218. package/dist/server/compat/react/dom-server.js +40 -0
  219. package/dist/server/compat/react/dom.js +52 -0
  220. package/dist/server/compat/react/hooks-extra.js +12 -0
  221. package/dist/server/compat/react/internals.js +14 -0
  222. package/dist/server/compat/react/parity.js +11 -0
  223. package/dist/server/compat/react/preact.js +113 -0
  224. package/dist/server/compat/react/react-server.js +133 -0
  225. package/dist/server/compat/react/router-shim.js +8 -0
  226. package/dist/server/compat/react/server-component-use.js +14 -0
  227. package/dist/server/compat/react/server-inserted-html.js +14 -0
  228. package/dist/server/compat/react/server.js +194 -0
  229. package/dist/server/compat/react/style-values.js +10 -0
  230. package/dist/server/compat/react/use.js +10 -0
  231. package/dist/server/compat/react/view-transition.js +12 -0
  232. package/dist/server/generation.json +1 -0
  233. package/package.json +4 -1
  234. package/src/api/dynamic.tsx +2 -0
  235. package/src/api/server.ts +24 -6
  236. package/src/cli/adapters/vercel-warm.ts +315 -61
  237. package/src/cli/adapters/vercel.ts +348 -71
  238. package/src/cli/build.ts +58 -33
  239. package/src/cli/index.ts +23 -10
  240. package/src/cli/serve/entry.ts +21 -159
  241. package/src/cli/serve/immutable.ts +31 -0
  242. package/src/cli/serve/pipeline.ts +82 -84
  243. package/src/cli/start.ts +3 -1
  244. package/src/client/chunk-fold.ts +19 -6
  245. package/src/client/react-tier.ts +3 -2
  246. package/src/client/reference-stub.ts +21 -2
  247. package/src/compat/actions/client-plugin.ts +4 -2
  248. package/src/compat/actions/config.ts +6 -5
  249. package/src/compat/actions/extensions.ts +2 -3
  250. package/src/compat/aliases.ts +8 -1
  251. package/src/compat/bundler/config.ts +88 -0
  252. package/src/compat/bundler/optimize-package-imports.ts +86 -26
  253. package/src/compat/bundler/relay-transform.ts +15 -3
  254. package/src/compat/cache-control.ts +16 -8
  255. package/src/compat/css/modules.ts +18 -5
  256. package/src/compat/lifecycle/error-funnel.ts +1 -1
  257. package/src/compat/lifecycle/instrumentation.ts +117 -24
  258. package/src/compat/lifecycle/testmode.ts +3 -2
  259. package/src/compat/next/config-loader.ts +137 -13
  260. package/src/compat/next/font/runtime.ts +22 -2
  261. package/src/compat/next/og.ts +3 -3
  262. package/src/compat/next/usage.ts +3 -2
  263. package/src/compat/pages/api.ts +83 -14
  264. package/src/compat/pages/router.ts +30 -14
  265. package/src/compat/register/bundler.ts +3 -1
  266. package/src/compat/register/middleware.ts +1 -1
  267. package/src/compat/register/otel.ts +5 -9
  268. package/src/compat/register/render.ts +3 -1
  269. package/src/compat/register/use-cache.ts +3 -1
  270. package/src/compat/release.ts +46 -0
  271. package/src/compat/segment/serve.ts +1 -1
  272. package/src/compat/validation/validate.ts +10 -7
  273. package/src/config.ts +51 -7
  274. package/src/css/assets.ts +213 -0
  275. package/src/css/build.ts +174 -238
  276. package/src/dev/server.ts +27 -8
  277. package/src/extensions.ts +4 -0
  278. package/src/render/hooks.ts +13 -0
  279. package/src/render/renderer.ts +52 -32
  280. package/src/request/context.ts +9 -0
  281. package/src/resolve/dynamic.ts +3 -1
  282. package/src/resolve/imports.ts +12 -52
  283. package/src/resolve/package-json.ts +56 -0
  284. package/src/resolve/scan-facts.ts +65 -0
  285. package/src/routing/href.ts +10 -3
  286. package/src/routing/match.ts +287 -0
  287. package/src/routing/metadata-files.ts +19 -5
  288. package/src/routing/proxy-config.ts +137 -0
  289. package/src/routing/proxy.ts +35 -134
  290. package/src/routing/routes.ts +22 -281
  291. package/src/runtime/fingerprint.ts +23 -8
  292. package/src/runtime/load.ts +170 -0
  293. package/src/runtime/loader.ts +215 -43
  294. package/src/runtime/module-cache.ts +13 -0
  295. package/src/runtime/modules.ts +370 -81
  296. package/src/runtime/prebundle.ts +81 -0
  297. package/src/runtime/production.ts +391 -0
  298. package/src/runtime/release-graph.ts +334 -0
  299. package/src/runtime/vendor-build.ts +724 -13
  300. package/src/runtime/vendor.ts +16 -3
  301. package/src/types.ts +2 -0
  302. package/src/utils/fs.ts +89 -3
@@ -0,0 +1,334 @@
1
+ /**
2
+ * A release's server dependencies, one graph per App Router layer, as Next bundles them. The compile
3
+ * vendors (or natively loads) each package import for the build's own prerender and logs it; once
4
+ * every release module is compiled, this links what a layer imports and repoints the release modules
5
+ * at the graph. Pages Router layers keep their per-package artifacts, as Next keeps those external.
6
+ */
7
+ import { existsSync, readFileSync, realpathSync } from 'node:fs'
8
+ import { readFile, readdir, rm } from 'node:fs/promises'
9
+ import path from 'node:path'
10
+ import type { ResolvedConfig } from '../config'
11
+ import { getExternalPackagePolicy } from '../resolve/imports'
12
+ import { importSpecifiers } from '../resolve/scan-facts'
13
+ import { toPosixPath, writeFileAtomic } from '../utils/fs'
14
+ import { hashBundleSpecifier } from './loader'
15
+ import { cacheRoot, devSourceIdentity } from './module-cache'
16
+ import { outputSpecifiers, spliceSource } from './module-transform'
17
+ import { compiledSpecifiersManifestSuffix, releaseLayerArtifactDir } from './modules'
18
+ import { emittedRefs } from './vendor'
19
+ import {
20
+ linkReleaseDependencies,
21
+ releaseDependencyLog,
22
+ type ReleaseDependency,
23
+ type ReleaseDependencyLayer,
24
+ } from './vendor-build'
25
+
26
+ const layerDirs: Record<ReleaseDependencyLayer, string> = {
27
+ 'server:server': 'rsc',
28
+ 'client:client': 'ssr',
29
+ }
30
+ const layers = Object.keys(layerDirs) as ReleaseDependencyLayer[]
31
+ const frameworkRoot = realpathSync(path.resolve(import.meta.dirname, '..', '..'))
32
+
33
+ export interface LinkedLayer {
34
+ /** Every file the graph wrote. */
35
+ files: string[]
36
+ /** A dependency artifact the compile handed out -> the graph entry that replaces it. */
37
+ moved: Map<string, string>
38
+ }
39
+
40
+ /** A release module compiled for another layer than its directory's. */
41
+ interface ReleaseModuleLayer {
42
+ module: string
43
+ layer: ReleaseDependencyLayer
44
+ }
45
+
46
+ /** Demands by the file the compile handed out (natives by real path too), per layer. */
47
+ type Demands = Map<string, Map<ReleaseDependencyLayer, ReleaseDependency>>
48
+
49
+ /**
50
+ * Link `layer` for the release whose modules are `roots`, and rewrite the release modules importing
51
+ * its dependencies to import the graph. `sources` holds the App Router modules read so far, shared
52
+ * across layers. Undefined when the layer imports no dependency.
53
+ */
54
+ export async function linkReleaseLayer(
55
+ config: ResolvedConfig,
56
+ layer: ReleaseDependencyLayer,
57
+ roots: readonly string[],
58
+ sources: Map<string, string>,
59
+ ): Promise<LinkedLayer | undefined> {
60
+ const { demands, moduleLayers } = loggedDependencies(config)
61
+ if (![...demands.values()].some(owners => owners.has(layer))) return undefined
62
+ const cache = cacheRoot(config.outPath)
63
+ const dirs = new Map(layers.map(each => [each, releaseLayerArtifactDir(config, each)] as const))
64
+ const inLayers = (file: string) => [...dirs.values()].some(dir => isInside(dir, file))
65
+ await readLayerModules(inLayers, roots, sources)
66
+ const policy = getExternalPackagePolicy()
67
+ // A native demand is imported bare; only its packages need resolving.
68
+ const natives = new Set(
69
+ [...demands]
70
+ .filter(([file, owners]) => owners.has(layer) && !isInside(cache, file))
71
+ .map(([, owners]) => packageName(owners.get(layer)!.specifier)),
72
+ )
73
+ const resolved = new Map<string, string | undefined>()
74
+ const resolveBare = (specifier: string, from: string) => {
75
+ const key = `${path.dirname(from)}\0${specifier}`
76
+ if (!resolved.has(key)) resolved.set(key, realFile(bunResolve(specifier, from)))
77
+ return resolved.get(key)
78
+ }
79
+ // The importer's compile layer picks the graph: a `'use client'` file compiles for the client layer
80
+ // into the RSC tree, and a cross-layer artifact is one file both layers demanded.
81
+ const demandOf = (file: string | undefined, importer: string) => {
82
+ const owners = file && (demands.get(file) ?? demands.get(realFile(file) ?? file))
83
+ if (!owners) return undefined
84
+ const importerLayer =
85
+ moduleLayers.get(importer) ?? [...dirs].find(([, dir]) => isInside(dir, importer))?.[0]
86
+ const owner =
87
+ importerLayer && owners.has(importerLayer)
88
+ ? importerLayer
89
+ : owners.size === 1
90
+ ? [...owners.keys()][0]
91
+ : undefined
92
+ return owner === layer ? owners.get(layer) : undefined
93
+ }
94
+ const entries = new Map<string, { in: string; out: string }>()
95
+ const entryOf = (demand: ReleaseDependency) => {
96
+ const entry = demand.entry!
97
+ if (!entries.has(entry)) entries.set(entry, { in: entry, out: entryName(config, entry) })
98
+ return entry
99
+ }
100
+ const edits = new Map<string, { start: number; end: number; suffix: string; to: string }[]>()
101
+ for (const [file, code] of sources) {
102
+ const list: { start: number; end: number; suffix: string; to: string }[] = []
103
+ for (const found of outputSpecifiers(code)) {
104
+ const { specifier, suffix } = splitSuffix(found.value)
105
+ const relative = specifier.startsWith('.')
106
+ const target = relative && path.resolve(path.dirname(file), specifier)
107
+ const demand = target
108
+ ? inLayers(target)
109
+ ? undefined
110
+ : demandOf(target, file)
111
+ : natives.has(packageName(specifier))
112
+ ? demandOf(resolveBare(specifier, file), file)
113
+ : undefined
114
+ if (!demand?.entry) continue
115
+ const edit = { start: found.start, end: found.end, suffix }
116
+ // Next's built-in externals load as plain imports wherever the release resolves them as the app does.
117
+ if (policy.releaseExternal?.(packageName(demand.specifier) ?? '')) {
118
+ if (!relative) continue
119
+ if (resolveBare(demand.specifier, file) === realFile(demand.entry)) {
120
+ list.push({ ...edit, to: demand.specifier })
121
+ continue
122
+ }
123
+ }
124
+ list.push({ ...edit, to: entryOf(demand) })
125
+ }
126
+ if (list.length > 0) edits.set(file, list)
127
+ }
128
+ // A release module the compile served straight from a dependency artifact (a package's client file).
129
+ const rootEntries = new Map<string, string>()
130
+ for (const root of roots) {
131
+ const demand = inLayers(root) ? undefined : demands.get(root)?.get(layer)
132
+ if (demand?.entry) rootEntries.set(root, entryOf(demand))
133
+ }
134
+ if (entries.size === 0 && edits.size === 0) return undefined
135
+ const outdir = path.join(cache, 'deps', layerDirs[layer])
136
+ const linked =
137
+ entries.size > 0
138
+ ? await linkReleaseDependencies(config, layer, [...entries.values()], outdir)
139
+ : { files: [], inPlace: [] }
140
+ // An entry left in place keeps the import the compile emitted.
141
+ for (const entry of linked.inPlace) entries.delete(entry)
142
+ const target = (edit: { to: string }) =>
143
+ entries.has(edit.to) || !path.isAbsolute(edit.to) ? edit.to : undefined
144
+ const output = (entry: string) => path.join(outdir, `${entries.get(entry)!.out}.js`)
145
+ await Promise.all(
146
+ [...edits].map(async ([file, all]) => {
147
+ const list = all.filter(target)
148
+ if (list.length === 0) return
149
+ const code = spliceSource(
150
+ sources.get(file)!,
151
+ list.map(edit => ({
152
+ start: edit.start,
153
+ end: edit.end,
154
+ value: JSON.stringify(
155
+ `${entries.has(edit.to) ? importPath(file, output(edit.to)) : edit.to}${edit.suffix}`,
156
+ ),
157
+ })),
158
+ )
159
+ sources.set(file, code)
160
+ // Nothing reads the release's modules while the build links them.
161
+ await Bun.write(file, code)
162
+ const sidecar = `${file}${compiledSpecifiersManifestSuffix}`
163
+ if (existsSync(sidecar)) {
164
+ await writeFileAtomic(sidecar, JSON.stringify(importSpecifiers(code, file)))
165
+ }
166
+ }),
167
+ )
168
+ return {
169
+ files: linked.files,
170
+ moved: new Map(
171
+ [...rootEntries]
172
+ .filter(([, entry]) => entries.has(entry))
173
+ .map(([root, entry]) => [root, output(entry)]),
174
+ ),
175
+ }
176
+ }
177
+
178
+ /** Read the App Router modules: the `roots` among them and what they import relatively. */
179
+ async function readLayerModules(
180
+ inLayers: (file: string) => boolean,
181
+ roots: readonly string[],
182
+ sources: Map<string, string>,
183
+ ) {
184
+ const seen = new Set<string>()
185
+ let frontier = roots.filter(inLayers)
186
+ while (frontier.length > 0) {
187
+ const next: string[] = []
188
+ await Promise.all(
189
+ frontier.map(async file => {
190
+ if (seen.has(file)) return
191
+ seen.add(file)
192
+ const code = sources.get(file) ?? (await readFile(file, 'utf8').catch(() => undefined))
193
+ if (code === undefined) return
194
+ sources.set(file, code)
195
+ for (const found of outputSpecifiers(code)) {
196
+ if (!found.value.startsWith('.')) continue
197
+ const target = path.resolve(path.dirname(file), splitSuffix(found.value).specifier)
198
+ if (inLayers(target)) next.push(target)
199
+ }
200
+ }),
201
+ )
202
+ frontier = next
203
+ }
204
+ }
205
+
206
+ function loggedDependencies(config: ResolvedConfig) {
207
+ const demands: Demands = new Map()
208
+ const moduleLayers = new Map<string, ReleaseDependencyLayer>()
209
+ let log: string
210
+ try {
211
+ log = readFileSync(releaseDependencyLog(config), 'utf8')
212
+ } catch {
213
+ return { demands, moduleLayers }
214
+ }
215
+ const add = (file: string, demand: ReleaseDependency) => {
216
+ const owners = demands.get(file) ?? new Map<ReleaseDependencyLayer, ReleaseDependency>()
217
+ if (!owners.has(demand.layer)) owners.set(demand.layer, demand)
218
+ demands.set(file, owners)
219
+ }
220
+ for (const line of log.split('\n')) {
221
+ if (!line) continue
222
+ const record = JSON.parse(line) as ReleaseDependency | ReleaseModuleLayer
223
+ if ('module' in record) {
224
+ moduleLayers.set(path.resolve(record.module), record.layer)
225
+ continue
226
+ }
227
+ // The framework is the runtime itself: its modules stay the ones the server loads.
228
+ if (record.entry && isInside(frameworkRoot, record.entry)) continue
229
+ add(path.resolve(record.file), record)
230
+ const real = realFile(record.file)
231
+ if (real && real !== path.resolve(record.file)) add(real, record)
232
+ }
233
+ return { demands, moduleLayers }
234
+ }
235
+
236
+ /**
237
+ * Remove the vendor artifacts no compiled module imports any more: the compile wrote them for the
238
+ * build's own prerender, and the linked graphs replaced them. `sources` are the App Router modules,
239
+ * already read.
240
+ */
241
+ export async function pruneReleaseVendor(config: ResolvedConfig, sources: Map<string, string>) {
242
+ const cache = cacheRoot(config.outPath)
243
+ const vendor = path.join(cache, 'vendor')
244
+ const graphs = path.join(cache, 'deps')
245
+ const compiled = (await readdir(cache, { recursive: true, withFileTypes: true }))
246
+ .filter(entry => !entry.isDirectory() && /\.[cm]?js$/.test(entry.name))
247
+ .map(entry => path.join(entry.parentPath, entry.name))
248
+ const reached = new Set<string>()
249
+ let frontier = compiled.filter(file => !isInside(vendor, file) && !isInside(graphs, file))
250
+ while (frontier.length > 0) {
251
+ const next: string[] = []
252
+ await Promise.all(
253
+ frontier.map(async file => {
254
+ if (reached.has(file)) return
255
+ reached.add(file)
256
+ const real = realFile(file)
257
+ if (real) reached.add(real)
258
+ const code =
259
+ sources.get(file) ??
260
+ (/\.[cm]?js$/.test(file)
261
+ ? await readFile(file, 'utf8').catch(() => undefined)
262
+ : undefined)
263
+ for (const specifier of code ? relativeReferences(code) : []) {
264
+ const target = path.resolve(path.dirname(file), splitSuffix(specifier).specifier)
265
+ if (isInside(vendor, target)) next.push(target)
266
+ }
267
+ }),
268
+ )
269
+ frontier = next
270
+ }
271
+ await Promise.all(
272
+ compiled
273
+ .filter(file => isInside(vendor, file) && !file.endsWith('.trace.js') && !reached.has(file))
274
+ .map(file => rm(file, { force: true })),
275
+ )
276
+ }
277
+
278
+ /** Relative module references in emitted code: imports, requires and `new URL(…, import.meta.url)`. */
279
+ function relativeReferences(code: string) {
280
+ return [
281
+ ...outputSpecifiers(code).map(found => found.value),
282
+ ...emittedRefs(code).map(ref => ref.specifier),
283
+ ...[...code.matchAll(/new URL\(("[^"]+"),\s*import\.meta\.url\)/g)].map(
284
+ match => JSON.parse(match[1]!) as string,
285
+ ),
286
+ ].filter(specifier => specifier.startsWith('.'))
287
+ }
288
+
289
+ /** A stable entry name: the package path it starts from, plus its workspace identity's hash. */
290
+ function entryName(config: ResolvedConfig, entry: string) {
291
+ const installed = entry.lastIndexOf(`${path.sep}node_modules${path.sep}`)
292
+ const label = toPosixPath(installed < 0 ? path.basename(entry) : entry.slice(installed + 14))
293
+ .replace(/\.[cm]?[jt]sx?$/, '')
294
+ .replace(/[^\w.-]+/g, '_')
295
+ return `${label.slice(-48)}.${hashBundleSpecifier(devSourceIdentity(entry, config.workspaceRoot)).slice(0, 8)}`
296
+ }
297
+
298
+ function splitSuffix(value: string) {
299
+ const index = value.search(/[?#]/)
300
+ return index < 0
301
+ ? { specifier: value, suffix: '' }
302
+ : { specifier: value.slice(0, index), suffix: value.slice(index) }
303
+ }
304
+
305
+ function packageName(specifier: string) {
306
+ const parts = specifier.split('/')
307
+ return specifier.startsWith('@') ? parts.slice(0, 2).join('/') : parts[0]
308
+ }
309
+
310
+ function importPath(from: string, to: string) {
311
+ const relative = toPosixPath(path.relative(path.dirname(from), to))
312
+ return relative.startsWith('.') ? relative : `./${relative}`
313
+ }
314
+
315
+ function bunResolve(specifier: string, from: string) {
316
+ try {
317
+ return Bun.resolveSync(specifier, path.dirname(from))
318
+ } catch {
319
+ return undefined
320
+ }
321
+ }
322
+
323
+ function realFile(file: string | undefined) {
324
+ if (!file) return undefined
325
+ try {
326
+ return realpathSync(file)
327
+ } catch {
328
+ return undefined
329
+ }
330
+ }
331
+
332
+ function isInside(dir: string, file: string) {
333
+ return file.startsWith(`${dir}${path.sep}`)
334
+ }