ppef 1.0.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (295) hide show
  1. package/README.md +76 -125
  2. package/bin/ppef.mjs +20 -0
  3. package/dist/__tests__/cli/evaluate-command.integration.test.d.ts +8 -0
  4. package/dist/__tests__/cli/evaluate-command.integration.test.d.ts.map +1 -0
  5. package/dist/__tests__/cli/evaluate-command.integration.test.js +308 -0
  6. package/dist/__tests__/cli/evaluate-command.integration.test.js.map +1 -0
  7. package/dist/__tests__/evaluators/claims-evaluator.unit.test.d.ts +8 -0
  8. package/dist/__tests__/evaluators/claims-evaluator.unit.test.d.ts.map +1 -0
  9. package/dist/__tests__/evaluators/claims-evaluator.unit.test.js +405 -0
  10. package/dist/__tests__/evaluators/claims-evaluator.unit.test.js.map +1 -0
  11. package/dist/__tests__/evaluators/metrics-evaluator.unit.test.d.ts +8 -0
  12. package/dist/__tests__/evaluators/metrics-evaluator.unit.test.d.ts.map +1 -0
  13. package/dist/__tests__/evaluators/metrics-evaluator.unit.test.js +424 -0
  14. package/dist/__tests__/evaluators/metrics-evaluator.unit.test.js.map +1 -0
  15. package/dist/__tests__/evaluators/registry.unit.test.d.ts +7 -0
  16. package/dist/__tests__/evaluators/registry.unit.test.d.ts.map +1 -0
  17. package/dist/__tests__/evaluators/registry.unit.test.js +173 -0
  18. package/dist/__tests__/evaluators/registry.unit.test.js.map +1 -0
  19. package/dist/__tests__/evaluators/robustness-evaluator.unit.test.d.ts +8 -0
  20. package/dist/__tests__/evaluators/robustness-evaluator.unit.test.d.ts.map +1 -0
  21. package/dist/__tests__/evaluators/robustness-evaluator.unit.test.js +260 -0
  22. package/dist/__tests__/evaluators/robustness-evaluator.unit.test.js.map +1 -0
  23. package/dist/__tests__/framework-pipeline.integration.test.js +49 -20
  24. package/dist/__tests__/framework-pipeline.integration.test.js.map +1 -1
  25. package/dist/__tests__/index-exports.unit.test.d.ts +8 -0
  26. package/dist/__tests__/index-exports.unit.test.d.ts.map +1 -0
  27. package/dist/__tests__/index-exports.unit.test.js +124 -0
  28. package/dist/__tests__/index-exports.unit.test.js.map +1 -0
  29. package/dist/__tests__/registry-executor.integration.test.js +12 -9
  30. package/dist/__tests__/registry-executor.integration.test.js.map +1 -1
  31. package/dist/aggregation/__tests__/aggregators.unit.test.d.ts +7 -0
  32. package/dist/aggregation/__tests__/aggregators.unit.test.d.ts.map +1 -0
  33. package/dist/aggregation/__tests__/aggregators.unit.test.js +350 -0
  34. package/dist/aggregation/__tests__/aggregators.unit.test.js.map +1 -0
  35. package/dist/aggregation/__tests__/pipeline.unit.test.d.ts +7 -0
  36. package/dist/aggregation/__tests__/pipeline.unit.test.d.ts.map +1 -0
  37. package/dist/aggregation/__tests__/pipeline.unit.test.js +213 -0
  38. package/dist/aggregation/__tests__/pipeline.unit.test.js.map +1 -0
  39. package/dist/aggregation/aggregators.d.ts +9 -0
  40. package/dist/aggregation/aggregators.d.ts.map +1 -1
  41. package/dist/aggregation/aggregators.js +1 -1
  42. package/dist/aggregation/aggregators.js.map +1 -1
  43. package/dist/aggregation/index.d.ts +1 -1
  44. package/dist/aggregation/index.d.ts.map +1 -1
  45. package/dist/aggregation/index.js +1 -1
  46. package/dist/aggregation/index.js.map +1 -1
  47. package/dist/aggregation/pipeline.d.ts.map +1 -1
  48. package/dist/aggregation/pipeline.js +40 -3
  49. package/dist/aggregation/pipeline.js.map +1 -1
  50. package/dist/claims/index.d.ts +6 -3
  51. package/dist/claims/index.d.ts.map +1 -1
  52. package/dist/claims/index.js +6 -3
  53. package/dist/claims/index.js.map +1 -1
  54. package/dist/cli/__tests__/aggregate.command.unit.test.d.ts +7 -0
  55. package/dist/cli/__tests__/aggregate.command.unit.test.d.ts.map +1 -0
  56. package/dist/cli/__tests__/aggregate.command.unit.test.js +399 -0
  57. package/dist/cli/__tests__/aggregate.command.unit.test.js.map +1 -0
  58. package/dist/cli/__tests__/binary-sut.integration.test.d.ts +8 -0
  59. package/dist/cli/__tests__/binary-sut.integration.test.d.ts.map +1 -0
  60. package/dist/cli/__tests__/binary-sut.integration.test.js +165 -0
  61. package/dist/cli/__tests__/binary-sut.integration.test.js.map +1 -0
  62. package/dist/cli/__tests__/commands.unit.test.d.ts +10 -0
  63. package/dist/cli/__tests__/commands.unit.test.d.ts.map +1 -0
  64. package/dist/cli/__tests__/commands.unit.test.js +217 -0
  65. package/dist/cli/__tests__/commands.unit.test.js.map +1 -0
  66. package/dist/cli/__tests__/config-loader.unit.test.d.ts +7 -0
  67. package/dist/cli/__tests__/config-loader.unit.test.d.ts.map +1 -0
  68. package/dist/cli/__tests__/config-loader.unit.test.js +611 -0
  69. package/dist/cli/__tests__/config-loader.unit.test.js.map +1 -0
  70. package/dist/cli/__tests__/index.unit.test.d.ts +10 -0
  71. package/dist/cli/__tests__/index.unit.test.d.ts.map +1 -0
  72. package/dist/cli/__tests__/index.unit.test.js +65 -0
  73. package/dist/cli/__tests__/index.unit.test.js.map +1 -0
  74. package/dist/cli/__tests__/logger.unit.test.d.ts +11 -0
  75. package/dist/cli/__tests__/logger.unit.test.d.ts.map +1 -0
  76. package/dist/cli/__tests__/logger.unit.test.js +180 -0
  77. package/dist/cli/__tests__/logger.unit.test.js.map +1 -0
  78. package/dist/cli/__tests__/module-loader.unit.test.d.ts +11 -0
  79. package/dist/cli/__tests__/module-loader.unit.test.d.ts.map +1 -0
  80. package/dist/cli/__tests__/module-loader.unit.test.js +262 -0
  81. package/dist/cli/__tests__/module-loader.unit.test.js.map +1 -0
  82. package/dist/cli/__tests__/output-writer.unit.test.d.ts +10 -0
  83. package/dist/cli/__tests__/output-writer.unit.test.d.ts.map +1 -0
  84. package/dist/cli/__tests__/output-writer.unit.test.js +216 -0
  85. package/dist/cli/__tests__/output-writer.unit.test.js.map +1 -0
  86. package/dist/cli/__tests__/plan.command.unit.test.d.ts +7 -0
  87. package/dist/cli/__tests__/plan.command.unit.test.d.ts.map +1 -0
  88. package/dist/cli/__tests__/plan.command.unit.test.js +289 -0
  89. package/dist/cli/__tests__/plan.command.unit.test.js.map +1 -0
  90. package/dist/cli/__tests__/run.command.unit.test.d.ts +7 -0
  91. package/dist/cli/__tests__/run.command.unit.test.d.ts.map +1 -0
  92. package/dist/cli/__tests__/run.command.unit.test.js +422 -0
  93. package/dist/cli/__tests__/run.command.unit.test.js.map +1 -0
  94. package/dist/cli/__tests__/validate.command.unit.test.d.ts +7 -0
  95. package/dist/cli/__tests__/validate.command.unit.test.d.ts.map +1 -0
  96. package/dist/cli/__tests__/validate.command.unit.test.js +226 -0
  97. package/dist/cli/__tests__/validate.command.unit.test.js.map +1 -0
  98. package/dist/cli/command-deps.d.ts +137 -0
  99. package/dist/cli/command-deps.d.ts.map +1 -0
  100. package/dist/cli/command-deps.js +7 -0
  101. package/dist/cli/command-deps.js.map +1 -0
  102. package/dist/cli/commands/aggregate.d.ts +35 -0
  103. package/dist/cli/commands/aggregate.d.ts.map +1 -0
  104. package/dist/cli/commands/aggregate.js +124 -0
  105. package/dist/cli/commands/aggregate.js.map +1 -0
  106. package/dist/cli/commands/evaluate.d.ts +41 -0
  107. package/dist/cli/commands/evaluate.d.ts.map +1 -0
  108. package/dist/cli/commands/evaluate.js +287 -0
  109. package/dist/cli/commands/evaluate.js.map +1 -0
  110. package/dist/cli/commands/plan.d.ts +36 -0
  111. package/dist/cli/commands/plan.d.ts.map +1 -0
  112. package/dist/cli/commands/plan.js +109 -0
  113. package/dist/cli/commands/plan.js.map +1 -0
  114. package/dist/cli/commands/run.d.ts +33 -0
  115. package/dist/cli/commands/run.d.ts.map +1 -0
  116. package/dist/cli/commands/run.js +277 -0
  117. package/dist/cli/commands/run.js.map +1 -0
  118. package/dist/cli/commands/validate.d.ts +27 -0
  119. package/dist/cli/commands/validate.d.ts.map +1 -0
  120. package/dist/cli/commands/validate.js +88 -0
  121. package/dist/cli/commands/validate.js.map +1 -0
  122. package/dist/cli/config-loader.d.ts +30 -0
  123. package/dist/cli/config-loader.d.ts.map +1 -0
  124. package/dist/cli/config-loader.js +181 -0
  125. package/dist/cli/config-loader.js.map +1 -0
  126. package/dist/cli/index.d.ts +27 -0
  127. package/dist/cli/index.d.ts.map +1 -0
  128. package/dist/cli/index.js +60 -0
  129. package/dist/cli/index.js.map +1 -0
  130. package/dist/cli/logger.d.ts +75 -0
  131. package/dist/cli/logger.d.ts.map +1 -0
  132. package/dist/cli/logger.js +131 -0
  133. package/dist/cli/logger.js.map +1 -0
  134. package/dist/cli/module-loader.d.ts +68 -0
  135. package/dist/cli/module-loader.d.ts.map +1 -0
  136. package/dist/cli/module-loader.js +134 -0
  137. package/dist/cli/module-loader.js.map +1 -0
  138. package/dist/cli/output-writer.d.ts +51 -0
  139. package/dist/cli/output-writer.d.ts.map +1 -0
  140. package/dist/cli/output-writer.js +65 -0
  141. package/dist/cli/output-writer.js.map +1 -0
  142. package/dist/cli/types.d.ts +193 -0
  143. package/dist/cli/types.d.ts.map +1 -0
  144. package/dist/cli/types.js +7 -0
  145. package/dist/cli/types.js.map +1 -0
  146. package/dist/collector/__tests__/result-collector.unit.test.d.ts +7 -0
  147. package/dist/collector/__tests__/result-collector.unit.test.d.ts.map +1 -0
  148. package/dist/collector/__tests__/result-collector.unit.test.js +1021 -0
  149. package/dist/collector/__tests__/result-collector.unit.test.js.map +1 -0
  150. package/dist/collector/__tests__/schema.unit.test.d.ts +7 -0
  151. package/dist/collector/__tests__/schema.unit.test.d.ts.map +1 -0
  152. package/dist/collector/__tests__/schema.unit.test.js +360 -0
  153. package/dist/collector/__tests__/schema.unit.test.js.map +1 -0
  154. package/dist/evaluators/claims-evaluator.d.ts +87 -0
  155. package/dist/evaluators/claims-evaluator.d.ts.map +1 -0
  156. package/dist/evaluators/claims-evaluator.js +289 -0
  157. package/dist/evaluators/claims-evaluator.js.map +1 -0
  158. package/dist/evaluators/exploratory-evaluator.d.ts +136 -0
  159. package/dist/evaluators/exploratory-evaluator.d.ts.map +1 -0
  160. package/dist/evaluators/exploratory-evaluator.js +545 -0
  161. package/dist/evaluators/exploratory-evaluator.js.map +1 -0
  162. package/dist/evaluators/index.d.ts +13 -0
  163. package/dist/evaluators/index.d.ts.map +1 -0
  164. package/dist/evaluators/index.js +14 -0
  165. package/dist/evaluators/index.js.map +1 -0
  166. package/dist/evaluators/metrics-evaluator.d.ts +114 -0
  167. package/dist/evaluators/metrics-evaluator.d.ts.map +1 -0
  168. package/dist/evaluators/metrics-evaluator.js +433 -0
  169. package/dist/evaluators/metrics-evaluator.js.map +1 -0
  170. package/dist/evaluators/registry.d.ts +106 -0
  171. package/dist/evaluators/registry.d.ts.map +1 -0
  172. package/dist/evaluators/registry.js +148 -0
  173. package/dist/evaluators/registry.js.map +1 -0
  174. package/dist/evaluators/robustness-evaluator.d.ts +57 -0
  175. package/dist/evaluators/robustness-evaluator.d.ts.map +1 -0
  176. package/dist/evaluators/robustness-evaluator.js +186 -0
  177. package/dist/evaluators/robustness-evaluator.js.map +1 -0
  178. package/dist/executor/__tests__/binary-sut.unit.test.d.ts +8 -0
  179. package/dist/executor/__tests__/binary-sut.unit.test.d.ts.map +1 -0
  180. package/dist/executor/__tests__/binary-sut.unit.test.js +313 -0
  181. package/dist/executor/__tests__/binary-sut.unit.test.js.map +1 -0
  182. package/dist/executor/__tests__/checkpoint-manager.unit.test.js +83 -1
  183. package/dist/executor/__tests__/checkpoint-manager.unit.test.js.map +1 -1
  184. package/dist/executor/__tests__/checkpoint-merge-bug.diagnostic.test.d.ts +3 -6
  185. package/dist/executor/__tests__/checkpoint-merge-bug.diagnostic.test.d.ts.map +1 -1
  186. package/dist/executor/__tests__/checkpoint-merge-bug.diagnostic.test.js +428 -159
  187. package/dist/executor/__tests__/checkpoint-merge-bug.diagnostic.test.js.map +1 -1
  188. package/dist/executor/__tests__/checkpoint-storage.unit.test.js +148 -1
  189. package/dist/executor/__tests__/checkpoint-storage.unit.test.js.map +1 -1
  190. package/dist/executor/__tests__/executor.unit.test.js +123 -8
  191. package/dist/executor/__tests__/executor.unit.test.js.map +1 -1
  192. package/dist/executor/__tests__/memory-monitor.unit.test.d.ts +7 -0
  193. package/dist/executor/__tests__/memory-monitor.unit.test.d.ts.map +1 -0
  194. package/dist/executor/__tests__/memory-monitor.unit.test.js +285 -0
  195. package/dist/executor/__tests__/memory-monitor.unit.test.js.map +1 -0
  196. package/dist/executor/__tests__/parallel-executor.unit.test.d.ts +2 -1
  197. package/dist/executor/__tests__/parallel-executor.unit.test.d.ts.map +1 -1
  198. package/dist/executor/__tests__/parallel-executor.unit.test.js +426 -156
  199. package/dist/executor/__tests__/parallel-executor.unit.test.js.map +1 -1
  200. package/dist/executor/__tests__/resource-calculator.unit.test.d.ts +10 -0
  201. package/dist/executor/__tests__/resource-calculator.unit.test.d.ts.map +1 -0
  202. package/dist/executor/__tests__/resource-calculator.unit.test.js +104 -0
  203. package/dist/executor/__tests__/resource-calculator.unit.test.js.map +1 -0
  204. package/dist/executor/__tests__/run-id.unit.test.d.ts +8 -0
  205. package/dist/executor/__tests__/run-id.unit.test.d.ts.map +1 -0
  206. package/dist/executor/__tests__/run-id.unit.test.js +156 -0
  207. package/dist/executor/__tests__/run-id.unit.test.js.map +1 -0
  208. package/dist/executor/__tests__/worker-entry.integration.test.d.ts +24 -0
  209. package/dist/executor/__tests__/worker-entry.integration.test.d.ts.map +1 -0
  210. package/dist/executor/__tests__/worker-entry.integration.test.js +82 -0
  211. package/dist/executor/__tests__/worker-entry.integration.test.js.map +1 -0
  212. package/dist/executor/__tests__/worker-entry.unit.test.d.ts +7 -0
  213. package/dist/executor/__tests__/worker-entry.unit.test.d.ts.map +1 -0
  214. package/dist/executor/__tests__/worker-entry.unit.test.js +364 -0
  215. package/dist/executor/__tests__/worker-entry.unit.test.js.map +1 -0
  216. package/dist/executor/__tests__/worker-threads-executor.unit.test.d.ts +8 -0
  217. package/dist/executor/__tests__/worker-threads-executor.unit.test.d.ts.map +1 -0
  218. package/dist/executor/__tests__/worker-threads-executor.unit.test.js +276 -0
  219. package/dist/executor/__tests__/worker-threads-executor.unit.test.js.map +1 -0
  220. package/dist/executor/binary-sut.d.ts +105 -0
  221. package/dist/executor/binary-sut.d.ts.map +1 -0
  222. package/dist/executor/binary-sut.js +174 -0
  223. package/dist/executor/binary-sut.js.map +1 -0
  224. package/dist/executor/checkpoint-storage.d.ts.map +1 -1
  225. package/dist/executor/checkpoint-storage.js +6 -4
  226. package/dist/executor/checkpoint-storage.js.map +1 -1
  227. package/dist/executor/executor.d.ts +28 -0
  228. package/dist/executor/executor.d.ts.map +1 -1
  229. package/dist/executor/executor.js +85 -24
  230. package/dist/executor/executor.js.map +1 -1
  231. package/dist/executor/index.d.ts +4 -0
  232. package/dist/executor/index.d.ts.map +1 -1
  233. package/dist/executor/index.js +4 -0
  234. package/dist/executor/index.js.map +1 -1
  235. package/dist/executor/parallel-executor.d.ts +186 -0
  236. package/dist/executor/parallel-executor.d.ts.map +1 -1
  237. package/dist/executor/parallel-executor.js +218 -83
  238. package/dist/executor/parallel-executor.js.map +1 -1
  239. package/dist/executor/resource-calculator.d.ts +49 -0
  240. package/dist/executor/resource-calculator.d.ts.map +1 -0
  241. package/dist/executor/resource-calculator.js +129 -0
  242. package/dist/executor/resource-calculator.js.map +1 -0
  243. package/dist/executor/run-id.d.ts.map +1 -1
  244. package/dist/executor/run-id.js +8 -1
  245. package/dist/executor/run-id.js.map +1 -1
  246. package/dist/executor/worker-entry.d.ts +2 -0
  247. package/dist/executor/worker-entry.d.ts.map +1 -1
  248. package/dist/executor/worker-entry.js +46 -55
  249. package/dist/executor/worker-entry.js.map +1 -1
  250. package/dist/executor/worker-executor.d.ts +257 -0
  251. package/dist/executor/worker-executor.d.ts.map +1 -0
  252. package/dist/executor/worker-executor.js +308 -0
  253. package/dist/executor/worker-executor.js.map +1 -0
  254. package/dist/executor/worker-threads-executor.d.ts +245 -0
  255. package/dist/executor/worker-threads-executor.d.ts.map +1 -0
  256. package/dist/executor/worker-threads-executor.js +332 -0
  257. package/dist/executor/worker-threads-executor.js.map +1 -0
  258. package/dist/index.d.ts +1 -0
  259. package/dist/index.d.ts.map +1 -1
  260. package/dist/index.js +4 -2
  261. package/dist/index.js.map +1 -1
  262. package/dist/renderers/latex-renderer.d.ts +60 -0
  263. package/dist/renderers/latex-renderer.d.ts.map +1 -1
  264. package/dist/renderers/latex-renderer.js +299 -0
  265. package/dist/renderers/latex-renderer.js.map +1 -1
  266. package/dist/renderers/types.d.ts +9 -0
  267. package/dist/renderers/types.d.ts.map +1 -1
  268. package/dist/renderers/types.js.map +1 -1
  269. package/dist/robustness/__tests__/perturbations.unit.test.d.ts +11 -0
  270. package/dist/robustness/__tests__/perturbations.unit.test.d.ts.map +1 -0
  271. package/dist/robustness/__tests__/perturbations.unit.test.js +284 -0
  272. package/dist/robustness/__tests__/perturbations.unit.test.js.map +1 -0
  273. package/dist/robustness/index.d.ts +5 -2
  274. package/dist/robustness/index.d.ts.map +1 -1
  275. package/dist/robustness/index.js +4 -2
  276. package/dist/robustness/index.js.map +1 -1
  277. package/dist/statistical/__tests__/mann-whitney-u.unit.test.d.ts +7 -0
  278. package/dist/statistical/__tests__/mann-whitney-u.unit.test.d.ts.map +1 -0
  279. package/dist/statistical/__tests__/mann-whitney-u.unit.test.js +185 -0
  280. package/dist/statistical/__tests__/mann-whitney-u.unit.test.js.map +1 -0
  281. package/dist/types/evaluator.d.ts +449 -0
  282. package/dist/types/evaluator.d.ts.map +1 -0
  283. package/dist/types/evaluator.js +9 -0
  284. package/dist/types/evaluator.js.map +1 -0
  285. package/dist/types/result.d.ts +2 -0
  286. package/dist/types/result.d.ts.map +1 -1
  287. package/package.json +8 -1
  288. package/dist/claims/evaluator.d.ts +0 -33
  289. package/dist/claims/evaluator.d.ts.map +0 -1
  290. package/dist/claims/evaluator.js +0 -174
  291. package/dist/claims/evaluator.js.map +0 -1
  292. package/dist/robustness/analyzer.d.ts +0 -61
  293. package/dist/robustness/analyzer.d.ts.map +0 -1
  294. package/dist/robustness/analyzer.js +0 -191
  295. package/dist/robustness/analyzer.js.map +0 -1
