@atlaspack/core 2.16.2-canary.27 → 2.16.2-canary.270

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 (358) hide show
  1. package/CHANGELOG.md +665 -0
  2. package/dist/AssetGraph.js +591 -0
  3. package/dist/Atlaspack.js +658 -0
  4. package/dist/AtlaspackConfig.js +324 -0
  5. package/dist/AtlaspackConfig.schema.js +108 -0
  6. package/dist/BundleGraph.js +1635 -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 +545 -0
  14. package/dist/ReporterRunner.js +151 -0
  15. package/dist/RequestTracker.js +1360 -0
  16. package/dist/SymbolPropagation.js +620 -0
  17. package/dist/TargetDescriptor.schema.js +143 -0
  18. package/dist/Transformation.js +490 -0
  19. package/dist/UncommittedAsset.js +315 -0
  20. package/dist/Validation.js +196 -0
  21. package/dist/applyRuntimes.js +305 -0
  22. package/dist/assetUtils.js +168 -0
  23. package/dist/atlaspack-v3/AtlaspackV3.js +70 -0
  24. package/dist/atlaspack-v3/NapiWorkerPool.js +57 -0
  25. package/dist/atlaspack-v3/fs.js +52 -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 +94 -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 +25 -0
  33. package/dist/atlaspack-v3/worker/compat/mutable-asset.js +152 -0
  34. package/dist/atlaspack-v3/worker/compat/plugin-config.js +76 -0
  35. package/dist/atlaspack-v3/worker/compat/plugin-logger.js +26 -0
  36. package/dist/atlaspack-v3/worker/compat/plugin-options.js +122 -0
  37. package/dist/atlaspack-v3/worker/compat/plugin-tracer.js +10 -0
  38. package/dist/atlaspack-v3/worker/compat/target.js +14 -0
  39. package/dist/atlaspack-v3/worker/worker.js +297 -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 +359 -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 +429 -0
  59. package/dist/requests/AssetGraphRequestRust.js +262 -0
  60. package/dist/requests/AssetRequest.js +130 -0
  61. package/dist/requests/AtlaspackBuildRequest.js +65 -0
  62. package/dist/requests/AtlaspackConfigRequest.js +493 -0
  63. package/dist/requests/BundleGraphRequest.js +445 -0
  64. package/dist/requests/ConfigRequest.js +222 -0
  65. package/dist/requests/DevDepRequest.js +204 -0
  66. package/dist/requests/EntryRequest.js +314 -0
  67. package/dist/requests/PackageRequest.js +62 -0
  68. package/dist/requests/PathRequest.js +349 -0
  69. package/dist/requests/TargetRequest.js +1311 -0
  70. package/dist/requests/ValidationRequest.js +49 -0
  71. package/dist/requests/WriteBundleRequest.js +254 -0
  72. package/dist/requests/WriteBundlesRequest.js +184 -0
  73. package/dist/requests/asset-graph-diff.js +128 -0
  74. package/dist/requests/asset-graph-dot.js +131 -0
  75. package/dist/resolveOptions.js +268 -0
  76. package/dist/rustWorkerThreadDylibHack.js +19 -0
  77. package/dist/serializerCore.browser.js +43 -0
  78. package/dist/summarizeRequest.js +39 -0
  79. package/dist/types.js +31 -0
  80. package/dist/utils.js +172 -0
  81. package/dist/worker.js +123 -0
  82. package/lib/AssetGraph.js +111 -14
  83. package/lib/Atlaspack.js +81 -37
  84. package/lib/AtlaspackConfig.js +15 -3
  85. package/lib/AtlaspackConfig.schema.js +7 -5
  86. package/lib/BundleGraph.js +90 -32
  87. package/lib/CommittedAsset.js +6 -0
  88. package/lib/Dependency.js +8 -2
  89. package/lib/Environment.js +15 -8
  90. package/lib/EnvironmentManager.js +143 -0
  91. package/lib/IdentifierRegistry.js +1 -3
  92. package/lib/InternalConfig.js +3 -2
  93. package/lib/PackagerRunner.js +90 -27
  94. package/lib/ReporterRunner.js +6 -9
  95. package/lib/RequestTracker.js +266 -156
  96. package/lib/SymbolPropagation.js +42 -18
  97. package/lib/TargetDescriptor.schema.js +7 -1
  98. package/lib/Transformation.js +26 -10
  99. package/lib/UncommittedAsset.js +30 -9
  100. package/lib/Validation.js +18 -2
  101. package/lib/applyRuntimes.js +9 -1
  102. package/lib/assetUtils.js +7 -4
  103. package/lib/atlaspack-v3/AtlaspackV3.js +32 -7
  104. package/lib/atlaspack-v3/NapiWorkerPool.js +3 -0
  105. package/lib/atlaspack-v3/fs.js +3 -1
  106. package/lib/atlaspack-v3/index.js +28 -1
  107. package/lib/atlaspack-v3/jsCallable.js +0 -2
  108. package/lib/atlaspack-v3/worker/compat/asset-symbols.js +7 -4
  109. package/lib/atlaspack-v3/worker/compat/bitflags.js +7 -6
  110. package/lib/atlaspack-v3/worker/compat/dependency.js +3 -0
  111. package/lib/atlaspack-v3/worker/compat/environment.js +10 -7
  112. package/lib/atlaspack-v3/worker/compat/mutable-asset.js +14 -9
  113. package/lib/atlaspack-v3/worker/compat/plugin-config.js +8 -10
  114. package/lib/atlaspack-v3/worker/compat/plugin-options.js +1 -0
  115. package/lib/atlaspack-v3/worker/compat/plugin-tracer.js +3 -0
  116. package/lib/atlaspack-v3/worker/compat/target.js +2 -0
  117. package/lib/atlaspack-v3/worker/index.js +3 -0
  118. package/lib/atlaspack-v3/worker/worker.js +43 -7
  119. package/lib/constants.js +0 -1
  120. package/lib/dumpGraphToGraphViz.js +71 -16
  121. package/lib/index.js +45 -1
  122. package/lib/loadDotEnv.js +4 -1
  123. package/lib/projectPath.js +5 -0
  124. package/lib/public/Asset.js +21 -11
  125. package/lib/public/Bundle.js +15 -16
  126. package/lib/public/BundleGraph.js +10 -4
  127. package/lib/public/BundleGroup.js +4 -5
  128. package/lib/public/Config.js +118 -17
  129. package/lib/public/Dependency.js +8 -6
  130. package/lib/public/Environment.js +12 -7
  131. package/lib/public/MutableBundleGraph.js +54 -12
  132. package/lib/public/PluginOptions.js +2 -2
  133. package/lib/public/Symbols.js +11 -11
  134. package/lib/public/Target.js +7 -6
  135. package/lib/registerCoreWithSerializer.js +5 -3
  136. package/lib/requests/AssetGraphRequest.js +42 -5
  137. package/lib/requests/AssetGraphRequestRust.js +126 -62
  138. package/lib/requests/AssetRequest.js +23 -6
  139. package/lib/requests/AtlaspackBuildRequest.js +10 -4
  140. package/lib/requests/AtlaspackConfigRequest.js +27 -16
  141. package/lib/requests/BundleGraphRequest.js +34 -19
  142. package/lib/requests/ConfigRequest.js +28 -4
  143. package/lib/requests/DevDepRequest.js +31 -5
  144. package/lib/requests/EntryRequest.js +2 -0
  145. package/lib/requests/PackageRequest.js +2 -1
  146. package/lib/requests/PathRequest.js +24 -3
  147. package/lib/requests/TargetRequest.js +122 -57
  148. package/lib/requests/ValidationRequest.js +5 -1
  149. package/lib/requests/WriteBundleRequest.js +39 -11
  150. package/lib/requests/WriteBundlesRequest.js +51 -4
  151. package/lib/requests/asset-graph-diff.js +12 -7
  152. package/lib/requests/asset-graph-dot.js +1 -7
  153. package/lib/resolveOptions.js +36 -10
  154. package/lib/rustWorkerThreadDylibHack.js +0 -1
  155. package/lib/types/AssetGraph.d.ts +80 -0
  156. package/lib/types/Atlaspack.d.ts +52 -0
  157. package/lib/types/AtlaspackConfig.d.ts +65 -0
  158. package/lib/types/AtlaspackConfig.schema.d.ts +46 -0
  159. package/lib/types/BundleGraph.d.ts +182 -0
  160. package/lib/types/CommittedAsset.d.ts +23 -0
  161. package/lib/types/Dependency.d.ts +44 -0
  162. package/lib/types/Environment.d.ts +11 -0
  163. package/lib/types/EnvironmentManager.d.ts +37 -0
  164. package/lib/types/IdentifierRegistry.d.ts +6 -0
  165. package/lib/types/InternalConfig.d.ts +24 -0
  166. package/lib/types/PackagerRunner.d.ts +85 -0
  167. package/lib/types/ReporterRunner.d.ts +25 -0
  168. package/lib/types/RequestTracker.d.ts +385 -0
  169. package/lib/types/SymbolPropagation.d.ts +11 -0
  170. package/lib/types/TargetDescriptor.schema.d.ts +5 -0
  171. package/lib/types/Transformation.d.ts +72 -0
  172. package/lib/types/UncommittedAsset.d.ts +61 -0
  173. package/lib/types/Validation.d.ts +37 -0
  174. package/lib/types/applyRuntimes.d.ts +25 -0
  175. package/lib/types/assetUtils.d.ts +42 -0
  176. package/lib/types/atlaspack-v3/AtlaspackV3.d.ts +26 -0
  177. package/lib/types/atlaspack-v3/NapiWorkerPool.d.ts +12 -0
  178. package/lib/types/atlaspack-v3/fs.d.ts +12 -0
  179. package/lib/types/atlaspack-v3/index.d.ts +5 -0
  180. package/lib/types/atlaspack-v3/jsCallable.d.ts +1 -0
  181. package/lib/types/atlaspack-v3/worker/compat/asset-symbols.d.ts +51 -0
  182. package/lib/types/atlaspack-v3/worker/compat/bitflags.d.ts +15 -0
  183. package/lib/types/atlaspack-v3/worker/compat/dependency.d.ts +25 -0
  184. package/lib/types/atlaspack-v3/worker/compat/environment.d.ts +27 -0
  185. package/{src/atlaspack-v3/worker/compat/index.js → lib/types/atlaspack-v3/worker/compat/index.d.ts} +0 -1
  186. package/lib/types/atlaspack-v3/worker/compat/mutable-asset.d.ts +49 -0
  187. package/lib/types/atlaspack-v3/worker/compat/plugin-config.d.ts +37 -0
  188. package/lib/types/atlaspack-v3/worker/compat/plugin-logger.d.ts +9 -0
  189. package/lib/types/atlaspack-v3/worker/compat/plugin-options.d.ts +22 -0
  190. package/lib/types/atlaspack-v3/worker/compat/plugin-tracer.d.ts +5 -0
  191. package/lib/types/atlaspack-v3/worker/compat/target.d.ts +11 -0
  192. package/lib/types/atlaspack-v3/worker/worker.d.ts +60 -0
  193. package/lib/types/constants.d.ts +13 -0
  194. package/lib/types/dumpGraphToGraphViz.d.ts +10 -0
  195. package/lib/types/index.d.ts +8 -0
  196. package/lib/types/loadAtlaspackPlugin.d.ts +8 -0
  197. package/lib/types/loadDotEnv.d.ts +3 -0
  198. package/lib/types/projectPath.d.ts +19 -0
  199. package/lib/types/public/Asset.d.ts +74 -0
  200. package/lib/types/public/Bundle.d.ts +45 -0
  201. package/lib/types/public/BundleGraph.d.ts +70 -0
  202. package/lib/types/public/BundleGroup.d.ts +12 -0
  203. package/lib/types/public/Config.d.ts +75 -0
  204. package/lib/types/public/Dependency.d.ts +32 -0
  205. package/lib/types/public/Environment.d.ts +34 -0
  206. package/lib/types/public/MutableBundleGraph.d.ts +26 -0
  207. package/lib/types/public/PluginOptions.d.ts +25 -0
  208. package/lib/types/public/Symbols.d.ts +81 -0
  209. package/lib/types/public/Target.d.ts +16 -0
  210. package/lib/types/registerCoreWithSerializer.d.ts +2 -0
  211. package/lib/types/requests/AssetGraphRequest.d.ts +74 -0
  212. package/lib/types/requests/AssetGraphRequestRust.d.ts +21 -0
  213. package/lib/types/requests/AssetRequest.d.ts +16 -0
  214. package/lib/types/requests/AtlaspackBuildRequest.d.ts +33 -0
  215. package/lib/types/requests/AtlaspackConfigRequest.d.ts +45 -0
  216. package/lib/types/requests/BundleGraphRequest.d.ts +28 -0
  217. package/lib/types/requests/ConfigRequest.d.ts +59 -0
  218. package/lib/types/requests/DevDepRequest.d.ts +30 -0
  219. package/lib/types/requests/EntryRequest.d.ts +36 -0
  220. package/lib/types/requests/PackageRequest.d.ts +27 -0
  221. package/lib/types/requests/PathRequest.d.ts +48 -0
  222. package/lib/types/requests/TargetRequest.d.ts +48 -0
  223. package/lib/types/requests/ValidationRequest.d.ts +20 -0
  224. package/lib/types/requests/WriteBundleRequest.d.ts +28 -0
  225. package/lib/types/requests/WriteBundlesRequest.d.ts +32 -0
  226. package/lib/types/requests/asset-graph-diff.d.ts +1 -0
  227. package/lib/types/requests/asset-graph-dot.d.ts +9 -0
  228. package/lib/types/resolveOptions.d.ts +3 -0
  229. package/lib/types/rustWorkerThreadDylibHack.d.ts +9 -0
  230. package/lib/types/serializerCore.browser.d.ts +3 -0
  231. package/lib/types/summarizeRequest.d.ts +10 -0
  232. package/lib/types/types.d.ts +493 -0
  233. package/lib/types/utils.d.ts +23 -0
  234. package/lib/types/worker.d.ts +44 -0
  235. package/lib/types.js +8 -1
  236. package/lib/utils.js +17 -2
  237. package/lib/worker.js +29 -13
  238. package/package.json +24 -34
  239. package/src/{AssetGraph.js → AssetGraph.ts} +156 -52
  240. package/src/{Atlaspack.js → Atlaspack.ts} +114 -61
  241. package/src/{AtlaspackConfig.schema.js → AtlaspackConfig.schema.ts} +16 -19
  242. package/src/{AtlaspackConfig.js → AtlaspackConfig.ts} +78 -54
  243. package/src/{BundleGraph.js → BundleGraph.ts} +231 -140
  244. package/src/{CommittedAsset.js → CommittedAsset.ts} +14 -12
  245. package/src/{Dependency.js → Dependency.ts} +59 -42
  246. package/src/{Environment.js → Environment.ts} +24 -15
  247. package/src/EnvironmentManager.ts +154 -0
  248. package/src/{IdentifierRegistry.js → IdentifierRegistry.ts} +1 -4
  249. package/src/{InternalConfig.js → InternalConfig.ts} +22 -23
  250. package/src/{PackagerRunner.js → PackagerRunner.ts} +178 -86
  251. package/src/{ReporterRunner.js → ReporterRunner.ts} +13 -18
  252. package/src/{RequestTracker.js → RequestTracker.ts} +572 -357
  253. package/src/{SymbolPropagation.js → SymbolPropagation.ts} +165 -57
  254. package/src/{TargetDescriptor.schema.js → TargetDescriptor.schema.ts} +7 -1
  255. package/src/{Transformation.js → Transformation.ts} +71 -62
  256. package/src/{UncommittedAsset.js → UncommittedAsset.ts} +57 -36
  257. package/src/{Validation.js → Validation.ts} +32 -17
  258. package/src/{applyRuntimes.js → applyRuntimes.ts} +35 -26
  259. package/src/{assetUtils.js → assetUtils.ts} +47 -35
  260. package/src/atlaspack-v3/AtlaspackV3.ts +122 -0
  261. package/src/atlaspack-v3/{NapiWorkerPool.js → NapiWorkerPool.ts} +10 -5
  262. package/src/atlaspack-v3/{fs.js → fs.ts} +3 -4
  263. package/src/atlaspack-v3/{index.js → index.ts} +2 -4
  264. package/src/atlaspack-v3/jsCallable.ts +14 -0
  265. package/src/atlaspack-v3/worker/compat/{asset-symbols.js → asset-symbols.ts} +40 -30
  266. package/src/atlaspack-v3/worker/compat/{bitflags.js → bitflags.ts} +9 -10
  267. package/src/atlaspack-v3/worker/compat/{dependency.js → dependency.ts} +12 -12
  268. package/src/atlaspack-v3/worker/compat/{environment.js → environment.ts} +13 -9
  269. package/src/atlaspack-v3/worker/compat/index.ts +9 -0
  270. package/src/atlaspack-v3/worker/compat/{mutable-asset.js → mutable-asset.ts} +20 -19
  271. package/src/atlaspack-v3/worker/compat/{plugin-config.js → plugin-config.ts} +27 -26
  272. package/src/atlaspack-v3/worker/compat/{plugin-logger.js → plugin-logger.ts} +0 -2
  273. package/src/atlaspack-v3/worker/compat/{plugin-options.js → plugin-options.ts} +4 -5
  274. package/src/atlaspack-v3/worker/compat/{plugin-tracer.js → plugin-tracer.ts} +2 -2
  275. package/src/atlaspack-v3/worker/compat/{target.js → target.ts} +3 -4
  276. package/src/atlaspack-v3/worker/index.js +2 -1
  277. package/src/atlaspack-v3/worker/{worker.js → worker.ts} +102 -66
  278. package/src/{constants.js → constants.ts} +0 -3
  279. package/src/{dumpGraphToGraphViz.js → dumpGraphToGraphViz.ts} +73 -28
  280. package/src/index.ts +18 -0
  281. package/src/{loadAtlaspackPlugin.js → loadAtlaspackPlugin.ts} +8 -9
  282. package/src/{loadDotEnv.js → loadDotEnv.ts} +2 -2
  283. package/src/{projectPath.js → projectPath.ts} +20 -9
  284. package/src/public/{Asset.js → Asset.ts} +40 -27
  285. package/src/public/{Bundle.js → Bundle.ts} +28 -29
  286. package/src/public/{BundleGraph.js → BundleGraph.ts} +81 -50
  287. package/src/public/{BundleGroup.js → BundleGroup.ts} +7 -10
  288. package/src/public/{Config.js → Config.ts} +171 -33
  289. package/src/public/{Dependency.js → Dependency.ts} +20 -17
  290. package/src/public/{Environment.js → Environment.ts} +28 -17
  291. package/src/public/{MutableBundleGraph.js → MutableBundleGraph.ts} +55 -24
  292. package/src/public/{PluginOptions.js → PluginOptions.ts} +6 -6
  293. package/src/public/{Symbols.js → Symbols.ts} +75 -36
  294. package/src/public/{Target.js → Target.ts} +10 -8
  295. package/src/{registerCoreWithSerializer.js → registerCoreWithSerializer.ts} +9 -7
  296. package/src/requests/{AssetGraphRequest.js → AssetGraphRequest.ts} +84 -49
  297. package/src/requests/AssetGraphRequestRust.ts +352 -0
  298. package/src/requests/{AssetRequest.js → AssetRequest.ts} +24 -18
  299. package/src/requests/{AtlaspackBuildRequest.js → AtlaspackBuildRequest.ts} +46 -32
  300. package/src/requests/{AtlaspackConfigRequest.js → AtlaspackConfigRequest.ts} +72 -58
  301. package/src/requests/{BundleGraphRequest.js → BundleGraphRequest.ts} +71 -58
  302. package/src/requests/{ConfigRequest.js → ConfigRequest.ts} +71 -50
  303. package/src/requests/{DevDepRequest.js → DevDepRequest.ts} +60 -35
  304. package/src/requests/{EntryRequest.js → EntryRequest.ts} +36 -31
  305. package/src/requests/{PackageRequest.js → PackageRequest.ts} +20 -22
  306. package/src/requests/{PathRequest.js → PathRequest.ts} +47 -37
  307. package/src/requests/{TargetRequest.js → TargetRequest.ts} +260 -179
  308. package/src/requests/{ValidationRequest.js → ValidationRequest.ts} +18 -17
  309. package/src/requests/{WriteBundleRequest.js → WriteBundleRequest.ts} +77 -49
  310. package/src/requests/{WriteBundlesRequest.js → WriteBundlesRequest.ts} +109 -37
  311. package/src/requests/{asset-graph-diff.js → asset-graph-diff.ts} +25 -21
  312. package/src/requests/{asset-graph-dot.js → asset-graph-dot.ts} +8 -12
  313. package/src/{resolveOptions.js → resolveOptions.ts} +56 -24
  314. package/src/{rustWorkerThreadDylibHack.js → rustWorkerThreadDylibHack.ts} +1 -4
  315. package/src/{serializerCore.browser.js → serializerCore.browser.ts} +2 -3
  316. package/src/{summarizeRequest.js → summarizeRequest.ts} +17 -5
  317. package/src/types.ts +647 -0
  318. package/src/{utils.js → utils.ts} +52 -21
  319. package/src/{worker.js → worker.ts} +49 -41
  320. package/test/{AssetGraph.test.js → AssetGraph.test.ts} +37 -8
  321. package/test/{Atlaspack.test.js → Atlaspack.test.ts} +5 -10
  322. package/test/{AtlaspackConfig.test.js → AtlaspackConfig.test.ts} +0 -5
  323. package/test/{AtlaspackConfigRequest.test.js → AtlaspackConfigRequest.test.ts} +75 -15
  324. package/test/{BundleGraph.test.js → BundleGraph.test.ts} +8 -13
  325. package/test/{Dependency.test.js → Dependency.test.ts} +2 -3
  326. package/test/{EntryRequest.test.js → EntryRequest.test.ts} +1 -6
  327. package/test/Environment.test.ts +153 -0
  328. package/test/EnvironmentManager.test.ts +188 -0
  329. package/test/{IdentifierRegistry.test.js → IdentifierRegistry.test.ts} +2 -4
  330. package/test/{InternalAsset.test.js → InternalAsset.test.ts} +2 -7
  331. package/test/PackagerRunner.test.ts +0 -0
  332. package/test/{PublicAsset.test.js → PublicAsset.test.ts} +2 -7
  333. package/test/{PublicBundle.test.js → PublicBundle.test.ts} +1 -2
  334. package/test/{PublicDependency.test.js → PublicDependency.test.ts} +0 -2
  335. package/test/PublicEnvironment.test.ts +49 -0
  336. package/test/{PublicMutableBundleGraph.test.js → PublicMutableBundleGraph.test.ts} +6 -11
  337. package/test/{RequestTracker.test.js → RequestTracker.test.ts} +314 -59
  338. package/test/{SymbolPropagation.test.js → SymbolPropagation.test.ts} +124 -74
  339. package/test/{TargetRequest.test.js → TargetRequest.test.ts} +66 -92
  340. package/test/fixtures/config-with-reporters/.parcelrc +7 -0
  341. package/test/fixtures/custom-targets/package.json +6 -0
  342. package/test/public/Config.test.ts +104 -0
  343. package/test/requests/{AssetGraphRequestRust.test.js → AssetGraphRequestRust.test.ts} +164 -134
  344. package/test/requests/{ConfigRequest.test.js → ConfigRequest.test.ts} +202 -13
  345. package/test/requests/{DevDepRequest.test.js → DevDepRequest.test.ts} +0 -2
  346. package/test/{test-utils.js → test-utils.ts} +4 -11
  347. package/test/{utils.test.js → utils.test.ts} +1 -3
  348. package/tsconfig.json +57 -0
  349. package/tsconfig.tsbuildinfo +1 -0
  350. package/index.d.ts +0 -30
  351. package/src/atlaspack-v3/AtlaspackV3.js +0 -87
  352. package/src/atlaspack-v3/jsCallable.js +0 -18
  353. package/src/index.js +0 -13
  354. package/src/requests/AssetGraphRequestRust.js +0 -263
  355. package/src/types.js +0 -600
  356. package/test/Environment.test.js +0 -119
  357. package/test/PackagerRunner.test.js +0 -27
  358. package/test/PublicEnvironment.test.js +0 -27
