groundswell 0.0.3 → 1.0.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 (292) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +26 -9
  3. package/dist/cache/cache-key.d.ts +20 -0
  4. package/dist/cache/cache-key.d.ts.map +1 -1
  5. package/dist/cache/cache-key.js +9 -0
  6. package/dist/cache/cache-key.js.map +1 -1
  7. package/dist/core/agent.d.ts +120 -29
  8. package/dist/core/agent.d.ts.map +1 -1
  9. package/dist/core/agent.js +584 -177
  10. package/dist/core/agent.js.map +1 -1
  11. package/dist/core/mcp-handler.d.ts +63 -5
  12. package/dist/core/mcp-handler.d.ts.map +1 -1
  13. package/dist/core/mcp-handler.js +184 -4
  14. package/dist/core/mcp-handler.js.map +1 -1
  15. package/dist/core/workflow-context.d.ts +6 -2
  16. package/dist/core/workflow-context.d.ts.map +1 -1
  17. package/dist/core/workflow-context.js +99 -4
  18. package/dist/core/workflow-context.js.map +1 -1
  19. package/dist/core/workflow.d.ts +315 -13
  20. package/dist/core/workflow.d.ts.map +1 -1
  21. package/dist/core/workflow.js +552 -30
  22. package/dist/core/workflow.js.map +1 -1
  23. package/dist/debugger/event-replayer.d.ts +422 -0
  24. package/dist/debugger/event-replayer.d.ts.map +1 -0
  25. package/dist/debugger/event-replayer.js +639 -0
  26. package/dist/debugger/event-replayer.js.map +1 -0
  27. package/dist/debugger/tree-debugger.d.ts +170 -1
  28. package/dist/debugger/tree-debugger.d.ts.map +1 -1
  29. package/dist/debugger/tree-debugger.js +423 -1
  30. package/dist/debugger/tree-debugger.js.map +1 -1
  31. package/dist/decorators/step.d.ts.map +1 -1
  32. package/dist/decorators/step.js +129 -47
  33. package/dist/decorators/step.js.map +1 -1
  34. package/dist/harnesses/claude-code-harness.d.ts +391 -0
  35. package/dist/harnesses/claude-code-harness.d.ts.map +1 -0
  36. package/dist/harnesses/claude-code-harness.js +1076 -0
  37. package/dist/harnesses/claude-code-harness.js.map +1 -0
  38. package/dist/harnesses/harness-registry.d.ts +440 -0
  39. package/dist/harnesses/harness-registry.d.ts.map +1 -0
  40. package/dist/harnesses/harness-registry.js +543 -0
  41. package/dist/harnesses/harness-registry.js.map +1 -0
  42. package/dist/harnesses/index.d.ts +12 -0
  43. package/dist/harnesses/index.d.ts.map +1 -0
  44. package/dist/harnesses/index.js +11 -0
  45. package/dist/harnesses/index.js.map +1 -0
  46. package/dist/harnesses/pi-harness.d.ts +219 -0
  47. package/dist/harnesses/pi-harness.d.ts.map +1 -0
  48. package/dist/harnesses/pi-harness.js +676 -0
  49. package/dist/harnesses/pi-harness.js.map +1 -0
  50. package/dist/harnesses/pi-schema-converter.d.ts +24 -0
  51. package/dist/harnesses/pi-schema-converter.d.ts.map +1 -0
  52. package/dist/harnesses/pi-schema-converter.js +81 -0
  53. package/dist/harnesses/pi-schema-converter.js.map +1 -0
  54. package/dist/harnesses/register-defaults.d.ts +24 -0
  55. package/dist/harnesses/register-defaults.d.ts.map +1 -0
  56. package/dist/harnesses/register-defaults.js +40 -0
  57. package/dist/harnesses/register-defaults.js.map +1 -0
  58. package/dist/harnesses/session-store.d.ts +201 -0
  59. package/dist/harnesses/session-store.d.ts.map +1 -0
  60. package/dist/harnesses/session-store.js +254 -0
  61. package/dist/harnesses/session-store.js.map +1 -0
  62. package/dist/index.d.ts +12 -2
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.js +17 -0
  65. package/dist/index.js.map +1 -1
  66. package/dist/reflection/reflection.d.ts.map +1 -1
  67. package/dist/reflection/reflection.js +19 -4
  68. package/dist/reflection/reflection.js.map +1 -1
  69. package/dist/types/agent.d.ts +1253 -2
  70. package/dist/types/agent.d.ts.map +1 -1
  71. package/dist/types/agent.js +418 -1
  72. package/dist/types/agent.js.map +1 -1
  73. package/dist/types/decorators.d.ts +10 -1
  74. package/dist/types/decorators.d.ts.map +1 -1
  75. package/dist/types/events.d.ts +26 -0
  76. package/dist/types/events.d.ts.map +1 -1
  77. package/dist/types/harnesses.d.ts +474 -0
  78. package/dist/types/harnesses.d.ts.map +1 -0
  79. package/dist/types/harnesses.js +2 -0
  80. package/dist/types/harnesses.js.map +1 -0
  81. package/dist/types/index.d.ts +9 -1
  82. package/dist/types/index.d.ts.map +1 -1
  83. package/dist/types/index.js +6 -0
  84. package/dist/types/index.js.map +1 -1
  85. package/dist/types/providers.d.ts +691 -0
  86. package/dist/types/providers.d.ts.map +1 -0
  87. package/dist/types/providers.js +14 -0
  88. package/dist/types/providers.js.map +1 -0
  89. package/dist/types/restart.d.ts +132 -0
  90. package/dist/types/restart.d.ts.map +1 -0
  91. package/dist/types/restart.js +2 -0
  92. package/dist/types/restart.js.map +1 -0
  93. package/dist/types/streaming.d.ts +194 -0
  94. package/dist/types/streaming.d.ts.map +1 -0
  95. package/dist/types/streaming.js +67 -0
  96. package/dist/types/streaming.js.map +1 -0
  97. package/dist/types/workflow-context.d.ts +137 -1
  98. package/dist/types/workflow-context.d.ts.map +1 -1
  99. package/dist/utils/agent-validation.d.ts +88 -0
  100. package/dist/utils/agent-validation.d.ts.map +1 -0
  101. package/dist/utils/agent-validation.js +87 -0
  102. package/dist/utils/agent-validation.js.map +1 -0
  103. package/dist/utils/delay.d.ts +7 -0
  104. package/dist/utils/delay.d.ts.map +1 -0
  105. package/dist/utils/delay.js +9 -0
  106. package/dist/utils/delay.js.map +1 -0
  107. package/dist/utils/harness-config.d.ts +180 -0
  108. package/dist/utils/harness-config.d.ts.map +1 -0
  109. package/dist/utils/harness-config.js +311 -0
  110. package/dist/utils/harness-config.js.map +1 -0
  111. package/dist/utils/index.d.ts +9 -1
  112. package/dist/utils/index.d.ts.map +1 -1
  113. package/dist/utils/index.js +8 -1
  114. package/dist/utils/index.js.map +1 -1
  115. package/dist/utils/model-spec.d.ts +110 -0
  116. package/dist/utils/model-spec.d.ts.map +1 -0
  117. package/dist/utils/model-spec.js +149 -0
  118. package/dist/utils/model-spec.js.map +1 -0
  119. package/dist/utils/provider-config.d.ts +10 -0
  120. package/dist/utils/provider-config.d.ts.map +1 -0
  121. package/dist/utils/provider-config.js +10 -0
  122. package/dist/utils/provider-config.js.map +1 -0
  123. package/dist/utils/restart-analysis.d.ts +202 -0
  124. package/dist/utils/restart-analysis.d.ts.map +1 -0
  125. package/dist/utils/restart-analysis.js +426 -0
  126. package/dist/utils/restart-analysis.js.map +1 -0
  127. package/dist/utils/session-serialization.d.ts +118 -0
  128. package/dist/utils/session-serialization.d.ts.map +1 -0
  129. package/dist/utils/session-serialization.js +217 -0
  130. package/dist/utils/session-serialization.js.map +1 -0
  131. package/package.json +31 -5
  132. package/CHANGELOG.md +0 -188
  133. package/dist/__tests__/adversarial/attachChild-performance.test.d.ts +0 -16
  134. package/dist/__tests__/adversarial/attachChild-performance.test.d.ts.map +0 -1
  135. package/dist/__tests__/adversarial/attachChild-performance.test.js +0 -187
  136. package/dist/__tests__/adversarial/attachChild-performance.test.js.map +0 -1
  137. package/dist/__tests__/adversarial/circular-reference.test.d.ts +0 -13
  138. package/dist/__tests__/adversarial/circular-reference.test.d.ts.map +0 -1
  139. package/dist/__tests__/adversarial/circular-reference.test.js +0 -92
  140. package/dist/__tests__/adversarial/circular-reference.test.js.map +0 -1
  141. package/dist/__tests__/adversarial/complex-circular-reference.test.d.ts +0 -16
  142. package/dist/__tests__/adversarial/complex-circular-reference.test.d.ts.map +0 -1
  143. package/dist/__tests__/adversarial/complex-circular-reference.test.js +0 -127
  144. package/dist/__tests__/adversarial/complex-circular-reference.test.js.map +0 -1
  145. package/dist/__tests__/adversarial/concurrent-task-failures.test.d.ts +0 -21
  146. package/dist/__tests__/adversarial/concurrent-task-failures.test.d.ts.map +0 -1
  147. package/dist/__tests__/adversarial/concurrent-task-failures.test.js +0 -667
  148. package/dist/__tests__/adversarial/concurrent-task-failures.test.js.map +0 -1
  149. package/dist/__tests__/adversarial/deep-analysis.test.d.ts +0 -6
  150. package/dist/__tests__/adversarial/deep-analysis.test.d.ts.map +0 -1
  151. package/dist/__tests__/adversarial/deep-analysis.test.js +0 -877
  152. package/dist/__tests__/adversarial/deep-analysis.test.js.map +0 -1
  153. package/dist/__tests__/adversarial/deep-hierarchy-stress.test.d.ts +0 -13
  154. package/dist/__tests__/adversarial/deep-hierarchy-stress.test.d.ts.map +0 -1
  155. package/dist/__tests__/adversarial/deep-hierarchy-stress.test.js +0 -186
  156. package/dist/__tests__/adversarial/deep-hierarchy-stress.test.js.map +0 -1
  157. package/dist/__tests__/adversarial/e2e-prd-validation.test.d.ts +0 -6
  158. package/dist/__tests__/adversarial/e2e-prd-validation.test.d.ts.map +0 -1
  159. package/dist/__tests__/adversarial/e2e-prd-validation.test.js +0 -626
  160. package/dist/__tests__/adversarial/e2e-prd-validation.test.js.map +0 -1
  161. package/dist/__tests__/adversarial/edge-case.test.d.ts +0 -6
  162. package/dist/__tests__/adversarial/edge-case.test.d.ts.map +0 -1
  163. package/dist/__tests__/adversarial/edge-case.test.js +0 -857
  164. package/dist/__tests__/adversarial/edge-case.test.js.map +0 -1
  165. package/dist/__tests__/adversarial/error-merge-strategy.test.d.ts +0 -20
  166. package/dist/__tests__/adversarial/error-merge-strategy.test.d.ts.map +0 -1
  167. package/dist/__tests__/adversarial/error-merge-strategy.test.js +0 -907
  168. package/dist/__tests__/adversarial/error-merge-strategy.test.js.map +0 -1
  169. package/dist/__tests__/adversarial/incremental-performance.test.d.ts +0 -2
  170. package/dist/__tests__/adversarial/incremental-performance.test.d.ts.map +0 -1
  171. package/dist/__tests__/adversarial/incremental-performance.test.js +0 -113
  172. package/dist/__tests__/adversarial/incremental-performance.test.js.map +0 -1
  173. package/dist/__tests__/adversarial/node-map-update-benchmarks.test.d.ts +0 -22
  174. package/dist/__tests__/adversarial/node-map-update-benchmarks.test.d.ts.map +0 -1
  175. package/dist/__tests__/adversarial/node-map-update-benchmarks.test.js +0 -383
  176. package/dist/__tests__/adversarial/node-map-update-benchmarks.test.js.map +0 -1
  177. package/dist/__tests__/adversarial/observer-propagation.test.d.ts +0 -21
  178. package/dist/__tests__/adversarial/observer-propagation.test.d.ts.map +0 -1
  179. package/dist/__tests__/adversarial/observer-propagation.test.js +0 -404
  180. package/dist/__tests__/adversarial/observer-propagation.test.js.map +0 -1
  181. package/dist/__tests__/adversarial/parent-validation.test.d.ts +0 -13
  182. package/dist/__tests__/adversarial/parent-validation.test.d.ts.map +0 -1
  183. package/dist/__tests__/adversarial/parent-validation.test.js +0 -128
  184. package/dist/__tests__/adversarial/parent-validation.test.js.map +0 -1
  185. package/dist/__tests__/adversarial/prd-12-2-compliance.test.d.ts +0 -20
  186. package/dist/__tests__/adversarial/prd-12-2-compliance.test.d.ts.map +0 -1
  187. package/dist/__tests__/adversarial/prd-12-2-compliance.test.js +0 -482
  188. package/dist/__tests__/adversarial/prd-12-2-compliance.test.js.map +0 -1
  189. package/dist/__tests__/adversarial/prd-compliance.test.d.ts +0 -6
  190. package/dist/__tests__/adversarial/prd-compliance.test.d.ts.map +0 -1
  191. package/dist/__tests__/adversarial/prd-compliance.test.js +0 -886
  192. package/dist/__tests__/adversarial/prd-compliance.test.js.map +0 -1
  193. package/dist/__tests__/compatibility/backward-compatibility.test.d.ts +0 -22
  194. package/dist/__tests__/compatibility/backward-compatibility.test.d.ts.map +0 -1
  195. package/dist/__tests__/compatibility/backward-compatibility.test.js +0 -1843
  196. package/dist/__tests__/compatibility/backward-compatibility.test.js.map +0 -1
  197. package/dist/__tests__/helpers/index.d.ts +0 -10
  198. package/dist/__tests__/helpers/index.d.ts.map +0 -1
  199. package/dist/__tests__/helpers/index.js +0 -10
  200. package/dist/__tests__/helpers/index.js.map +0 -1
  201. package/dist/__tests__/helpers/tree-verification.d.ts +0 -90
  202. package/dist/__tests__/helpers/tree-verification.d.ts.map +0 -1
  203. package/dist/__tests__/helpers/tree-verification.js +0 -202
  204. package/dist/__tests__/helpers/tree-verification.js.map +0 -1
  205. package/dist/__tests__/integration/agent-workflow.test.d.ts +0 -2
  206. package/dist/__tests__/integration/agent-workflow.test.d.ts.map +0 -1
  207. package/dist/__tests__/integration/agent-workflow.test.js +0 -256
  208. package/dist/__tests__/integration/agent-workflow.test.js.map +0 -1
  209. package/dist/__tests__/integration/bidirectional-consistency.test.d.ts +0 -14
  210. package/dist/__tests__/integration/bidirectional-consistency.test.d.ts.map +0 -1
  211. package/dist/__tests__/integration/bidirectional-consistency.test.js +0 -668
  212. package/dist/__tests__/integration/bidirectional-consistency.test.js.map +0 -1
  213. package/dist/__tests__/integration/observer-logging.test.d.ts +0 -2
  214. package/dist/__tests__/integration/observer-logging.test.d.ts.map +0 -1
  215. package/dist/__tests__/integration/observer-logging.test.js +0 -517
  216. package/dist/__tests__/integration/observer-logging.test.js.map +0 -1
  217. package/dist/__tests__/integration/tree-mirroring.test.d.ts +0 -2
  218. package/dist/__tests__/integration/tree-mirroring.test.d.ts.map +0 -1
  219. package/dist/__tests__/integration/tree-mirroring.test.js +0 -117
  220. package/dist/__tests__/integration/tree-mirroring.test.js.map +0 -1
  221. package/dist/__tests__/integration/workflow-reparenting.test.d.ts +0 -12
  222. package/dist/__tests__/integration/workflow-reparenting.test.d.ts.map +0 -1
  223. package/dist/__tests__/integration/workflow-reparenting.test.js +0 -239
  224. package/dist/__tests__/integration/workflow-reparenting.test.js.map +0 -1
  225. package/dist/__tests__/unit/agent.test.d.ts +0 -2
  226. package/dist/__tests__/unit/agent.test.d.ts.map +0 -1
  227. package/dist/__tests__/unit/agent.test.js +0 -143
  228. package/dist/__tests__/unit/agent.test.js.map +0 -1
  229. package/dist/__tests__/unit/cache-key.test.d.ts +0 -5
  230. package/dist/__tests__/unit/cache-key.test.d.ts.map +0 -1
  231. package/dist/__tests__/unit/cache-key.test.js +0 -145
  232. package/dist/__tests__/unit/cache-key.test.js.map +0 -1
  233. package/dist/__tests__/unit/cache.test.d.ts +0 -5
  234. package/dist/__tests__/unit/cache.test.d.ts.map +0 -1
  235. package/dist/__tests__/unit/cache.test.js +0 -132
  236. package/dist/__tests__/unit/cache.test.js.map +0 -1
  237. package/dist/__tests__/unit/context.test.d.ts +0 -2
  238. package/dist/__tests__/unit/context.test.d.ts.map +0 -1
  239. package/dist/__tests__/unit/context.test.js +0 -220
  240. package/dist/__tests__/unit/context.test.js.map +0 -1
  241. package/dist/__tests__/unit/decorators.test.d.ts +0 -2
  242. package/dist/__tests__/unit/decorators.test.d.ts.map +0 -1
  243. package/dist/__tests__/unit/decorators.test.js +0 -162
  244. package/dist/__tests__/unit/decorators.test.js.map +0 -1
  245. package/dist/__tests__/unit/introspection-tools.test.d.ts +0 -5
  246. package/dist/__tests__/unit/introspection-tools.test.d.ts.map +0 -1
  247. package/dist/__tests__/unit/introspection-tools.test.js +0 -191
  248. package/dist/__tests__/unit/introspection-tools.test.js.map +0 -1
  249. package/dist/__tests__/unit/logger.test.d.ts +0 -2
  250. package/dist/__tests__/unit/logger.test.d.ts.map +0 -1
  251. package/dist/__tests__/unit/logger.test.js +0 -241
  252. package/dist/__tests__/unit/logger.test.js.map +0 -1
  253. package/dist/__tests__/unit/observable.test.d.ts +0 -2
  254. package/dist/__tests__/unit/observable.test.d.ts.map +0 -1
  255. package/dist/__tests__/unit/observable.test.js +0 -251
  256. package/dist/__tests__/unit/observable.test.js.map +0 -1
  257. package/dist/__tests__/unit/prompt.test.d.ts +0 -2
  258. package/dist/__tests__/unit/prompt.test.d.ts.map +0 -1
  259. package/dist/__tests__/unit/prompt.test.js +0 -113
  260. package/dist/__tests__/unit/prompt.test.js.map +0 -1
  261. package/dist/__tests__/unit/reflection.test.d.ts +0 -5
  262. package/dist/__tests__/unit/reflection.test.d.ts.map +0 -1
  263. package/dist/__tests__/unit/reflection.test.js +0 -160
  264. package/dist/__tests__/unit/reflection.test.js.map +0 -1
  265. package/dist/__tests__/unit/tree-debugger-incremental.test.d.ts +0 -2
  266. package/dist/__tests__/unit/tree-debugger-incremental.test.d.ts.map +0 -1
  267. package/dist/__tests__/unit/tree-debugger-incremental.test.js +0 -136
  268. package/dist/__tests__/unit/tree-debugger-incremental.test.js.map +0 -1
  269. package/dist/__tests__/unit/tree-debugger.test.d.ts +0 -2
  270. package/dist/__tests__/unit/tree-debugger.test.d.ts.map +0 -1
  271. package/dist/__tests__/unit/tree-debugger.test.js +0 -69
  272. package/dist/__tests__/unit/tree-debugger.test.js.map +0 -1
  273. package/dist/__tests__/unit/utils/workflow-error-utils.test.d.ts +0 -2
  274. package/dist/__tests__/unit/utils/workflow-error-utils.test.d.ts.map +0 -1
  275. package/dist/__tests__/unit/utils/workflow-error-utils.test.js +0 -154
  276. package/dist/__tests__/unit/utils/workflow-error-utils.test.js.map +0 -1
  277. package/dist/__tests__/unit/workflow-detachChild.test.d.ts +0 -2
  278. package/dist/__tests__/unit/workflow-detachChild.test.d.ts.map +0 -1
  279. package/dist/__tests__/unit/workflow-detachChild.test.js +0 -76
  280. package/dist/__tests__/unit/workflow-detachChild.test.js.map +0 -1
  281. package/dist/__tests__/unit/workflow-emitEvent-childDetached.test.d.ts +0 -2
  282. package/dist/__tests__/unit/workflow-emitEvent-childDetached.test.d.ts.map +0 -1
  283. package/dist/__tests__/unit/workflow-emitEvent-childDetached.test.js +0 -122
  284. package/dist/__tests__/unit/workflow-emitEvent-childDetached.test.js.map +0 -1
  285. package/dist/__tests__/unit/workflow-isDescendantOf.test.d.ts +0 -2
  286. package/dist/__tests__/unit/workflow-isDescendantOf.test.d.ts.map +0 -1
  287. package/dist/__tests__/unit/workflow-isDescendantOf.test.js +0 -140
  288. package/dist/__tests__/unit/workflow-isDescendantOf.test.js.map +0 -1
  289. package/dist/__tests__/unit/workflow.test.d.ts +0 -2
  290. package/dist/__tests__/unit/workflow.test.d.ts.map +0 -1
  291. package/dist/__tests__/unit/workflow.test.js +0 -330
  292. package/dist/__tests__/unit/workflow.test.js.map +0 -1
