@grafema/core 0.1.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (402) hide show
  1. package/LICENSE +190 -0
  2. package/README.md +76 -0
  3. package/dist/Orchestrator.d.ts +142 -0
  4. package/dist/Orchestrator.d.ts.map +1 -0
  5. package/dist/Orchestrator.js +481 -0
  6. package/dist/api/GraphAPI.d.ts +87 -0
  7. package/dist/api/GraphAPI.d.ts.map +1 -0
  8. package/dist/api/GraphAPI.js +210 -0
  9. package/dist/api/GuaranteeAPI.d.ts +147 -0
  10. package/dist/api/GuaranteeAPI.d.ts.map +1 -0
  11. package/dist/api/GuaranteeAPI.js +288 -0
  12. package/dist/core/ASTWorker.d.ts +133 -0
  13. package/dist/core/ASTWorker.d.ts.map +1 -0
  14. package/dist/core/ASTWorker.js +352 -0
  15. package/dist/core/ASTWorkerPool.d.ts +85 -0
  16. package/dist/core/ASTWorkerPool.d.ts.map +1 -0
  17. package/dist/core/ASTWorkerPool.js +207 -0
  18. package/dist/core/AnalysisQueue.d.ts +104 -0
  19. package/dist/core/AnalysisQueue.d.ts.map +1 -0
  20. package/dist/core/AnalysisQueue.js +299 -0
  21. package/dist/core/AnalysisWorker.d.ts +14 -0
  22. package/dist/core/AnalysisWorker.d.ts.map +1 -0
  23. package/dist/core/AnalysisWorker.js +307 -0
  24. package/dist/core/GraphBackend.d.ts +156 -0
  25. package/dist/core/GraphBackend.d.ts.map +1 -0
  26. package/dist/core/GraphBackend.js +85 -0
  27. package/dist/core/GuaranteeManager.d.ts +230 -0
  28. package/dist/core/GuaranteeManager.d.ts.map +1 -0
  29. package/dist/core/GuaranteeManager.js +352 -0
  30. package/dist/core/ManifestStore.d.ts +71 -0
  31. package/dist/core/ManifestStore.d.ts.map +1 -0
  32. package/dist/core/ManifestStore.js +146 -0
  33. package/dist/core/NodeFactory.d.ts +160 -0
  34. package/dist/core/NodeFactory.d.ts.map +1 -0
  35. package/dist/core/NodeFactory.js +137 -0
  36. package/dist/core/NodeId.d.ts +88 -0
  37. package/dist/core/NodeId.d.ts.map +1 -0
  38. package/dist/core/NodeId.js +170 -0
  39. package/dist/core/ParallelAnalyzer.d.ts +120 -0
  40. package/dist/core/ParallelAnalyzer.d.ts.map +1 -0
  41. package/dist/core/ParallelAnalyzer.js +331 -0
  42. package/dist/core/PriorityQueue.d.ts +106 -0
  43. package/dist/core/PriorityQueue.d.ts.map +1 -0
  44. package/dist/core/PriorityQueue.js +168 -0
  45. package/dist/core/Profiler.d.ts +75 -0
  46. package/dist/core/Profiler.d.ts.map +1 -0
  47. package/dist/core/Profiler.js +149 -0
  48. package/dist/core/QueueWorker.d.ts +12 -0
  49. package/dist/core/QueueWorker.d.ts.map +1 -0
  50. package/dist/core/QueueWorker.js +567 -0
  51. package/dist/core/RFDBClient.d.ts +179 -0
  52. package/dist/core/RFDBClient.d.ts.map +1 -0
  53. package/dist/core/RFDBClient.js +429 -0
  54. package/dist/core/Task.d.ts +56 -0
  55. package/dist/core/Task.d.ts.map +1 -0
  56. package/dist/core/Task.js +85 -0
  57. package/dist/core/TaskTypes.d.ts +20 -0
  58. package/dist/core/TaskTypes.d.ts.map +1 -0
  59. package/dist/core/TaskTypes.js +10 -0
  60. package/dist/core/VersionManager.d.ts +166 -0
  61. package/dist/core/VersionManager.d.ts.map +1 -0
  62. package/dist/core/VersionManager.js +237 -0
  63. package/dist/core/WorkerPool.d.ts +82 -0
  64. package/dist/core/WorkerPool.d.ts.map +1 -0
  65. package/dist/core/WorkerPool.js +109 -0
  66. package/dist/core/nodes/CallSiteNode.d.ts +26 -0
  67. package/dist/core/nodes/CallSiteNode.d.ts.map +1 -0
  68. package/dist/core/nodes/CallSiteNode.js +44 -0
  69. package/dist/core/nodes/ClassNode.d.ts +25 -0
  70. package/dist/core/nodes/ClassNode.d.ts.map +1 -0
  71. package/dist/core/nodes/ClassNode.js +40 -0
  72. package/dist/core/nodes/ConstantNode.d.ts +24 -0
  73. package/dist/core/nodes/ConstantNode.d.ts.map +1 -0
  74. package/dist/core/nodes/ConstantNode.js +39 -0
  75. package/dist/core/nodes/DatabaseQueryNode.d.ts +22 -0
  76. package/dist/core/nodes/DatabaseQueryNode.d.ts.map +1 -0
  77. package/dist/core/nodes/DatabaseQueryNode.js +37 -0
  78. package/dist/core/nodes/EntrypointNode.d.ts +102 -0
  79. package/dist/core/nodes/EntrypointNode.d.ts.map +1 -0
  80. package/dist/core/nodes/EntrypointNode.js +119 -0
  81. package/dist/core/nodes/EventListenerNode.d.ts +25 -0
  82. package/dist/core/nodes/EventListenerNode.d.ts.map +1 -0
  83. package/dist/core/nodes/EventListenerNode.js +39 -0
  84. package/dist/core/nodes/ExportNode.d.ts +26 -0
  85. package/dist/core/nodes/ExportNode.d.ts.map +1 -0
  86. package/dist/core/nodes/ExportNode.js +40 -0
  87. package/dist/core/nodes/ExternalStdioNode.d.ts +17 -0
  88. package/dist/core/nodes/ExternalStdioNode.d.ts.map +1 -0
  89. package/dist/core/nodes/ExternalStdioNode.js +26 -0
  90. package/dist/core/nodes/FunctionNode.d.ts +27 -0
  91. package/dist/core/nodes/FunctionNode.d.ts.map +1 -0
  92. package/dist/core/nodes/FunctionNode.js +53 -0
  93. package/dist/core/nodes/GuaranteeNode.d.ts +76 -0
  94. package/dist/core/nodes/GuaranteeNode.d.ts.map +1 -0
  95. package/dist/core/nodes/GuaranteeNode.js +117 -0
  96. package/dist/core/nodes/HttpRequestNode.d.ts +24 -0
  97. package/dist/core/nodes/HttpRequestNode.d.ts.map +1 -0
  98. package/dist/core/nodes/HttpRequestNode.js +38 -0
  99. package/dist/core/nodes/ImportNode.d.ts +27 -0
  100. package/dist/core/nodes/ImportNode.d.ts.map +1 -0
  101. package/dist/core/nodes/ImportNode.js +43 -0
  102. package/dist/core/nodes/LiteralNode.d.ts +26 -0
  103. package/dist/core/nodes/LiteralNode.d.ts.map +1 -0
  104. package/dist/core/nodes/LiteralNode.js +40 -0
  105. package/dist/core/nodes/MethodCallNode.d.ts +29 -0
  106. package/dist/core/nodes/MethodCallNode.d.ts.map +1 -0
  107. package/dist/core/nodes/MethodCallNode.js +47 -0
  108. package/dist/core/nodes/MethodNode.d.ts +29 -0
  109. package/dist/core/nodes/MethodNode.d.ts.map +1 -0
  110. package/dist/core/nodes/MethodNode.js +44 -0
  111. package/dist/core/nodes/ModuleNode.d.ts +29 -0
  112. package/dist/core/nodes/ModuleNode.d.ts.map +1 -0
  113. package/dist/core/nodes/ModuleNode.js +49 -0
  114. package/dist/core/nodes/NodeKind.d.ts +91 -0
  115. package/dist/core/nodes/NodeKind.d.ts.map +1 -0
  116. package/dist/core/nodes/NodeKind.js +146 -0
  117. package/dist/core/nodes/ParameterNode.d.ts +26 -0
  118. package/dist/core/nodes/ParameterNode.d.ts.map +1 -0
  119. package/dist/core/nodes/ParameterNode.js +43 -0
  120. package/dist/core/nodes/ScopeNode.d.ts +32 -0
  121. package/dist/core/nodes/ScopeNode.d.ts.map +1 -0
  122. package/dist/core/nodes/ScopeNode.js +47 -0
  123. package/dist/core/nodes/ServiceNode.d.ts +44 -0
  124. package/dist/core/nodes/ServiceNode.d.ts.map +1 -0
  125. package/dist/core/nodes/ServiceNode.js +49 -0
  126. package/dist/core/nodes/VariableDeclarationNode.d.ts +22 -0
  127. package/dist/core/nodes/VariableDeclarationNode.d.ts.map +1 -0
  128. package/dist/core/nodes/VariableDeclarationNode.js +38 -0
  129. package/dist/core/nodes/index.d.ts +25 -0
  130. package/dist/core/nodes/index.d.ts.map +1 -0
  131. package/dist/core/nodes/index.js +30 -0
  132. package/dist/index.d.ts +57 -0
  133. package/dist/index.d.ts.map +1 -0
  134. package/dist/index.js +63 -0
  135. package/dist/plugins/Plugin.d.ts +44 -0
  136. package/dist/plugins/Plugin.d.ts.map +1 -0
  137. package/dist/plugins/Plugin.js +46 -0
  138. package/dist/plugins/analysis/DatabaseAnalyzer.d.ts +23 -0
  139. package/dist/plugins/analysis/DatabaseAnalyzer.d.ts.map +1 -0
  140. package/dist/plugins/analysis/DatabaseAnalyzer.js +260 -0
  141. package/dist/plugins/analysis/ExpressAnalyzer.d.ts +19 -0
  142. package/dist/plugins/analysis/ExpressAnalyzer.d.ts.map +1 -0
  143. package/dist/plugins/analysis/ExpressAnalyzer.js +306 -0
  144. package/dist/plugins/analysis/ExpressRouteAnalyzer.d.ts +17 -0
  145. package/dist/plugins/analysis/ExpressRouteAnalyzer.d.ts.map +1 -0
  146. package/dist/plugins/analysis/ExpressRouteAnalyzer.js +308 -0
  147. package/dist/plugins/analysis/FetchAnalyzer.d.ts +38 -0
  148. package/dist/plugins/analysis/FetchAnalyzer.d.ts.map +1 -0
  149. package/dist/plugins/analysis/FetchAnalyzer.js +344 -0
  150. package/dist/plugins/analysis/IncrementalAnalysisPlugin.d.ts +65 -0
  151. package/dist/plugins/analysis/IncrementalAnalysisPlugin.d.ts.map +1 -0
  152. package/dist/plugins/analysis/IncrementalAnalysisPlugin.js +472 -0
  153. package/dist/plugins/analysis/JSASTAnalyzer.d.ts +84 -0
  154. package/dist/plugins/analysis/JSASTAnalyzer.d.ts.map +1 -0
  155. package/dist/plugins/analysis/JSASTAnalyzer.js +1378 -0
  156. package/dist/plugins/analysis/ReactAnalyzer.d.ts +90 -0
  157. package/dist/plugins/analysis/ReactAnalyzer.d.ts.map +1 -0
  158. package/dist/plugins/analysis/ReactAnalyzer.js +1153 -0
  159. package/dist/plugins/analysis/RustAnalyzer.d.ts +13 -0
  160. package/dist/plugins/analysis/RustAnalyzer.d.ts.map +1 -0
  161. package/dist/plugins/analysis/RustAnalyzer.js +259 -0
  162. package/dist/plugins/analysis/SQLiteAnalyzer.d.ts +21 -0
  163. package/dist/plugins/analysis/SQLiteAnalyzer.d.ts.map +1 -0
  164. package/dist/plugins/analysis/SQLiteAnalyzer.js +317 -0
  165. package/dist/plugins/analysis/ServiceLayerAnalyzer.d.ts +35 -0
  166. package/dist/plugins/analysis/ServiceLayerAnalyzer.d.ts.map +1 -0
  167. package/dist/plugins/analysis/ServiceLayerAnalyzer.js +303 -0
  168. package/dist/plugins/analysis/SocketIOAnalyzer.d.ts +33 -0
  169. package/dist/plugins/analysis/SocketIOAnalyzer.d.ts.map +1 -0
  170. package/dist/plugins/analysis/SocketIOAnalyzer.js +283 -0
  171. package/dist/plugins/analysis/SystemDbAnalyzer.d.ts +27 -0
  172. package/dist/plugins/analysis/SystemDbAnalyzer.d.ts.map +1 -0
  173. package/dist/plugins/analysis/SystemDbAnalyzer.js +211 -0
  174. package/dist/plugins/analysis/ast/ConditionParser.d.ts +85 -0
  175. package/dist/plugins/analysis/ast/ConditionParser.d.ts.map +1 -0
  176. package/dist/plugins/analysis/ast/ConditionParser.js +277 -0
  177. package/dist/plugins/analysis/ast/ExpressionEvaluator.d.ts +15 -0
  178. package/dist/plugins/analysis/ast/ExpressionEvaluator.d.ts.map +1 -0
  179. package/dist/plugins/analysis/ast/ExpressionEvaluator.js +91 -0
  180. package/dist/plugins/analysis/ast/GraphBuilder.d.ts +77 -0
  181. package/dist/plugins/analysis/ast/GraphBuilder.d.ts.map +1 -0
  182. package/dist/plugins/analysis/ast/GraphBuilder.js +1077 -0
  183. package/dist/plugins/analysis/ast/OxcAdapter.d.ts +41 -0
  184. package/dist/plugins/analysis/ast/OxcAdapter.d.ts.map +1 -0
  185. package/dist/plugins/analysis/ast/OxcAdapter.js +40 -0
  186. package/dist/plugins/analysis/ast/types.d.ts +346 -0
  187. package/dist/plugins/analysis/ast/types.d.ts.map +1 -0
  188. package/dist/plugins/analysis/ast/types.js +4 -0
  189. package/dist/plugins/analysis/ast/visitors/ASTVisitor.d.ts +93 -0
  190. package/dist/plugins/analysis/ast/visitors/ASTVisitor.d.ts.map +1 -0
  191. package/dist/plugins/analysis/ast/visitors/ASTVisitor.js +24 -0
  192. package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.d.ts +77 -0
  193. package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.d.ts.map +1 -0
  194. package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.js +377 -0
  195. package/dist/plugins/analysis/ast/visitors/ClassVisitor.d.ts +27 -0
  196. package/dist/plugins/analysis/ast/visitors/ClassVisitor.d.ts.map +1 -0
  197. package/dist/plugins/analysis/ast/visitors/ClassVisitor.js +232 -0
  198. package/dist/plugins/analysis/ast/visitors/FunctionVisitor.d.ts +25 -0
  199. package/dist/plugins/analysis/ast/visitors/FunctionVisitor.d.ts.map +1 -0
  200. package/dist/plugins/analysis/ast/visitors/FunctionVisitor.js +172 -0
  201. package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.d.ts +29 -0
  202. package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.d.ts.map +1 -0
  203. package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.js +180 -0
  204. package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.d.ts +14 -0
  205. package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.d.ts.map +1 -0
  206. package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.js +200 -0
  207. package/dist/plugins/analysis/ast/visitors/VariableVisitor.d.ts +45 -0
  208. package/dist/plugins/analysis/ast/visitors/VariableVisitor.d.ts.map +1 -0
  209. package/dist/plugins/analysis/ast/visitors/VariableVisitor.js +150 -0
  210. package/dist/plugins/analysis/ast/visitors/index.d.ts +17 -0
  211. package/dist/plugins/analysis/ast/visitors/index.d.ts.map +1 -0
  212. package/dist/plugins/analysis/ast/visitors/index.js +13 -0
  213. package/dist/plugins/discovery/DiscoveryPlugin.d.ts +34 -0
  214. package/dist/plugins/discovery/DiscoveryPlugin.d.ts.map +1 -0
  215. package/dist/plugins/discovery/DiscoveryPlugin.js +26 -0
  216. package/dist/plugins/discovery/MonorepoServiceDiscovery.d.ts +26 -0
  217. package/dist/plugins/discovery/MonorepoServiceDiscovery.d.ts.map +1 -0
  218. package/dist/plugins/discovery/MonorepoServiceDiscovery.js +79 -0
  219. package/dist/plugins/discovery/SimpleProjectDiscovery.d.ts +14 -0
  220. package/dist/plugins/discovery/SimpleProjectDiscovery.d.ts.map +1 -0
  221. package/dist/plugins/discovery/SimpleProjectDiscovery.js +65 -0
  222. package/dist/plugins/discovery/ZonServiceDiscovery.d.ts +19 -0
  223. package/dist/plugins/discovery/ZonServiceDiscovery.d.ts.map +1 -0
  224. package/dist/plugins/discovery/ZonServiceDiscovery.js +204 -0
  225. package/dist/plugins/enrichment/AliasTracker.d.ts +40 -0
  226. package/dist/plugins/enrichment/AliasTracker.d.ts.map +1 -0
  227. package/dist/plugins/enrichment/AliasTracker.js +290 -0
  228. package/dist/plugins/enrichment/HTTPConnectionEnricher.d.ts +30 -0
  229. package/dist/plugins/enrichment/HTTPConnectionEnricher.d.ts.map +1 -0
  230. package/dist/plugins/enrichment/HTTPConnectionEnricher.js +135 -0
  231. package/dist/plugins/enrichment/ImportExportLinker.d.ts +30 -0
  232. package/dist/plugins/enrichment/ImportExportLinker.d.ts.map +1 -0
  233. package/dist/plugins/enrichment/ImportExportLinker.js +176 -0
  234. package/dist/plugins/enrichment/InstanceOfResolver.d.ts +21 -0
  235. package/dist/plugins/enrichment/InstanceOfResolver.d.ts.map +1 -0
  236. package/dist/plugins/enrichment/InstanceOfResolver.js +117 -0
  237. package/dist/plugins/enrichment/MethodCallResolver.d.ts +41 -0
  238. package/dist/plugins/enrichment/MethodCallResolver.d.ts.map +1 -0
  239. package/dist/plugins/enrichment/MethodCallResolver.js +252 -0
  240. package/dist/plugins/enrichment/MountPointResolver.d.ts +26 -0
  241. package/dist/plugins/enrichment/MountPointResolver.d.ts.map +1 -0
  242. package/dist/plugins/enrichment/MountPointResolver.js +189 -0
  243. package/dist/plugins/enrichment/PrefixEvaluator.d.ts +89 -0
  244. package/dist/plugins/enrichment/PrefixEvaluator.d.ts.map +1 -0
  245. package/dist/plugins/enrichment/PrefixEvaluator.js +415 -0
  246. package/dist/plugins/enrichment/RustFFIEnricher.d.ts +25 -0
  247. package/dist/plugins/enrichment/RustFFIEnricher.d.ts.map +1 -0
  248. package/dist/plugins/enrichment/RustFFIEnricher.js +170 -0
  249. package/dist/plugins/enrichment/ValueDomainAnalyzer.d.ts +114 -0
  250. package/dist/plugins/enrichment/ValueDomainAnalyzer.d.ts.map +1 -0
  251. package/dist/plugins/enrichment/ValueDomainAnalyzer.js +464 -0
  252. package/dist/plugins/indexing/IncrementalModuleIndexer.d.ts +27 -0
  253. package/dist/plugins/indexing/IncrementalModuleIndexer.d.ts.map +1 -0
  254. package/dist/plugins/indexing/IncrementalModuleIndexer.js +238 -0
  255. package/dist/plugins/indexing/JSModuleIndexer.d.ts +33 -0
  256. package/dist/plugins/indexing/JSModuleIndexer.d.ts.map +1 -0
  257. package/dist/plugins/indexing/JSModuleIndexer.js +299 -0
  258. package/dist/plugins/indexing/RustModuleIndexer.d.ts +28 -0
  259. package/dist/plugins/indexing/RustModuleIndexer.d.ts.map +1 -0
  260. package/dist/plugins/indexing/RustModuleIndexer.js +140 -0
  261. package/dist/plugins/indexing/ServiceDetector.d.ts +46 -0
  262. package/dist/plugins/indexing/ServiceDetector.d.ts.map +1 -0
  263. package/dist/plugins/indexing/ServiceDetector.js +164 -0
  264. package/dist/plugins/validation/CallResolverValidator.d.ts +23 -0
  265. package/dist/plugins/validation/CallResolverValidator.d.ts.map +1 -0
  266. package/dist/plugins/validation/CallResolverValidator.js +108 -0
  267. package/dist/plugins/validation/DataFlowValidator.d.ts +24 -0
  268. package/dist/plugins/validation/DataFlowValidator.d.ts.map +1 -0
  269. package/dist/plugins/validation/DataFlowValidator.js +148 -0
  270. package/dist/plugins/validation/EvalBanValidator.d.ts +25 -0
  271. package/dist/plugins/validation/EvalBanValidator.d.ts.map +1 -0
  272. package/dist/plugins/validation/EvalBanValidator.js +123 -0
  273. package/dist/plugins/validation/GraphConnectivityValidator.d.ts +11 -0
  274. package/dist/plugins/validation/GraphConnectivityValidator.d.ts.map +1 -0
  275. package/dist/plugins/validation/GraphConnectivityValidator.js +135 -0
  276. package/dist/plugins/validation/SQLInjectionValidator.d.ts +43 -0
  277. package/dist/plugins/validation/SQLInjectionValidator.d.ts.map +1 -0
  278. package/dist/plugins/validation/SQLInjectionValidator.js +251 -0
  279. package/dist/plugins/validation/ShadowingDetector.d.ts +26 -0
  280. package/dist/plugins/validation/ShadowingDetector.d.ts.map +1 -0
  281. package/dist/plugins/validation/ShadowingDetector.js +119 -0
  282. package/dist/plugins/validation/TypeScriptDeadCodeValidator.d.ts +21 -0
  283. package/dist/plugins/validation/TypeScriptDeadCodeValidator.d.ts.map +1 -0
  284. package/dist/plugins/validation/TypeScriptDeadCodeValidator.js +151 -0
  285. package/dist/plugins/vcs/GitPlugin.d.ts +84 -0
  286. package/dist/plugins/vcs/GitPlugin.d.ts.map +1 -0
  287. package/dist/plugins/vcs/GitPlugin.js +295 -0
  288. package/dist/plugins/vcs/VCSPlugin.d.ts +133 -0
  289. package/dist/plugins/vcs/VCSPlugin.d.ts.map +1 -0
  290. package/dist/plugins/vcs/VCSPlugin.js +82 -0
  291. package/dist/plugins/vcs/index.d.ts +10 -0
  292. package/dist/plugins/vcs/index.d.ts.map +1 -0
  293. package/dist/plugins/vcs/index.js +18 -0
  294. package/dist/storage/backends/RFDBServerBackend.d.ts +258 -0
  295. package/dist/storage/backends/RFDBServerBackend.d.ts.map +1 -0
  296. package/dist/storage/backends/RFDBServerBackend.js +565 -0
  297. package/dist/storage/backends/typeValidation.d.ts +47 -0
  298. package/dist/storage/backends/typeValidation.d.ts.map +1 -0
  299. package/dist/storage/backends/typeValidation.js +137 -0
  300. package/dist/validation/PathValidator.d.ts +81 -0
  301. package/dist/validation/PathValidator.d.ts.map +1 -0
  302. package/dist/validation/PathValidator.js +251 -0
  303. package/package.json +57 -0
  304. package/src/.rfguard/current-session.txt +1 -0
  305. package/src/Orchestrator.ts +673 -0
  306. package/src/api/GraphAPI.ts +305 -0
  307. package/src/api/GuaranteeAPI.ts +401 -0
  308. package/src/core/ASTWorker.ts +567 -0
  309. package/src/core/ASTWorkerPool.ts +299 -0
  310. package/src/core/AnalysisQueue.ts +447 -0
  311. package/src/core/AnalysisWorker.ts +410 -0
  312. package/src/core/GraphBackend.ts +265 -0
  313. package/src/core/GuaranteeManager.ts +581 -0
  314. package/src/core/ManifestStore.ts +196 -0
  315. package/src/core/NodeFactory.ts +274 -0
  316. package/src/core/NodeId.ts +257 -0
  317. package/src/core/ParallelAnalyzer.ts +476 -0
  318. package/src/core/PriorityQueue.ts +227 -0
  319. package/src/core/Profiler.ts +188 -0
  320. package/src/core/QueueWorker.ts +780 -0
  321. package/src/core/Task.ts +107 -0
  322. package/src/core/TaskTypes.ts +40 -0
  323. package/src/core/VersionManager.ts +404 -0
  324. package/src/core/WorkerPool.ts +180 -0
  325. package/src/core/nodes/CallSiteNode.ts +72 -0
  326. package/src/core/nodes/ClassNode.ts +69 -0
  327. package/src/core/nodes/ConstantNode.ts +63 -0
  328. package/src/core/nodes/DatabaseQueryNode.ts +60 -0
  329. package/src/core/nodes/EntrypointNode.ts +164 -0
  330. package/src/core/nodes/EventListenerNode.ts +64 -0
  331. package/src/core/nodes/ExportNode.ts +71 -0
  332. package/src/core/nodes/ExternalStdioNode.ts +36 -0
  333. package/src/core/nodes/FunctionNode.ts +78 -0
  334. package/src/core/nodes/GuaranteeNode.ts +162 -0
  335. package/src/core/nodes/HttpRequestNode.ts +63 -0
  336. package/src/core/nodes/ImportNode.ts +75 -0
  337. package/src/core/nodes/LiteralNode.ts +67 -0
  338. package/src/core/nodes/MethodCallNode.ts +79 -0
  339. package/src/core/nodes/MethodNode.ts +78 -0
  340. package/src/core/nodes/ModuleNode.ts +74 -0
  341. package/src/core/nodes/NodeKind.ts +171 -0
  342. package/src/core/nodes/ParameterNode.ts +73 -0
  343. package/src/core/nodes/ScopeNode.ts +80 -0
  344. package/src/core/nodes/ServiceNode.ts +86 -0
  345. package/src/core/nodes/VariableDeclarationNode.ts +60 -0
  346. package/src/core/nodes/index.ts +49 -0
  347. package/src/index.ts +93 -0
  348. package/src/plugins/Plugin.ts +74 -0
  349. package/src/plugins/analysis/DatabaseAnalyzer.ts +322 -0
  350. package/src/plugins/analysis/ExpressAnalyzer.ts +401 -0
  351. package/src/plugins/analysis/ExpressRouteAnalyzer.ts +414 -0
  352. package/src/plugins/analysis/FetchAnalyzer.ts +441 -0
  353. package/src/plugins/analysis/IncrementalAnalysisPlugin.ts +686 -0
  354. package/src/plugins/analysis/JSASTAnalyzer.ts +1680 -0
  355. package/src/plugins/analysis/ReactAnalyzer.ts +1368 -0
  356. package/src/plugins/analysis/RustAnalyzer.ts +438 -0
  357. package/src/plugins/analysis/SQLiteAnalyzer.ts +388 -0
  358. package/src/plugins/analysis/ServiceLayerAnalyzer.ts +429 -0
  359. package/src/plugins/analysis/SocketIOAnalyzer.ts +395 -0
  360. package/src/plugins/analysis/SystemDbAnalyzer.ts +284 -0
  361. package/src/plugins/analysis/ast/ConditionParser.ts +333 -0
  362. package/src/plugins/analysis/ast/ExpressionEvaluator.ts +117 -0
  363. package/src/plugins/analysis/ast/GraphBuilder.ts +1371 -0
  364. package/src/plugins/analysis/ast/OxcAdapter.ts +63 -0
  365. package/src/plugins/analysis/ast/types.ts +400 -0
  366. package/src/plugins/analysis/ast/visitors/ASTVisitor.ts +137 -0
  367. package/src/plugins/analysis/ast/visitors/CallExpressionVisitor.ts +528 -0
  368. package/src/plugins/analysis/ast/visitors/ClassVisitor.ts +339 -0
  369. package/src/plugins/analysis/ast/visitors/FunctionVisitor.ts +273 -0
  370. package/src/plugins/analysis/ast/visitors/ImportExportVisitor.ts +259 -0
  371. package/src/plugins/analysis/ast/visitors/TypeScriptVisitor.ts +235 -0
  372. package/src/plugins/analysis/ast/visitors/VariableVisitor.ts +268 -0
  373. package/src/plugins/analysis/ast/visitors/index.ts +36 -0
  374. package/src/plugins/discovery/DiscoveryPlugin.ts +50 -0
  375. package/src/plugins/discovery/MonorepoServiceDiscovery.ts +117 -0
  376. package/src/plugins/discovery/SimpleProjectDiscovery.ts +102 -0
  377. package/src/plugins/enrichment/AliasTracker.ts +399 -0
  378. package/src/plugins/enrichment/HTTPConnectionEnricher.ts +192 -0
  379. package/src/plugins/enrichment/ImportExportLinker.ts +221 -0
  380. package/src/plugins/enrichment/InstanceOfResolver.ts +165 -0
  381. package/src/plugins/enrichment/MethodCallResolver.ts +333 -0
  382. package/src/plugins/enrichment/MountPointResolver.ts +264 -0
  383. package/src/plugins/enrichment/PrefixEvaluator.ts +527 -0
  384. package/src/plugins/enrichment/RustFFIEnricher.ts +218 -0
  385. package/src/plugins/enrichment/ValueDomainAnalyzer.ts +682 -0
  386. package/src/plugins/indexing/IncrementalModuleIndexer.ts +287 -0
  387. package/src/plugins/indexing/JSModuleIndexer.ts +374 -0
  388. package/src/plugins/indexing/RustModuleIndexer.ts +160 -0
  389. package/src/plugins/indexing/ServiceDetector.ts +230 -0
  390. package/src/plugins/validation/CallResolverValidator.ts +170 -0
  391. package/src/plugins/validation/DataFlowValidator.ts +233 -0
  392. package/src/plugins/validation/EvalBanValidator.ts +175 -0
  393. package/src/plugins/validation/GraphConnectivityValidator.ts +201 -0
  394. package/src/plugins/validation/SQLInjectionValidator.ts +363 -0
  395. package/src/plugins/validation/ShadowingDetector.ts +173 -0
  396. package/src/plugins/validation/TypeScriptDeadCodeValidator.ts +203 -0
  397. package/src/plugins/vcs/GitPlugin.ts +344 -0
  398. package/src/plugins/vcs/VCSPlugin.ts +190 -0
  399. package/src/plugins/vcs/index.ts +32 -0
  400. package/src/storage/backends/RFDBServerBackend.ts +687 -0
  401. package/src/storage/backends/typeValidation.ts +151 -0
  402. package/src/validation/PathValidator.ts +342 -0