@@ -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 {LMDBLiteCache, Cache} from '@atlaspack/cache';
8
6
  import {getFeatureFlag} from '@atlaspack/feature-flags';
9
7
  import {ContentGraph} from '@atlaspack/graph';
10
8
  import type {
@@ -18,7 +16,7 @@ import logger, {instrument} 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));
@@ -474,7 +499,7 @@ export class RequestGraph extends ContentGraph<
474
499
  * Nodes invalidated by environment changes, corresponds to `env: ...` inputs.
475
500
  */
476
501
  invalidateEnvNodes(env: EnvMap): string[] {
477
- const invalidatedKeys = [];
502
+ const invalidatedKeys: Array<string> = [];
478
503
 
479
504
  for (let nodeId of this.envNodeIds) {
480
505
  let node = nullthrows(this.getNode(nodeId));
@@ -501,13 +526,14 @@ export class RequestGraph extends ContentGraph<
501
526
  * Nodes invalidated by option changes.
502
527
  */
503
528
  invalidateOptionNodes(options: AtlaspackOptions): string[] {
504
- const invalidatedKeys = [];
529
+ const invalidatedKeys: Array<string> = [];
505
530
 
506
531
  for (let nodeId of this.optionNodeIds) {
507
532
  let node = nullthrows(this.getNode(nodeId));
508
533
  invariant(node.type === OPTION);
509
534
  const key = keyFromOptionContentKey(node.id);
510
535
 
536
+ // @ts-expect-error TS7053
511
537
  if (hashFromOption(options[key]) !== node.hash) {
512
538
  invalidatedKeys.push(key);
513
539
  let parentNodes = this.getNodeIdsConnectedTo(
@@ -526,7 +552,7 @@ export class RequestGraph extends ContentGraph<
526
552
  invalidateOnConfigKeyChange(
527
553
  requestNodeId: NodeId,
528
554
  filePath: ProjectPath,
529
- configKey: string,
555
+ configKey: string[],
530
556
  contentHash: string,
531
557
  ) {
532
558
  let configKeyNodeId = this.addNode(
@@ -598,9 +624,13 @@ export class RequestGraph extends ContentGraph<
598
624
  input: InternalFileCreateInvalidation,
599
625
  ) {
600
626
  let node;
627
+ // @ts-expect-error TS2339
601
628
  if (input.glob != null) {
629
+ // @ts-expect-error TS2339
602
630
  node = nodeFromGlob(input.glob);
631
+ // @ts-expect-error TS2339
603
632
  } else if (input.fileName != null && input.aboveFilePath != null) {
633
+ // @ts-expect-error TS2339
604
634
  let aboveFilePath = input.aboveFilePath;
605
635
 
606
636
  // Create nodes and edges for each part of the filename pattern.
@@ -608,6 +638,7 @@ export class RequestGraph extends ContentGraph<
608
638
  // This creates a sort of trie structure within the graph that can be
609
639
  // quickly matched by following the edges. This is also memory efficient
610
640
  // since common sub-paths (e.g. 'node_modules') are deduplicated.
641
+ // @ts-expect-error TS2339
611
642
  let parts = input.fileName.split('/').reverse();
612
643
  let lastNodeId;
613
644
  for (let part of parts) {
@@ -676,7 +707,9 @@ export class RequestGraph extends ContentGraph<
676
707
  requestGraphEdgeTypes.invalidated_by_create_above,
677
708
  );
678
709
  }
710
+ // @ts-expect-error TS2339
679
711
  } else if (input.filePath != null) {
712
+ // @ts-expect-error TS2339
680
713
  node = nodeFromFilePath(input.filePath);
681
714
  } else {
682
715
  throw new Error('Invalid invalidation');
@@ -708,13 +741,9 @@ export class RequestGraph extends ContentGraph<
708
741
  this.invalidateOnBuildNodeIds.add(requestNodeId);
709
742
  }
710
743
 
711
- invalidateOnEnvChange(
712
- requestNodeId: NodeId,
713
- env: string,
714
- value: string | void,
715
- ) {
716
- let envNode = nodeFromEnv(env, value);
717
- 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);
718
747
 
719
748
  if (
720
749
  !this.hasEdge(
@@ -734,7 +763,7 @@ export class RequestGraph extends ContentGraph<
734
763
  invalidateOnOptionChange(
735
764
  requestNodeId: NodeId,
736
765
  option: string,
737
- value: mixed,
766
+ value: unknown,
738
767
  ) {
739
768
  let optionNode = nodeFromOption(option, value);
740
769
  let optionNodeId = this.addNode(optionNode);
@@ -787,6 +816,7 @@ export class RequestGraph extends ContentGraph<
787
816
  requestNodeId,
788
817
  requestGraphEdgeTypes.invalidated_by_update,
789
818
  );
819
+ // @ts-expect-error TS2322
790
820
  return invalidations
791
821
  .map((nodeId) => {
792
822
  let node = nullthrows(this.getNode(nodeId));
@@ -845,7 +875,7 @@ export class RequestGraph extends ContentGraph<
845
875
  node: FileNameNode,
846
876
  filePath: ProjectPath,
847
877
  matchNodes: Array<FileNode>,
848
- invalidateNode: (NodeId, InvalidateReason) => void,
878
+ invalidateNode: (arg1: NodeId, arg2: InvalidateReason) => void,
849
879
  ) {
850
880
  // If there is an edge between this file_name node and one of the original file nodes pointed to
851
881
  // by the original file_name node, and the matched node is inside the current directory, invalidate
@@ -934,7 +964,10 @@ export class RequestGraph extends ContentGraph<
934
964
  * True if this is the start-up (loading phase) invalidation.
935
965
  */
936
966
  isInitialBuild: boolean = false,
937
- ): Async<boolean> {
967
+ ): Promise<{
968
+ didInvalidate: boolean;
969
+ invalidationsByPath: Map<string, number>;
970
+ }> {
938
971
  let didInvalidate = false;
939
972
  let count = 0;
940
973
  let predictedTime = 0;
@@ -943,7 +976,10 @@ export class RequestGraph extends ContentGraph<
943
976
  const removeOrphans = !enableOptimization;
944
977
 
945
978
  const invalidatedNodes = new Set();
946
- const invalidateNode = (nodeId, reason) => {
979
+ const invalidateNode = (
980
+ nodeId: NodeId,
981
+ reason: InvalidateReason | number,
982
+ ) => {
947
983
  if (enableOptimization && invalidatedNodes.has(nodeId)) {
948
984
  return;
949
985
  }
@@ -951,13 +987,13 @@ export class RequestGraph extends ContentGraph<
951
987
  this.invalidateNode(nodeId, reason);
952
988
  };
953
989
  const aboveCache = new Map();
954
- const getAbove = (fileNameNodeId) => {
990
+ const getAbove = (fileNameNodeId: NodeId) => {
955
991
  const cachedResult = aboveCache.get(fileNameNodeId);
956
992
  if (enableOptimization && cachedResult) {
957
993
  return cachedResult;
958
994
  }
959
995
 
960
- let above = [];
996
+ let above: Array<FileNode> = [];
961
997
  const children = this.getNodeIdsConnectedTo(
962
998
  fileNameNodeId,
963
999
  requestGraphEdgeTypes.invalidated_by_create_above,
@@ -972,7 +1008,10 @@ export class RequestGraph extends ContentGraph<
972
1008
  return above;
973
1009
  };
974
1010
 
1011
+ const invalidationsByPath = new Map();
975
1012
  for (let {path: _path, type} of events) {
1013
+ const invalidationsBefore = this.getInvalidNodeCount();
1014
+
976
1015
  if (
977
1016
  !enableOptimization &&
978
1017
  process.env.ATLASPACK_DISABLE_CACHE_TIMEOUT !== 'true' &&
@@ -1018,7 +1057,10 @@ export class RequestGraph extends ContentGraph<
1018
1057
  this.invalidNodeIds.add(id);
1019
1058
  }
1020
1059
  }
1021
- return true;
1060
+ return {
1061
+ didInvalidate: true,
1062
+ invalidationsByPath: new Map(),
1063
+ };
1022
1064
  }
1023
1065
 
1024
1066
  // sometimes mac os reports update events as create events.
@@ -1099,11 +1141,18 @@ export class RequestGraph extends ContentGraph<
1099
1141
  }
1100
1142
 
1101
1143
  let configKeyNodes = this.configKeyNodes.get(_filePath);
1102
- 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) {
1103
1152
  for (let nodeId of configKeyNodes) {
1104
1153
  let isInvalid = type === 'delete';
1105
1154
 
1106
- if (type === 'update') {
1155
+ if (type !== 'delete') {
1107
1156
  let node = this.getNode(nodeId);
1108
1157
  invariant(node && node.type === CONFIG_KEY);
1109
1158
 
@@ -1131,6 +1180,13 @@ export class RequestGraph extends ContentGraph<
1131
1180
  }
1132
1181
  }
1133
1182
  }
1183
+
1184
+ const invalidationsAfter = this.getInvalidNodeCount();
1185
+ const invalidationsForEvent = invalidationsAfter - invalidationsBefore;
1186
+ invalidationsByPath.set(
1187
+ _path,
1188
+ (invalidationsByPath.get(_path) ?? 0) + invalidationsForEvent,
1189
+ );
1134
1190
  }
1135
1191
 
1136
1192
  if (getFeatureFlag('fixQuadraticCacheInvalidation')) {
@@ -1151,7 +1207,10 @@ export class RequestGraph extends ContentGraph<
1151
1207
  },
1152
1208
  });
1153
1209
 
1154
- return didInvalidate && this.invalidNodeIds.size > 0;
1210
+ return {
1211
+ didInvalidate,
1212
+ invalidationsByPath,
1213
+ };
1155
1214
  }
1156
1215
 
1157
1216
  hasCachedRequestChunk(index: number): boolean {
@@ -1165,14 +1224,20 @@ export class RequestGraph extends ContentGraph<
1165
1224
  removeCachedRequestChunkForNode(nodeId: number): void {
1166
1225
  this.cachedRequestChunks.delete(Math.floor(nodeId / this.nodesPerBlob));
1167
1226
  }
1227
+
1228
+ /**
1229
+ * Returns the number of invalidated nodes in the graph.
1230
+ */
1231
+ getInvalidNodeCount(): number {
1232
+ return this.invalidNodeIds.size;
1233
+ }
1168
1234
  }
1169
1235
 
1170
1236
  export default class RequestTracker {
1171
1237
  graph: RequestGraph;
1172
1238
  farm: WorkerFarm;
1173
1239
  options: AtlaspackOptions;
1174
- rustAtlaspack: ?AtlaspackV3;
1175
- signal: ?AbortSignal;
1240
+ rustAtlaspack: AtlaspackV3 | null | undefined;
1176
1241
  stats: Map<RequestType, number> = new Map();
1177
1242
 
1178
1243
  constructor({
@@ -1180,27 +1245,22 @@ export default class RequestTracker {
1180
1245
  farm,
1181
1246
  options,
1182
1247
  rustAtlaspack,
1183
- }: {|
1184
- graph?: RequestGraph,
1185
- farm: WorkerFarm,
1186
- options: AtlaspackOptions,
1187
- rustAtlaspack?: AtlaspackV3,
1188
- |}) {
1248
+ }: {
1249
+ graph?: RequestGraph;
1250
+ farm: WorkerFarm;
1251
+ options: AtlaspackOptions;
1252
+ rustAtlaspack?: AtlaspackV3;
1253
+ }) {
1189
1254
  this.graph = graph || new RequestGraph();
1190
1255
  this.farm = farm;
1191
1256
  this.options = options;
1192
1257
  this.rustAtlaspack = rustAtlaspack;
1193
1258
  }
1194
1259
 
1195
- // TODO: refactor (abortcontroller should be created by RequestTracker)
1196
- setSignal(signal?: AbortSignal) {
1197
- this.signal = signal;
1198
- }
1199
-
1200
- startRequest(request: RequestNode): {|
1201
- requestNodeId: NodeId,
1202
- deferred: Deferred<boolean>,
1203
- |} {
1260
+ startRequest(request: RequestNode): {
1261
+ requestNodeId: NodeId;
1262
+ deferred: Deferred<boolean>;
1263
+ } {
1204
1264
  let didPreviouslyExist = this.graph.hasContentKey(request.id);
1205
1265
  let requestNodeId;
1206
1266
  if (didPreviouslyExist) {
@@ -1216,13 +1276,14 @@ export default class RequestTracker {
1216
1276
  this.graph.invalidNodeIds.delete(requestNodeId);
1217
1277
 
1218
1278
  let {promise, deferred} = makeDeferredWithPromise();
1279
+ // @ts-expect-error TS2345
1219
1280
  this.graph.incompleteNodePromises.set(requestNodeId, promise);
1220
1281
 
1221
1282
  return {requestNodeId, deferred};
1222
1283
  }
1223
1284
 
1224
1285
  // If a cache key is provided, the result will be removed from the node and stored in a separate cache entry
1225
- storeResult(nodeId: NodeId, result: RequestResult, cacheKey: ?string) {
1286
+ storeResult(nodeId: NodeId, result: RequestResult, cacheKey?: string | null) {
1226
1287
  let node = this.graph.getNode(nodeId);
1227
1288
  if (node && node.type === REQUEST) {
1228
1289
  node.result = result;
@@ -1238,10 +1299,10 @@ export default class RequestTracker {
1238
1299
  );
1239
1300
  }
1240
1301
 
1241
- async getRequestResult<T: RequestResult>(
1302
+ async getRequestResult<T extends RequestResult>(
1242
1303
  contentKey: ContentKey,
1243
1304
  ifMatch?: string,
1244
- ): Promise<?T> {
1305
+ ): Promise<T | null | undefined> {
1245
1306
  let node = nullthrows(this.graph.getNodeByContentKey(contentKey));
1246
1307
  invariant(node.type === REQUEST);
1247
1308
 
@@ -1250,8 +1311,7 @@ export default class RequestTracker {
1250
1311
  }
1251
1312
 
1252
1313
  if (node.result != undefined) {
1253
- // $FlowFixMe
1254
- let result: T = (node.result: any);
1314
+ let result: T = node.result as any;
1255
1315
  return result;
1256
1316
  } else if (node.resultCacheKey != null && ifMatch == null) {
1257
1317
  let key = node.resultCacheKey;
@@ -1288,7 +1348,13 @@ export default class RequestTracker {
1288
1348
  }
1289
1349
  }
1290
1350
 
1291
- respondToFSEvents(events: Array<Event>, threshold: number): Async<boolean> {
1351
+ respondToFSEvents(
1352
+ events: Array<Event>,
1353
+ threshold: number,
1354
+ ): Promise<{
1355
+ didInvalidate: boolean;
1356
+ invalidationsByPath: Map<string, number>;
1357
+ }> {
1292
1358
  return this.graph.respondToFSEvents(events, this.options, threshold);
1293
1359
  }
1294
1360
 
@@ -1297,7 +1363,7 @@ export default class RequestTracker {
1297
1363
  }
1298
1364
 
1299
1365
  getInvalidRequests(): Array<RequestNode> {
1300
- let invalidRequests = [];
1366
+ let invalidRequests: Array<RequestNode> = [];
1301
1367
  for (let id of this.graph.invalidNodeIds) {
1302
1368
  let node = nullthrows(this.graph.getNode(id));
1303
1369
  invariant(node.type === REQUEST);
@@ -1313,9 +1379,9 @@ export default class RequestTracker {
1313
1379
  this.graph.replaceSubrequests(requestNodeId, subrequestContextKeys);
1314
1380
  }
1315
1381
 
1316
- async runRequest<TInput, TResult: RequestResult>(
1382
+ async runRequest<TInput, TResult extends RequestResult>(
1317
1383
  request: Request<TInput, TResult>,
1318
- opts?: ?RunRequestOpts,
1384
+ opts?: RunRequestOpts | null,
1319
1385
  ): Promise<TResult> {
1320
1386
  let hasKey = this.graph.hasContentKey(request.id);
1321
1387
  let requestId = hasKey
@@ -1324,7 +1390,7 @@ export default class RequestTracker {
1324
1390
  let hasValidResult = requestId != null && this.hasValidResult(requestId);
1325
1391
 
1326
1392
  if (!opts?.force && hasValidResult) {
1327
- // $FlowFixMe[incompatible-type]
1393
+ // @ts-expect-error TS2322
1328
1394
  return this.getRequestResult<TResult>(request.id);
1329
1395
  }
1330
1396
 
@@ -1334,10 +1400,10 @@ export default class RequestTracker {
1334
1400
  // There is a another instance of this request already running, wait for its completion and reuse its result
1335
1401
  try {
1336
1402
  if (await incompletePromise) {
1337
- // $FlowFixMe[incompatible-type]
1403
+ // @ts-expect-error TS2322
1338
1404
  return this.getRequestResult<TResult>(request.id);
1339
1405
  }
1340
- } catch (e) {
1406
+ } catch (e: any) {
1341
1407
  // Rerun this request
1342
1408
  }
1343
1409
  }
@@ -1371,12 +1437,11 @@ export default class RequestTracker {
1371
1437
  rustAtlaspack: this.rustAtlaspack,
1372
1438
  });
1373
1439
 
1374
- assertSignalNotAborted(this.signal);
1375
1440
  this.completeRequest(requestNodeId);
1376
1441
 
1377
1442
  deferred.resolve(true);
1378
1443
  return result;
1379
- } catch (err) {
1444
+ } catch (err: any) {
1380
1445
  if (
1381
1446
  !(err instanceof BuildAbortError) &&
1382
1447
  request.type === requestTypes.dev_dep_request
@@ -1400,14 +1465,16 @@ export default class RequestTracker {
1400
1465
  }
1401
1466
  }
1402
1467
 
1403
- flushStats(): {[requestType: string]: number} {
1404
- let requestTypeEntries = {};
1468
+ flushStats(): {
1469
+ [requestType: string]: number;
1470
+ } {
1471
+ let requestTypeEntries: Record<string, any> = {};
1405
1472
 
1406
- for (let key of (Object.keys(requestTypes): RequestTypeName[])) {
1473
+ for (let key of Object.keys(requestTypes) as RequestTypeName[]) {
1407
1474
  requestTypeEntries[requestTypes[key]] = key;
1408
1475
  }
1409
1476
 
1410
- let formattedStats = {};
1477
+ let formattedStats: Record<string, any> = {};
1411
1478
 
1412
1479
  for (let [requestType, count] of this.stats.entries()) {
1413
1480
  let requestTypeName = requestTypeEntries[requestType];
@@ -1419,10 +1486,13 @@ export default class RequestTracker {
1419
1486
  return formattedStats;
1420
1487
  }
1421
1488
 
1422
- createAPI<TResult: RequestResult>(
1489
+ createAPI<TResult extends RequestResult>(
1423
1490
  requestId: NodeId,
1424
1491
  previousInvalidations: Array<RequestInvalidation>,
1425
- ): {|api: RunAPI<TResult>, subRequestContentKeys: Set<ContentKey>|} {
1492
+ ): {
1493
+ api: RunAPI<TResult>;
1494
+ subRequestContentKeys: Set<ContentKey>;
1495
+ } {
1426
1496
  let subRequestContentKeys = new Set<ContentKey>();
1427
1497
  let api: RunAPI<TResult> = {
1428
1498
  invalidateOnFileCreate: (input) =>
@@ -1446,6 +1516,7 @@ export default class RequestTracker {
1446
1516
  this.graph.invalidateOnOptionChange(
1447
1517
  requestId,
1448
1518
  option,
1519
+ // @ts-expect-error TS7053
1449
1520
  this.options[option],
1450
1521
  ),
1451
1522
  getInvalidations: () => previousInvalidations,
@@ -1454,12 +1525,16 @@ export default class RequestTracker {
1454
1525
  },
1455
1526
  getSubRequests: () => this.graph.getSubRequests(requestId),
1456
1527
  getInvalidSubRequests: () => this.graph.getInvalidSubRequests(requestId),
1457
- getPreviousResult: <T: RequestResult>(ifMatch?: string): Async<?T> => {
1528
+ getPreviousResult: <T extends RequestResult>(
1529
+ ifMatch?: string,
1530
+ ): Async<T | null | undefined> => {
1458
1531
  let contentKey = nullthrows(this.graph.getNode(requestId)?.id);
1459
1532
  return this.getRequestResult<T>(contentKey, ifMatch);
1460
1533
  },
1461
- getRequestResult: <T: RequestResult>(id): Async<?T> =>
1462
- this.getRequestResult<T>(id),
1534
+ getRequestResult: <T extends RequestResult>(
1535
+ // @ts-expect-error TS7006
1536
+ id,
1537
+ ): Async<T | null | undefined> => this.getRequestResult<T>(id),
1463
1538
  canSkipSubrequest: (contentKey) => {
1464
1539
  if (
1465
1540
  this.graph.hasContentKey(contentKey) &&
@@ -1471,7 +1546,7 @@ export default class RequestTracker {
1471
1546
 
1472
1547
  return false;
1473
1548
  },
1474
- runRequest: <TInput, TResult: RequestResult>(
1549
+ runRequest: <TInput, TResult extends RequestResult>(
1475
1550
  subRequest: Request<TInput, TResult>,
1476
1551
  opts?: RunRequestOpts,
1477
1552
  ): Promise<TResult> => {
@@ -1499,130 +1574,143 @@ export default class RequestTracker {
1499
1574
  }
1500
1575
  }
1501
1576
 
1577
+ let cacheKey = getCacheKey(this.options);
1578
+ let requestGraphKey = getFeatureFlag('cachePerformanceImprovements')
1579
+ ? `${cacheKey}/RequestGraph`
1580
+ : `requestGraph-${cacheKey}`;
1581
+ let snapshotKey = getFeatureFlag('cachePerformanceImprovements')
1582
+ ? `${cacheKey}/snapshot`
1583
+ : `snapshot-${cacheKey}`;
1584
+
1585
+ if (this.options.shouldDisableCache) {
1586
+ return;
1587
+ }
1588
+
1589
+ let total = 0;
1502
1590
  await runCacheImprovements(
1503
1591
  async (cache) => {
1504
1592
  await cache.getNativeRef().startWriteTransaction();
1505
1593
  },
1506
1594
  () => Promise.resolve(),
1507
1595
  );
1596
+ try {
1597
+ report({
1598
+ type: 'cache',
1599
+ phase: 'start',
1600
+ total,
1601
+ size: this.graph.nodes.length,
1602
+ });
1508
1603
 
1509
- let cacheKey = getCacheKey(this.options);
1510
- let requestGraphKey = `requestGraph-${cacheKey}`;
1511
- let snapshotKey = `snapshot-${cacheKey}`;
1512
-
1513
- if (this.options.shouldDisableCache) {
1514
- return;
1515
- }
1604
+ if (getFeatureFlag('environmentDeduplication')) {
1605
+ await writeEnvironmentsToCache(options.cache);
1606
+ }
1516
1607
 
1517
- let total = 0;
1518
- report({
1519
- type: 'cache',
1520
- phase: 'start',
1521
- total,
1522
- size: this.graph.nodes.length,
1523
- });
1608
+ let serialisedGraph = this.graph.serialize();
1524
1609
 
1525
- let serialisedGraph = this.graph.serialize();
1610
+ // Delete an existing request graph cache, to prevent invalid states
1611
+ await this.options.cache.deleteLargeBlob(requestGraphKey);
1526
1612
 
1527
- // Delete an existing request graph cache, to prevent invalid states
1528
- await this.options.cache.deleteLargeBlob(requestGraphKey);
1613
+ const serialiseAndSet = async (
1614
+ key: string,
1615
+ contents: any,
1616
+ ): Promise<void> => {
1617
+ if (signal?.aborted) {
1618
+ throw new Error('Serialization was aborted');
1619
+ }
1529
1620
 
1530
- const serialiseAndSet = async (
1531
- key: string,
1532
- // $FlowFixMe serialise input is any type
1533
- contents: any,
1534
- ): Promise<void> => {
1535
- if (signal?.aborted) {
1536
- throw new Error('Serialization was aborted');
1537
- }
1621
+ await runCacheImprovements(
1622
+ (cache) => {
1623
+ instrument(
1624
+ `RequestTracker::writeToCache::cache.put(${key})`,
1625
+ () => {
1626
+ cache.getNativeRef().putNoConfirm(key, serialize(contents));
1627
+ },
1628
+ );
1629
+ return Promise.resolve();
1630
+ },
1631
+ async () => {
1632
+ await this.options.cache.setLargeBlob(
1633
+ key,
1634
+ serialize(contents),
1635
+ signal
1636
+ ? {
1637
+ signal: signal,
1638
+ }
1639
+ : undefined,
1640
+ );
1641
+ },
1642
+ );
1538
1643
 
1539
- await runCacheImprovements(
1540
- (cache) => {
1541
- instrument(`cache.put(${key})`, () => {
1542
- cache.getNativeRef().putNoConfirm(key, serialize(contents));
1543
- });
1544
- return Promise.resolve();
1545
- },
1546
- async () => {
1547
- await this.options.cache.setLargeBlob(
1548
- key,
1549
- serialize(contents),
1550
- signal
1551
- ? {
1552
- signal: signal,
1553
- }
1554
- : undefined,
1555
- );
1556
- },
1557
- );
1644
+ total += 1;
1558
1645
 
1559
- total += 1;
1646
+ report({
1647
+ type: 'cache',
1648
+ phase: 'write',
1649
+ total,
1650
+ size: this.graph.nodes.length,
1651
+ });
1652
+ };
1560
1653
 
1561
- report({
1562
- type: 'cache',
1563
- phase: 'write',
1564
- total,
1565
- size: this.graph.nodes.length,
1654
+ let queue = new PromiseQueue({
1655
+ maxConcurrent: 32,
1566
1656
  });
1567
- };
1568
-
1569
- let queue = new PromiseQueue({
1570
- maxConcurrent: 32,
1571
- });
1572
1657
 
1573
- // Preallocating a sparse array is faster than pushing when N is high enough
1574
- let cacheableNodes = new Array(serialisedGraph.nodes.length);
1575
- for (let i = 0; i < serialisedGraph.nodes.length; i += 1) {
1576
- let node = serialisedGraph.nodes[i];
1658
+ // Preallocating a sparse array is faster than pushing when N is high enough
1659
+ let cacheableNodes = new Array(serialisedGraph.nodes.length);
1660
+ for (let i = 0; i < serialisedGraph.nodes.length; i += 1) {
1661
+ let node = serialisedGraph.nodes[i];
1577
1662
 
1578
- let resultCacheKey = node?.resultCacheKey;
1579
- if (
1580
- node?.type === REQUEST &&
1581
- resultCacheKey != null &&
1582
- node?.result != null
1583
- ) {
1584
- queue.add(() => serialiseAndSet(resultCacheKey, node.result));
1663
+ // @ts-expect-error TS2339
1664
+ let resultCacheKey = node?.resultCacheKey;
1665
+ if (
1666
+ node?.type === REQUEST &&
1667
+ resultCacheKey != null &&
1668
+ node?.result != null
1669
+ ) {
1670
+ queue.add(() => serialiseAndSet(resultCacheKey, node.result));
1585
1671
 
1586
- // eslint-disable-next-line no-unused-vars
1587
- let {result: _, ...newNode} = node;
1588
- cacheableNodes[i] = newNode;
1589
- } else {
1590
- cacheableNodes[i] = node;
1672
+ // eslint-disable-next-line no-unused-vars
1673
+ let {result: _, ...newNode} = node;
1674
+ cacheableNodes[i] = newNode;
1675
+ } else {
1676
+ cacheableNodes[i] = node;
1677
+ }
1591
1678
  }
1592
- }
1593
1679
 
1594
- let nodeCountsPerBlob = [];
1680
+ let nodeCountsPerBlob: Array<number> = [];
1595
1681
 
1596
- for (
1597
- let i = 0;
1598
- i * this.graph.nodesPerBlob < cacheableNodes.length;
1599
- i += 1
1600
- ) {
1601
- let nodesStartIndex = i * this.graph.nodesPerBlob;
1602
- let nodesEndIndex = Math.min(
1603
- (i + 1) * this.graph.nodesPerBlob,
1604
- cacheableNodes.length,
1605
- );
1682
+ for (
1683
+ let i = 0;
1684
+ i * this.graph.nodesPerBlob < cacheableNodes.length;
1685
+ i += 1
1686
+ ) {
1687
+ let nodesStartIndex = i * this.graph.nodesPerBlob;
1688
+ let nodesEndIndex = Math.min(
1689
+ (i + 1) * this.graph.nodesPerBlob,
1690
+ cacheableNodes.length,
1691
+ );
1606
1692
 
1607
- nodeCountsPerBlob.push(nodesEndIndex - nodesStartIndex);
1693
+ nodeCountsPerBlob.push(nodesEndIndex - nodesStartIndex);
1608
1694
 
1609
- if (!this.graph.hasCachedRequestChunk(i)) {
1610
- // We assume the request graph nodes are immutable and won't change
1611
- let nodesToCache = cacheableNodes.slice(nodesStartIndex, nodesEndIndex);
1695
+ if (!this.graph.hasCachedRequestChunk(i)) {
1696
+ // We assume the request graph nodes are immutable and won't change
1697
+ let nodesToCache = cacheableNodes.slice(
1698
+ nodesStartIndex,
1699
+ nodesEndIndex,
1700
+ );
1612
1701
 
1613
- queue.add(() =>
1614
- serialiseAndSet(
1615
- getRequestGraphNodeKey(i, cacheKey),
1616
- nodesToCache,
1617
- ).then(() => {
1618
- // Succeeded in writing to disk, save that we have completed this chunk
1619
- this.graph.setCachedRequestChunk(i);
1620
- }),
1621
- );
1702
+ queue.add(() =>
1703
+ serialiseAndSet(
1704
+ getRequestGraphNodeKey(i, cacheKey),
1705
+ nodesToCache,
1706
+ ).then(() => {
1707
+ // Succeeded in writing to disk, save that we have completed this chunk
1708
+ this.graph.setCachedRequestChunk(i);
1709
+ }),
1710
+ );
1711
+ }
1622
1712
  }
1623
- }
1624
1713
 
1625
- try {
1626
1714
  await queue.run();
1627
1715
 
1628
1716
  // Set the request graph after the queue is flushed to avoid writing an invalid state
@@ -1634,7 +1722,7 @@ export default class RequestTracker {
1634
1722
 
1635
1723
  await runCacheImprovements(
1636
1724
  () =>
1637
- serialiseAndSet(`request_tracker:cache_metadata:${cacheKey}`, {
1725
+ serialiseAndSet(`${cacheKey}/cache_metadata`, {
1638
1726
  version: ATLASPACK_VERSION,
1639
1727
  entries: this.options.entries,
1640
1728
  mode: this.options.mode,
@@ -1652,18 +1740,18 @@ export default class RequestTracker {
1652
1740
  snapshotPath,
1653
1741
  opts,
1654
1742
  );
1655
- } catch (err) {
1743
+ } catch (err: any) {
1656
1744
  // If we have aborted, ignore the error and continue
1657
1745
  if (!signal?.aborted) throw err;
1746
+ } finally {
1747
+ await runCacheImprovements(
1748
+ async (cache) => {
1749
+ await cache.getNativeRef().commitWriteTransaction();
1750
+ },
1751
+ () => Promise.resolve(),
1752
+ );
1658
1753
  }
1659
1754
 
1660
- await runCacheImprovements(
1661
- async (cache) => {
1662
- await cache.getNativeRef().commitWriteTransaction();
1663
- },
1664
- () => Promise.resolve(),
1665
- );
1666
-
1667
1755
  report({type: 'cache', phase: 'end', total, size: this.graph.nodes.length});
1668
1756
  }
1669
1757
 
@@ -1671,11 +1759,11 @@ export default class RequestTracker {
1671
1759
  farm,
1672
1760
  options,
1673
1761
  rustAtlaspack,
1674
- }: {|
1675
- farm: WorkerFarm,
1676
- options: AtlaspackOptions,
1677
- rustAtlaspack?: AtlaspackV3,
1678
- |}): Async<RequestTracker> {
1762
+ }: {
1763
+ farm: WorkerFarm;
1764
+ options: AtlaspackOptions;
1765
+ rustAtlaspack?: AtlaspackV3;
1766
+ }): Promise<Async<RequestTracker>> {
1679
1767
  let graph = await loadRequestGraph(options);
1680
1768
  return new RequestTracker({farm, graph, options, rustAtlaspack});
1681
1769
  }
@@ -1694,7 +1782,19 @@ export function getWatcherOptions({
1694
1782
  return {ignore, backend: watchBackend};
1695
1783
  }
1696
1784
 
1697
- function getCacheKey(options) {
1785
+ function getCacheKey(options: AtlaspackOptions) {
1786
+ if (getFeatureFlag('cachePerformanceImprovements')) {
1787
+ const hash = hashString(
1788
+ `${ATLASPACK_VERSION}:${JSON.stringify(options.entries)}:${
1789
+ options.mode
1790
+ }:${options.shouldBuildLazily ? 'lazy' : 'eager'}:${
1791
+ options.watchBackend ?? ''
1792
+ }`,
1793
+ );
1794
+
1795
+ return `RequestTracker/${ATLASPACK_VERSION}/${hash}`;
1796
+ }
1797
+
1698
1798
  return hashString(
1699
1799
  `${ATLASPACK_VERSION}:${JSON.stringify(options.entries)}:${options.mode}:${
1700
1800
  options.shouldBuildLazily ? 'lazy' : 'eager'
@@ -1703,6 +1803,10 @@ function getCacheKey(options) {
1703
1803
  }
1704
1804
 
1705
1805
  function getRequestGraphNodeKey(index: number, cacheKey: string) {
1806
+ if (getFeatureFlag('cachePerformanceImprovements')) {
1807
+ return `${cacheKey}/RequestGraph/nodes/${index}`;
1808
+ }
1809
+
1706
1810
  return `requestGraph-nodes-${index}-${cacheKey}`;
1707
1811
  }
1708
1812
 
@@ -1710,18 +1814,30 @@ export async function readAndDeserializeRequestGraph(
1710
1814
  cache: Cache,
1711
1815
  requestGraphKey: string,
1712
1816
  cacheKey: string,
1713
- ): Async<{|requestGraph: RequestGraph, bufferLength: number|}> {
1817
+ ): Promise<
1818
+ Async<{
1819
+ requestGraph: RequestGraph;
1820
+ bufferLength: number;
1821
+ }>
1822
+ > {
1714
1823
  let bufferLength = 0;
1715
1824
 
1716
1825
  const getAndDeserialize = async (key: string) => {
1717
- let buffer = await cache.getLargeBlob(key);
1718
- bufferLength += Buffer.byteLength(buffer);
1719
- return deserialize(buffer);
1826
+ if (getFeatureFlag('cachePerformanceImprovements')) {
1827
+ const buffer = await cache.getBlob(key);
1828
+ bufferLength += Buffer.byteLength(buffer);
1829
+ return deserialize(buffer);
1830
+ } else {
1831
+ const buffer = await cache.getLargeBlob(key);
1832
+ bufferLength += Buffer.byteLength(buffer);
1833
+ return deserialize(buffer);
1834
+ }
1720
1835
  };
1721
1836
 
1722
1837
  let serializedRequestGraph = await getAndDeserialize(requestGraphKey);
1723
1838
 
1724
1839
  let nodePromises = serializedRequestGraph.nodeCountsPerBlob.map(
1840
+ // @ts-expect-error TS7006
1725
1841
  async (nodesCount, i) => {
1726
1842
  let nodes = await getAndDeserialize(getRequestGraphNodeKey(i, cacheKey));
1727
1843
  invariant.equal(
@@ -1743,15 +1859,22 @@ export async function readAndDeserializeRequestGraph(
1743
1859
  };
1744
1860
  }
1745
1861
 
1746
- async function loadRequestGraph(options): Async<RequestGraph> {
1862
+ async function loadRequestGraph(
1863
+ options: AtlaspackOptions,
1864
+ ): Promise<Async<RequestGraph>> {
1747
1865
  if (options.shouldDisableCache) {
1748
1866
  return new RequestGraph();
1749
1867
  }
1750
1868
 
1751
1869
  let cacheKey = getCacheKey(options);
1752
- let requestGraphKey = `requestGraph-${cacheKey}`;
1870
+ let requestGraphKey = getFeatureFlag('cachePerformanceImprovements')
1871
+ ? `${cacheKey}/RequestGraph`
1872
+ : `requestGraph-${cacheKey}`;
1873
+
1753
1874
  let timeout;
1754
- const snapshotKey = `snapshot-${cacheKey}`;
1875
+ const snapshotKey = getFeatureFlag('cachePerformanceImprovements')
1876
+ ? `${cacheKey}/snapshot`
1877
+ : `snapshot-${cacheKey}`;
1755
1878
  const snapshotPath = path.join(options.cacheDir, snapshotKey + '.txt');
1756
1879
 
1757
1880
  const commonMeta = {
@@ -1764,7 +1887,7 @@ async function loadRequestGraph(options): Async<RequestGraph> {
1764
1887
  shouldBuildLazily: options.shouldBuildLazily,
1765
1888
  watchBackend: options.watchBackend,
1766
1889
  },
1767
- };
1890
+ } as const;
1768
1891
 
1769
1892
  logger.verbose({
1770
1893
  origin: '@atlaspack/core',
@@ -1774,7 +1897,15 @@ async function loadRequestGraph(options): Async<RequestGraph> {
1774
1897
  },
1775
1898
  });
1776
1899
 
1777
- if (await options.cache.hasLargeBlob(requestGraphKey)) {
1900
+ if (getFeatureFlag('environmentDeduplication')) {
1901
+ await loadEnvironmentsFromCache(options.cache);
1902
+ }
1903
+
1904
+ const hasRequestGraphInCache = getFeatureFlag('cachePerformanceImprovements')
1905
+ ? await options.cache.has(requestGraphKey)
1906
+ : await options.cache.hasLargeBlob(requestGraphKey);
1907
+
1908
+ if (hasRequestGraphInCache) {
1778
1909
  try {
1779
1910
  let {requestGraph} = await readAndDeserializeRequestGraph(
1780
1911
  options.cache,
@@ -1812,31 +1943,24 @@ async function loadRequestGraph(options): Async<RequestGraph> {
1812
1943
  },
1813
1944
  });
1814
1945
 
1815
- if (getFeatureFlag('verboseRequestInvalidationStats')) {
1816
- const invalidationStats = await invalidateRequestGraph(
1817
- requestGraph,
1818
- options,
1819
- events,
1820
- );
1946
+ const invalidationStats = await invalidateRequestGraph(
1947
+ requestGraph,
1948
+ options,
1949
+ events,
1950
+ );
1821
1951
 
1822
- logger.verbose({
1823
- origin: '@atlaspack/core',
1824
- message: 'Request track loaded from cache',
1825
- meta: {
1826
- ...commonMeta,
1827
- trackableEvent: 'request_tracker_cache_key_hit',
1828
- invalidationStats,
1829
- },
1830
- });
1831
- } else {
1832
- requestGraph.invalidateUnpredictableNodes();
1833
- requestGraph.invalidateOnBuildNodes();
1834
- requestGraph.invalidateEnvNodes(options.env);
1835
- requestGraph.invalidateOptionNodes(options);
1836
- }
1952
+ logger.verbose({
1953
+ origin: '@atlaspack/core',
1954
+ message: 'Request track loaded from cache',
1955
+ meta: {
1956
+ ...commonMeta,
1957
+ trackableEvent: 'request_tracker_cache_key_hit',
1958
+ invalidationStats,
1959
+ },
1960
+ });
1837
1961
 
1838
1962
  return requestGraph;
1839
- } catch (e) {
1963
+ } catch (e: any) {
1840
1964
  // Prevent logging fs events took too long warning
1841
1965
  clearTimeout(timeout);
1842
1966
  logErrorOnBailout(options, snapshotPath, e);
@@ -1861,42 +1985,73 @@ async function loadRequestGraph(options): Async<RequestGraph> {
1861
1985
  /**
1862
1986
  * A wrapper around an invalidation type / method
1863
1987
  */
1864
- type InvalidationFn = {|
1865
- key: string,
1866
- fn: () => string[] | void | Promise<void>,
1867
- |};
1988
+ type InvalidationFn = {
1989
+ key: string;
1990
+ fn: () =>
1991
+ | InvalidationDetail
1992
+ | Promise<InvalidationDetail>
1993
+ | undefined
1994
+ | Promise<undefined>;
1995
+ };
1868
1996
 
1869
- type InvalidationStats = {|
1997
+ type InvalidationStats = {
1870
1998
  /**
1871
1999
  * Total number of request graph nodes
1872
2000
  */
1873
- nodeCount: number,
2001
+ nodeCount: number;
1874
2002
  /**
1875
2003
  * Number of requests in RequestGraph
1876
2004
  */
1877
- requestCount: number,
2005
+ requestCount: number;
1878
2006
  /**
1879
2007
  * Number of nodes that have been invalidated.
1880
2008
  */
1881
- invalidatedCount: number,
2009
+ invalidatedCount: number;
1882
2010
  /**
1883
2011
  * Percentage of requests that have been invalidated
1884
2012
  */
1885
- requestInvalidationRatio: number,
2013
+ requestInvalidationRatio: number;
1886
2014
  /**
1887
2015
  * Percentage of nodes that have been invalidated
1888
2016
  */
1889
- nodeInvalidationRatio: number,
2017
+ nodeInvalidationRatio: number;
1890
2018
  /**
1891
2019
  * Details for each invalidation type
1892
2020
  */
1893
- invalidations: InvalidationFnStats[],
1894
- |};
2021
+ invalidations: InvalidationFnStats[];
2022
+ };
2023
+
2024
+ /**
2025
+ * Details about an invalidation.
2026
+ *
2027
+ * If this is a fs events invalidation, this key will contain statistics about invalidations
2028
+ * by path.
2029
+ *
2030
+ * If this is a env or option invalidation, this key will contain the list of changed environment
2031
+ * variables or options.
2032
+ */
2033
+ type InvalidationDetail = string[] | FSInvalidationStats;
2034
+
2035
+ /**
2036
+ * Number of invalidations for a given file-system event.
2037
+ */
2038
+ type FSInvalidation = {
2039
+ path: string;
2040
+ count: number;
2041
+ };
2042
+
2043
+ type FSInvalidationStats = {
2044
+ /**
2045
+ * This list will be sorted by the number of nodes invalidated and only the top 10 will be
2046
+ * included.
2047
+ */
2048
+ biggestInvalidations: FSInvalidation[];
2049
+ };
1895
2050
 
1896
2051
  /**
1897
2052
  * Information about a certain cache invalidation type.
1898
2053
  */
1899
- type InvalidationFnStats = {|
2054
+ type InvalidationFnStats = {
1900
2055
  /**
1901
2056
  * Invalidation type, one of:
1902
2057
  *
@@ -1906,16 +2061,22 @@ type InvalidationFnStats = {|
1906
2061
  * - option
1907
2062
  * - fsEvents
1908
2063
  */
1909
- key: string,
2064
+ key: string;
1910
2065
  /**
1911
2066
  * Number of invalidated nodes coming from this invalidation type.
1912
2067
  */
1913
- count: number,
2068
+ count: number;
1914
2069
  /**
1915
2070
  * If this is a env or option invalidation, this key will contain the list of changed values.
2071
+ *
2072
+ * If this is a fs events invalidation, this key will contain statistics about invalidations
2073
+ */
2074
+ detail: null | InvalidationDetail;
2075
+ /**
2076
+ * Time in milliseconds it took to run the invalidation.
1916
2077
  */
1917
- changes: null | string[],
1918
- |};
2078
+ duration: number;
2079
+ };
1919
2080
 
1920
2081
  /**
1921
2082
  * Respond to unpredictable, build, environment changes, option changes and file-system events
@@ -1923,7 +2084,7 @@ type InvalidationFnStats = {|
1923
2084
  *
1924
2085
  * Returns the count of nodes invalidated by each invalidation type.
1925
2086
  */
1926
- async function invalidateRequestGraph(
2087
+ export async function invalidateRequestGraph(
1927
2088
  requestGraph: RequestGraph,
1928
2089
  options: AtlaspackOptions,
1929
2090
  events: Event[],
@@ -1931,10 +2092,12 @@ async function invalidateRequestGraph(
1931
2092
  const invalidationFns: InvalidationFn[] = [
1932
2093
  {
1933
2094
  key: 'unpredictable',
2095
+ // @ts-expect-error TS2322
1934
2096
  fn: () => requestGraph.invalidateUnpredictableNodes(),
1935
2097
  },
1936
2098
  {
1937
2099
  key: 'onBuild',
2100
+ // @ts-expect-error TS2322
1938
2101
  fn: () => requestGraph.invalidateOnBuildNodes(),
1939
2102
  },
1940
2103
  {
@@ -1947,18 +2110,11 @@ async function invalidateRequestGraph(
1947
2110
  },
1948
2111
  {
1949
2112
  key: 'fsEvents',
1950
- fn: async () => {
1951
- await requestGraph.respondToFSEvents(
1952
- options.unstableFileInvalidations || events,
1953
- options,
1954
- 10000,
1955
- true,
1956
- );
1957
- },
2113
+ fn: () => invalidateRequestGraphFSEvents(requestGraph, options, events),
1958
2114
  },
1959
2115
  ];
1960
2116
 
1961
- const invalidations = [];
2117
+ const invalidations: Array<InvalidationFnStats> = [];
1962
2118
  for (const invalidation of invalidationFns) {
1963
2119
  invalidations.push(await runInvalidation(requestGraph, invalidation));
1964
2120
  }
@@ -1984,22 +2140,63 @@ async function invalidateRequestGraph(
1984
2140
  };
1985
2141
  }
1986
2142
 
2143
+ interface InvalidateRequestGraphFSEventsInput {
2144
+ respondToFSEvents(
2145
+ events: Event[],
2146
+ options: AtlaspackOptions,
2147
+ timeout: number,
2148
+ shouldLog: boolean,
2149
+ ): Promise<{
2150
+ invalidationsByPath: Map<string, number>;
2151
+ }>;
2152
+ }
2153
+
2154
+ /**
2155
+ * Invalidate the request graph based on file-system events.
2156
+ *
2157
+ * Returns statistics about the invalidations.
2158
+ */
2159
+ export async function invalidateRequestGraphFSEvents(
2160
+ requestGraph: InvalidateRequestGraphFSEventsInput,
2161
+ options: AtlaspackOptions,
2162
+ events: Event[],
2163
+ ): Promise<FSInvalidationStats> {
2164
+ const {invalidationsByPath} = await requestGraph.respondToFSEvents(
2165
+ options.unstableFileInvalidations || events,
2166
+ options,
2167
+ 10000,
2168
+ true,
2169
+ );
2170
+ const biggestInvalidations =
2171
+ getBiggestFSEventsInvalidations(invalidationsByPath);
2172
+
2173
+ return {
2174
+ biggestInvalidations,
2175
+ };
2176
+ }
2177
+
2178
+ interface RunInvalidationInput {
2179
+ getInvalidNodeCount(): number;
2180
+ }
2181
+
1987
2182
  /**
1988
2183
  * Runs an invalidation function and reports metrics.
1989
2184
  */
1990
- async function runInvalidation(
1991
- requestGraph: RequestGraph,
2185
+ export async function runInvalidation(
2186
+ requestGraph: RunInvalidationInput,
1992
2187
  invalidationFn: InvalidationFn,
1993
2188
  ): Promise<InvalidationFnStats> {
1994
- const startInvalidationCount = requestGraph.invalidNodeIds.size;
2189
+ const start = performance.now();
2190
+ const startInvalidationCount = requestGraph.getInvalidNodeCount();
1995
2191
  const result = await invalidationFn.fn();
1996
- const count = requestGraph.invalidNodeIds.size - startInvalidationCount;
2192
+ const count = requestGraph.getInvalidNodeCount() - startInvalidationCount;
2193
+ const duration = performance.now() - start;
1997
2194
 
1998
2195
  return {
1999
2196
  key: invalidationFn.key,
2000
2197
  count,
2001
- changes:
2002
- typeof result === 'object' && Array.isArray(result) ? result : null,
2198
+ detail: result ?? null,
2199
+ duration,
2003
2200
  };
2004
2201
  }
2005
2202
 
@@ -2034,7 +2231,9 @@ function logErrorOnBailout(
2034
2231
  }
2035
2232
  }
2036
2233
 
2037
- export function cleanUpOrphans<N, E: number>(graph: Graph<N, E>): NodeId[] {
2234
+ export function cleanUpOrphans<N, E extends number>(
2235
+ graph: Graph<N, E>,
2236
+ ): NodeId[] {
2038
2237
  if (graph.rootNodeId == null) {
2039
2238
  return [];
2040
2239
  }
@@ -2044,7 +2243,7 @@ export function cleanUpOrphans<N, E: number>(graph: Graph<N, E>): NodeId[] {
2044
2243
  reachableNodes.add(nodeId);
2045
2244
  });
2046
2245
 
2047
- const removedNodeIds = [];
2246
+ const removedNodeIds: Array<NodeId> = [];
2048
2247
  graph.nodes.forEach((_node, nodeId) => {
2049
2248
  if (!reachableNodes.has(nodeId)) {
2050
2249
  removedNodeIds.push(nodeId);
@@ -2054,3 +2253,19 @@ export function cleanUpOrphans<N, E: number>(graph: Graph<N, E>): NodeId[] {
2054
2253
 
2055
2254
  return removedNodeIds;
2056
2255
  }
2256
+
2257
+ /**
2258
+ * Returns paths that invalidated the most nodes
2259
+ */
2260
+ export function getBiggestFSEventsInvalidations(
2261
+ invalidationsByPath: Map<string, number>,
2262
+ limit: number = 10,
2263
+ ): Array<FSInvalidation> {
2264
+ const invalidations: Array<FSInvalidation> = [];
2265
+ for (const [path, count] of invalidationsByPath) {
2266
+ invalidations.push({path, count});
2267
+ }
2268
+ invalidations.sort((a, b) => b.count - a.count);
2269
+
2270
+ return invalidations.slice(0, limit);
2271
+ }