@@ -1,907 +0,0 @@
1
- /**
2
- * ErrorMergeStrategy Functionality Test Suite
3
- *
4
- * Tests the ErrorMergeStrategy feature for concurrent task error aggregation.
5
- *
6
- * Validates:
7
- * - Default behavior (disabled) - first error wins
8
- * - Enabled with default merge - uses mergeWorkflowErrors
9
- * - Enabled with custom combine - user-provided merger
10
- * - Edge cases - single failure, all failing, mixed scenarios
11
- * - Event emission - individual and merged error events
12
- * - Completion verification - all workflows complete
13
- *
14
- * Related:
15
- * - P1.M2.T2.S2: Error aggregation logic implementation
16
- * - P1.M2.T2.S3: Default error merger utility
17
- * - Bug: 001_e8e04329daf3 - Concurrent task error handling
18
- */
19
- var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
20
- var useValue = arguments.length > 2;
21
- for (var i = 0; i < initializers.length; i++) {
22
- value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
23
- }
24
- return useValue ? value : void 0;
25
- };
26
- var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
27
- function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
28
- var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
29
- var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
30
- var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
31
- var _, done = false;
32
- for (var i = decorators.length - 1; i >= 0; i--) {
33
- var context = {};
34
- for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
35
- for (var p in contextIn.access) context.access[p] = contextIn.access[p];
36
- context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
37
- var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
38
- if (kind === "accessor") {
39
- if (result === void 0) continue;
40
- if (result === null || typeof result !== "object") throw new TypeError("Object expected");
41
- if (_ = accept(result.get)) descriptor.get = _;
42
- if (_ = accept(result.set)) descriptor.set = _;
43
- if (_ = accept(result.init)) initializers.unshift(_);
44
- }
45
- else if (_ = accept(result)) {
46
- if (kind === "field") initializers.unshift(_);
47
- else descriptor[key] = _;
48
- }
49
- }
50
- if (target) Object.defineProperty(target, contextIn.name, descriptor);
51
- done = true;
52
- };
53
- import { describe, it, expect, vi } from 'vitest';
54
- import { Workflow, Task, Step } from '../../index.js';
55
- describe('@Task decorator ErrorMergeStrategy', () => {
56
- /**
57
- * Helper to create a child workflow that may fail
58
- * Pattern from: src/__tests__/adversarial/concurrent-task-failures.test.ts (lines 30-52)
59
- */
60
- function createChildWorkflow(parent, name, shouldFail = false) {
61
- return new ((() => {
62
- let _classSuper = Workflow;
63
- let _instanceExtraInitializers = [];
64
- let _executeStep_decorators;
65
- return class extends _classSuper {
66
- static {
67
- const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
68
- _executeStep_decorators = [Step()];
69
- __esDecorate(this, null, _executeStep_decorators, { kind: "method", name: "executeStep", static: false, private: false, access: { has: obj => "executeStep" in obj, get: obj => obj.executeStep }, metadata: _metadata }, null, _instanceExtraInitializers);
70
- if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
71
- }
72
- constructor(n, p) {
73
- super(n, p);
74
- __runInitializers(this, _instanceExtraInitializers);
75
- }
76
- async executeStep() {
77
- if (shouldFail) {
78
- throw new Error(`${name} failed`);
79
- }
80
- return `${name} succeeded`;
81
- }
82
- async run() {
83
- return this.executeStep();
84
- }
85
- };
86
- })())(name, parent);
87
- }
88
- /**
89
- * Helper to setup event observer for event collection
90
- * Pattern from: src/__tests__/adversarial/concurrent-task-failures.test.ts (lines 58-67)
91
- */
92
- function setupEventObserver(workflow) {
93
- const events = [];
94
- workflow.addObserver({
95
- onLog: () => { },
96
- onEvent: (e) => events.push(e),
97
- onStateUpdated: () => { },
98
- onTreeChanged: () => { },
99
- });
100
- return events;
101
- }
102
- /**
103
- * Helper to create a mock WorkflowError for custom combine() tests
104
- * Pattern from: src/__tests__/unit/utils/workflow-error-utils.test.ts (lines 7-25)
105
- */
106
- function createMockWorkflowError(overrides) {
107
- return {
108
- message: 'Test error',
109
- original: new Error('Original error'),
110
- workflowId: 'wf-test-123',
111
- stack: 'Error: Test error\n at test.ts:10:15',
112
- state: { key: 'value' },
113
- logs: [
114
- {
115
- id: 'log-1',
116
- workflowId: 'wf-test-123',
117
- timestamp: Date.now(),
118
- level: 'error',
119
- message: 'Test log message',
120
- },
121
- ],
122
- ...overrides,
123
- };
124
- }
125
- describe('Default behavior (errorMergeStrategy disabled)', () => {
126
- it('should throw first error when errorMergeStrategy not provided', async () => {
127
- // ARRANGE: Create parent with concurrent tasks, no error merge strategy
128
- let ParentWorkflow = (() => {
129
- let _classSuper = Workflow;
130
- let _instanceExtraInitializers = [];
131
- let _spawnChildren_decorators;
132
- return class ParentWorkflow extends _classSuper {
133
- static {
134
- const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
135
- _spawnChildren_decorators = [Task({ concurrent: true })];
136
- __esDecorate(this, null, _spawnChildren_decorators, { kind: "method", name: "spawnChildren", static: false, private: false, access: { has: obj => "spawnChildren" in obj, get: obj => obj.spawnChildren }, metadata: _metadata }, null, _instanceExtraInitializers);
137
- if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
138
- }
139
- async spawnChildren() {
140
- return [
141
- createChildWorkflow(this, 'Child-0', false),
142
- createChildWorkflow(this, 'Child-1', true), // Will fail
143
- createChildWorkflow(this, 'Child-2', false),
144
- ];
145
- }
146
- async run() {
147
- try {
148
- await this.spawnChildren();
149
- }
150
- catch (err) {
151
- // Expected - capture error for validation
152
- return err;
153
- }
154
- }
155
- constructor() {
156
- super(...arguments);
157
- __runInitializers(this, _instanceExtraInitializers);
158
- }
159
- };
160
- })();
161
- const parent = new ParentWorkflow('Parent');
162
- const events = setupEventObserver(parent);
163
- // ACT: Run parent workflow
164
- const thrownError = await parent.run();
165
- // ASSERT: All children completed (Promise.allSettled behavior)
166
- expect(parent.children.length).toBe(3);
167
- // ASSERT: Error was thrown (first error wins)
168
- expect(thrownError).toBeDefined();
169
- expect(thrownError.message).toContain('Child-1 failed');
170
- // ASSERT: No additional error event from @Task (only individual workflow errors)
171
- const errorEvents = events.filter((e) => e.type === 'error');
172
- expect(errorEvents.length).toBe(1); // Only Child-1's error event
173
- });
174
- it('should throw first error when errorMergeStrategy.enabled=false', async () => {
175
- // ARRANGE: Create parent with explicit enabled=false
176
- let ParentWorkflow = (() => {
177
- let _classSuper = Workflow;
178
- let _instanceExtraInitializers = [];
179
- let _spawnChildren_decorators;
180
- return class ParentWorkflow extends _classSuper {
181
- static {
182
- const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
183
- _spawnChildren_decorators = [Task({
184
- concurrent: true,
185
- errorMergeStrategy: { enabled: false }, // Explicitly disabled
186
- })];
187
- __esDecorate(this, null, _spawnChildren_decorators, { kind: "method", name: "spawnChildren", static: false, private: false, access: { has: obj => "spawnChildren" in obj, get: obj => obj.spawnChildren }, metadata: _metadata }, null, _instanceExtraInitializers);
188
- if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
189
- }
190
- async spawnChildren() {
191
- return [
192
- createChildWorkflow(this, 'Alpha', false),
193
- createChildWorkflow(this, 'Beta', true),
194
- createChildWorkflow(this, 'Gamma', true),
195
- ];
196
- }
197
- async run() {
198
- try {
199
- await this.spawnChildren();
200
- }
201
- catch (err) {
202
- return err;
203
- }
204
- }
205
- constructor() {
206
- super(...arguments);
207
- __runInitializers(this, _instanceExtraInitializers);
208
- }
209
- };
210
- })();
211
- const parent = new ParentWorkflow('Parent');
212
- const events = setupEventObserver(parent);
213
- const thrownError = await parent.run();
214
- // ASSERT: All children completed
215
- expect(parent.children.length).toBe(3);
216
- // ASSERT: First error thrown (not aggregated)
217
- expect(thrownError).toBeDefined();
218
- const errorMsg = thrownError.message;
219
- expect(errorMsg).toMatch(/Alpha failed|Beta failed|Gamma failed/);
220
- // ASSERT: Only individual error events (no merge event)
221
- const errorEvents = events.filter((e) => e.type === 'error');
222
- expect(errorEvents.length).toBe(2); // Beta and Gamma errors only
223
- // ASSERT: Error message does not contain aggregated format
224
- expect(errorMsg).not.toContain('concurrent child workflows failed');
225
- });
226
- });
227
- describe('Enabled with default error merge', () => {
228
- it('should merge all errors when errorMergeStrategy.enabled=true', async () => {
229
- // ARRANGE: Create parent with error merge enabled
230
- let ParentWorkflow = (() => {
231
- let _classSuper = Workflow;
232
- let _instanceExtraInitializers = [];
233
- let _spawnChildren_decorators;
234
- return class ParentWorkflow extends _classSuper {
235
- static {
236
- const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
237
- _spawnChildren_decorators = [Task({
238
- concurrent: true,
239
- errorMergeStrategy: { enabled: true }, // No combine() - use default
240
- })];
241
- __esDecorate(this, null, _spawnChildren_decorators, { kind: "method", name: "spawnChildren", static: false, private: false, access: { has: obj => "spawnChildren" in obj, get: obj => obj.spawnChildren }, metadata: _metadata }, null, _instanceExtraInitializers);
242
- if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
243
- }
244
- async spawnChildren() {
245
- return [
246
- createChildWorkflow(this, 'Alpha', false),
247
- createChildWorkflow(this, 'Beta', true), // Will fail
248
- createChildWorkflow(this, 'Gamma', false),
249
- createChildWorkflow(this, 'Delta', true), // Will fail
250
- createChildWorkflow(this, 'Epsilon', false),
251
- ];
252
- }
253
- async run() {
254
- try {
255
- await this.spawnChildren();
256
- }
257
- catch (err) {
258
- return err;
259
- }
260
- }
261
- constructor() {
262
- super(...arguments);
263
- __runInitializers(this, _instanceExtraInitializers);
264
- }
265
- };
266
- })();
267
- const parent = new ParentWorkflow('Parent');
268
- const events = setupEventObserver(parent);
269
- // ACT
270
- const thrownError = await parent.run();
271
- // ASSERT: All children completed
272
- expect(parent.children.length).toBe(5);
273
- // ASSERT: Merged error thrown
274
- expect(thrownError).toBeDefined();
275
- const error = thrownError;
276
- // ASSERT: Message includes count and task name
277
- expect(error.message).toBe("2 of 5 concurrent child workflows failed in task 'spawnChildren'");
278
- // ASSERT: Metadata in original field
279
- const metadata = error.original;
280
- expect(metadata.name).toBe('WorkflowAggregateError');
281
- expect(metadata.totalChildren).toBe(5);
282
- expect(metadata.failedChildren).toBe(2);
283
- expect(metadata.failedWorkflowIds).toHaveLength(2);
284
- expect(metadata.errors).toHaveLength(2);
285
- // ASSERT: Logs aggregated from all errors (empty array if child workflows don't log)
286
- expect(error.logs).toBeDefined();
287
- expect(Array.isArray(error.logs)).toBe(true);
288
- // Note: Logs are empty here because createChildWorkflow doesn't log
289
- // The "should aggregate all logs from all failed workflows" test specifically tests log aggregation
290
- // ASSERT: Error event emitted with merged error
291
- const errorEvents = events.filter((e) => e.type === 'error');
292
- expect(errorEvents.length).toBeGreaterThanOrEqual(3); // 2 individual + 1 merged
293
- // Find the merged error event (has different message format)
294
- const mergedErrorEvent = errorEvents.find((e) => {
295
- if (e.type === 'error') {
296
- return e.error.message.includes('2 of 5 concurrent');
297
- }
298
- return false;
299
- });
300
- expect(mergedErrorEvent).toBeDefined();
301
- });
302
- it('should create aggregated error message with counts and task name', async () => {
303
- // ARRANGE: Test various counts
304
- let ParentWorkflow = (() => {
305
- let _classSuper = Workflow;
306
- let _instanceExtraInitializers = [];
307
- let _spawnChildren_decorators;
308
- return class ParentWorkflow extends _classSuper {
309
- static {
310
- const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
311
- _spawnChildren_decorators = [Task({
312
- concurrent: true,
313
- errorMergeStrategy: { enabled: true },
314
- })];
315
- __esDecorate(this, null, _spawnChildren_decorators, { kind: "method", name: "spawnChildren", static: false, private: false, access: { has: obj => "spawnChildren" in obj, get: obj => obj.spawnChildren }, metadata: _metadata }, null, _instanceExtraInitializers);
316
- if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
317
- }
318
- async spawnChildren() {
319
- return [
320
- createChildWorkflow(this, 'Success1', false),
321
- createChildWorkflow(this, 'Fail1', true),
322
- createChildWorkflow(this, 'Success2', false),
323
- createChildWorkflow(this, 'Fail2', true),
324
- createChildWorkflow(this, 'Fail3', true),
325
- ];
326
- }
327
- async run() {
328
- try {
329
- await this.spawnChildren();
330
- }
331
- catch (err) {
332
- return err;
333
- }
334
- }
335
- constructor() {
336
- super(...arguments);
337
- __runInitializers(this, _instanceExtraInitializers);
338
- }
339
- };
340
- })();
341
- const parent = new ParentWorkflow('Parent');
342
- const thrownError = await parent.run();
343
- // ASSERT: Message format "${X} of ${Y} concurrent child workflows failed in task '${taskName}'"
344
- expect(thrownError.message).toBe("3 of 5 concurrent child workflows failed in task 'spawnChildren'");
345
- expect(thrownError.message).toMatch(/\d+ of \d+ concurrent child workflows failed/);
346
- expect(thrownError.message).toContain("task 'spawnChildren'");
347
- });
348
- it('should aggregate all logs from all failed workflows', async () => {
349
- // ARRANGE: Create workflows that log before failing
350
- let LoggingWorkflow = (() => {
351
- let _classSuper = Workflow;
352
- let _instanceExtraInitializers = [];
353
- let _executeStep_decorators;
354
- return class LoggingWorkflow extends _classSuper {
355
- static {
356
- const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
357
- _executeStep_decorators = [Step()];
358
- __esDecorate(this, null, _executeStep_decorators, { kind: "method", name: "executeStep", static: false, private: false, access: { has: obj => "executeStep" in obj, get: obj => obj.executeStep }, metadata: _metadata }, null, _instanceExtraInitializers);
359
- if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
360
- }
361
- shouldFail = __runInitializers(this, _instanceExtraInitializers);
362
- constructor(name, parent, shouldFail) {
363
- super(name, parent);
364
- this.shouldFail = shouldFail;
365
- }
366
- async executeStep() {
367
- this.logger.info(`${this.node.name} starting`);
368
- if (this.shouldFail) {
369
- this.logger.error(`${this.node.name} failing`);
370
- throw new Error(`${this.node.name} failed`);
371
- }
372
- this.logger.info(`${this.node.name} completed`);
373
- }
374
- async run() {
375
- return this.executeStep();
376
- }
377
- };
378
- })();
379
- let ParentWorkflow = (() => {
380
- let _classSuper = Workflow;
381
- let _instanceExtraInitializers = [];
382
- let _spawnChildren_decorators;
383
- return class ParentWorkflow extends _classSuper {
384
- static {
385
- const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
386
- _spawnChildren_decorators = [Task({
387
- concurrent: true,
388
- errorMergeStrategy: { enabled: true },
389
- })];
390
- __esDecorate(this, null, _spawnChildren_decorators, { kind: "method", name: "spawnChildren", static: false, private: false, access: { has: obj => "spawnChildren" in obj, get: obj => obj.spawnChildren }, metadata: _metadata }, null, _instanceExtraInitializers);
391
- if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
392
- }
393
- async spawnChildren() {
394
- return [
395
- new LoggingWorkflow('Workflow-1', this, true),
396
- new LoggingWorkflow('Workflow-2', this, true),
397
- new LoggingWorkflow('Workflow-3', this, false),
398
- ];
399
- }
400
- async run() {
401
- try {
402
- await this.spawnChildren();
403
- }
404
- catch (err) {
405
- return err;
406
- }
407
- }
408
- constructor() {
409
- super(...arguments);
410
- __runInitializers(this, _instanceExtraInitializers);
411
- }
412
- };
413
- })();
414
- const parent = new ParentWorkflow('Parent');
415
- const thrownError = (await parent.run());
416
- // ASSERT: Logs from both failed workflows aggregated
417
- expect(thrownError.logs).toBeDefined();
418
- const logMessages = thrownError.logs.map((l) => l.message);
419
- // Should have logs from both failing workflows
420
- expect(logMessages.some((m) => m.includes('Workflow-1'))).toBe(true);
421
- expect(logMessages.some((m) => m.includes('Workflow-2'))).toBe(true);
422
- });
423
- it('should include metadata in original field', async () => {
424
- // ARRANGE: Test metadata structure
425
- let ParentWorkflow = (() => {
426
- let _classSuper = Workflow;
427
- let _instanceExtraInitializers = [];
428
- let _spawnChildren_decorators;
429
- return class ParentWorkflow extends _classSuper {
430
- static {
431
- const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
432
- _spawnChildren_decorators = [Task({
433
- concurrent: true,
434
- errorMergeStrategy: { enabled: true },
435
- })];
436
- __esDecorate(this, null, _spawnChildren_decorators, { kind: "method", name: "spawnChildren", static: false, private: false, access: { has: obj => "spawnChildren" in obj, get: obj => obj.spawnChildren }, metadata: _metadata }, null, _instanceExtraInitializers);
437
- if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
438
- }
439
- async spawnChildren() {
440
- return [
441
- createChildWorkflow(this, 'W1', true),
442
- createChildWorkflow(this, 'W2', true),
443
- createChildWorkflow(this, 'W3', true),
444
- ];
445
- }
446
- async run() {
447
- try {
448
- await this.spawnChildren();
449
- }
450
- catch (err) {
451
- return err;
452
- }
453
- }
454
- constructor() {
455
- super(...arguments);
456
- __runInitializers(this, _instanceExtraInitializers);
457
- }
458
- };
459
- })();
460
- const parent = new ParentWorkflow('Parent');
461
- const thrownError = (await parent.run());
462
- // ASSERT: Metadata structure is correct
463
- const metadata = thrownError.original;
464
- expect(metadata.name).toBe('WorkflowAggregateError');
465
- expect(metadata.message).toContain('concurrent child workflows failed');
466
- expect(metadata.errors).toHaveLength(3);
467
- expect(metadata.totalChildren).toBe(3);
468
- expect(metadata.failedChildren).toBe(3);
469
- expect(metadata.failedWorkflowIds).toHaveLength(3);
470
- // ASSERT: Each error in metadata has workflowId
471
- metadata.failedWorkflowIds.forEach((id) => {
472
- expect(id).toBeDefined();
473
- expect(typeof id).toBe('string');
474
- });
475
- });
476
- });
477
- describe('Enabled with custom combine function', () => {
478
- it('should call custom combine function when provided', async () => {
479
- // ARRANGE: Create spy for combine function
480
- const combineSpy = vi.fn((errors) => ({
481
- message: `Custom merge: ${errors.length} errors`,
482
- original: errors,
483
- workflowId: 'custom-parent',
484
- logs: errors.flatMap((e) => e.logs),
485
- stack: errors[0]?.stack,
486
- state: errors[0]?.state || {},
487
- }));
488
- let ParentWorkflow = (() => {
489
- let _classSuper = Workflow;
490
- let _instanceExtraInitializers = [];
491
- let _spawnChildren_decorators;
492
- return class ParentWorkflow extends _classSuper {
493
- static {
494
- const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
495
- _spawnChildren_decorators = [Task({
496
- concurrent: true,
497
- errorMergeStrategy: {
498
- enabled: true,
499
- combine: combineSpy, // Custom combine function
500
- },
501
- })];
502
- __esDecorate(this, null, _spawnChildren_decorators, { kind: "method", name: "spawnChildren", static: false, private: false, access: { has: obj => "spawnChildren" in obj, get: obj => obj.spawnChildren }, metadata: _metadata }, null, _instanceExtraInitializers);
503
- if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
504
- }
505
- async spawnChildren() {
506
- return [
507
- createChildWorkflow(this, 'Alpha', true),
508
- createChildWorkflow(this, 'Beta', true),
509
- createChildWorkflow(this, 'Gamma', false),
510
- ];
511
- }
512
- async run() {
513
- try {
514
- await this.spawnChildren();
515
- }
516
- catch (err) {
517
- return err;
518
- }
519
- }
520
- constructor() {
521
- super(...arguments);
522
- __runInitializers(this, _instanceExtraInitializers);
523
- }
524
- };
525
- })();
526
- const parent = new ParentWorkflow('Parent');
527
- // ACT
528
- await parent.run();
529
- // ASSERT: Custom combine function was called
530
- expect(combineSpy).toHaveBeenCalledTimes(1);
531
- // ASSERT: Called with array of WorkflowError objects
532
- const calls = combineSpy.mock.calls;
533
- expect(calls).toHaveLength(1);
534
- const errorsArg = calls[0][0];
535
- expect(Array.isArray(errorsArg)).toBe(true);
536
- expect(errorsArg).toHaveLength(2); // Alpha and Beta failed
537
- });
538
- it('should use custom merge result from combine function', async () => {
539
- // ARRANGE: Custom combine that returns specific format
540
- const customMerger = (errors) => ({
541
- message: `MERGED: ${errors.map((e) => e.message).join(' | ')}`,
542
- original: {
543
- customField: 'custom-value',
544
- errors,
545
- },
546
- workflowId: 'merged-workflow',
547
- logs: errors.flatMap((e) => e.logs),
548
- stack: errors[0]?.stack,
549
- state: errors[0]?.state || {},
550
- });
551
- let ParentWorkflow = (() => {
552
- let _classSuper = Workflow;
553
- let _instanceExtraInitializers = [];
554
- let _spawnChildren_decorators;
555
- return class ParentWorkflow extends _classSuper {
556
- static {
557
- const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
558
- _spawnChildren_decorators = [Task({
559
- concurrent: true,
560
- errorMergeStrategy: {
561
- enabled: true,
562
- combine: customMerger,
563
- },
564
- })];
565
- __esDecorate(this, null, _spawnChildren_decorators, { kind: "method", name: "spawnChildren", static: false, private: false, access: { has: obj => "spawnChildren" in obj, get: obj => obj.spawnChildren }, metadata: _metadata }, null, _instanceExtraInitializers);
566
- if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
567
- }
568
- async spawnChildren() {
569
- return [
570
- createChildWorkflow(this, 'First', true),
571
- createChildWorkflow(this, 'Second', true),
572
- ];
573
- }
574
- async run() {
575
- try {
576
- await this.spawnChildren();
577
- }
578
- catch (err) {
579
- return err;
580
- }
581
- }
582
- constructor() {
583
- super(...arguments);
584
- __runInitializers(this, _instanceExtraInitializers);
585
- }
586
- };
587
- })();
588
- const parent = new ParentWorkflow('Parent');
589
- const thrownError = (await parent.run());
590
- // ASSERT: Custom merge result used
591
- expect(thrownError.message).toBe('MERGED: First failed | Second failed');
592
- expect(thrownError.workflowId).toBe('merged-workflow');
593
- // ASSERT: Custom fields preserved
594
- const customMetadata = thrownError.original;
595
- expect(customMetadata.customField).toBe('custom-value');
596
- });
597
- it('should pass all errors to custom combine function', async () => {
598
- // ARRANGE: Track which errors were passed
599
- let receivedErrors = [];
600
- const trackingMerger = (errors) => {
601
- receivedErrors = errors;
602
- return createMockWorkflowError({
603
- message: `Tracked ${errors.length} errors`,
604
- });
605
- };
606
- let ParentWorkflow = (() => {
607
- let _classSuper = Workflow;
608
- let _instanceExtraInitializers = [];
609
- let _spawnChildren_decorators;
610
- return class ParentWorkflow extends _classSuper {
611
- static {
612
- const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
613
- _spawnChildren_decorators = [Task({
614
- concurrent: true,
615
- errorMergeStrategy: {
616
- enabled: true,
617
- combine: trackingMerger,
618
- },
619
- })];
620
- __esDecorate(this, null, _spawnChildren_decorators, { kind: "method", name: "spawnChildren", static: false, private: false, access: { has: obj => "spawnChildren" in obj, get: obj => obj.spawnChildren }, metadata: _metadata }, null, _instanceExtraInitializers);
621
- if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
622
- }
623
- async spawnChildren() {
624
- return [
625
- createChildWorkflow(this, 'A', true),
626
- createChildWorkflow(this, 'B', true),
627
- createChildWorkflow(this, 'C', true),
628
- createChildWorkflow(this, 'D', false),
629
- ];
630
- }
631
- async run() {
632
- try {
633
- await this.spawnChildren();
634
- }
635
- catch (err) {
636
- return err;
637
- }
638
- }
639
- constructor() {
640
- super(...arguments);
641
- __runInitializers(this, _instanceExtraInitializers);
642
- }
643
- };
644
- })();
645
- const parent = new ParentWorkflow('Parent');
646
- await parent.run();
647
- // ASSERT: All failed errors passed to combine
648
- expect(receivedErrors).toHaveLength(3);
649
- const errorMessages = receivedErrors.map((e) => e.message);
650
- expect(errorMessages).toContain('A failed');
651
- expect(errorMessages).toContain('B failed');
652
- expect(errorMessages).toContain('C failed');
653
- });
654
- });
655
- describe('Edge cases and error scenarios', () => {
656
- it('should handle single failure with merge enabled', async () => {
657
- let ParentWorkflow = (() => {
658
- let _classSuper = Workflow;
659
- let _instanceExtraInitializers = [];
660
- let _spawnChildren_decorators;
661
- return class ParentWorkflow extends _classSuper {
662
- static {
663
- const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
664
- _spawnChildren_decorators = [Task({
665
- concurrent: true,
666
- errorMergeStrategy: { enabled: true },
667
- })];
668
- __esDecorate(this, null, _spawnChildren_decorators, { kind: "method", name: "spawnChildren", static: false, private: false, access: { has: obj => "spawnChildren" in obj, get: obj => obj.spawnChildren }, metadata: _metadata }, null, _instanceExtraInitializers);
669
- if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
670
- }
671
- async spawnChildren() {
672
- return [createChildWorkflow(this, 'OnlyChild', true)];
673
- }
674
- async run() {
675
- try {
676
- await this.spawnChildren();
677
- }
678
- catch (err) {
679
- return err;
680
- }
681
- }
682
- constructor() {
683
- super(...arguments);
684
- __runInitializers(this, _instanceExtraInitializers);
685
- }
686
- };
687
- })();
688
- const parent = new ParentWorkflow('Parent');
689
- const thrownError = (await parent.run());
690
- // ASSERT: Message format correct for single failure
691
- expect(thrownError.message).toBe("1 of 1 concurrent child workflows failed in task 'spawnChildren'");
692
- });
693
- it('should handle all workflows failing with merge enabled', async () => {
694
- let ParentWorkflow = (() => {
695
- let _classSuper = Workflow;
696
- let _instanceExtraInitializers = [];
697
- let _spawnChildren_decorators;
698
- return class ParentWorkflow extends _classSuper {
699
- static {
700
- const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
701
- _spawnChildren_decorators = [Task({
702
- concurrent: true,
703
- errorMergeStrategy: { enabled: true },
704
- })];
705
- __esDecorate(this, null, _spawnChildren_decorators, { kind: "method", name: "spawnChildren", static: false, private: false, access: { has: obj => "spawnChildren" in obj, get: obj => obj.spawnChildren }, metadata: _metadata }, null, _instanceExtraInitializers);
706
- if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
707
- }
708
- async spawnChildren() {
709
- return [
710
- createChildWorkflow(this, 'W1', true),
711
- createChildWorkflow(this, 'W2', true),
712
- createChildWorkflow(this, 'W3', true),
713
- createChildWorkflow(this, 'W4', true),
714
- ];
715
- }
716
- async run() {
717
- try {
718
- await this.spawnChildren();
719
- }
720
- catch (err) {
721
- return err;
722
- }
723
- }
724
- constructor() {
725
- super(...arguments);
726
- __runInitializers(this, _instanceExtraInitializers);
727
- }
728
- };
729
- })();
730
- const parent = new ParentWorkflow('Parent');
731
- const thrownError = (await parent.run());
732
- // ASSERT: All failures counted
733
- expect(thrownError.message).toBe("4 of 4 concurrent child workflows failed in task 'spawnChildren'");
734
- // ASSERT: All workflows completed
735
- expect(parent.children.length).toBe(4);
736
- });
737
- it('should handle mixed success/failure with merge enabled', async () => {
738
- let ParentWorkflow = (() => {
739
- let _classSuper = Workflow;
740
- let _instanceExtraInitializers = [];
741
- let _spawnChildren_decorators;
742
- return class ParentWorkflow extends _classSuper {
743
- static {
744
- const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
745
- _spawnChildren_decorators = [Task({
746
- concurrent: true,
747
- errorMergeStrategy: { enabled: true },
748
- })];
749
- __esDecorate(this, null, _spawnChildren_decorators, { kind: "method", name: "spawnChildren", static: false, private: false, access: { has: obj => "spawnChildren" in obj, get: obj => obj.spawnChildren }, metadata: _metadata }, null, _instanceExtraInitializers);
750
- if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
751
- }
752
- async spawnChildren() {
753
- return [
754
- createChildWorkflow(this, 'Success1', false),
755
- createChildWorkflow(this, 'Fail1', true),
756
- createChildWorkflow(this, 'Success2', false),
757
- createChildWorkflow(this, 'Fail2', true),
758
- createChildWorkflow(this, 'Success3', false),
759
- ];
760
- }
761
- async run() {
762
- try {
763
- await this.spawnChildren();
764
- }
765
- catch (err) {
766
- return err;
767
- }
768
- }
769
- constructor() {
770
- super(...arguments);
771
- __runInitializers(this, _instanceExtraInitializers);
772
- }
773
- };
774
- })();
775
- const parent = new ParentWorkflow('Parent');
776
- const thrownError = (await parent.run());
777
- // ASSERT: Only failed children counted in message
778
- expect(thrownError.message).toBe("2 of 5 concurrent child workflows failed in task 'spawnChildren'");
779
- // ASSERT: All workflows completed
780
- expect(parent.children.length).toBe(5);
781
- // ASSERT: Metadata correct
782
- const metadata = thrownError.original;
783
- expect(metadata.failedChildren).toBe(2);
784
- expect(metadata.totalChildren).toBe(5);
785
- });
786
- it('should complete all workflows even when errors occur', async () => {
787
- const completedWorkflows = new Set();
788
- let ParentWorkflow = (() => {
789
- let _classSuper = Workflow;
790
- let _instanceExtraInitializers = [];
791
- let _spawnChildren_decorators;
792
- return class ParentWorkflow extends _classSuper {
793
- static {
794
- const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
795
- _spawnChildren_decorators = [Task({
796
- concurrent: true,
797
- errorMergeStrategy: { enabled: true },
798
- })];
799
- __esDecorate(this, null, _spawnChildren_decorators, { kind: "method", name: "spawnChildren", static: false, private: false, access: { has: obj => "spawnChildren" in obj, get: obj => obj.spawnChildren }, metadata: _metadata }, null, _instanceExtraInitializers);
800
- if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
801
- }
802
- async spawnChildren() {
803
- const children = [
804
- createChildWorkflow(this, 'Success1', false),
805
- createChildWorkflow(this, 'Fail1', true),
806
- createChildWorkflow(this, 'Success2', false),
807
- createChildWorkflow(this, 'Fail2', true),
808
- ];
809
- // Track completion
810
- children.forEach((child) => {
811
- child.run().then(() => completedWorkflows.add(child.id), () => completedWorkflows.add(child.id));
812
- });
813
- return children;
814
- }
815
- async run() {
816
- try {
817
- await this.spawnChildren();
818
- }
819
- catch (err) {
820
- // Expected
821
- }
822
- }
823
- constructor() {
824
- super(...arguments);
825
- __runInitializers(this, _instanceExtraInitializers);
826
- }
827
- };
828
- })();
829
- const parent = new ParentWorkflow('Parent');
830
- await parent.run();
831
- // ASSERT: All workflows completed (no orphans)
832
- expect(completedWorkflows.size).toBe(4);
833
- expect(parent.children.length).toBe(4);
834
- });
835
- it('should emit error event with merged error', async () => {
836
- let ParentWorkflow = (() => {
837
- let _classSuper = Workflow;
838
- let _instanceExtraInitializers = [];
839
- let _spawnChildren_decorators;
840
- return class ParentWorkflow extends _classSuper {
841
- static {
842
- const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
843
- _spawnChildren_decorators = [Task({
844
- concurrent: true,
845
- errorMergeStrategy: { enabled: true },
846
- })];
847
- __esDecorate(this, null, _spawnChildren_decorators, { kind: "method", name: "spawnChildren", static: false, private: false, access: { has: obj => "spawnChildren" in obj, get: obj => obj.spawnChildren }, metadata: _metadata }, null, _instanceExtraInitializers);
848
- if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
849
- }
850
- async spawnChildren() {
851
- return [
852
- createChildWorkflow(this, 'OK', false),
853
- createChildWorkflow(this, 'Bad1', true),
854
- createChildWorkflow(this, 'Bad2', true),
855
- ];
856
- }
857
- async run() {
858
- try {
859
- await this.spawnChildren();
860
- }
861
- catch (err) {
862
- return err;
863
- }
864
- }
865
- constructor() {
866
- super(...arguments);
867
- __runInitializers(this, _instanceExtraInitializers);
868
- }
869
- };
870
- })();
871
- const parent = new ParentWorkflow('Parent');
872
- const events = setupEventObserver(parent);
873
- await parent.run();
874
- // ASSERT: Error events emitted for individual failures
875
- const individualErrorEvents = events.filter((e) => {
876
- if (e.type === 'error') {
877
- return e.error.message === 'Bad1 failed' || e.error.message === 'Bad2 failed';
878
- }
879
- return false;
880
- });
881
- expect(individualErrorEvents.length).toBeGreaterThanOrEqual(2);
882
- // ASSERT: Additional merged error event emitted
883
- const mergedErrorEvent = events.find((e) => {
884
- if (e.type === 'error') {
885
- return e.error.message.includes('concurrent child workflows failed');
886
- }
887
- return false;
888
- });
889
- expect(mergedErrorEvent).toBeDefined();
890
- // ASSERT: Merged error has correct structure
891
- if (mergedErrorEvent && mergedErrorEvent.type === 'error') {
892
- expect(mergedErrorEvent.error.message).toContain('2 of 3');
893
- expect(mergedErrorEvent.error.workflowId).toBeDefined();
894
- expect(Array.isArray(mergedErrorEvent.error.logs)).toBe(true);
895
- }
896
- });
897
- });
898
- describe.skip('maxMergeDepth validation', () => {
899
- // NOTE: maxMergeDepth is defined in ErrorMergeStrategy interface
900
- // but not currently implemented in src/decorators/task.ts
901
- // These tests should be implemented when maxMergeDepth is added
902
- it('should respect maxMergeDepth when merging nested errors');
903
- it('should handle maxMergeDepth=0 (no merging)');
904
- it('should handle maxMergeDepth=1 (single level merging)');
905
- });
906
- });
907
- //# sourceMappingURL=error-merge-strategy.test.js.map