@atlaspack/core 2.16.2-canary.5 → 2.16.2-canary.500

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 (380) hide show
  1. package/CHANGELOG.md +1452 -0
  2. package/dist/AssetGraph.js +523 -0
  3. package/dist/Atlaspack.js +701 -0
  4. package/dist/AtlaspackConfig.js +324 -0
  5. package/dist/AtlaspackConfig.schema.js +117 -0
  6. package/dist/BundleGraph.js +1906 -0
  7. package/dist/CommittedAsset.js +142 -0
  8. package/dist/Dependency.js +125 -0
  9. package/dist/Environment.js +132 -0
  10. package/dist/EnvironmentManager.js +108 -0
  11. package/dist/IdentifierRegistry.js +38 -0
  12. package/dist/InternalConfig.js +37 -0
  13. package/dist/PackagerRunner.js +470 -0
  14. package/dist/ReporterRunner.js +151 -0
  15. package/dist/RequestTracker.js +1297 -0
  16. package/dist/SymbolPropagation.js +624 -0
  17. package/dist/TargetDescriptor.schema.js +146 -0
  18. package/dist/Transformation.js +514 -0
  19. package/dist/UncommittedAsset.js +310 -0
  20. package/dist/Validation.js +196 -0
  21. package/dist/applyRuntimes.js +384 -0
  22. package/dist/assetUtils.js +169 -0
  23. package/dist/atlaspack-v3/AtlaspackV3.js +83 -0
  24. package/dist/atlaspack-v3/NapiWorkerPool.js +114 -0
  25. package/dist/atlaspack-v3/fs.js +53 -0
  26. package/dist/atlaspack-v3/index.js +25 -0
  27. package/dist/atlaspack-v3/jsCallable.js +16 -0
  28. package/dist/atlaspack-v3/worker/compat/asset-symbols.js +190 -0
  29. package/dist/atlaspack-v3/worker/compat/bitflags.js +98 -0
  30. package/dist/atlaspack-v3/worker/compat/dependency.js +43 -0
  31. package/dist/atlaspack-v3/worker/compat/environment.js +57 -0
  32. package/dist/atlaspack-v3/worker/compat/index.js +24 -0
  33. package/dist/atlaspack-v3/worker/compat/mutable-asset.js +152 -0
  34. package/dist/atlaspack-v3/worker/compat/plugin-config.js +64 -0
  35. package/dist/atlaspack-v3/worker/compat/plugin-options.js +137 -0
  36. package/dist/atlaspack-v3/worker/compat/plugin-tracer.js +10 -0
  37. package/dist/atlaspack-v3/worker/compat/target.js +14 -0
  38. package/dist/atlaspack-v3/worker/side-effect-detector.js +243 -0
  39. package/dist/atlaspack-v3/worker/worker.js +398 -0
  40. package/dist/constants.js +17 -0
  41. package/dist/dumpGraphToGraphViz.js +281 -0
  42. package/dist/index.js +62 -0
  43. package/dist/loadAtlaspackPlugin.js +128 -0
  44. package/dist/loadDotEnv.js +41 -0
  45. package/dist/projectPath.js +83 -0
  46. package/dist/public/Asset.js +279 -0
  47. package/dist/public/Bundle.js +224 -0
  48. package/dist/public/BundleGraph.js +371 -0
  49. package/dist/public/BundleGroup.js +53 -0
  50. package/dist/public/Config.js +286 -0
  51. package/dist/public/Dependency.js +138 -0
  52. package/dist/public/Environment.js +278 -0
  53. package/dist/public/MutableBundleGraph.js +277 -0
  54. package/dist/public/PluginOptions.js +80 -0
  55. package/dist/public/Symbols.js +248 -0
  56. package/dist/public/Target.js +69 -0
  57. package/dist/registerCoreWithSerializer.js +38 -0
  58. package/dist/requests/AssetGraphRequest.js +430 -0
  59. package/dist/requests/AssetGraphRequestRust.js +471 -0
  60. package/dist/requests/AssetRequest.js +130 -0
  61. package/dist/requests/AtlaspackBuildRequest.js +98 -0
  62. package/dist/requests/AtlaspackConfigRequest.js +493 -0
  63. package/dist/requests/BundleGraphRequest.js +381 -0
  64. package/dist/requests/BundleGraphRequestRust.js +324 -0
  65. package/dist/requests/BundleGraphRequestUtils.js +262 -0
  66. package/dist/requests/ConfigRequest.js +246 -0
  67. package/dist/requests/DevDepRequest.js +204 -0
  68. package/dist/requests/EntryRequest.js +314 -0
  69. package/dist/requests/PackageRequest.js +89 -0
  70. package/dist/requests/PathRequest.js +349 -0
  71. package/dist/requests/TargetRequest.js +1316 -0
  72. package/dist/requests/ValidationRequest.js +49 -0
  73. package/dist/requests/WriteBundleRequest.js +522 -0
  74. package/dist/requests/WriteBundlesRequest.js +190 -0
  75. package/dist/requests/asset-graph-diff.js +128 -0
  76. package/dist/requests/asset-graph-dot.js +131 -0
  77. package/dist/resolveOptions.js +267 -0
  78. package/dist/rustWorkerThreadDylibHack.js +19 -0
  79. package/dist/serializerCore.browser.js +43 -0
  80. package/dist/summarizeRequest.js +39 -0
  81. package/dist/types.js +31 -0
  82. package/dist/utils.js +172 -0
  83. package/dist/worker.js +123 -0
  84. package/lib/AssetGraph.js +53 -15
  85. package/lib/Atlaspack.js +160 -57
  86. package/lib/AtlaspackConfig.js +17 -6
  87. package/lib/AtlaspackConfig.schema.js +16 -5
  88. package/lib/BundleGraph.js +390 -43
  89. package/lib/CommittedAsset.js +8 -2
  90. package/lib/Dependency.js +9 -3
  91. package/lib/Environment.js +16 -10
  92. package/lib/EnvironmentManager.js +143 -0
  93. package/lib/IdentifierRegistry.js +2 -4
  94. package/lib/InternalConfig.js +3 -2
  95. package/lib/PackagerRunner.js +38 -40
  96. package/lib/ReporterRunner.js +8 -12
  97. package/lib/RequestTracker.js +336 -168
  98. package/lib/SymbolPropagation.js +52 -29
  99. package/lib/TargetDescriptor.schema.js +10 -1
  100. package/lib/Transformation.js +68 -19
  101. package/lib/UncommittedAsset.js +23 -13
  102. package/lib/Validation.js +20 -5
  103. package/lib/applyRuntimes.js +98 -7
  104. package/lib/assetUtils.js +16 -6
  105. package/lib/atlaspack-v3/AtlaspackV3.js +58 -15
  106. package/lib/atlaspack-v3/NapiWorkerPool.js +63 -2
  107. package/lib/atlaspack-v3/fs.js +4 -1
  108. package/lib/atlaspack-v3/index.js +28 -1
  109. package/lib/atlaspack-v3/jsCallable.js +0 -2
  110. package/lib/atlaspack-v3/worker/compat/asset-symbols.js +7 -4
  111. package/lib/atlaspack-v3/worker/compat/bitflags.js +31 -25
  112. package/lib/atlaspack-v3/worker/compat/dependency.js +4 -1
  113. package/lib/atlaspack-v3/worker/compat/environment.js +10 -7
  114. package/lib/atlaspack-v3/worker/compat/index.js +0 -11
  115. package/lib/atlaspack-v3/worker/compat/mutable-asset.js +16 -11
  116. package/lib/atlaspack-v3/worker/compat/plugin-config.js +14 -35
  117. package/lib/atlaspack-v3/worker/compat/plugin-options.js +16 -2
  118. package/lib/atlaspack-v3/worker/compat/plugin-tracer.js +3 -0
  119. package/lib/atlaspack-v3/worker/compat/target.js +2 -0
  120. package/lib/atlaspack-v3/worker/index.js +3 -0
  121. package/lib/atlaspack-v3/worker/side-effect-detector.js +214 -0
  122. package/lib/atlaspack-v3/worker/worker.js +239 -79
  123. package/lib/constants.js +0 -1
  124. package/lib/dumpGraphToGraphViz.js +72 -17
  125. package/lib/index.js +46 -3
  126. package/lib/loadAtlaspackPlugin.js +2 -3
  127. package/lib/loadDotEnv.js +5 -2
  128. package/lib/projectPath.js +6 -1
  129. package/lib/public/Asset.js +22 -12
  130. package/lib/public/Bundle.js +16 -18
  131. package/lib/public/BundleGraph.js +25 -7
  132. package/lib/public/BundleGroup.js +5 -6
  133. package/lib/public/Config.js +118 -18
  134. package/lib/public/Dependency.js +9 -7
  135. package/lib/public/Environment.js +13 -8
  136. package/lib/public/MutableBundleGraph.js +56 -15
  137. package/lib/public/PluginOptions.js +2 -2
  138. package/lib/public/Symbols.js +12 -12
  139. package/lib/public/Target.js +8 -7
  140. package/lib/registerCoreWithSerializer.js +7 -4
  141. package/lib/requests/AssetGraphRequest.js +60 -27
  142. package/lib/requests/AssetGraphRequestRust.js +314 -82
  143. package/lib/requests/AssetRequest.js +24 -7
  144. package/lib/requests/AtlaspackBuildRequest.js +53 -7
  145. package/lib/requests/AtlaspackConfigRequest.js +29 -19
  146. package/lib/requests/BundleGraphRequest.js +67 -124
  147. package/lib/requests/BundleGraphRequestRust.js +381 -0
  148. package/lib/requests/BundleGraphRequestUtils.js +280 -0
  149. package/lib/requests/ConfigRequest.js +55 -7
  150. package/lib/requests/DevDepRequest.js +32 -6
  151. package/lib/requests/EntryRequest.js +4 -3
  152. package/lib/requests/PackageRequest.js +56 -12
  153. package/lib/requests/PathRequest.js +26 -6
  154. package/lib/requests/TargetRequest.js +129 -60
  155. package/lib/requests/ValidationRequest.js +6 -2
  156. package/lib/requests/WriteBundleRequest.js +336 -18
  157. package/lib/requests/WriteBundlesRequest.js +64 -10
  158. package/lib/requests/asset-graph-diff.js +13 -8
  159. package/lib/requests/asset-graph-dot.js +2 -8
  160. package/lib/resolveOptions.js +35 -10
  161. package/lib/rustWorkerThreadDylibHack.js +0 -1
  162. package/lib/serializerCore.browser.js +1 -2
  163. package/lib/summarizeRequest.js +1 -1
  164. package/lib/types/AssetGraph.d.ts +55 -0
  165. package/lib/types/Atlaspack.d.ts +52 -0
  166. package/lib/types/AtlaspackConfig.d.ts +65 -0
  167. package/lib/types/AtlaspackConfig.schema.d.ts +53 -0
  168. package/lib/types/BundleGraph.d.ts +232 -0
  169. package/lib/types/CommittedAsset.d.ts +23 -0
  170. package/lib/types/Dependency.d.ts +44 -0
  171. package/lib/types/Environment.d.ts +11 -0
  172. package/lib/types/EnvironmentManager.d.ts +37 -0
  173. package/lib/types/IdentifierRegistry.d.ts +6 -0
  174. package/lib/types/InternalConfig.d.ts +23 -0
  175. package/lib/types/PackagerRunner.d.ts +85 -0
  176. package/lib/types/ReporterRunner.d.ts +25 -0
  177. package/lib/types/RequestTracker.d.ts +385 -0
  178. package/lib/types/SymbolPropagation.d.ts +11 -0
  179. package/lib/types/TargetDescriptor.schema.d.ts +5 -0
  180. package/lib/types/Transformation.d.ts +72 -0
  181. package/lib/types/UncommittedAsset.d.ts +61 -0
  182. package/lib/types/Validation.d.ts +37 -0
  183. package/lib/types/applyRuntimes.d.ts +25 -0
  184. package/lib/types/assetUtils.d.ts +42 -0
  185. package/lib/types/atlaspack-v3/AtlaspackV3.d.ts +35 -0
  186. package/lib/types/atlaspack-v3/NapiWorkerPool.d.ts +13 -0
  187. package/lib/types/atlaspack-v3/fs.d.ts +13 -0
  188. package/lib/types/atlaspack-v3/index.d.ts +6 -0
  189. package/lib/types/atlaspack-v3/jsCallable.d.ts +1 -0
  190. package/lib/types/atlaspack-v3/worker/compat/asset-symbols.d.ts +51 -0
  191. package/lib/types/atlaspack-v3/worker/compat/bitflags.d.ts +14 -0
  192. package/lib/types/atlaspack-v3/worker/compat/dependency.d.ts +25 -0
  193. package/lib/types/atlaspack-v3/worker/compat/environment.d.ts +27 -0
  194. package/{src/atlaspack-v3/worker/compat/index.js → lib/types/atlaspack-v3/worker/compat/index.d.ts} +0 -2
  195. package/lib/types/atlaspack-v3/worker/compat/mutable-asset.d.ts +49 -0
  196. package/lib/types/atlaspack-v3/worker/compat/plugin-config.d.ts +29 -0
  197. package/lib/types/atlaspack-v3/worker/compat/plugin-options.d.ts +23 -0
  198. package/lib/types/atlaspack-v3/worker/compat/plugin-tracer.d.ts +5 -0
  199. package/lib/types/atlaspack-v3/worker/compat/target.d.ts +11 -0
  200. package/lib/types/atlaspack-v3/worker/side-effect-detector.d.ts +76 -0
  201. package/lib/types/atlaspack-v3/worker/worker.d.ts +81 -0
  202. package/lib/types/constants.d.ts +13 -0
  203. package/lib/types/dumpGraphToGraphViz.d.ts +10 -0
  204. package/lib/types/index.d.ts +8 -0
  205. package/lib/types/loadAtlaspackPlugin.d.ts +8 -0
  206. package/lib/types/loadDotEnv.d.ts +3 -0
  207. package/lib/types/projectPath.d.ts +19 -0
  208. package/lib/types/public/Asset.d.ts +74 -0
  209. package/lib/types/public/Bundle.d.ts +45 -0
  210. package/lib/types/public/BundleGraph.d.ts +72 -0
  211. package/lib/types/public/BundleGroup.d.ts +12 -0
  212. package/lib/types/public/Config.d.ts +75 -0
  213. package/lib/types/public/Dependency.d.ts +32 -0
  214. package/lib/types/public/Environment.d.ts +34 -0
  215. package/lib/types/public/MutableBundleGraph.d.ts +26 -0
  216. package/lib/types/public/PluginOptions.d.ts +25 -0
  217. package/lib/types/public/Symbols.d.ts +81 -0
  218. package/lib/types/public/Target.d.ts +16 -0
  219. package/lib/types/registerCoreWithSerializer.d.ts +2 -0
  220. package/lib/types/requests/AssetGraphRequest.d.ts +76 -0
  221. package/lib/types/requests/AssetGraphRequestRust.d.ts +21 -0
  222. package/lib/types/requests/AssetRequest.d.ts +16 -0
  223. package/lib/types/requests/AtlaspackBuildRequest.d.ts +33 -0
  224. package/lib/types/requests/AtlaspackConfigRequest.d.ts +45 -0
  225. package/lib/types/requests/BundleGraphRequest.d.ts +28 -0
  226. package/lib/types/requests/BundleGraphRequestRust.d.ts +34 -0
  227. package/lib/types/requests/BundleGraphRequestUtils.d.ts +38 -0
  228. package/lib/types/requests/ConfigRequest.d.ts +67 -0
  229. package/lib/types/requests/DevDepRequest.d.ts +30 -0
  230. package/lib/types/requests/EntryRequest.d.ts +36 -0
  231. package/lib/types/requests/PackageRequest.d.ts +27 -0
  232. package/lib/types/requests/PathRequest.d.ts +48 -0
  233. package/lib/types/requests/TargetRequest.d.ts +48 -0
  234. package/lib/types/requests/ValidationRequest.d.ts +20 -0
  235. package/lib/types/requests/WriteBundleRequest.d.ts +80 -0
  236. package/lib/types/requests/WriteBundlesRequest.d.ts +32 -0
  237. package/lib/types/requests/asset-graph-diff.d.ts +1 -0
  238. package/lib/types/requests/asset-graph-dot.d.ts +9 -0
  239. package/lib/types/resolveOptions.d.ts +3 -0
  240. package/lib/types/rustWorkerThreadDylibHack.d.ts +9 -0
  241. package/lib/types/serializerCore.browser.d.ts +3 -0
  242. package/lib/types/summarizeRequest.d.ts +10 -0
  243. package/lib/types/types.d.ts +496 -0
  244. package/lib/types/utils.d.ts +23 -0
  245. package/lib/types/worker.d.ts +44 -0
  246. package/lib/types.js +8 -1
  247. package/lib/utils.js +18 -3
  248. package/lib/worker.js +32 -15
  249. package/package.json +27 -33
  250. package/src/{AssetGraph.js → AssetGraph.ts} +87 -51
  251. package/src/{Atlaspack.js → Atlaspack.ts} +203 -73
  252. package/src/{AtlaspackConfig.schema.js → AtlaspackConfig.schema.ts} +25 -19
  253. package/src/{AtlaspackConfig.js → AtlaspackConfig.ts} +78 -54
  254. package/src/{BundleGraph.js → BundleGraph.ts} +575 -145
  255. package/src/{CommittedAsset.js → CommittedAsset.ts} +15 -13
  256. package/src/{Dependency.js → Dependency.ts} +59 -42
  257. package/src/{Environment.js → Environment.ts} +24 -15
  258. package/src/EnvironmentManager.ts +154 -0
  259. package/src/{IdentifierRegistry.js → IdentifierRegistry.ts} +1 -4
  260. package/src/{InternalConfig.js → InternalConfig.ts} +22 -23
  261. package/src/{PackagerRunner.js → PackagerRunner.ts} +109 -103
  262. package/src/{ReporterRunner.js → ReporterRunner.ts} +13 -18
  263. package/src/{RequestTracker.js → RequestTracker.ts} +672 -347
  264. package/src/{SymbolPropagation.js → SymbolPropagation.ts} +178 -61
  265. package/src/{TargetDescriptor.schema.js → TargetDescriptor.schema.ts} +10 -1
  266. package/src/{Transformation.js → Transformation.ts} +110 -65
  267. package/src/{UncommittedAsset.js → UncommittedAsset.ts} +50 -39
  268. package/src/{Validation.js → Validation.ts} +32 -17
  269. package/src/{applyRuntimes.js → applyRuntimes.ts} +135 -26
  270. package/src/{assetUtils.js → assetUtils.ts} +49 -36
  271. package/src/atlaspack-v3/AtlaspackV3.ts +183 -0
  272. package/src/atlaspack-v3/NapiWorkerPool.ts +129 -0
  273. package/src/atlaspack-v3/{fs.js → fs.ts} +8 -4
  274. package/src/atlaspack-v3/{index.js → index.ts} +3 -4
  275. package/src/atlaspack-v3/jsCallable.ts +14 -0
  276. package/src/atlaspack-v3/worker/compat/{asset-symbols.js → asset-symbols.ts} +40 -30
  277. package/src/atlaspack-v3/worker/compat/bitflags.ts +102 -0
  278. package/src/atlaspack-v3/worker/compat/{dependency.js → dependency.ts} +13 -13
  279. package/src/atlaspack-v3/worker/compat/{environment.js → environment.ts} +13 -9
  280. package/src/atlaspack-v3/worker/compat/index.ts +8 -0
  281. package/src/atlaspack-v3/worker/compat/{mutable-asset.js → mutable-asset.ts} +21 -20
  282. package/src/atlaspack-v3/worker/compat/{plugin-config.js → plugin-config.ts} +25 -56
  283. package/src/atlaspack-v3/worker/compat/{plugin-options.js → plugin-options.ts} +19 -5
  284. package/src/atlaspack-v3/worker/compat/{plugin-tracer.js → plugin-tracer.ts} +2 -2
  285. package/src/atlaspack-v3/worker/compat/{target.js → target.ts} +3 -4
  286. package/src/atlaspack-v3/worker/index.js +2 -1
  287. package/src/atlaspack-v3/worker/side-effect-detector.ts +298 -0
  288. package/src/atlaspack-v3/worker/worker.ts +548 -0
  289. package/src/{constants.js → constants.ts} +0 -3
  290. package/src/{dumpGraphToGraphViz.js → dumpGraphToGraphViz.ts} +73 -28
  291. package/src/index.ts +18 -0
  292. package/src/{loadAtlaspackPlugin.js → loadAtlaspackPlugin.ts} +8 -9
  293. package/src/{loadDotEnv.js → loadDotEnv.ts} +2 -2
  294. package/src/{projectPath.js → projectPath.ts} +20 -9
  295. package/src/public/{Asset.js → Asset.ts} +41 -28
  296. package/src/public/{Bundle.js → Bundle.ts} +28 -29
  297. package/src/public/{BundleGraph.js → BundleGraph.ts} +102 -50
  298. package/src/public/{BundleGroup.js → BundleGroup.ts} +7 -10
  299. package/src/public/{Config.js → Config.ts} +171 -33
  300. package/src/public/{Dependency.js → Dependency.ts} +20 -17
  301. package/src/public/{Environment.js → Environment.ts} +28 -17
  302. package/src/public/{MutableBundleGraph.js → MutableBundleGraph.ts} +55 -24
  303. package/src/public/{PluginOptions.js → PluginOptions.ts} +6 -6
  304. package/src/public/{Symbols.js → Symbols.ts} +75 -36
  305. package/src/public/{Target.js → Target.ts} +10 -8
  306. package/src/{registerCoreWithSerializer.js → registerCoreWithSerializer.ts} +9 -7
  307. package/src/requests/{AssetGraphRequest.js → AssetGraphRequest.ts} +114 -77
  308. package/src/requests/AssetGraphRequestRust.ts +557 -0
  309. package/src/requests/{AssetRequest.js → AssetRequest.ts} +24 -18
  310. package/src/requests/AtlaspackBuildRequest.ts +168 -0
  311. package/src/requests/{AtlaspackConfigRequest.js → AtlaspackConfigRequest.ts} +72 -58
  312. package/src/requests/{BundleGraphRequest.js → BundleGraphRequest.ts} +117 -187
  313. package/src/requests/BundleGraphRequestRust.ts +470 -0
  314. package/src/requests/BundleGraphRequestUtils.ts +323 -0
  315. package/src/requests/{ConfigRequest.js → ConfigRequest.ts} +110 -50
  316. package/src/requests/{DevDepRequest.js → DevDepRequest.ts} +60 -35
  317. package/src/requests/{EntryRequest.js → EntryRequest.ts} +36 -31
  318. package/src/requests/{PackageRequest.js → PackageRequest.ts} +52 -25
  319. package/src/requests/{PathRequest.js → PathRequest.ts} +47 -37
  320. package/src/requests/{TargetRequest.js → TargetRequest.ts} +265 -179
  321. package/src/requests/{ValidationRequest.js → ValidationRequest.ts} +18 -17
  322. package/src/requests/WriteBundleRequest.ts +734 -0
  323. package/src/requests/{WriteBundlesRequest.js → WriteBundlesRequest.ts} +134 -50
  324. package/src/requests/{asset-graph-diff.js → asset-graph-diff.ts} +25 -21
  325. package/src/requests/{asset-graph-dot.js → asset-graph-dot.ts} +8 -12
  326. package/src/{resolveOptions.js → resolveOptions.ts} +55 -23
  327. package/src/{rustWorkerThreadDylibHack.js → rustWorkerThreadDylibHack.ts} +1 -4
  328. package/src/{serializerCore.browser.js → serializerCore.browser.ts} +2 -3
  329. package/src/{summarizeRequest.js → summarizeRequest.ts} +17 -5
  330. package/src/types.ts +651 -0
  331. package/src/{utils.js → utils.ts} +52 -21
  332. package/src/{worker.js → worker.ts} +50 -42
  333. package/test/{AssetGraph.test.js → AssetGraph.test.ts} +5 -8
  334. package/test/{Atlaspack.test.js → Atlaspack.test.ts} +5 -10
  335. package/test/{AtlaspackConfig.test.js → AtlaspackConfig.test.ts} +0 -5
  336. package/test/{AtlaspackConfigRequest.test.js → AtlaspackConfigRequest.test.ts} +76 -16
  337. package/test/{BundleGraph.test.js → BundleGraph.test.ts} +8 -13
  338. package/test/{Dependency.test.js → Dependency.test.ts} +2 -3
  339. package/test/{EntryRequest.test.js → EntryRequest.test.ts} +1 -6
  340. package/test/Environment.test.ts +153 -0
  341. package/test/EnvironmentManager.test.ts +188 -0
  342. package/test/{IdentifierRegistry.test.js → IdentifierRegistry.test.ts} +2 -4
  343. package/test/{InternalAsset.test.js → InternalAsset.test.ts} +2 -7
  344. package/test/PackagerRunner.test.ts +0 -0
  345. package/test/{PublicAsset.test.js → PublicAsset.test.ts} +2 -7
  346. package/test/{PublicBundle.test.js → PublicBundle.test.ts} +1 -2
  347. package/test/{PublicDependency.test.js → PublicDependency.test.ts} +0 -2
  348. package/test/PublicEnvironment.test.ts +49 -0
  349. package/test/{PublicMutableBundleGraph.test.js → PublicMutableBundleGraph.test.ts} +6 -11
  350. package/test/{RequestTracker.test.js → RequestTracker.test.ts} +149 -59
  351. package/test/{SymbolPropagation.test.js → SymbolPropagation.test.ts} +124 -74
  352. package/test/{TargetRequest.test.js → TargetRequest.test.ts} +91 -92
  353. package/test/fixtures/config-with-reporters/.parcelrc +7 -0
  354. package/test/fixtures/custom-targets/package.json +6 -0
  355. package/test/public/Config.test.ts +104 -0
  356. package/test/requests/AssetGraphRequestRust.test.ts +443 -0
  357. package/test/requests/{ConfigRequest.test.js → ConfigRequest.test.ts} +202 -13
  358. package/test/requests/{DevDepRequest.test.js → DevDepRequest.test.ts} +0 -2
  359. package/test/requests/WriteBundleRequest.test.ts +602 -0
  360. package/test/{test-utils.js → test-utils.ts} +4 -11
  361. package/test/{utils.test.js → utils.test.ts} +1 -3
  362. package/tsconfig.json +60 -0
  363. package/tsconfig.tsbuildinfo +1 -0
  364. package/index.d.ts +0 -30
  365. package/lib/atlaspack-v3/worker/compat/plugin-logger.js +0 -29
  366. package/src/atlaspack-v3/AtlaspackV3.js +0 -87
  367. package/src/atlaspack-v3/NapiWorkerPool.js +0 -53
  368. package/src/atlaspack-v3/jsCallable.js +0 -18
  369. package/src/atlaspack-v3/worker/compat/bitflags.js +0 -100
  370. package/src/atlaspack-v3/worker/compat/plugin-logger.js +0 -47
  371. package/src/atlaspack-v3/worker/worker.js +0 -362
  372. package/src/index.js +0 -13
  373. package/src/requests/AssetGraphRequestRust.js +0 -263
  374. package/src/requests/AtlaspackBuildRequest.js +0 -111
  375. package/src/requests/WriteBundleRequest.js +0 -362
  376. package/src/types.js +0 -600
  377. package/test/Environment.test.js +0 -119
  378. package/test/PackagerRunner.test.js +0 -27
  379. package/test/PublicEnvironment.test.js +0 -27
  380. package/test/requests/AssetGraphRequestRust.test.js +0 -411
