@hyperfrontend/builder 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (561) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/FUNDING.md +141 -0
  3. package/LICENSE.md +21 -0
  4. package/README.md +162 -0
  5. package/SECURITY.md +82 -0
  6. package/THIRD_PARTY_LICENSES.md +13 -0
  7. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/array/index.cjs.js +7 -0
  8. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/array/index.esm.js +5 -0
  9. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/console/index.cjs.js +13 -0
  10. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/console/index.esm.js +8 -0
  11. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/date/index.cjs.js +5 -0
  12. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/date/index.esm.js +4 -0
  13. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/encoding/index.cjs.js +1 -0
  14. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/encoding/index.esm.js +1 -0
  15. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/error/index.cjs.js +6 -0
  16. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/error/index.esm.js +5 -0
  17. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/function/index.cjs.js +1 -0
  18. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/function/index.esm.js +1 -0
  19. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/json/index.cjs.js +7 -0
  20. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/json/index.esm.js +5 -0
  21. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/map/index.cjs.js +6 -0
  22. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/map/index.esm.js +5 -0
  23. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/math/index.cjs.js +7 -0
  24. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/math/index.esm.js +5 -0
  25. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/messaging/index.cjs.js +1 -0
  26. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/messaging/index.esm.js +1 -0
  27. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/number/index.cjs.js +1 -0
  28. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/number/index.esm.js +1 -0
  29. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/object/index.cjs.js +13 -0
  30. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/object/index.esm.js +8 -0
  31. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/promise/index.cjs.js +6 -0
  32. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/promise/index.esm.js +5 -0
  33. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/reflect/index.cjs.js +1 -0
  34. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/reflect/index.esm.js +1 -0
  35. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/regexp/index.cjs.js +6 -0
  36. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/regexp/index.esm.js +5 -0
  37. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/set/index.cjs.js +6 -0
  38. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/set/index.esm.js +5 -0
  39. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/string/index.cjs.js +1 -0
  40. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/string/index.esm.js +1 -0
  41. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/symbol/index.cjs.js +1 -0
  42. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/symbol/index.esm.js +1 -0
  43. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/timers/index.cjs.js +13 -0
  44. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/timers/index.esm.js +10 -0
  45. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/typed-arrays/index.cjs.js +1 -0
  46. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/typed-arrays/index.esm.js +1 -0
  47. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/url/index.cjs.js +6 -0
  48. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/url/index.esm.js +5 -0
  49. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/weak-map/index.cjs.js +1 -0
  50. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/weak-map/index.esm.js +1 -0
  51. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/weak-set/index.cjs.js +1 -0
  52. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/weak-set/index.esm.js +1 -0
  53. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/websocket/index.cjs.js +1 -0
  54. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/websocket/index.esm.js +1 -0
  55. package/_dependencies/@hyperfrontend/immutable-api-utils/index.cjs.js +1 -0
  56. package/_dependencies/@hyperfrontend/immutable-api-utils/index.esm.js +1 -0
  57. package/_dependencies/@hyperfrontend/immutable-api-utils/locked/index.cjs.js +1 -0
  58. package/_dependencies/@hyperfrontend/immutable-api-utils/locked/index.esm.js +1 -0
  59. package/_dependencies/@hyperfrontend/immutable-api-utils/locked-prop-descriptors/index.cjs.js +1 -0
  60. package/_dependencies/@hyperfrontend/immutable-api-utils/locked-prop-descriptors/index.esm.js +1 -0
  61. package/_dependencies/@hyperfrontend/immutable-api-utils/locked-props/index.cjs.js +1 -0
  62. package/_dependencies/@hyperfrontend/immutable-api-utils/locked-props/index.esm.js +1 -0
  63. package/_dependencies/@hyperfrontend/logging/index.cjs.js +191 -0
  64. package/_dependencies/@hyperfrontend/logging/index.esm.js +186 -0
  65. package/_dependencies/@hyperfrontend/project-scope/cli/index.cjs.js +196 -0
  66. package/_dependencies/@hyperfrontend/project-scope/cli/index.esm.js +196 -0
  67. package/_dependencies/@hyperfrontend/project-scope/core/encoding/index.cjs.js +82 -0
  68. package/_dependencies/@hyperfrontend/project-scope/core/encoding/index.esm.js +82 -0
  69. package/_dependencies/@hyperfrontend/project-scope/core/fs/index.cjs.js +154 -0
  70. package/_dependencies/@hyperfrontend/project-scope/core/fs/index.esm.js +149 -0
  71. package/_dependencies/@hyperfrontend/project-scope/core/index.cjs.js +459 -0
  72. package/_dependencies/@hyperfrontend/project-scope/core/index.esm.js +440 -0
  73. package/_dependencies/@hyperfrontend/project-scope/core/logger/index.cjs.js +84 -0
  74. package/_dependencies/@hyperfrontend/project-scope/core/logger/index.esm.js +80 -0
  75. package/_dependencies/@hyperfrontend/project-scope/core/path/index.cjs.js +26 -0
  76. package/_dependencies/@hyperfrontend/project-scope/core/path/index.esm.js +22 -0
  77. package/_dependencies/@hyperfrontend/project-scope/core/platform/index.cjs.js +1 -0
  78. package/_dependencies/@hyperfrontend/project-scope/core/platform/index.esm.js +1 -0
  79. package/_dependencies/@hyperfrontend/project-scope/heuristics/dependencies/index.cjs.js +90 -0
  80. package/_dependencies/@hyperfrontend/project-scope/heuristics/dependencies/index.esm.js +90 -0
  81. package/_dependencies/@hyperfrontend/project-scope/heuristics/entry-points/index.cjs.js +174 -0
  82. package/_dependencies/@hyperfrontend/project-scope/heuristics/entry-points/index.esm.js +174 -0
  83. package/_dependencies/@hyperfrontend/project-scope/heuristics/framework/index.cjs.js +174 -0
  84. package/_dependencies/@hyperfrontend/project-scope/heuristics/framework/index.esm.js +172 -0
  85. package/_dependencies/@hyperfrontend/project-scope/heuristics/index.cjs.js +184 -0
  86. package/_dependencies/@hyperfrontend/project-scope/heuristics/index.esm.js +184 -0
  87. package/_dependencies/@hyperfrontend/project-scope/heuristics/project-type/index.cjs.js +172 -0
  88. package/_dependencies/@hyperfrontend/project-scope/heuristics/project-type/index.esm.js +172 -0
  89. package/_dependencies/@hyperfrontend/project-scope/index.cjs.js +222 -0
  90. package/_dependencies/@hyperfrontend/project-scope/index.esm.js +219 -0
  91. package/_dependencies/@hyperfrontend/project-scope/models/index.cjs.js +2 -0
  92. package/_dependencies/@hyperfrontend/project-scope/models/index.esm.js +1 -0
  93. package/_dependencies/@hyperfrontend/project-scope/nx/index.cjs.js +94 -0
  94. package/_dependencies/@hyperfrontend/project-scope/nx/index.esm.js +94 -0
  95. package/_dependencies/@hyperfrontend/project-scope/project/config/index.cjs.js +172 -0
  96. package/_dependencies/@hyperfrontend/project-scope/project/config/index.esm.js +172 -0
  97. package/_dependencies/@hyperfrontend/project-scope/project/index.cjs.js +176 -0
  98. package/_dependencies/@hyperfrontend/project-scope/project/index.esm.js +176 -0
  99. package/_dependencies/@hyperfrontend/project-scope/project/package/index.cjs.js +88 -0
  100. package/_dependencies/@hyperfrontend/project-scope/project/package/index.esm.js +88 -0
  101. package/_dependencies/@hyperfrontend/project-scope/project/root/index.cjs.js +154 -0
  102. package/_dependencies/@hyperfrontend/project-scope/project/root/index.esm.js +153 -0
  103. package/_dependencies/@hyperfrontend/project-scope/project/traversal/index.cjs.js +91 -0
  104. package/_dependencies/@hyperfrontend/project-scope/project/traversal/index.esm.js +89 -0
  105. package/_dependencies/@hyperfrontend/project-scope/tech/backend/index.cjs.js +88 -0
  106. package/_dependencies/@hyperfrontend/project-scope/tech/backend/index.esm.js +88 -0
  107. package/_dependencies/@hyperfrontend/project-scope/tech/build/index.cjs.js +88 -0
  108. package/_dependencies/@hyperfrontend/project-scope/tech/build/index.esm.js +88 -0
  109. package/_dependencies/@hyperfrontend/project-scope/tech/frontend/index.cjs.js +88 -0
  110. package/_dependencies/@hyperfrontend/project-scope/tech/frontend/index.esm.js +88 -0
  111. package/_dependencies/@hyperfrontend/project-scope/tech/index.cjs.js +171 -0
  112. package/_dependencies/@hyperfrontend/project-scope/tech/index.esm.js +169 -0
  113. package/_dependencies/@hyperfrontend/project-scope/tech/legacy/index.cjs.js +88 -0
  114. package/_dependencies/@hyperfrontend/project-scope/tech/legacy/index.esm.js +88 -0
  115. package/_dependencies/@hyperfrontend/project-scope/tech/linting/index.cjs.js +88 -0
  116. package/_dependencies/@hyperfrontend/project-scope/tech/linting/index.esm.js +88 -0
  117. package/_dependencies/@hyperfrontend/project-scope/tech/monorepo/index.cjs.js +88 -0
  118. package/_dependencies/@hyperfrontend/project-scope/tech/monorepo/index.esm.js +88 -0
  119. package/_dependencies/@hyperfrontend/project-scope/tech/testing/index.cjs.js +88 -0
  120. package/_dependencies/@hyperfrontend/project-scope/tech/testing/index.esm.js +88 -0
  121. package/_dependencies/@hyperfrontend/project-scope/tech/types/index.cjs.js +88 -0
  122. package/_dependencies/@hyperfrontend/project-scope/tech/types/index.esm.js +88 -0
  123. package/_dependencies/@hyperfrontend/project-scope/vfs/index.cjs.js +102 -0
  124. package/_dependencies/@hyperfrontend/project-scope/vfs/index.esm.js +102 -0
  125. package/_dependencies/@hyperfrontend/versioning/changelog/compare/index.cjs.js +1 -0
  126. package/_dependencies/@hyperfrontend/versioning/changelog/compare/index.esm.js +1 -0
  127. package/_dependencies/@hyperfrontend/versioning/changelog/index.cjs.js +1 -0
  128. package/_dependencies/@hyperfrontend/versioning/changelog/index.esm.js +1 -0
  129. package/_dependencies/@hyperfrontend/versioning/changelog/models/index.cjs.js +1 -0
  130. package/_dependencies/@hyperfrontend/versioning/changelog/models/index.esm.js +1 -0
  131. package/_dependencies/@hyperfrontend/versioning/changelog/operations/index.cjs.js +1 -0
  132. package/_dependencies/@hyperfrontend/versioning/changelog/operations/index.esm.js +1 -0
  133. package/_dependencies/@hyperfrontend/versioning/changelog/parse/index.cjs.js +1 -0
  134. package/_dependencies/@hyperfrontend/versioning/changelog/parse/index.esm.js +1 -0
  135. package/_dependencies/@hyperfrontend/versioning/changelog/serialize/index.cjs.js +1 -0
  136. package/_dependencies/@hyperfrontend/versioning/changelog/serialize/index.esm.js +1 -0
  137. package/_dependencies/@hyperfrontend/versioning/commits/author/index.cjs.js +2403 -0
  138. package/_dependencies/@hyperfrontend/versioning/commits/author/index.esm.js +2381 -0
  139. package/_dependencies/@hyperfrontend/versioning/commits/classify/index.cjs.js +38 -0
  140. package/_dependencies/@hyperfrontend/versioning/commits/classify/index.esm.js +30 -0
  141. package/_dependencies/@hyperfrontend/versioning/commits/format/index.cjs.js +1 -0
  142. package/_dependencies/@hyperfrontend/versioning/commits/format/index.esm.js +1 -0
  143. package/_dependencies/@hyperfrontend/versioning/commits/index.cjs.js +2457 -0
  144. package/_dependencies/@hyperfrontend/versioning/commits/index.esm.js +2407 -0
  145. package/_dependencies/@hyperfrontend/versioning/commits/models/index.cjs.js +1 -0
  146. package/_dependencies/@hyperfrontend/versioning/commits/models/index.esm.js +1 -0
  147. package/_dependencies/@hyperfrontend/versioning/commits/parse/index.cjs.js +1 -0
  148. package/_dependencies/@hyperfrontend/versioning/commits/parse/index.esm.js +1 -0
  149. package/_dependencies/@hyperfrontend/versioning/commits/validate/index.cjs.js +27 -0
  150. package/_dependencies/@hyperfrontend/versioning/commits/validate/index.esm.js +25 -0
  151. package/_dependencies/@hyperfrontend/versioning/flow/executor/index.cjs.js +36 -0
  152. package/_dependencies/@hyperfrontend/versioning/flow/executor/index.esm.js +36 -0
  153. package/_dependencies/@hyperfrontend/versioning/flow/index.cjs.js +51 -0
  154. package/_dependencies/@hyperfrontend/versioning/flow/index.esm.js +51 -0
  155. package/_dependencies/@hyperfrontend/versioning/flow/models/index.cjs.js +30 -0
  156. package/_dependencies/@hyperfrontend/versioning/flow/models/index.esm.js +28 -0
  157. package/_dependencies/@hyperfrontend/versioning/flow/presets/index.cjs.js +47 -0
  158. package/_dependencies/@hyperfrontend/versioning/flow/presets/index.esm.js +45 -0
  159. package/_dependencies/@hyperfrontend/versioning/flow/steps/index.cjs.js +47 -0
  160. package/_dependencies/@hyperfrontend/versioning/flow/steps/index.esm.js +45 -0
  161. package/_dependencies/@hyperfrontend/versioning/git/index.cjs.js +8 -0
  162. package/_dependencies/@hyperfrontend/versioning/git/index.esm.js +9 -0
  163. package/_dependencies/@hyperfrontend/versioning/git/models/index.cjs.js +1 -0
  164. package/_dependencies/@hyperfrontend/versioning/git/models/index.esm.js +1 -0
  165. package/_dependencies/@hyperfrontend/versioning/git/operations/index.cjs.js +3 -0
  166. package/_dependencies/@hyperfrontend/versioning/git/operations/index.esm.js +3 -0
  167. package/_dependencies/@hyperfrontend/versioning/index.cjs.js +2481 -0
  168. package/_dependencies/@hyperfrontend/versioning/index.esm.js +2423 -0
  169. package/_dependencies/@hyperfrontend/versioning/registry/index.cjs.js +1 -0
  170. package/_dependencies/@hyperfrontend/versioning/registry/index.esm.js +1 -0
  171. package/_dependencies/@hyperfrontend/versioning/registry/models/index.cjs.js +1 -0
  172. package/_dependencies/@hyperfrontend/versioning/registry/models/index.esm.js +1 -0
  173. package/_dependencies/@hyperfrontend/versioning/registry/npm/index.cjs.js +1 -0
  174. package/_dependencies/@hyperfrontend/versioning/registry/npm/index.esm.js +1 -0
  175. package/_dependencies/@hyperfrontend/versioning/repository/index.cjs.js +18 -0
  176. package/_dependencies/@hyperfrontend/versioning/repository/index.esm.js +17 -0
  177. package/_dependencies/@hyperfrontend/versioning/repository/models/index.cjs.js +11 -0
  178. package/_dependencies/@hyperfrontend/versioning/repository/models/index.esm.js +10 -0
  179. package/_dependencies/@hyperfrontend/versioning/repository/parse/index.cjs.js +184 -0
  180. package/_dependencies/@hyperfrontend/versioning/repository/parse/index.esm.js +185 -0
  181. package/_dependencies/@hyperfrontend/versioning/repository/url/index.cjs.js +10 -0
  182. package/_dependencies/@hyperfrontend/versioning/repository/url/index.esm.js +8 -0
  183. package/_dependencies/@hyperfrontend/versioning/semver/compare/index.cjs.js +1 -0
  184. package/_dependencies/@hyperfrontend/versioning/semver/compare/index.esm.js +1 -0
  185. package/_dependencies/@hyperfrontend/versioning/semver/format/index.cjs.js +1 -0
  186. package/_dependencies/@hyperfrontend/versioning/semver/format/index.esm.js +1 -0
  187. package/_dependencies/@hyperfrontend/versioning/semver/increment/index.cjs.js +1 -0
  188. package/_dependencies/@hyperfrontend/versioning/semver/increment/index.esm.js +1 -0
  189. package/_dependencies/@hyperfrontend/versioning/semver/index.cjs.js +1 -0
  190. package/_dependencies/@hyperfrontend/versioning/semver/index.esm.js +1 -0
  191. package/_dependencies/@hyperfrontend/versioning/semver/models/index.cjs.js +1 -0
  192. package/_dependencies/@hyperfrontend/versioning/semver/models/index.esm.js +1 -0
  193. package/_dependencies/@hyperfrontend/versioning/semver/parse/index.cjs.js +1 -0
  194. package/_dependencies/@hyperfrontend/versioning/semver/parse/index.esm.js +1 -0
  195. package/_dependencies/@hyperfrontend/versioning/workspace/discovery/index.cjs.js +29 -0
  196. package/_dependencies/@hyperfrontend/versioning/workspace/discovery/index.esm.js +29 -0
  197. package/_dependencies/@hyperfrontend/versioning/workspace/index.cjs.js +29 -0
  198. package/_dependencies/@hyperfrontend/versioning/workspace/index.esm.js +29 -0
  199. package/_dependencies/@hyperfrontend/versioning/workspace/models/index.cjs.js +1 -0
  200. package/_dependencies/@hyperfrontend/versioning/workspace/models/index.esm.js +1 -0
  201. package/_dependencies/@hyperfrontend/versioning/workspace/operations/index.cjs.js +2 -0
  202. package/_dependencies/@hyperfrontend/versioning/workspace/operations/index.esm.js +2 -0
  203. package/_dependencies/@rollup/plugin-commonjs/index.cjs.js +6629 -0
  204. package/_dependencies/@rollup/plugin-commonjs/index.esm.js +6608 -0
  205. package/_dependencies/@rollup/plugin-json/index.cjs.js +2324 -0
  206. package/_dependencies/@rollup/plugin-json/index.esm.js +2322 -0
  207. package/_dependencies/@rollup/plugin-node-resolve/index.cjs.js +5430 -0
  208. package/_dependencies/@rollup/plugin-node-resolve/index.esm.js +5424 -0
  209. package/_dependencies/@rollup/plugin-terser/index.cjs.js +33220 -0
  210. package/_dependencies/@rollup/plugin-terser/index.esm.js +33217 -0
  211. package/_dependencies/@rollup/plugin-typescript/index.cjs.js +4840 -0
  212. package/_dependencies/@rollup/plugin-typescript/index.esm.js +4819 -0
  213. package/_dependencies/postject/index.cjs.js +5140 -0
  214. package/_dependencies/postject/index.esm.js +5131 -0
  215. package/_dependencies/rollup/index.cjs.js +24668 -0
  216. package/_dependencies/rollup/index.d.ts +1921 -0
  217. package/_dependencies/rollup/index.esm.js +24652 -0
  218. package/_dependencies/rollup-plugin-dts/index.cjs.js +6547 -0
  219. package/_dependencies/rollup-plugin-dts/index.esm.js +6537 -0
  220. package/_shared/bin/format/index.cjs.js +7 -0
  221. package/_shared/bin/format/index.esm.js +5 -0
  222. package/_shared/bin/native/codesign/index.cjs.js +30 -0
  223. package/_shared/bin/native/codesign/index.esm.js +26 -0
  224. package/_shared/bin/native/host-binary/index.cjs.js +13 -0
  225. package/_shared/bin/native/host-binary/index.esm.js +11 -0
  226. package/_shared/bin/native/inject/index.cjs.js +25 -0
  227. package/_shared/bin/native/inject/index.esm.js +18 -0
  228. package/_shared/bin/native/platform-check/index.cjs.js +13 -0
  229. package/_shared/bin/native/platform-check/index.esm.js +10 -0
  230. package/_shared/bin/native/sea-blob/index.cjs.js +21 -0
  231. package/_shared/bin/native/sea-blob/index.esm.js +19 -0
  232. package/_shared/bin/native/sea-config/index.cjs.js +9 -0
  233. package/_shared/bin/native/sea-config/index.esm.js +7 -0
  234. package/_shared/bin/script/bootstrap-footer/index.cjs.js +22 -0
  235. package/_shared/bin/script/bootstrap-footer/index.esm.js +19 -0
  236. package/_shared/bundle/declarations/flatten-paths/index.cjs.js +34 -0
  237. package/_shared/bundle/declarations/flatten-paths/index.esm.js +29 -0
  238. package/_shared/bundle/dependencies/collect-workspace-deps/index.cjs.js +24 -0
  239. package/_shared/bundle/dependencies/collect-workspace-deps/index.esm.js +21 -0
  240. package/_shared/bundle/dependencies/externalize-plugin/index.cjs.js +93 -0
  241. package/_shared/bundle/dependencies/externalize-plugin/index.esm.js +86 -0
  242. package/_shared/bundle/dependencies/prune/ast-utils/index.esm.js +31 -0
  243. package/_shared/bundle/dependencies/prune/namespace-usage/index.esm.js +208 -0
  244. package/_shared/bundle/dependencies/prune/specifiers/index.cjs.js +62 -0
  245. package/_shared/bundle/dependencies/prune/specifiers/index.esm.js +53 -0
  246. package/_shared/bundle/entries/discover-entries/index.cjs.js +87 -0
  247. package/_shared/bundle/entries/discover-entries/index.esm.js +80 -0
  248. package/_shared/bundle/entries/resolve-entries/index.cjs.js +38 -0
  249. package/_shared/bundle/entries/resolve-entries/index.esm.js +34 -0
  250. package/_shared/bundle/externals/validate-globals/index.cjs.js +14 -0
  251. package/_shared/bundle/externals/validate-globals/index.esm.js +12 -0
  252. package/_shared/bundle/fs/deps-root/index.cjs.js +7 -0
  253. package/_shared/bundle/fs/deps-root/index.esm.js +5 -0
  254. package/_shared/bundle/fs/empty-dirs/index.cjs.js +23 -0
  255. package/_shared/bundle/fs/empty-dirs/index.esm.js +21 -0
  256. package/_shared/bundle/fs/entry-dir/index.cjs.js +7 -0
  257. package/_shared/bundle/fs/entry-dir/index.esm.js +5 -0
  258. package/_shared/bundle/fs/posix-path/index.cjs.js +9 -0
  259. package/_shared/bundle/fs/posix-path/index.esm.js +4 -0
  260. package/_shared/bundle/fs/under-dir/index.cjs.js +5 -0
  261. package/_shared/bundle/fs/under-dir/index.esm.js +3 -0
  262. package/_shared/memory/recover/index.cjs.js +15 -0
  263. package/_shared/memory/recover/index.esm.js +14 -0
  264. package/_shared/package/finalize-files/index.cjs.js +16 -0
  265. package/_shared/package/finalize-files/index.esm.js +15 -0
  266. package/_shared/package/json/cdn-paths/index.cjs.js +13 -0
  267. package/_shared/package/json/cdn-paths/index.esm.js +11 -0
  268. package/_shared/package/json/filter-deps/index.cjs.js +37 -0
  269. package/_shared/package/json/filter-deps/index.esm.js +34 -0
  270. package/_shared/package/json/generate-exports/index.cjs.js +56 -0
  271. package/_shared/package/json/generate-exports/index.esm.js +52 -0
  272. package/_shared/package/json/inherit-fields/index.cjs.js +19 -0
  273. package/_shared/package/json/inherit-fields/index.esm.js +17 -0
  274. package/_shared/package/json/read-package-json/index.cjs.js +7 -0
  275. package/_shared/package/json/read-package-json/index.esm.js +6 -0
  276. package/_shared/package/json/reflect-files-allowlist/index.cjs.js +39 -0
  277. package/_shared/package/json/reflect-files-allowlist/index.esm.js +33 -0
  278. package/_shared/package/json/synthesize/index.cjs.js +72 -0
  279. package/_shared/package/json/synthesize/index.esm.js +68 -0
  280. package/_shared/package/json/write/index.cjs.js +9 -0
  281. package/_shared/package/json/write/index.esm.js +8 -0
  282. package/_shared/package/licenses/generate-content/index.cjs.js +17 -0
  283. package/_shared/package/licenses/generate-content/index.esm.js +17 -0
  284. package/_shared/package/licenses/license-url/index.esm.js +29 -0
  285. package/_shared/package/licenses/write/index.cjs.js +9 -0
  286. package/_shared/package/licenses/write/index.esm.js +8 -0
  287. package/_shared/presets/by-names/index.cjs.js +10 -0
  288. package/_shared/presets/by-names/index.esm.js +8 -0
  289. package/_shared/presets/by-prefix/index.cjs.js +7 -0
  290. package/_shared/presets/by-prefix/index.esm.js +5 -0
  291. package/bin/format.d.ts +18 -0
  292. package/bin/format.d.ts.map +1 -0
  293. package/bin/hf-build.d.ts +81 -0
  294. package/bin/hf-build.d.ts.map +1 -0
  295. package/bin/hf-build.js +208533 -0
  296. package/bin/hf-build.linux-x64 +0 -0
  297. package/bin/index.cjs.js +548 -0
  298. package/bin/index.d.ts +26 -0
  299. package/bin/index.d.ts.map +1 -0
  300. package/bin/index.esm.js +546 -0
  301. package/bin/native/build-native.d.ts +44 -0
  302. package/bin/native/build-native.d.ts.map +1 -0
  303. package/bin/native/codesign.d.ts +65 -0
  304. package/bin/native/codesign.d.ts.map +1 -0
  305. package/bin/native/dispatch.d.ts +75 -0
  306. package/bin/native/dispatch.d.ts.map +1 -0
  307. package/bin/native/host-binary.d.ts +36 -0
  308. package/bin/native/host-binary.d.ts.map +1 -0
  309. package/bin/native/index.cjs.js +264 -0
  310. package/bin/native/index.d.ts +407 -0
  311. package/bin/native/index.d.ts.map +1 -0
  312. package/bin/native/index.esm.js +249 -0
  313. package/bin/native/inject.d.ts +61 -0
  314. package/bin/native/inject.d.ts.map +1 -0
  315. package/bin/native/platform-check.d.ts +39 -0
  316. package/bin/native/platform-check.d.ts.map +1 -0
  317. package/bin/native/sea-blob.d.ts +40 -0
  318. package/bin/native/sea-blob.d.ts.map +1 -0
  319. package/bin/native/sea-config.d.ts +45 -0
  320. package/bin/native/sea-config.d.ts.map +1 -0
  321. package/bin/native/worker/index.cjs.js +88 -0
  322. package/bin/native/worker/index.d.ts +68 -0
  323. package/bin/native/worker/index.d.ts.map +1 -0
  324. package/bin/native/worker/index.esm.js +86 -0
  325. package/bin/native/worker/job-runner.d.ts +29 -0
  326. package/bin/native/worker/job-runner.d.ts.map +1 -0
  327. package/bin/native/worker/types.d.ts +38 -0
  328. package/bin/native/worker/types.d.ts.map +1 -0
  329. package/bin/run-bin-phase.d.ts +24 -0
  330. package/bin/run-bin-phase.d.ts.map +1 -0
  331. package/bin/script/bootstrap-footer.d.ts +41 -0
  332. package/bin/script/bootstrap-footer.d.ts.map +1 -0
  333. package/bin/script/build-bin.d.ts +36 -0
  334. package/bin/script/build-bin.d.ts.map +1 -0
  335. package/bin/script/index.cjs.js +265 -0
  336. package/bin/script/index.d.ts +79 -0
  337. package/bin/script/index.d.ts.map +1 -0
  338. package/bin/script/index.esm.js +262 -0
  339. package/build.d.ts +56 -0
  340. package/build.d.ts.map +1 -0
  341. package/bundle/declarations/dts-per-entry.d.ts +27 -0
  342. package/bundle/declarations/dts-per-entry.d.ts.map +1 -0
  343. package/bundle/declarations/dts-pre-pass.d.ts +18 -0
  344. package/bundle/declarations/dts-pre-pass.d.ts.map +1 -0
  345. package/bundle/declarations/flatten-paths.d.ts +28 -0
  346. package/bundle/declarations/flatten-paths.d.ts.map +1 -0
  347. package/bundle/declarations/generate-declarations.d.ts +33 -0
  348. package/bundle/declarations/generate-declarations.d.ts.map +1 -0
  349. package/bundle/declarations/index.cjs.js +868 -0
  350. package/bundle/declarations/index.d.ts +262 -0
  351. package/bundle/declarations/index.d.ts.map +1 -0
  352. package/bundle/declarations/index.esm.js +857 -0
  353. package/bundle/declarations/prune-orphan-dts.d.ts +33 -0
  354. package/bundle/declarations/prune-orphan-dts.d.ts.map +1 -0
  355. package/bundle/declarations/sibling-resolver.d.ts +125 -0
  356. package/bundle/declarations/sibling-resolver.d.ts.map +1 -0
  357. package/bundle/dedupe/attribute-modules.d.ts +178 -0
  358. package/bundle/dedupe/attribute-modules.d.ts.map +1 -0
  359. package/bundle/dedupe/extract-chunk.d.ts +103 -0
  360. package/bundle/dedupe/extract-chunk.d.ts.map +1 -0
  361. package/bundle/dedupe/hoist-shared.d.ts +37 -0
  362. package/bundle/dedupe/hoist-shared.d.ts.map +1 -0
  363. package/bundle/dedupe/index.cjs.js +818 -0
  364. package/bundle/dedupe/index.d.ts +400 -0
  365. package/bundle/dedupe/index.d.ts.map +1 -0
  366. package/bundle/dedupe/index.esm.js +766 -0
  367. package/bundle/dedupe/plan-hoists.d.ts +46 -0
  368. package/bundle/dedupe/plan-hoists.d.ts.map +1 -0
  369. package/bundle/dedupe/rewrite-entry.d.ts +39 -0
  370. package/bundle/dedupe/rewrite-entry.d.ts.map +1 -0
  371. package/bundle/dependencies/collect-workspace-deps.d.ts +34 -0
  372. package/bundle/dependencies/collect-workspace-deps.d.ts.map +1 -0
  373. package/bundle/dependencies/externalize-plugin.d.ts +100 -0
  374. package/bundle/dependencies/externalize-plugin.d.ts.map +1 -0
  375. package/bundle/dependencies/index.cjs.js +964 -0
  376. package/bundle/dependencies/index.d.ts +388 -0
  377. package/bundle/dependencies/index.d.ts.map +1 -0
  378. package/bundle/dependencies/index.esm.js +947 -0
  379. package/bundle/dependencies/pre-pass.d.ts +154 -0
  380. package/bundle/dependencies/pre-pass.d.ts.map +1 -0
  381. package/bundle/dependencies/prune/ast-utils.d.ts +121 -0
  382. package/bundle/dependencies/prune/ast-utils.d.ts.map +1 -0
  383. package/bundle/dependencies/prune/chunk-graph.d.ts +175 -0
  384. package/bundle/dependencies/prune/chunk-graph.d.ts.map +1 -0
  385. package/bundle/dependencies/prune/dead-export-pass.d.ts +32 -0
  386. package/bundle/dependencies/prune/dead-export-pass.d.ts.map +1 -0
  387. package/bundle/dependencies/prune/dead-exports.d.ts +36 -0
  388. package/bundle/dependencies/prune/dead-exports.d.ts.map +1 -0
  389. package/bundle/dependencies/prune/destructure-requires-pass.d.ts +31 -0
  390. package/bundle/dependencies/prune/destructure-requires-pass.d.ts.map +1 -0
  391. package/bundle/dependencies/prune/destructure-requires.d.ts +42 -0
  392. package/bundle/dependencies/prune/destructure-requires.d.ts.map +1 -0
  393. package/bundle/dependencies/prune/edits.d.ts +30 -0
  394. package/bundle/dependencies/prune/edits.d.ts.map +1 -0
  395. package/bundle/dependencies/prune/namespace-usage.d.ts +104 -0
  396. package/bundle/dependencies/prune/namespace-usage.d.ts.map +1 -0
  397. package/bundle/dependencies/prune/orphan-chunks.d.ts +69 -0
  398. package/bundle/dependencies/prune/orphan-chunks.d.ts.map +1 -0
  399. package/bundle/dependencies/prune/property-strip-pass.d.ts +38 -0
  400. package/bundle/dependencies/prune/property-strip-pass.d.ts.map +1 -0
  401. package/bundle/dependencies/prune/property-strip.d.ts +69 -0
  402. package/bundle/dependencies/prune/property-strip.d.ts.map +1 -0
  403. package/bundle/dependencies/prune/prune-dependencies.d.ts +52 -0
  404. package/bundle/dependencies/prune/prune-dependencies.d.ts.map +1 -0
  405. package/bundle/dependencies/prune/reachability.d.ts +36 -0
  406. package/bundle/dependencies/prune/reachability.d.ts.map +1 -0
  407. package/bundle/dependencies/prune/specifiers.d.ts +39 -0
  408. package/bundle/dependencies/prune/specifiers.d.ts.map +1 -0
  409. package/bundle/dependencies/prune/strip-comments.d.ts +47 -0
  410. package/bundle/dependencies/prune/strip-comments.d.ts.map +1 -0
  411. package/bundle/dependencies/prune/used-exports.d.ts +32 -0
  412. package/bundle/dependencies/prune/used-exports.d.ts.map +1 -0
  413. package/bundle/dependencies/resolve-bundled-deps.d.ts +37 -0
  414. package/bundle/dependencies/resolve-bundled-deps.d.ts.map +1 -0
  415. package/bundle/dependencies/resolve-dep-entry.d.ts +38 -0
  416. package/bundle/dependencies/resolve-dep-entry.d.ts.map +1 -0
  417. package/bundle/dependencies/resolve-workspace-bundled-deps.d.ts +96 -0
  418. package/bundle/dependencies/resolve-workspace-bundled-deps.d.ts.map +1 -0
  419. package/bundle/dependencies/worker/index.cjs.js +524 -0
  420. package/bundle/dependencies/worker/index.d.ts +102 -0
  421. package/bundle/dependencies/worker/index.d.ts.map +1 -0
  422. package/bundle/dependencies/worker/index.esm.js +515 -0
  423. package/bundle/dependencies/worker/job-runner.d.ts +115 -0
  424. package/bundle/dependencies/worker/job-runner.d.ts.map +1 -0
  425. package/bundle/entries/by-platform.d.ts +27 -0
  426. package/bundle/entries/by-platform.d.ts.map +1 -0
  427. package/bundle/entries/discover-entries.d.ts +24 -0
  428. package/bundle/entries/discover-entries.d.ts.map +1 -0
  429. package/bundle/entries/index.cjs.js +38 -0
  430. package/bundle/entries/index.d.ts +70 -0
  431. package/bundle/entries/index.d.ts.map +1 -0
  432. package/bundle/entries/index.esm.js +33 -0
  433. package/bundle/entries/resolve-entries.d.ts +19 -0
  434. package/bundle/entries/resolve-entries.d.ts.map +1 -0
  435. package/bundle/externals/index.cjs.js +54 -0
  436. package/bundle/externals/index.d.ts +74 -0
  437. package/bundle/externals/index.d.ts.map +1 -0
  438. package/bundle/externals/index.esm.js +51 -0
  439. package/bundle/externals/resolve-externals.d.ts +52 -0
  440. package/bundle/externals/resolve-externals.d.ts.map +1 -0
  441. package/bundle/externals/validate-globals.d.ts +19 -0
  442. package/bundle/externals/validate-globals.d.ts.map +1 -0
  443. package/bundle/fs/deps-root.d.ts +17 -0
  444. package/bundle/fs/deps-root.d.ts.map +1 -0
  445. package/bundle/fs/empty-dirs.d.ts +18 -0
  446. package/bundle/fs/empty-dirs.d.ts.map +1 -0
  447. package/bundle/fs/entry-dir.d.ts +21 -0
  448. package/bundle/fs/entry-dir.d.ts.map +1 -0
  449. package/bundle/fs/posix-path.d.ts +30 -0
  450. package/bundle/fs/posix-path.d.ts.map +1 -0
  451. package/bundle/fs/under-dir.d.ts +19 -0
  452. package/bundle/fs/under-dir.d.ts.map +1 -0
  453. package/bundle/index.cjs.js +4046 -0
  454. package/bundle/index.d.ts +25 -0
  455. package/bundle/index.d.ts.map +1 -0
  456. package/bundle/index.esm.js +3689 -0
  457. package/bundle/rollup/descriptor.d.ts +99 -0
  458. package/bundle/rollup/descriptor.d.ts.map +1 -0
  459. package/bundle/rollup/dispatch.d.ts +72 -0
  460. package/bundle/rollup/dispatch.d.ts.map +1 -0
  461. package/bundle/rollup/index.cjs.js +715 -0
  462. package/bundle/rollup/index.d.ts +174 -0
  463. package/bundle/rollup/index.d.ts.map +1 -0
  464. package/bundle/rollup/index.esm.js +698 -0
  465. package/bundle/rollup/worker/index.cjs.js +290 -0
  466. package/bundle/rollup/worker/index.d.ts +131 -0
  467. package/bundle/rollup/worker/index.d.ts.map +1 -0
  468. package/bundle/rollup/worker/index.esm.js +280 -0
  469. package/bundle/rollup/worker/job-runner.d.ts +18 -0
  470. package/bundle/rollup/worker/job-runner.d.ts.map +1 -0
  471. package/bundle/rollup/worker/types.d.ts +111 -0
  472. package/bundle/rollup/worker/types.d.ts.map +1 -0
  473. package/bundle/run-bundle-phase.d.ts +23 -0
  474. package/bundle/run-bundle-phase.d.ts.map +1 -0
  475. package/clean-output.d.ts +26 -0
  476. package/clean-output.d.ts.map +1 -0
  477. package/index.cjs.js +5317 -0
  478. package/index.d.ts +64 -0
  479. package/index.d.ts.map +1 -0
  480. package/index.esm.js +4910 -0
  481. package/memory/index.cjs.js +101 -0
  482. package/memory/index.d.ts +81 -0
  483. package/memory/index.d.ts.map +1 -0
  484. package/memory/index.esm.js +98 -0
  485. package/memory/monitor.d.ts +59 -0
  486. package/memory/monitor.d.ts.map +1 -0
  487. package/memory/recover.d.ts +19 -0
  488. package/memory/recover.d.ts.map +1 -0
  489. package/models/build-config.d.ts +266 -0
  490. package/models/build-config.d.ts.map +1 -0
  491. package/models/build-context.d.ts +68 -0
  492. package/models/build-context.d.ts.map +1 -0
  493. package/models/build-result.d.ts +43 -0
  494. package/models/build-result.d.ts.map +1 -0
  495. package/models/entry-point.d.ts +45 -0
  496. package/models/entry-point.d.ts.map +1 -0
  497. package/models/format-output.d.ts +34 -0
  498. package/models/format-output.d.ts.map +1 -0
  499. package/models/index.cjs.js +2 -0
  500. package/models/index.d.ts +581 -0
  501. package/models/index.d.ts.map +1 -0
  502. package/models/index.esm.js +1 -0
  503. package/models/package-json.d.ts +130 -0
  504. package/models/package-json.d.ts.map +1 -0
  505. package/package/assets/copy-assets.d.ts +31 -0
  506. package/package/assets/copy-assets.d.ts.map +1 -0
  507. package/package/assets/index.cjs.js +84 -0
  508. package/package/assets/index.d.ts +33 -0
  509. package/package/assets/index.d.ts.map +1 -0
  510. package/package/assets/index.esm.js +82 -0
  511. package/package/finalize-files.d.ts +25 -0
  512. package/package/finalize-files.d.ts.map +1 -0
  513. package/package/index.cjs.js +276 -0
  514. package/package/index.d.ts +56 -0
  515. package/package/index.d.ts.map +1 -0
  516. package/package/index.esm.js +231 -0
  517. package/package/json/cdn-paths.d.ts +41 -0
  518. package/package/json/cdn-paths.d.ts.map +1 -0
  519. package/package/json/filter-deps.d.ts +39 -0
  520. package/package/json/filter-deps.d.ts.map +1 -0
  521. package/package/json/generate-exports.d.ts +29 -0
  522. package/package/json/generate-exports.d.ts.map +1 -0
  523. package/package/json/index.cjs.js +24 -0
  524. package/package/json/index.d.ts +252 -0
  525. package/package/json/index.d.ts.map +1 -0
  526. package/package/json/index.esm.js +14 -0
  527. package/package/json/inherit-fields.d.ts +25 -0
  528. package/package/json/inherit-fields.d.ts.map +1 -0
  529. package/package/json/read-package-json.d.ts +18 -0
  530. package/package/json/read-package-json.d.ts.map +1 -0
  531. package/package/json/reflect-files-allowlist.d.ts +32 -0
  532. package/package/json/reflect-files-allowlist.d.ts.map +1 -0
  533. package/package/json/synthesize.d.ts +53 -0
  534. package/package/json/synthesize.d.ts.map +1 -0
  535. package/package/json/write.d.ts +18 -0
  536. package/package/json/write.d.ts.map +1 -0
  537. package/package/licenses/collect.d.ts +25 -0
  538. package/package/licenses/collect.d.ts.map +1 -0
  539. package/package/licenses/generate-content.d.ts +20 -0
  540. package/package/licenses/generate-content.d.ts.map +1 -0
  541. package/package/licenses/index.cjs.js +135 -0
  542. package/package/licenses/index.d.ts +73 -0
  543. package/package/licenses/index.d.ts.map +1 -0
  544. package/package/licenses/index.esm.js +89 -0
  545. package/package/licenses/license-url.d.ts +20 -0
  546. package/package/licenses/license-url.d.ts.map +1 -0
  547. package/package/licenses/types.d.ts +12 -0
  548. package/package/licenses/types.d.ts.map +1 -0
  549. package/package/licenses/write.d.ts +16 -0
  550. package/package/licenses/write.d.ts.map +1 -0
  551. package/package/run-package-phase.d.ts +30 -0
  552. package/package/run-package-phase.d.ts.map +1 -0
  553. package/package.json +347 -0
  554. package/presets/by-names.d.ts +20 -0
  555. package/presets/by-names.d.ts.map +1 -0
  556. package/presets/by-prefix.d.ts +22 -0
  557. package/presets/by-prefix.d.ts.map +1 -0
  558. package/presets/index.cjs.js +8 -0
  559. package/presets/index.d.ts +43 -0
  560. package/presets/index.d.ts.map +1 -0
  561. package/presets/index.esm.js +5 -0