@@ -0,0 +1,476 @@
1
+ /**
2
+ * ParallelAnalyzer - orchestrates parallel AST analysis using worker threads
3
+ *
4
+ * Features:
5
+ * - Configurable number of workers (default: CPU cores)
6
+ * - Each worker connects to RFDB server directly
7
+ * - Real-time statistics available during analysis
8
+ * - Concurrent reads while writes are happening
9
+ *
10
+ * Usage:
11
+ * const analyzer = new ParallelAnalyzer({
12
+ * socketPath: '/tmp/rfdb.sock',
13
+ * maxWorkers: 4,
14
+ * });
15
+ * await analyzer.start();
16
+ * const stats = await analyzer.analyzeFiles(files);
17
+ * await analyzer.stop();
18
+ */
19
+
20
+ import { Worker } from 'worker_threads';
21
+ import { EventEmitter } from 'events';
22
+ import { cpus } from 'os';
23
+ import { fileURLToPath } from 'url';
24
+ import { dirname, join } from 'path';
25
+
26
+ import { RFDBClient } from '@grafema/rfdb-client';
27
+
28
+ const __filename = fileURLToPath(import.meta.url);
29
+ const __dirname = dirname(__filename);
30
+ const WORKER_SCRIPT = join(__dirname, 'AnalysisWorker.js');
31
+
32
+ /**
33
+ * Analyzer options
34
+ */
35
+ export interface ParallelAnalyzerOptions {
36
+ socketPath?: string;
37
+ maxWorkers?: number;
38
+ }
39
+
40
+ /**
41
+ * File info for analysis
42
+ */
43
+ export interface FileInfo {
44
+ file: string;
45
+ id?: string;
46
+ moduleId?: string;
47
+ name?: string;
48
+ moduleName?: string;
49
+ }
50
+
51
+ /**
52
+ * Analysis stats per file
53
+ */
54
+ export interface FileStats {
55
+ nodes?: number;
56
+ edges?: number;
57
+ functions?: number;
58
+ calls?: number;
59
+ }
60
+
61
+ /**
62
+ * Overall analysis statistics
63
+ */
64
+ export interface AnalysisStats {
65
+ filesTotal: number;
66
+ filesProcessed: number;
67
+ filesFailed: number;
68
+ nodesCreated: number;
69
+ edgesCreated: number;
70
+ functionsFound: number;
71
+ callsFound: number;
72
+ startTime: number | null;
73
+ errors: Array<{ file: string; error: string }>;
74
+ }
75
+
76
+ /**
77
+ * Analysis task
78
+ */
79
+ interface AnalysisTask {
80
+ taskId: number;
81
+ file: string;
82
+ moduleId: string;
83
+ moduleName: string;
84
+ resolve: (stats: FileStats | null) => void;
85
+ reject: (error: Error) => void;
86
+ }
87
+
88
+ /**
89
+ * Worker message types
90
+ */
91
+ interface ReadyMessage {
92
+ type: 'ready';
93
+ workerId: number;
94
+ }
95
+
96
+ interface DoneMessage {
97
+ type: 'done';
98
+ file: string;
99
+ stats: FileStats;
100
+ workerId: number;
101
+ }
102
+
103
+ interface ErrorMessage {
104
+ type: 'error';
105
+ file?: string;
106
+ error: string;
107
+ workerId?: number;
108
+ }
109
+
110
+ type WorkerResponse = ReadyMessage | DoneMessage | ErrorMessage;
111
+
112
+ /**
113
+ * Graph stats from RFDB
114
+ */
115
+ export interface GraphStats {
116
+ nodeCount: number;
117
+ edgeCount: number;
118
+ nodesByType: Record<string, number>;
119
+ edgesByType: Record<string, number>;
120
+ }
121
+
122
+ export class ParallelAnalyzer extends EventEmitter {
123
+ private socketPath: string;
124
+ private maxWorkers: number;
125
+ private workers: Worker[];
126
+ private readyWorkers: Worker[];
127
+ private taskQueue: AnalysisTask[];
128
+ private pendingTasks: Map<number, AnalysisTask>;
129
+ private taskIdCounter: number;
130
+ private running: boolean;
131
+ private stats: AnalysisStats;
132
+ private statsClient: RFDBClient | null;
133
+
134
+ constructor(options: ParallelAnalyzerOptions = {}) {
135
+ super();
136
+
137
+ // Configuration
138
+ this.socketPath = options.socketPath || '/tmp/rfdb.sock';
139
+ this.maxWorkers = options.maxWorkers || cpus().length;
140
+ this.maxWorkers = Math.min(this.maxWorkers, 16); // Cap at 16
141
+
142
+ // State
143
+ this.workers = [];
144
+ this.readyWorkers = [];
145
+ this.taskQueue = [];
146
+ this.pendingTasks = new Map();
147
+ this.taskIdCounter = 0;
148
+ this.running = false;
149
+
150
+ // Stats (updated in real-time)
151
+ this.stats = {
152
+ filesTotal: 0,
153
+ filesProcessed: 0,
154
+ filesFailed: 0,
155
+ nodesCreated: 0,
156
+ edgesCreated: 0,
157
+ functionsFound: 0,
158
+ callsFound: 0,
159
+ startTime: null,
160
+ errors: []
161
+ };
162
+
163
+ // Stats client (for reading during analysis)
164
+ this.statsClient = null;
165
+ }
166
+
167
+ /**
168
+ * Start the analyzer (spawn workers)
169
+ */
170
+ async start(): Promise<void> {
171
+ if (this.running) return;
172
+
173
+ console.log(`[ParallelAnalyzer] Starting ${this.maxWorkers} workers...`);
174
+
175
+ // Connect stats client for real-time queries
176
+ this.statsClient = new RFDBClient(this.socketPath);
177
+ await this.statsClient.connect();
178
+
179
+ // Spawn workers
180
+ const initPromises: Promise<void>[] = [];
181
+
182
+ for (let i = 0; i < this.maxWorkers; i++) {
183
+ const worker = new Worker(WORKER_SCRIPT, {
184
+ workerData: {
185
+ workerId: i,
186
+ socketPath: this.socketPath,
187
+ autoConnect: true
188
+ }
189
+ });
190
+
191
+ const initPromise = new Promise<void>((resolve, reject) => {
192
+ const timeout = setTimeout(() => {
193
+ reject(new Error(`Worker ${i} initialization timeout`));
194
+ }, 30000);
195
+
196
+ const onMessage = (msg: WorkerResponse) => {
197
+ if (msg.type === 'ready') {
198
+ clearTimeout(timeout);
199
+ worker.removeListener('message', onMessage);
200
+ resolve();
201
+ } else if (msg.type === 'error' && !this.running) {
202
+ clearTimeout(timeout);
203
+ worker.removeListener('message', onMessage);
204
+ reject(new Error(msg.error));
205
+ }
206
+ };
207
+
208
+ worker.on('message', onMessage);
209
+ worker.once('error', (err: Error) => {
210
+ clearTimeout(timeout);
211
+ reject(err);
212
+ });
213
+ });
214
+
215
+ worker.on('message', (msg: WorkerResponse) => this._handleWorkerMessage(worker, msg));
216
+ worker.on('error', (err: Error) => this._handleWorkerError(worker, err));
217
+ worker.on('exit', (code: number) => this._handleWorkerExit(worker, code));
218
+
219
+ this.workers.push(worker);
220
+ initPromises.push(initPromise);
221
+ }
222
+
223
+ await Promise.all(initPromises);
224
+
225
+ this.readyWorkers = [...this.workers];
226
+ this.running = true;
227
+
228
+ console.log(`[ParallelAnalyzer] ${this.maxWorkers} workers ready`);
229
+ this.emit('started', { workerCount: this.maxWorkers });
230
+ }
231
+
232
+ /**
233
+ * Stop the analyzer (terminate workers)
234
+ */
235
+ async stop(): Promise<void> {
236
+ if (!this.running) return;
237
+
238
+ console.log('[ParallelAnalyzer] Stopping workers...');
239
+
240
+ // Close stats client
241
+ if (this.statsClient) {
242
+ await this.statsClient.close();
243
+ this.statsClient = null;
244
+ }
245
+
246
+ // Terminate workers
247
+ const terminatePromises = this.workers.map(worker => {
248
+ return new Promise<void>((resolve) => {
249
+ worker.once('exit', () => resolve());
250
+ worker.postMessage({ type: 'exit' });
251
+ });
252
+ });
253
+
254
+ await Promise.all(terminatePromises);
255
+
256
+ this.workers = [];
257
+ this.readyWorkers = [];
258
+ this.running = false;
259
+
260
+ console.log('[ParallelAnalyzer] Stopped');
261
+ this.emit('stopped');
262
+ }
263
+
264
+ /**
265
+ * Analyze multiple files in parallel
266
+ */
267
+ async analyzeFiles(files: FileInfo[]): Promise<AnalysisStats> {
268
+ if (!this.running) {
269
+ throw new Error('Analyzer not started. Call start() first.');
270
+ }
271
+
272
+ this.stats = {
273
+ filesTotal: files.length,
274
+ filesProcessed: 0,
275
+ filesFailed: 0,
276
+ nodesCreated: 0,
277
+ edgesCreated: 0,
278
+ functionsFound: 0,
279
+ callsFound: 0,
280
+ startTime: Date.now(),
281
+ errors: []
282
+ };
283
+
284
+ console.log(`[ParallelAnalyzer] Analyzing ${files.length} files with ${this.maxWorkers} workers...`);
285
+
286
+ // Create promises for all files
287
+ const promises = files.map(f => this._analyzeFile(f));
288
+
289
+ // Wait for all to complete
290
+ await Promise.all(promises);
291
+
292
+ const duration = Date.now() - this.stats.startTime!;
293
+ const filesPerSecond = (this.stats.filesProcessed / (duration / 1000)).toFixed(2);
294
+
295
+ console.log(`[ParallelAnalyzer] Done in ${duration}ms (${filesPerSecond} files/sec)`);
296
+ console.log(`[ParallelAnalyzer] ${this.stats.filesProcessed} succeeded, ${this.stats.filesFailed} failed`);
297
+ console.log(`[ParallelAnalyzer] ${this.stats.nodesCreated} nodes, ${this.stats.edgesCreated} edges`);
298
+
299
+ this.emit('completed', { ...this.stats, duration });
300
+
301
+ return this.stats;
302
+ }
303
+
304
+ /**
305
+ * Get current statistics (can be called during analysis)
306
+ */
307
+ getStats(): AnalysisStats & { elapsed: number; activeWorkers: number; queuedTasks: number } {
308
+ return {
309
+ ...this.stats,
310
+ elapsed: this.stats.startTime ? Date.now() - this.stats.startTime : 0,
311
+ activeWorkers: this.maxWorkers - this.readyWorkers.length,
312
+ queuedTasks: this.taskQueue.length
313
+ };
314
+ }
315
+
316
+ /**
317
+ * Get graph statistics from RFDB (can be called during analysis)
318
+ */
319
+ async getGraphStats(): Promise<GraphStats> {
320
+ if (!this.statsClient) {
321
+ throw new Error('Analyzer not started');
322
+ }
323
+
324
+ const [nodeCount, edgeCount, nodesByType, edgesByType] = await Promise.all([
325
+ this.statsClient.nodeCount(),
326
+ this.statsClient.edgeCount(),
327
+ this.statsClient.countNodesByType(),
328
+ this.statsClient.countEdgesByType()
329
+ ]);
330
+
331
+ return { nodeCount, edgeCount, nodesByType, edgesByType };
332
+ }
333
+
334
+ /**
335
+ * Query nodes from RFDB (can be called during analysis)
336
+ */
337
+ async queryNodes(nodeType: string): Promise<string[]> {
338
+ if (!this.statsClient) {
339
+ throw new Error('Analyzer not started');
340
+ }
341
+ return this.statsClient.findByType(nodeType as never);
342
+ }
343
+
344
+ // ===========================================================================
345
+ // Internal methods
346
+ // ===========================================================================
347
+
348
+ private _analyzeFile(fileInfo: FileInfo): Promise<FileStats | null> {
349
+ return new Promise((resolve, reject) => {
350
+ const taskId = this.taskIdCounter++;
351
+ const task: AnalysisTask = {
352
+ taskId,
353
+ file: fileInfo.file,
354
+ moduleId: fileInfo.moduleId || fileInfo.id || fileInfo.file,
355
+ moduleName: fileInfo.moduleName || fileInfo.name || fileInfo.file,
356
+ resolve,
357
+ reject
358
+ };
359
+
360
+ this.pendingTasks.set(taskId, task);
361
+ this._dispatchTask(task);
362
+ });
363
+ }
364
+
365
+ private _dispatchTask(task: AnalysisTask): void {
366
+ if (this.readyWorkers.length > 0) {
367
+ const worker = this.readyWorkers.pop()!;
368
+ worker.postMessage({
369
+ type: 'analyze',
370
+ file: task.file,
371
+ moduleId: task.moduleId,
372
+ moduleName: task.moduleName,
373
+ taskId: task.taskId
374
+ });
375
+ this.emit('taskStarted', { file: task.file });
376
+ } else {
377
+ this.taskQueue.push(task);
378
+ }
379
+ }
380
+
381
+ private _handleWorkerMessage(worker: Worker, msg: WorkerResponse): void {
382
+ switch (msg.type) {
383
+ case 'done': {
384
+ // Find task by file (workers don't track taskId internally)
385
+ let task: AnalysisTask | null = null;
386
+ for (const [id, t] of this.pendingTasks) {
387
+ if (t.file === msg.file) {
388
+ task = t;
389
+ this.pendingTasks.delete(id);
390
+ break;
391
+ }
392
+ }
393
+
394
+ if (task) {
395
+ // Update stats
396
+ this.stats.filesProcessed++;
397
+ this.stats.nodesCreated += msg.stats?.nodes || 0;
398
+ this.stats.edgesCreated += msg.stats?.edges || 0;
399
+ this.stats.functionsFound += msg.stats?.functions || 0;
400
+ this.stats.callsFound += msg.stats?.calls || 0;
401
+
402
+ this.emit('fileCompleted', { file: msg.file, stats: msg.stats });
403
+ task.resolve(msg.stats);
404
+ }
405
+
406
+ this._workerReady(worker);
407
+ break;
408
+ }
409
+
410
+ case 'error': {
411
+ let task: AnalysisTask | null = null;
412
+ for (const [id, t] of this.pendingTasks) {
413
+ if (t.file === msg.file) {
414
+ task = t;
415
+ this.pendingTasks.delete(id);
416
+ break;
417
+ }
418
+ }
419
+
420
+ if (task) {
421
+ this.stats.filesFailed++;
422
+ this.stats.errors.push({ file: msg.file!, error: msg.error });
423
+
424
+ this.emit('fileError', { file: msg.file, error: msg.error });
425
+ task.resolve(null); // Don't reject, just continue
426
+ }
427
+
428
+ this._workerReady(worker);
429
+ break;
430
+ }
431
+
432
+ case 'ready':
433
+ // Worker reconnected
434
+ if (!this.readyWorkers.includes(worker)) {
435
+ this._workerReady(worker);
436
+ }
437
+ break;
438
+ }
439
+ }
440
+
441
+ private _workerReady(worker: Worker): void {
442
+ if (this.taskQueue.length > 0) {
443
+ const nextTask = this.taskQueue.shift()!;
444
+ worker.postMessage({
445
+ type: 'analyze',
446
+ file: nextTask.file,
447
+ moduleId: nextTask.moduleId,
448
+ moduleName: nextTask.moduleName,
449
+ taskId: nextTask.taskId
450
+ });
451
+ this.emit('taskStarted', { file: nextTask.file });
452
+ } else {
453
+ this.readyWorkers.push(worker);
454
+ }
455
+ }
456
+
457
+ private _handleWorkerError(worker: Worker, error: Error): void {
458
+ console.error('[ParallelAnalyzer] Worker error:', error);
459
+ this.emit('workerError', { error });
460
+ }
461
+
462
+ private _handleWorkerExit(worker: Worker, code: number): void {
463
+ if (code !== 0 && this.running) {
464
+ console.error(`[ParallelAnalyzer] Worker exited with code ${code}`);
465
+ }
466
+
467
+ // Remove from lists
468
+ const idx = this.workers.indexOf(worker);
469
+ if (idx !== -1) this.workers.splice(idx, 1);
470
+
471
+ const readyIdx = this.readyWorkers.indexOf(worker);
472
+ if (readyIdx !== -1) this.readyWorkers.splice(readyIdx, 1);
473
+ }
474
+ }
475
+
476
+ export default ParallelAnalyzer;
@@ -0,0 +1,227 @@
1
+ /**
2
+ * PriorityQueue - fast task queue with priorities
3
+ *
4
+ * Uses Map for O(1) access by ID + sorted array for fast retrieval
5
+ */
6
+
7
+ import { EventEmitter } from 'events';
8
+ import type { TaskData, TaskType } from './TaskTypes.js';
9
+
10
+ /**
11
+ * Task status type
12
+ */
13
+ export type TaskStatus = 'pending' | 'running' | 'completed' | 'failed';
14
+
15
+ /**
16
+ * Task interface
17
+ */
18
+ export interface Task {
19
+ id: string;
20
+ type: TaskType;
21
+ priority: number;
22
+ status: TaskStatus;
23
+ data: TaskData;
24
+ retryCount?: number;
25
+ maxRetries?: number;
26
+ result?: unknown;
27
+ error: Error | null;
28
+ canExecute(completedTasks: Set<string>): boolean;
29
+ complete(result: unknown): void;
30
+ fail(error: Error): void;
31
+ canRetry(): boolean;
32
+ retry(): void;
33
+ start(): void;
34
+ }
35
+
36
+ /**
37
+ * Queue statistics
38
+ */
39
+ export interface QueueStats {
40
+ total: number;
41
+ pending: number;
42
+ running: number;
43
+ completed: number;
44
+ failed: number;
45
+ }
46
+
47
+ export class PriorityQueue extends EventEmitter {
48
+ private tasks: Map<string, Task>;
49
+ private sorted: Task[];
50
+ private completedTasks: Set<string>;
51
+
52
+ constructor() {
53
+ super();
54
+ this.tasks = new Map();
55
+ this.sorted = [];
56
+ this.completedTasks = new Set();
57
+ }
58
+
59
+ /**
60
+ * Add task to queue
61
+ */
62
+ add(task: Task): void {
63
+ if (this.tasks.has(task.id)) {
64
+ throw new Error(`Task ${task.id} already exists in queue`);
65
+ }
66
+
67
+ this.tasks.set(task.id, task);
68
+
69
+ // Insert with sort preservation (binary search)
70
+ this._insertSorted(task);
71
+
72
+ this.emit('task:added', task);
73
+ }
74
+
75
+ /**
76
+ * Insert into sorted array (O(log n) search + O(n) insert)
77
+ * For better performance could use heap, but for <10K tasks array is faster
78
+ */
79
+ private _insertSorted(task: Task): void {
80
+ let left = 0;
81
+ let right = this.sorted.length;
82
+
83
+ while (left < right) {
84
+ const mid = Math.floor((left + right) / 2);
85
+ if (this.sorted[mid].priority > task.priority) {
86
+ left = mid + 1;
87
+ } else {
88
+ right = mid;
89
+ }
90
+ }
91
+
92
+ this.sorted.splice(left, 0, task);
93
+ }
94
+
95
+ /**
96
+ * Remove task from sorted array
97
+ */
98
+ private _removeSorted(task: Task): void {
99
+ const index = this.sorted.indexOf(task);
100
+ if (index !== -1) {
101
+ this.sorted.splice(index, 1);
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Get next task for execution (highest priority + all dependencies ready)
107
+ * O(n) in worst case, but O(1) in practice if few dependencies
108
+ */
109
+ next(): Task | null {
110
+ for (const task of this.sorted) {
111
+ if (task.status === 'pending' && task.canExecute(this.completedTasks)) {
112
+ return task;
113
+ }
114
+ }
115
+ return null;
116
+ }
117
+
118
+ /**
119
+ * Get task by ID
120
+ */
121
+ get(id: string): Task | undefined {
122
+ return this.tasks.get(id);
123
+ }
124
+
125
+ /**
126
+ * Mark task as completed
127
+ */
128
+ complete(taskId: string, result: unknown): void {
129
+ const task = this.tasks.get(taskId);
130
+ if (!task) return;
131
+
132
+ task.complete(result);
133
+ this.completedTasks.add(taskId);
134
+ this._removeSorted(task);
135
+
136
+ this.emit('task:completed', task);
137
+ }
138
+
139
+ /**
140
+ * Mark task as failed
141
+ */
142
+ fail(taskId: string, error: Error): void {
143
+ const task = this.tasks.get(taskId);
144
+ if (!task) return;
145
+
146
+ task.fail(error);
147
+
148
+ // Retry if possible
149
+ if (task.canRetry()) {
150
+ task.retry();
151
+ this.emit('task:retry', task);
152
+ } else {
153
+ this._removeSorted(task);
154
+ this.emit('task:failed', task);
155
+ }
156
+ }
157
+
158
+ /**
159
+ * Number of tasks
160
+ */
161
+ get size(): number {
162
+ return this.tasks.size;
163
+ }
164
+
165
+ /**
166
+ * Number of pending tasks
167
+ */
168
+ get pendingCount(): number {
169
+ return this.sorted.length;
170
+ }
171
+
172
+ /**
173
+ * Number of completed tasks
174
+ */
175
+ get completedCount(): number {
176
+ return this.completedTasks.size;
177
+ }
178
+
179
+ /**
180
+ * All tasks completed?
181
+ */
182
+ get isEmpty(): boolean {
183
+ return this.sorted.length === 0;
184
+ }
185
+
186
+ /**
187
+ * Statistics
188
+ */
189
+ getStats(): QueueStats {
190
+ const stats: QueueStats = {
191
+ total: this.size,
192
+ pending: 0,
193
+ running: 0,
194
+ completed: this.completedCount,
195
+ failed: 0
196
+ };
197
+
198
+ for (const task of this.tasks.values()) {
199
+ if (task.status === 'pending') stats.pending++;
200
+ else if (task.status === 'running') stats.running++;
201
+ else if (task.status === 'failed') stats.failed++;
202
+ }
203
+
204
+ return stats;
205
+ }
206
+
207
+ /**
208
+ * Iterate over completed tasks
209
+ */
210
+ *getCompletedTasks(): Generator<Task> {
211
+ for (const task of this.tasks.values()) {
212
+ if (task.status === 'completed') {
213
+ yield task;
214
+ }
215
+ }
216
+ }
217
+
218
+ /**
219
+ * Clear queue
220
+ */
221
+ clear(): void {
222
+ this.tasks.clear();
223
+ this.sorted = [];
224
+ this.completedTasks.clear();
225
+ this.emit('queue:cleared');
226
+ }
227
+ }