@@ -1,10 +1,8 @@
1
- // @flow strict-local
2
-
3
1
  import invariant, {AssertionError} from 'assert';
4
2
  import path from 'path';
5
3
 
6
4
  import {deserialize, serialize} from '@atlaspack/build-cache';
7
- import {LMDBLiteCache, type Cache} from '@atlaspack/cache';
5
+ import {Cache} from '@atlaspack/cache';
8
6
  import {getFeatureFlag} from '@atlaspack/feature-flags';
9
7
  import {ContentGraph} from '@atlaspack/graph';
10
8
  import type {
@@ -14,11 +12,11 @@ import type {
14
12
  SerializedContentGraph,
15
13
  Graph,
16
14
  } from '@atlaspack/graph';
17
- import logger, {instrument} from '@atlaspack/logger';
15
+ import logger from '@atlaspack/logger';
18
16
  import {hashString} from '@atlaspack/rust';
19
17
  import type {Async, EnvMap} from '@atlaspack/types';
20
18
  import {
21
- type Deferred,
19
+ Deferred,
22
20
  isGlobMatch,
23
21
  isDirectoryInside,
24
22
  makeDeferredWithPromise,
@@ -30,19 +28,19 @@ import nullthrows from 'nullthrows';
30
28
 
31
29
  import {
32
30
  ATLASPACK_VERSION,
33
- VALID,
34
- INITIAL_BUILD,
35
31
  FILE_CREATE,
36
- FILE_UPDATE,
37
32
  FILE_DELETE,
33
+ FILE_UPDATE,
38
34
  ENV_CHANGE,
35
+ ERROR,
36
+ INITIAL_BUILD,
39
37
  OPTION_CHANGE,
40
38
  STARTUP,
41
- ERROR,
39
+ VALID,
42
40
  } from './constants';
43
41
  import type {AtlaspackV3} from './atlaspack-v3/AtlaspackV3';
44
42
  import {
45
- type ProjectPath,
43
+ ProjectPath,
46
44
  fromProjectPathRelative,
47
45
  toProjectPathUnsafe,
48
46
  toProjectPath,
@@ -68,7 +66,13 @@ import type {
68
66
  InternalFileCreateInvalidation,
69
67
  InternalGlob,
70
68
  } from './types';
71
- import {BuildAbortError, assertSignalNotAborted, hashFromOption} from './utils';
69
+ import {BuildAbortError, hashFromOption} from './utils';
70
+ import {performance} from 'perf_hooks';
71
+
72
+ import {
73
+ loadEnvironmentsFromCache,
74
+ writeEnvironmentsToCache,
75
+ } from './EnvironmentManager';
72
76
 
73
77
  export const requestGraphEdgeTypes = {
74
78
  subrequest: 2,
@@ -77,39 +81,44 @@ export const requestGraphEdgeTypes = {
77
81
  invalidated_by_create: 5,
78
82
  invalidated_by_create_above: 6,
79
83
  dirname: 7,
80
- };
84
+ } as const;
81
85
 
82
86
  class FSBailoutError extends Error {
83
87
  name: string = 'FSBailoutError';
84
88
  }
85
89
 
86
- export type RequestGraphEdgeType = $Values<typeof requestGraphEdgeTypes>;
87
-
88
- type RequestGraphOpts = {|
89
- ...ContentGraphOpts<RequestGraphNode, RequestGraphEdgeType>,
90
- invalidNodeIds: Set<NodeId>,
91
- incompleteNodeIds: Set<NodeId>,
92
- globNodeIds: Set<NodeId>,
93
- envNodeIds: Set<NodeId>,
94
- optionNodeIds: Set<NodeId>,
95
- unpredicatableNodeIds: Set<NodeId>,
96
- invalidateOnBuildNodeIds: Set<NodeId>,
97
- cachedRequestChunks: Set<number>,
98
- configKeyNodes: Map<ProjectPath, Set<NodeId>>,
99
- |};
100
-
101
- type SerializedRequestGraph = {|
102
- ...SerializedContentGraph<RequestGraphNode, RequestGraphEdgeType>,
103
- invalidNodeIds: Set<NodeId>,
104
- incompleteNodeIds: Set<NodeId>,
105
- globNodeIds: Set<NodeId>,
106
- envNodeIds: Set<NodeId>,
107
- optionNodeIds: Set<NodeId>,
108
- unpredicatableNodeIds: Set<NodeId>,
109
- invalidateOnBuildNodeIds: Set<NodeId>,
110
- cachedRequestChunks: Set<number>,
111
- configKeyNodes: Map<ProjectPath, Set<NodeId>>,
112
- |};
90
+ export type RequestGraphEdgeType =
91
+ (typeof requestGraphEdgeTypes)[keyof typeof requestGraphEdgeTypes];
92
+
93
+ type RequestGraphOpts = ContentGraphOpts<
94
+ RequestGraphNode,
95
+ RequestGraphEdgeType
96
+ > & {
97
+ invalidNodeIds: Set<NodeId>;
98
+ incompleteNodeIds: Set<NodeId>;
99
+ globNodeIds: Set<NodeId>;
100
+ envNodeIds: Set<NodeId>;
101
+ optionNodeIds: Set<NodeId>;
102
+ unpredicatableNodeIds: Set<NodeId>;
103
+ invalidateOnBuildNodeIds: Set<NodeId>;
104
+ cachedRequestChunks: Set<number>;
105
+ configKeyNodes: Map<ProjectPath, Set<NodeId>>;
106
+ };
107
+
108
+ type SerializedRequestGraph = SerializedContentGraph<
109
+ RequestGraphNode,
110
+ RequestGraphEdgeType
111
+ > & {
112
+ invalidNodeIds: Set<NodeId>;
113
+ incompleteNodeIds: Set<NodeId>;
114
+ globNodeIds: Set<NodeId>;
115
+ envNodeIds: Set<NodeId>;
116
+ optionNodeIds: Set<NodeId>;
117
+ unpredicatableNodeIds: Set<NodeId>;
118
+ invalidateOnBuildNodeIds: Set<NodeId>;
119
+ cachedRequestChunks: Set<number>;
120
+ configKeyNodes: Map<ProjectPath, Set<NodeId>>;
121
+ };
113
122
 
114
123
  const FILE: 0 = 0;
115
124
  const REQUEST: 1 = 1;
@@ -119,40 +128,51 @@ const OPTION: 4 = 4;
119
128
  const GLOB: 5 = 5;
120
129
  const CONFIG_KEY: 6 = 6;
121
130
 
122
- type FileNode = {|id: ContentKey, +type: typeof FILE|};
131
+ type FileNode = {
132
+ id: ContentKey;
133
+ readonly type: typeof FILE;
134
+ };
123
135
 
124
- type GlobNode = {|id: ContentKey, +type: typeof GLOB, value: InternalGlob|};
136
+ type GlobNode = {
137
+ id: ContentKey;
138
+ readonly type: typeof GLOB;
139
+ value: InternalGlob;
140
+ };
125
141
 
126
- type FileNameNode = {|
127
- id: ContentKey,
128
- +type: typeof FILE_NAME,
129
- |};
142
+ type FileNameNode = {
143
+ id: ContentKey;
144
+ readonly type: typeof FILE_NAME;
145
+ };
130
146
 
131
- type EnvNode = {|
132
- id: ContentKey,
133
- +type: typeof ENV,
134
- value: string | void,
135
- |};
147
+ type EnvNode = {
148
+ id: ContentKey;
149
+ readonly type: typeof ENV;
150
+ value: string | undefined;
151
+ };
136
152
 
137
- type OptionNode = {|
138
- id: ContentKey,
139
- +type: typeof OPTION,
140
- hash: string,
141
- |};
153
+ type OptionNode = {
154
+ id: ContentKey;
155
+ readonly type: typeof OPTION;
156
+ hash: string;
157
+ };
142
158
 
143
- type ConfigKeyNode = {|
144
- id: ContentKey,
145
- +type: typeof CONFIG_KEY,
146
- configKey: string,
147
- contentHash: string,
148
- |};
159
+ type ConfigKeyNode = {
160
+ id: ContentKey;
161
+ readonly type: typeof CONFIG_KEY;
162
+ configKey: string[];
163
+ contentHash: string;
164
+ };
149
165
 
150
- type Request<TInput, TResult> = {|
151
- id: string,
152
- +type: RequestType,
153
- input: TInput,
154
- run: ({|input: TInput, ...StaticRunOpts<TResult>|}) => Async<TResult>,
155
- |};
166
+ type Request<TInput, TResult> = {
167
+ id: string;
168
+ readonly type: RequestType;
169
+ input: TInput;
170
+ run: (
171
+ arg1: {
172
+ input: TInput;
173
+ } & StaticRunOpts<TResult>,
174
+ ) => Async<TResult>;
175
+ };
156
176
 
157
177
  export type RequestResult =
158
178
  | AssetGraphRequestResult
@@ -170,15 +190,15 @@ export type RequestResult =
170
190
  | AssetRequestResult;
171
191
 
172
192
  type InvalidateReason = number;
173
- type RequestNode = {|
174
- id: ContentKey,
175
- +type: typeof REQUEST,
176
- +requestType: RequestType,
177
- invalidateReason: InvalidateReason,
178
- result?: RequestResult,
179
- resultCacheKey?: ?string,
180
- hash?: string,
181
- |};
193
+ type RequestNode = {
194
+ id: ContentKey;
195
+ readonly type: typeof REQUEST;
196
+ readonly requestType: RequestType;
197
+ invalidateReason: InvalidateReason;
198
+ result?: RequestResult;
199
+ resultCacheKey?: string | null | undefined;
200
+ hash?: string;
201
+ };
182
202
 
183
203
  export const requestTypes = {
184
204
  atlaspack_build_request: 1,
@@ -195,10 +215,10 @@ export const requestTypes = {
195
215
  package_request: 12,
196
216
  write_bundle_request: 13,
197
217
  validation_request: 14,
198
- };
218
+ } as const;
199
219
 
200
- type RequestType = $Values<typeof requestTypes>;
201
- type RequestTypeName = $Keys<typeof requestTypes>;
220
+ type RequestType = (typeof requestTypes)[keyof typeof requestTypes];
221
+ type RequestTypeName = keyof typeof requestTypes;
202
222
 
203
223
  type RequestGraphNode =
204
224
  | RequestNode
@@ -209,43 +229,48 @@ type RequestGraphNode =
209
229
  | OptionNode
210
230
  | ConfigKeyNode;
211
231
 
212
- export type RunAPI<TResult: RequestResult> = {|
213
- invalidateOnFileCreate: (InternalFileCreateInvalidation) => void,
214
- invalidateOnFileDelete: (ProjectPath) => void,
215
- invalidateOnFileUpdate: (ProjectPath) => void,
232
+ export type RunAPI<TResult extends RequestResult> = {
233
+ invalidateOnFileCreate: (arg1: InternalFileCreateInvalidation) => void;
234
+ invalidateOnFileDelete: (arg1: ProjectPath) => void;
235
+ invalidateOnFileUpdate: (arg1: ProjectPath) => void;
216
236
  invalidateOnConfigKeyChange: (
217
237
  filePath: ProjectPath,
218
- configKey: string,
238
+ configKey: string[],
219
239
  contentHash: string,
220
- ) => void,
221
- invalidateOnStartup: () => void,
222
- invalidateOnBuild: () => void,
223
- invalidateOnEnvChange: (string) => void,
224
- invalidateOnOptionChange: (string) => void,
225
- getInvalidations(): Array<RequestInvalidation>,
226
- storeResult(result: TResult, cacheKey?: string): void,
227
- getRequestResult<T: RequestResult>(contentKey: ContentKey): Async<?T>,
228
- getPreviousResult<T: RequestResult>(ifMatch?: string): Async<?T>,
229
- getSubRequests(): Array<RequestNode>,
230
- getInvalidSubRequests(): Array<RequestNode>,
231
- canSkipSubrequest(ContentKey): boolean,
232
- runRequest: <TInput, TResult: RequestResult>(
240
+ ) => void;
241
+ invalidateOnStartup: () => void;
242
+ invalidateOnBuild: () => void;
243
+ invalidateOnEnvChange: (arg1: string) => void;
244
+ invalidateOnOptionChange: (arg1: string) => void;
245
+ getInvalidations(): Array<RequestInvalidation>;
246
+ storeResult(result: TResult, cacheKey?: string): void;
247
+ getRequestResult<T extends RequestResult>(
248
+ contentKey: ContentKey,
249
+ ): Async<T | null | undefined>;
250
+ getPreviousResult<T extends RequestResult>(
251
+ ifMatch?: string,
252
+ ): Async<T | null | undefined>;
253
+ getSubRequests(): Array<RequestNode>;
254
+ getInvalidSubRequests(): Array<RequestNode>;
255
+ canSkipSubrequest(arg1: ContentKey): boolean;
256
+ runRequest: <TInput, TResult extends RequestResult>(
233
257
  subRequest: Request<TInput, TResult>,
234
258
  opts?: RunRequestOpts,
235
- ) => Promise<TResult>,
236
- |};
259
+ ) => Promise<TResult>;
260
+ };
237
261
 
238
- type RunRequestOpts = {|
239
- force: boolean,
240
- |};
262
+ type RunRequestOpts = {
263
+ force: boolean;
264
+ };
241
265
 
242
- export type StaticRunOpts<TResult> = {|
243
- api: RunAPI<TResult>,
244
- farm: WorkerFarm,
245
- invalidateReason: InvalidateReason,
246
- options: AtlaspackOptions,
247
- rustAtlaspack: ?AtlaspackV3,
248
- |};
266
+ export type StaticRunOpts<TResult> = {
267
+ // @ts-expect-error TS2344
268
+ api: RunAPI<TResult>;
269
+ farm: WorkerFarm;
270
+ invalidateReason: InvalidateReason;
271
+ options: AtlaspackOptions;
272
+ rustAtlaspack: AtlaspackV3 | null | undefined;
273
+ };
249
274
 
250
275
  const nodeFromFilePath = (filePath: ProjectPath): RequestGraphNode => ({
251
276
  id: fromProjectPathRelative(filePath),
@@ -268,13 +293,13 @@ const nodeFromRequest = (request: RequestNode): RequestGraphNode => ({
268
293
  invalidateReason: INITIAL_BUILD,
269
294
  });
270
295
 
271
- const nodeFromEnv = (env: string, value: string | void): RequestGraphNode => ({
296
+ const nodeFromEnv = (env: string, value?: string): RequestGraphNode => ({
272
297
  id: 'env:' + env,
273
298
  type: ENV,
274
299
  value,
275
300
  });
276
301
 
277
- const nodeFromOption = (option: string, value: mixed): RequestGraphNode => ({
302
+ const nodeFromOption = (option: string, value: unknown): RequestGraphNode => ({
278
303
  id: 'option:' + option,
279
304
  type: OPTION,
280
305
  hash: hashFromOption(value),
@@ -282,10 +307,12 @@ const nodeFromOption = (option: string, value: mixed): RequestGraphNode => ({
282
307
 
283
308
  const nodeFromConfigKey = (
284
309
  fileName: ProjectPath,
285
- configKey: string,
310
+ configKey: string[],
286
311
  contentHash: string,
287
312
  ): RequestGraphNode => ({
288
- id: `config_key:${fromProjectPathRelative(fileName)}:${configKey}`,
313
+ id: `config_key:${fromProjectPathRelative(fileName)}:${JSON.stringify(
314
+ configKey,
315
+ )}`,
289
316
  type: CONFIG_KEY,
290
317
  configKey,
291
318
  contentHash,
@@ -301,9 +328,10 @@ const keyFromOptionContentKey = (contentKey: ContentKey): string =>
301
328
  // The goal is to free up the event loop periodically to allow interruption by the user.
302
329
  const NODES_PER_BLOB = 2 ** 14;
303
330
 
331
+ // @ts-expect-error TS2417
304
332
  export class RequestGraph extends ContentGraph<
305
333
  RequestGraphNode,
306
- RequestGraphEdgeType,
334
+ RequestGraphEdgeType
307
335
  > {
308
336
  invalidNodeIds: Set<NodeId> = new Set();
309
337
  incompleteNodeIds: Set<NodeId> = new Set();
@@ -319,9 +347,7 @@ export class RequestGraph extends ContentGraph<
319
347
  configKeyNodes: Map<ProjectPath, Set<NodeId>> = new Map();
320
348
  nodesPerBlob: number = NODES_PER_BLOB;
321
349
 
322
- // $FlowFixMe[prop-missing]
323
350
  static deserialize(opts: RequestGraphOpts): RequestGraph {
324
- // $FlowFixMe[prop-missing]
325
351
  let deserialized = new RequestGraph(opts);
326
352
  deserialized.invalidNodeIds = opts.invalidNodeIds;
327
353
  deserialized.incompleteNodeIds = opts.incompleteNodeIds;
@@ -335,7 +361,6 @@ export class RequestGraph extends ContentGraph<
335
361
  return deserialized;
336
362
  }
337
363
 
338
- // $FlowFixMe[prop-missing]
339
364
  serialize(): SerializedRequestGraph {
340
365
  return {
341
366
  ...super.serialize(),
@@ -413,7 +438,7 @@ export class RequestGraph extends ContentGraph<
413
438
  requestNodeId: NodeId,
414
439
  subrequestContentKeys: Array<ContentKey>,
415
440
  ) {
416
- let subrequestNodeIds = [];
441
+ let subrequestNodeIds: Array<NodeId> = [];
417
442
  for (let key of subrequestContentKeys) {
418
443
  if (this.hasContentKey(key)) {
419
444
  subrequestNodeIds.push(this.getNodeIdByContentKey(key));
@@ -446,6 +471,11 @@ export class RequestGraph extends ContentGraph<
446
471
  this.removeCachedRequestChunkForNode(nodeId);
447
472
  }
448
473
 
474
+ /**
475
+ * Nodes that are invalidated on start-up, such as JavaScript babel configuration files which are
476
+ * imported when the build kicks-off and might doing arbitrary work such as reading from the file
477
+ * system.
478
+ */
449
479
  invalidateUnpredictableNodes() {
450
480
  for (let nodeId of this.unpredicatableNodeIds) {
451
481
  let node = nullthrows(this.getNode(nodeId));
@@ -454,6 +484,9 @@ export class RequestGraph extends ContentGraph<
454
484
  }
455
485
  }
456
486
 
487
+ /**
488
+ * Effectively uncacheable nodes.
489
+ */
457
490
  invalidateOnBuildNodes() {
458
491
  for (let nodeId of this.invalidateOnBuildNodeIds) {
459
492
  let node = nullthrows(this.getNode(nodeId));
@@ -462,11 +495,20 @@ export class RequestGraph extends ContentGraph<
462
495
  }
463
496
  }
464
497
 
465
- invalidateEnvNodes(env: EnvMap) {
498
+ /**
499
+ * Nodes invalidated by environment changes, corresponds to `env: ...` inputs.
500
+ */
501
+ invalidateEnvNodes(env: EnvMap): string[] {
502
+ const invalidatedKeys: Array<string> = [];
503
+
466
504
  for (let nodeId of this.envNodeIds) {
467
505
  let node = nullthrows(this.getNode(nodeId));
468
506
  invariant(node.type === ENV);
469
- if (env[keyFromEnvContentKey(node.id)] !== node.value) {
507
+
508
+ const key = keyFromEnvContentKey(node.id);
509
+ if (env[key] !== node.value) {
510
+ invalidatedKeys.push(key);
511
+
470
512
  let parentNodes = this.getNodeIdsConnectedTo(
471
513
  nodeId,
472
514
  requestGraphEdgeTypes.invalidated_by_update,
@@ -476,15 +518,24 @@ export class RequestGraph extends ContentGraph<
476
518
  }
477
519
  }
478
520
  }
521
+
522
+ return invalidatedKeys;
479
523
  }
480
524
 
481
- invalidateOptionNodes(options: AtlaspackOptions) {
525
+ /**
526
+ * Nodes invalidated by option changes.
527
+ */
528
+ invalidateOptionNodes(options: AtlaspackOptions): string[] {
529
+ const invalidatedKeys: Array<string> = [];
530
+
482
531
  for (let nodeId of this.optionNodeIds) {
483
532
  let node = nullthrows(this.getNode(nodeId));
484
533
  invariant(node.type === OPTION);
485
- if (
486
- hashFromOption(options[keyFromOptionContentKey(node.id)]) !== node.hash
487
- ) {
534
+ const key = keyFromOptionContentKey(node.id);
535
+
536
+ // @ts-expect-error TS7053
537
+ if (hashFromOption(options[key]) !== node.hash) {
538
+ invalidatedKeys.push(key);
488
539
  let parentNodes = this.getNodeIdsConnectedTo(
489
540
  nodeId,
490
541
  requestGraphEdgeTypes.invalidated_by_update,
@@ -494,12 +545,14 @@ export class RequestGraph extends ContentGraph<
494
545
  }
495
546
  }
496
547
  }
548
+
549
+ return invalidatedKeys;
497
550
  }
498
551
 
499
552
  invalidateOnConfigKeyChange(
500
553
  requestNodeId: NodeId,
501
554
  filePath: ProjectPath,
502
- configKey: string,
555
+ configKey: string[],
503
556
  contentHash: string,
504
557
  ) {
505
558
  let configKeyNodeId = this.addNode(
@@ -571,9 +624,13 @@ export class RequestGraph extends ContentGraph<
571
624
  input: InternalFileCreateInvalidation,
572
625
  ) {
573
626
  let node;
627
+ // @ts-expect-error TS2339
574
628
  if (input.glob != null) {
629
+ // @ts-expect-error TS2339
575
630
  node = nodeFromGlob(input.glob);
631
+ // @ts-expect-error TS2339
576
632
  } else if (input.fileName != null && input.aboveFilePath != null) {
633
+ // @ts-expect-error TS2339
577
634
  let aboveFilePath = input.aboveFilePath;
578
635
 
579
636
  // Create nodes and edges for each part of the filename pattern.
@@ -581,6 +638,7 @@ export class RequestGraph extends ContentGraph<
581
638
  // This creates a sort of trie structure within the graph that can be
582
639
  // quickly matched by following the edges. This is also memory efficient
583
640
  // since common sub-paths (e.g. 'node_modules') are deduplicated.
641
+ // @ts-expect-error TS2339
584
642
  let parts = input.fileName.split('/').reverse();
585
643
  let lastNodeId;
586
644
  for (let part of parts) {
@@ -649,7 +707,9 @@ export class RequestGraph extends ContentGraph<
649
707
  requestGraphEdgeTypes.invalidated_by_create_above,
650
708
  );
651
709
  }
710
+ // @ts-expect-error TS2339
652
711
  } else if (input.filePath != null) {
712
+ // @ts-expect-error TS2339
653
713
  node = nodeFromFilePath(input.filePath);
654
714
  } else {
655
715
  throw new Error('Invalid invalidation');
@@ -681,13 +741,9 @@ export class RequestGraph extends ContentGraph<
681
741
  this.invalidateOnBuildNodeIds.add(requestNodeId);
682
742
  }
683
743
 
684
- invalidateOnEnvChange(
685
- requestNodeId: NodeId,
686
- env: string,
687
- value: string | void,
688
- ) {
689
- let envNode = nodeFromEnv(env, value);
690
- let envNodeId = this.addNode(envNode);
744
+ invalidateOnEnvChange(requestNodeId: NodeId, env: string, value?: string) {
745
+ const envNode = nodeFromEnv(env, value);
746
+ const envNodeId = this.addNode(envNode);
691
747
 
692
748
  if (
693
749
  !this.hasEdge(
@@ -707,7 +763,7 @@ export class RequestGraph extends ContentGraph<
707
763
  invalidateOnOptionChange(
708
764
  requestNodeId: NodeId,
709
765
  option: string,
710
- value: mixed,
766
+ value: unknown,
711
767
  ) {
712
768
  let optionNode = nodeFromOption(option, value);
713
769
  let optionNodeId = this.addNode(optionNode);
@@ -760,6 +816,7 @@ export class RequestGraph extends ContentGraph<
760
816
  requestNodeId,
761
817
  requestGraphEdgeTypes.invalidated_by_update,
762
818
  );
819
+ // @ts-expect-error TS2322
763
820
  return invalidations
764
821
  .map((nodeId) => {
765
822
  let node = nullthrows(this.getNode(nodeId));
@@ -818,7 +875,7 @@ export class RequestGraph extends ContentGraph<
818
875
  node: FileNameNode,
819
876
  filePath: ProjectPath,
820
877
  matchNodes: Array<FileNode>,
821
- invalidateNode: (NodeId, InvalidateReason) => void,
878
+ invalidateNode: (arg1: NodeId, arg2: InvalidateReason) => void,
822
879
  ) {
823
880
  // If there is an edge between this file_name node and one of the original file nodes pointed to
824
881
  // by the original file_name node, and the matched node is inside the current directory, invalidate
@@ -907,7 +964,10 @@ export class RequestGraph extends ContentGraph<
907
964
  * True if this is the start-up (loading phase) invalidation.
908
965
  */
909
966
  isInitialBuild: boolean = false,
910
- ): Async<boolean> {
967
+ ): Promise<{
968
+ didInvalidate: boolean;
969
+ invalidationsByPath: Map<string, number>;
970
+ }> {
911
971
  let didInvalidate = false;
912
972
  let count = 0;
913
973
  let predictedTime = 0;
@@ -916,7 +976,10 @@ export class RequestGraph extends ContentGraph<
916
976
  const removeOrphans = !enableOptimization;
917
977
 
918
978
  const invalidatedNodes = new Set();
919
- const invalidateNode = (nodeId, reason) => {
979
+ const invalidateNode = (
980
+ nodeId: NodeId,
981
+ reason: InvalidateReason | number,
982
+ ) => {
920
983
  if (enableOptimization && invalidatedNodes.has(nodeId)) {
921
984
  return;
922
985
  }
@@ -924,13 +987,13 @@ export class RequestGraph extends ContentGraph<
924
987
  this.invalidateNode(nodeId, reason);
925
988
  };
926
989
  const aboveCache = new Map();
927
- const getAbove = (fileNameNodeId) => {
990
+ const getAbove = (fileNameNodeId: NodeId) => {
928
991
  const cachedResult = aboveCache.get(fileNameNodeId);
929
992
  if (enableOptimization && cachedResult) {
930
993
  return cachedResult;
931
994
  }
932
995
 
933
- let above = [];
996
+ let above: Array<FileNode> = [];
934
997
  const children = this.getNodeIdsConnectedTo(
935
998
  fileNameNodeId,
936
999
  requestGraphEdgeTypes.invalidated_by_create_above,
@@ -945,7 +1008,10 @@ export class RequestGraph extends ContentGraph<
945
1008
  return above;
946
1009
  };
947
1010
 
1011
+ const invalidationsByPath = new Map();
948
1012
  for (let {path: _path, type} of events) {
1013
+ const invalidationsBefore = this.getInvalidNodeCount();
1014
+
949
1015
  if (
950
1016
  !enableOptimization &&
951
1017
  process.env.ATLASPACK_DISABLE_CACHE_TIMEOUT !== 'true' &&
@@ -991,7 +1057,10 @@ export class RequestGraph extends ContentGraph<
991
1057
  this.invalidNodeIds.add(id);
992
1058
  }
993
1059
  }
994
- return true;
1060
+ return {
1061
+ didInvalidate: true,
1062
+ invalidationsByPath: new Map(),
1063
+ };
995
1064
  }
996
1065
 
997
1066
  // sometimes mac os reports update events as create events.
@@ -1072,11 +1141,18 @@ export class RequestGraph extends ContentGraph<
1072
1141
  }
1073
1142
 
1074
1143
  let configKeyNodes = this.configKeyNodes.get(_filePath);
1075
- if (configKeyNodes && (type === 'delete' || type === 'update')) {
1144
+
1145
+ // With granular invalidations we will always run this block,
1146
+ // so even if we get a create event (for whatever reason), we will still
1147
+ // try to limit invalidations from config key changes through hashing.
1148
+ //
1149
+ // Currently create events can invalidate a large number of nodes due to
1150
+ // "create above" invalidations.
1151
+ if (configKeyNodes) {
1076
1152
  for (let nodeId of configKeyNodes) {
1077
1153
  let isInvalid = type === 'delete';
1078
1154
 
1079
- if (type === 'update') {
1155
+ if (type !== 'delete') {
1080
1156
  let node = this.getNode(nodeId);
1081
1157
  invariant(node && node.type === CONFIG_KEY);
1082
1158
 
@@ -1104,6 +1180,13 @@ export class RequestGraph extends ContentGraph<
1104
1180
  }
1105
1181
  }
1106
1182
  }
1183
+
1184
+ const invalidationsAfter = this.getInvalidNodeCount();
1185
+ const invalidationsForEvent = invalidationsAfter - invalidationsBefore;
1186
+ invalidationsByPath.set(
1187
+ _path,
1188
+ (invalidationsByPath.get(_path) ?? 0) + invalidationsForEvent,
1189
+ );
1107
1190
  }
1108
1191
 
1109
1192
  if (getFeatureFlag('fixQuadraticCacheInvalidation')) {
@@ -1124,7 +1207,10 @@ export class RequestGraph extends ContentGraph<
1124
1207
  },
1125
1208
  });
1126
1209
 
1127
- return didInvalidate && this.invalidNodeIds.size > 0;
1210
+ return {
1211
+ didInvalidate,
1212
+ invalidationsByPath,
1213
+ };
1128
1214
  }
1129
1215
 
1130
1216
  hasCachedRequestChunk(index: number): boolean {
@@ -1138,14 +1224,20 @@ export class RequestGraph extends ContentGraph<
1138
1224
  removeCachedRequestChunkForNode(nodeId: number): void {
1139
1225
  this.cachedRequestChunks.delete(Math.floor(nodeId / this.nodesPerBlob));
1140
1226
  }
1227
+
1228
+ /**
1229
+ * Returns the number of invalidated nodes in the graph.
1230
+ */
1231
+ getInvalidNodeCount(): number {
1232
+ return this.invalidNodeIds.size;
1233
+ }
1141
1234
  }
1142
1235
 
1143
1236
  export default class RequestTracker {
1144
1237
  graph: RequestGraph;
1145
1238
  farm: WorkerFarm;
1146
1239
  options: AtlaspackOptions;
1147
- rustAtlaspack: ?AtlaspackV3;
1148
- signal: ?AbortSignal;
1240
+ rustAtlaspack: AtlaspackV3 | null | undefined;
1149
1241
  stats: Map<RequestType, number> = new Map();
1150
1242
 
1151
1243
  constructor({
@@ -1153,27 +1245,22 @@ export default class RequestTracker {
1153
1245
  farm,
1154
1246
  options,
1155
1247
  rustAtlaspack,
1156
- }: {|
1157
- graph?: RequestGraph,
1158
- farm: WorkerFarm,
1159
- options: AtlaspackOptions,
1160
- rustAtlaspack?: AtlaspackV3,
1161
- |}) {
1248
+ }: {
1249
+ graph?: RequestGraph;
1250
+ farm: WorkerFarm;
1251
+ options: AtlaspackOptions;
1252
+ rustAtlaspack?: AtlaspackV3;
1253
+ }) {
1162
1254
  this.graph = graph || new RequestGraph();
1163
1255
  this.farm = farm;
1164
1256
  this.options = options;
1165
1257
  this.rustAtlaspack = rustAtlaspack;
1166
1258
  }
1167
1259
 
1168
- // TODO: refactor (abortcontroller should be created by RequestTracker)
1169
- setSignal(signal?: AbortSignal) {
1170
- this.signal = signal;
1171
- }
1172
-
1173
- startRequest(request: RequestNode): {|
1174
- requestNodeId: NodeId,
1175
- deferred: Deferred<boolean>,
1176
- |} {
1260
+ startRequest(request: RequestNode): {
1261
+ requestNodeId: NodeId;
1262
+ deferred: Deferred<boolean>;
1263
+ } {
1177
1264
  let didPreviouslyExist = this.graph.hasContentKey(request.id);
1178
1265
  let requestNodeId;
1179
1266
  if (didPreviouslyExist) {
@@ -1189,13 +1276,14 @@ export default class RequestTracker {
1189
1276
  this.graph.invalidNodeIds.delete(requestNodeId);
1190
1277
 
1191
1278
  let {promise, deferred} = makeDeferredWithPromise();
1279
+ // @ts-expect-error TS2345
1192
1280
  this.graph.incompleteNodePromises.set(requestNodeId, promise);
1193
1281
 
1194
1282
  return {requestNodeId, deferred};
1195
1283
  }
1196
1284
 
1197
1285
  // If a cache key is provided, the result will be removed from the node and stored in a separate cache entry
1198
- storeResult(nodeId: NodeId, result: RequestResult, cacheKey: ?string) {
1286
+ storeResult(nodeId: NodeId, result: RequestResult, cacheKey?: string | null) {
1199
1287
  let node = this.graph.getNode(nodeId);
1200
1288
  if (node && node.type === REQUEST) {
1201
1289
  node.result = result;
@@ -1211,10 +1299,10 @@ export default class RequestTracker {
1211
1299
  );
1212
1300
  }
1213
1301
 
1214
- async getRequestResult<T: RequestResult>(
1302
+ async getRequestResult<T extends RequestResult>(
1215
1303
  contentKey: ContentKey,
1216
1304
  ifMatch?: string,
1217
- ): Promise<?T> {
1305
+ ): Promise<T | null | undefined> {
1218
1306
  let node = nullthrows(this.graph.getNodeByContentKey(contentKey));
1219
1307
  invariant(node.type === REQUEST);
1220
1308
 
@@ -1223,18 +1311,15 @@ export default class RequestTracker {
1223
1311
  }
1224
1312
 
1225
1313
  if (node.result != undefined) {
1226
- // $FlowFixMe
1227
- let result: T = (node.result: any);
1314
+ let result: T = node.result as any;
1228
1315
  return result;
1229
1316
  } else if (node.resultCacheKey != null && ifMatch == null) {
1230
1317
  let key = node.resultCacheKey;
1231
- if (!getFeatureFlag('cachePerformanceImprovements')) {
1232
- invariant(this.options.cache.hasLargeBlob(key));
1233
- }
1318
+ invariant(this.options.cache.hasLargeBlob(key));
1234
1319
 
1235
- let cachedResult: T = getFeatureFlag('cachePerformanceImprovements')
1236
- ? nullthrows(await this.options.cache.get<T>(key))
1237
- : deserialize(await this.options.cache.getLargeBlob(key));
1320
+ let cachedResult: T = deserialize(
1321
+ await this.options.cache.getLargeBlob(key),
1322
+ );
1238
1323
  node.result = cachedResult;
1239
1324
  return cachedResult;
1240
1325
  }
@@ -1261,7 +1346,13 @@ export default class RequestTracker {
1261
1346
  }
1262
1347
  }
1263
1348
 
1264
- respondToFSEvents(events: Array<Event>, threshold: number): Async<boolean> {
1349
+ respondToFSEvents(
1350
+ events: Array<Event>,
1351
+ threshold: number,
1352
+ ): Promise<{
1353
+ didInvalidate: boolean;
1354
+ invalidationsByPath: Map<string, number>;
1355
+ }> {
1265
1356
  return this.graph.respondToFSEvents(events, this.options, threshold);
1266
1357
  }
1267
1358
 
@@ -1270,7 +1361,7 @@ export default class RequestTracker {
1270
1361
  }
1271
1362
 
1272
1363
  getInvalidRequests(): Array<RequestNode> {
1273
- let invalidRequests = [];
1364
+ let invalidRequests: Array<RequestNode> = [];
1274
1365
  for (let id of this.graph.invalidNodeIds) {
1275
1366
  let node = nullthrows(this.graph.getNode(id));
1276
1367
  invariant(node.type === REQUEST);
@@ -1286,9 +1377,9 @@ export default class RequestTracker {
1286
1377
  this.graph.replaceSubrequests(requestNodeId, subrequestContextKeys);
1287
1378
  }
1288
1379
 
1289
- async runRequest<TInput, TResult: RequestResult>(
1380
+ async runRequest<TInput, TResult extends RequestResult>(
1290
1381
  request: Request<TInput, TResult>,
1291
- opts?: ?RunRequestOpts,
1382
+ opts?: RunRequestOpts | null,
1292
1383
  ): Promise<TResult> {
1293
1384
  let hasKey = this.graph.hasContentKey(request.id);
1294
1385
  let requestId = hasKey
@@ -1297,7 +1388,7 @@ export default class RequestTracker {
1297
1388
  let hasValidResult = requestId != null && this.hasValidResult(requestId);
1298
1389
 
1299
1390
  if (!opts?.force && hasValidResult) {
1300
- // $FlowFixMe[incompatible-type]
1391
+ // @ts-expect-error TS2322
1301
1392
  return this.getRequestResult<TResult>(request.id);
1302
1393
  }
1303
1394
 
@@ -1307,10 +1398,10 @@ export default class RequestTracker {
1307
1398
  // There is a another instance of this request already running, wait for its completion and reuse its result
1308
1399
  try {
1309
1400
  if (await incompletePromise) {
1310
- // $FlowFixMe[incompatible-type]
1401
+ // @ts-expect-error TS2322
1311
1402
  return this.getRequestResult<TResult>(request.id);
1312
1403
  }
1313
- } catch (e) {
1404
+ } catch (e: any) {
1314
1405
  // Rerun this request
1315
1406
  }
1316
1407
  }
@@ -1344,12 +1435,11 @@ export default class RequestTracker {
1344
1435
  rustAtlaspack: this.rustAtlaspack,
1345
1436
  });
1346
1437
 
1347
- assertSignalNotAborted(this.signal);
1348
1438
  this.completeRequest(requestNodeId);
1349
1439
 
1350
1440
  deferred.resolve(true);
1351
1441
  return result;
1352
- } catch (err) {
1442
+ } catch (err: any) {
1353
1443
  if (
1354
1444
  !(err instanceof BuildAbortError) &&
1355
1445
  request.type === requestTypes.dev_dep_request
@@ -1373,14 +1463,16 @@ export default class RequestTracker {
1373
1463
  }
1374
1464
  }
1375
1465
 
1376
- flushStats(): {[requestType: string]: number} {
1377
- let requestTypeEntries = {};
1466
+ flushStats(): {
1467
+ [requestType: string]: number;
1468
+ } {
1469
+ let requestTypeEntries: Record<string, any> = {};
1378
1470
 
1379
- for (let key of (Object.keys(requestTypes): RequestTypeName[])) {
1471
+ for (let key of Object.keys(requestTypes) as RequestTypeName[]) {
1380
1472
  requestTypeEntries[requestTypes[key]] = key;
1381
1473
  }
1382
1474
 
1383
- let formattedStats = {};
1475
+ let formattedStats: Record<string, any> = {};
1384
1476
 
1385
1477
  for (let [requestType, count] of this.stats.entries()) {
1386
1478
  let requestTypeName = requestTypeEntries[requestType];
@@ -1392,10 +1484,13 @@ export default class RequestTracker {
1392
1484
  return formattedStats;
1393
1485
  }
1394
1486
 
1395
- createAPI<TResult: RequestResult>(
1487
+ createAPI<TResult extends RequestResult>(
1396
1488
  requestId: NodeId,
1397
1489
  previousInvalidations: Array<RequestInvalidation>,
1398
- ): {|api: RunAPI<TResult>, subRequestContentKeys: Set<ContentKey>|} {
1490
+ ): {
1491
+ api: RunAPI<TResult>;
1492
+ subRequestContentKeys: Set<ContentKey>;
1493
+ } {
1399
1494
  let subRequestContentKeys = new Set<ContentKey>();
1400
1495
  let api: RunAPI<TResult> = {
1401
1496
  invalidateOnFileCreate: (input) =>
@@ -1419,6 +1514,7 @@ export default class RequestTracker {
1419
1514
  this.graph.invalidateOnOptionChange(
1420
1515
  requestId,
1421
1516
  option,
1517
+ // @ts-expect-error TS7053
1422
1518
  this.options[option],
1423
1519
  ),
1424
1520
  getInvalidations: () => previousInvalidations,
@@ -1427,12 +1523,16 @@ export default class RequestTracker {
1427
1523
  },
1428
1524
  getSubRequests: () => this.graph.getSubRequests(requestId),
1429
1525
  getInvalidSubRequests: () => this.graph.getInvalidSubRequests(requestId),
1430
- getPreviousResult: <T: RequestResult>(ifMatch?: string): Async<?T> => {
1526
+ getPreviousResult: <T extends RequestResult>(
1527
+ ifMatch?: string,
1528
+ ): Async<T | null | undefined> => {
1431
1529
  let contentKey = nullthrows(this.graph.getNode(requestId)?.id);
1432
1530
  return this.getRequestResult<T>(contentKey, ifMatch);
1433
1531
  },
1434
- getRequestResult: <T: RequestResult>(id): Async<?T> =>
1435
- this.getRequestResult<T>(id),
1532
+ getRequestResult: <T extends RequestResult>(
1533
+ // @ts-expect-error TS7006
1534
+ id,
1535
+ ): Async<T | null | undefined> => this.getRequestResult<T>(id),
1436
1536
  canSkipSubrequest: (contentKey) => {
1437
1537
  if (
1438
1538
  this.graph.hasContentKey(contentKey) &&
@@ -1444,7 +1544,7 @@ export default class RequestTracker {
1444
1544
 
1445
1545
  return false;
1446
1546
  },
1447
- runRequest: <TInput, TResult: RequestResult>(
1547
+ runRequest: <TInput, TResult extends RequestResult>(
1448
1548
  subRequest: Request<TInput, TResult>,
1449
1549
  opts?: RunRequestOpts,
1450
1550
  ): Promise<TResult> => {
@@ -1457,28 +1557,6 @@ export default class RequestTracker {
1457
1557
  }
1458
1558
 
1459
1559
  async writeToCache(signal?: AbortSignal) {
1460
- const options = this.options;
1461
- async function runCacheImprovements<T>(
1462
- newPath: (cache: LMDBLiteCache) => Promise<T>,
1463
- oldPath: () => Promise<T>,
1464
- ): Promise<T> {
1465
- if (getFeatureFlag('cachePerformanceImprovements')) {
1466
- invariant(options.cache instanceof LMDBLiteCache);
1467
- const result = await newPath(options.cache);
1468
- return result;
1469
- } else {
1470
- const result = await oldPath();
1471
- return result;
1472
- }
1473
- }
1474
-
1475
- await runCacheImprovements(
1476
- async (cache) => {
1477
- await cache.getNativeRef().startWriteTransaction();
1478
- },
1479
- () => Promise.resolve(),
1480
- );
1481
-
1482
1560
  let cacheKey = getCacheKey(this.options);
1483
1561
  let requestGraphKey = `requestGraph-${cacheKey}`;
1484
1562
  let snapshotKey = `snapshot-${cacheKey}`;
@@ -1488,114 +1566,111 @@ export default class RequestTracker {
1488
1566
  }
1489
1567
 
1490
1568
  let total = 0;
1491
- report({
1492
- type: 'cache',
1493
- phase: 'start',
1494
- total,
1495
- size: this.graph.nodes.length,
1496
- });
1569
+ try {
1570
+ report({
1571
+ type: 'cache',
1572
+ phase: 'start',
1573
+ total,
1574
+ size: this.graph.nodes.length,
1575
+ });
1497
1576
 
1498
- let serialisedGraph = this.graph.serialize();
1577
+ if (getFeatureFlag('environmentDeduplication')) {
1578
+ await writeEnvironmentsToCache(this.options.cache);
1579
+ }
1499
1580
 
1500
- // Delete an existing request graph cache, to prevent invalid states
1501
- await this.options.cache.deleteLargeBlob(requestGraphKey);
1581
+ let serialisedGraph = this.graph.serialize();
1502
1582
 
1503
- const serialiseAndSet = async (
1504
- key: string,
1505
- // $FlowFixMe serialise input is any type
1506
- contents: any,
1507
- ): Promise<void> => {
1508
- if (signal?.aborted) {
1509
- throw new Error('Serialization was aborted');
1510
- }
1583
+ // Delete an existing request graph cache, to prevent invalid states
1584
+ await this.options.cache.deleteLargeBlob(requestGraphKey);
1511
1585
 
1512
- await runCacheImprovements(
1513
- (cache) => {
1514
- instrument(`cache.put(${key})`, () => {
1515
- cache.getNativeRef().putNoConfirm(key, serialize(contents));
1516
- });
1517
- return Promise.resolve();
1518
- },
1519
- async () => {
1520
- await this.options.cache.setLargeBlob(
1521
- key,
1522
- serialize(contents),
1523
- signal
1524
- ? {
1525
- signal: signal,
1526
- }
1527
- : undefined,
1528
- );
1529
- },
1530
- );
1586
+ const serialiseAndSet = async (
1587
+ key: string,
1588
+ contents: any,
1589
+ ): Promise<void> => {
1590
+ if (signal?.aborted) {
1591
+ throw new Error('Serialization was aborted');
1592
+ }
1531
1593
 
1532
- total += 1;
1594
+ await this.options.cache.setLargeBlob(
1595
+ key,
1596
+ serialize(contents),
1597
+ signal
1598
+ ? {
1599
+ signal: signal,
1600
+ }
1601
+ : undefined,
1602
+ );
1533
1603
 
1534
- report({
1535
- type: 'cache',
1536
- phase: 'write',
1537
- total,
1538
- size: this.graph.nodes.length,
1539
- });
1540
- };
1604
+ total += 1;
1541
1605
 
1542
- let queue = new PromiseQueue({
1543
- maxConcurrent: 32,
1544
- });
1606
+ report({
1607
+ type: 'cache',
1608
+ phase: 'write',
1609
+ total,
1610
+ size: this.graph.nodes.length,
1611
+ });
1612
+ };
1545
1613
 
1546
- // Preallocating a sparse array is faster than pushing when N is high enough
1547
- let cacheableNodes = new Array(serialisedGraph.nodes.length);
1548
- for (let i = 0; i < serialisedGraph.nodes.length; i += 1) {
1549
- let node = serialisedGraph.nodes[i];
1614
+ let queue = new PromiseQueue({
1615
+ maxConcurrent: 32,
1616
+ });
1550
1617
 
1551
- let resultCacheKey = node?.resultCacheKey;
1552
- if (
1553
- node?.type === REQUEST &&
1554
- resultCacheKey != null &&
1555
- node?.result != null
1556
- ) {
1557
- queue.add(() => serialiseAndSet(resultCacheKey, node.result));
1618
+ // Preallocating a sparse array is faster than pushing when N is high enough
1619
+ let cacheableNodes = new Array(serialisedGraph.nodes.length);
1620
+ for (let i = 0; i < serialisedGraph.nodes.length; i += 1) {
1621
+ let node = serialisedGraph.nodes[i];
1558
1622
 
1559
- // eslint-disable-next-line no-unused-vars
1560
- let {result: _, ...newNode} = node;
1561
- cacheableNodes[i] = newNode;
1562
- } else {
1563
- cacheableNodes[i] = node;
1623
+ // @ts-expect-error TS2339
1624
+ let resultCacheKey = node?.resultCacheKey;
1625
+ if (
1626
+ node?.type === REQUEST &&
1627
+ resultCacheKey != null &&
1628
+ node?.result != null
1629
+ ) {
1630
+ queue.add(() => serialiseAndSet(resultCacheKey, node.result));
1631
+
1632
+ // eslint-disable-next-line no-unused-vars
1633
+ let {result: _, ...newNode} = node;
1634
+ cacheableNodes[i] = newNode;
1635
+ } else {
1636
+ cacheableNodes[i] = node;
1637
+ }
1564
1638
  }
1565
- }
1566
1639
 
1567
- let nodeCountsPerBlob = [];
1640
+ let nodeCountsPerBlob: Array<number> = [];
1568
1641
 
1569
- for (
1570
- let i = 0;
1571
- i * this.graph.nodesPerBlob < cacheableNodes.length;
1572
- i += 1
1573
- ) {
1574
- let nodesStartIndex = i * this.graph.nodesPerBlob;
1575
- let nodesEndIndex = Math.min(
1576
- (i + 1) * this.graph.nodesPerBlob,
1577
- cacheableNodes.length,
1578
- );
1642
+ for (
1643
+ let i = 0;
1644
+ i * this.graph.nodesPerBlob < cacheableNodes.length;
1645
+ i += 1
1646
+ ) {
1647
+ let nodesStartIndex = i * this.graph.nodesPerBlob;
1648
+ let nodesEndIndex = Math.min(
1649
+ (i + 1) * this.graph.nodesPerBlob,
1650
+ cacheableNodes.length,
1651
+ );
1579
1652
 
1580
- nodeCountsPerBlob.push(nodesEndIndex - nodesStartIndex);
1653
+ nodeCountsPerBlob.push(nodesEndIndex - nodesStartIndex);
1581
1654
 
1582
- if (!this.graph.hasCachedRequestChunk(i)) {
1583
- // We assume the request graph nodes are immutable and won't change
1584
- let nodesToCache = cacheableNodes.slice(nodesStartIndex, nodesEndIndex);
1655
+ if (!this.graph.hasCachedRequestChunk(i)) {
1656
+ // We assume the request graph nodes are immutable and won't change
1657
+ let nodesToCache = cacheableNodes.slice(
1658
+ nodesStartIndex,
1659
+ nodesEndIndex,
1660
+ );
1585
1661
 
1586
- queue.add(() =>
1587
- serialiseAndSet(
1588
- getRequestGraphNodeKey(i, cacheKey),
1589
- nodesToCache,
1590
- ).then(() => {
1591
- // Succeeded in writing to disk, save that we have completed this chunk
1592
- this.graph.setCachedRequestChunk(i);
1593
- }),
1594
- );
1662
+ queue.add(() =>
1663
+ serialiseAndSet(
1664
+ getRequestGraphNodeKey(i, cacheKey),
1665
+ nodesToCache,
1666
+ ).then(() => {
1667
+ // Succeeded in writing to disk, save that we have completed this chunk
1668
+ this.graph.setCachedRequestChunk(i);
1669
+ }),
1670
+ );
1671
+ }
1595
1672
  }
1596
- }
1597
1673
 
1598
- try {
1599
1674
  await queue.run();
1600
1675
 
1601
1676
  // Set the request graph after the queue is flushed to avoid writing an invalid state
@@ -1605,18 +1680,6 @@ export default class RequestTracker {
1605
1680
  nodes: undefined,
1606
1681
  });
1607
1682
 
1608
- await runCacheImprovements(
1609
- () =>
1610
- serialiseAndSet(`request_tracker:cache_metadata:${cacheKey}`, {
1611
- version: ATLASPACK_VERSION,
1612
- entries: this.options.entries,
1613
- mode: this.options.mode,
1614
- shouldBuildLazily: this.options.shouldBuildLazily,
1615
- watchBackend: this.options.watchBackend,
1616
- }),
1617
- () => Promise.resolve(),
1618
- );
1619
-
1620
1683
  let opts = getWatcherOptions(this.options);
1621
1684
  let snapshotPath = path.join(this.options.cacheDir, snapshotKey + '.txt');
1622
1685
 
@@ -1625,18 +1688,11 @@ export default class RequestTracker {
1625
1688
  snapshotPath,
1626
1689
  opts,
1627
1690
  );
1628
- } catch (err) {
1691
+ } catch (err: any) {
1629
1692
  // If we have aborted, ignore the error and continue
1630
1693
  if (!signal?.aborted) throw err;
1631
1694
  }
1632
1695
 
1633
- await runCacheImprovements(
1634
- async (cache) => {
1635
- await cache.getNativeRef().commitWriteTransaction();
1636
- },
1637
- () => Promise.resolve(),
1638
- );
1639
-
1640
1696
  report({type: 'cache', phase: 'end', total, size: this.graph.nodes.length});
1641
1697
  }
1642
1698
 
@@ -1644,11 +1700,11 @@ export default class RequestTracker {
1644
1700
  farm,
1645
1701
  options,
1646
1702
  rustAtlaspack,
1647
- }: {|
1648
- farm: WorkerFarm,
1649
- options: AtlaspackOptions,
1650
- rustAtlaspack?: AtlaspackV3,
1651
- |}): Async<RequestTracker> {
1703
+ }: {
1704
+ farm: WorkerFarm;
1705
+ options: AtlaspackOptions;
1706
+ rustAtlaspack?: AtlaspackV3;
1707
+ }): Promise<Async<RequestTracker>> {
1652
1708
  let graph = await loadRequestGraph(options);
1653
1709
  return new RequestTracker({farm, graph, options, rustAtlaspack});
1654
1710
  }
@@ -1667,7 +1723,7 @@ export function getWatcherOptions({
1667
1723
  return {ignore, backend: watchBackend};
1668
1724
  }
1669
1725
 
1670
- function getCacheKey(options) {
1726
+ function getCacheKey(options: AtlaspackOptions) {
1671
1727
  return hashString(
1672
1728
  `${ATLASPACK_VERSION}:${JSON.stringify(options.entries)}:${options.mode}:${
1673
1729
  options.shouldBuildLazily ? 'lazy' : 'eager'
@@ -1683,11 +1739,16 @@ export async function readAndDeserializeRequestGraph(
1683
1739
  cache: Cache,
1684
1740
  requestGraphKey: string,
1685
1741
  cacheKey: string,
1686
- ): Async<{|requestGraph: RequestGraph, bufferLength: number|}> {
1742
+ ): Promise<
1743
+ Async<{
1744
+ requestGraph: RequestGraph;
1745
+ bufferLength: number;
1746
+ }>
1747
+ > {
1687
1748
  let bufferLength = 0;
1688
1749
 
1689
1750
  const getAndDeserialize = async (key: string) => {
1690
- let buffer = await cache.getLargeBlob(key);
1751
+ const buffer = await cache.getLargeBlob(key);
1691
1752
  bufferLength += Buffer.byteLength(buffer);
1692
1753
  return deserialize(buffer);
1693
1754
  };
@@ -1695,6 +1756,7 @@ export async function readAndDeserializeRequestGraph(
1695
1756
  let serializedRequestGraph = await getAndDeserialize(requestGraphKey);
1696
1757
 
1697
1758
  let nodePromises = serializedRequestGraph.nodeCountsPerBlob.map(
1759
+ // @ts-expect-error TS7006
1698
1760
  async (nodesCount, i) => {
1699
1761
  let nodes = await getAndDeserialize(getRequestGraphNodeKey(i, cacheKey));
1700
1762
  invariant.equal(
@@ -1716,27 +1778,48 @@ export async function readAndDeserializeRequestGraph(
1716
1778
  };
1717
1779
  }
1718
1780
 
1719
- async function loadRequestGraph(options): Async<RequestGraph> {
1781
+ async function loadRequestGraph(
1782
+ options: AtlaspackOptions,
1783
+ ): Promise<Async<RequestGraph>> {
1720
1784
  if (options.shouldDisableCache) {
1721
1785
  return new RequestGraph();
1722
1786
  }
1723
1787
 
1724
1788
  let cacheKey = getCacheKey(options);
1725
1789
  let requestGraphKey = `requestGraph-${cacheKey}`;
1790
+
1726
1791
  let timeout;
1727
1792
  const snapshotKey = `snapshot-${cacheKey}`;
1728
1793
  const snapshotPath = path.join(options.cacheDir, snapshotKey + '.txt');
1729
1794
 
1795
+ const commonMeta = {
1796
+ cacheKey,
1797
+ snapshotKey,
1798
+ cacheKeyOptions: {
1799
+ version: ATLASPACK_VERSION,
1800
+ entries: options.entries,
1801
+ mode: options.mode,
1802
+ shouldBuildLazily: options.shouldBuildLazily,
1803
+ watchBackend: options.watchBackend,
1804
+ },
1805
+ } as const;
1806
+
1730
1807
  logger.verbose({
1731
1808
  origin: '@atlaspack/core',
1732
1809
  message: 'Loading request graph',
1733
1810
  meta: {
1734
- cacheKey,
1735
- snapshotKey,
1811
+ ...commonMeta,
1736
1812
  },
1737
1813
  });
1738
1814
 
1739
- if (await options.cache.hasLargeBlob(requestGraphKey)) {
1815
+ if (getFeatureFlag('environmentDeduplication')) {
1816
+ await loadEnvironmentsFromCache(options.cache);
1817
+ }
1818
+
1819
+ const hasRequestGraphInCache =
1820
+ await options.cache.hasLargeBlob(requestGraphKey);
1821
+
1822
+ if (hasRequestGraphInCache) {
1740
1823
  try {
1741
1824
  let {requestGraph} = await readAndDeserializeRequestGraph(
1742
1825
  options.cache,
@@ -1767,25 +1850,31 @@ async function loadRequestGraph(options): Async<RequestGraph> {
1767
1850
  origin: '@atlaspack/core',
1768
1851
  message: `File system event count: ${events.length}`,
1769
1852
  meta: {
1853
+ ...commonMeta,
1770
1854
  trackableEvent: 'watcher_events_count',
1771
1855
  watcherEventCount: events.length,
1772
1856
  duration: Date.now() - startTime,
1773
1857
  },
1774
1858
  });
1775
1859
 
1776
- requestGraph.invalidateUnpredictableNodes();
1777
- requestGraph.invalidateOnBuildNodes();
1778
- requestGraph.invalidateEnvNodes(options.env);
1779
- requestGraph.invalidateOptionNodes(options);
1780
-
1781
- await requestGraph.respondToFSEvents(
1782
- options.unstableFileInvalidations || events,
1860
+ const invalidationStats = await invalidateRequestGraph(
1861
+ requestGraph,
1783
1862
  options,
1784
- 10000,
1785
- true,
1863
+ events,
1786
1864
  );
1865
+
1866
+ logger.verbose({
1867
+ origin: '@atlaspack/core',
1868
+ message: 'Request track loaded from cache',
1869
+ meta: {
1870
+ ...commonMeta,
1871
+ trackableEvent: 'request_tracker_cache_key_hit',
1872
+ invalidationStats,
1873
+ },
1874
+ });
1875
+
1787
1876
  return requestGraph;
1788
- } catch (e) {
1877
+ } catch (e: any) {
1789
1878
  // Prevent logging fs events took too long warning
1790
1879
  clearTimeout(timeout);
1791
1880
  logErrorOnBailout(options, snapshotPath, e);
@@ -1800,13 +1889,231 @@ async function loadRequestGraph(options): Async<RequestGraph> {
1800
1889
  message:
1801
1890
  'Cache entry for request tracker was not found, initializing a clean cache.',
1802
1891
  meta: {
1803
- cacheKey,
1804
- snapshotKey,
1892
+ ...commonMeta,
1893
+ trackableEvent: 'request_tracker_cache_key_miss',
1805
1894
  },
1806
1895
  });
1807
1896
  return new RequestGraph();
1808
1897
  }
1809
1898
 
1899
+ /**
1900
+ * A wrapper around an invalidation type / method
1901
+ */
1902
+ type InvalidationFn = {
1903
+ key: string;
1904
+ fn: () =>
1905
+ | InvalidationDetail
1906
+ | Promise<InvalidationDetail>
1907
+ | undefined
1908
+ | Promise<undefined>;
1909
+ };
1910
+
1911
+ type InvalidationStats = {
1912
+ /**
1913
+ * Total number of request graph nodes
1914
+ */
1915
+ nodeCount: number;
1916
+ /**
1917
+ * Number of requests in RequestGraph
1918
+ */
1919
+ requestCount: number;
1920
+ /**
1921
+ * Number of nodes that have been invalidated.
1922
+ */
1923
+ invalidatedCount: number;
1924
+ /**
1925
+ * Percentage of requests that have been invalidated
1926
+ */
1927
+ requestInvalidationRatio: number;
1928
+ /**
1929
+ * Percentage of nodes that have been invalidated
1930
+ */
1931
+ nodeInvalidationRatio: number;
1932
+ /**
1933
+ * Details for each invalidation type
1934
+ */
1935
+ invalidations: InvalidationFnStats[];
1936
+ };
1937
+
1938
+ /**
1939
+ * Details about an invalidation.
1940
+ *
1941
+ * If this is a fs events invalidation, this key will contain statistics about invalidations
1942
+ * by path.
1943
+ *
1944
+ * If this is a env or option invalidation, this key will contain the list of changed environment
1945
+ * variables or options.
1946
+ */
1947
+ type InvalidationDetail = string[] | FSInvalidationStats;
1948
+
1949
+ /**
1950
+ * Number of invalidations for a given file-system event.
1951
+ */
1952
+ type FSInvalidation = {
1953
+ path: string;
1954
+ count: number;
1955
+ };
1956
+
1957
+ type FSInvalidationStats = {
1958
+ /**
1959
+ * This list will be sorted by the number of nodes invalidated and only the top 10 will be
1960
+ * included.
1961
+ */
1962
+ biggestInvalidations: FSInvalidation[];
1963
+ };
1964
+
1965
+ /**
1966
+ * Information about a certain cache invalidation type.
1967
+ */
1968
+ type InvalidationFnStats = {
1969
+ /**
1970
+ * Invalidation type, one of:
1971
+ *
1972
+ * - unpredictable
1973
+ * - onBuild
1974
+ * - env
1975
+ * - option
1976
+ * - fsEvents
1977
+ */
1978
+ key: string;
1979
+ /**
1980
+ * Number of invalidated nodes coming from this invalidation type.
1981
+ */
1982
+ count: number;
1983
+ /**
1984
+ * If this is a env or option invalidation, this key will contain the list of changed values.
1985
+ *
1986
+ * If this is a fs events invalidation, this key will contain statistics about invalidations
1987
+ */
1988
+ detail: null | InvalidationDetail;
1989
+ /**
1990
+ * Time in milliseconds it took to run the invalidation.
1991
+ */
1992
+ duration: number;
1993
+ };
1994
+
1995
+ /**
1996
+ * Respond to unpredictable, build, environment changes, option changes and file-system events
1997
+ * invalidating RequestGraph nodes.
1998
+ *
1999
+ * Returns the count of nodes invalidated by each invalidation type.
2000
+ */
2001
+ export async function invalidateRequestGraph(
2002
+ requestGraph: RequestGraph,
2003
+ options: AtlaspackOptions,
2004
+ events: Event[],
2005
+ ): Promise<InvalidationStats> {
2006
+ const invalidationFns: InvalidationFn[] = [
2007
+ {
2008
+ key: 'unpredictable',
2009
+ // @ts-expect-error TS2322
2010
+ fn: () => requestGraph.invalidateUnpredictableNodes(),
2011
+ },
2012
+ {
2013
+ key: 'onBuild',
2014
+ // @ts-expect-error TS2322
2015
+ fn: () => requestGraph.invalidateOnBuildNodes(),
2016
+ },
2017
+ {
2018
+ key: 'env',
2019
+ fn: () => requestGraph.invalidateEnvNodes(options.env),
2020
+ },
2021
+ {
2022
+ key: 'option',
2023
+ fn: () => requestGraph.invalidateOptionNodes(options),
2024
+ },
2025
+ {
2026
+ key: 'fsEvents',
2027
+ fn: () => invalidateRequestGraphFSEvents(requestGraph, options, events),
2028
+ },
2029
+ ];
2030
+
2031
+ const invalidations: Array<InvalidationFnStats> = [];
2032
+ for (const invalidation of invalidationFns) {
2033
+ invalidations.push(await runInvalidation(requestGraph, invalidation));
2034
+ }
2035
+ const invalidatedCount = invalidations.reduce(
2036
+ (acc, invalidation) => acc + invalidation.count,
2037
+ 0,
2038
+ );
2039
+ const requestCount = requestGraph.nodes.reduce(
2040
+ (acc, node) => acc + (node?.type === REQUEST ? 1 : 0),
2041
+ 0,
2042
+ );
2043
+ const nodeCount = requestGraph.nodes.length;
2044
+ const nodeInvalidationRatio = invalidatedCount / nodeCount;
2045
+ const requestInvalidationRatio = invalidatedCount / requestCount;
2046
+
2047
+ return {
2048
+ invalidations,
2049
+ nodeCount,
2050
+ requestCount,
2051
+ invalidatedCount,
2052
+ nodeInvalidationRatio,
2053
+ requestInvalidationRatio,
2054
+ };
2055
+ }
2056
+
2057
+ interface InvalidateRequestGraphFSEventsInput {
2058
+ respondToFSEvents(
2059
+ events: Event[],
2060
+ options: AtlaspackOptions,
2061
+ timeout: number,
2062
+ shouldLog: boolean,
2063
+ ): Promise<{
2064
+ invalidationsByPath: Map<string, number>;
2065
+ }>;
2066
+ }
2067
+
2068
+ /**
2069
+ * Invalidate the request graph based on file-system events.
2070
+ *
2071
+ * Returns statistics about the invalidations.
2072
+ */
2073
+ export async function invalidateRequestGraphFSEvents(
2074
+ requestGraph: InvalidateRequestGraphFSEventsInput,
2075
+ options: AtlaspackOptions,
2076
+ events: Event[],
2077
+ ): Promise<FSInvalidationStats> {
2078
+ const {invalidationsByPath} = await requestGraph.respondToFSEvents(
2079
+ options.unstableFileInvalidations || events,
2080
+ options,
2081
+ 10000,
2082
+ true,
2083
+ );
2084
+ const biggestInvalidations =
2085
+ getBiggestFSEventsInvalidations(invalidationsByPath);
2086
+
2087
+ return {
2088
+ biggestInvalidations,
2089
+ };
2090
+ }
2091
+
2092
+ interface RunInvalidationInput {
2093
+ getInvalidNodeCount(): number;
2094
+ }
2095
+
2096
+ /**
2097
+ * Runs an invalidation function and reports metrics.
2098
+ */
2099
+ export async function runInvalidation(
2100
+ requestGraph: RunInvalidationInput,
2101
+ invalidationFn: InvalidationFn,
2102
+ ): Promise<InvalidationFnStats> {
2103
+ const start = performance.now();
2104
+ const startInvalidationCount = requestGraph.getInvalidNodeCount();
2105
+ const result = await invalidationFn.fn();
2106
+ const count = requestGraph.getInvalidNodeCount() - startInvalidationCount;
2107
+ const duration = performance.now() - start;
2108
+
2109
+ return {
2110
+ key: invalidationFn.key,
2111
+ count,
2112
+ detail: result ?? null,
2113
+ duration,
2114
+ };
2115
+ }
2116
+
1810
2117
  function logErrorOnBailout(
1811
2118
  options: AtlaspackOptions,
1812
2119
  snapshotPath: string,
@@ -1838,7 +2145,9 @@ function logErrorOnBailout(
1838
2145
  }
1839
2146
  }
1840
2147
 
1841
- export function cleanUpOrphans<N, E: number>(graph: Graph<N, E>): NodeId[] {
2148
+ export function cleanUpOrphans<N, E extends number>(
2149
+ graph: Graph<N, E>,
2150
+ ): NodeId[] {
1842
2151
  if (graph.rootNodeId == null) {
1843
2152
  return [];
1844
2153
  }
@@ -1848,7 +2157,7 @@ export function cleanUpOrphans<N, E: number>(graph: Graph<N, E>): NodeId[] {
1848
2157
  reachableNodes.add(nodeId);
1849
2158
  });
1850
2159
 
1851
- const removedNodeIds = [];
2160
+ const removedNodeIds: Array<NodeId> = [];
1852
2161
  graph.nodes.forEach((_node, nodeId) => {
1853
2162
  if (!reachableNodes.has(nodeId)) {
1854
2163
  removedNodeIds.push(nodeId);
@@ -1858,3 +2167,19 @@ export function cleanUpOrphans<N, E: number>(graph: Graph<N, E>): NodeId[] {
1858
2167
 
1859
2168
  return removedNodeIds;
1860
2169
  }
2170
+
2171
+ /**
2172
+ * Returns paths that invalidated the most nodes
2173
+ */
2174
+ export function getBiggestFSEventsInvalidations(
2175
+ invalidationsByPath: Map<string, number>,
2176
+ limit: number = 10,
2177
+ ): Array<FSInvalidation> {
2178
+ const invalidations: Array<FSInvalidation> = [];
2179
+ for (const [path, count] of invalidationsByPath) {
2180
+ invalidations.push({path, count});
2181
+ }
2182
+ invalidations.sort((a, b) => b.count - a.count);
2183
+
2184
+ return invalidations.slice(0, limit);
2185
+ }