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.
- package/LICENSE +21 -0
- package/README.md +26 -9
- package/dist/cache/cache-key.d.ts +20 -0
- package/dist/cache/cache-key.d.ts.map +1 -1
- package/dist/cache/cache-key.js +9 -0
- package/dist/cache/cache-key.js.map +1 -1
- package/dist/core/agent.d.ts +120 -29
- package/dist/core/agent.d.ts.map +1 -1
- package/dist/core/agent.js +584 -177
- package/dist/core/agent.js.map +1 -1
- package/dist/core/mcp-handler.d.ts +63 -5
- package/dist/core/mcp-handler.d.ts.map +1 -1
- package/dist/core/mcp-handler.js +184 -4
- package/dist/core/mcp-handler.js.map +1 -1
- package/dist/core/workflow-context.d.ts +6 -2
- package/dist/core/workflow-context.d.ts.map +1 -1
- package/dist/core/workflow-context.js +99 -4
- package/dist/core/workflow-context.js.map +1 -1
- package/dist/core/workflow.d.ts +315 -13
- package/dist/core/workflow.d.ts.map +1 -1
- package/dist/core/workflow.js +552 -30
- package/dist/core/workflow.js.map +1 -1
- package/dist/debugger/event-replayer.d.ts +422 -0
- package/dist/debugger/event-replayer.d.ts.map +1 -0
- package/dist/debugger/event-replayer.js +639 -0
- package/dist/debugger/event-replayer.js.map +1 -0
- package/dist/debugger/tree-debugger.d.ts +170 -1
- package/dist/debugger/tree-debugger.d.ts.map +1 -1
- package/dist/debugger/tree-debugger.js +423 -1
- package/dist/debugger/tree-debugger.js.map +1 -1
- package/dist/decorators/step.d.ts.map +1 -1
- package/dist/decorators/step.js +129 -47
- package/dist/decorators/step.js.map +1 -1
- package/dist/harnesses/claude-code-harness.d.ts +391 -0
- package/dist/harnesses/claude-code-harness.d.ts.map +1 -0
- package/dist/harnesses/claude-code-harness.js +1076 -0
- package/dist/harnesses/claude-code-harness.js.map +1 -0
- package/dist/harnesses/harness-registry.d.ts +440 -0
- package/dist/harnesses/harness-registry.d.ts.map +1 -0
- package/dist/harnesses/harness-registry.js +543 -0
- package/dist/harnesses/harness-registry.js.map +1 -0
- package/dist/harnesses/index.d.ts +12 -0
- package/dist/harnesses/index.d.ts.map +1 -0
- package/dist/harnesses/index.js +11 -0
- package/dist/harnesses/index.js.map +1 -0
- package/dist/harnesses/pi-harness.d.ts +219 -0
- package/dist/harnesses/pi-harness.d.ts.map +1 -0
- package/dist/harnesses/pi-harness.js +676 -0
- package/dist/harnesses/pi-harness.js.map +1 -0
- package/dist/harnesses/pi-schema-converter.d.ts +24 -0
- package/dist/harnesses/pi-schema-converter.d.ts.map +1 -0
- package/dist/harnesses/pi-schema-converter.js +81 -0
- package/dist/harnesses/pi-schema-converter.js.map +1 -0
- package/dist/harnesses/register-defaults.d.ts +24 -0
- package/dist/harnesses/register-defaults.d.ts.map +1 -0
- package/dist/harnesses/register-defaults.js +40 -0
- package/dist/harnesses/register-defaults.js.map +1 -0
- package/dist/harnesses/session-store.d.ts +201 -0
- package/dist/harnesses/session-store.d.ts.map +1 -0
- package/dist/harnesses/session-store.js +254 -0
- package/dist/harnesses/session-store.js.map +1 -0
- package/dist/index.d.ts +12 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -1
- package/dist/reflection/reflection.d.ts.map +1 -1
- package/dist/reflection/reflection.js +19 -4
- package/dist/reflection/reflection.js.map +1 -1
- package/dist/types/agent.d.ts +1253 -2
- package/dist/types/agent.d.ts.map +1 -1
- package/dist/types/agent.js +418 -1
- package/dist/types/agent.js.map +1 -1
- package/dist/types/decorators.d.ts +10 -1
- package/dist/types/decorators.d.ts.map +1 -1
- package/dist/types/events.d.ts +26 -0
- package/dist/types/events.d.ts.map +1 -1
- package/dist/types/harnesses.d.ts +474 -0
- package/dist/types/harnesses.d.ts.map +1 -0
- package/dist/types/harnesses.js +2 -0
- package/dist/types/harnesses.js.map +1 -0
- package/dist/types/index.d.ts +9 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/providers.d.ts +691 -0
- package/dist/types/providers.d.ts.map +1 -0
- package/dist/types/providers.js +14 -0
- package/dist/types/providers.js.map +1 -0
- package/dist/types/restart.d.ts +132 -0
- package/dist/types/restart.d.ts.map +1 -0
- package/dist/types/restart.js +2 -0
- package/dist/types/restart.js.map +1 -0
- package/dist/types/streaming.d.ts +194 -0
- package/dist/types/streaming.d.ts.map +1 -0
- package/dist/types/streaming.js +67 -0
- package/dist/types/streaming.js.map +1 -0
- package/dist/types/workflow-context.d.ts +137 -1
- package/dist/types/workflow-context.d.ts.map +1 -1
- package/dist/utils/agent-validation.d.ts +88 -0
- package/dist/utils/agent-validation.d.ts.map +1 -0
- package/dist/utils/agent-validation.js +87 -0
- package/dist/utils/agent-validation.js.map +1 -0
- package/dist/utils/delay.d.ts +7 -0
- package/dist/utils/delay.d.ts.map +1 -0
- package/dist/utils/delay.js +9 -0
- package/dist/utils/delay.js.map +1 -0
- package/dist/utils/harness-config.d.ts +180 -0
- package/dist/utils/harness-config.d.ts.map +1 -0
- package/dist/utils/harness-config.js +311 -0
- package/dist/utils/harness-config.js.map +1 -0
- package/dist/utils/index.d.ts +9 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +8 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/model-spec.d.ts +110 -0
- package/dist/utils/model-spec.d.ts.map +1 -0
- package/dist/utils/model-spec.js +149 -0
- package/dist/utils/model-spec.js.map +1 -0
- package/dist/utils/provider-config.d.ts +10 -0
- package/dist/utils/provider-config.d.ts.map +1 -0
- package/dist/utils/provider-config.js +10 -0
- package/dist/utils/provider-config.js.map +1 -0
- package/dist/utils/restart-analysis.d.ts +202 -0
- package/dist/utils/restart-analysis.d.ts.map +1 -0
- package/dist/utils/restart-analysis.js +426 -0
- package/dist/utils/restart-analysis.js.map +1 -0
- package/dist/utils/session-serialization.d.ts +118 -0
- package/dist/utils/session-serialization.d.ts.map +1 -0
- package/dist/utils/session-serialization.js +217 -0
- package/dist/utils/session-serialization.js.map +1 -0
- package/package.json +31 -5
- package/CHANGELOG.md +0 -188
- package/dist/__tests__/adversarial/attachChild-performance.test.d.ts +0 -16
- package/dist/__tests__/adversarial/attachChild-performance.test.d.ts.map +0 -1
- package/dist/__tests__/adversarial/attachChild-performance.test.js +0 -187
- package/dist/__tests__/adversarial/attachChild-performance.test.js.map +0 -1
- package/dist/__tests__/adversarial/circular-reference.test.d.ts +0 -13
- package/dist/__tests__/adversarial/circular-reference.test.d.ts.map +0 -1
- package/dist/__tests__/adversarial/circular-reference.test.js +0 -92
- package/dist/__tests__/adversarial/circular-reference.test.js.map +0 -1
- package/dist/__tests__/adversarial/complex-circular-reference.test.d.ts +0 -16
- package/dist/__tests__/adversarial/complex-circular-reference.test.d.ts.map +0 -1
- package/dist/__tests__/adversarial/complex-circular-reference.test.js +0 -127
- package/dist/__tests__/adversarial/complex-circular-reference.test.js.map +0 -1
- package/dist/__tests__/adversarial/concurrent-task-failures.test.d.ts +0 -21
- package/dist/__tests__/adversarial/concurrent-task-failures.test.d.ts.map +0 -1
- package/dist/__tests__/adversarial/concurrent-task-failures.test.js +0 -667
- package/dist/__tests__/adversarial/concurrent-task-failures.test.js.map +0 -1
- package/dist/__tests__/adversarial/deep-analysis.test.d.ts +0 -6
- package/dist/__tests__/adversarial/deep-analysis.test.d.ts.map +0 -1
- package/dist/__tests__/adversarial/deep-analysis.test.js +0 -877
- package/dist/__tests__/adversarial/deep-analysis.test.js.map +0 -1
- package/dist/__tests__/adversarial/deep-hierarchy-stress.test.d.ts +0 -13
- package/dist/__tests__/adversarial/deep-hierarchy-stress.test.d.ts.map +0 -1
- package/dist/__tests__/adversarial/deep-hierarchy-stress.test.js +0 -186
- package/dist/__tests__/adversarial/deep-hierarchy-stress.test.js.map +0 -1
- package/dist/__tests__/adversarial/e2e-prd-validation.test.d.ts +0 -6
- package/dist/__tests__/adversarial/e2e-prd-validation.test.d.ts.map +0 -1
- package/dist/__tests__/adversarial/e2e-prd-validation.test.js +0 -626
- package/dist/__tests__/adversarial/e2e-prd-validation.test.js.map +0 -1
- package/dist/__tests__/adversarial/edge-case.test.d.ts +0 -6
- package/dist/__tests__/adversarial/edge-case.test.d.ts.map +0 -1
- package/dist/__tests__/adversarial/edge-case.test.js +0 -857
- package/dist/__tests__/adversarial/edge-case.test.js.map +0 -1
- package/dist/__tests__/adversarial/error-merge-strategy.test.d.ts +0 -20
- package/dist/__tests__/adversarial/error-merge-strategy.test.d.ts.map +0 -1
- package/dist/__tests__/adversarial/error-merge-strategy.test.js +0 -907
- package/dist/__tests__/adversarial/error-merge-strategy.test.js.map +0 -1
- package/dist/__tests__/adversarial/incremental-performance.test.d.ts +0 -2
- package/dist/__tests__/adversarial/incremental-performance.test.d.ts.map +0 -1
- package/dist/__tests__/adversarial/incremental-performance.test.js +0 -113
- package/dist/__tests__/adversarial/incremental-performance.test.js.map +0 -1
- package/dist/__tests__/adversarial/node-map-update-benchmarks.test.d.ts +0 -22
- package/dist/__tests__/adversarial/node-map-update-benchmarks.test.d.ts.map +0 -1
- package/dist/__tests__/adversarial/node-map-update-benchmarks.test.js +0 -383
- package/dist/__tests__/adversarial/node-map-update-benchmarks.test.js.map +0 -1
- package/dist/__tests__/adversarial/observer-propagation.test.d.ts +0 -21
- package/dist/__tests__/adversarial/observer-propagation.test.d.ts.map +0 -1
- package/dist/__tests__/adversarial/observer-propagation.test.js +0 -404
- package/dist/__tests__/adversarial/observer-propagation.test.js.map +0 -1
- package/dist/__tests__/adversarial/parent-validation.test.d.ts +0 -13
- package/dist/__tests__/adversarial/parent-validation.test.d.ts.map +0 -1
- package/dist/__tests__/adversarial/parent-validation.test.js +0 -128
- package/dist/__tests__/adversarial/parent-validation.test.js.map +0 -1
- package/dist/__tests__/adversarial/prd-12-2-compliance.test.d.ts +0 -20
- package/dist/__tests__/adversarial/prd-12-2-compliance.test.d.ts.map +0 -1
- package/dist/__tests__/adversarial/prd-12-2-compliance.test.js +0 -482
- package/dist/__tests__/adversarial/prd-12-2-compliance.test.js.map +0 -1
- package/dist/__tests__/adversarial/prd-compliance.test.d.ts +0 -6
- package/dist/__tests__/adversarial/prd-compliance.test.d.ts.map +0 -1
- package/dist/__tests__/adversarial/prd-compliance.test.js +0 -886
- package/dist/__tests__/adversarial/prd-compliance.test.js.map +0 -1
- package/dist/__tests__/compatibility/backward-compatibility.test.d.ts +0 -22
- package/dist/__tests__/compatibility/backward-compatibility.test.d.ts.map +0 -1
- package/dist/__tests__/compatibility/backward-compatibility.test.js +0 -1843
- package/dist/__tests__/compatibility/backward-compatibility.test.js.map +0 -1
- package/dist/__tests__/helpers/index.d.ts +0 -10
- package/dist/__tests__/helpers/index.d.ts.map +0 -1
- package/dist/__tests__/helpers/index.js +0 -10
- package/dist/__tests__/helpers/index.js.map +0 -1
- package/dist/__tests__/helpers/tree-verification.d.ts +0 -90
- package/dist/__tests__/helpers/tree-verification.d.ts.map +0 -1
- package/dist/__tests__/helpers/tree-verification.js +0 -202
- package/dist/__tests__/helpers/tree-verification.js.map +0 -1
- package/dist/__tests__/integration/agent-workflow.test.d.ts +0 -2
- package/dist/__tests__/integration/agent-workflow.test.d.ts.map +0 -1
- package/dist/__tests__/integration/agent-workflow.test.js +0 -256
- package/dist/__tests__/integration/agent-workflow.test.js.map +0 -1
- package/dist/__tests__/integration/bidirectional-consistency.test.d.ts +0 -14
- package/dist/__tests__/integration/bidirectional-consistency.test.d.ts.map +0 -1
- package/dist/__tests__/integration/bidirectional-consistency.test.js +0 -668
- package/dist/__tests__/integration/bidirectional-consistency.test.js.map +0 -1
- package/dist/__tests__/integration/observer-logging.test.d.ts +0 -2
- package/dist/__tests__/integration/observer-logging.test.d.ts.map +0 -1
- package/dist/__tests__/integration/observer-logging.test.js +0 -517
- package/dist/__tests__/integration/observer-logging.test.js.map +0 -1
- package/dist/__tests__/integration/tree-mirroring.test.d.ts +0 -2
- package/dist/__tests__/integration/tree-mirroring.test.d.ts.map +0 -1
- package/dist/__tests__/integration/tree-mirroring.test.js +0 -117
- package/dist/__tests__/integration/tree-mirroring.test.js.map +0 -1
- package/dist/__tests__/integration/workflow-reparenting.test.d.ts +0 -12
- package/dist/__tests__/integration/workflow-reparenting.test.d.ts.map +0 -1
- package/dist/__tests__/integration/workflow-reparenting.test.js +0 -239
- package/dist/__tests__/integration/workflow-reparenting.test.js.map +0 -1
- package/dist/__tests__/unit/agent.test.d.ts +0 -2
- package/dist/__tests__/unit/agent.test.d.ts.map +0 -1
- package/dist/__tests__/unit/agent.test.js +0 -143
- package/dist/__tests__/unit/agent.test.js.map +0 -1
- package/dist/__tests__/unit/cache-key.test.d.ts +0 -5
- package/dist/__tests__/unit/cache-key.test.d.ts.map +0 -1
- package/dist/__tests__/unit/cache-key.test.js +0 -145
- package/dist/__tests__/unit/cache-key.test.js.map +0 -1
- package/dist/__tests__/unit/cache.test.d.ts +0 -5
- package/dist/__tests__/unit/cache.test.d.ts.map +0 -1
- package/dist/__tests__/unit/cache.test.js +0 -132
- package/dist/__tests__/unit/cache.test.js.map +0 -1
- package/dist/__tests__/unit/context.test.d.ts +0 -2
- package/dist/__tests__/unit/context.test.d.ts.map +0 -1
- package/dist/__tests__/unit/context.test.js +0 -220
- package/dist/__tests__/unit/context.test.js.map +0 -1
- package/dist/__tests__/unit/decorators.test.d.ts +0 -2
- package/dist/__tests__/unit/decorators.test.d.ts.map +0 -1
- package/dist/__tests__/unit/decorators.test.js +0 -162
- package/dist/__tests__/unit/decorators.test.js.map +0 -1
- package/dist/__tests__/unit/introspection-tools.test.d.ts +0 -5
- package/dist/__tests__/unit/introspection-tools.test.d.ts.map +0 -1
- package/dist/__tests__/unit/introspection-tools.test.js +0 -191
- package/dist/__tests__/unit/introspection-tools.test.js.map +0 -1
- package/dist/__tests__/unit/logger.test.d.ts +0 -2
- package/dist/__tests__/unit/logger.test.d.ts.map +0 -1
- package/dist/__tests__/unit/logger.test.js +0 -241
- package/dist/__tests__/unit/logger.test.js.map +0 -1
- package/dist/__tests__/unit/observable.test.d.ts +0 -2
- package/dist/__tests__/unit/observable.test.d.ts.map +0 -1
- package/dist/__tests__/unit/observable.test.js +0 -251
- package/dist/__tests__/unit/observable.test.js.map +0 -1
- package/dist/__tests__/unit/prompt.test.d.ts +0 -2
- package/dist/__tests__/unit/prompt.test.d.ts.map +0 -1
- package/dist/__tests__/unit/prompt.test.js +0 -113
- package/dist/__tests__/unit/prompt.test.js.map +0 -1
- package/dist/__tests__/unit/reflection.test.d.ts +0 -5
- package/dist/__tests__/unit/reflection.test.d.ts.map +0 -1
- package/dist/__tests__/unit/reflection.test.js +0 -160
- package/dist/__tests__/unit/reflection.test.js.map +0 -1
- package/dist/__tests__/unit/tree-debugger-incremental.test.d.ts +0 -2
- package/dist/__tests__/unit/tree-debugger-incremental.test.d.ts.map +0 -1
- package/dist/__tests__/unit/tree-debugger-incremental.test.js +0 -136
- package/dist/__tests__/unit/tree-debugger-incremental.test.js.map +0 -1
- package/dist/__tests__/unit/tree-debugger.test.d.ts +0 -2
- package/dist/__tests__/unit/tree-debugger.test.d.ts.map +0 -1
- package/dist/__tests__/unit/tree-debugger.test.js +0 -69
- package/dist/__tests__/unit/tree-debugger.test.js.map +0 -1
- package/dist/__tests__/unit/utils/workflow-error-utils.test.d.ts +0 -2
- package/dist/__tests__/unit/utils/workflow-error-utils.test.d.ts.map +0 -1
- package/dist/__tests__/unit/utils/workflow-error-utils.test.js +0 -154
- package/dist/__tests__/unit/utils/workflow-error-utils.test.js.map +0 -1
- package/dist/__tests__/unit/workflow-detachChild.test.d.ts +0 -2
- package/dist/__tests__/unit/workflow-detachChild.test.d.ts.map +0 -1
- package/dist/__tests__/unit/workflow-detachChild.test.js +0 -76
- package/dist/__tests__/unit/workflow-detachChild.test.js.map +0 -1
- package/dist/__tests__/unit/workflow-emitEvent-childDetached.test.d.ts +0 -2
- package/dist/__tests__/unit/workflow-emitEvent-childDetached.test.d.ts.map +0 -1
- package/dist/__tests__/unit/workflow-emitEvent-childDetached.test.js +0 -122
- package/dist/__tests__/unit/workflow-emitEvent-childDetached.test.js.map +0 -1
- package/dist/__tests__/unit/workflow-isDescendantOf.test.d.ts +0 -2
- package/dist/__tests__/unit/workflow-isDescendantOf.test.d.ts.map +0 -1
- package/dist/__tests__/unit/workflow-isDescendantOf.test.js +0 -140
- package/dist/__tests__/unit/workflow-isDescendantOf.test.js.map +0 -1
- package/dist/__tests__/unit/workflow.test.d.ts +0 -2
- package/dist/__tests__/unit/workflow.test.d.ts.map +0 -1
- package/dist/__tests__/unit/workflow.test.js +0 -330
- package/dist/__tests__/unit/workflow.test.js.map +0 -1
|
@@ -1,667 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Concurrent Task Failure Scenarios Test Suite
|
|
3
|
-
*
|
|
4
|
-
* Tests the Promise.allSettled implementation in @Task decorator
|
|
5
|
-
* for concurrent execution with various failure scenarios.
|
|
6
|
-
*
|
|
7
|
-
* Validates:
|
|
8
|
-
* - Single child failure in concurrent batch
|
|
9
|
-
* - Multiple children failing concurrently
|
|
10
|
-
* - Mixed success/failure scenarios
|
|
11
|
-
* - All children failing edge case
|
|
12
|
-
* - No orphaned or hanging promises
|
|
13
|
-
* - Error collection correctness
|
|
14
|
-
* - Event emission during failures
|
|
15
|
-
*
|
|
16
|
-
* Related:
|
|
17
|
-
* - S2 Implementation: Promise.allSettled in task.ts (lines 111-120)
|
|
18
|
-
* - Bug: 001_e8e04329daf3 - Concurrent task error collection
|
|
19
|
-
*/
|
|
20
|
-
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
21
|
-
var useValue = arguments.length > 2;
|
|
22
|
-
for (var i = 0; i < initializers.length; i++) {
|
|
23
|
-
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
24
|
-
}
|
|
25
|
-
return useValue ? value : void 0;
|
|
26
|
-
};
|
|
27
|
-
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
28
|
-
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
29
|
-
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
30
|
-
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
31
|
-
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
32
|
-
var _, done = false;
|
|
33
|
-
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
34
|
-
var context = {};
|
|
35
|
-
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
36
|
-
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
37
|
-
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
38
|
-
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
39
|
-
if (kind === "accessor") {
|
|
40
|
-
if (result === void 0) continue;
|
|
41
|
-
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
42
|
-
if (_ = accept(result.get)) descriptor.get = _;
|
|
43
|
-
if (_ = accept(result.set)) descriptor.set = _;
|
|
44
|
-
if (_ = accept(result.init)) initializers.unshift(_);
|
|
45
|
-
}
|
|
46
|
-
else if (_ = accept(result)) {
|
|
47
|
-
if (kind === "field") initializers.unshift(_);
|
|
48
|
-
else descriptor[key] = _;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
52
|
-
done = true;
|
|
53
|
-
};
|
|
54
|
-
import { describe, it, expect } from 'vitest';
|
|
55
|
-
import { Workflow, Task, Step } from '../../index.js';
|
|
56
|
-
describe('@Task decorator concurrent failure scenarios', () => {
|
|
57
|
-
/**
|
|
58
|
-
* Helper to create a child workflow that may fail
|
|
59
|
-
* Pattern from: src/__tests__/adversarial/edge-case.test.ts (lines 146-167)
|
|
60
|
-
*/
|
|
61
|
-
function createChildWorkflow(parent, name, shouldFail = false) {
|
|
62
|
-
return new ((() => {
|
|
63
|
-
let _classSuper = Workflow;
|
|
64
|
-
let _instanceExtraInitializers = [];
|
|
65
|
-
let _executeStep_decorators;
|
|
66
|
-
return class extends _classSuper {
|
|
67
|
-
static {
|
|
68
|
-
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
69
|
-
_executeStep_decorators = [Step()];
|
|
70
|
-
__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);
|
|
71
|
-
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
72
|
-
}
|
|
73
|
-
constructor(n, p) {
|
|
74
|
-
super(n, p);
|
|
75
|
-
__runInitializers(this, _instanceExtraInitializers);
|
|
76
|
-
}
|
|
77
|
-
async executeStep() {
|
|
78
|
-
if (shouldFail) {
|
|
79
|
-
throw new Error(`${name} failed`);
|
|
80
|
-
}
|
|
81
|
-
return `${name} succeeded`;
|
|
82
|
-
}
|
|
83
|
-
async run() {
|
|
84
|
-
return this.executeStep();
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
|
-
})())(name, parent);
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Helper to setup event observer for event collection
|
|
91
|
-
* Pattern from: src/__tests__/adversarial/observer-propagation.test.ts (lines 42-49)
|
|
92
|
-
*/
|
|
93
|
-
function setupEventObserver(workflow) {
|
|
94
|
-
const events = [];
|
|
95
|
-
workflow.addObserver({
|
|
96
|
-
onLog: () => { },
|
|
97
|
-
onEvent: (e) => events.push(e),
|
|
98
|
-
onStateUpdated: () => { },
|
|
99
|
-
onTreeChanged: () => { },
|
|
100
|
-
});
|
|
101
|
-
return events;
|
|
102
|
-
}
|
|
103
|
-
describe('Single child failure scenarios', () => {
|
|
104
|
-
it('should complete all siblings when one child fails', async () => {
|
|
105
|
-
// ARRANGE: Create parent with 4 children, child[1] will fail
|
|
106
|
-
let ParentWorkflow = (() => {
|
|
107
|
-
let _classSuper = Workflow;
|
|
108
|
-
let _instanceExtraInitializers = [];
|
|
109
|
-
let _spawnChildren_decorators;
|
|
110
|
-
return class ParentWorkflow extends _classSuper {
|
|
111
|
-
static {
|
|
112
|
-
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
113
|
-
_spawnChildren_decorators = [Task({ concurrent: true })];
|
|
114
|
-
__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);
|
|
115
|
-
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
116
|
-
}
|
|
117
|
-
async spawnChildren() {
|
|
118
|
-
return [
|
|
119
|
-
createChildWorkflow(this, 'Child-0', false),
|
|
120
|
-
createChildWorkflow(this, 'Child-1', true), // Will fail
|
|
121
|
-
createChildWorkflow(this, 'Child-2', false),
|
|
122
|
-
createChildWorkflow(this, 'Child-3', false),
|
|
123
|
-
];
|
|
124
|
-
}
|
|
125
|
-
async run() {
|
|
126
|
-
try {
|
|
127
|
-
await this.spawnChildren();
|
|
128
|
-
}
|
|
129
|
-
catch (err) {
|
|
130
|
-
// Expected - first error thrown after all complete
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
constructor() {
|
|
134
|
-
super(...arguments);
|
|
135
|
-
__runInitializers(this, _instanceExtraInitializers);
|
|
136
|
-
}
|
|
137
|
-
};
|
|
138
|
-
})();
|
|
139
|
-
const parent = new ParentWorkflow('Parent');
|
|
140
|
-
// ACT: Run parent (children run concurrently)
|
|
141
|
-
await parent.run();
|
|
142
|
-
// ASSERT: All 4 children attached (Promise.allSettled completed all)
|
|
143
|
-
expect(parent.children.length).toBe(4);
|
|
144
|
-
// ASSERT: Verify child names match what we created
|
|
145
|
-
const childNames = parent.children.map((c) => c.node.name);
|
|
146
|
-
expect(childNames).toContain('Child-0');
|
|
147
|
-
expect(childNames).toContain('Child-1');
|
|
148
|
-
expect(childNames).toContain('Child-2');
|
|
149
|
-
expect(childNames).toContain('Child-3');
|
|
150
|
-
});
|
|
151
|
-
});
|
|
152
|
-
describe('Multiple concurrent failures', () => {
|
|
153
|
-
it('should collect all errors when multiple children fail concurrently', async () => {
|
|
154
|
-
// ARRANGE: Create parent with 6 children, 3 will fail
|
|
155
|
-
let ParentWorkflow = (() => {
|
|
156
|
-
let _classSuper = Workflow;
|
|
157
|
-
let _instanceExtraInitializers = [];
|
|
158
|
-
let _spawnChildren_decorators;
|
|
159
|
-
return class ParentWorkflow extends _classSuper {
|
|
160
|
-
static {
|
|
161
|
-
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
162
|
-
_spawnChildren_decorators = [Task({ concurrent: true })];
|
|
163
|
-
__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);
|
|
164
|
-
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
165
|
-
}
|
|
166
|
-
async spawnChildren() {
|
|
167
|
-
return [
|
|
168
|
-
createChildWorkflow(this, 'Alpha', false),
|
|
169
|
-
createChildWorkflow(this, 'Beta', true), // Will fail
|
|
170
|
-
createChildWorkflow(this, 'Gamma', false),
|
|
171
|
-
createChildWorkflow(this, 'Delta', true), // Will fail
|
|
172
|
-
createChildWorkflow(this, 'Epsilon', false),
|
|
173
|
-
createChildWorkflow(this, 'Zeta', true), // Will fail
|
|
174
|
-
];
|
|
175
|
-
}
|
|
176
|
-
async run() {
|
|
177
|
-
try {
|
|
178
|
-
await this.spawnChildren();
|
|
179
|
-
}
|
|
180
|
-
catch (err) {
|
|
181
|
-
// Expected
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
constructor() {
|
|
185
|
-
super(...arguments);
|
|
186
|
-
__runInitializers(this, _instanceExtraInitializers);
|
|
187
|
-
}
|
|
188
|
-
};
|
|
189
|
-
})();
|
|
190
|
-
const parent = new ParentWorkflow('Parent');
|
|
191
|
-
// ACT
|
|
192
|
-
await parent.run();
|
|
193
|
-
// ASSERT: All 6 children attached (Promise.allSettled completed all)
|
|
194
|
-
expect(parent.children.length).toBe(6);
|
|
195
|
-
// ASSERT: Verify expected child names are present
|
|
196
|
-
const childNames = parent.children.map((c) => c.node.name);
|
|
197
|
-
expect(childNames).toContain('Alpha');
|
|
198
|
-
expect(childNames).toContain('Beta');
|
|
199
|
-
expect(childNames).toContain('Gamma');
|
|
200
|
-
expect(childNames).toContain('Delta');
|
|
201
|
-
expect(childNames).toContain('Epsilon');
|
|
202
|
-
expect(childNames).toContain('Zeta');
|
|
203
|
-
});
|
|
204
|
-
it('should preserve error context for each failure', async () => {
|
|
205
|
-
// ARRANGE: Create parent with multiple failing children
|
|
206
|
-
let ParentWorkflow = (() => {
|
|
207
|
-
let _classSuper = Workflow;
|
|
208
|
-
let _instanceExtraInitializers = [];
|
|
209
|
-
let _spawnChildren_decorators;
|
|
210
|
-
return class ParentWorkflow extends _classSuper {
|
|
211
|
-
static {
|
|
212
|
-
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
213
|
-
_spawnChildren_decorators = [Task({ concurrent: true })];
|
|
214
|
-
__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);
|
|
215
|
-
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
216
|
-
}
|
|
217
|
-
async spawnChildren() {
|
|
218
|
-
return [
|
|
219
|
-
createChildWorkflow(this, 'Alpha', true),
|
|
220
|
-
createChildWorkflow(this, 'Beta', true),
|
|
221
|
-
createChildWorkflow(this, 'Gamma', true),
|
|
222
|
-
];
|
|
223
|
-
}
|
|
224
|
-
async run() {
|
|
225
|
-
try {
|
|
226
|
-
await this.spawnChildren();
|
|
227
|
-
}
|
|
228
|
-
catch (err) {
|
|
229
|
-
// Expected
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
constructor() {
|
|
233
|
-
super(...arguments);
|
|
234
|
-
__runInitializers(this, _instanceExtraInitializers);
|
|
235
|
-
}
|
|
236
|
-
};
|
|
237
|
-
})();
|
|
238
|
-
const parent = new ParentWorkflow('Parent');
|
|
239
|
-
const events = setupEventObserver(parent);
|
|
240
|
-
// ACT
|
|
241
|
-
await parent.run();
|
|
242
|
-
// ASSERT: Error events emitted for all failures
|
|
243
|
-
const errorEvents = events.filter((e) => e.type === 'error');
|
|
244
|
-
expect(errorEvents.length).toBeGreaterThanOrEqual(3);
|
|
245
|
-
// ASSERT: Each error event has correct structure
|
|
246
|
-
errorEvents.forEach((event) => {
|
|
247
|
-
expect(event.type).toBe('error');
|
|
248
|
-
if (event.type === 'error') {
|
|
249
|
-
expect(event.error).toBeDefined();
|
|
250
|
-
expect(event.error.workflowId).toBeDefined();
|
|
251
|
-
expect(event.error.message).toBeDefined();
|
|
252
|
-
expect(Array.isArray(event.error.logs)).toBe(true);
|
|
253
|
-
}
|
|
254
|
-
});
|
|
255
|
-
// ASSERT: All three distinct error messages captured
|
|
256
|
-
const errorMessages = errorEvents
|
|
257
|
-
.filter((e) => e.type === 'error')
|
|
258
|
-
.map((e) => e.error.message);
|
|
259
|
-
expect(errorMessages).toContain('Alpha failed');
|
|
260
|
-
expect(errorMessages).toContain('Beta failed');
|
|
261
|
-
expect(errorMessages).toContain('Gamma failed');
|
|
262
|
-
});
|
|
263
|
-
});
|
|
264
|
-
describe('Mixed success/failure scenarios', () => {
|
|
265
|
-
it('should complete successful workflows despite failures', async () => {
|
|
266
|
-
// ARRANGE: Create parent with mixed success/failure children
|
|
267
|
-
let ParentWorkflow = (() => {
|
|
268
|
-
let _classSuper = Workflow;
|
|
269
|
-
let _instanceExtraInitializers = [];
|
|
270
|
-
let _spawnChildren_decorators;
|
|
271
|
-
return class ParentWorkflow extends _classSuper {
|
|
272
|
-
static {
|
|
273
|
-
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
274
|
-
_spawnChildren_decorators = [Task({ concurrent: true })];
|
|
275
|
-
__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);
|
|
276
|
-
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
277
|
-
}
|
|
278
|
-
async spawnChildren() {
|
|
279
|
-
return [
|
|
280
|
-
createChildWorkflow(this, 'Success-1', false),
|
|
281
|
-
createChildWorkflow(this, 'Fail-1', true),
|
|
282
|
-
createChildWorkflow(this, 'Success-2', false),
|
|
283
|
-
createChildWorkflow(this, 'Fail-2', true),
|
|
284
|
-
createChildWorkflow(this, 'Success-3', false),
|
|
285
|
-
];
|
|
286
|
-
}
|
|
287
|
-
async run() {
|
|
288
|
-
try {
|
|
289
|
-
await this.spawnChildren();
|
|
290
|
-
}
|
|
291
|
-
catch (err) {
|
|
292
|
-
// Expected
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
constructor() {
|
|
296
|
-
super(...arguments);
|
|
297
|
-
__runInitializers(this, _instanceExtraInitializers);
|
|
298
|
-
}
|
|
299
|
-
};
|
|
300
|
-
})();
|
|
301
|
-
const parent = new ParentWorkflow('Parent');
|
|
302
|
-
// ACT
|
|
303
|
-
await parent.run();
|
|
304
|
-
// ASSERT: All 5 children attached (Promise.allSettled completed all)
|
|
305
|
-
expect(parent.children.length).toBe(5);
|
|
306
|
-
// ASSERT: Verify all expected children are present
|
|
307
|
-
const childNames = parent.children.map((c) => c.node.name);
|
|
308
|
-
expect(childNames).toContain('Success-1');
|
|
309
|
-
expect(childNames).toContain('Fail-1');
|
|
310
|
-
expect(childNames).toContain('Success-2');
|
|
311
|
-
expect(childNames).toContain('Fail-2');
|
|
312
|
-
expect(childNames).toContain('Success-3');
|
|
313
|
-
});
|
|
314
|
-
it('should ensure no orphaned workflows in mixed scenario', async () => {
|
|
315
|
-
// ARRANGE: Track all completions
|
|
316
|
-
const completedWorkflows = new Set();
|
|
317
|
-
let ParentWorkflow = (() => {
|
|
318
|
-
let _classSuper = Workflow;
|
|
319
|
-
let _instanceExtraInitializers = [];
|
|
320
|
-
let _spawnChildren_decorators;
|
|
321
|
-
return class ParentWorkflow extends _classSuper {
|
|
322
|
-
static {
|
|
323
|
-
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
324
|
-
_spawnChildren_decorators = [Task({ concurrent: true })];
|
|
325
|
-
__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);
|
|
326
|
-
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
327
|
-
}
|
|
328
|
-
async spawnChildren() {
|
|
329
|
-
const children = [
|
|
330
|
-
createChildWorkflow(this, 'Alpha', false),
|
|
331
|
-
createChildWorkflow(this, 'Beta', true),
|
|
332
|
-
createChildWorkflow(this, 'Gamma', false),
|
|
333
|
-
createChildWorkflow(this, 'Delta', false),
|
|
334
|
-
createChildWorkflow(this, 'Epsilon', true),
|
|
335
|
-
];
|
|
336
|
-
// Track completion for all children
|
|
337
|
-
children.forEach((child) => {
|
|
338
|
-
child.run().then(() => completedWorkflows.add(child.id), () => completedWorkflows.add(child.id));
|
|
339
|
-
});
|
|
340
|
-
return children;
|
|
341
|
-
}
|
|
342
|
-
async run() {
|
|
343
|
-
try {
|
|
344
|
-
await this.spawnChildren();
|
|
345
|
-
}
|
|
346
|
-
catch (err) {
|
|
347
|
-
// Expected
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
constructor() {
|
|
351
|
-
super(...arguments);
|
|
352
|
-
__runInitializers(this, _instanceExtraInitializers);
|
|
353
|
-
}
|
|
354
|
-
};
|
|
355
|
-
})();
|
|
356
|
-
const parent = new ParentWorkflow('Parent');
|
|
357
|
-
// ACT
|
|
358
|
-
await parent.run();
|
|
359
|
-
// ASSERT: All 5 workflows accounted for (no orphans)
|
|
360
|
-
expect(completedWorkflows.size).toBe(5);
|
|
361
|
-
expect(parent.children.length).toBe(5);
|
|
362
|
-
});
|
|
363
|
-
});
|
|
364
|
-
describe('All children failing', () => {
|
|
365
|
-
it('should handle edge case of all children failing', async () => {
|
|
366
|
-
// ARRANGE: All children will fail
|
|
367
|
-
let ParentWorkflow = (() => {
|
|
368
|
-
let _classSuper = Workflow;
|
|
369
|
-
let _instanceExtraInitializers = [];
|
|
370
|
-
let _spawnChildren_decorators;
|
|
371
|
-
return class ParentWorkflow extends _classSuper {
|
|
372
|
-
static {
|
|
373
|
-
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
374
|
-
_spawnChildren_decorators = [Task({ concurrent: true })];
|
|
375
|
-
__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);
|
|
376
|
-
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
377
|
-
}
|
|
378
|
-
async spawnChildren() {
|
|
379
|
-
return Array.from({ length: 5 }, (_, i) => createChildWorkflow(this, `FailChild-${i}`, true) // All fail
|
|
380
|
-
);
|
|
381
|
-
}
|
|
382
|
-
async run() {
|
|
383
|
-
try {
|
|
384
|
-
await this.spawnChildren();
|
|
385
|
-
}
|
|
386
|
-
catch (err) {
|
|
387
|
-
// Expected - first error thrown
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
constructor() {
|
|
391
|
-
super(...arguments);
|
|
392
|
-
__runInitializers(this, _instanceExtraInitializers);
|
|
393
|
-
}
|
|
394
|
-
};
|
|
395
|
-
})();
|
|
396
|
-
const parent = new ParentWorkflow('Parent');
|
|
397
|
-
const events = setupEventObserver(parent);
|
|
398
|
-
// ACT
|
|
399
|
-
await parent.run();
|
|
400
|
-
// ASSERT: All 5 children attached
|
|
401
|
-
expect(parent.children.length).toBe(5);
|
|
402
|
-
// ASSERT: Error events emitted for all failures
|
|
403
|
-
const errorEvents = events.filter((e) => e.type === 'error');
|
|
404
|
-
expect(errorEvents.length).toBeGreaterThanOrEqual(5);
|
|
405
|
-
// ASSERT: Each failure has distinct error message
|
|
406
|
-
const errorMessages = errorEvents
|
|
407
|
-
.filter((e) => e.type === 'error')
|
|
408
|
-
.map((e) => e.error.message);
|
|
409
|
-
for (let i = 0; i < 5; i++) {
|
|
410
|
-
expect(errorMessages).toContain(`FailChild-${i} failed`);
|
|
411
|
-
}
|
|
412
|
-
});
|
|
413
|
-
});
|
|
414
|
-
describe('No orphaned workflows', () => {
|
|
415
|
-
it('should verify all workflows complete with no hanging promises', async () => {
|
|
416
|
-
// ARRANGE: Track all completions
|
|
417
|
-
const completedWorkflows = new Set();
|
|
418
|
-
let ParentWorkflow = (() => {
|
|
419
|
-
let _classSuper = Workflow;
|
|
420
|
-
let _instanceExtraInitializers = [];
|
|
421
|
-
let _spawnChildren_decorators;
|
|
422
|
-
return class ParentWorkflow extends _classSuper {
|
|
423
|
-
static {
|
|
424
|
-
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
425
|
-
_spawnChildren_decorators = [Task({ concurrent: true })];
|
|
426
|
-
__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);
|
|
427
|
-
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
428
|
-
}
|
|
429
|
-
async spawnChildren() {
|
|
430
|
-
const children = Array.from({ length: 10 }, (_, i) => createChildWorkflow(this, `Child-${i}`, Math.random() < 0.3 // 30% failure rate
|
|
431
|
-
));
|
|
432
|
-
// Track completion for all children
|
|
433
|
-
children.forEach((child) => {
|
|
434
|
-
child.run().then(() => completedWorkflows.add(child.id), () => completedWorkflows.add(child.id));
|
|
435
|
-
});
|
|
436
|
-
return children;
|
|
437
|
-
}
|
|
438
|
-
async run() {
|
|
439
|
-
try {
|
|
440
|
-
await this.spawnChildren();
|
|
441
|
-
}
|
|
442
|
-
catch (err) {
|
|
443
|
-
// Expected
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
constructor() {
|
|
447
|
-
super(...arguments);
|
|
448
|
-
__runInitializers(this, _instanceExtraInitializers);
|
|
449
|
-
}
|
|
450
|
-
};
|
|
451
|
-
})();
|
|
452
|
-
const parent = new ParentWorkflow('Parent');
|
|
453
|
-
// ACT: Run with timeout to detect hanging promises
|
|
454
|
-
const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout: workflows hung')), 5000));
|
|
455
|
-
const runPromise = parent.run();
|
|
456
|
-
await Promise.race([runPromise, timeoutPromise]);
|
|
457
|
-
// ASSERT: All 10 workflows accounted for (no orphans)
|
|
458
|
-
expect(completedWorkflows.size).toBe(10);
|
|
459
|
-
});
|
|
460
|
-
});
|
|
461
|
-
describe('Event emission verification', () => {
|
|
462
|
-
it('should emit error events for all failing workflows', async () => {
|
|
463
|
-
// ARRANGE: Setup event observer
|
|
464
|
-
let ParentWorkflow = (() => {
|
|
465
|
-
let _classSuper = Workflow;
|
|
466
|
-
let _instanceExtraInitializers = [];
|
|
467
|
-
let _spawnChildren_decorators;
|
|
468
|
-
return class ParentWorkflow extends _classSuper {
|
|
469
|
-
static {
|
|
470
|
-
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
471
|
-
_spawnChildren_decorators = [Task({ concurrent: true })];
|
|
472
|
-
__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);
|
|
473
|
-
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
474
|
-
}
|
|
475
|
-
async spawnChildren() {
|
|
476
|
-
return [
|
|
477
|
-
createChildWorkflow(this, 'Good', false),
|
|
478
|
-
createChildWorkflow(this, 'Bad1', true),
|
|
479
|
-
createChildWorkflow(this, 'Bad2', true),
|
|
480
|
-
];
|
|
481
|
-
}
|
|
482
|
-
async run() {
|
|
483
|
-
try {
|
|
484
|
-
await this.spawnChildren();
|
|
485
|
-
}
|
|
486
|
-
catch (err) {
|
|
487
|
-
// Expected
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
constructor() {
|
|
491
|
-
super(...arguments);
|
|
492
|
-
__runInitializers(this, _instanceExtraInitializers);
|
|
493
|
-
}
|
|
494
|
-
};
|
|
495
|
-
})();
|
|
496
|
-
const parent = new ParentWorkflow('Parent');
|
|
497
|
-
const events = [];
|
|
498
|
-
// CRITICAL: Add observer to root workflow
|
|
499
|
-
parent.addObserver({
|
|
500
|
-
onLog: () => { },
|
|
501
|
-
onEvent: (e) => events.push(e),
|
|
502
|
-
onStateUpdated: () => { },
|
|
503
|
-
onTreeChanged: () => { },
|
|
504
|
-
});
|
|
505
|
-
// ACT
|
|
506
|
-
await parent.run();
|
|
507
|
-
// ASSERT: Error events emitted for both failures
|
|
508
|
-
const errorEvents = events.filter((e) => e.type === 'error');
|
|
509
|
-
expect(errorEvents.length).toBeGreaterThanOrEqual(2);
|
|
510
|
-
// ASSERT: Each error event has correct structure
|
|
511
|
-
errorEvents.forEach((event) => {
|
|
512
|
-
expect(event.type).toBe('error');
|
|
513
|
-
if (event.type === 'error') {
|
|
514
|
-
expect(event.error).toBeDefined();
|
|
515
|
-
expect(event.error.workflowId).toBeDefined();
|
|
516
|
-
expect(event.error.message).toBeDefined();
|
|
517
|
-
expect(Array.isArray(event.error.logs)).toBe(true);
|
|
518
|
-
}
|
|
519
|
-
});
|
|
520
|
-
// ASSERT: Verify expected error messages
|
|
521
|
-
const errorMessages = errorEvents
|
|
522
|
-
.filter((e) => e.type === 'error')
|
|
523
|
-
.map((e) => e.error.message);
|
|
524
|
-
expect(errorMessages).toContain('Bad1 failed');
|
|
525
|
-
expect(errorMessages).toContain('Bad2 failed');
|
|
526
|
-
});
|
|
527
|
-
it('should capture logs from both successful and failed workflows', async () => {
|
|
528
|
-
// ARRANGE: Create workflows that log before completion/failure
|
|
529
|
-
let ChildWorkflow = (() => {
|
|
530
|
-
let _classSuper = Workflow;
|
|
531
|
-
let _instanceExtraInitializers = [];
|
|
532
|
-
let _executeStep_decorators;
|
|
533
|
-
return class ChildWorkflow extends _classSuper {
|
|
534
|
-
static {
|
|
535
|
-
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
536
|
-
_executeStep_decorators = [Step()];
|
|
537
|
-
__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);
|
|
538
|
-
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
539
|
-
}
|
|
540
|
-
shouldFail = __runInitializers(this, _instanceExtraInitializers);
|
|
541
|
-
constructor(name, parent, shouldFail) {
|
|
542
|
-
super(name, parent);
|
|
543
|
-
this.shouldFail = shouldFail;
|
|
544
|
-
}
|
|
545
|
-
async executeStep() {
|
|
546
|
-
this.logger.info(`${this.node.name} is running`);
|
|
547
|
-
if (this.shouldFail) {
|
|
548
|
-
this.logger.error(`${this.node.name} is about to fail`);
|
|
549
|
-
throw new Error(`${this.node.name} failed`);
|
|
550
|
-
}
|
|
551
|
-
this.logger.info(`${this.node.name} completed successfully`);
|
|
552
|
-
return `${this.node.name} succeeded`;
|
|
553
|
-
}
|
|
554
|
-
async run() {
|
|
555
|
-
return this.executeStep();
|
|
556
|
-
}
|
|
557
|
-
};
|
|
558
|
-
})();
|
|
559
|
-
let ParentWorkflow = (() => {
|
|
560
|
-
let _classSuper = Workflow;
|
|
561
|
-
let _instanceExtraInitializers = [];
|
|
562
|
-
let _spawnChildren_decorators;
|
|
563
|
-
return class ParentWorkflow extends _classSuper {
|
|
564
|
-
static {
|
|
565
|
-
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
566
|
-
_spawnChildren_decorators = [Task({ concurrent: true })];
|
|
567
|
-
__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);
|
|
568
|
-
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
569
|
-
}
|
|
570
|
-
async spawnChildren() {
|
|
571
|
-
return [
|
|
572
|
-
new ChildWorkflow('SuccessChild', this, false),
|
|
573
|
-
new ChildWorkflow('FailChild', this, true),
|
|
574
|
-
];
|
|
575
|
-
}
|
|
576
|
-
async run() {
|
|
577
|
-
try {
|
|
578
|
-
await this.spawnChildren();
|
|
579
|
-
}
|
|
580
|
-
catch (err) {
|
|
581
|
-
// Expected
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
constructor() {
|
|
585
|
-
super(...arguments);
|
|
586
|
-
__runInitializers(this, _instanceExtraInitializers);
|
|
587
|
-
}
|
|
588
|
-
};
|
|
589
|
-
})();
|
|
590
|
-
const parent = new ParentWorkflow('Parent');
|
|
591
|
-
const allLogs = [];
|
|
592
|
-
parent.addObserver({
|
|
593
|
-
onLog: (entry) => allLogs.push(entry.message),
|
|
594
|
-
onEvent: () => { },
|
|
595
|
-
onStateUpdated: () => { },
|
|
596
|
-
onTreeChanged: () => { },
|
|
597
|
-
});
|
|
598
|
-
// ACT
|
|
599
|
-
await parent.run();
|
|
600
|
-
// ASSERT: Logs from both children captured
|
|
601
|
-
expect(allLogs.length).toBeGreaterThan(0);
|
|
602
|
-
// ASSERT: Success child logs present
|
|
603
|
-
expect(allLogs.some((msg) => msg.includes('SuccessChild is running'))).toBe(true);
|
|
604
|
-
expect(allLogs.some((msg) => msg.includes('SuccessChild completed successfully'))).toBe(true);
|
|
605
|
-
// ASSERT: Fail child logs present
|
|
606
|
-
expect(allLogs.some((msg) => msg.includes('FailChild is running'))).toBe(true);
|
|
607
|
-
expect(allLogs.some((msg) => msg.includes('FailChild is about to fail'))).toBe(true);
|
|
608
|
-
});
|
|
609
|
-
});
|
|
610
|
-
describe('Error collection correctness', () => {
|
|
611
|
-
it('should verify error messages are preserved correctly', async () => {
|
|
612
|
-
// ARRANGE: Create children with specific error messages
|
|
613
|
-
let ParentWorkflow = (() => {
|
|
614
|
-
let _classSuper = Workflow;
|
|
615
|
-
let _instanceExtraInitializers = [];
|
|
616
|
-
let _spawnChildren_decorators;
|
|
617
|
-
return class ParentWorkflow extends _classSuper {
|
|
618
|
-
static {
|
|
619
|
-
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
620
|
-
_spawnChildren_decorators = [Task({ concurrent: true })];
|
|
621
|
-
__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);
|
|
622
|
-
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
623
|
-
}
|
|
624
|
-
async spawnChildren() {
|
|
625
|
-
return [
|
|
626
|
-
createChildWorkflow(this, 'Task-Alpha', false),
|
|
627
|
-
createChildWorkflow(this, 'Task-Beta', true), // Will fail with "Task-Beta failed"
|
|
628
|
-
createChildWorkflow(this, 'Task-Gamma', false),
|
|
629
|
-
];
|
|
630
|
-
}
|
|
631
|
-
async run() {
|
|
632
|
-
try {
|
|
633
|
-
await this.spawnChildren();
|
|
634
|
-
}
|
|
635
|
-
catch (err) {
|
|
636
|
-
// Expected - error should be thrown
|
|
637
|
-
return err;
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
constructor() {
|
|
641
|
-
super(...arguments);
|
|
642
|
-
__runInitializers(this, _instanceExtraInitializers);
|
|
643
|
-
}
|
|
644
|
-
};
|
|
645
|
-
})();
|
|
646
|
-
const parent = new ParentWorkflow('Parent');
|
|
647
|
-
const events = setupEventObserver(parent);
|
|
648
|
-
// ACT
|
|
649
|
-
const thrownError = await parent.run();
|
|
650
|
-
// ASSERT: Error was thrown
|
|
651
|
-
expect(thrownError).toBeDefined();
|
|
652
|
-
// ASSERT: Error message is preserved (WorkflowError wraps the original)
|
|
653
|
-
expect(thrownError.message).toContain('Task-Beta failed');
|
|
654
|
-
// ASSERT: Error events captured with correct messages
|
|
655
|
-
const errorEvents = events.filter((e) => e.type === 'error');
|
|
656
|
-
expect(errorEvents.length).toBeGreaterThanOrEqual(1);
|
|
657
|
-
const matchingError = errorEvents.find((e) => {
|
|
658
|
-
if (e.type === 'error') {
|
|
659
|
-
return e.error.message.includes('Task-Beta');
|
|
660
|
-
}
|
|
661
|
-
return false;
|
|
662
|
-
});
|
|
663
|
-
expect(matchingError).toBeDefined();
|
|
664
|
-
});
|
|
665
|
-
});
|
|
666
|
-
});
|
|
667
|
-
//# sourceMappingURL=concurrent-task-failures.test.js.map
|