@@ -0,0 +1,308 @@
1
+ /**
2
+ * WorkerExecutor - Core worker logic with dependency injection.
3
+ *
4
+ * This class can be tested by injecting mock dependencies,
5
+ * while worker-entry.ts provides real implementations.
6
+ *
7
+ * Two execution modes:
8
+ * 1. Legacy mode: Uses module loader to dynamically load SUTs/cases (for backward compatibility)
9
+ * 2. Serialized mode: SUTs/cases passed via WorkerMessage (for worker threads isolation)
10
+ */
11
+ /**
12
+ * Type-safe dynamic import helper.
13
+ * TypeScript's import() returns `any`, so we use a type assertion function
14
+ * to satisfy ESLint's no-unsafe-assignment rule.
15
+ */
16
+ async function dynamicImport(modulePath) {
17
+ return import(modulePath);
18
+ }
19
+ /**
20
+ * WorkerExecutor - Core worker execution logic with injected dependencies.
21
+ *
22
+ * Supports two execution modes:
23
+ * 1. Legacy mode: Uses module loader for dynamic imports (backward compatible)
24
+ * 2. Serialized mode: SUTs/cases passed via WorkerMessage (worker threads isolation)
25
+ */
26
+ export class WorkerExecutor {
27
+ parentPort;
28
+ moduleLoader;
29
+ projectRoot;
30
+ /**
31
+ * Create a new WorkerExecutor with injected dependencies.
32
+ * @param parentPort - Communication port to parent thread
33
+ * @param moduleLoader - Module loader for dynamic imports (legacy mode)
34
+ * @param projectRoot - Root directory for the project (used for module resolution)
35
+ */
36
+ constructor(parentPort, moduleLoader, projectRoot) {
37
+ this.parentPort = parentPort;
38
+ this.moduleLoader = moduleLoader;
39
+ this.projectRoot = projectRoot;
40
+ }
41
+ /**
42
+ * Start listening for messages from parent thread.
43
+ */
44
+ start() {
45
+ this.parentPort.on("message", (data) => {
46
+ void this.handleMessage(data);
47
+ });
48
+ }
49
+ /**
50
+ * Handle an incoming message from the parent thread.
51
+ */
52
+ async handleMessage(data) {
53
+ const message = data;
54
+ try {
55
+ const result = await this.executeBatch(message);
56
+ this.parentPort.postMessage({ type: "done", ...result });
57
+ }
58
+ catch (error) {
59
+ this.parentPort.postMessage({
60
+ type: "error",
61
+ error: error instanceof Error ? error.message : String(error),
62
+ });
63
+ }
64
+ }
65
+ /**
66
+ * Execute a batch of runs.
67
+ *
68
+ * Three execution modes:
69
+ * 1. Legacy mode: Uses module loader to dynamically load SUTs/cases
70
+ * 2. Serialized mode: SUTs/cases passed via WorkerMessage (for worker threads)
71
+ * 3. Registry mode: Reconstructs registry from manifest (for registry-based SUTs)
72
+ */
73
+ async executeBatch(message) {
74
+ // Check for registry manifest mode
75
+ if (message.registryManifest && message.baseDir) {
76
+ return this.executeBatchRegistry(message);
77
+ }
78
+ // Check if serialized mode (SUTs/cases provided in message)
79
+ if (message.suts && message.cases && message.baseDir) {
80
+ return this.executeBatchSerialized(message);
81
+ }
82
+ // Legacy mode: Use module loader
83
+ return this.executeBatchLegacy(message);
84
+ }
85
+ /**
86
+ * Execute using legacy mode with dynamic module loading.
87
+ * Used for backward compatibility with existing tests.
88
+ */
89
+ async executeBatchLegacy(message) {
90
+ // Import the executor and other dependencies
91
+ const executorModule = await this.moduleLoader.loadExecutor();
92
+ const evaluateModule = await this.moduleLoader.loadEvaluate();
93
+ const registryModule = await this.moduleLoader.loadRegistry();
94
+ const sutsModule = await this.moduleLoader.loadSuts();
95
+ const datasetsModule = await this.moduleLoader.loadDatasets();
96
+ // Register all datasets and SUTs
97
+ await datasetsModule.registerBenchmarkDatasets();
98
+ sutsModule.registerAllSuts();
99
+ const caseRegistry = await registryModule.registerAllBenchmarkCases();
100
+ const sutRegistry = {
101
+ list: () => ["degree-prioritised", "standard-bfs", "frontier-balanced", "random-priority"],
102
+ getFactory: () => {
103
+ // This would need to be implemented properly
104
+ return null;
105
+ },
106
+ };
107
+ const suts = evaluateModule.getSutDefinitions(sutRegistry);
108
+ const cases = evaluateModule.getCaseDefinitions(caseRegistry);
109
+ // Create executor with no onResult callback (workers don't save checkpoints)
110
+ const executor = new executorModule.Executor({
111
+ repetitions: message.config.repetitions,
112
+ seedBase: message.config.seedBase,
113
+ continueOnError: message.config.continueOnError,
114
+ timeoutMs: message.config.timeoutMs,
115
+ collectProvenance: message.config.collectProvenance,
116
+ });
117
+ // Execute the runs
118
+ const results = await executor.execute(suts, cases, () => ({}));
119
+ return {
120
+ results: results.results,
121
+ errors: results.errors,
122
+ };
123
+ }
124
+ /**
125
+ * Execute using serialized mode (SUTs/cases passed via WorkerMessage).
126
+ * This mode is used for worker threads isolation.
127
+ *
128
+ * Dynamically imports SUT and case modules based on provided definitions,
129
+ * creates an Executor instance, and executes the planned runs.
130
+ */
131
+ async executeBatchSerialized(message) {
132
+ if (!message.baseDir || !message.suts || !message.cases) {
133
+ throw new Error("Serialized mode requires baseDir, suts, and cases in WorkerMessage");
134
+ }
135
+ // Load executor module
136
+ const executorModule = await this.moduleLoader.loadExecutor();
137
+ // Load SUTs dynamically
138
+ const suts = [];
139
+ const sutMap = new Map();
140
+ for (const serializedSut of message.suts) {
141
+ try {
142
+ // Handle binary SUTs
143
+ if (serializedSut.binary) {
144
+ const binarySutModule = await dynamicImport(`${this.projectRoot}/dist/executor/binary-sut.js`);
145
+ const BinarySutClass = binarySutModule.BinarySut;
146
+ const sut = new BinarySutClass(serializedSut.id, serializedSut.binary);
147
+ const sutDefinition = {
148
+ factory: () => sut,
149
+ registration: {
150
+ ...serializedSut.registration,
151
+ id: serializedSut.id,
152
+ },
153
+ };
154
+ suts.push(sutDefinition);
155
+ sutMap.set(serializedSut.id, sutDefinition);
156
+ continue;
157
+ }
158
+ // Resolve module path (baseDir is already absolute)
159
+ const modulePath = `${this.projectRoot}/${serializedSut.module}`;
160
+ // Dynamic import from the module path
161
+ const module = await dynamicImport(modulePath);
162
+ const factory = module[serializedSut.exportName];
163
+ if (typeof factory !== "function") {
164
+ throw new Error(`Export ${serializedSut.exportName} in ${modulePath} is not a function`);
165
+ }
166
+ // Build SutDefinition object
167
+ const sutDefinition = {
168
+ factory,
169
+ registration: {
170
+ ...serializedSut.registration,
171
+ id: serializedSut.id,
172
+ },
173
+ };
174
+ suts.push(sutDefinition);
175
+ sutMap.set(serializedSut.id, sutDefinition);
176
+ }
177
+ catch (error) {
178
+ throw new Error(`Failed to load SUT "${serializedSut.id}": ${error instanceof Error ? error.message : String(error)}`);
179
+ }
180
+ }
181
+ // Load cases dynamically
182
+ const cases = [];
183
+ const caseMap = new Map();
184
+ for (const serializedCase of message.cases) {
185
+ // Resolve module path (baseDir is already absolute)
186
+ const modulePath = `${this.projectRoot}/${serializedCase.module}`;
187
+ try {
188
+ // Dynamic import from the module path
189
+ const module = await dynamicImport(modulePath);
190
+ const caseDefinitionFn = module[serializedCase.exportName];
191
+ if (typeof caseDefinitionFn !== "function") {
192
+ throw new Error(`Export ${serializedCase.exportName} in ${modulePath} is not a function`);
193
+ }
194
+ // Call the function to get the case definition
195
+ const caseDefinition = caseDefinitionFn();
196
+ // Validate that we got a proper CaseDefinition
197
+ if (typeof caseDefinition.getInput !== "function" ||
198
+ typeof caseDefinition.getInputs !== "function") {
199
+ throw new Error(`Export ${serializedCase.exportName} in ${modulePath} did not return a valid CaseDefinition`);
200
+ }
201
+ cases.push(caseDefinition);
202
+ caseMap.set(serializedCase.caseId, caseDefinition);
203
+ }
204
+ catch (error) {
205
+ throw new Error(`Failed to load case "${serializedCase.caseId}" from ${modulePath}: ${error instanceof Error ? error.message : String(error)}`);
206
+ }
207
+ }
208
+ // Create executor with config
209
+ const executor = new executorModule.Executor({
210
+ repetitions: message.config.repetitions,
211
+ seedBase: message.config.seedBase,
212
+ continueOnError: message.config.continueOnError,
213
+ timeoutMs: message.config.timeoutMs,
214
+ collectProvenance: message.config.collectProvenance,
215
+ });
216
+ // Execute the runs (pass no-op callback - workers don't save checkpoints)
217
+ const results = await executor.execute(suts, cases, () => ({}));
218
+ return {
219
+ results: results.results,
220
+ errors: results.errors,
221
+ };
222
+ }
223
+ /**
224
+ * Execute using registry manifest mode.
225
+ * Reconstructs SUT registry from manifest and executes runs.
226
+ *
227
+ * This mode enables registry-based SUTs (like GraphBox wrapper classes)
228
+ * to work with worker thread isolation without requiring standalone files.
229
+ */
230
+ async executeBatchRegistry(message) {
231
+ if (!message.baseDir || !message.registryManifest) {
232
+ throw new Error("Registry mode requires baseDir and registryManifest in WorkerMessage");
233
+ }
234
+ const { registryManifest } = message;
235
+ // Load executor module
236
+ const executorModule = await this.moduleLoader.loadExecutor();
237
+ // Reconstruct SUTs from registry manifest
238
+ const suts = [];
239
+ const sutMap = new Map();
240
+ for (const sutMeta of registryManifest.suts) {
241
+ try {
242
+ // Resolve module path from sutModules map
243
+ const modulePath = `${this.projectRoot}/${registryManifest.sutModules[sutMeta.id]}`;
244
+ // Dynamic import the SUT module
245
+ const module = await dynamicImport(modulePath);
246
+ const factory = module[registryManifest.exportName];
247
+ if (typeof factory !== "function") {
248
+ throw new Error(`Export ${registryManifest.exportName} in ${modulePath} is not a function`);
249
+ }
250
+ // Build SutDefinition object with registry metadata
251
+ const sutDefinition = {
252
+ factory,
253
+ registration: {
254
+ ...sutMeta,
255
+ },
256
+ };
257
+ suts.push(sutDefinition);
258
+ sutMap.set(sutMeta.id, sutDefinition);
259
+ }
260
+ catch (error) {
261
+ throw new Error(`Failed to load SUT "${sutMeta.id}" from registry: ${error instanceof Error ? error.message : String(error)}`);
262
+ }
263
+ }
264
+ // For registry mode, cases must still be provided separately
265
+ // This is a design limitation - full registry support would require case manifests too
266
+ if (!message.cases || message.cases.length === 0) {
267
+ throw new Error("Registry mode requires cases array in WorkerMessage");
268
+ }
269
+ // Load cases using the same logic as serialized mode
270
+ const cases = [];
271
+ const caseMap = new Map();
272
+ for (const serializedCase of message.cases) {
273
+ const modulePath = `${this.projectRoot}/${serializedCase.module}`;
274
+ try {
275
+ const module = await dynamicImport(modulePath);
276
+ const caseDefinitionFn = module[serializedCase.exportName];
277
+ if (typeof caseDefinitionFn !== "function") {
278
+ throw new Error(`Export ${serializedCase.exportName} in ${modulePath} is not a function`);
279
+ }
280
+ const caseDefinition = caseDefinitionFn();
281
+ if (typeof caseDefinition.getInput !== "function" ||
282
+ typeof caseDefinition.getInputs !== "function") {
283
+ throw new Error(`Export ${serializedCase.exportName} in ${modulePath} did not return a valid CaseDefinition`);
284
+ }
285
+ cases.push(caseDefinition);
286
+ caseMap.set(serializedCase.caseId, caseDefinition);
287
+ }
288
+ catch (error) {
289
+ throw new Error(`Failed to load case "${serializedCase.caseId}" from ${modulePath}: ${error instanceof Error ? error.message : String(error)}`);
290
+ }
291
+ }
292
+ // Create executor with config
293
+ const executor = new executorModule.Executor({
294
+ repetitions: message.config.repetitions,
295
+ seedBase: message.config.seedBase,
296
+ continueOnError: message.config.continueOnError,
297
+ timeoutMs: message.config.timeoutMs,
298
+ collectProvenance: message.config.collectProvenance,
299
+ });
300
+ // Execute the runs
301
+ const results = await executor.execute(suts, cases, () => ({}));
302
+ return {
303
+ results: results.results,
304
+ errors: results.errors,
305
+ };
306
+ }
307
+ }
308
+ //# sourceMappingURL=worker-executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-executor.js","sourceRoot":"","sources":["../../src/executor/worker-executor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,245 @@
1
+ /**
2
+ * Worker Threads Executor
3
+ *
4
+ * Executes experiments using Node.js worker threads for parallelism.
5
+ * Each worker runs in isolation, preventing SUT crashes from affecting the main process.
6
+ *
7
+ * Architecture:
8
+ * - Main thread spawns N worker threads (75% of CPU cores by default)
9
+ * - Each worker receives a batch of runs via postMessage
10
+ * - Workers write results to sharded checkpoint files
11
+ * - Main thread merges shards after all workers complete
12
+ *
13
+ * Benefits:
14
+ * - Main thread isolation: SUT crashes don't crash the CLI
15
+ * - True parallelism: Workers run on separate OS threads
16
+ * - Resource managed: Automatic 75% resource allocation
17
+ * - Fault tolerance: Single worker failure doesn't stop others
18
+ *
19
+ * Dependency Injection:
20
+ * - Logger interface enables testing of log output
21
+ * - WorkerFactory interface enables mocking Worker for testing
22
+ * - WorkerEntryPath interface enables testing worker path resolution
23
+ */
24
+ import type { EvaluationResult } from "../types/result.js";
25
+ import type { ExecutorConfig, PlannedRun } from "./executor.js";
26
+ import type { WorkerMessage, WorkerOutputMessage } from "./worker-executor.js";
27
+ import type { ResourceLimits } from "./resource-calculator.js";
28
+ /**
29
+ * Logger interface for output handling.
30
+ * Enables testing of log messages.
31
+ */
32
+ export interface ILogger {
33
+ log(message: string): void;
34
+ debug(message: string): void;
35
+ info(message: string): void;
36
+ warn(message: string): void;
37
+ }
38
+ /**
39
+ * Production logger using console.
40
+ */
41
+ export declare class ConsoleLogger implements ILogger {
42
+ log(message: string): void;
43
+ debug(message: string): void;
44
+ info(message: string): void;
45
+ warn(message: string): void;
46
+ }
47
+ /**
48
+ * Worker interface.
49
+ * Abstraction over Node.js Worker.
50
+ */
51
+ export interface IWorker {
52
+ postMessage(message: WorkerMessage): void;
53
+ on(event: "message", listener: (data: WorkerOutputMessage) => void): void;
54
+ on(event: "error", listener: (error: Error) => void): void;
55
+ terminate(): Promise<number>;
56
+ }
57
+ /**
58
+ * Worker factory interface.
59
+ * Enables mocking of Worker construction for testing.
60
+ */
61
+ export interface IWorkerFactory {
62
+ create(workerPath: string): IWorker;
63
+ }
64
+ /**
65
+ * Production worker factory using node:worker_threads.
66
+ * Registers the tsx loader when spawning workers from TypeScript source.
67
+ */
68
+ export declare class WorkerFactory implements IWorkerFactory {
69
+ create(workerPath: string): IWorker;
70
+ }
71
+ /**
72
+ * Path resolver interface.
73
+ * Enables testing of worker entry path resolution.
74
+ */
75
+ export interface IWorkerEntryPath {
76
+ /**
77
+ * Get the absolute path to the worker entry point.
78
+ */
79
+ getWorkerEntryPath(): string;
80
+ }
81
+ /**
82
+ * Production path resolver using import.meta.url.
83
+ * Handles both compiled (dist/*.js) and source (src/*.ts via tsx) contexts.
84
+ */
85
+ export declare class WorkerEntryPath implements IWorkerEntryPath {
86
+ getWorkerEntryPath(): string;
87
+ }
88
+ /**
89
+ * Batch of runs for a worker.
90
+ */
91
+ export interface RunBatch {
92
+ /** Batch index */
93
+ index: number;
94
+ /** Run IDs in this batch */
95
+ runIds: string[];
96
+ /** Runs in this batch */
97
+ runs: PlannedRun[];
98
+ /** First run ID in batch */
99
+ firstRunId: string;
100
+ /** Last run ID in batch */
101
+ lastRunId: string;
102
+ }
103
+ /**
104
+ * Worker threads executor options.
105
+ */
106
+ export interface WorkerThreadsExecutorOptions {
107
+ /** Number of worker threads (default: auto-calculated from 75% CPU) */
108
+ workers?: number;
109
+ /** Maximum memory per worker in MB */
110
+ maxMemoryMb?: number;
111
+ /** Maximum concurrent I/O operations per worker */
112
+ maxConcurrentIo?: number;
113
+ /** Logger instance */
114
+ logger?: ILogger;
115
+ /** Worker factory instance */
116
+ workerFactory?: IWorkerFactory;
117
+ /** Worker entry path resolver */
118
+ workerEntryPath?: IWorkerEntryPath;
119
+ /** Base directory for resolving module paths (default: process.cwd()) */
120
+ baseDir?: string;
121
+ /** Use registry manifest mode for SUTs (enables registry-based SUTs with worker isolation) */
122
+ useRegistryManifest?: boolean;
123
+ }
124
+ /**
125
+ * Worker threads executor class with dependency injection.
126
+ *
127
+ * Executes experiments using Node.js worker threads for parallelism.
128
+ * Each worker runs in isolation, preventing SUT crashes from affecting the main process.
129
+ */
130
+ export declare class WorkerThreadsExecutor {
131
+ private readonly logger;
132
+ private readonly workerFactory;
133
+ private readonly workerEntryPath;
134
+ private readonly baseDir;
135
+ private readonly useRegistryManifest;
136
+ constructor(options?: WorkerThreadsExecutorOptions);
137
+ /**
138
+ * Split runs into batches for parallel processing.
139
+ * @param runs - Runs to distribute
140
+ * @param numberWorkers - Number of worker threads
141
+ * @returns Array of run batches
142
+ */
143
+ private _createBatches;
144
+ /**
145
+ * Execute runs using multiple worker threads.
146
+ *
147
+ * Each worker writes to its own sharded checkpoint file to avoid race conditions.
148
+ * After all workers complete, results are aggregated and returned.
149
+ *
150
+ * @param runs - Planned runs to execute
151
+ * @param suts - SUT definitions (serialized and passed to workers)
152
+ * @param cases - Case definitions (serialized and passed to workers)
153
+ * @param config - Executor configuration
154
+ * @param options - Worker threads executor options
155
+ * @param checkpointDir - Checkpoint directory for shard files
156
+ * @returns Execution results
157
+ */
158
+ execute(runs: PlannedRun[], suts: {
159
+ registration: {
160
+ id: string;
161
+ name: string;
162
+ version: string;
163
+ role: string;
164
+ };
165
+ factory: unknown;
166
+ }[], cases: {
167
+ case: {
168
+ caseId: string;
169
+ };
170
+ getInput: () => Promise<unknown>;
171
+ getInputs: () => unknown;
172
+ }[], config: ExecutorConfig & {
173
+ onResult?: (result: EvaluationResult) => void;
174
+ }, options?: WorkerThreadsExecutorOptions, checkpointDir?: string): Promise<{
175
+ results: EvaluationResult[];
176
+ errors: {
177
+ runId: string;
178
+ error: string;
179
+ }[];
180
+ }>;
181
+ /**
182
+ * Spawn worker threads for all batches.
183
+ * @param batches - Run batches
184
+ * @param workerPath - Path to worker entry point
185
+ * @param checkpointDir - Checkpoint directory
186
+ * @param config - Executor configuration
187
+ * @param suts - SUT definitions to serialize
188
+ * @param cases - Case definitions to serialize
189
+ * @returns Array of worker states
190
+ */
191
+ private _spawnWorkers;
192
+ /**
193
+ * Handle a message from a worker.
194
+ * @param state - Worker state
195
+ * @param data - Message data
196
+ * @param config - Executor configuration
197
+ */
198
+ private _handleWorkerMessage;
199
+ /**
200
+ * Wait for all workers to complete.
201
+ * @param workerStates - Worker states
202
+ * @returns Promise that resolves when all workers complete
203
+ */
204
+ private _waitForWorkers;
205
+ }
206
+ /**
207
+ * Execute runs using multiple worker threads.
208
+ *
209
+ * Each worker writes to its own sharded checkpoint file to avoid race conditions.
210
+ * After all workers complete, results are aggregated and returned.
211
+ *
212
+ * This is a convenience function that creates a WorkerThreadsExecutor with default dependencies.
213
+ * For testing or custom behavior, use the WorkerThreadsExecutor class directly.
214
+ *
215
+ * @param runs - Planned runs to execute
216
+ * @param suts - SUT definitions (serialized and passed to workers)
217
+ * @param cases - Case definitions (serialized and passed to workers)
218
+ * @param config - Executor configuration
219
+ * @param options - Worker threads executor options
220
+ * @returns Execution results
221
+ */
222
+ export declare const executeWithWorkerThreads: (runs: PlannedRun[], suts: {
223
+ registration: {
224
+ id: string;
225
+ name: string;
226
+ version: string;
227
+ role: string;
228
+ };
229
+ factory: unknown;
230
+ }[], cases: {
231
+ case: {
232
+ caseId: string;
233
+ };
234
+ getInput: () => Promise<unknown>;
235
+ getInputs: () => unknown;
236
+ }[], config: ExecutorConfig & {
237
+ onResult?: (result: EvaluationResult) => void;
238
+ }, options?: WorkerThreadsExecutorOptions & Partial<ResourceLimits>) => Promise<{
239
+ results: EvaluationResult[];
240
+ errors: {
241
+ runId: string;
242
+ error: string;
243
+ }[];
244
+ }>;
245
+ //# sourceMappingURL=worker-threads-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-threads-executor.d.ts","sourceRoot":"","sources":["../../src/executor/worker-threads-executor.ts"],"names":[],"mappings":"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"}