@@ -0,0 +1,4046 @@
1
+ 'use strict';
2
+
3
+ const index_cjs_js$3 = require('../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/array/index.cjs.js');
4
+ const index_cjs_js$7 = require('../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/error/index.cjs.js');
5
+ const index_cjs_js$2 = require('../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/set/index.cjs.js');
6
+ const index_cjs_js$4 = require('../_dependencies/@hyperfrontend/logging/index.cjs.js');
7
+ const index_cjs_js$5 = require('../_dependencies/@hyperfrontend/project-scope/core/index.cjs.js');
8
+ const index_cjs_js = require('../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/promise/index.cjs.js');
9
+ const index_cjs_js$1 = require('../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/timers/index.cjs.js');
10
+ const node_module = require('node:module');
11
+ const node_path = require('node:path');
12
+ const node_child_process = require('node:child_process');
13
+ const node_fs = require('node:fs');
14
+ const node_os = require('node:os');
15
+ const index_cjs_js$6 = require('../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/json/index.cjs.js');
16
+ const index_cjs_js$8 = require('../_dependencies/@hyperfrontend/project-scope/core/fs/index.cjs.js');
17
+ const index_cjs_js$9 = require('../_dependencies/@hyperfrontend/project-scope/core/path/index.cjs.js');
18
+ const index_cjs_js$a = require('../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/date/index.cjs.js');
19
+ const ts = require('typescript');
20
+ const index_cjs_js$b = require('../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/map/index.cjs.js');
21
+ const index_cjs_js$c = require('../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/math/index.cjs.js');
22
+ const index_cjs_js$d = require('../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/object/index.cjs.js');
23
+ const { recover } = require('../_shared/memory/recover/index.cjs.js');
24
+ const { normalizeToForwardSlashes, join } = require('../_shared/bundle/fs/posix-path/index.cjs.js');
25
+ const { buildWorkspaceRoutes } = require('../_shared/bundle/dependencies/externalize-plugin/index.cjs.js');
26
+ const { validateExternalsConfig } = require('../_shared/bundle/externals/validate-globals/index.cjs.js');
27
+ const { depsRootOf } = require('../_shared/bundle/fs/deps-root/index.cjs.js');
28
+ const { collectWorkspacePrefixDeps, collectWorkspaceExactSpecifiers } = require('../_shared/bundle/dependencies/collect-workspace-deps/index.cjs.js');
29
+ const { flattenDeclarationPaths } = require('../_shared/bundle/declarations/flatten-paths/index.cjs.js');
30
+ const { collectChunkSpecifiers, hasDynamicSpecifier } = require('../_shared/bundle/dependencies/prune/specifiers/index.cjs.js');
31
+ const { entryDirOf } = require('../_shared/bundle/fs/entry-dir/index.cjs.js');
32
+ const { isUnderDir } = require('../_shared/bundle/fs/under-dir/index.cjs.js');
33
+ const { removeEmptyDirs } = require('../_shared/bundle/fs/empty-dirs/index.cjs.js');
34
+ const { resolveEntries } = require('../_shared/bundle/entries/resolve-entries/index.cjs.js');
35
+
36
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
37
+
38
+ const ts__default = /*#__PURE__*/_interopDefaultCompat(ts);
39
+
40
+ const log$b = index_cjs_js$4.logger.channel('builder:bundle:dependencies:pre-pass');
41
+ const REPORT_DIR_PREFIX$1 = 'hf-builder-prepass-';
42
+ const createReportDir$1 = () => node_fs.mkdtempSync(index_cjs_js$5.join(node_os.tmpdir(), REPORT_DIR_PREFIX$1));
43
+ const reportPathFor$1 = (reportDir, job, index) => index_cjs_js$5.join(reportDir, `${index}-${job.dep.replace(/\//g, '__')}-${job.kind}-${job.format}.json`);
44
+ const runOne$1 = (job, reportPath, options) => index_cjs_js.createPromise((resolve, reject) => {
45
+ const execPath = options.execPath ?? process.execPath;
46
+ const argv = [...(options.execArgv ?? []), options.workerPath, index_cjs_js$6.stringify({ ...job, reportPath })];
47
+ const child = node_child_process.spawn(execPath, argv, { stdio: ['ignore', 'pipe', 'pipe'] });
48
+ let capturedStderr = '';
49
+ child.stdout?.on('data', (chunk) => {
50
+ process.stdout.write(chunk);
51
+ });
52
+ child.stderr?.on('data', (chunk) => {
53
+ const text = typeof chunk === 'string' ? chunk : chunk.toString();
54
+ capturedStderr += text;
55
+ process.stderr.write(text);
56
+ });
57
+ child.on('error', (error) => {
58
+ reject(index_cjs_js$7.createError(`pre-pass worker for ${job.dep} (${job.kind}/${job.format}) failed to spawn: ${error.message}`));
59
+ });
60
+ child.on('exit', (code) => {
61
+ if (code !== 0) {
62
+ const tail = capturedStderr.trim().split('\n').slice(-10).join('\n');
63
+ reject(index_cjs_js$7.createError(`pre-pass worker for ${job.dep} (${job.kind}/${job.format}) exited with code ${code}\n${tail}`));
64
+ return;
65
+ }
66
+ resolve();
67
+ });
68
+ });
69
+ const readReport$1 = (reportPath, job) => {
70
+ if (!node_fs.existsSync(reportPath)) {
71
+ throw index_cjs_js$7.createError(`pre-pass worker for ${job.dep} (${job.kind}/${job.format}) did not write a report at ${reportPath}`);
72
+ }
73
+ const data = index_cjs_js$6.parse(node_fs.readFileSync(reportPath, 'utf8'));
74
+ return { job, outputSize: data.outputSize, endHeapMB: data.endHeapMB, endRssMB: data.endRssMB, durationMs: data.durationMs };
75
+ };
76
+ const SWC_NODE_REGISTER$1 = '@swc-node/register';
77
+ const swcNodeAvailable$1 = (workspaceRoot) => node_fs.existsSync(index_cjs_js$5.join(workspaceRoot, 'node_modules', '@swc-node', 'register', 'index.js'));
78
+ /**
79
+ * Default worker-path resolution: prefers the built-and-published artifact, falls
80
+ * back to the workspace dist path, and finally to the in-source TypeScript file
81
+ * via `@swc-node/register` (bootstrap case where builder is building itself for
82
+ * the first time and the dist worker doesn't exist yet).
83
+ *
84
+ * Looks at, in order:
85
+ * 1. `<workspaceRoot>/dist/libs/builder/bundle/dependencies/worker/index.cjs.js`
86
+ * 2. `<workspaceRoot>/node_modules/@hyperfrontend/builder/bundle/dependencies/worker/index.cjs.js`
87
+ * 3. `<workspaceRoot>/libs/builder/src/bundle/dependencies/worker/index.ts` (with `--require \@swc-node/register`)
88
+ *
89
+ * @param workspaceRoot - Absolute workspace root.
90
+ * @returns Worker invocation descriptor, or `undefined` if no candidate exists.
91
+ *
92
+ * @example Locating the worker for an in-workspace consumer
93
+ * ```typescript
94
+ * const invocation = resolveDefaultWorkerPath('/abs/repo')
95
+ * if (!invocation) throw new Error('builder worker artifact not found')
96
+ * ```
97
+ */
98
+ const resolveDefaultWorkerPath = (workspaceRoot) => {
99
+ const distCandidates = [
100
+ index_cjs_js$5.join(workspaceRoot, 'dist', 'libs', 'builder', 'bundle', 'dependencies', 'worker', 'index.cjs.js'),
101
+ index_cjs_js$5.join(workspaceRoot, 'node_modules', '@hyperfrontend', 'builder', 'bundle', 'dependencies', 'worker', 'index.cjs.js'),
102
+ ];
103
+ for (const path of distCandidates) {
104
+ if (node_fs.existsSync(path))
105
+ return { path, execArgv: [] };
106
+ }
107
+ const sourcePath = index_cjs_js$5.join(workspaceRoot, 'libs', 'builder', 'src', 'bundle', 'dependencies', 'worker', 'index.ts');
108
+ if (node_fs.existsSync(sourcePath) && swcNodeAvailable$1(workspaceRoot)) {
109
+ return { path: sourcePath, execArgv: ['--require', SWC_NODE_REGISTER$1] };
110
+ }
111
+ return undefined;
112
+ };
113
+ /**
114
+ * Sequentially runs the supplied pre-pass jobs by forking a fresh Node child
115
+ * per invocation. Strict sequential execution is mandatory — concurrent
116
+ * children would simultaneously pressure RAM and OOM the container.
117
+ *
118
+ * Each child writes a JSON report to a parent-supplied path; this function
119
+ * reads the report after the child exits and accumulates per-job statistics.
120
+ * If any worker exits non-zero or fails to produce a report, the function
121
+ * throws with the failed job's context.
122
+ *
123
+ * The report directory is created in the OS temp dir and removed before
124
+ * returning, regardless of success or failure.
125
+ *
126
+ * @param jobs - Pre-pass jobs to run.
127
+ * @param options - Worker path + optional memory monitor.
128
+ * @returns One result per supplied job, in the order the jobs were given.
129
+ *
130
+ * @example Pre-passing rollup and one of its plugins
131
+ * ```typescript
132
+ * const results = await runPrePass(jobs, { workerPath: '/abs/dist/libs/builder/bundle/dependencies/worker.cjs.js' })
133
+ * ```
134
+ */
135
+ const runPrePass = async (jobs, options) => {
136
+ if (jobs.length === 0)
137
+ return [];
138
+ const reportDir = createReportDir$1();
139
+ const results = [];
140
+ try {
141
+ for (const [index, job] of jobs.entries()) {
142
+ const reportPath = reportPathFor$1(reportDir, job, index);
143
+ log$b.info(`pre-pass ${index + 1}/${jobs.length}: ${job.dep} (${job.kind}/${job.format})`);
144
+ options.monitor?.check(`bundle:dependencies:prepass:${index + 1}/${jobs.length}:${job.dep}:${job.kind}:${job.format}:start`);
145
+ await runOne$1(job, reportPath, options);
146
+ const result = readReport$1(reportPath, job);
147
+ log$b.debug(`pre-pass ${index + 1}/${jobs.length} done: ${job.dep} size=${result.outputSize}B heap=${result.endHeapMB.toFixed(1)}MB rss=${result.endRssMB.toFixed(1)}MB t=${result.durationMs}ms`);
148
+ options.monitor?.check(`bundle:dependencies:prepass:${index + 1}/${jobs.length}:${job.dep}:${job.kind}:${job.format}:end`);
149
+ results.push(result);
150
+ }
151
+ return results;
152
+ }
153
+ finally {
154
+ node_fs.rmSync(reportDir, { recursive: true, force: true });
155
+ }
156
+ };
157
+
158
+ /**
159
+ * Joins an output base directory with an entry's `srcPath` to produce the
160
+ * absolute path of the entry's bundled `index.d.ts`.
161
+ *
162
+ * @param outputPath - Absolute output directory.
163
+ * @param srcPath - Entry's `srcPath`. `''` for root.
164
+ * @returns Absolute path to `<outputPath>/<srcPath>/index.d.ts`.
165
+ *
166
+ * @example Computing the d.ts path for a sub-entry
167
+ * ```typescript
168
+ * dtsPathFor('/abs/dist/libs/foo', 'models') // => '/abs/dist/libs/foo/models/index.d.ts'
169
+ * ```
170
+ */
171
+ const dtsPathFor = (outputPath, srcPath) => srcPath ? join(outputPath, srcPath, 'index.d.ts') : join(outputPath, 'index.d.ts');
172
+
173
+ const log$a = index_cjs_js$4.logger.channel('builder:bundle:declarations:dts-per-entry');
174
+ const buildSiblingDescriptors = (entries, context, currentSrcPath) => {
175
+ const descriptors = [];
176
+ for (const entry of entries) {
177
+ if (entry.srcPath === currentSrcPath)
178
+ continue;
179
+ const indexDtsPath = dtsPathFor(context.outputPath, entry.srcPath);
180
+ if (!index_cjs_js$5.exists(indexDtsPath))
181
+ continue;
182
+ descriptors.push({ srcPath: entry.srcPath, indexDtsPath });
183
+ }
184
+ return descriptors;
185
+ };
186
+ const buildJobs$1 = (entries, context) => {
187
+ const jobs = [];
188
+ const workspacePrefixDeps = collectWorkspacePrefixDeps(context);
189
+ const workspaceExactSpecifiers = collectWorkspaceExactSpecifiers(context);
190
+ const workspaceRoutes = buildWorkspaceRoutes(context.workspaceBundledDeps);
191
+ const depsRoot = depsRootOf(context);
192
+ for (const entry of entries) {
193
+ const inputPath = dtsPathFor(context.outputPath, entry.srcPath);
194
+ if (!index_cjs_js$5.exists(inputPath))
195
+ continue;
196
+ const siblingEntries = buildSiblingDescriptors(entries, context, entry.srcPath);
197
+ jobs.push({
198
+ kind: 'dts',
199
+ dep: entry.exportPath,
200
+ inputPath,
201
+ format: 'esm',
202
+ outputPath: inputPath,
203
+ otherDeps: [...context.bundledDeps, ...workspacePrefixDeps],
204
+ otherWorkspaceSpecifiers: workspaceExactSpecifiers,
205
+ siblingEntries,
206
+ selfDtsPath: inputPath,
207
+ selfSrcPath: entry.srcPath,
208
+ npmDeps: context.bundledDeps,
209
+ workspaceRoutes,
210
+ depsRoot,
211
+ });
212
+ }
213
+ return jobs;
214
+ };
215
+ /**
216
+ * Runs the per-entry d.ts inlining pass: re-runs `rollup-plugin-dts` over every
217
+ * tsc-emitted entry `.d.ts` so (a) local per-source sibling re-exports
218
+ * (`export … from './create-logger'`) are flattened into the entry's
219
+ * `index.d.ts`, and (b) bundled-dep type imports are routed through
220
+ * `_dependencies/<dep>/index.d.ts` rather than left as bare specifiers. This
221
+ * self-containment is what lets `pruneOrphanDeclarations` delete the orphaned
222
+ * per-source `.d.ts` afterwards without orphaning a still-referenced sibling.
223
+ *
224
+ * Runs whenever the build bundles any dep — npm (`bundledDeps`) **or** workspace
225
+ * (`workspaceBundledDeps`); a package whose deps are all `@hyperfrontend/*` still
226
+ * needs the flatten. Entries whose tsc output is missing are skipped silently —
227
+ * the bundle phase may have skipped them deliberately (e.g., empty bundles).
228
+ *
229
+ * @param context - Resolved build context.
230
+ * @param monitor - Optional memory monitor invoked between jobs.
231
+ * @throws {Error} When the worker artifact cannot be located, or when any per-entry job fails.
232
+ *
233
+ * @example Inlining bundled-dep types into every entry's .d.ts after tsc emission
234
+ * ```typescript
235
+ * await runDtsPerEntry(context)
236
+ * ```
237
+ */
238
+ const runDtsPerEntry = async (context, monitor) => {
239
+ if (context.bundledDeps.length === 0 && context.workspaceBundledDeps.length === 0)
240
+ return;
241
+ const invocation = resolveDefaultWorkerPath(context.workspaceRoot);
242
+ if (!invocation) {
243
+ throw index_cjs_js$7.createError('bundleAllDeps is enabled but the pre-pass worker artifact was not found for the per-entry d.ts pass.');
244
+ }
245
+ const jobs = buildJobs$1(context.entryPointDiscovery.entryPoints, context);
246
+ if (jobs.length === 0) {
247
+ log$a.debug('per-entry d.ts pass: no entries with tsc-emitted .d.ts files');
248
+ return;
249
+ }
250
+ log$a.info(`per-entry d.ts pass: ${jobs.length} entries`);
251
+ monitor?.check('bundle:declarations:dts-perentry:start');
252
+ await runPrePass(jobs, { workerPath: invocation.path, execArgv: invocation.execArgv, monitor });
253
+ monitor?.check('bundle:declarations:dts-perentry:end');
254
+ };
255
+
256
+ const ROOTS = (projectRoot, workspaceRoot) => [projectRoot, workspaceRoot];
257
+ const findPackageJsonByWalkingUp = (entryPath, dep) => {
258
+ const segments = entryPath.split('/');
259
+ for (let i = segments.length - 1; i > 0; i--) {
260
+ const prefix = segments.slice(0, i).join('/');
261
+ const candidate = `${prefix}/package.json`;
262
+ if (!index_cjs_js$8.exists(candidate))
263
+ continue;
264
+ try {
265
+ const meta = index_cjs_js$8.readJsonFileIfExists(candidate);
266
+ if (meta?.name === dep)
267
+ return candidate;
268
+ }
269
+ catch {
270
+ // fall through
271
+ }
272
+ }
273
+ return undefined;
274
+ };
275
+ const findPackageJsonViaRequire = (dep, fromRoots) => {
276
+ for (const root of fromRoots) {
277
+ try {
278
+ const anchor = index_cjs_js$9.join(root, 'package.json');
279
+ if (!index_cjs_js$8.exists(anchor))
280
+ continue;
281
+ const req = node_module.createRequire(anchor);
282
+ const direct = `${dep}/package.json`;
283
+ try {
284
+ const path = req.resolve(direct);
285
+ if (index_cjs_js$8.exists(path))
286
+ return path;
287
+ }
288
+ catch {
289
+ // package may restrict ./package.json via exports — fall through to entry-anchored walk
290
+ }
291
+ try {
292
+ const entryPath = req.resolve(dep);
293
+ const found = findPackageJsonByWalkingUp(entryPath, dep);
294
+ if (found)
295
+ return found;
296
+ }
297
+ catch {
298
+ // entry resolution may also fail (e.g., type-only package); try the next root
299
+ }
300
+ }
301
+ catch {
302
+ // try next root
303
+ }
304
+ }
305
+ return undefined;
306
+ };
307
+ const ensureJsEntry = (pkg) => pkg.module ?? pkg.main;
308
+ const ensureDtsEntry = (pkg) => pkg.types ?? pkg.typings;
309
+ const absolutize = (relativeTo, rel) => {
310
+ if (node_path.isAbsolute(rel))
311
+ return index_cjs_js$9.normalizeToForwardSlashes(rel);
312
+ return index_cjs_js$9.normalizeToForwardSlashes(node_path.resolve(relativeTo, rel));
313
+ };
314
+ /**
315
+ * Resolves the absolute path to a bundled dep's entry file (JS or `.d.ts`) for a
316
+ * pre-pass invocation.
317
+ *
318
+ * For JS jobs the resolution prefers the dep's `module` field (ESM) over `main`
319
+ * (CJS). For dts jobs it prefers `types` over `typings`. Lookup walks the project
320
+ * root first, then the workspace root, using `createRequire` so node's standard
321
+ * resolution semantics apply (including support for hoisted `node_modules`).
322
+ *
323
+ * @param options - Dep name, root paths, and kind.
324
+ * @returns Absolute path to the dep's entry file.
325
+ * @throws {Error} When the dep's `package.json` cannot be located or it lacks the
326
+ * required entry field.
327
+ *
328
+ * @example Resolving the runtime entry for `rollup`
329
+ * ```typescript
330
+ * const entry = resolveDepEntry({ dep: 'rollup', projectRoot, workspaceRoot, kind: 'js' })
331
+ * ```
332
+ */
333
+ const resolveDepEntry = (options) => {
334
+ const { dep, projectRoot, workspaceRoot, kind } = options;
335
+ const pkgPath = findPackageJsonViaRequire(dep, ROOTS(projectRoot, workspaceRoot));
336
+ if (!pkgPath)
337
+ throw index_cjs_js$7.createError(`pre-pass: cannot locate package.json for dep "${dep}"`);
338
+ const pkg = index_cjs_js$8.readJsonFileIfExists(pkgPath);
339
+ if (!pkg)
340
+ throw index_cjs_js$7.createError(`pre-pass: package.json for dep "${dep}" could not be read at ${pkgPath}`);
341
+ const relative = kind === 'js' ? ensureJsEntry(pkg) : ensureDtsEntry(pkg);
342
+ if (!relative)
343
+ throw index_cjs_js$7.createError(`pre-pass: dep "${dep}" has no ${kind === 'js' ? 'main/module' : 'types/typings'} entry`);
344
+ return absolutize(node_path.dirname(pkgPath), relative);
345
+ };
346
+
347
+ const log$9 = index_cjs_js$4.logger.channel('builder:bundle:declarations:dts-pre-pass');
348
+ const workspaceDtsOutputFile = (entry) => entry.subPath ? `${entry.specifier}/index.d.ts` : `${entry.packageName}/index.d.ts`;
349
+ const filterRouteEntries$1 = (entry, all) => all.filter((other) => (entry.policy === 'sub-path' ? other.specifier !== entry.specifier : other.packageName !== entry.packageName));
350
+ const buildJobs = (deps, context) => {
351
+ const depsRoot = depsRootOf(context);
352
+ const jobs = [];
353
+ const workspacePrefixDeps = collectWorkspacePrefixDeps(context);
354
+ const workspaceExactSpecifiers = collectWorkspaceExactSpecifiers(context);
355
+ const workspaceRoutes = buildWorkspaceRoutes(context.workspaceBundledDeps);
356
+ for (const dep of deps) {
357
+ let inputPath;
358
+ try {
359
+ inputPath = resolveDepEntry({ dep, projectRoot: context.projectRoot, workspaceRoot: context.workspaceRoot, kind: 'dts' });
360
+ }
361
+ catch (error) {
362
+ log$9.warn(`skipping d.ts pre-pass for ${dep}: ${error instanceof Error ? error.message : String(error)}`);
363
+ continue;
364
+ }
365
+ const otherNpmDeps = deps.filter((d) => d !== dep);
366
+ jobs.push({
367
+ kind: 'dts',
368
+ dep,
369
+ inputPath,
370
+ format: 'esm',
371
+ outputPath: index_cjs_js$5.join(depsRoot, dep, 'index.d.ts'),
372
+ otherDeps: [...otherNpmDeps, ...workspacePrefixDeps],
373
+ otherWorkspaceSpecifiers: workspaceExactSpecifiers,
374
+ npmDeps: otherNpmDeps,
375
+ workspaceRoutes,
376
+ depsRoot,
377
+ });
378
+ }
379
+ return jobs;
380
+ };
381
+ const buildWorkspaceJobs = (context, npmDeps) => {
382
+ if (context.workspaceBundledDeps.length === 0)
383
+ return [];
384
+ const depsRoot = depsRootOf(context);
385
+ const wholeSurface = collectWorkspacePrefixDeps(context);
386
+ const subPathSpecifiers = collectWorkspaceExactSpecifiers(context);
387
+ const jobs = [];
388
+ for (const entry of context.workspaceBundledDeps) {
389
+ const otherWorkspacePackages = wholeSurface.filter((name) => name !== entry.packageName || entry.policy === 'sub-path');
390
+ const otherSubPathSpecifiers = subPathSpecifiers.filter((spec) => spec !== entry.specifier);
391
+ const workspaceRoutes = buildWorkspaceRoutes(filterRouteEntries$1(entry, context.workspaceBundledDeps));
392
+ jobs.push({
393
+ kind: 'workspace-dts',
394
+ dep: entry.specifier,
395
+ inputPath: entry.inputPath,
396
+ format: 'esm',
397
+ outputPath: index_cjs_js$5.join(depsRoot, workspaceDtsOutputFile(entry)),
398
+ otherDeps: [...npmDeps, ...otherWorkspacePackages],
399
+ otherWorkspaceSpecifiers: otherSubPathSpecifiers,
400
+ tsConfigPath: entry.tsConfigPath,
401
+ workspaceRoot: context.workspaceRoot,
402
+ npmDeps,
403
+ workspaceRoutes,
404
+ depsRoot,
405
+ });
406
+ }
407
+ return jobs;
408
+ };
409
+ /**
410
+ * Runs the d.ts pre-pass: for each bundled dep, produces `_dependencies/<dep>/index.d.ts`
411
+ * by running `rollup-plugin-dts` over the dep's types entry. Cross-dep type imports are
412
+ * marked external so the per-entry d.ts pass can route them through `_dependencies/`.
413
+ *
414
+ * @param context - Resolved build context.
415
+ * @param monitor - Optional memory monitor invoked between jobs.
416
+ * @throws {Error} When the worker artifact cannot be located, or when any d.ts job fails.
417
+ *
418
+ * @example Producing _dependencies/<dep>/index.d.ts for a self-contained build
419
+ * ```typescript
420
+ * await runDtsPrePass(context)
421
+ * ```
422
+ */
423
+ const runDtsPrePass = async (context, monitor) => {
424
+ if (context.bundledDeps.length === 0 && context.workspaceBundledDeps.length === 0)
425
+ return;
426
+ const invocation = resolveDefaultWorkerPath(context.workspaceRoot);
427
+ if (!invocation) {
428
+ throw index_cjs_js$7.createError('bundleAllDeps is enabled but the pre-pass worker artifact was not found for the d.ts pre-pass.');
429
+ }
430
+ const npmJobs = buildJobs(context.bundledDeps, context);
431
+ const workspaceJobs = buildWorkspaceJobs(context, context.bundledDeps);
432
+ const jobs = [...npmJobs, ...workspaceJobs];
433
+ if (jobs.length === 0) {
434
+ log$9.debug('d.ts pre-pass: no eligible deps (all skipped due to missing types)');
435
+ return;
436
+ }
437
+ log$9.info(`d.ts pre-pass: ${npmJobs.length} npm + ${workspaceJobs.length} workspace = ${jobs.length} job(s)`);
438
+ monitor?.check('bundle:declarations:dts-prepass:start');
439
+ await runPrePass(jobs, { workerPath: invocation.path, execArgv: invocation.execArgv, monitor });
440
+ monitor?.check('bundle:declarations:dts-prepass:end');
441
+ };
442
+
443
+ const log$8 = index_cjs_js$4.logger.channel('builder:bundle:declarations');
444
+ const HEARTBEAT_INTERVAL_MS = 5000;
445
+ const BYTES_PER_MB = 1024 * 1024;
446
+ const formatMB = (bytes) => (bytes / BYTES_PER_MB).toFixed(1);
447
+ const startHeartbeat = (label, startedAt) => index_cjs_js$1.setInterval(() => {
448
+ const usage = process.memoryUsage();
449
+ const elapsedSec = ((index_cjs_js$a.dateNow() - startedAt) / 1000).toFixed(1);
450
+ log$8.info(`${label} still running: elapsed=${elapsedSec}s parent heap=${formatMB(usage.heapUsed)}MB rss=${formatMB(usage.rss)}MB`);
451
+ }, HEARTBEAT_INTERVAL_MS);
452
+ const runTsc = (tscPath, args, cwd) => index_cjs_js.createPromise((resolve, reject) => {
453
+ const startedAt = index_cjs_js$a.dateNow();
454
+ const child = node_child_process.spawn(tscPath, args, { cwd, stdio: ['ignore', 'pipe', 'pipe'] });
455
+ log$8.info(`tsc spawned: pid=${child.pid ?? 'unknown'}`);
456
+ log$8.debug(`tsc args: ${args.join(' ')}`);
457
+ const heartbeat = startHeartbeat('tsc', startedAt);
458
+ let stdout = '';
459
+ let stderr = '';
460
+ child.stdout.on('data', (chunk) => {
461
+ const text = chunk.toString();
462
+ stdout += text;
463
+ log$8.debug(text.trimEnd());
464
+ });
465
+ child.stderr.on('data', (chunk) => {
466
+ const text = chunk.toString();
467
+ stderr += text;
468
+ log$8.warn(text.trimEnd());
469
+ });
470
+ child.on('error', (error) => {
471
+ index_cjs_js$1.clearInterval(heartbeat);
472
+ log$8.error(`tsc spawn error: ${error.message}`);
473
+ reject(error);
474
+ });
475
+ child.on('close', (code) => {
476
+ index_cjs_js$1.clearInterval(heartbeat);
477
+ const durationMs = index_cjs_js$a.dateNow() - startedAt;
478
+ if (code !== 0) {
479
+ log$8.error(`tsc failed with exit code ${code} after ${durationMs}ms`);
480
+ reject(index_cjs_js$7.createError(`tsc failed with exit code ${code}`));
481
+ return;
482
+ }
483
+ log$8.info(`tsc exited 0 in ${durationMs}ms`);
484
+ resolve({ success: true, stdout, stderr });
485
+ });
486
+ });
487
+ /**
488
+ * Generates `.d.ts` and `.d.ts.map` files for every entry point in the project
489
+ * by spawning the workspace-local TypeScript compiler.
490
+ *
491
+ * After tsc finishes, calls `flattenDeclarationPaths` to relocate the nested
492
+ * `dist/<lib>/libs/<lib>/src/...` structure that tsc emits with `baseUrl=workspaceRoot`
493
+ * back into the flat per-library shape consumers expect.
494
+ *
495
+ * @param context - Resolved build context. Provides project root, output path, tsconfig path,
496
+ * workspace root, and entry point discovery for the flatten step.
497
+ * @returns Promise resolving with tsc's exit status, captured stdout, and captured stderr.
498
+ * @throws {Error} When tsc exits with a non-zero status or fails to spawn.
499
+ *
500
+ * @example Generating declarations as part of a custom build
501
+ * ```typescript
502
+ * const result = await generateDeclarations(context)
503
+ * console.log(result.stdout)
504
+ * ```
505
+ */
506
+ const generateDeclarations = async (context) => {
507
+ log$8.info('generating typescript declarations');
508
+ const usage = process.memoryUsage();
509
+ log$8.info(`pre-tsc memory: parent heap=${formatMB(usage.heapUsed)}MB rss=${formatMB(usage.rss)}MB`);
510
+ const tscPath = index_cjs_js$9.join(context.workspaceRoot, 'node_modules', '.bin', 'tsc');
511
+ const args = [
512
+ '--project',
513
+ context.tsConfigPath,
514
+ '--noEmit',
515
+ 'false',
516
+ '--emitDeclarationOnly',
517
+ '--declaration',
518
+ '--declarationMap',
519
+ '--outDir',
520
+ context.outputPath,
521
+ ];
522
+ const result = await runTsc(tscPath, args, context.projectRoot);
523
+ log$8.info('flattening declaration paths');
524
+ const flattenStart = index_cjs_js$a.dateNow();
525
+ flattenDeclarationPaths(context);
526
+ log$8.info(`flatten complete in ${index_cjs_js$a.dateNow() - flattenStart}ms`);
527
+ return result;
528
+ };
529
+
530
+ const log$7 = index_cjs_js$4.logger.channel('builder:bundle:declarations:prune-orphans');
531
+ const ORPHAN_DTS_RE = /\.d\.ts$|\.d\.ts\.map$/;
532
+ const INDEX_DTS_NAME = 'index.d.ts';
533
+ /**
534
+ * Resolves a relative specifier found in a `.d.ts` to the absolute `.d.ts` file
535
+ * it points at, or `null` when it resolves to nothing on disk or into
536
+ * `_dependencies/`.
537
+ *
538
+ * Declaration specifiers are extensionless (`./create-logger`, `./shared/consts`)
539
+ * or directory imports (`./shared` → `shared/index.d.ts`); the canonical
540
+ * `_dependencies` routing uses an explicit runtime extension (`.../index.js`),
541
+ * which is rewritten to its declaration sibling. Targets under `depsRoot` are
542
+ * never edges for this pass — bundled-dep declarations are managed by the
543
+ * dependency Type Prune, and this pass must never touch them.
544
+ *
545
+ * @param dir - Absolute directory of the referencing `.d.ts`.
546
+ * @param spec - Relative specifier text (already known to start with `.`).
547
+ * @param depsRoot - Absolute path to the `_dependencies/` directory.
548
+ * @returns Absolute `.d.ts` path of the referenced sibling, or `null`.
549
+ */
550
+ const toDtsTarget$1 = (dir, spec, depsRoot) => {
551
+ const abs = index_cjs_js$5.join(dir, spec);
552
+ // why: a `.js` specifier is the bundled-dep routing shape; map it onto its declaration sibling.
553
+ const candidates = spec.endsWith('.js') ? [`${abs.slice(0, -3)}.d.ts`] : [`${abs}.d.ts`, index_cjs_js$5.join(abs, INDEX_DTS_NAME)];
554
+ for (const candidate of candidates) {
555
+ if (isUnderDir(candidate, depsRoot))
556
+ return null;
557
+ if (index_cjs_js$5.exists(candidate))
558
+ return candidate;
559
+ }
560
+ return null;
561
+ };
562
+ /**
563
+ * Computes the set of `.d.ts` files reachable from the entry-point `index.d.ts`
564
+ * roots by transitively following their relative specifiers.
565
+ *
566
+ * Breadth-first: each visited file's text is read, scanned once, then released
567
+ * before the next, so only one declaration source is resident at a time and the
568
+ * memory profile stays flat. Edges into `_dependencies/` and to non-existent
569
+ * targets are dropped. The specifier scan over-approximates (a spurious match
570
+ * over-keeps harmless bytes) so it never under-keeps a referenced sibling.
571
+ *
572
+ * If any reached `.d.ts` contains a dynamic (non-literal) `import(`/`require(`,
573
+ * the graph cannot be fully resolved, so the function returns `null` — the
574
+ * safe sentinel that makes the caller keep every declaration.
575
+ *
576
+ * @param roots - Absolute paths to the entry-point `index.d.ts` roots.
577
+ * @param depsRoot - Absolute path to the `_dependencies/` directory.
578
+ * @returns The set of reachable absolute `.d.ts` paths, or `null` on a dynamic
579
+ * specifier bail.
580
+ */
581
+ const computeReachableDeclarations = (roots, depsRoot) => {
582
+ const reachable = index_cjs_js$2.createSet([]);
583
+ const queue = [];
584
+ for (const root of roots) {
585
+ if (index_cjs_js$5.exists(root) && !reachable.has(root)) {
586
+ reachable.add(root);
587
+ queue.push(root);
588
+ }
589
+ }
590
+ let head = 0;
591
+ while (head < queue.length) {
592
+ const file = queue[head];
593
+ head += 1;
594
+ // why: every queued path was `exists`-checked before enqueue (roots and `toDtsTarget` targets), so a direct read is safe.
595
+ const source = index_cjs_js$5.readFileContent(file);
596
+ if (hasDynamicSpecifier(source)) {
597
+ log$7.warn(`dynamic import/require in ${file}; keeping all orphan declarations for safety`);
598
+ return null;
599
+ }
600
+ const dir = index_cjs_js$5.getDirname(file);
601
+ for (const spec of collectChunkSpecifiers(source)) {
602
+ const target = toDtsTarget$1(dir, spec, depsRoot);
603
+ if (target !== null && !reachable.has(target)) {
604
+ reachable.add(target);
605
+ queue.push(target);
606
+ }
607
+ }
608
+ }
609
+ return reachable;
610
+ };
611
+ /**
612
+ * Collects every `.d.ts` / `.d.ts.map` file under `root`, recursing the whole
613
+ * package tree but skipping the `_dependencies/` subtree (managed by the
614
+ * dependency Type Prune, never touched here).
615
+ *
616
+ * @param root - Absolute path to the package output root.
617
+ * @param depsRoot - Absolute path to the `_dependencies/` directory.
618
+ * @returns Absolute paths of all declaration files outside `_dependencies/`.
619
+ */
620
+ const collectDeclarationFiles = (root, depsRoot) => {
621
+ const files = [];
622
+ if (!index_cjs_js$5.exists(root))
623
+ return files;
624
+ const visit = (dir) => {
625
+ for (const entry of index_cjs_js$5.readDirectory(dir)) {
626
+ if (entry.isDirectory) {
627
+ if (isUnderDir(entry.path, depsRoot))
628
+ continue;
629
+ visit(entry.path);
630
+ }
631
+ else if (entry.isFile && ORPHAN_DTS_RE.test(entry.name)) {
632
+ files.push(entry.path);
633
+ }
634
+ }
635
+ };
636
+ visit(root);
637
+ return files;
638
+ };
639
+ /**
640
+ * Removes redundant per-source `.d.ts` / `.d.ts.map` files left behind once the
641
+ * per-entry flatten has inlined each entry's declarations into a self-contained
642
+ * `index.d.ts`.
643
+ *
644
+ * Walks the whole package tree (excluding `_dependencies/`) and deletes every
645
+ * declaration file **not reachable** from an entry-point `index.d.ts` via its
646
+ * transitive relative specifiers. Reachability — rather than a per-directory
647
+ * sweep — guarantees the invariant that after this runs no surviving `.d.ts`
648
+ * references a removed one: when the flatten made `index.d.ts` self-contained
649
+ * the reachable set collapses to the roots and every per-source sibling is
650
+ * pruned; when the flatten was skipped the siblings the public entry still
651
+ * re-exports (and anything they transitively re-export) stay live so the shipped
652
+ * types resolve. This removes the redundancy at the source so `dist` == the
653
+ * shipped tarball, demoting `package.json#files` to a backstop.
654
+ *
655
+ * Safety rails:
656
+ * - Never touches anything inside `_dependencies/`.
657
+ * - A `.d.ts.map` is kept iff its sibling `.d.ts` is reachable.
658
+ * - A dynamic (non-literal) `import(`/`require(` in any reached declaration
659
+ * aborts the prune and keeps every declaration file.
660
+ *
661
+ * @param context - Resolved build context.
662
+ * @returns The total number of `.d.ts` / `.d.ts.map` files removed.
663
+ *
664
+ * @example Pruning orphans after generateDeclarations
665
+ * ```typescript
666
+ * const removed = pruneOrphanDeclarations(context)
667
+ * ```
668
+ */
669
+ const pruneOrphanDeclarations = (context) => {
670
+ const depsRoot = depsRootOf(context);
671
+ const roots = [];
672
+ for (const entry of context.entryPointDiscovery.entryPoints) {
673
+ const dir = entryDirOf(entry, context);
674
+ if (isUnderDir(dir, depsRoot))
675
+ continue;
676
+ roots.push(index_cjs_js$5.join(dir, INDEX_DTS_NAME));
677
+ }
678
+ const reachable = computeReachableDeclarations(roots, depsRoot);
679
+ if (reachable === null)
680
+ return 0;
681
+ let total = 0;
682
+ for (const file of collectDeclarationFiles(context.outputPath, depsRoot)) {
683
+ // why: a `.d.ts.map` shares the liveness of its `.d.ts` sibling, keyed by stripping the trailing `.map`.
684
+ const dtsKey = file.endsWith('.d.ts.map') ? file.slice(0, -4) : file;
685
+ if (reachable.has(dtsKey))
686
+ continue;
687
+ node_fs.unlinkSync(file);
688
+ total += 1;
689
+ }
690
+ if (total > 0)
691
+ log$7.info(`pruned ${total} orphan declaration file(s)`);
692
+ return total;
693
+ };
694
+
695
+ /**
696
+ * Parses a bundled chunk's source into a `ts.SourceFile`.
697
+ *
698
+ * Always parses as plain JavaScript with parent pointers set, so callers can
699
+ * inspect each node's lexical context (member-access position, declaration
700
+ * names) during the dead-export analysis.
701
+ *
702
+ * @param source - Raw chunk source text.
703
+ * @returns The parsed source file with parent nodes populated.
704
+ *
705
+ * @example Parsing a chunk before analysis
706
+ * ```typescript
707
+ * const sourceFile = parseChunk("export { a };\nconst a = 1")
708
+ * ```
709
+ */
710
+ const parseChunk = (source) => ts__default.default.createSourceFile('chunk.js', source, ts__default.default.ScriptTarget.Latest, true, ts__default.default.ScriptKind.JS);
711
+ /**
712
+ * Resolves a module specifier to the absolute chunk path it targets, or `null`
713
+ * when the specifier is not a relative chunk reference.
714
+ *
715
+ * Only specifiers starting with `.` are real edges into the `_dependencies/`
716
+ * tree; bare and node-builtin specifiers resolve to `null` and are ignored by
717
+ * reachability and usage analysis alike.
718
+ *
719
+ * @param importerDir - Absolute directory of the file containing the specifier.
720
+ * @param specifier - The raw module specifier string.
721
+ * @returns The absolute resolved path, or `null` for non-relative specifiers.
722
+ *
723
+ * @example Resolving a sibling chunk reference
724
+ * ```typescript
725
+ * resolveRelativeTarget('/dist/libs/foo/_dependencies/a', '../b/index.esm.js')
726
+ * // => '/dist/libs/foo/_dependencies/b/index.esm.js'
727
+ * ```
728
+ */
729
+ const resolveRelativeTarget = (importerDir, specifier) => specifier.startsWith('.') ? index_cjs_js$5.join(importerDir, specifier) : null;
730
+ /**
731
+ * Returns the literal specifier of a `require('…')` call expression, or `null`
732
+ * when the node is not a single-string-literal `require` call.
733
+ *
734
+ * @param node - Any AST node.
735
+ * @returns The required specifier string, or `null`.
736
+ *
737
+ * @example Extracting a CJS chunk dependency
738
+ * ```typescript
739
+ * // for the call node in `var x = require('./dep/index.cjs.js')`
740
+ * getRequireSpecifier(callNode) // => './dep/index.cjs.js'
741
+ * ```
742
+ */
743
+ const getRequireSpecifier = (node) => {
744
+ if (!ts__default.default.isCallExpression(node) || !ts__default.default.isIdentifier(node.expression) || node.expression.text !== 'require' || node.arguments.length !== 1)
745
+ return null;
746
+ const arg = node.arguments[0];
747
+ return ts__default.default.isStringLiteralLike(arg) ? arg.text : null;
748
+ };
749
+ /**
750
+ * Classifies how a `require('…')` call's result is consumed, by inspecting the
751
+ * call's parent node.
752
+ *
753
+ * A bare `require('F');` statement is classified as `side-effect`, not `escape`.
754
+ * A `require('F').#priv` (not valid JS) does not match `prop` and falls through
755
+ * to `escape`.
756
+ *
757
+ * @param call - The `require('…')` call expression to classify.
758
+ * @returns The discriminated shape of the call's binding position.
759
+ *
760
+ * @example A destructured require
761
+ * ```typescript
762
+ * // for the call in `var { a, b } = require('./x.cjs.js')`
763
+ * classifyRequireBinding(call) // => { kind: 'destructure', pattern: … }
764
+ * ```
765
+ */
766
+ const classifyRequireBinding = (call) => {
767
+ const parent = call.parent;
768
+ if (ts__default.default.isPropertyAccessExpression(parent) && parent.expression === call && ts__default.default.isIdentifier(parent.name))
769
+ return { kind: 'prop', member: parent, name: parent.name.text };
770
+ if (ts__default.default.isElementAccessExpression(parent) && parent.expression === call)
771
+ return ts__default.default.isStringLiteralLike(parent.argumentExpression)
772
+ ? { kind: 'elem-static', member: parent, name: parent.argumentExpression.text }
773
+ : { kind: 'elem-dynamic' };
774
+ if (ts__default.default.isExpressionStatement(parent))
775
+ return { kind: 'side-effect' };
776
+ if (!ts__default.default.isVariableDeclaration(parent) || parent.initializer !== call)
777
+ return { kind: 'escape' };
778
+ if (ts__default.default.isIdentifier(parent.name))
779
+ return { kind: 'ns-binding', name: parent.name };
780
+ if (ts__default.default.isObjectBindingPattern(parent.name))
781
+ return { kind: 'destructure', pattern: parent.name };
782
+ return { kind: 'escape' };
783
+ };
784
+
785
+ /** Per-format output chunk file name, mirroring the bundler's entry naming. */
786
+ const CHUNK_FILE = { esm: 'index.esm.js', cjs: 'index.cjs.js' };
787
+ /**
788
+ * Strips rollup's `$N` collision-rename suffix from a local name, yielding the
789
+ * canonical source symbol name.
790
+ *
791
+ * @param name - A local identifier from an emitted bundle.
792
+ * @returns The base name with any trailing `$digits` removed.
793
+ *
794
+ * @example Undoing a collision rename
795
+ * ```typescript
796
+ * baseName('Store$1') // => 'Store'
797
+ * ```
798
+ */
799
+ const baseName = (name) => name.replace(/\$\d+$/, '');
800
+ /**
801
+ * Computes a rename-insensitive identity key for a top-level statement.
802
+ *
803
+ * Two copies of the same source that differ only in rollup's per-entry `$N`
804
+ * collision suffixes compare equal, while genuinely different code never
805
+ * collides: `$N` is stripped from identifier nodes only, so string literals,
806
+ * comments, numeric tokens, and discriminating member names stay intact.
807
+ *
808
+ * @param statement - The top-level statement to fingerprint.
809
+ * @param sourceFile - The source file the statement belongs to.
810
+ * @returns The statement's text with `$N` stripped from every identifier node.
811
+ *
812
+ * @example Stripping a dep-namespace local's collision suffix
813
+ * ```typescript
814
+ * fingerprintOf(statement, sourceFile) // 'const x = index_cjs_js.getType();' for both `$1` and `$2` copies
815
+ * ```
816
+ */
817
+ const fingerprintOf = (statement, sourceFile) => {
818
+ const start = statement.getStart(sourceFile);
819
+ const text = statement.getText(sourceFile);
820
+ const edits = [];
821
+ const visit = (node) => {
822
+ if (ts__default.default.isIdentifier(node)) {
823
+ const base = baseName(node.text);
824
+ if (base !== node.text)
825
+ edits.push([node.getStart(sourceFile) - start, node.getEnd() - start, base]);
826
+ }
827
+ ts__default.default.forEachChild(node, visit);
828
+ };
829
+ visit(statement);
830
+ let out = text;
831
+ for (const [s, e, replacement] of edits.sort((a, b) => b[0] - a[0]))
832
+ out = `${out.slice(0, s)}${replacement}${out.slice(e)}`;
833
+ return out;
834
+ };
835
+ /**
836
+ * Resolves a hoisted module's chunk file name for a format.
837
+ *
838
+ * @param format - Output module format.
839
+ * @returns The per-entry chunk file name (`index.esm.js` / `index.cjs.js`).
840
+ *
841
+ * @example Naming the CJS chunk
842
+ * ```typescript
843
+ * chunkFileName('cjs') // => 'index.cjs.js'
844
+ * ```
845
+ */
846
+ const chunkFileName = (format) => CHUNK_FILE[format];
847
+ /**
848
+ * Computes the `_shared/` directory (relative to the output root) that holds a
849
+ * module's hoisted chunk.
850
+ *
851
+ * @param moduleKey - The owning module's key.
852
+ * @returns The forward-slashed `_shared/<moduleKey>` directory.
853
+ *
854
+ * @example Locating a module's shared directory
855
+ * ```typescript
856
+ * sharedDirFor('events/events') // => '_shared/events/events'
857
+ * ```
858
+ */
859
+ const sharedDirFor = (moduleKey) => `_shared/${moduleKey}`;
860
+ const isExported = (statement) => ts__default.default.canHaveModifiers(statement) && (ts__default.default.getModifiers(statement) ?? []).some((modifier) => modifier.kind === ts__default.default.SyntaxKind.ExportKeyword);
861
+ const declaredNames = (statement) => {
862
+ if ((ts__default.default.isFunctionDeclaration(statement) || ts__default.default.isClassDeclaration(statement) || ts__default.default.isEnumDeclaration(statement)) && statement.name)
863
+ return [statement.name.text];
864
+ if (!ts__default.default.isVariableStatement(statement))
865
+ return [];
866
+ const names = [];
867
+ for (const decl of statement.declarationList.declarations)
868
+ if (ts__default.default.isIdentifier(decl.name))
869
+ names.push(decl.name.text);
870
+ return names;
871
+ };
872
+ const requireSpecifierOf = (initializer) => {
873
+ if (initializer === undefined)
874
+ return null;
875
+ if (ts__default.default.isPropertyAccessExpression(initializer))
876
+ return getRequireSpecifier(initializer.expression);
877
+ return getRequireSpecifier(initializer);
878
+ };
879
+ const isRequireVarStatement$1 = (statement) => ts__default.default.isVariableStatement(statement) &&
880
+ statement.declarationList.declarations.length > 0 &&
881
+ statement.declarationList.declarations.every((decl) => requireSpecifierOf(decl.initializer) !== null);
882
+ const collectCjsBindings = (statement, bindings) => {
883
+ for (const decl of statement.declarationList.declarations) {
884
+ const specifier = requireSpecifierOf(decl.initializer);
885
+ if (specifier === null)
886
+ continue;
887
+ if (ts__default.default.isIdentifier(decl.name)) {
888
+ // why: `var x = require('s').foo` binds a single named export; the bare `var ns = require('s')` binds the whole namespace.
889
+ const imported = decl.initializer && ts__default.default.isPropertyAccessExpression(decl.initializer) ? decl.initializer.name.text : undefined;
890
+ bindings.set(decl.name.text, imported ? { specifier, kind: 'cjs-named', imported } : { specifier, kind: 'cjs-namespace' });
891
+ }
892
+ else if (ts__default.default.isObjectBindingPattern(decl.name)) {
893
+ for (const element of decl.name.elements)
894
+ if (ts__default.default.isIdentifier(element.name))
895
+ bindings.set(element.name.text, { specifier, kind: 'cjs-named', imported: (element.propertyName ?? element.name).getText() });
896
+ }
897
+ }
898
+ };
899
+ const collectEsmBindings = (statement, bindings) => {
900
+ const specifier = statement.moduleSpecifier.text;
901
+ const clause = statement.importClause;
902
+ if (!clause)
903
+ return;
904
+ if (clause.name)
905
+ bindings.set(clause.name.text, { specifier, kind: 'default' });
906
+ if (!clause.namedBindings)
907
+ return;
908
+ if (ts__default.default.isNamespaceImport(clause.namedBindings)) {
909
+ bindings.set(clause.namedBindings.name.text, { specifier, kind: 'namespace' });
910
+ return;
911
+ }
912
+ for (const element of clause.namedBindings.elements)
913
+ bindings.set(element.name.text, { specifier, kind: 'named', imported: (element.propertyName ?? element.name).text });
914
+ };
915
+ const isUseStrict = (statement) => ts__default.default.isExpressionStatement(statement) && ts__default.default.isStringLiteral(statement.expression) && statement.expression.text === 'use strict';
916
+ const isHeaderStatement = (statement, format) => isUseStrict(statement) || (format === 'esm' ? ts__default.default.isImportDeclaration(statement) : isRequireVarStatement$1(statement));
917
+ const isExportSurface = (statement, format) => {
918
+ if (format === 'esm')
919
+ return ts__default.default.isExportDeclaration(statement) && !statement.moduleSpecifier;
920
+ // why: CJS export surface is a chain of `exports.x = y` assignment statements emitted at the bundle tail.
921
+ if (!ts__default.default.isExpressionStatement(statement) || !ts__default.default.isBinaryExpression(statement.expression))
922
+ return false;
923
+ const { left, operatorToken } = statement.expression;
924
+ return (operatorToken.kind === ts__default.default.SyntaxKind.EqualsToken &&
925
+ ts__default.default.isPropertyAccessExpression(left) &&
926
+ ts__default.default.isIdentifier(left.expression) &&
927
+ left.expression.text === 'exports');
928
+ };
929
+ /**
930
+ * Parses one entry bundle into the structural model the hoist pass consumes.
931
+ *
932
+ * Classifies every top-level statement as an import binding, a removable
933
+ * runtime declaration, the export surface, or an opaque bare statement. Inline
934
+ * `export`-modified declarations are treated as part of the export surface
935
+ * (never removable), so the bundle's published API is never disturbed.
936
+ *
937
+ * @param source - Raw entry bundle source text.
938
+ * @param format - Module format selecting ESM vs CJS import/export shapes.
939
+ * @returns The parsed entry model.
940
+ *
941
+ * @example Modeling an ESM entry bundle
942
+ * ```typescript
943
+ * const parsed = parseEntry("import { x } from './_dependencies/a/index.esm.js'\nclass C {}", 'esm')
944
+ * ```
945
+ */
946
+ const parseEntry = (source, format) => {
947
+ const sourceFile = parseChunk(source);
948
+ const decls = [];
949
+ const importBindings = index_cjs_js$b.createMap();
950
+ const bareStatements = [];
951
+ const declNames = index_cjs_js$2.createSet([]);
952
+ let headerEnd = 0;
953
+ let inHeader = true;
954
+ for (const statement of sourceFile.statements) {
955
+ if (inHeader && isHeaderStatement(statement, format))
956
+ headerEnd = statement.getEnd();
957
+ else
958
+ inHeader = false;
959
+ if (format === 'esm' && ts__default.default.isImportDeclaration(statement)) {
960
+ collectEsmBindings(statement, importBindings);
961
+ continue;
962
+ }
963
+ if (format === 'cjs' && isRequireVarStatement$1(statement)) {
964
+ collectCjsBindings(statement, importBindings);
965
+ continue;
966
+ }
967
+ if (isUseStrict(statement) || isExportSurface(statement, format))
968
+ continue;
969
+ const names = isExported(statement) ? [] : declaredNames(statement);
970
+ for (const name of names)
971
+ declNames.add(name);
972
+ // why: only a single-name, non-exported declaration can be cleanly lifted; multi-declarator and inline-exported statements stay put (and may entangle their module out of the plan).
973
+ if (names.length !== 1) {
974
+ bareStatements.push(statement);
975
+ continue;
976
+ }
977
+ decls.push({
978
+ base: baseName(names[0]),
979
+ localName: names[0],
980
+ statement,
981
+ text: statement.getText(sourceFile),
982
+ fingerprint: fingerprintOf(statement, sourceFile),
983
+ });
984
+ }
985
+ return { sourceFile, decls, importBindings, bareStatements, declNames, headerEnd };
986
+ };
987
+ /**
988
+ * Groups an entry's attributable declarations by their owning module.
989
+ *
990
+ * Declarations whose base name is unowned (a dependency or unexported helper
991
+ * inlined into the bundle) are skipped, leaving them in place.
992
+ *
993
+ * @param parsed - A parsed entry bundle.
994
+ * @param owners - The first-party ownership index.
995
+ * @returns Map from module key to that module's declarations in source order.
996
+ *
997
+ * @example Attributing an entry's declarations
998
+ * ```typescript
999
+ * const byModule = attribute(parseEntry(source, 'esm'), owners)
1000
+ * ```
1001
+ */
1002
+ const attribute = (parsed, owners) => {
1003
+ const byModule = index_cjs_js$b.createMap();
1004
+ for (const decl of parsed.decls) {
1005
+ const moduleKey = owners.ownerOf.get(decl.base);
1006
+ if (moduleKey === undefined)
1007
+ continue;
1008
+ const group = byModule.get(moduleKey) ?? [];
1009
+ group.push(decl);
1010
+ byModule.set(moduleKey, group);
1011
+ }
1012
+ return byModule;
1013
+ };
1014
+ const toModuleKey = (srcRoot, file) => file
1015
+ .slice(srcRoot.length + 1)
1016
+ .replace(/\.ts$/, '')
1017
+ .split(/[\\/]/)
1018
+ .join('/');
1019
+ // why: private top-level helpers (e.g. a reducer's `handlers` map) are inlined alongside the exported symbols that use them; attributing them too lets the whole module hoist instead of bailing on the "unresolved" private reference. Collisions across modules are dropped as ambiguous by indexOwners, preserving safety.
1020
+ const ownersFromSource = (source) => {
1021
+ const sourceFile = ts__default.default.createSourceFile('module.ts', source, ts__default.default.ScriptTarget.Latest, true, ts__default.default.ScriptKind.TS);
1022
+ const names = [];
1023
+ for (const statement of sourceFile.statements)
1024
+ names.push(...declaredNames(statement));
1025
+ return names;
1026
+ };
1027
+ const walkTsFiles = (dir, acc) => {
1028
+ for (const entry of index_cjs_js$5.readDirectory(dir)) {
1029
+ if (entry.isDirectory)
1030
+ walkTsFiles(entry.path, acc);
1031
+ else if (entry.name.endsWith('.ts') && !entry.name.endsWith('.d.ts') && !entry.name.endsWith('.spec.ts'))
1032
+ acc.push(entry.path);
1033
+ }
1034
+ };
1035
+ /**
1036
+ * Builds the first-party ownership index by scanning `<srcRoot>/**` for the
1037
+ * runtime symbols each module exports.
1038
+ *
1039
+ * Both exported and private top-level runtime declarations are indexed, so a
1040
+ * module's private helpers hoist alongside the exports that use them. Types-only
1041
+ * modules declare no runtime symbols and contribute nothing. A name declared by
1042
+ * two different modules is ambiguous and dropped from the index, so the pass can
1043
+ * never misattribute it.
1044
+ *
1045
+ * @param srcRoot - Absolute path to the project's `src/` directory.
1046
+ * @returns The ownership index.
1047
+ *
1048
+ * @example Indexing a library's source tree
1049
+ * ```typescript
1050
+ * const owners = indexOwners('/abs/libs/foo/src')
1051
+ * ```
1052
+ */
1053
+ const indexOwners = (srcRoot) => {
1054
+ const files = [];
1055
+ walkTsFiles(srcRoot, files);
1056
+ const firstOwner = index_cjs_js$b.createMap();
1057
+ const ambiguous = index_cjs_js$2.createSet([]);
1058
+ const ownerOf = index_cjs_js$b.createMap();
1059
+ for (const file of files) {
1060
+ const moduleKey = toModuleKey(srcRoot, file);
1061
+ for (const name of ownersFromSource(index_cjs_js$5.readFileContent(file))) {
1062
+ if (ambiguous.has(name))
1063
+ continue;
1064
+ const prior = firstOwner.get(name);
1065
+ if (prior !== undefined && prior !== moduleKey) {
1066
+ ambiguous.add(name);
1067
+ ownerOf.delete(name);
1068
+ continue;
1069
+ }
1070
+ firstOwner.set(name, moduleKey);
1071
+ ownerOf.set(name, moduleKey);
1072
+ }
1073
+ }
1074
+ return { ownerOf };
1075
+ };
1076
+
1077
+ const EVAL_SIDE_EFFECT_KINDS = index_cjs_js$2.createSet([
1078
+ ts__default.default.SyntaxKind.CallExpression,
1079
+ ts__default.default.SyntaxKind.NewExpression,
1080
+ ts__default.default.SyntaxKind.AwaitExpression,
1081
+ ts__default.default.SyntaxKind.YieldExpression,
1082
+ ts__default.default.SyntaxKind.TaggedTemplateExpression,
1083
+ ]);
1084
+ /**
1085
+ * Globals whose call observably only mutates-then-returns its (fresh-literal)
1086
+ * argument and is therefore side-effect-free — `freeze`/`seal`/`preventExtensions`
1087
+ * all behave this way on a freshly-built object/array literal.
1088
+ */
1089
+ const PURE_GLOBAL_CALLEES = index_cjs_js$2.createSet(['Object.freeze', 'Object.seal', 'Object.preventExtensions']);
1090
+ // context: dotted global-rooted name for a call target, with a leading `globalThis.` stripped and each top-level binding resolved through `resolution`. Null when the base is a local binding that does not resolve to a global (a shadow) or is not a plain identifier/property chain (a call, element access, …).
1091
+ const canonicalCallee = (expr, resolution) => {
1092
+ if (ts__default.default.isIdentifier(expr)) {
1093
+ const mapped = resolution.canonical.get(expr.text);
1094
+ if (mapped !== undefined)
1095
+ return mapped;
1096
+ // why: a top-level binding that did not resolve to a global alias shadows that global; treat as opaque so e.g. `const Object = {}` disables bare `Object.freeze`.
1097
+ return resolution.bindings.has(expr.text) ? null : expr.text;
1098
+ }
1099
+ if (ts__default.default.isPropertyAccessExpression(expr)) {
1100
+ const base = canonicalCallee(expr.expression, resolution);
1101
+ if (base === null)
1102
+ return null;
1103
+ const dotted = `${base}.${expr.name.text}`;
1104
+ return dotted.startsWith('globalThis.') ? dotted.slice('globalThis.'.length) : dotted;
1105
+ }
1106
+ return null;
1107
+ };
1108
+ /**
1109
+ * Maps each top-level binding to its canonical global-rooted callee form, in
1110
+ * source order so a later alias resolves through an earlier one. Both `const`
1111
+ * and `var` are resolved; bundled dep chunks never reassign these interop
1112
+ * bindings. A call/literal initializer is opaque and only contributes a
1113
+ * shadowing entry in `bindings`.
1114
+ *
1115
+ * @param sourceFile - The parsed chunk whose top-level bindings are resolved.
1116
+ * @returns The binding resolution: every top-level name plus the global-rooted
1117
+ * canonical form of each identifier/property-chain alias.
1118
+ *
1119
+ * @example Resolving an alias-of-global freeze
1120
+ * ```typescript
1121
+ * const { canonical } = collectBindingCanonical(parseChunk('const _O = globalThis.Object;\nconst freeze = _O.freeze;'))
1122
+ * canonical.get('freeze') // => 'Object.freeze'
1123
+ * ```
1124
+ */
1125
+ const collectBindingCanonical = (sourceFile) => {
1126
+ const resolution = { bindings: index_cjs_js$2.createSet([]), canonical: index_cjs_js$b.createMap() };
1127
+ for (const statement of sourceFile.statements) {
1128
+ if ((ts__default.default.isFunctionDeclaration(statement) || ts__default.default.isClassDeclaration(statement)) && statement.name)
1129
+ resolution.bindings.add(statement.name.text);
1130
+ if (!ts__default.default.isVariableStatement(statement))
1131
+ continue;
1132
+ for (const decl of statement.declarationList.declarations) {
1133
+ if (!ts__default.default.isIdentifier(decl.name))
1134
+ continue;
1135
+ resolution.bindings.add(decl.name.text);
1136
+ // why: only an identifier/property-access initializer can alias a global; resolve it through the bindings collected so far (leftmost identifier only).
1137
+ if (decl.initializer && (ts__default.default.isIdentifier(decl.initializer) || ts__default.default.isPropertyAccessExpression(decl.initializer))) {
1138
+ const resolved = canonicalCallee(decl.initializer, resolution);
1139
+ if (resolved !== null)
1140
+ resolution.canonical.set(decl.name.text, resolved);
1141
+ }
1142
+ }
1143
+ }
1144
+ return resolution;
1145
+ };
1146
+ /**
1147
+ * Reports whether a call is a recognized pure callee
1148
+ * (`Object.freeze`/`seal`/`preventExtensions`, however aliased) over a fresh
1149
+ * object/array literal. The argument must be a same-expression literal —
1150
+ * freezing a shared binding mutates it observably, so an identifier argument is
1151
+ * rejected. This checks only the callee and argument shape, not the purity of
1152
+ * the argument's own subexpressions.
1153
+ *
1154
+ * @param call - The call expression to classify.
1155
+ * @param resolution - The chunk's binding resolution, used to canonicalize the callee.
1156
+ * @returns `true` when the call is an observably pure freeze of a fresh literal.
1157
+ *
1158
+ * @example Recognizing an aliased freeze of a fresh literal
1159
+ * ```typescript
1160
+ * const sourceFile = parseChunk('const _O = globalThis.Object;\nconst X = _O.freeze({ a: 1 });')
1161
+ * // for the `_O.freeze({ a: 1 })` call node
1162
+ * isPureFreezeCall(call, collectBindingCanonical(sourceFile)) // => true
1163
+ * ```
1164
+ */
1165
+ const isPureFreezeCall = (call, resolution) => {
1166
+ const callee = canonicalCallee(call.expression, resolution);
1167
+ if (callee === null || !PURE_GLOBAL_CALLEES.has(callee))
1168
+ return false;
1169
+ if (call.arguments.length < 1)
1170
+ return false;
1171
+ const first = call.arguments[0];
1172
+ return ts__default.default.isObjectLiteralExpression(first) || ts__default.default.isArrayLiteralExpression(first);
1173
+ };
1174
+ /**
1175
+ * Reports whether a call is `<global-rooted chain>.bind(…)`.
1176
+ * `Function.prototype.bind` only builds and returns a new bound function — no
1177
+ * observable side effect. The receiver must canonicalize to a global so an
1178
+ * arbitrary user object's `.bind` — potentially a redefined, side-effecting
1179
+ * method — is never assumed pure. As with {@link isPureFreezeCall}, this checks
1180
+ * only the call shape, not the purity of the argument's own subexpressions.
1181
+ *
1182
+ * @param call - The call expression to classify.
1183
+ * @param resolution - The chunk's binding resolution, used to canonicalize the receiver.
1184
+ * @returns `true` when the call binds a method off a global-rooted receiver chain.
1185
+ *
1186
+ * @example Recognizing a bind of a global-rooted receiver
1187
+ * ```typescript
1188
+ * const sourceFile = parseChunk('const _P = globalThis.Promise;\nconst X = _P.resolve.bind(_P);')
1189
+ * // for the `_P.resolve.bind(_P)` call node
1190
+ * isPureBindCall(call, collectBindingCanonical(sourceFile)) // => true
1191
+ * ```
1192
+ */
1193
+ const isPureBindCall = (call, resolution) => {
1194
+ const callee = call.expression;
1195
+ if (!ts__default.default.isPropertyAccessExpression(callee) || callee.name.text !== 'bind')
1196
+ return false;
1197
+ return canonicalCallee(callee.expression, resolution) !== null;
1198
+ };
1199
+
1200
+ const PURE_ANNOTATION = /[@#]__PURE__/;
1201
+
1202
+ const isAnnotatedPure = (node) => PURE_ANNOTATION.test(node.getSourceFile().text.slice(node.getFullStart(), node.getStart()));
1203
+
1204
+ const containsEvalSideEffect = (node, resolution) => {
1205
+ let found = false;
1206
+ const visit = (current) => {
1207
+ if (found || ts__default.default.isFunctionLike(current))
1208
+ return;
1209
+ if (ts__default.default.isCallExpression(current) || ts__default.default.isNewExpression(current)) {
1210
+ if ((ts__default.default.isCallExpression(current) && (isPureFreezeCall(current, resolution) || isPureBindCall(current, resolution))) ||
1211
+ isAnnotatedPure(current)) {
1212
+ ts__default.default.forEachChild(current, visit);
1213
+ return;
1214
+ }
1215
+ found = true;
1216
+ return;
1217
+ }
1218
+ if (EVAL_SIDE_EFFECT_KINDS.has(current.kind)) {
1219
+ found = true;
1220
+ return;
1221
+ }
1222
+ ts__default.default.forEachChild(current, visit);
1223
+ };
1224
+ visit(node);
1225
+ return found;
1226
+ };
1227
+ const isSideEffectFreeInitializer = (initializer, resolution) => initializer === undefined || !containsEvalSideEffect(initializer, resolution);
1228
+ /**
1229
+ * Collects the identifier names referenced within a node, excluding identifiers
1230
+ * that sit in a property-name position (`obj.name`, `{ name: … }`, `{ name: x }`
1231
+ * binding keys) since those never refer to a top-level declaration.
1232
+ *
1233
+ * Deliberately over-approximates: a name captured that is not actually a
1234
+ * top-level declaration is harmless, and capturing more only keeps more code.
1235
+ *
1236
+ * @param node - The subtree to scan.
1237
+ * @param sink - Set that receives every referenced identifier name.
1238
+ *
1239
+ * @example Collecting references inside a function body
1240
+ * ```typescript
1241
+ * const refs = createSet<string>([])
1242
+ * collectRefs(functionDeclaration, refs)
1243
+ * ```
1244
+ */
1245
+ const collectRefs = (node, sink) => {
1246
+ const visit = (current) => {
1247
+ if (ts__default.default.isIdentifier(current)) {
1248
+ const parent = current.parent;
1249
+ if (ts__default.default.isPropertyAccessExpression(parent) && parent.name === current)
1250
+ return;
1251
+ if (ts__default.default.isPropertyAssignment(parent) && parent.name === current)
1252
+ return;
1253
+ if (ts__default.default.isBindingElement(parent) && parent.propertyName === current)
1254
+ return;
1255
+ sink.add(current.text);
1256
+ return;
1257
+ }
1258
+ ts__default.default.forEachChild(current, visit);
1259
+ };
1260
+ visit(node);
1261
+ };
1262
+ const hasExportModifier = (node) => ts__default.default.canHaveModifiers(node) && (ts__default.default.getModifiers(node) ?? []).some((modifier) => modifier.kind === ts__default.default.SyntaxKind.ExportKeyword);
1263
+ const isRequireInitializer = (init) => getRequireSpecifier(init) !== null || (ts__default.default.isPropertyAccessExpression(init) && getRequireSpecifier(init.expression) !== null);
1264
+ const isRequireVarStatement = (statement) => ts__default.default.isVariableStatement(statement) &&
1265
+ statement.declarationList.declarations.some((decl) => decl.initializer !== undefined && isRequireInitializer(decl.initializer));
1266
+ /**
1267
+ * Returns the local binding names introduced by a CJS `require` variable
1268
+ * statement, across identifier and object-destructure bindings.
1269
+ *
1270
+ * @param statement - A variable statement known to bind a `require` call.
1271
+ * @returns The local names it introduces.
1272
+ *
1273
+ * @example Bindings of a destructured require
1274
+ * ```typescript
1275
+ * // for `var { a, b } = require('./x.cjs.js')`
1276
+ * requireBindingLocals(statement) // => ['a', 'b']
1277
+ * ```
1278
+ */
1279
+ const requireBindingLocals = (statement) => {
1280
+ const locals = [];
1281
+ if (!ts__default.default.isVariableStatement(statement))
1282
+ return locals;
1283
+ for (const decl of statement.declarationList.declarations) {
1284
+ if (ts__default.default.isIdentifier(decl.name))
1285
+ locals.push(decl.name.text);
1286
+ else if (ts__default.default.isObjectBindingPattern(decl.name))
1287
+ for (const element of decl.name.elements)
1288
+ if (ts__default.default.isIdentifier(element.name))
1289
+ locals.push(element.name.text);
1290
+ }
1291
+ return locals;
1292
+ };
1293
+ const tryDecl = (statement, resolution) => {
1294
+ if ((ts__default.default.isFunctionDeclaration(statement) || ts__default.default.isClassDeclaration(statement)) && statement.name) {
1295
+ return { statement, names: [statement.name.text], sideEffectFree: true };
1296
+ }
1297
+ if (!ts__default.default.isVariableStatement(statement))
1298
+ return null;
1299
+ const names = [];
1300
+ let sideEffectFree = true;
1301
+ for (const decl of statement.declarationList.declarations) {
1302
+ // why: a destructured top-level binding is not a simple named export and its initializer is typically a call — never treat it as a removable declaration.
1303
+ if (!ts__default.default.isIdentifier(decl.name))
1304
+ return null;
1305
+ names.push(decl.name.text);
1306
+ if (!isSideEffectFreeInitializer(decl.initializer, resolution))
1307
+ sideEffectFree = false;
1308
+ }
1309
+ return { statement, names, sideEffectFree };
1310
+ };
1311
+ const collectEsmExports = (statement, entries, surface) => {
1312
+ if (ts__default.default.isExportDeclaration(statement) &&
1313
+ !statement.moduleSpecifier &&
1314
+ statement.exportClause &&
1315
+ ts__default.default.isNamedExports(statement.exportClause)) {
1316
+ surface.add(statement);
1317
+ for (const element of statement.exportClause.elements)
1318
+ entries.push({ exported: element.name.text, local: (element.propertyName ?? element.name).text, statement, kind: 'esm-list' });
1319
+ return;
1320
+ }
1321
+ if (!hasExportModifier(statement))
1322
+ return;
1323
+ if ((ts__default.default.isFunctionDeclaration(statement) || ts__default.default.isClassDeclaration(statement)) && statement.name) {
1324
+ entries.push({ exported: statement.name.text, local: statement.name.text, statement, kind: 'esm-inline' });
1325
+ }
1326
+ else if (ts__default.default.isVariableStatement(statement)) {
1327
+ for (const decl of statement.declarationList.declarations)
1328
+ if (ts__default.default.isIdentifier(decl.name))
1329
+ entries.push({ exported: decl.name.text, local: decl.name.text, statement, kind: 'esm-inline' });
1330
+ }
1331
+ };
1332
+ const collectCjsExports = (statement, entries, surface) => {
1333
+ if (!ts__default.default.isExpressionStatement(statement) || !ts__default.default.isBinaryExpression(statement.expression))
1334
+ return;
1335
+ const { left, operatorToken, right } = statement.expression;
1336
+ if (operatorToken.kind !== ts__default.default.SyntaxKind.EqualsToken)
1337
+ return;
1338
+ if (ts__default.default.isPropertyAccessExpression(left) &&
1339
+ ts__default.default.isIdentifier(left.expression) &&
1340
+ left.expression.text === 'exports' &&
1341
+ ts__default.default.isIdentifier(left.name) &&
1342
+ ts__default.default.isIdentifier(right)) {
1343
+ surface.add(statement);
1344
+ entries.push({ exported: left.name.text, local: right.text, statement, kind: 'cjs-assign' });
1345
+ }
1346
+ };
1347
+ /**
1348
+ * Builds the structural model of a chunk: its removable declarations, import
1349
+ * sites, and export surface.
1350
+ *
1351
+ * @param sourceFile - The parsed chunk.
1352
+ * @param format - Module format selecting ESM vs CJS export/import shapes.
1353
+ * @returns The chunk model consumed by {@link computeKeepClosure}.
1354
+ *
1355
+ * @example Modeling an ESM chunk
1356
+ * ```typescript
1357
+ * const model = analyzeChunk(parseChunk(source), 'esm')
1358
+ * ```
1359
+ */
1360
+ const analyzeChunk = (sourceFile, format) => {
1361
+ const nameToDecl = index_cjs_js$b.createMap();
1362
+ const decls = [];
1363
+ const importStatements = [];
1364
+ // why: not named `exports` — a local `exports` shadows the module object, breaking the transpiled `(0, exports.collectBindingCanonical)` reference under isolatedModules CJS.
1365
+ const exportEntries = [];
1366
+ const exportSurfaceStatements = index_cjs_js$2.createSet([]);
1367
+ const resolution = collectBindingCanonical(sourceFile);
1368
+ for (const statement of sourceFile.statements) {
1369
+ if (format === 'esm' ? ts__default.default.isImportDeclaration(statement) : isRequireVarStatement(statement)) {
1370
+ importStatements.push(statement);
1371
+ continue;
1372
+ }
1373
+ const decl = tryDecl(statement, resolution);
1374
+ if (decl) {
1375
+ decls.push(decl);
1376
+ for (const name of decl.names)
1377
+ nameToDecl.set(name, decl);
1378
+ }
1379
+ if (format === 'esm')
1380
+ collectEsmExports(statement, exportEntries, exportSurfaceStatements);
1381
+ else
1382
+ collectCjsExports(statement, exportEntries, exportSurfaceStatements);
1383
+ }
1384
+ return { nameToDecl, decls, importStatements, exports: exportEntries, exportSurfaceStatements };
1385
+ };
1386
+ const collectRoots = (sourceFile, model, keep, declStatements) => {
1387
+ const roots = index_cjs_js$2.createSet([]);
1388
+ for (const entry of model.exports)
1389
+ if (keep.has(entry.exported))
1390
+ roots.add(entry.local);
1391
+ for (const decl of model.decls)
1392
+ if (!decl.sideEffectFree)
1393
+ for (const name of decl.names)
1394
+ roots.add(name);
1395
+ for (const statement of sourceFile.statements) {
1396
+ if (declStatements.has(statement) || model.exportSurfaceStatements.has(statement) || model.importStatements.includes(statement))
1397
+ continue;
1398
+ collectRefs(statement, roots);
1399
+ }
1400
+ return roots;
1401
+ };
1402
+ /**
1403
+ * Computes the closure of local declaration names that must be retained: every
1404
+ * kept export, every side-effecting declaration, every name referenced by a
1405
+ * bare top-level statement, and everything those transitively reference.
1406
+ *
1407
+ * @param sourceFile - The parsed chunk.
1408
+ * @param model - The chunk model from {@link analyzeChunk}.
1409
+ * @param keep - Exported names demanded by importers.
1410
+ * @returns The set of local names that may not be removed.
1411
+ *
1412
+ * @example Names that survive given a one-export demand
1413
+ * ```typescript
1414
+ * const live = computeKeepClosure(sourceFile, model, createSet(['getType']))
1415
+ * ```
1416
+ */
1417
+ const computeKeepClosure = (sourceFile, model, keep) => {
1418
+ const declStatements = index_cjs_js$2.createSet(model.decls.map((decl) => decl.statement));
1419
+ const refsCache = index_cjs_js$b.createMap();
1420
+ const refsOf = (statement) => {
1421
+ const cached = refsCache.get(statement);
1422
+ if (cached)
1423
+ return cached;
1424
+ const refs = index_cjs_js$2.createSet([]);
1425
+ collectRefs(statement, refs);
1426
+ refsCache.set(statement, refs);
1427
+ return refs;
1428
+ };
1429
+ const keepClosure = index_cjs_js$2.createSet([]);
1430
+ const stack = index_cjs_js$3.from(collectRoots(sourceFile, model, keep, declStatements));
1431
+ while (stack.length > 0) {
1432
+ const name = stack.pop();
1433
+ if (keepClosure.has(name))
1434
+ continue;
1435
+ keepClosure.add(name);
1436
+ const decl = model.nameToDecl.get(name);
1437
+ if (!decl)
1438
+ continue;
1439
+ for (const ref of refsOf(decl.statement))
1440
+ if (!keepClosure.has(ref))
1441
+ stack.push(ref);
1442
+ }
1443
+ return keepClosure;
1444
+ };
1445
+
1446
+ /**
1447
+ * Classifies every free identifier referenced by a module's declarations,
1448
+ * partitioning them into cross-module edges, dependency edges, and hard
1449
+ * blockers.
1450
+ *
1451
+ * Identifiers the module declares itself are intra-chunk and ignored. A name
1452
+ * that is neither owned, nor a dependency binding, nor a top-level entry
1453
+ * declaration is a runtime global and needs no import. Cross-module references
1454
+ * are always safe to lift because {@link planHoists} only keeps an acyclic
1455
+ * subset, so every dependency chunk is fully evaluated before its dependent.
1456
+ *
1457
+ * @param decls - The module's canonical declarations.
1458
+ * @param owners - First-party ownership index.
1459
+ * @param importBindings - The consuming entry's import bindings.
1460
+ * @param entryDeclNames - Every top-level declaration name in the entry.
1461
+ * @param selfModuleKey - The module being resolved.
1462
+ * @returns The reference resolution.
1463
+ *
1464
+ * @example Resolving a module's references
1465
+ * ```typescript
1466
+ * const resolution = resolveModuleRefs(decls, owners, parsed.importBindings, parsed.declNames, 'events/events')
1467
+ * ```
1468
+ */
1469
+ const resolveModuleRefs = (decls, owners, importBindings, entryDeclNames, selfModuleKey) => {
1470
+ const selfLocals = index_cjs_js$2.createSet(decls.map((decl) => decl.localName));
1471
+ const allRefs = index_cjs_js$2.createSet([]);
1472
+ for (const decl of decls)
1473
+ collectRefs(decl.statement, allRefs);
1474
+ const crossModule = [];
1475
+ const depImports = [];
1476
+ const unresolved = [];
1477
+ for (const ref of allRefs) {
1478
+ if (selfLocals.has(ref))
1479
+ continue;
1480
+ const base = baseName(ref);
1481
+ const owner = owners.ownerOf.get(base);
1482
+ if (owner !== undefined) {
1483
+ if (owner !== selfModuleKey)
1484
+ crossModule.push({ ref, base, moduleKey: owner });
1485
+ continue;
1486
+ }
1487
+ const binding = importBindings.get(ref);
1488
+ if (binding !== undefined) {
1489
+ depImports.push({ ref, binding });
1490
+ continue;
1491
+ }
1492
+ if (entryDeclNames.has(ref))
1493
+ unresolved.push(ref);
1494
+ }
1495
+ return { crossModule, depImports, unresolved };
1496
+ };
1497
+ const namedBinding = (local, imported) => (imported === local ? local : `${imported} as ${local}`);
1498
+ const cjsBinding$1 = (local, imported) => (imported === local ? local : `${imported}: ${local}`);
1499
+ const groupBySpecifier = (items, specifierOf) => {
1500
+ const groups = index_cjs_js$b.createMap();
1501
+ for (const item of items) {
1502
+ const group = groups.get(specifierOf(item)) ?? [];
1503
+ group.push(item);
1504
+ groups.set(specifierOf(item), group);
1505
+ }
1506
+ return index_cjs_js$3.from(groups.entries()).sort(([a], [b]) => (a < b ? -1 : 1));
1507
+ };
1508
+ const renderEsmImports = (crossImports, depImports) => {
1509
+ const lines = [];
1510
+ for (const [specifier, group] of groupBySpecifier(crossImports, (c) => c.specifier))
1511
+ lines.push(`import { ${group.map((c) => namedBinding(c.ref, c.exported)).join(', ')} } from '${specifier}';`);
1512
+ for (const dep of depImports.filter((d) => d.kind === 'namespace'))
1513
+ lines.push(`import * as ${dep.ref} from '${dep.specifier}';`);
1514
+ for (const dep of depImports.filter((d) => d.kind === 'default'))
1515
+ lines.push(`import ${dep.ref} from '${dep.specifier}';`);
1516
+ for (const [specifier, group] of groupBySpecifier(depImports.filter((d) => d.kind === 'named'), (d) => d.specifier))
1517
+ lines.push(`import { ${group.map((d) => namedBinding(d.ref, d.imported ?? d.ref)).join(', ')} } from '${specifier}';`);
1518
+ return lines;
1519
+ };
1520
+ const renderCjsRequires = (crossImports, depImports) => {
1521
+ const lines = [];
1522
+ for (const [specifier, group] of groupBySpecifier(crossImports, (c) => c.specifier))
1523
+ lines.push(`const { ${group.map((c) => cjsBinding$1(c.ref, c.exported)).join(', ')} } = require('${specifier}');`);
1524
+ for (const dep of depImports.filter((d) => d.kind === 'cjs-namespace'))
1525
+ lines.push(`const ${dep.ref} = require('${dep.specifier}');`);
1526
+ for (const [specifier, group] of groupBySpecifier(depImports.filter((d) => d.kind === 'cjs-named'), (d) => d.specifier))
1527
+ lines.push(`const { ${group.map((d) => cjsBinding$1(d.ref, d.imported ?? d.ref)).join(', ')} } = require('${specifier}');`);
1528
+ return lines;
1529
+ };
1530
+ const renderEsmExports = (decls) => `export { ${decls.map((decl) => (decl.localName === decl.base ? decl.base : `${decl.localName} as ${decl.base}`)).join(', ')} };`;
1531
+ const renderCjsExports = (decls) => decls.map((decl) => `exports.${decl.base} = ${decl.localName};`).join('\n');
1532
+ /**
1533
+ * Renders a hoisted module chunk: its resolved imports, the union of its
1534
+ * declarations, and an export surface naming each declaration by its base name.
1535
+ *
1536
+ * @param plan - The module's declarations plus resolved import edges.
1537
+ * @param format - Output module format.
1538
+ * @returns The chunk source text.
1539
+ *
1540
+ * @example Rendering an ESM chunk
1541
+ * ```typescript
1542
+ * const source = renderChunk({ decls, crossImports: [], depImports: [] }, 'esm')
1543
+ * ```
1544
+ */
1545
+ const renderChunk = (plan, format) => {
1546
+ const body = plan.decls.map((decl) => decl.text).join('\n');
1547
+ if (format === 'esm') {
1548
+ const imports = renderEsmImports(plan.crossImports, plan.depImports);
1549
+ const blocks = imports.length > 0 ? [imports.join('\n'), body, renderEsmExports(plan.decls)] : [body, renderEsmExports(plan.decls)];
1550
+ return `${blocks.join('\n\n')}\n`;
1551
+ }
1552
+ const requires = renderCjsRequires(plan.crossImports, plan.depImports);
1553
+ const blocks = requires.length > 0
1554
+ ? ["'use strict';", requires.join('\n'), body, renderCjsExports(plan.decls)]
1555
+ : ["'use strict';", body, renderCjsExports(plan.decls)];
1556
+ return `${blocks.join('\n\n')}\n`;
1557
+ };
1558
+
1559
+ const invertOwners = (owners) => {
1560
+ const byModule = index_cjs_js$b.createMap();
1561
+ for (const [base, moduleKey] of owners.ownerOf) {
1562
+ const names = byModule.get(moduleKey) ?? index_cjs_js$2.createSet([]);
1563
+ names.add(base);
1564
+ byModule.set(moduleKey, names);
1565
+ }
1566
+ return byModule;
1567
+ };
1568
+ const collectAppearances = (entries) => {
1569
+ const appearances = index_cjs_js$b.createMap();
1570
+ for (const [index, entry] of entries.entries())
1571
+ for (const moduleKey of entry.byModule.keys()) {
1572
+ const list = appearances.get(moduleKey) ?? [];
1573
+ list.push(index);
1574
+ appearances.set(moduleKey, list);
1575
+ }
1576
+ return appearances;
1577
+ };
1578
+ // why: a bare statement (multi-declarator var, enum IIFE, side-effecting init) that names one of the module's symbols cannot be cleanly split out — its symbol would vanish from the chunk; leave the whole module inlined.
1579
+ const isEntangled = (entries, indexes, ownedNames) => indexes.some((index) => entries[index].parsed.bareStatements.some((statement) => {
1580
+ const refs = index_cjs_js$2.createSet([]);
1581
+ collectRefs(statement, refs);
1582
+ return index_cjs_js$3.from(refs).some((ref) => ownedNames.has(baseName(ref)));
1583
+ }));
1584
+ const pickCanonical = (entries, moduleKey, indexes) => indexes.reduce((best, index) => (entries[index].byModule.get(moduleKey) ?? []).length > (entries[best].byModule.get(moduleKey) ?? []).length ? index : best);
1585
+ const isConsistentCopy = (canonicalFingerprint, order, decls) => {
1586
+ let previous = -1;
1587
+ for (const decl of decls) {
1588
+ const index = order.get(decl.base);
1589
+ // why: a copy that names a declaration absent from the canonical superset, reorders it, or differs structurally (rename-insensitive fingerprint) is not provably the same code.
1590
+ if (index === undefined || index <= previous || canonicalFingerprint.get(decl.base) !== decl.fingerprint)
1591
+ return false;
1592
+ previous = index;
1593
+ }
1594
+ return true;
1595
+ };
1596
+ const planCandidate = (entries, owners, moduleKey, indexes, ownedNames) => {
1597
+ if (isEntangled(entries, indexes, ownedNames))
1598
+ return null;
1599
+ const canonicalEntryIndex = pickCanonical(entries, moduleKey, indexes);
1600
+ const canonicalDecls = entries[canonicalEntryIndex].byModule.get(moduleKey) ?? [];
1601
+ // why: identity gates on the rename-insensitive fingerprint, but chunk rendering still uses each decl's raw `text` via canonicalDecls.
1602
+ const canonicalFingerprint = index_cjs_js$b.createMap();
1603
+ const order = index_cjs_js$b.createMap();
1604
+ for (const [index, decl] of canonicalDecls.entries()) {
1605
+ canonicalFingerprint.set(decl.base, decl.fingerprint);
1606
+ order.set(decl.base, index);
1607
+ }
1608
+ for (const index of indexes)
1609
+ if (!isConsistentCopy(canonicalFingerprint, order, entries[index].byModule.get(moduleKey) ?? []))
1610
+ return null;
1611
+ const canonical = entries[canonicalEntryIndex].parsed;
1612
+ const resolution = resolveModuleRefs(canonicalDecls, owners, canonical.importBindings, canonical.declNames, moduleKey);
1613
+ if (resolution.unresolved.length > 0)
1614
+ return null;
1615
+ return { canonicalEntryIndex, decls: canonicalDecls, resolution, consumingEntryIndexes: indexes };
1616
+ };
1617
+ const closeOverDependencies = (candidates) => {
1618
+ let changed = true;
1619
+ while (changed) {
1620
+ changed = false;
1621
+ for (const [moduleKey, planned] of candidates)
1622
+ if (planned.resolution.crossModule.some((ref) => !candidates.has(ref.moduleKey))) {
1623
+ candidates.delete(moduleKey);
1624
+ changed = true;
1625
+ }
1626
+ }
1627
+ return candidates;
1628
+ };
1629
+ // why: shared chunks load topologically, so an acyclic dependency graph guarantees every chunk is fully evaluated before its dependents — no cross-chunk temporal-dead-zone. Modules in (or feeding) a cycle cannot be ordered safely, so they are peeled off and left inlined.
1630
+ const keepAcyclic = (candidates) => {
1631
+ const depsOf = index_cjs_js$b.createMap();
1632
+ for (const [moduleKey, planned] of candidates)
1633
+ depsOf.set(moduleKey, planned.resolution.crossModule.map((ref) => ref.moduleKey));
1634
+ const pending = index_cjs_js$2.createSet(candidates.keys());
1635
+ let changed = true;
1636
+ while (changed) {
1637
+ changed = false;
1638
+ for (const [moduleKey, deps] of depsOf)
1639
+ if (pending.has(moduleKey) && deps.every((dep) => !pending.has(dep))) {
1640
+ pending.delete(moduleKey);
1641
+ changed = true;
1642
+ }
1643
+ }
1644
+ for (const moduleKey of pending)
1645
+ candidates.delete(moduleKey);
1646
+ return candidates;
1647
+ };
1648
+ /**
1649
+ * Plans which first-party modules can be hoisted into shared chunks.
1650
+ *
1651
+ * A module qualifies only when it is inlined into at least two entries, is not
1652
+ * entangled with a bare statement, presents structurally identical declarations
1653
+ * (rename-insensitive) in a consistent order across every copy, references
1654
+ * nothing unresolvable, and —
1655
+ * after closure and acyclic peeling — depends only on other hoisted modules
1656
+ * through a cycle-free graph. Anything failing these is left inlined, so the
1657
+ * worst case equals the unmodified output.
1658
+ *
1659
+ * @param entries - Parsed entries with their per-module attribution.
1660
+ * @param owners - First-party ownership index.
1661
+ * @returns Map from module key to its hoist plan.
1662
+ *
1663
+ * @example Planning hoists for a set of entries
1664
+ * ```typescript
1665
+ * const plan = planHoists(entries, owners)
1666
+ * ```
1667
+ */
1668
+ const planHoists = (entries, owners) => {
1669
+ const ownedNames = invertOwners(owners);
1670
+ const candidates = index_cjs_js$b.createMap();
1671
+ for (const [moduleKey, indexes] of collectAppearances(entries)) {
1672
+ if (indexes.length < 2)
1673
+ continue;
1674
+ const planned = planCandidate(entries, owners, moduleKey, indexes, ownedNames.get(moduleKey) ?? index_cjs_js$2.createSet([]));
1675
+ if (planned)
1676
+ candidates.set(moduleKey, planned);
1677
+ }
1678
+ return keepAcyclic(closeOverDependencies(candidates));
1679
+ };
1680
+
1681
+ const esmBinding = (decl) => (decl.base === decl.localName ? decl.base : `${decl.base} as ${decl.localName}`);
1682
+ const cjsBinding = (decl) => (decl.base === decl.localName ? decl.base : `${decl.base}: ${decl.localName}`);
1683
+ const renderImport = (hoist, format) => format === 'esm'
1684
+ ? `import { ${hoist.decls.map(esmBinding).join(', ')} } from '${hoist.specifier}';`
1685
+ : `const { ${hoist.decls.map(cjsBinding).join(', ')} } = require('${hoist.specifier}');`;
1686
+ const applyEdits$1 = (source, edits) => {
1687
+ let code = source;
1688
+ for (const edit of index_cjs_js$3.from(edits).sort((a, b) => b.start - a.start))
1689
+ code = `${code.slice(0, edit.start)}${edit.text}${code.slice(edit.end)}`;
1690
+ // why: splicing whole statements leaves runs of blank lines; collapse them so the trimmed entry stays readable.
1691
+ return code.replace(/\n{3,}/g, '\n\n');
1692
+ };
1693
+ // why: liveness over-approximates — every identifier node (property names included) counts as a use, so trimming an import can only drop a name nothing references, never one that survives.
1694
+ const collectIdentifierNames = (source) => {
1695
+ const names = index_cjs_js$2.createSet([]);
1696
+ const visit = (node) => {
1697
+ if (ts__default.default.isIdentifier(node))
1698
+ names.add(node.text);
1699
+ ts__default.default.forEachChild(node, visit);
1700
+ };
1701
+ visit(parseChunk(source));
1702
+ return names;
1703
+ };
1704
+ /**
1705
+ * Rewrites an entry bundle to consume hoisted modules from `_shared/` chunks
1706
+ * instead of inlining them.
1707
+ *
1708
+ * Splices every hoisted declaration (and its leading comments) out of the entry
1709
+ * and prepends an import/`require` binding the chunk's base export to the
1710
+ * entry's local name — aliasing when rollup renamed the local (`foo as foo$1`).
1711
+ * Only the hoisted symbols the entry still references after splicing are
1712
+ * re-imported: a private helper used solely by another hoisted export (e.g. a
1713
+ * reducer's `handlers`, used only by the hoisted `rootReducer`) is seen as dead
1714
+ * against the spliced body and omitted from the import, while the chunk it lives
1715
+ * in keeps it. The bundle's export surface is left untouched: surviving spliced
1716
+ * names are now supplied by the inserted imports, so the published API is
1717
+ * byte-for-byte identical to before.
1718
+ *
1719
+ * @param parsed - The parsed entry bundle.
1720
+ * @param hoists - The modules hoisted out of this entry, each with its chunk specifier.
1721
+ * @param format - Output module format.
1722
+ * @returns The rewritten entry source, or the original source when `hoists` is empty.
1723
+ *
1724
+ * @example Rewriting an entry to import a shared module
1725
+ * ```typescript
1726
+ * const rewritten = rewriteEntry(parseEntry(source, 'esm'), [{ decls, specifier: './_shared/state/index.esm.js' }], 'esm')
1727
+ * ```
1728
+ */
1729
+ const rewriteEntry = (parsed, hoists, format) => {
1730
+ if (hoists.length === 0)
1731
+ return parsed.sourceFile.text;
1732
+ const deletions = [];
1733
+ for (const hoist of hoists)
1734
+ for (const decl of hoist.decls)
1735
+ deletions.push({ start: decl.statement.getFullStart(), end: decl.statement.getEnd(), text: '' });
1736
+ // why: liveness is measured on the body WITHOUT the hoisted decls (and before re-inserting imports), so a private symbol used only by another hoisted decl (e.g. `handlers`, used only by the hoisted `rootReducer`) is correctly seen as dead and never re-imported.
1737
+ const spliced = applyEdits$1(parsed.sourceFile.text, deletions);
1738
+ const live = collectIdentifierNames(spliced);
1739
+ const liveHoists = hoists
1740
+ .map((hoist) => ({ ...hoist, decls: hoist.decls.filter((decl) => live.has(decl.localName)) }))
1741
+ .filter((hoist) => hoist.decls.length > 0);
1742
+ if (liveHoists.length === 0)
1743
+ return spliced;
1744
+ const block = liveHoists.map((hoist) => renderImport(hoist, format)).join('\n');
1745
+ const insertion = parsed.headerEnd > 0 ? `\n${block}` : `${block}\n`;
1746
+ return applyEdits$1(parsed.sourceFile.text, [...deletions, { start: parsed.headerEnd, end: parsed.headerEnd, text: insertion }]);
1747
+ };
1748
+
1749
+ const log$6 = index_cjs_js$4.logger.channel('builder:bundle:dedupe');
1750
+ const FORMATS = ['esm', 'cjs'];
1751
+ const toSpecifier = (relative) => (relative.startsWith('.') ? relative : `./${relative}`);
1752
+ const recomputeSpecifier = (specifier, fromDir, baseDir) =>
1753
+ // why: relative `_dependencies`/`_shared` edges move with the chunk; bare and node-builtin specifiers resolve identically from anywhere, so they pass through verbatim.
1754
+ specifier.startsWith('.') ? toSpecifier(index_cjs_js$5.relativePath(fromDir, index_cjs_js$5.join(baseDir, specifier))) : specifier;
1755
+ const locateEntries = (context, format) => {
1756
+ const locations = [];
1757
+ for (const entry of context.entryPointDiscovery.entryPoints) {
1758
+ const dir = entryDirOf(entry, context);
1759
+ const file = index_cjs_js$5.join(dir, chunkFileName(format));
1760
+ if (index_cjs_js$5.exists(file))
1761
+ locations.push({ dir, file });
1762
+ }
1763
+ return locations;
1764
+ };
1765
+ const chunkFileFor = (context, moduleKey, format) => index_cjs_js$5.join(context.outputPath, sharedDirFor(moduleKey), chunkFileName(format));
1766
+ const buildChunkPlan = (planned, context, chunkDir, canonicalDir, format) => {
1767
+ const crossImports = planned.resolution.crossModule.map((ref) => ({
1768
+ ref: ref.ref,
1769
+ exported: ref.base,
1770
+ specifier: toSpecifier(index_cjs_js$5.relativePath(chunkDir, chunkFileFor(context, ref.moduleKey, format))),
1771
+ }));
1772
+ const depImports = planned.resolution.depImports.map((dep) => ({
1773
+ ref: dep.ref,
1774
+ kind: dep.binding.kind,
1775
+ imported: dep.binding.imported,
1776
+ specifier: recomputeSpecifier(dep.binding.specifier, chunkDir, canonicalDir),
1777
+ }));
1778
+ return { decls: planned.decls, crossImports, depImports };
1779
+ };
1780
+ const writeChunks = (context, plan, locations, format, report) => {
1781
+ for (const [moduleKey, planned] of plan) {
1782
+ const chunkDir = index_cjs_js$5.join(context.outputPath, sharedDirFor(moduleKey));
1783
+ const chunkPlan = buildChunkPlan(planned, context, chunkDir, locations[planned.canonicalEntryIndex].dir, format);
1784
+ const source = renderChunk(chunkPlan, format);
1785
+ index_cjs_js$5.ensureDir(chunkDir);
1786
+ index_cjs_js$5.writeFileContent(chunkFileFor(context, moduleKey, format), source);
1787
+ report.chunksWritten += 1;
1788
+ report.bytesReclaimed -= Buffer.byteLength(source);
1789
+ }
1790
+ };
1791
+ const rewriteEntries = (context, plan, entries, locations, format, report) => {
1792
+ for (const [index, entry] of entries.entries()) {
1793
+ const hoists = [];
1794
+ for (const [moduleKey] of plan) {
1795
+ const decls = entry.byModule.get(moduleKey);
1796
+ if (decls === undefined)
1797
+ continue;
1798
+ hoists.push({
1799
+ decls,
1800
+ specifier: toSpecifier(index_cjs_js$5.relativePath(locations[index].dir, chunkFileFor(context, moduleKey, format))),
1801
+ });
1802
+ for (const decl of decls)
1803
+ report.bytesReclaimed += Buffer.byteLength(decl.text);
1804
+ }
1805
+ if (hoists.length > 0)
1806
+ index_cjs_js$5.writeFileContent(locations[index].file, rewriteEntry(entry.parsed, hoists, format));
1807
+ }
1808
+ };
1809
+ const processFormat$2 = (context, owners, format, report) => {
1810
+ const locations = locateEntries(context, format);
1811
+ if (locations.length < 2)
1812
+ return;
1813
+ const entries = locations.map((location) => {
1814
+ const parsed = parseEntry(index_cjs_js$5.readFileContent(location.file), format);
1815
+ return { parsed, byModule: attribute(parsed, owners) };
1816
+ });
1817
+ const plan = planHoists(entries, owners);
1818
+ if (plan.size === 0)
1819
+ return;
1820
+ writeChunks(context, plan, locations, format, report);
1821
+ rewriteEntries(context, plan, entries, locations, format, report);
1822
+ };
1823
+ /**
1824
+ * Lifts first-party modules that are inlined into multiple entry bundles into
1825
+ * shared `_shared/<srcPath>/index.<fmt>.js` chunks and rewrites every consuming
1826
+ * entry to import them.
1827
+ *
1828
+ * Runs as an additive post-emit pass over the already-bundled `esm` and `cjs`
1829
+ * outputs, each processed independently; `iife`/`umd`/`bin` and `.d.ts` outputs
1830
+ * are never read. Per-entry isolated bundling is untouched. Every hoist is
1831
+ * proven safe by {@link planHoists} before it happens — structurally identical
1832
+ * copies, resolvable references, and cycle-free module-initialization — so any module
1833
+ * that cannot be proven safe is left inlined and the output is, worst case,
1834
+ * identical to the input.
1835
+ *
1836
+ * @param context - Resolved build context. `outputPath` locates the bundles and
1837
+ * `projectRoot/src` drives ownership attribution.
1838
+ * @param monitor - Optional memory monitor; a checkpoint is captured after each
1839
+ * format so the pass is observable.
1840
+ * @returns Counts of chunks written and net bytes reclaimed.
1841
+ *
1842
+ * @example Hoisting after the dependency prune
1843
+ * ```typescript
1844
+ * const report = hoistSharedFirstParty(context, monitor)
1845
+ * ```
1846
+ */
1847
+ const hoistSharedFirstParty = (context, monitor) => {
1848
+ const report = { chunksWritten: 0, bytesReclaimed: 0 };
1849
+ const srcRoot = index_cjs_js$5.join(context.projectRoot, 'src');
1850
+ if (!index_cjs_js$5.exists(srcRoot))
1851
+ return report;
1852
+ const owners = indexOwners(srcRoot);
1853
+ for (const format of FORMATS) {
1854
+ processFormat$2(context, owners, format, report);
1855
+ monitor?.check(`bundle:dedupe:shared-first-party:${format}:end`);
1856
+ }
1857
+ if (report.chunksWritten > 0)
1858
+ log$6.info(`hoisted ${report.chunksWritten} shared chunk(s), reclaimed ${report.bytesReclaimed} byte(s)`);
1859
+ return report;
1860
+ };
1861
+
1862
+ /**
1863
+ * Applies text-range edits to a chunk source by splicing each span in
1864
+ * descending start order, so every edit's offsets stay valid against the
1865
+ * original source regardless of the order they are passed in. All offsets must
1866
+ * refer to the original `source`, and spans must not overlap. The input `edits`
1867
+ * array is copied before sorting, so the caller's order is left untouched.
1868
+ *
1869
+ * @param source - Original chunk source text.
1870
+ * @param edits - Edits to apply; their relative order does not matter.
1871
+ * @param collapseBlankLines - When `true`, runs of three or more newlines left
1872
+ * behind by whole-statement splices are collapsed to a single blank line so the
1873
+ * trimmed chunk stays readable. Defaults to `false`.
1874
+ * @returns The rewritten source.
1875
+ *
1876
+ * @example Deleting a statement and collapsing the blank run it leaves
1877
+ * ```typescript
1878
+ * applyEdits(source, [{ start, end, text: '' }], true)
1879
+ * ```
1880
+ */
1881
+ const applyEdits = (source, edits, collapseBlankLines = false) => {
1882
+ let code = source;
1883
+ for (const edit of [...edits].sort((a, b) => b.start - a.start))
1884
+ code = `${code.slice(0, edit.start)}${edit.text}${code.slice(edit.end)}`;
1885
+ // why: splicing whole statements leaves runs of blank lines; collapse them so the trimmed chunk stays readable.
1886
+ return collapseBlankLines ? code.replace(/\n{3,}/g, '\n\n') : code;
1887
+ };
1888
+
1889
+ const renderEsmExportList = (entries) => `export { ${entries.map((entry) => (entry.exported === entry.local ? entry.local : `${entry.local} as ${entry.exported}`)).join(', ')} };`;
1890
+ const renderEsmImport = (elements, specifierText) => {
1891
+ const bindings = elements.map((element) => {
1892
+ const imported = (element.propertyName ?? element.name).text;
1893
+ return imported === element.name.text ? imported : `${imported} as ${element.name.text}`;
1894
+ });
1895
+ return `import { ${bindings.join(', ')} } from ${specifierText};`;
1896
+ };
1897
+ const narrowEsmImport = (statement, usedNames, sourceFile, edits) => {
1898
+ const clause = statement.importClause;
1899
+ // why: default and namespace imports bind the whole module object — never narrowed.
1900
+ if (!clause || clause.name || !clause.namedBindings || !ts__default.default.isNamedImports(clause.namedBindings))
1901
+ return;
1902
+ const surviving = clause.namedBindings.elements.filter((element) => usedNames.has(element.name.text));
1903
+ if (surviving.length === clause.namedBindings.elements.length)
1904
+ return;
1905
+ if (surviving.length === 0)
1906
+ edits.push({ start: statement.getFullStart(), end: statement.getEnd(), text: '' });
1907
+ else
1908
+ edits.push({
1909
+ start: statement.getStart(sourceFile),
1910
+ end: statement.getEnd(),
1911
+ text: renderEsmImport(surviving, statement.moduleSpecifier.getText(sourceFile)),
1912
+ });
1913
+ };
1914
+ const narrowCjsRequire = (statement, usedNames, edits) => {
1915
+ const locals = requireBindingLocals(statement);
1916
+ if (locals.length > 0 && locals.every((local) => !usedNames.has(local)))
1917
+ edits.push({ start: statement.getFullStart(), end: statement.getEnd(), text: '' });
1918
+ };
1919
+ const collectExportEdits = (exports$1, removedLocals, sourceFile, edits) => {
1920
+ const listGroups = index_cjs_js$b.createMap();
1921
+ for (const entry of exports$1) {
1922
+ if (entry.kind === 'cjs-assign' && removedLocals.has(entry.local))
1923
+ edits.push({ start: entry.statement.getFullStart(), end: entry.statement.getEnd(), text: '' });
1924
+ if (entry.kind !== 'esm-list')
1925
+ continue;
1926
+ const group = listGroups.get(entry.statement) ?? [];
1927
+ group.push(entry);
1928
+ listGroups.set(entry.statement, group);
1929
+ }
1930
+ for (const [statement, group] of listGroups) {
1931
+ const surviving = group.filter((entry) => !removedLocals.has(entry.local));
1932
+ if (surviving.length === group.length)
1933
+ continue;
1934
+ if (surviving.length === 0)
1935
+ edits.push({ start: statement.getFullStart(), end: statement.getEnd(), text: '' });
1936
+ else
1937
+ edits.push({ start: statement.getStart(sourceFile), end: statement.getEnd(), text: renderEsmExportList(surviving) });
1938
+ }
1939
+ };
1940
+ /**
1941
+ * Removes guaranteed-dead exported declarations (and the now-dead private code
1942
+ * and imports they pulled in) from a single chunk's source.
1943
+ *
1944
+ * Builds the chunk's declaration/export model, computes the keep-closure from
1945
+ * the importer-supplied `keep` demand, and splices out every side-effect-free
1946
+ * top-level declaration that no kept declaration, kept export, or bare
1947
+ * side-effecting statement references. The matching entries are dropped from the
1948
+ * export surface, and import bindings left unreferenced by the surviving code are
1949
+ * narrowed away (whole import statements when fully unused) — which is what
1950
+ * shrinks the cross-chunk dependency graph for the next fixpoint pass.
1951
+ * Side-effecting initializers and bare statements are always kept.
1952
+ *
1953
+ * @param source - Raw chunk source text.
1954
+ * @param format - Module format of the chunk.
1955
+ * @param keep - Exported names importers demand, or `'all'` to keep everything.
1956
+ * @returns The rewritten source and removed export names, or `null` when nothing
1957
+ * could be removed.
1958
+ *
1959
+ * @example Stripping all but one export from a chunk
1960
+ * ```typescript
1961
+ * stripDeadExports(source, 'esm', createSet(['getType']))
1962
+ * ```
1963
+ */
1964
+ const stripDeadExports = (source, format, keep) => {
1965
+ if (keep === 'all')
1966
+ return null;
1967
+ const sourceFile = parseChunk(source);
1968
+ const model = analyzeChunk(sourceFile, format);
1969
+ const keepClosure = computeKeepClosure(sourceFile, model, keep);
1970
+ const removableDecls = model.decls.filter((decl) => decl.sideEffectFree && decl.names.every((name) => !keepClosure.has(name)));
1971
+ if (removableDecls.length === 0)
1972
+ return null;
1973
+ const removedLocals = index_cjs_js$2.createSet([]);
1974
+ for (const decl of removableDecls)
1975
+ for (const name of decl.names)
1976
+ removedLocals.add(name);
1977
+ const removeSet = index_cjs_js$2.createSet(removableDecls.map((decl) => decl.statement));
1978
+ const removedNames = index_cjs_js$2.createSet([]);
1979
+ for (const entry of model.exports)
1980
+ if (removedLocals.has(entry.local))
1981
+ removedNames.add(entry.exported);
1982
+ const usedNames = index_cjs_js$2.createSet([]);
1983
+ for (const statement of sourceFile.statements) {
1984
+ if (model.importStatements.includes(statement) || removeSet.has(statement))
1985
+ continue;
1986
+ collectRefs(statement, usedNames);
1987
+ }
1988
+ const edits = removableDecls.map((decl) => ({ start: decl.statement.getFullStart(), end: decl.statement.getEnd(), text: '' }));
1989
+ collectExportEdits(model.exports, removedLocals, sourceFile, edits);
1990
+ for (const statement of model.importStatements) {
1991
+ if (format === 'esm')
1992
+ narrowEsmImport(statement, usedNames, sourceFile, edits);
1993
+ else
1994
+ narrowCjsRequire(statement, usedNames, edits);
1995
+ }
1996
+ return { code: applyEdits(source, edits, true), removedNames: index_cjs_js$3.from(removedNames) };
1997
+ };
1998
+
1999
+ const log$5 = index_cjs_js$4.logger.channel('builder:bundle:dependencies:prune');
2000
+ /**
2001
+ * Computes the set of files reachable from a set of root files by following
2002
+ * literal relative specifiers, restricted to targets under `depsRoot`.
2003
+ *
2004
+ * Targets that resolve outside `depsRoot` (the package's own non-dependency
2005
+ * code) are ignored; the roots themselves are always included so callers can use
2006
+ * the returned set as a single live-membership oracle.
2007
+ *
2008
+ * If a reached file **under `depsRoot`** contains a dynamic (non-literal)
2009
+ * `import(`/`require(`, the dependency chunk graph cannot be fully resolved, so
2010
+ * the function logs and returns `null` — the guaranteed-safe sentinel that
2011
+ * disables orphan deletion for the run. A dynamic specifier in a first-party
2012
+ * **root** (which is never under `depsRoot`) is ignored: its target is always an
2013
+ * external/user path, never a bundled dep chunk, so it cannot hide a
2014
+ * `_dependencies/` edge — bailing on it would needlessly strand emptied dep
2015
+ * chunks the sweep should reclaim.
2016
+ *
2017
+ * @param roots - Absolute paths to the root files reachability starts from.
2018
+ * @param depsRoot - Absolute path to the `_dependencies/` directory; traversal
2019
+ * never leaves it.
2020
+ * @param resolveTarget - Maps each resolved specifier target before it is
2021
+ * visited; defaults to identity. The d.ts pass passes a mapper that rewrites a
2022
+ * runtime specifier (`'.../index.js'`) to its declaration sibling
2023
+ * (`'.../index.d.ts'`) so traversal follows the type graph, never the runtime
2024
+ * graph.
2025
+ * @returns The set of reachable absolute file paths, or `null` when a dynamic
2026
+ * specifier forces a safety bail.
2027
+ *
2028
+ * @example Reachability from an ESM entry chunk
2029
+ * ```typescript
2030
+ * const live = computeReachable(['/dist/libs/foo/index.esm.js'], '/dist/libs/foo/_dependencies')
2031
+ * if (live && !live.has(orphanChunk)) unlinkSync(orphanChunk)
2032
+ * ```
2033
+ */
2034
+ const computeReachable = (roots, depsRoot, resolveTarget = (target) => target) => {
2035
+ const reachable = index_cjs_js$2.createSet([]);
2036
+ const queue = [];
2037
+ for (const root of roots) {
2038
+ if (index_cjs_js$5.exists(root) && !reachable.has(root)) {
2039
+ reachable.add(root);
2040
+ queue.push(root);
2041
+ }
2042
+ }
2043
+ let head = 0;
2044
+ while (head < queue.length) {
2045
+ const file = queue[head];
2046
+ head += 1;
2047
+ const source = index_cjs_js$5.readFileContent(file);
2048
+ // why: a dynamic specifier only threatens the sweep when it sits in a `_dependencies/` chunk, where it can hide an intra-deps edge to a sibling chunk we'd otherwise delete. First-party entry roots legitimately carry dynamic `import(<expr>)` (e.g. runtime config loading) whose targets are always external user paths — never bundled dep chunks — so bailing on those needlessly disables the entire sweep and strands emptied dep chunks. Roots are never under `depsRoot` (collectEntryFiles excludes them), so this scopes the bail to dep chunks only.
2049
+ if (isUnderDir(file, depsRoot) && hasDynamicSpecifier(source)) {
2050
+ log$5.warn(`dynamic import/require in ${file}; skipping dependency orphan prune for safety`);
2051
+ return null;
2052
+ }
2053
+ const dir = index_cjs_js$5.getDirname(file);
2054
+ for (const spec of collectChunkSpecifiers(source)) {
2055
+ const target = resolveTarget(index_cjs_js$5.join(dir, spec));
2056
+ if (isUnderDir(target, depsRoot) && index_cjs_js$5.exists(target) && !reachable.has(target)) {
2057
+ reachable.add(target);
2058
+ queue.push(target);
2059
+ }
2060
+ }
2061
+ }
2062
+ return reachable;
2063
+ };
2064
+
2065
+ /**
2066
+ * Resolves the package's own entry output files for the given file names,
2067
+ * skipping any entry directory that resolves at or under `_dependencies/`.
2068
+ *
2069
+ * These are the reachability/usage roots: the chunks a consumer's package entry
2070
+ * points actually load, from which dependency code is reached.
2071
+ *
2072
+ * @param context - Resolved build context supplying the entry points.
2073
+ * @param depsRoot - Absolute path to the `_dependencies/` directory.
2074
+ * @param fileNames - Output file names to look for in each entry directory
2075
+ * (e.g. `['index.esm.js']`).
2076
+ * @returns Absolute paths of every entry file that exists on disk.
2077
+ *
2078
+ * @example Collecting ESM entry roots
2079
+ * ```typescript
2080
+ * const roots = collectEntryFiles(context, depsRoot, ['index.esm.js'])
2081
+ * ```
2082
+ */
2083
+ const collectEntryFiles = (context, depsRoot, fileNames) => {
2084
+ const files = [];
2085
+ for (const entry of context.entryPointDiscovery.entryPoints) {
2086
+ const dir = entryDirOf(entry, context);
2087
+ if (isUnderDir(dir, depsRoot))
2088
+ continue;
2089
+ for (const name of fileNames) {
2090
+ const candidate = index_cjs_js$5.join(dir, name);
2091
+ if (index_cjs_js$5.exists(candidate))
2092
+ files.push(candidate);
2093
+ }
2094
+ }
2095
+ return files;
2096
+ };
2097
+ /**
2098
+ * Recursively collects file paths under `dir` whose base name satisfies
2099
+ * `matches`, appending them to `acc`.
2100
+ *
2101
+ * @param dir - Directory to walk; assumed to exist (the `_dependencies/` root or
2102
+ * a directory yielded by `readDirectory`).
2103
+ * @param matches - Predicate over a file's base name.
2104
+ * @param acc - Accumulator that receives every matching absolute path.
2105
+ *
2106
+ * @example Gathering every ESM chunk
2107
+ * ```typescript
2108
+ * const chunks: string[] = []
2109
+ * walkFiles(depsRoot, (name) => name === 'index.esm.js', chunks)
2110
+ * ```
2111
+ */
2112
+ const walkFiles = (dir, matches, acc) => {
2113
+ // why: only ever called on the validated `_dependencies/` root or a directory from `readDirectory`, so the target always exists — no existence guard needed.
2114
+ for (const entry of index_cjs_js$5.readDirectory(dir)) {
2115
+ if (entry.isDirectory)
2116
+ walkFiles(entry.path, matches, acc);
2117
+ else if (matches(entry.name))
2118
+ acc.push(entry.path);
2119
+ }
2120
+ };
2121
+ const unlinkWithMap = (path) => {
2122
+ // why: the caller only passes paths it just enumerated from disk, so statSync never misses.
2123
+ let bytesRemoved = node_fs.statSync(path).size;
2124
+ let orphanFilesRemoved = 1;
2125
+ node_fs.unlinkSync(path);
2126
+ const mapPath = `${path}.map`;
2127
+ if (index_cjs_js$5.exists(mapPath)) {
2128
+ bytesRemoved += node_fs.statSync(mapPath).size;
2129
+ node_fs.unlinkSync(mapPath);
2130
+ orphanFilesRemoved += 1;
2131
+ }
2132
+ return { orphanFilesRemoved, bytesRemoved };
2133
+ };
2134
+ const pruneJsOrphans = (context, depsRoot) => {
2135
+ const roots = collectEntryFiles(context, depsRoot, ['index.esm.js', 'index.cjs.js']);
2136
+ const reachable = computeReachable(roots, depsRoot);
2137
+ const chunks = [];
2138
+ walkFiles(depsRoot, (name) => name === 'index.esm.js' || name === 'index.cjs.js', chunks);
2139
+ // why: a dynamic-specifier bail keeps every chunk.
2140
+ if (reachable === null)
2141
+ return { orphanFilesRemoved: 0, bytesRemoved: 0 };
2142
+ let orphanFilesRemoved = 0;
2143
+ let bytesRemoved = 0;
2144
+ for (const chunk of chunks) {
2145
+ if (reachable.has(chunk))
2146
+ continue;
2147
+ const removed = unlinkWithMap(chunk);
2148
+ orphanFilesRemoved += removed.orphanFilesRemoved;
2149
+ bytesRemoved += removed.bytesRemoved;
2150
+ }
2151
+ return { orphanFilesRemoved, bytesRemoved };
2152
+ };
2153
+ // why: declaration specifiers carry the runtime extension (`'.../index.js'`, also `.esm.js`/`.cjs.js`); a d.ts type-reference resolves to the sibling `index.d.ts`, so the type-graph walk must rewrite the target before visiting it.
2154
+ const toDtsTarget = (target) => target.replace(/(?:\.esm|\.cjs)?\.[mc]?js$/, '.d.ts');
2155
+ const pruneDtsOrphans = (context, depsRoot) => {
2156
+ const roots = collectEntryFiles(context, depsRoot, ['index.d.ts']);
2157
+ const reachable = computeReachable(roots, depsRoot, toDtsTarget);
2158
+ const chunks = [];
2159
+ walkFiles(depsRoot, (name) => name === 'index.d.ts', chunks);
2160
+ // why: a dynamic specifier in the type graph cannot be resolved — keep every dep d.ts (guaranteed-safe fallback), mirroring the JS sweep.
2161
+ if (reachable === null)
2162
+ return { orphanFilesRemoved: 0, bytesRemoved: 0 };
2163
+ let orphanFilesRemoved = 0;
2164
+ let bytesRemoved = 0;
2165
+ for (const chunk of chunks) {
2166
+ // why: keep a dep's types only when an entry's own d.ts type-graph reaches them — the dts-per-entry pass makes each entry `index.d.ts` self-contained, so any dep d.ts no entry type-graph references is dead.
2167
+ if (reachable.has(chunk))
2168
+ continue;
2169
+ const removed = unlinkWithMap(chunk);
2170
+ orphanFilesRemoved += removed.orphanFilesRemoved;
2171
+ bytesRemoved += removed.bytesRemoved;
2172
+ }
2173
+ return { orphanFilesRemoved, bytesRemoved };
2174
+ };
2175
+ /**
2176
+ * Orphan Sweep: deletes `_dependencies/**` chunk files that no package entry
2177
+ * reaches.
2178
+ *
2179
+ * Runs reachability from the package's own entry output chunks over the
2180
+ * `_dependencies/` JS graph, unlinks every `index.{esm,cjs}.js` (and `.map`
2181
+ * sibling) that is unreachable, then applies the d.ts retention rule — a dep's
2182
+ * `index.d.ts` is kept only when it is reachable from an entry's `.d.ts` graph.
2183
+ * Entry `index.d.ts` are self-contained (dts-per-entry), so dep types no entry
2184
+ * type-graph references are dead and removed. Empty directories left behind are
2185
+ * removed. A dynamic, non-literal `import(`/`require(` anywhere in the reachable
2186
+ * graph disables deletion entirely (guaranteed-safe fallback).
2187
+ *
2188
+ * @param context - Resolved build context.
2189
+ * @param depsRoot - Absolute path to the `_dependencies/` directory.
2190
+ * @returns Aggregate count of files removed and bytes reclaimed.
2191
+ *
2192
+ * @example Sweeping orphans after the per-entry d.ts pass
2193
+ * ```typescript
2194
+ * const { orphanFilesRemoved } = pruneOrphanChunks(context, depsRootOf(context))
2195
+ * ```
2196
+ */
2197
+ const pruneOrphanChunks = (context, depsRoot) => {
2198
+ if (!index_cjs_js$5.exists(depsRoot) || !index_cjs_js$5.isDirectory(depsRoot))
2199
+ return { orphanFilesRemoved: 0, bytesRemoved: 0 };
2200
+ const js = pruneJsOrphans(context, depsRoot);
2201
+ const dts = pruneDtsOrphans(context, depsRoot);
2202
+ // why: shares the package-wide empty-dir helper; `depsRoot` itself is left intact, matching the prior `cleanupEmptyDirs` behavior.
2203
+ removeEmptyDirs(depsRoot);
2204
+ return {
2205
+ orphanFilesRemoved: js.orphanFilesRemoved + dts.orphanFilesRemoved,
2206
+ bytesRemoved: js.bytesRemoved + dts.bytesRemoved,
2207
+ };
2208
+ };
2209
+
2210
+ const mergeName = (edges, target, name) => {
2211
+ const current = edges.get(target);
2212
+ if (current === 'all')
2213
+ return;
2214
+ if (current)
2215
+ current.add(name);
2216
+ else
2217
+ edges.set(target, index_cjs_js$2.createSet([name]));
2218
+ };
2219
+ const mergeAll = (edges, target) => void edges.set(target, 'all');
2220
+ // why: a side-effect-only import (`import './x'`) reaches a chunk without naming any export; record it with an empty demand so the orphan re-sweep, not the export stripper, decides its fate.
2221
+ const markReached = (edges, target) => void (edges.has(target) || edges.set(target, index_cjs_js$2.createSet([])));
2222
+ const collectEsmEdges = (sourceFile, importerDir, edges) => {
2223
+ for (const statement of sourceFile.statements) {
2224
+ if (ts__default.default.isImportDeclaration(statement)) {
2225
+ // why: an `ImportDeclaration`'s module specifier is always a string literal in parseable source.
2226
+ const target = resolveRelativeTarget(importerDir, statement.moduleSpecifier.text);
2227
+ if (target === null)
2228
+ continue;
2229
+ const clause = statement.importClause;
2230
+ if (!clause) {
2231
+ markReached(edges, target);
2232
+ continue;
2233
+ }
2234
+ // why: `import def from 'F'` pulls the default export — consume the whole surface to stay safe.
2235
+ if (clause.name) {
2236
+ mergeAll(edges, target);
2237
+ continue;
2238
+ }
2239
+ // why: with no default binding, a parseable import always carries named bindings — either `* as ns` or `{ … }`.
2240
+ const bindings = clause.namedBindings;
2241
+ if (ts__default.default.isNamespaceImport(bindings)) {
2242
+ mergeAll(edges, target);
2243
+ continue;
2244
+ }
2245
+ for (const element of bindings.elements)
2246
+ mergeName(edges, target, (element.propertyName ?? element.name).text);
2247
+ continue;
2248
+ }
2249
+ if (ts__default.default.isExportDeclaration(statement) && statement.moduleSpecifier) {
2250
+ // why: a re-export's module specifier, when present, is always a string literal in parseable source.
2251
+ const target = resolveRelativeTarget(importerDir, statement.moduleSpecifier.text);
2252
+ if (target === null)
2253
+ continue;
2254
+ // why: `export * from 'F'` re-exports the entire surface — treat as wholesale demand.
2255
+ if (!statement.exportClause || !ts__default.default.isNamedExports(statement.exportClause)) {
2256
+ mergeAll(edges, target);
2257
+ continue;
2258
+ }
2259
+ for (const element of statement.exportClause.elements)
2260
+ mergeName(edges, target, (element.propertyName ?? element.name).text);
2261
+ }
2262
+ }
2263
+ };
2264
+ const collectCjsBindingEdges = (node, target, edges, namespaceBindings, declNames) => {
2265
+ const shape = classifyRequireBinding(node);
2266
+ switch (shape.kind) {
2267
+ case 'prop':
2268
+ mergeName(edges, target, shape.name);
2269
+ return;
2270
+ // why: inline element access (`require('./x')['foo']`, static or computed) keeps the whole chunk — this pass never narrowed it, and preserving that is safe (the namespace-usage pass narrows the static case). Narrowing here would be a separate enhancement.
2271
+ case 'elem-static':
2272
+ case 'elem-dynamic':
2273
+ mergeAll(edges, target);
2274
+ return;
2275
+ // why: a bare `require('./x')` statement pulls the chunk only for its side effects, naming no export; record it reached with empty demand — mirroring an ESM side-effect import — so the orphan re-sweep, not the export stripper, decides its fate.
2276
+ case 'side-effect':
2277
+ markReached(edges, target);
2278
+ return;
2279
+ case 'ns-binding':
2280
+ namespaceBindings.set(shape.name.text, target);
2281
+ declNames.add(shape.name);
2282
+ return;
2283
+ case 'destructure':
2284
+ for (const element of shape.pattern.elements) {
2285
+ // why: a rest element (`...rest`) captures every remaining export, so the surface must be kept whole.
2286
+ if (element.dotDotDotToken) {
2287
+ mergeAll(edges, target);
2288
+ continue;
2289
+ }
2290
+ const key = element.propertyName ?? element.name;
2291
+ if (ts__default.default.isIdentifier(key) || ts__default.default.isStringLiteralLike(key))
2292
+ mergeName(edges, target, key.text);
2293
+ else
2294
+ mergeAll(edges, target);
2295
+ }
2296
+ return;
2297
+ // why: a `require` used as a call argument, spread, or any non-binding position escapes member tracking — keep the whole chunk.
2298
+ case 'escape':
2299
+ mergeAll(edges, target);
2300
+ return;
2301
+ }
2302
+ };
2303
+ const scanNamespaceUse = (identifier, namespaceBindings, edges, declNames) => {
2304
+ const target = namespaceBindings.get(identifier.text);
2305
+ if (target === undefined || declNames.has(identifier))
2306
+ return;
2307
+ const parent = identifier.parent;
2308
+ if (ts__default.default.isPropertyAccessExpression(parent) && parent.expression === identifier && ts__default.default.isIdentifier(parent.name)) {
2309
+ mergeName(edges, target, parent.name.text);
2310
+ return;
2311
+ }
2312
+ if (ts__default.default.isElementAccessExpression(parent) && parent.expression === identifier) {
2313
+ if (ts__default.default.isStringLiteralLike(parent.argumentExpression))
2314
+ mergeName(edges, target, parent.argumentExpression.text);
2315
+ else
2316
+ mergeAll(edges, target);
2317
+ return;
2318
+ }
2319
+ // why: the binding name appearing as another object's property key is unrelated; every other position is a wholesale escape.
2320
+ if (!(ts__default.default.isPropertyAccessExpression(parent) && parent.name === identifier))
2321
+ mergeAll(edges, target);
2322
+ };
2323
+ const collectCjsEdges = (sourceFile, importerDir, edges) => {
2324
+ const namespaceBindings = index_cjs_js$b.createMap();
2325
+ const declNames = index_cjs_js$2.createSet([]);
2326
+ const findRequires = (node) => {
2327
+ const specifier = getRequireSpecifier(node);
2328
+ if (specifier !== null) {
2329
+ const target = resolveRelativeTarget(importerDir, specifier);
2330
+ if (target !== null)
2331
+ collectCjsBindingEdges(node, target, edges, namespaceBindings, declNames);
2332
+ }
2333
+ ts__default.default.forEachChild(node, findRequires);
2334
+ };
2335
+ findRequires(sourceFile);
2336
+ if (namespaceBindings.size === 0)
2337
+ return;
2338
+ const scanUses = (node) => {
2339
+ if (ts__default.default.isIdentifier(node))
2340
+ scanNamespaceUse(node, namespaceBindings, edges, declNames);
2341
+ ts__default.default.forEachChild(node, scanUses);
2342
+ };
2343
+ scanUses(sourceFile);
2344
+ };
2345
+ /**
2346
+ * Builds the map of chunk → exported-name demand for every relative module edge
2347
+ * a single importer declares.
2348
+ *
2349
+ * Each key is the absolute path the importer references; each value is the set
2350
+ * of exported names it pulls from that chunk, or `'all'` when the reference is
2351
+ * wholesale (namespace/default import, `export *`, or a `require` binding that
2352
+ * escapes member access). A side-effect-only `import './x'` records the target
2353
+ * with an empty set.
2354
+ *
2355
+ * @param source - Raw importer source text.
2356
+ * @param importerDir - Absolute directory of the importer file.
2357
+ * @param format - Module format that determines ESM vs CJS edge extraction.
2358
+ * @returns Map from resolved chunk path to its usage demand.
2359
+ *
2360
+ * @example Edges of an ESM entry
2361
+ * ```typescript
2362
+ * collectImportEdges("import { getType } from './_dependencies/x/index.esm.js'", '/dist/libs/foo', 'esm')
2363
+ * // => Map { '/dist/libs/foo/_dependencies/x/index.esm.js' => Set { 'getType' } }
2364
+ * ```
2365
+ */
2366
+ const collectImportEdges = (source, importerDir, format) => {
2367
+ const sourceFile = parseChunk(source);
2368
+ const edges = index_cjs_js$b.createMap();
2369
+ if (format === 'esm')
2370
+ collectEsmEdges(sourceFile, importerDir, edges);
2371
+ else
2372
+ collectCjsEdges(sourceFile, importerDir, edges);
2373
+ return edges;
2374
+ };
2375
+
2376
+ const log$4 = index_cjs_js$4.logger.channel('builder:bundle:dependencies:prune');
2377
+ // why: the strip → re-derive → strip cycle converges in passes bounded by the chunk-import depth; this cap is a runaway guard, logged if ever reached.
2378
+ const MAX_ITERATIONS = 50;
2379
+ const FORMAT_FILES$1 = [
2380
+ { format: 'esm', fileName: 'index.esm.js' },
2381
+ { format: 'cjs', fileName: 'index.cjs.js' },
2382
+ ];
2383
+ const mergeUsage = (usageMap, target, usage) => {
2384
+ const current = usageMap.get(target);
2385
+ // why: targets outside the surviving-chunk set are the package's own code — not strippable, so ignore their demand.
2386
+ if (current === undefined || current === 'all')
2387
+ return;
2388
+ if (usage === 'all') {
2389
+ usageMap.set(target, 'all');
2390
+ return;
2391
+ }
2392
+ for (const name of usage)
2393
+ current.add(name);
2394
+ };
2395
+ const buildUsageMap = (importers, chunks, format) => {
2396
+ const usageMap = index_cjs_js$b.createMap();
2397
+ for (const chunk of chunks)
2398
+ usageMap.set(chunk, index_cjs_js$2.createSet([]));
2399
+ // why: every importer is either a validated entry file or a chunk just walked off disk, so all are present — no existence guard needed.
2400
+ for (const importer of importers) {
2401
+ for (const [target, usage] of collectImportEdges(index_cjs_js$5.readFileContent(importer), index_cjs_js$5.getDirname(importer), format))
2402
+ mergeUsage(usageMap, target, usage);
2403
+ }
2404
+ return usageMap;
2405
+ };
2406
+ const stripChunks = (usageMap, format, result) => {
2407
+ let changed = false;
2408
+ for (const [chunk, keep] of usageMap) {
2409
+ const source = index_cjs_js$5.readFileContent(chunk);
2410
+ const stripped = stripDeadExports(source, format, keep);
2411
+ if (!stripped)
2412
+ continue;
2413
+ index_cjs_js$5.writeFileContent(chunk, stripped.code);
2414
+ result.deadExportsRemoved += stripped.removedNames.length;
2415
+ result.bytesRemoved += Buffer.byteLength(source) - Buffer.byteLength(stripped.code);
2416
+ changed = true;
2417
+ }
2418
+ return changed;
2419
+ };
2420
+ const processFormat$1 = (context, depsRoot, format, fileName, result) => {
2421
+ const entries = collectEntryFiles(context, depsRoot, [fileName]);
2422
+ for (let iteration = 0; iteration < MAX_ITERATIONS; iteration += 1) {
2423
+ const chunks = [];
2424
+ walkFiles(depsRoot, (name) => name === fileName, chunks);
2425
+ if (chunks.length === 0)
2426
+ return;
2427
+ const usageMap = buildUsageMap([...entries, ...chunks], chunks, format);
2428
+ if (!stripChunks(usageMap, format, result))
2429
+ return;
2430
+ // istanbul ignore next -- why: convergence exits via the early return above; a >50-deep chunk import chain that would exhaust the cap cannot occur in bundled dependency output, so the guard log is unreachable in practice.
2431
+ if (iteration === MAX_ITERATIONS - 1)
2432
+ log$4.warn(`dead-export strip for ${format} hit the ${MAX_ITERATIONS}-iteration cap before converging`);
2433
+ }
2434
+ };
2435
+ /**
2436
+ * Shrinks surviving `_dependencies/` chunks by stripping dead exported
2437
+ * declarations, iterating to a fixpoint per format.
2438
+ *
2439
+ * Each iteration re-derives the importer demand for every surviving chunk from
2440
+ * the current on-disk sources (entries plus sibling chunks), strips each chunk
2441
+ * to that demand, and repeats until no chunk changes — because removing one
2442
+ * chunk's import can make another chunk's export dead in turn. ESM and CJS are
2443
+ * processed independently. The orphan sweep is expected to run afterwards to
2444
+ * reclaim any chunk whose last import was removed here.
2445
+ *
2446
+ * @param context - Resolved build context supplying the entry points.
2447
+ * @param depsRoot - Absolute path to the `_dependencies/` directory.
2448
+ * @returns Counts of exports removed and bytes reclaimed.
2449
+ *
2450
+ * @example Running the strip pass after the orphan sweep
2451
+ * ```typescript
2452
+ * const { deadExportsRemoved } = stripDeadExportsPass(context, depsRootOf(context))
2453
+ * ```
2454
+ */
2455
+ const stripDeadExportsPass = (context, depsRoot) => {
2456
+ const result = { deadExportsRemoved: 0, bytesRemoved: 0 };
2457
+ if (!index_cjs_js$5.exists(depsRoot))
2458
+ return result;
2459
+ for (const { format, fileName } of FORMAT_FILES$1)
2460
+ processFormat$1(context, depsRoot, format, fileName, result);
2461
+ return result;
2462
+ };
2463
+
2464
+ /**
2465
+ * Merges a property demand into a per-export demand map, with `'all'` absorbing.
2466
+ *
2467
+ * @param demand - Map from export name to its accumulated property demand.
2468
+ * @param name - The export name receiving the contribution.
2469
+ * @param contribution - Either a set of read property names or `'all'`.
2470
+ *
2471
+ * @example Accumulating two reads of the same export
2472
+ * ```typescript
2473
+ * mergeDemand(demand, 'SafeObject', createSet(['freeze']))
2474
+ * mergeDemand(demand, 'SafeObject', createSet(['keys'])) // => { SafeObject: { freeze, keys } }
2475
+ * ```
2476
+ */
2477
+ const mergeDemand = (demand, name, contribution) => {
2478
+ const current = demand.get(name);
2479
+ if (current === 'all')
2480
+ return;
2481
+ if (contribution === 'all') {
2482
+ demand.set(name, 'all');
2483
+ return;
2484
+ }
2485
+ if (current)
2486
+ for (const prop of contribution)
2487
+ current.add(prop);
2488
+ else
2489
+ demand.set(name, index_cjs_js$2.createSet([...contribution]));
2490
+ };
2491
+ /**
2492
+ * Classifies a single identifier occurrence of a namespace binding as a static
2493
+ * property read, a wholesale-escape that forbids stripping, or an unrelated
2494
+ * position that names something else.
2495
+ *
2496
+ * Only `NS.prop` and `NS["prop"]` are property reads; a dynamic `NS[k]`, a
2497
+ * spread, or any value position (call argument, assignment, return, re-export,
2498
+ * shorthand) is an escape. A value sitting as a member name (`obj.NS`),
2499
+ * object-literal key (`{ NS: … }`), or binding property name is unrelated. The
2500
+ * value is usually an identifier binding, but may be a member node (`dep.NS`)
2501
+ * when classifying the use of a CJS export selected off a require binding.
2502
+ *
2503
+ * @param node - The expression occurrence to classify (an identifier binding or a `dep.Export` member node).
2504
+ * @returns The classification of this occurrence.
2505
+ *
2506
+ * @example A static property read
2507
+ * ```typescript
2508
+ * // for the `NS` in `NS.freeze(x)`
2509
+ * classifyNamespaceUse(id) // => { kind: 'read', prop: 'freeze' }
2510
+ * ```
2511
+ */
2512
+ const classifyNamespaceUse = (node) => {
2513
+ const parent = node.parent;
2514
+ if (ts__default.default.isPropertyAccessExpression(parent)) {
2515
+ // why: `obj.NS` — the value sits as the member name, not a use of the binding's value.
2516
+ if (parent.name === node)
2517
+ return { kind: 'ignore' };
2518
+ return { kind: 'read', prop: parent.name.text };
2519
+ }
2520
+ if (ts__default.default.isElementAccessExpression(parent) && parent.expression === node) {
2521
+ // why: a literal `NS["freeze"]` is a known slot; a computed `NS[k]` could read any slot, so keep them all.
2522
+ return ts__default.default.isStringLiteralLike(parent.argumentExpression) ? { kind: 'read', prop: parent.argumentExpression.text } : { kind: 'bail' };
2523
+ }
2524
+ // why: `{ NS: … }` key and `{ NS: x } = …` binding key never reference the binding's value.
2525
+ if (ts__default.default.isPropertyAssignment(parent) && parent.name === node)
2526
+ return { kind: 'ignore' };
2527
+ if (ts__default.default.isBindingElement(parent) && parent.propertyName === node)
2528
+ return { kind: 'ignore' };
2529
+ return { kind: 'bail' };
2530
+ };
2531
+ // why: a member node `mod.Export` selects one export; classify how *that* member is then used (its `.prop` read, or a wholesale escape) and fold it into the export's demand. Shared by CJS whole-`require` namespace bindings and inline `require(...).Export` access.
2532
+ const recordMemberUse = (memberNode, exportName, usage) => {
2533
+ const classification = classifyNamespaceUse(memberNode);
2534
+ if (classification.kind === 'read')
2535
+ mergeDemand(usage.perName, exportName, index_cjs_js$2.createSet([classification.prop]));
2536
+ else
2537
+ mergeDemand(usage.perName, exportName, 'all');
2538
+ };
2539
+ const ensureUsage = (edges, target) => {
2540
+ const current = edges.get(target);
2541
+ if (current)
2542
+ return current;
2543
+ const created = { bailAll: false, perName: index_cjs_js$b.createMap() };
2544
+ edges.set(target, created);
2545
+ return created;
2546
+ };
2547
+ const collectImports = (sourceFile, importerDir, edges, locals, bindingNodes) => {
2548
+ for (const statement of sourceFile.statements) {
2549
+ if (ts__default.default.isImportDeclaration(statement)) {
2550
+ const target = resolveRelativeTarget(importerDir, statement.moduleSpecifier.text);
2551
+ // why: a side-effect-only import has no clause and binds nothing to track.
2552
+ if (target === null || !statement.importClause)
2553
+ continue;
2554
+ const clause = statement.importClause;
2555
+ // why: a default import binds the whole module object — we cannot tell which export it aliases, so keep every namespace of the target.
2556
+ if (clause.name)
2557
+ ensureUsage(edges, target).bailAll = true;
2558
+ const bindings = clause.namedBindings;
2559
+ if (!bindings)
2560
+ continue;
2561
+ if (ts__default.default.isNamespaceImport(bindings)) {
2562
+ ensureUsage(edges, target).bailAll = true;
2563
+ continue;
2564
+ }
2565
+ for (const element of bindings.elements) {
2566
+ locals.set(element.name.text, { target, exportName: (element.propertyName ?? element.name).text });
2567
+ bindingNodes.add(element.name);
2568
+ ensureUsage(edges, target);
2569
+ }
2570
+ continue;
2571
+ }
2572
+ if (ts__default.default.isExportDeclaration(statement) && statement.moduleSpecifier) {
2573
+ const target = resolveRelativeTarget(importerDir, statement.moduleSpecifier.text);
2574
+ if (target === null)
2575
+ continue;
2576
+ const usage = ensureUsage(edges, target);
2577
+ // why: `export * from 'F'` re-exports every name wholesale — keep the whole surface.
2578
+ if (!statement.exportClause || !ts__default.default.isNamedExports(statement.exportClause)) {
2579
+ usage.bailAll = true;
2580
+ continue;
2581
+ }
2582
+ // why: a re-export hands the namespace to another chunk's importers we cannot see — keep it whole (one-hop safety).
2583
+ for (const element of statement.exportClause.elements)
2584
+ mergeDemand(usage.perName, (element.propertyName ?? element.name).text, 'all');
2585
+ }
2586
+ }
2587
+ };
2588
+ const scanUse = (id, locals, edges, bindingNodes) => {
2589
+ const tracked = locals.get(id.text);
2590
+ if (!tracked || bindingNodes.has(id))
2591
+ return;
2592
+ const usage = edges.get(tracked.target);
2593
+ // why: a target already marked wholesale needs no finer demand.
2594
+ if (!usage || usage.bailAll)
2595
+ return;
2596
+ const classification = classifyNamespaceUse(id);
2597
+ if (classification.kind === 'read')
2598
+ mergeDemand(usage.perName, tracked.exportName, index_cjs_js$2.createSet([classification.prop]));
2599
+ else if (classification.kind === 'bail')
2600
+ mergeDemand(usage.perName, tracked.exportName, 'all');
2601
+ };
2602
+ // why: a CJS `var dep = require('F')` reaches an export as `dep.Export`, so the property read is two-level (`dep.Export.prop`); a `var { Export } = require('F')` destructure binds the export directly (one-level, tracked like an ESM named import). This records both, plus inline `require('F').Export` access.
2603
+ const bindRequire = (call, target, edges, locals, namespaceBindings, bindingNodes) => {
2604
+ const usage = ensureUsage(edges, target);
2605
+ const shape = classifyRequireBinding(call);
2606
+ switch (shape.kind) {
2607
+ // why: `require('F').Export` / `require('F')['Export']` — inline member access selecting one export; classify the member's own use.
2608
+ case 'prop':
2609
+ case 'elem-static':
2610
+ recordMemberUse(shape.member, shape.name, usage);
2611
+ return;
2612
+ // why: `require('F')[k]` could select any export — keep the whole target.
2613
+ case 'elem-dynamic':
2614
+ usage.bailAll = true;
2615
+ return;
2616
+ // why: a bare `require('./x')` statement binds nothing and reads no property — a side-effect-only import (mirrored from ESM, which skips clause-less imports) that forbids no slot.
2617
+ case 'side-effect':
2618
+ return;
2619
+ case 'ns-binding':
2620
+ namespaceBindings.set(shape.name.text, target);
2621
+ bindingNodes.add(shape.name);
2622
+ return;
2623
+ case 'destructure':
2624
+ for (const element of shape.pattern.elements) {
2625
+ const key = element.propertyName ?? element.name;
2626
+ // why: a rest element or a nested/computed binding captures more than one named export — keep the whole target.
2627
+ if (element.dotDotDotToken || !ts__default.default.isIdentifier(element.name) || !(ts__default.default.isIdentifier(key) || ts__default.default.isStringLiteralLike(key))) {
2628
+ usage.bailAll = true;
2629
+ continue;
2630
+ }
2631
+ locals.set(element.name.text, { target, exportName: key.text });
2632
+ bindingNodes.add(element.name);
2633
+ }
2634
+ return;
2635
+ // why: a `require` not bound to a variable (call argument, spread, …) escapes member tracking — keep the whole target.
2636
+ case 'escape':
2637
+ usage.bailAll = true;
2638
+ return;
2639
+ }
2640
+ };
2641
+ const collectRequires = (sourceFile, importerDir, edges, locals, namespaceBindings, bindingNodes) => {
2642
+ const visit = (node) => {
2643
+ const specifier = getRequireSpecifier(node);
2644
+ if (specifier !== null) {
2645
+ const target = resolveRelativeTarget(importerDir, specifier);
2646
+ if (target !== null)
2647
+ bindRequire(node, target, edges, locals, namespaceBindings, bindingNodes);
2648
+ }
2649
+ ts__default.default.forEachChild(node, visit);
2650
+ };
2651
+ visit(sourceFile);
2652
+ };
2653
+ const scanNamespaceBindingUse = (id, namespaceBindings, edges, bindingNodes) => {
2654
+ const target = namespaceBindings.get(id.text);
2655
+ if (target === undefined || bindingNodes.has(id))
2656
+ return;
2657
+ const usage = edges.get(target);
2658
+ if (!usage || usage.bailAll)
2659
+ return;
2660
+ const parent = id.parent;
2661
+ // why: `dep.Export …` — the member selects one export; classify how that member is used for the property read.
2662
+ if (ts__default.default.isPropertyAccessExpression(parent) && parent.expression === id) {
2663
+ recordMemberUse(parent, parent.name.text, usage);
2664
+ return;
2665
+ }
2666
+ if (ts__default.default.isElementAccessExpression(parent) && parent.expression === id) {
2667
+ // why: `dep["Export"]` selects a known export; `dep[k]` could select any, so keep every export of the target.
2668
+ if (ts__default.default.isStringLiteralLike(parent.argumentExpression))
2669
+ recordMemberUse(parent, parent.argumentExpression.text, usage);
2670
+ else
2671
+ usage.bailAll = true;
2672
+ return;
2673
+ }
2674
+ // why: `obj.dep` — the binding sits as a member name, unrelated. Every other position consumes the module wholesale.
2675
+ if (!(ts__default.default.isPropertyAccessExpression(parent) && parent.name === id))
2676
+ usage.bailAll = true;
2677
+ };
2678
+ /**
2679
+ * Builds the per-target namespace-usage map an ESM importer declares: for every
2680
+ * relative chunk it imports, which exported names it reads at a strict set of
2681
+ * properties versus consumes wholesale.
2682
+ *
2683
+ * ESM named imports (`import { NS as L }`) and CJS destructured requires
2684
+ * (`const { NS: L } = require('F')`) bind an export to a local `L` tracked
2685
+ * one-level: every occurrence of `L` is classified. A CJS whole-module binding
2686
+ * (`const dep = require('F')`) is tracked two-level: `dep.NS.prop` reads the
2687
+ * property `prop` of export `NS`. A namespace/default import, `export *`, a
2688
+ * dynamic `dep[k]`, or any wholesale use of the module binding marks the target
2689
+ * `bailAll`; a re-export marks the re-exported name `'all'`. The importer is
2690
+ * parsed exactly once and released by the caller.
2691
+ *
2692
+ * @param source - Raw importer source text.
2693
+ * @param importerDir - Absolute directory of the importer file.
2694
+ * @param format - Module format selecting ESM `import` vs CJS `require` edges.
2695
+ * @returns Map from resolved chunk path to its namespace usage.
2696
+ *
2697
+ * @example Reading two slots off an imported namespace
2698
+ * ```typescript
2699
+ * collectNamespaceUsage("import { SafeObject } from './d/index.esm.js';\nSafeObject.freeze(x);\nSafeObject.keys(y);", '/dist/libs/foo', 'esm')
2700
+ * // => Map { '/dist/libs/foo/d/index.esm.js' => { bailAll: false, perName: { SafeObject: { freeze, keys } } } }
2701
+ * ```
2702
+ */
2703
+ const collectNamespaceUsage = (source, importerDir, format) => {
2704
+ const edges = index_cjs_js$b.createMap();
2705
+ const sourceFile = parseChunk(source);
2706
+ const locals = index_cjs_js$b.createMap();
2707
+ const namespaceBindings = index_cjs_js$b.createMap();
2708
+ const bindingNodes = index_cjs_js$2.createSet([]);
2709
+ if (format === 'esm')
2710
+ collectImports(sourceFile, importerDir, edges, locals, bindingNodes);
2711
+ else
2712
+ collectRequires(sourceFile, importerDir, edges, locals, namespaceBindings, bindingNodes);
2713
+ if (locals.size === 0 && namespaceBindings.size === 0)
2714
+ return edges;
2715
+ const visit = (node) => {
2716
+ if (ts__default.default.isIdentifier(node)) {
2717
+ scanUse(node, locals, edges, bindingNodes);
2718
+ if (namespaceBindings.size > 0)
2719
+ scanNamespaceBindingUse(node, namespaceBindings, edges, bindingNodes);
2720
+ }
2721
+ ts__default.default.forEachChild(node, visit);
2722
+ };
2723
+ visit(sourceFile);
2724
+ return edges;
2725
+ };
2726
+
2727
+ // why: an identifier is a free reference or a binding name unless it sits in a member-name / object-key position, where it never introduces or reads a top-level-visible name. The reserved set is what new destructured locals must avoid colliding with.
2728
+ const isNameOnlyPosition = (id) => {
2729
+ const parent = id.parent;
2730
+ if (ts__default.default.isPropertyAccessExpression(parent) && parent.name === id)
2731
+ return true;
2732
+ if (ts__default.default.isPropertyAssignment(parent) && parent.name === id)
2733
+ return true;
2734
+ if (ts__default.default.isBindingElement(parent) && parent.propertyName === id)
2735
+ return true;
2736
+ return false;
2737
+ };
2738
+ const collectReserved = (sourceFile, bindingNodes) => {
2739
+ const reserved = index_cjs_js$2.createSet([]);
2740
+ const visit = (node) => {
2741
+ // why: a candidate's own binding name is being removed, so it never blocks a chosen local.
2742
+ if (ts__default.default.isIdentifier(node) && !bindingNodes.has(node) && !isNameOnlyPosition(node))
2743
+ reserved.add(node.text);
2744
+ ts__default.default.forEachChild(node, visit);
2745
+ };
2746
+ visit(sourceFile);
2747
+ return reserved;
2748
+ };
2749
+ const collectCandidates = (sourceFile, chunkDir, isSafeTarget) => {
2750
+ const candidates = index_cjs_js$b.createMap();
2751
+ const seen = index_cjs_js$2.createSet([]);
2752
+ const visit = (node) => {
2753
+ const specifier = getRequireSpecifier(node);
2754
+ if (specifier !== null) {
2755
+ const target = resolveRelativeTarget(chunkDir, specifier);
2756
+ const parent = node.parent;
2757
+ // why: when a `require` call's direct parent is a `VariableDeclaration`, the call is necessarily its initializer (a declaration's only expression child), so no separate initializer check is needed.
2758
+ if (target !== null && isSafeTarget(target) && ts__default.default.isVariableDeclaration(parent) && ts__default.default.isIdentifier(parent.name)) {
2759
+ const local = parent.name.text;
2760
+ // why: a local bound twice cannot be tracked unambiguously by text scan — drop it from consideration entirely.
2761
+ if (seen.has(local))
2762
+ candidates.delete(local);
2763
+ else {
2764
+ seen.add(local);
2765
+ candidates.set(local, { local, nameNode: parent.name, members: index_cjs_js$b.createMap(), bail: false });
2766
+ }
2767
+ }
2768
+ }
2769
+ ts__default.default.forEachChild(node, visit);
2770
+ };
2771
+ visit(sourceFile);
2772
+ return candidates;
2773
+ };
2774
+ // why: a destructure shorthand `const { name } = require(...)` is legal only when `name` is a real BindingIdentifier — so lex `name` whole. A single `Identifier` followed by end-of-input proves it: a keyword (`default`, and strict-reserved `let`/`yield`/`static`/`await`, illegal in rollup's strict CJS) lexes to its own keyword token, not `Identifier`; a non-identifier key (`foo-bar` from `NS["foo-bar"]`) lexes to `Identifier` + more tokens, so the EOF check fails. Over-bailing a rare contextual export name (`as`/`type`) is safe: it keeps the namespace form, which is valid.
2775
+ const isValidBindingName = (name) => {
2776
+ const scanner = ts__default.default.createScanner(ts__default.default.ScriptTarget.ESNext, /*skipTrivia*/ true, ts__default.default.LanguageVariant.Standard, name);
2777
+ return scanner.scan() === ts__default.default.SyntaxKind.Identifier && scanner.scan() === ts__default.default.SyntaxKind.EndOfFileToken;
2778
+ };
2779
+ const scanUses = (sourceFile, candidates, bindingNodes) => {
2780
+ const visit = (node) => {
2781
+ if (ts__default.default.isIdentifier(node) && !bindingNodes.has(node)) {
2782
+ const candidate = candidates.get(node.text);
2783
+ if (candidate && !candidate.bail) {
2784
+ const classification = classifyNamespaceUse(node);
2785
+ // why: a member named by a non-identifier (`m['foo-bar']`) or a keyword (`m.default`) cannot be destructured to a legal `const { … }` binding — bail the whole candidate to its namespace form rather than emit invalid JS.
2786
+ if (classification.kind === 'bail' || (classification.kind === 'read' && !isValidBindingName(classification.prop)))
2787
+ candidate.bail = true;
2788
+ else if (classification.kind === 'read') {
2789
+ const nodes = candidate.members.get(classification.prop) ?? [];
2790
+ nodes.push(node.parent);
2791
+ candidate.members.set(classification.prop, nodes);
2792
+ }
2793
+ }
2794
+ }
2795
+ ts__default.default.forEachChild(node, visit);
2796
+ };
2797
+ visit(sourceFile);
2798
+ };
2799
+ const renderBindingPattern = (assignments) => `{ ${assignments.map(({ exported, local }) => (exported === local ? exported : `${exported}: ${local}`)).join(', ')} }`;
2800
+ const allocateLocal = (exported, taken) => {
2801
+ if (!taken.has(exported))
2802
+ return exported;
2803
+ let suffix = 1;
2804
+ while (taken.has(`${exported}$${suffix}`))
2805
+ suffix += 1;
2806
+ return `${exported}$${suffix}`;
2807
+ };
2808
+ /**
2809
+ * Rewrites whole-module CJS require bindings to destructuring binds when the
2810
+ * binding is consumed only as static member reads.
2811
+ *
2812
+ * For every top-level `const NS = require('./rel')` whose target `isSafeTarget`
2813
+ * accepts (a relative sibling chunk that is provably not in a `require` cycle
2814
+ * with this chunk), and where `NS` is used exclusively as `NS.member` /
2815
+ * `NS['member']` reads, the binding is collapsed to `const { member, … } =
2816
+ * require('./rel')` and each `NS.member` access is replaced by the bound local.
2817
+ * Locals that would collide with an existing free identifier or another bound
2818
+ * local are aliased (`member: member$1`) — so the rewrite never shadows the
2819
+ * chunk's own names. Any wholesale, dynamic, or reassigning use of `NS` leaves
2820
+ * its binding untouched, matching rollup's namespace-access codegen.
2821
+ *
2822
+ * The cycle guard is the caller's responsibility: rollup keeps the namespace
2823
+ * form precisely so an eager destructure cannot capture an export before a
2824
+ * circular dependency has initialized it. Passing only acyclic targets to
2825
+ * `isSafeTarget` preserves that guarantee.
2826
+ *
2827
+ * @param source - Raw CJS chunk source text.
2828
+ * @param chunkDir - Absolute directory of the chunk, for resolving relative requires.
2829
+ * @param isSafeTarget - Predicate selecting which resolved require targets may be destructured.
2830
+ * @returns The rewritten source and the count of bindings destructured, or `null`
2831
+ * when no binding qualified.
2832
+ *
2833
+ * @example Destructuring a single-member require
2834
+ * ```typescript
2835
+ * destructureRequires("const m = require('./math/index.cjs.js');\nm.abs(x);", '/d/p', () => true)
2836
+ * // => { code: "const { abs } = require('./math/index.cjs.js');\nabs(x);", rewrittenBindings: 1 }
2837
+ * ```
2838
+ */
2839
+ const destructureRequires = (source, chunkDir, isSafeTarget) => {
2840
+ const sourceFile = parseChunk(source);
2841
+ const candidates = collectCandidates(sourceFile, chunkDir, isSafeTarget);
2842
+ if (candidates.size === 0)
2843
+ return null;
2844
+ const bindingNodes = index_cjs_js$2.createSet([...candidates.values()].map((candidate) => candidate.nameNode));
2845
+ scanUses(sourceFile, candidates, bindingNodes);
2846
+ const qualified = [...candidates.values()].filter((candidate) => !candidate.bail && candidate.members.size > 0);
2847
+ if (qualified.length === 0)
2848
+ return null;
2849
+ // why: every binding being collapsed frees its own name, so exclude binding nodes; new locals must dodge all other free identifiers.
2850
+ const taken = collectReserved(sourceFile, bindingNodes);
2851
+ const edits = [];
2852
+ for (const candidate of qualified) {
2853
+ const assignments = [];
2854
+ for (const exported of [...candidate.members.keys()].sort()) {
2855
+ const local = allocateLocal(exported, taken);
2856
+ taken.add(local);
2857
+ assignments.push({ exported, local });
2858
+ // why: the member-access node (`NS.member` or `NS['member']`) collapses to the bound local; the key came from this same map, so the lookup always resolves.
2859
+ for (const accessNode of candidate.members.get(exported))
2860
+ edits.push({ start: accessNode.getStart(sourceFile), end: accessNode.getEnd(), text: local });
2861
+ }
2862
+ edits.push({
2863
+ start: candidate.nameNode.getStart(sourceFile),
2864
+ end: candidate.nameNode.getEnd(),
2865
+ text: renderBindingPattern(assignments),
2866
+ });
2867
+ }
2868
+ return { code: applyEdits(source, edits), rewrittenBindings: qualified.length };
2869
+ };
2870
+
2871
+ const log$3 = index_cjs_js$4.logger.channel('builder:bundle:dependencies:prune');
2872
+ const CJS_CHUNK = 'index.cjs.js';
2873
+ const collectRequireTargets = (source, chunkDir, chunkSet) => {
2874
+ const sourceFile = parseChunk(source);
2875
+ const targets = index_cjs_js$2.createSet([]);
2876
+ const visit = (node) => {
2877
+ const specifier = getRequireSpecifier(node);
2878
+ if (specifier !== null) {
2879
+ const target = resolveRelativeTarget(chunkDir, specifier);
2880
+ if (target !== null && chunkSet.has(target))
2881
+ targets.add(target);
2882
+ }
2883
+ ts__default.default.forEachChild(node, visit);
2884
+ };
2885
+ visit(sourceFile);
2886
+ return targets;
2887
+ };
2888
+ const buildRequireGraph = (chunks, chunkSet) => {
2889
+ const graph = index_cjs_js$b.createMap();
2890
+ for (const chunk of chunks)
2891
+ graph.set(chunk, collectRequireTargets(index_cjs_js$5.readFileContent(chunk), index_cjs_js$5.getDirname(chunk), chunkSet));
2892
+ return graph;
2893
+ };
2894
+ /**
2895
+ * Assigns every chunk a strongly-connected-component id via iterative Tarjan, so
2896
+ * a require edge `importer → target` is a cycle exactly when both share an id.
2897
+ *
2898
+ * Iterative (explicit work stack) to stay safe on deep require chains; the graph
2899
+ * is the relative-require graph restricted to chunks under `_dependencies/`.
2900
+ *
2901
+ * @param nodes - All chunk paths, in a stable order.
2902
+ * @param graph - Adjacency from each chunk to the chunks it requires.
2903
+ * @returns Map from chunk path to its SCC id.
2904
+ */
2905
+ const computeSccIds = (nodes, graph) => {
2906
+ const index = index_cjs_js$b.createMap();
2907
+ const low = index_cjs_js$b.createMap();
2908
+ const onStack = index_cjs_js$2.createSet([]);
2909
+ const componentOf = index_cjs_js$b.createMap();
2910
+ const tarjanStack = [];
2911
+ // why: invariants guarantee every node read below was opened (written) first, so the cast is total.
2912
+ const idxOf = (node) => index.get(node);
2913
+ const lowOf = (node) => low.get(node);
2914
+ // why: the graph holds an entry for every node, so the lookup always resolves.
2915
+ const neighborsOf = (node) => [...graph.get(node)];
2916
+ let counter = 0;
2917
+ let component = 0;
2918
+ const open = (node) => {
2919
+ index.set(node, counter);
2920
+ low.set(node, counter);
2921
+ counter += 1;
2922
+ tarjanStack.push(node);
2923
+ onStack.add(node);
2924
+ };
2925
+ for (const start of nodes) {
2926
+ if (index.has(start))
2927
+ continue;
2928
+ open(start);
2929
+ const work = [{ node: start, neighbors: neighborsOf(start), cursor: 0 }];
2930
+ while (work.length > 0) {
2931
+ const frame = work[work.length - 1];
2932
+ if (frame.cursor < frame.neighbors.length) {
2933
+ const next = frame.neighbors[frame.cursor];
2934
+ frame.cursor += 1;
2935
+ if (!index.has(next)) {
2936
+ open(next);
2937
+ work.push({ node: next, neighbors: neighborsOf(next), cursor: 0 });
2938
+ }
2939
+ else if (onStack.has(next))
2940
+ low.set(frame.node, index_cjs_js$c.min(lowOf(frame.node), idxOf(next)));
2941
+ continue;
2942
+ }
2943
+ if (lowOf(frame.node) === idxOf(frame.node)) {
2944
+ for (;;) {
2945
+ const popped = tarjanStack.pop();
2946
+ onStack.delete(popped);
2947
+ componentOf.set(popped, component);
2948
+ if (popped === frame.node)
2949
+ break;
2950
+ }
2951
+ component += 1;
2952
+ }
2953
+ work.pop();
2954
+ const parent = work[work.length - 1];
2955
+ if (parent)
2956
+ low.set(parent.node, index_cjs_js$c.min(lowOf(parent.node), lowOf(frame.node)));
2957
+ }
2958
+ }
2959
+ return componentOf;
2960
+ };
2961
+ /**
2962
+ * Collapses whole-module CJS require bindings (`const NS = require('./rel')`) to
2963
+ * destructuring binds across the surviving `_dependencies/` chunks, guarded so it
2964
+ * never destructures across a `require` cycle.
2965
+ *
2966
+ * Builds the relative-require graph over the CJS chunks, finds its
2967
+ * strongly-connected components, and lets each chunk destructure a target only
2968
+ * when the two sit in different components — i.e. the edge is acyclic, so an
2969
+ * eager destructure cannot capture an export before a circular dependency
2970
+ * finished initializing (the exact hazard rollup's namespace-access codegen
2971
+ * avoids). ESM chunks need nothing: their named imports already destructure. A
2972
+ * dynamic `import(`/`require(` anywhere disables the pass for safety, since it
2973
+ * could hide a cycle the static graph cannot see.
2974
+ *
2975
+ * @param depsRoot - Absolute path to the `_dependencies/` directory.
2976
+ * @returns Count of require bindings destructured.
2977
+ *
2978
+ * @example Running the pass after the strip/orphan passes
2979
+ * ```typescript
2980
+ * const { requireBindingsDestructured } = destructureRequiresPass(depsRootOf(context))
2981
+ * ```
2982
+ */
2983
+ const destructureRequiresPass = (depsRoot) => {
2984
+ const result = { requireBindingsDestructured: 0 };
2985
+ if (!index_cjs_js$5.exists(depsRoot))
2986
+ return result;
2987
+ const chunks = [];
2988
+ walkFiles(depsRoot, (name) => name === CJS_CHUNK, chunks);
2989
+ if (chunks.length === 0)
2990
+ return result;
2991
+ const sources = index_cjs_js$b.createMap();
2992
+ for (const chunk of chunks) {
2993
+ const source = index_cjs_js$5.readFileContent(chunk);
2994
+ // why: a dynamic specifier could hide a require cycle the static graph misses; bail the whole pass, mirroring the orphan sweep's safety posture.
2995
+ if (hasDynamicSpecifier(source)) {
2996
+ log$3.warn(`dynamic import/require in ${chunk}; skipping require-destructure pass for safety`);
2997
+ return result;
2998
+ }
2999
+ sources.set(chunk, source);
3000
+ }
3001
+ const chunkSet = index_cjs_js$2.createSet(chunks);
3002
+ const graph = buildRequireGraph(chunks, chunkSet);
3003
+ const componentOf = computeSccIds(chunks, graph);
3004
+ for (const chunk of chunks) {
3005
+ // why: every chunk was just read into `sources` above, so the lookup always resolves.
3006
+ const source = sources.get(chunk);
3007
+ const myComponent = componentOf.get(chunk);
3008
+ const isSafeTarget = (target) => chunkSet.has(target) && componentOf.get(target) !== myComponent;
3009
+ const rewritten = destructureRequires(source, index_cjs_js$5.getDirname(chunk), isSafeTarget);
3010
+ if (!rewritten)
3011
+ continue;
3012
+ index_cjs_js$5.writeFileContent(chunk, rewritten.code);
3013
+ result.requireBindingsDestructured += rewritten.rewrittenBindings;
3014
+ }
3015
+ return result;
3016
+ };
3017
+
3018
+ const propertyName = (element) => {
3019
+ if (ts__default.default.isShorthandPropertyAssignment(element))
3020
+ return element.name.text;
3021
+ if (ts__default.default.isPropertyAssignment(element) && (ts__default.default.isIdentifier(element.name) || ts__default.default.isStringLiteralLike(element.name)))
3022
+ return element.name.text;
3023
+ return null;
3024
+ };
3025
+ // why: only a literal of plain `key: value` / shorthand slots can be safely partitioned; a spread, computed key, method, or accessor makes per-slot removal unsound, so such a literal is left whole (no NamespaceObject yielded).
3026
+ const readProperties = (literal) => {
3027
+ const properties = [];
3028
+ for (const element of literal.properties) {
3029
+ const name = propertyName(element);
3030
+ if (name === null)
3031
+ return null;
3032
+ properties.push({ name, element });
3033
+ }
3034
+ return properties;
3035
+ };
3036
+ const exportedLocalNames = (sourceFile, format) => {
3037
+ const single = index_cjs_js$b.createMap();
3038
+ const seen = index_cjs_js$2.createSet([]);
3039
+ for (const entry of analyzeChunk(sourceFile, format).exports) {
3040
+ // why: a local published under two names cannot be keyed to one demand set — drop it from the strippable set.
3041
+ if (seen.has(entry.local))
3042
+ single.delete(entry.local);
3043
+ else {
3044
+ seen.add(entry.local);
3045
+ single.set(entry.local, entry.exported);
3046
+ }
3047
+ }
3048
+ return single;
3049
+ };
3050
+ // context: visits each exported, frozen, plain-slot namespace object in source order. A namespace is a single-declarator top-level `const`/`var` whose initializer is a recognized pure freeze (`Object.freeze`/`seal`/`preventExtensions`, however aliased) of a fresh object literal, and whose local is exported under exactly one name.
3051
+ const forEachNamespaceObject = (sourceFile, format, visit) => {
3052
+ const exported = exportedLocalNames(sourceFile, format);
3053
+ const resolution = collectBindingCanonical(sourceFile);
3054
+ for (const statement of sourceFile.statements) {
3055
+ if (!ts__default.default.isVariableStatement(statement) || statement.declarationList.declarations.length !== 1)
3056
+ continue;
3057
+ const decl = statement.declarationList.declarations[0];
3058
+ if (!decl || !ts__default.default.isIdentifier(decl.name))
3059
+ continue;
3060
+ const name = decl.name.text;
3061
+ const exportName = exported.get(name);
3062
+ if (exportName === undefined || !decl.initializer || !ts__default.default.isCallExpression(decl.initializer))
3063
+ continue;
3064
+ if (!isPureFreezeCall(decl.initializer, resolution))
3065
+ continue;
3066
+ const argument = decl.initializer.arguments[0];
3067
+ if (!argument || !ts__default.default.isObjectLiteralExpression(argument))
3068
+ continue;
3069
+ const properties = readProperties(argument);
3070
+ if (properties === null)
3071
+ continue;
3072
+ visit({ exported: exportName, local: name, statement, literal: argument, properties });
3073
+ }
3074
+ };
3075
+ /**
3076
+ * Analyzes a single chunk for frozen namespace exports and the demand its own
3077
+ * body places on them.
3078
+ *
3079
+ * Returns the namespace exports as node-free data (so the parsed source can be
3080
+ * released) and a self-demand map folding every reference to a namespace's local
3081
+ * binding outside its own declaration and export surface: a static `NS.prop`
3082
+ * read contributes that property, any other use marks the namespace `'all'`.
3083
+ *
3084
+ * @param source - Raw chunk source text.
3085
+ * @param format - Module format selecting the export shape.
3086
+ * @returns The chunk's namespace exports and the demand it self-imposes.
3087
+ *
3088
+ * @example A chunk that exports a frozen namespace it never self-references
3089
+ * ```typescript
3090
+ * analyzeChunkNamespaces('const a = 1;\nconst NS = Object.freeze({ a });\nexport { a, NS };', 'esm')
3091
+ * // => { namespaces: [{ exported: 'NS', properties: ['a'] }], selfDemand: Map {} }
3092
+ * ```
3093
+ */
3094
+ const analyzeChunkNamespaces = (source, format) => {
3095
+ const sourceFile = parseChunk(source);
3096
+ const namespaces = [];
3097
+ const localToExport = index_cjs_js$b.createMap();
3098
+ const skip = index_cjs_js$2.createSet([]);
3099
+ forEachNamespaceObject(sourceFile, format, (object) => {
3100
+ namespaces.push({ exported: object.exported, properties: object.properties.map((property) => property.name) });
3101
+ localToExport.set(object.local, object.exported);
3102
+ skip.add(object.statement);
3103
+ });
3104
+ const selfDemand = index_cjs_js$b.createMap();
3105
+ if (namespaces.length === 0)
3106
+ return { namespaces, selfDemand };
3107
+ // why: a namespace's own declaration and its `export { … }` site are not consumer reads — skip them so only genuine internal uses count.
3108
+ for (const entry of analyzeChunk(sourceFile, format).exportSurfaceStatements)
3109
+ skip.add(entry);
3110
+ const visit = (node) => {
3111
+ if (ts__default.default.isIdentifier(node)) {
3112
+ const exportName = localToExport.get(node.text);
3113
+ if (exportName !== undefined) {
3114
+ const classification = classifyNamespaceUse(node);
3115
+ if (classification.kind === 'read')
3116
+ mergeDemand(selfDemand, exportName, index_cjs_js$2.createSet([classification.prop]));
3117
+ else if (classification.kind === 'bail')
3118
+ mergeDemand(selfDemand, exportName, 'all');
3119
+ }
3120
+ }
3121
+ ts__default.default.forEachChild(node, visit);
3122
+ };
3123
+ for (const statement of sourceFile.statements)
3124
+ if (!skip.has(statement))
3125
+ visit(statement);
3126
+ return { namespaces, selfDemand };
3127
+ };
3128
+ /**
3129
+ * Rewrites a chunk's frozen namespace literals to keep only the slots the
3130
+ * consumer graph reads, dropping the rest.
3131
+ *
3132
+ * For every exported frozen namespace, `keepByExport` supplies the property names
3133
+ * to retain (the read set already intersected with the literal's own slots). A
3134
+ * namespace absent from the map, or whose kept set is empty or covers every
3135
+ * slot, is left untouched. Dropping a slot removes the only reference its factory
3136
+ * binding had, so the subsequent dead-export pass collapses the now-dead
3137
+ * factories — this pass only edits the literal.
3138
+ *
3139
+ * @param source - Raw chunk source text.
3140
+ * @param format - Module format selecting the export shape.
3141
+ * @param keepByExport - Per-export set of property names to retain.
3142
+ * @returns The rewritten source and slot-removal count, or `null` when nothing changed.
3143
+ *
3144
+ * @example Keeping a single slot of a two-slot namespace
3145
+ * ```typescript
3146
+ * stripDeadProperties('const a=1;\nconst b=2;\nconst NS=Object.freeze({a,b});\nexport{NS};', 'esm', new Map([['NS', new Set(['a'])]]))
3147
+ * // => literal rewritten to `{ a }`, removedProperties: 1
3148
+ * ```
3149
+ */
3150
+ const stripDeadProperties = (source, format, keepByExport) => {
3151
+ const sourceFile = parseChunk(source);
3152
+ const edits = [];
3153
+ let removedProperties = 0;
3154
+ forEachNamespaceObject(sourceFile, format, (object) => {
3155
+ const keep = keepByExport.get(object.exported);
3156
+ if (!keep)
3157
+ return;
3158
+ const survivors = object.properties.filter((property) => keep.has(property.name));
3159
+ // why: never produce an empty `freeze({})` and never rewrite when nothing is dropped.
3160
+ if (survivors.length === 0 || survivors.length === object.properties.length)
3161
+ return;
3162
+ removedProperties += object.properties.length - survivors.length;
3163
+ const rendered = survivors.map((property) => source.slice(property.element.getStart(sourceFile), property.element.getEnd()));
3164
+ edits.push({ start: object.literal.getStart(sourceFile), end: object.literal.getEnd(), text: `{ ${rendered.join(', ')} }` });
3165
+ });
3166
+ if (edits.length === 0)
3167
+ return null;
3168
+ return { code: applyEdits(source, edits), removedProperties };
3169
+ };
3170
+
3171
+ const FORMAT_FILES = [
3172
+ { format: 'esm', fileName: 'index.esm.js' },
3173
+ { format: 'cjs', fileName: 'index.cjs.js' },
3174
+ ];
3175
+ // why: a dynamic, non-literal `import(`/`require(` anywhere in the consumer graph means a consumer we cannot resolve might read a namespace wholesale — disable property-strip for the format (guaranteed-safe fallback, mirroring the orphan sweep).
3176
+ const graphHasDynamicSpecifier = (importers) => importers.some((importer) => hasDynamicSpecifier(index_cjs_js$5.readFileContent(importer)));
3177
+ const collectChunkNamespaces = (chunks, format) => {
3178
+ const byChunk = index_cjs_js$b.createMap();
3179
+ for (const chunk of chunks) {
3180
+ const { namespaces } = analyzeChunkNamespaces(index_cjs_js$5.readFileContent(chunk), format);
3181
+ if (namespaces.length > 0)
3182
+ byChunk.set(chunk, namespaces);
3183
+ }
3184
+ return byChunk;
3185
+ };
3186
+ // why: seed each namespace-bearing chunk's demand with the demand its own body imposes, so an internal read or escape is counted before importers are scanned.
3187
+ const seedSelfDemand = (chunks, namespacesByChunk, format) => {
3188
+ const demand = index_cjs_js$b.createMap();
3189
+ for (const chunk of chunks) {
3190
+ if (!namespacesByChunk.has(chunk))
3191
+ continue;
3192
+ const { selfDemand } = analyzeChunkNamespaces(index_cjs_js$5.readFileContent(chunk), format);
3193
+ demand.set(chunk, selfDemand);
3194
+ }
3195
+ return demand;
3196
+ };
3197
+ const accumulateImporterDemand = (importers, namespacesByChunk, demand, format) => {
3198
+ for (const importer of importers) {
3199
+ const edges = collectNamespaceUsage(index_cjs_js$5.readFileContent(importer), index_cjs_js$5.getDirname(importer), format);
3200
+ for (const [target, usage] of edges) {
3201
+ const chunkDemand = demand.get(target);
3202
+ const namespaces = namespacesByChunk.get(target);
3203
+ // why: edges to chunks with no strippable namespace are irrelevant here.
3204
+ if (!chunkDemand || !namespaces)
3205
+ continue;
3206
+ if (usage.bailAll) {
3207
+ for (const namespace of namespaces)
3208
+ mergeDemand(chunkDemand, namespace.exported, 'all');
3209
+ continue;
3210
+ }
3211
+ for (const [name, propDemand] of usage.perName)
3212
+ mergeDemand(chunkDemand, name, propDemand);
3213
+ }
3214
+ }
3215
+ };
3216
+ // context: the set of property names to retain for each namespace export of one chunk — only namespaces read at a strict, non-empty subset of their slots, so leaving a fully-unread namespace (dead) to the export pass and a wholesale-consumed one untouched.
3217
+ const keepSetsForChunk = (namespaces, chunkDemand) => {
3218
+ const keepByExport = index_cjs_js$b.createMap();
3219
+ for (const namespace of namespaces) {
3220
+ const propDemand = chunkDemand.get(namespace.exported);
3221
+ if (propDemand === undefined || propDemand === 'all')
3222
+ continue;
3223
+ const keep = index_cjs_js$2.createSet(namespace.properties.filter((property) => propDemand.has(property)));
3224
+ if (keep.size > 0 && keep.size < namespace.properties.length)
3225
+ keepByExport.set(namespace.exported, keep);
3226
+ }
3227
+ return keepByExport;
3228
+ };
3229
+ const rewriteChunks = (namespacesByChunk, demand, format, result) => {
3230
+ for (const [chunk, namespaces] of namespacesByChunk) {
3231
+ const chunkDemand = demand.get(chunk);
3232
+ if (!chunkDemand)
3233
+ continue;
3234
+ const keepByExport = keepSetsForChunk(namespaces, chunkDemand);
3235
+ if (keepByExport.size === 0)
3236
+ continue;
3237
+ const source = index_cjs_js$5.readFileContent(chunk);
3238
+ const stripped = stripDeadProperties(source, format, keepByExport);
3239
+ if (!stripped)
3240
+ continue;
3241
+ index_cjs_js$5.writeFileContent(chunk, stripped.code);
3242
+ result.deadPropertiesRemoved += stripped.removedProperties;
3243
+ result.bytesRemoved += Buffer.byteLength(source) - Buffer.byteLength(stripped.code);
3244
+ }
3245
+ };
3246
+ const processFormat = (context, depsRoot, format, fileName, result) => {
3247
+ const chunks = [];
3248
+ walkFiles(depsRoot, (name) => name === fileName, chunks);
3249
+ if (chunks.length === 0)
3250
+ return;
3251
+ const importers = [...collectEntryFiles(context, depsRoot, [fileName]), ...chunks];
3252
+ if (graphHasDynamicSpecifier(importers))
3253
+ return;
3254
+ const namespacesByChunk = collectChunkNamespaces(chunks, format);
3255
+ if (namespacesByChunk.size === 0)
3256
+ return;
3257
+ const demand = seedSelfDemand(chunks, namespacesByChunk, format);
3258
+ accumulateImporterDemand(importers, namespacesByChunk, demand, format);
3259
+ rewriteChunks(namespacesByChunk, demand, format, result);
3260
+ };
3261
+ /**
3262
+ * Property-level tree-shaking of kept, live frozen namespace objects: drops the
3263
+ * slots of an exported `freeze({ … })` namespace that no consumer in the whole
3264
+ * graph ever reads, letting the dead-export pass then collapse the now-dead
3265
+ * factory bindings.
3266
+ *
3267
+ * Runs per format (ESM and CJS) over `_dependencies/` chunks. The consumer graph
3268
+ * is the package's entry chunks plus every sibling dependency chunk — a complete
3269
+ * importer set, since per-entry bundling inlines all other first-party code.
3270
+ * Each namespace's demand is the union of its `NS.prop` reads across that graph
3271
+ * (in CJS, a two-level `require(...).NS.prop`); a wholesale consumption (spread,
3272
+ * pass-through, enumeration, dynamic index, re-export, namespace/default import)
3273
+ * or any dynamic specifier in the graph keeps the namespace whole. Only a
3274
+ * namespace read at a strict, non-empty subset of its slots is rewritten. The
3275
+ * caller is expected to re-run the dead-export pass afterwards to reclaim the
3276
+ * orphaned factories.
3277
+ *
3278
+ * @param context - Resolved build context supplying the entry points.
3279
+ * @param depsRoot - Absolute path to the `_dependencies/` directory.
3280
+ * @returns Counts of slots removed and bytes reclaimed.
3281
+ *
3282
+ * @example Running the property strip before the dead-export re-pass
3283
+ * ```typescript
3284
+ * const { deadPropertiesRemoved } = stripDeadPropertiesPass(context, depsRootOf(context))
3285
+ * ```
3286
+ */
3287
+ const stripDeadPropertiesPass = (context, depsRoot) => {
3288
+ const result = { deadPropertiesRemoved: 0, bytesRemoved: 0 };
3289
+ if (!index_cjs_js$5.exists(depsRoot))
3290
+ return result;
3291
+ for (const { format, fileName } of FORMAT_FILES)
3292
+ processFormat(context, depsRoot, format, fileName, result);
3293
+ return result;
3294
+ };
3295
+
3296
+ const PRESERVE = /@(?:__PURE__|__NO_SIDE_EFFECTS__|license|preserve|cc_on)|^\s*\/[*/]!|#__PURE__/;
3297
+ // why: tokens after which a `/` is the division operator, not a regex opener. After every other token (operators, `(`, `,`, `=`, keywords like `return`/`typeof`, or start of input) a `/` begins a regex, so the scanner must re-lex it as a whole regex literal — otherwise a `//` or `/*` *inside the regex body* (e.g. `/https?:\/\//`, `str.split(/\//g)`) is mis-scanned as comment trivia and the splice corrupts the regex.
3298
+ const VALUE_END_TOKENS = index_cjs_js$2.createSet([
3299
+ ts__default.default.SyntaxKind.Identifier,
3300
+ ts__default.default.SyntaxKind.NumericLiteral,
3301
+ ts__default.default.SyntaxKind.BigIntLiteral,
3302
+ ts__default.default.SyntaxKind.StringLiteral,
3303
+ ts__default.default.SyntaxKind.NoSubstitutionTemplateLiteral,
3304
+ ts__default.default.SyntaxKind.TemplateTail,
3305
+ ts__default.default.SyntaxKind.RegularExpressionLiteral,
3306
+ ts__default.default.SyntaxKind.CloseParenToken,
3307
+ ts__default.default.SyntaxKind.CloseBracketToken,
3308
+ ts__default.default.SyntaxKind.CloseBraceToken,
3309
+ ts__default.default.SyntaxKind.PlusPlusToken,
3310
+ ts__default.default.SyntaxKind.MinusMinusToken,
3311
+ ts__default.default.SyntaxKind.ThisKeyword,
3312
+ ts__default.default.SyntaxKind.SuperKeyword,
3313
+ ts__default.default.SyntaxKind.TrueKeyword,
3314
+ ts__default.default.SyntaxKind.FalseKeyword,
3315
+ ts__default.default.SyntaxKind.NullKeyword,
3316
+ ]);
3317
+ /**
3318
+ * Enumerates every comment trivia range in `text` via a `ts.Scanner` over the raw
3319
+ * source. The scanner keeps comment-looking text inside strings, templates, and
3320
+ * (with regex re-lexing) regex literals bound to those tokens, so the ranges it
3321
+ * returns are always genuine comments — never a `//` buried in a string or regex.
3322
+ *
3323
+ * @param text - Raw chunk source to scan.
3324
+ * @returns Every comment trivia range, in ascending source order.
3325
+ */
3326
+ const collectComments = (text) => {
3327
+ const scanner = ts__default.default.createScanner(ts__default.default.ScriptTarget.Latest, /*skipTrivia*/ false, ts__default.default.LanguageVariant.Standard, text);
3328
+ const ranges = [];
3329
+ // why: start-of-input is an expression position, so a leading `/` opens a regex.
3330
+ let prevSignificant = ts__default.default.SyntaxKind.Unknown;
3331
+ // why: ts.Scanner.scan() does not resume a template literal across its `${...}` substitution on its own — it returns the substitution's closing `}` as a bare CloseBraceToken, so the next backtick is mis-lexed as *opening* a string instead of closing the template. That flips backtick polarity for the rest of the file and exposes `//`/`/*` inside later templates as phantom comments. Track each open substitution's brace depth so the `}` that closes one is re-lexed as the template's continuation (TemplateMiddle when another `${` follows, TemplateTail when the backtick closes); a depth>0 brace is an ordinary block/object brace inside the expression and is left alone.
3332
+ const templateBraceDepths = [];
3333
+ let token = scanner.scan();
3334
+ while (token !== ts__default.default.SyntaxKind.EndOfFileToken) {
3335
+ const inSubstitution = templateBraceDepths.length > 0;
3336
+ if ((token === ts__default.default.SyntaxKind.SlashToken || token === ts__default.default.SyntaxKind.SlashEqualsToken) && !VALUE_END_TOKENS.has(prevSignificant)) {
3337
+ // why: a `/` in expression position is a regex; re-lex the whole literal so its body is never tokenized into stray comments. reScanSlashToken returns the original SlashToken when no valid regex closes on the line, which leaves a true division untouched.
3338
+ token = scanner.reScanSlashToken();
3339
+ }
3340
+ else if (token === ts__default.default.SyntaxKind.CloseBraceToken && inSubstitution && templateBraceDepths[templateBraceDepths.length - 1] === 0) {
3341
+ // why: this `}` closes the innermost `${...}`; re-lex it as the template's continuation so the trailing backtick is scanned as template text, not a fresh string opener.
3342
+ token = scanner.reScanTemplateToken(/*isTaggedTemplate*/ false);
3343
+ }
3344
+ if (token === ts__default.default.SyntaxKind.SingleLineCommentTrivia || token === ts__default.default.SyntaxKind.MultiLineCommentTrivia) {
3345
+ ranges.push({ start: scanner.getTokenStart(), end: scanner.getTextPos() });
3346
+ }
3347
+ else if (token !== ts__default.default.SyntaxKind.WhitespaceTrivia && token !== ts__default.default.SyntaxKind.NewLineTrivia) {
3348
+ // why: comments and whitespace don't change whether the next `/` is division or regex; only real tokens do.
3349
+ prevSignificant = token;
3350
+ }
3351
+ // why: maintain the substitution-depth stack after re-lexing so each token's effect (open a substitution, descend/ascend a nested brace, or close the template) is counted once.
3352
+ if (token === ts__default.default.SyntaxKind.TemplateHead)
3353
+ templateBraceDepths.push(0);
3354
+ else if (token === ts__default.default.SyntaxKind.TemplateTail)
3355
+ templateBraceDepths.pop();
3356
+ else if (inSubstitution && token === ts__default.default.SyntaxKind.OpenBraceToken)
3357
+ templateBraceDepths[templateBraceDepths.length - 1]++;
3358
+ else if (inSubstitution && token === ts__default.default.SyntaxKind.CloseBraceToken)
3359
+ templateBraceDepths[templateBraceDepths.length - 1]--;
3360
+ token = scanner.scan();
3361
+ }
3362
+ return ranges;
3363
+ };
3364
+ // why: include `\r` so a CRLF whole-line comment (trailing `\r` before the `\n`) still takes the line-collapse path. Rollup emits LF today, but a CRLF chunk would otherwise leave the `\r\n` residue behind.
3365
+ const isBlankSlice = (text, from, to) => /^[ \t\r]*$/.test(text.slice(from, to));
3366
+ const lineStartOf = (text, pos) => text.lastIndexOf('\n', pos - 1) + 1;
3367
+ const nextNewline = (text, pos) => {
3368
+ const nl = text.indexOf('\n', pos);
3369
+ return nl === -1 ? text.length : nl;
3370
+ };
3371
+ /**
3372
+ * Expands a bare comment range to the removal range actually spliced out.
3373
+ *
3374
+ * A comment that occupies a whole line (only whitespace before it on the line and
3375
+ * only whitespace after it up to the newline) is removed line-and-all, then any
3376
+ * immediately following blank lines are swallowed so contiguous JSDoc/banner
3377
+ * removals collapse without leaving blank-line residue. An inline comment is
3378
+ * removed verbatim. Blank-line swallowing is template-safe by construction:
3379
+ * comments only exist in code context, so the lines adjacent to a removed comment
3380
+ * are never inside a string or template literal.
3381
+ *
3382
+ * @param text - Raw chunk source the comment was found in.
3383
+ * @param comment - The bare comment range to expand.
3384
+ * @returns The offset range to splice out for this comment.
3385
+ */
3386
+ const removalRange = (text, comment) => {
3387
+ const lineStart = lineStartOf(text, comment.start);
3388
+ const eol = nextNewline(text, comment.end);
3389
+ const wholeLine = isBlankSlice(text, lineStart, comment.start) && isBlankSlice(text, comment.end, eol);
3390
+ if (!wholeLine)
3391
+ return comment;
3392
+ let to = eol < text.length ? eol + 1 : eol;
3393
+ while (to < text.length) {
3394
+ const nl = nextNewline(text, to);
3395
+ if (!isBlankSlice(text, to, nl))
3396
+ break;
3397
+ to = nl < text.length ? nl + 1 : nl;
3398
+ }
3399
+ return { start: lineStart, end: to };
3400
+ };
3401
+
3402
+ const stripComments = (source) => {
3403
+ const removable = collectComments(source).filter((range) => !PRESERVE.test(source.slice(range.start, range.end)));
3404
+ if (removable.length === 0)
3405
+ return null;
3406
+ const ranges = removable.map((comment) => removalRange(source, comment));
3407
+ // why: splice from the back so each earlier (smaller) offset stays valid; the ranges are disjoint and ascending, so descending removal never disturbs a not-yet-applied offset.
3408
+ let out = source;
3409
+ for (let i = ranges.length - 1; i >= 0; i--)
3410
+ out = out.slice(0, ranges[i].start) + out.slice(ranges[i].end);
3411
+ return out;
3412
+ };
3413
+
3414
+ const stripCommentsPass = (depsRoot) => {
3415
+ const result = { commentBytesRemoved: 0 };
3416
+ if (!index_cjs_js$5.exists(depsRoot))
3417
+ return result;
3418
+ const chunks = [];
3419
+ walkFiles(depsRoot, (name) => name === 'index.esm.js' || name === 'index.cjs.js', chunks);
3420
+ for (const chunk of chunks) {
3421
+ const source = index_cjs_js$5.readFileContent(chunk);
3422
+ const stripped = stripComments(source);
3423
+ if (stripped === null)
3424
+ continue;
3425
+ index_cjs_js$5.writeFileContent(chunk, stripped);
3426
+ result.commentBytesRemoved += Buffer.byteLength(source) - Buffer.byteLength(stripped);
3427
+ }
3428
+ return result;
3429
+ };
3430
+
3431
+ const log$2 = index_cjs_js$4.logger.channel('builder:bundle:dependencies:prune');
3432
+
3433
+ const pruneDependencies = (context, monitor) => {
3434
+ const depsRoot = depsRootOf(context);
3435
+ const orphans = pruneOrphanChunks(context, depsRoot);
3436
+ monitor?.check('bundle:dependencies:prune:orphans:end');
3437
+ const deadExports = stripDeadExportsPass(context, depsRoot);
3438
+ monitor?.check('bundle:dependencies:prune:dead-exports:end');
3439
+ const properties = stripDeadPropertiesPass(context, depsRoot);
3440
+ monitor?.check('bundle:dependencies:prune:property-strip:end');
3441
+ // why: dropping a namespace slot orphans the factory binding it held alive; a second export strip collapses those (and re-narrows the imports they pulled).
3442
+ const cascade = properties.deadPropertiesRemoved > 0 ? stripDeadExportsPass(context, depsRoot) : { deadExportsRemoved: 0, bytesRemoved: 0 };
3443
+ // why: a chunk whose last importing symbol was just stripped is now an orphan; reclaim it (and any d.ts left behind).
3444
+ const resweep = pruneOrphanChunks(context, depsRoot);
3445
+ // why: collapse whole-module CJS require bindings to destructures once the chunk surfaces are final; runs among the AST passes (before the comment strip) since it rewrites member-access spans.
3446
+ const destructured = destructureRequiresPass(depsRoot);
3447
+ monitor?.check('bundle:dependencies:prune:destructure-requires:end');
3448
+
3449
+ const comments = stripCommentsPass(depsRoot);
3450
+ monitor?.check('bundle:dependencies:prune:comment-strip:end');
3451
+ const report = {
3452
+ orphanFilesRemoved: orphans.orphanFilesRemoved + resweep.orphanFilesRemoved,
3453
+ deadExportsRemoved: deadExports.deadExportsRemoved + cascade.deadExportsRemoved,
3454
+ deadPropertiesRemoved: properties.deadPropertiesRemoved,
3455
+ requireBindingsDestructured: destructured.requireBindingsDestructured,
3456
+ commentBytesRemoved: comments.commentBytesRemoved,
3457
+ bytesRemoved: orphans.bytesRemoved +
3458
+ deadExports.bytesRemoved +
3459
+ properties.bytesRemoved +
3460
+ cascade.bytesRemoved +
3461
+ resweep.bytesRemoved +
3462
+ comments.commentBytesRemoved,
3463
+ };
3464
+ if (report.orphanFilesRemoved > 0 ||
3465
+ report.deadExportsRemoved > 0 ||
3466
+ report.deadPropertiesRemoved > 0 ||
3467
+ report.requireBindingsDestructured > 0 ||
3468
+ report.commentBytesRemoved > 0) {
3469
+ log$2.info(`pruned ${report.orphanFilesRemoved} orphan dependency file(s), ${report.deadExportsRemoved} dead export(s), and ${report.deadPropertiesRemoved} dead namespace slot(s), destructured ${report.requireBindingsDestructured} require binding(s), stripped ${report.commentBytesRemoved} comment byte(s), reclaimed ${report.bytesRemoved} byte(s)`);
3470
+ }
3471
+ return report;
3472
+ };
3473
+
3474
+ const readPkg = (packageJsonPath) => (index_cjs_js$8.exists(packageJsonPath) ? index_cjs_js$8.readJsonFile(packageJsonPath) : {});
3475
+ /**
3476
+ * Resolves the external package list for a single bundle.
3477
+ *
3478
+ * The output combines:
3479
+ * - top-level `dependencies` from the project's `package.json`
3480
+ * - `peerDependencies` (always external regardless of `bundleWorkspaceDeps`)
3481
+ * - the caller-supplied `additional` list
3482
+ *
3483
+ * When `bundleWorkspaceDeps` is `true` and a workspace predicate is supplied, packages
3484
+ * matching the predicate are stripped from `dependencies` and `additional` so they get
3485
+ * inlined by the bundler. Peer dependencies are always preserved.
3486
+ *
3487
+ * @param options - Inputs controlling the resolution.
3488
+ * @returns Sorted, de-duplicated list of external package names.
3489
+ *
3490
+ * @example Resolving externals while inlining workspace deps
3491
+ * ```typescript
3492
+ * const external = resolveExternals({
3493
+ * packageJsonPath: '/abs/libs/foo/package.json',
3494
+ * isWorkspacePackage: (n) => n.startsWith('@hyperfrontend/'),
3495
+ * bundleWorkspaceDeps: true,
3496
+ * })
3497
+ * ```
3498
+ */
3499
+ const resolveExternals = (options) => {
3500
+ const pkg = readPkg(options.packageJsonPath);
3501
+ const deps = index_cjs_js$d.keys(pkg.dependencies ?? {});
3502
+ const peerDeps = index_cjs_js$d.keys(pkg.peerDependencies ?? {});
3503
+ const additional = options.additional ?? [];
3504
+ const bundledSet = index_cjs_js$2.createSet(options.bundledDeps ?? []);
3505
+ const workspaceBundledSet = index_cjs_js$2.createSet(options.workspaceBundledDepNames ?? []);
3506
+ const inlineWorkspace = options.bundleWorkspaceDeps === true && options.isWorkspacePackage !== undefined;
3507
+ const filterWorkspace = (names) => inlineWorkspace ? names.filter((n) => !options.isWorkspacePackage(n)) : names;
3508
+ const filterBundled = (names) => (bundledSet.size === 0 ? names : names.filter((n) => !bundledSet.has(n)));
3509
+ const filterWorkspaceBundled = (names) => workspaceBundledSet.size === 0 ? names : names.filter((n) => !workspaceBundledSet.has(n));
3510
+ return index_cjs_js$3.from(index_cjs_js$2.createSet([
3511
+ ...filterWorkspaceBundled(filterBundled(filterWorkspace(deps))),
3512
+ ...filterWorkspaceBundled(filterBundled(peerDeps)),
3513
+ ...filterWorkspaceBundled(filterBundled(filterWorkspace(additional))),
3514
+ ]));
3515
+ };
3516
+
3517
+ const computeEntryOutputDir = (entry, context) => entry.srcPath ? index_cjs_js$9.join(context.outputPath, entry.srcPath) : context.outputPath;
3518
+ const computeBundleOutputDir = (bundleSubDir, context) => index_cjs_js$9.join(context.outputPath, bundleSubDir ?? 'bundle');
3519
+ /**
3520
+ * Builds the worker descriptor for the ESM output of a single entry point.
3521
+ *
3522
+ * The returned descriptor is fully serializable (no functions), ready to be
3523
+ * passed to {@link dispatchRollupWorker}.
3524
+ *
3525
+ * @param entry - Entry point to compile.
3526
+ * @param config - ESM-format configuration.
3527
+ * @param context - Resolved build context.
3528
+ * @param reportPath - Absolute path the worker will write its JSON report to.
3529
+ * @returns Descriptor ready to be JSON-serialized for the worker.
3530
+ *
3531
+ * @example Producing the descriptor for the root entry
3532
+ * ```typescript
3533
+ * const descriptor = toEsmBuildDescriptor(entry, esmConfig, context, '/tmp/report.json')
3534
+ * ```
3535
+ */
3536
+ const toEsmBuildDescriptor = (entry, config, context, reportPath) => {
3537
+ const outputDir = computeEntryOutputDir(entry, context);
3538
+ const sourcemap = config.sourcemap ?? false;
3539
+ const bundleWorkspaceDeps = config.bundleWorkspaceDeps ?? true;
3540
+ const bundleAllRequested = Boolean(config.bundleAllDeps);
3541
+ const bundledDeps = bundleAllRequested ? context.bundledDeps : [];
3542
+ const workspaceRoutes = bundleAllRequested ? buildWorkspaceRoutes(context.workspaceBundledDeps) : [];
3543
+ const useExternalizePlugin = bundledDeps.length > 0 || workspaceRoutes.length > 0;
3544
+ const external = resolveExternals({
3545
+ packageJsonPath: index_cjs_js$9.join(context.projectRoot, 'package.json'),
3546
+ additional: [...context.external, ...(config.external ?? [])],
3547
+ isWorkspacePackage: context.isWorkspacePackage,
3548
+ bundleWorkspaceDeps,
3549
+ bundledDeps,
3550
+ workspaceBundledDepNames: workspaceRoutes.map((r) => r.packageName),
3551
+ });
3552
+ return {
3553
+ format: 'esm',
3554
+ inputFile: entry.inputFile,
3555
+ outputDir,
3556
+ external,
3557
+ sourcemap,
3558
+ bundledDepsPlugin: useExternalizePlugin ? { deps: bundledDeps, depsRoot: depsRootOf(context) } : null,
3559
+ workspaceRoutes,
3560
+ tsConfigPath: context.tsConfigPath,
3561
+ projectRoot: context.projectRoot,
3562
+ workspaceRoot: context.workspaceRoot,
3563
+ bundleWorkspaceDeps,
3564
+ bundle: null,
3565
+ bin: null,
3566
+ reportPath,
3567
+ };
3568
+ };
3569
+ /**
3570
+ * Builds the worker descriptor for the CommonJS output of a single entry point.
3571
+ *
3572
+ * @param entry - Entry point to compile.
3573
+ * @param config - CJS-format configuration.
3574
+ * @param context - Resolved build context.
3575
+ * @param reportPath - Absolute path the worker will write its JSON report to.
3576
+ * @returns Descriptor ready to be JSON-serialized for the worker.
3577
+ *
3578
+ * @example Producing the descriptor for the root entry
3579
+ * ```typescript
3580
+ * const descriptor = toCjsBuildDescriptor(entry, cjsConfig, context, '/tmp/report.json')
3581
+ * ```
3582
+ */
3583
+ const toCjsBuildDescriptor = (entry, config, context, reportPath) => {
3584
+ const outputDir = computeEntryOutputDir(entry, context);
3585
+ const sourcemap = config.sourcemap ?? false;
3586
+ const bundleWorkspaceDeps = config.bundleWorkspaceDeps ?? true;
3587
+ const bundleAllRequested = Boolean(config.bundleAllDeps);
3588
+ const bundledDeps = bundleAllRequested ? context.bundledDeps : [];
3589
+ const workspaceRoutes = bundleAllRequested ? buildWorkspaceRoutes(context.workspaceBundledDeps) : [];
3590
+ const useExternalizePlugin = bundledDeps.length > 0 || workspaceRoutes.length > 0;
3591
+ const external = resolveExternals({
3592
+ packageJsonPath: index_cjs_js$9.join(context.projectRoot, 'package.json'),
3593
+ additional: [...context.external, ...(config.external ?? [])],
3594
+ isWorkspacePackage: context.isWorkspacePackage,
3595
+ bundleWorkspaceDeps,
3596
+ bundledDeps,
3597
+ workspaceBundledDepNames: workspaceRoutes.map((r) => r.packageName),
3598
+ });
3599
+ return {
3600
+ format: 'cjs',
3601
+ inputFile: entry.inputFile,
3602
+ outputDir,
3603
+ external,
3604
+ sourcemap,
3605
+ bundledDepsPlugin: useExternalizePlugin ? { deps: bundledDeps, depsRoot: depsRootOf(context) } : null,
3606
+ workspaceRoutes,
3607
+ tsConfigPath: context.tsConfigPath,
3608
+ projectRoot: context.projectRoot,
3609
+ workspaceRoot: context.workspaceRoot,
3610
+ bundleWorkspaceDeps,
3611
+ bundle: null,
3612
+ bin: null,
3613
+ reportPath,
3614
+ };
3615
+ };
3616
+ /**
3617
+ * Builds the worker descriptor for an IIFE bundle of a single entry point.
3618
+ *
3619
+ * Validates the externals/globals pairing eagerly, throwing before the
3620
+ * descriptor is returned.
3621
+ *
3622
+ * @param entry - Entry point to bundle.
3623
+ * @param config - IIFE-format configuration.
3624
+ * @param context - Resolved build context.
3625
+ * @param reportPath - Absolute path the worker will write its JSON report to.
3626
+ * @returns Descriptor ready to be JSON-serialized for the worker.
3627
+ * @throws {Error} When `config.external` is non-empty but `config.globals` is missing entries.
3628
+ *
3629
+ * @example Producing the descriptor for an IIFE bundle
3630
+ * ```typescript
3631
+ * const descriptor = toIifeBuildDescriptor(entry, iifeConfig, context, '/tmp/report.json')
3632
+ * ```
3633
+ */
3634
+ const toIifeBuildDescriptor = (entry, config, context, reportPath) => {
3635
+ validateExternalsConfig(config.external, config.globals);
3636
+ const outputDir = computeBundleOutputDir(config.output, context);
3637
+ const sourcemap = config.sourcemap ?? false;
3638
+ const minify = config.minify ?? true;
3639
+ return {
3640
+ format: 'iife',
3641
+ inputFile: entry.inputFile,
3642
+ outputDir,
3643
+ external: config.external ?? [],
3644
+ sourcemap,
3645
+ bundledDepsPlugin: null,
3646
+ workspaceRoutes: [],
3647
+ tsConfigPath: context.tsConfigPath,
3648
+ projectRoot: context.projectRoot,
3649
+ workspaceRoot: context.workspaceRoot,
3650
+ bundleWorkspaceDeps: false,
3651
+ bundle: { globalName: config.globalName, minify, globals: config.globals },
3652
+ bin: null,
3653
+ reportPath,
3654
+ };
3655
+ };
3656
+ /**
3657
+ * Builds the worker descriptor for a UMD bundle of a single entry point.
3658
+ *
3659
+ * Validates the externals/globals pairing eagerly, throwing before the
3660
+ * descriptor is returned.
3661
+ *
3662
+ * @param entry - Entry point to bundle.
3663
+ * @param config - UMD-format configuration.
3664
+ * @param context - Resolved build context.
3665
+ * @param reportPath - Absolute path the worker will write its JSON report to.
3666
+ * @returns Descriptor ready to be JSON-serialized for the worker.
3667
+ * @throws {Error} When `config.external` is non-empty but `config.globals` is missing entries.
3668
+ *
3669
+ * @example Producing the descriptor for a UMD bundle
3670
+ * ```typescript
3671
+ * const descriptor = toUmdBuildDescriptor(entry, umdConfig, context, '/tmp/report.json')
3672
+ * ```
3673
+ */
3674
+ const toUmdBuildDescriptor = (entry, config, context, reportPath) => {
3675
+ validateExternalsConfig(config.external, config.globals);
3676
+ const outputDir = computeBundleOutputDir(config.output, context);
3677
+ const sourcemap = config.sourcemap ?? false;
3678
+ const minify = config.minify ?? true;
3679
+ return {
3680
+ format: 'umd',
3681
+ inputFile: entry.inputFile,
3682
+ outputDir,
3683
+ external: config.external ?? [],
3684
+ sourcemap,
3685
+ bundledDepsPlugin: null,
3686
+ workspaceRoutes: [],
3687
+ tsConfigPath: context.tsConfigPath,
3688
+ projectRoot: context.projectRoot,
3689
+ workspaceRoot: context.workspaceRoot,
3690
+ bundleWorkspaceDeps: false,
3691
+ bundle: { globalName: config.globalName, minify, globals: config.globals, amdId: config.amdId },
3692
+ bin: null,
3693
+ reportPath,
3694
+ };
3695
+ };
3696
+
3697
+ const log$1 = index_cjs_js$4.logger.channel('builder:bundle:rollup:dispatch');
3698
+ const REPORT_DIR_PREFIX = 'hf-builder-rollup-';
3699
+ const SWC_NODE_REGISTER = '@swc-node/register';
3700
+ const swcNodeAvailable = (workspaceRoot) => node_fs.existsSync(index_cjs_js$5.join(workspaceRoot, 'node_modules', '@swc-node', 'register', 'index.js'));
3701
+ /**
3702
+ * Default worker-path resolution: prefers the built-and-published artifact, falls
3703
+ * back to the workspace dist path, and finally to the in-source TypeScript file
3704
+ * via `@swc-node/register` (bootstrap case where builder is building itself for
3705
+ * the first time and the dist worker doesn't exist yet).
3706
+ *
3707
+ * Looks at, in order:
3708
+ * 1. `<workspaceRoot>/dist/libs/builder/bundle/rollup/worker/index.cjs.js`
3709
+ * 2. `<workspaceRoot>/node_modules/@hyperfrontend/builder/bundle/rollup/worker/index.cjs.js`
3710
+ * 3. `<workspaceRoot>/libs/builder/src/bundle/rollup/worker/index.ts` (with `--require \@swc-node/register`)
3711
+ *
3712
+ * @param workspaceRoot - Absolute workspace root.
3713
+ * @returns Worker invocation descriptor, or `undefined` if no candidate exists.
3714
+ *
3715
+ * @example Locating the worker for an in-workspace consumer
3716
+ * ```typescript
3717
+ * const invocation = resolveDefaultRollupWorkerPath('/abs/repo')
3718
+ * if (!invocation) throw new Error('builder rollup worker artifact not found')
3719
+ * ```
3720
+ */
3721
+ const resolveDefaultRollupWorkerPath = (workspaceRoot) => {
3722
+ const distCandidates = [
3723
+ index_cjs_js$5.join(workspaceRoot, 'dist', 'libs', 'builder', 'bundle', 'rollup', 'worker', 'index.cjs.js'),
3724
+ index_cjs_js$5.join(workspaceRoot, 'node_modules', '@hyperfrontend', 'builder', 'bundle', 'rollup', 'worker', 'index.cjs.js'),
3725
+ ];
3726
+ for (const path of distCandidates) {
3727
+ if (node_fs.existsSync(path))
3728
+ return { path, execArgv: [] };
3729
+ }
3730
+ const sourcePath = index_cjs_js$5.join(workspaceRoot, 'libs', 'builder', 'src', 'bundle', 'rollup', 'worker', 'index.ts');
3731
+ if (node_fs.existsSync(sourcePath) && swcNodeAvailable(workspaceRoot)) {
3732
+ return { path: sourcePath, execArgv: ['--require', SWC_NODE_REGISTER] };
3733
+ }
3734
+ return undefined;
3735
+ };
3736
+ const createReportDir = () => node_fs.mkdtempSync(index_cjs_js$5.join(node_os.tmpdir(), REPORT_DIR_PREFIX));
3737
+ const reportPathFor = (reportDir, descriptor) => {
3738
+ const safeLabel = descriptor.inputFile.replace(/[^a-zA-Z0-9_-]+/g, '_');
3739
+ return index_cjs_js$5.join(reportDir, `${descriptor.format}-${safeLabel}.json`);
3740
+ };
3741
+ const runOne = (descriptor, options, label) => index_cjs_js.createPromise((resolve, reject) => {
3742
+ const execPath = options.execPath ?? process.execPath;
3743
+ const argv = [...(options.execArgv ?? []), options.workerPath, index_cjs_js$6.stringify(descriptor)];
3744
+ const child = node_child_process.spawn(execPath, argv, { stdio: ['ignore', 'pipe', 'pipe'] });
3745
+ let capturedStderr = '';
3746
+ child.stdout?.on('data', (chunk) => {
3747
+ process.stdout.write(chunk);
3748
+ });
3749
+ child.stderr?.on('data', (chunk) => {
3750
+ const text = typeof chunk === 'string' ? chunk : chunk.toString();
3751
+ capturedStderr += text;
3752
+ process.stderr.write(text);
3753
+ });
3754
+ child.on('error', (error) => {
3755
+ reject(index_cjs_js$7.createError(`rollup worker for ${label} failed to spawn: ${error.message}`));
3756
+ });
3757
+ child.on('exit', (code) => {
3758
+ if (code !== 0) {
3759
+ const tail = capturedStderr.trim().split('\n').slice(-10).join('\n');
3760
+ reject(index_cjs_js$7.createError(`rollup worker for ${label} exited with code ${code}\n${tail}`));
3761
+ return;
3762
+ }
3763
+ resolve();
3764
+ });
3765
+ });
3766
+ const readReport = (reportPath, label) => {
3767
+ if (!node_fs.existsSync(reportPath)) {
3768
+ throw index_cjs_js$7.createError(`rollup worker for ${label} did not write a report at ${reportPath}`);
3769
+ }
3770
+ const data = index_cjs_js$6.parse(node_fs.readFileSync(reportPath, 'utf8'));
3771
+ return data;
3772
+ };
3773
+ /**
3774
+ * Forks a single rollup worker for the supplied descriptor and waits for it
3775
+ * to exit. The caller-provided descriptor's `reportPath` is overwritten with
3776
+ * a temp-dir path created by this function.
3777
+ *
3778
+ * Each worker writes a JSON report at the temp path; this function reads it
3779
+ * after the child exits and returns the per-job statistics. If the worker
3780
+ * exits non-zero or fails to produce a report, the function throws with a
3781
+ * label-rich message.
3782
+ *
3783
+ * The temp report directory is cleaned up before returning, regardless of
3784
+ * success or failure.
3785
+ *
3786
+ * @param descriptor - Build descriptor to dispatch.
3787
+ * @param options - Worker path + optional memory monitor.
3788
+ * @returns Worker report (output size + memory + duration) for the dispatched job.
3789
+ *
3790
+ * @example Dispatching a single ESM build
3791
+ * ```typescript
3792
+ * const report = await dispatchRollupWorker(descriptor, { workerPath: '/abs/dist/.../worker.cjs.js' })
3793
+ * ```
3794
+ */
3795
+ const dispatchRollupWorker = async (descriptor, options) => {
3796
+ const reportDir = createReportDir();
3797
+ const label = options.label ?? `${descriptor.format}:${descriptor.inputFile}`;
3798
+ const reportPath = reportPathFor(reportDir, descriptor);
3799
+ const job = { ...descriptor, reportPath };
3800
+ try {
3801
+ options.monitor?.check(`bundle:rollup:dispatch:${label}:start`);
3802
+ log$1.info(`rollup dispatch: ${label}`);
3803
+ await runOne(job, options, label);
3804
+ const report = readReport(reportPath, label);
3805
+ log$1.debug(`rollup dispatch done: ${label} size=${report.outputSize}B heap=${report.endHeapMB.toFixed(1)}MB rss=${report.endRssMB.toFixed(1)}MB t=${report.durationMs}ms`);
3806
+ options.monitor?.check(`bundle:rollup:dispatch:${label}:end`);
3807
+ return report;
3808
+ }
3809
+ finally {
3810
+ node_fs.rmSync(reportDir, { recursive: true, force: true });
3811
+ }
3812
+ };
3813
+
3814
+ const log = index_cjs_js$4.logger.channel('builder:bundle');
3815
+ const toArray = (value) => (value === undefined ? [] : index_cjs_js$3.isArray(value) ? value : [value]);
3816
+ const collectFormatsRequestingPrePass = (config) => {
3817
+ const formats = index_cjs_js$2.createSet([]);
3818
+ for (const c of toArray(config.esm))
3819
+ if (c.bundleAllDeps)
3820
+ formats.add('esm');
3821
+ for (const c of toArray(config.cjs))
3822
+ if (c.bundleAllDeps)
3823
+ formats.add('cjs');
3824
+ return index_cjs_js$3.from(formats);
3825
+ };
3826
+ const buildJsPrePassJobs = (deps, formats, context) => {
3827
+ const jobs = [];
3828
+ const depsRoot = depsRootOf(context);
3829
+ const workspacePrefixDeps = collectWorkspacePrefixDeps(context);
3830
+ const workspaceExactSpecifiers = collectWorkspaceExactSpecifiers(context);
3831
+ const workspaceRoutes = buildWorkspaceRoutes(context.workspaceBundledDeps);
3832
+ for (const dep of deps) {
3833
+ const entry = resolveDepEntry({ dep, projectRoot: context.projectRoot, workspaceRoot: context.workspaceRoot, kind: 'js' });
3834
+ const otherNpmDeps = deps.filter((d) => d !== dep);
3835
+ for (const format of formats) {
3836
+ jobs.push({
3837
+ kind: 'js',
3838
+ dep,
3839
+ inputPath: entry,
3840
+ format,
3841
+ outputPath: index_cjs_js$5.join(depsRoot, dep, chunkFileName(format)),
3842
+ otherDeps: [...otherNpmDeps, ...workspacePrefixDeps],
3843
+ otherWorkspaceSpecifiers: workspaceExactSpecifiers,
3844
+ npmDeps: otherNpmDeps,
3845
+ workspaceRoutes,
3846
+ depsRoot,
3847
+ });
3848
+ }
3849
+ }
3850
+ return jobs;
3851
+ };
3852
+ const workspaceOutputFile = (entry, format) => {
3853
+ const fileName = chunkFileName(format);
3854
+ return entry.subPath ? `${entry.specifier}/${fileName}` : `${entry.packageName}/${fileName}`;
3855
+ };
3856
+ const filterRouteEntries = (entry, all) => all.filter((other) => (entry.policy === 'sub-path' ? other.specifier !== entry.specifier : other.packageName !== entry.packageName));
3857
+ const buildWorkspaceJsPrePassJobs = (npmDeps, formats, context) => {
3858
+ if (context.workspaceBundledDeps.length === 0)
3859
+ return [];
3860
+ const jobs = [];
3861
+ const depsRoot = depsRootOf(context);
3862
+ const wholeSurface = collectWorkspacePrefixDeps(context);
3863
+ const subPathSpecifiers = collectWorkspaceExactSpecifiers(context);
3864
+ for (const entry of context.workspaceBundledDeps) {
3865
+ const otherWorkspacePackages = wholeSurface.filter((name) => name !== entry.packageName || entry.policy === 'sub-path');
3866
+ const otherSubPathSpecifiers = subPathSpecifiers.filter((spec) => spec !== entry.specifier);
3867
+ const workspaceRoutes = buildWorkspaceRoutes(filterRouteEntries(entry, context.workspaceBundledDeps));
3868
+ for (const format of formats) {
3869
+ jobs.push({
3870
+ kind: 'workspace-js',
3871
+ dep: entry.specifier,
3872
+ inputPath: entry.inputPath,
3873
+ format,
3874
+ outputPath: index_cjs_js$5.join(depsRoot, workspaceOutputFile(entry, format)),
3875
+ otherDeps: [...npmDeps, ...otherWorkspacePackages],
3876
+ otherWorkspaceSpecifiers: otherSubPathSpecifiers,
3877
+ tsConfigPath: entry.tsConfigPath,
3878
+ workspaceRoot: context.workspaceRoot,
3879
+ npmDeps,
3880
+ workspaceRoutes,
3881
+ depsRoot,
3882
+ });
3883
+ }
3884
+ }
3885
+ return jobs;
3886
+ };
3887
+ const resolvePrePassWorkerOrThrow = (workspaceRoot) => {
3888
+ const invocation = resolveDefaultWorkerPath(workspaceRoot);
3889
+ if (!invocation) {
3890
+ throw index_cjs_js$7.createError('bundleAllDeps is enabled but the pre-pass worker could not be resolved. Build @hyperfrontend/builder once with bundleAllDeps disabled, or ensure @swc-node/register is installed for source-mode bootstrap.');
3891
+ }
3892
+ return invocation;
3893
+ };
3894
+ const resolveRollupWorkerOrThrow = (workspaceRoot) => {
3895
+ const invocation = resolveDefaultRollupWorkerPath(workspaceRoot);
3896
+ if (!invocation) {
3897
+ throw index_cjs_js$7.createError('rollup worker could not be resolved. Build @hyperfrontend/builder at least once before invoking the bundle phase, or ensure @swc-node/register is installed for source-mode bootstrap.');
3898
+ }
3899
+ return invocation;
3900
+ };
3901
+ const createLazyDispatchResolver = (workspaceRoot) => {
3902
+ let cached = null;
3903
+ return () => {
3904
+ if (!cached) {
3905
+ const invocation = resolveRollupWorkerOrThrow(workspaceRoot);
3906
+ cached = { workerPath: invocation.path, execArgv: invocation.execArgv };
3907
+ }
3908
+ return cached;
3909
+ };
3910
+ };
3911
+ const dispatch = async (descriptor, label, options) => {
3912
+ await dispatchRollupWorker(descriptor, {
3913
+ workerPath: options.workerPath,
3914
+ execArgv: options.execArgv,
3915
+ label,
3916
+ });
3917
+ };
3918
+ const runEsmFormats = async (config, context, outputs, resolveDispatch, monitor) => {
3919
+ for (const esmConfig of toArray(config.esm)) {
3920
+ const entries = resolveEntries(esmConfig, context.entryPointDiscovery.entryPoints);
3921
+ for (const [i, entry] of entries.entries()) {
3922
+ const label = `esm:${i}/${entries.length}:${entry.exportPath}`;
3923
+ monitor?.check(`bundle:${label}:start`);
3924
+ const descriptor = toEsmBuildDescriptor(entry, esmConfig, context, '');
3925
+ await dispatch(descriptor, label, resolveDispatch());
3926
+ monitor?.check(`bundle:${label}:end`);
3927
+ }
3928
+ outputs.esm.push(...entries);
3929
+ }
3930
+ };
3931
+ const runCjsFormats = async (config, context, outputs, resolveDispatch, monitor) => {
3932
+ for (const cjsConfig of toArray(config.cjs)) {
3933
+ const entries = resolveEntries(cjsConfig, context.entryPointDiscovery.entryPoints);
3934
+ for (const [i, entry] of entries.entries()) {
3935
+ const label = `cjs:${i}/${entries.length}:${entry.exportPath}`;
3936
+ monitor?.check(`bundle:${label}:start`);
3937
+ const descriptor = toCjsBuildDescriptor(entry, cjsConfig, context, '');
3938
+ await dispatch(descriptor, label, resolveDispatch());
3939
+ monitor?.check(`bundle:${label}:end`);
3940
+ }
3941
+ outputs.cjs.push(...entries);
3942
+ }
3943
+ };
3944
+ const runIifeFormats = async (config, context, outputs, resolveDispatch, monitor) => {
3945
+ for (const iifeConfig of toArray(config.iife)) {
3946
+ const entries = resolveEntries(iifeConfig, context.entryPointDiscovery.entryPoints);
3947
+ if (entries.length === 0)
3948
+ continue;
3949
+ index_cjs_js$5.ensureDir(index_cjs_js$5.join(context.outputPath, iifeConfig.output ?? 'bundle'));
3950
+ for (const [i, entry] of entries.entries()) {
3951
+ const label = `iife:${i}/${entries.length}:${entry.exportPath}`;
3952
+ monitor?.check(`bundle:${label}:start`);
3953
+ const descriptor = toIifeBuildDescriptor(entry, iifeConfig, context, '');
3954
+ await dispatch(descriptor, label, resolveDispatch());
3955
+ monitor?.check(`bundle:${label}:end`);
3956
+ }
3957
+ outputs.iife.push({ config: iifeConfig, entries });
3958
+ }
3959
+ };
3960
+ const runUmdFormats = async (config, context, outputs, resolveDispatch, monitor) => {
3961
+ for (const umdConfig of toArray(config.umd)) {
3962
+ const entries = resolveEntries(umdConfig, context.entryPointDiscovery.entryPoints);
3963
+ if (entries.length === 0)
3964
+ continue;
3965
+ index_cjs_js$5.ensureDir(index_cjs_js$5.join(context.outputPath, umdConfig.output ?? 'bundle'));
3966
+ for (const [i, entry] of entries.entries()) {
3967
+ const label = `umd:${i}/${entries.length}:${entry.exportPath}`;
3968
+ monitor?.check(`bundle:${label}:start`);
3969
+ const descriptor = toUmdBuildDescriptor(entry, umdConfig, context, '');
3970
+ await dispatch(descriptor, label, resolveDispatch());
3971
+ monitor?.check(`bundle:${label}:end`);
3972
+ }
3973
+ outputs.umd.push({ config: umdConfig, entries });
3974
+ }
3975
+ };
3976
+ /**
3977
+ * Runs the entire bundle phase: ESM, CJS, IIFE, UMD outputs followed by declaration emission.
3978
+ *
3979
+ * Iterates the format-specific configurations in `config`, resolves the matching
3980
+ * entry points for each format, and bundles every one. After all bundles are
3981
+ * written, emits `.d.ts` declarations for the project exactly once.
3982
+ *
3983
+ * @param context - Resolved build context.
3984
+ * @param config - Top-level builder configuration. Only the format and `tsConfig`
3985
+ * fields are consulted by this phase.
3986
+ * @param monitor - Optional memory monitor; when provided, peak heap inside the
3987
+ * bundle phase is sampled at each format and declaration step.
3988
+ * @returns Aggregated outputs grouped by format.
3989
+ *
3990
+ * @example Driving the bundle phase from a custom orchestrator
3991
+ * ```typescript
3992
+ * const formatOutputs = await runBundlePhase(context, config)
3993
+ * ```
3994
+ */
3995
+ const runBundlePhase = async (context, config, monitor) => {
3996
+ const outputs = { esm: [], cjs: [], iife: [], umd: [] };
3997
+ const requestedPrePassFormats = collectFormatsRequestingPrePass(config);
3998
+ if (requestedPrePassFormats.length > 0 && (context.bundledDeps.length > 0 || context.workspaceBundledDeps.length > 0)) {
3999
+ const invocation = resolvePrePassWorkerOrThrow(context.workspaceRoot);
4000
+ const npmJobs = buildJsPrePassJobs(context.bundledDeps, requestedPrePassFormats, context);
4001
+ const workspaceJobs = buildWorkspaceJsPrePassJobs(context.bundledDeps, requestedPrePassFormats, context);
4002
+ const jobs = [...npmJobs, ...workspaceJobs];
4003
+ log.info(`bundle dependencies pre-pass: ${context.bundledDeps.length} npm + ${context.workspaceBundledDeps.length} workspace × ${requestedPrePassFormats.length} formats = ${jobs.length} jobs`);
4004
+ monitor?.check('bundle:dependencies:prepass:start');
4005
+ await runPrePass(jobs, { workerPath: invocation.path, execArgv: invocation.execArgv, monitor });
4006
+ monitor?.check('bundle:dependencies:prepass:end');
4007
+ }
4008
+ const resolveDispatch = createLazyDispatchResolver(context.workspaceRoot);
4009
+ await runEsmFormats(config, context, outputs, resolveDispatch, monitor);
4010
+ await recover();
4011
+ monitor?.check('bundle:esm:end:post-recover');
4012
+ await runCjsFormats(config, context, outputs, resolveDispatch, monitor);
4013
+ await recover();
4014
+ monitor?.check('bundle:cjs:end:post-recover');
4015
+ await runIifeFormats(config, context, outputs, resolveDispatch, monitor);
4016
+ await runUmdFormats(config, context, outputs, resolveDispatch, monitor);
4017
+ await recover();
4018
+ monitor?.check('bundle:declarations:start');
4019
+ await generateDeclarations(context);
4020
+ monitor?.check('bundle:declarations:end');
4021
+ if (context.bundledDeps.length > 0 || context.workspaceBundledDeps.length > 0) {
4022
+ await runDtsPrePass(context, monitor);
4023
+ await runDtsPerEntry(context, monitor);
4024
+ }
4025
+ pruneOrphanDeclarations(context);
4026
+ monitor?.check('bundle:declarations:prune-orphans:end');
4027
+ if (context.bundledDeps.length > 0 || context.workspaceBundledDeps.length > 0) {
4028
+ pruneDependencies(context, monitor);
4029
+ monitor?.check('bundle:dependencies:prune:end');
4030
+ }
4031
+ // why: dedup runs after prune so the lifted `_shared/` files are still present when `finalizeFilesAllowlist` reflects the published output tree.
4032
+ if (config.dedupeSharedInternals !== false) {
4033
+ hoistSharedFirstParty(context, monitor);
4034
+ monitor?.check('bundle:dedupe:shared-first-party:end');
4035
+ }
4036
+ // why: runs last (after the final file-producing pass) so no later pass re-creates a file under a removed directory; sweeps the per-source dirs left empty by the orphan-d.ts prune across the whole package, not just `_dependencies/`. Guarded for the degenerate case where no format produced an output tree.
4037
+ if (index_cjs_js$5.exists(context.outputPath)) {
4038
+ const emptyDirsRemoved = removeEmptyDirs(context.outputPath);
4039
+ if (emptyDirsRemoved > 0)
4040
+ log.info(`removed ${emptyDirsRemoved} empty director${emptyDirsRemoved === 1 ? 'y' : 'ies'}`);
4041
+ }
4042
+ monitor?.check('bundle:empty-dirs:end');
4043
+ return outputs;
4044
+ };
4045
+
4046
+ exports.runBundlePhase = runBundlePhase;