@calmo/task-runner 3.8.0 → 3.8.2
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/CHANGELOG.md +10 -0
- package/coverage/coverage-final.json +5 -4
- package/coverage/index.html +18 -18
- package/coverage/lcov-report/index.html +18 -18
- package/coverage/lcov-report/src/EventBus.ts.html +70 -34
- package/coverage/lcov-report/src/TaskGraphValidationError.ts.html +1 -1
- package/coverage/lcov-report/src/TaskGraphValidator.ts.html +120 -60
- package/coverage/lcov-report/src/TaskRunner.ts.html +78 -63
- package/coverage/lcov-report/src/TaskRunnerBuilder.ts.html +1 -1
- package/coverage/lcov-report/src/TaskRunnerExecutionConfig.ts.html +1 -1
- package/coverage/lcov-report/src/TaskStateManager.ts.html +17 -29
- package/coverage/lcov-report/src/WorkflowExecutor.ts.html +1 -1
- package/coverage/lcov-report/src/contracts/ErrorTypes.ts.html +103 -0
- package/coverage/lcov-report/src/contracts/RunnerEvents.ts.html +1 -1
- package/coverage/lcov-report/src/contracts/index.html +23 -8
- package/coverage/lcov-report/src/index.html +13 -13
- package/coverage/lcov-report/src/strategies/DryRunExecutionStrategy.ts.html +1 -1
- package/coverage/lcov-report/src/strategies/RetryingExecutionStrategy.ts.html +1 -1
- package/coverage/lcov-report/src/strategies/StandardExecutionStrategy.ts.html +1 -1
- package/coverage/lcov-report/src/strategies/index.html +1 -1
- package/coverage/lcov.info +238 -213
- package/coverage/src/EventBus.ts.html +70 -34
- package/coverage/src/TaskGraphValidationError.ts.html +1 -1
- package/coverage/src/TaskGraphValidator.ts.html +120 -60
- package/coverage/src/TaskRunner.ts.html +78 -63
- package/coverage/src/TaskRunnerBuilder.ts.html +1 -1
- package/coverage/src/TaskRunnerExecutionConfig.ts.html +1 -1
- package/coverage/src/TaskStateManager.ts.html +17 -29
- package/coverage/src/WorkflowExecutor.ts.html +1 -1
- package/coverage/src/contracts/ErrorTypes.ts.html +103 -0
- package/coverage/src/contracts/RunnerEvents.ts.html +1 -1
- package/coverage/src/contracts/index.html +23 -8
- package/coverage/src/index.html +13 -13
- package/coverage/src/strategies/DryRunExecutionStrategy.ts.html +1 -1
- package/coverage/src/strategies/RetryingExecutionStrategy.ts.html +1 -1
- package/coverage/src/strategies/StandardExecutionStrategy.ts.html +1 -1
- package/coverage/src/strategies/index.html +1 -1
- package/dist/EventBus.js +11 -2
- package/dist/EventBus.js.map +1 -1
- package/dist/TaskGraphValidator.d.ts +3 -0
- package/dist/TaskGraphValidator.js +33 -26
- package/dist/TaskGraphValidator.js.map +1 -1
- package/dist/TaskRunner.d.ts +4 -0
- package/dist/TaskRunner.js +38 -44
- package/dist/TaskRunner.js.map +1 -1
- package/dist/TaskStateManager.js +1 -5
- package/dist/TaskStateManager.js.map +1 -1
- package/dist/contracts/ErrorTypes.d.ts +6 -0
- package/dist/contracts/ErrorTypes.js +7 -0
- package/dist/contracts/ErrorTypes.js.map +1 -0
- package/dist/contracts/ValidationError.d.ts +2 -1
- package/package.json +1 -1
- package/src/EventBus.ts +27 -15
- package/src/TaskGraphValidator.ts +52 -32
- package/src/TaskRunner.ts +51 -46
- package/src/TaskStateManager.ts +1 -5
- package/src/contracts/ErrorTypes.ts +6 -0
- package/src/contracts/ValidationError.ts +10 -1
- package/test-report.xml +152 -128
package/coverage/src/index.html
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
<div class='fl pad1y space-right2'>
|
|
26
26
|
<span class="strong">100% </span>
|
|
27
27
|
<span class="quiet">Statements</span>
|
|
28
|
-
<span class='fraction'>
|
|
28
|
+
<span class='fraction'>257/257</span>
|
|
29
29
|
</div>
|
|
30
30
|
|
|
31
31
|
|
|
@@ -39,14 +39,14 @@
|
|
|
39
39
|
<div class='fl pad1y space-right2'>
|
|
40
40
|
<span class="strong">100% </span>
|
|
41
41
|
<span class="quiet">Functions</span>
|
|
42
|
-
<span class='fraction'>
|
|
42
|
+
<span class='fraction'>51/51</span>
|
|
43
43
|
</div>
|
|
44
44
|
|
|
45
45
|
|
|
46
46
|
<div class='fl pad1y space-right2'>
|
|
47
47
|
<span class="strong">100% </span>
|
|
48
48
|
<span class="quiet">Lines</span>
|
|
49
|
-
<span class='fraction'>
|
|
49
|
+
<span class='fraction'>254/254</span>
|
|
50
50
|
</div>
|
|
51
51
|
|
|
52
52
|
|
|
@@ -84,13 +84,13 @@
|
|
|
84
84
|
<div class="chart"><div class="cover-fill cover-full" style="width: 100%"></div><div class="cover-empty" style="width: 0%"></div></div>
|
|
85
85
|
</td>
|
|
86
86
|
<td data-value="100" class="pct high">100%</td>
|
|
87
|
-
<td data-value="
|
|
87
|
+
<td data-value="17" class="abs high">17/17</td>
|
|
88
88
|
<td data-value="100" class="pct high">100%</td>
|
|
89
89
|
<td data-value="8" class="abs high">8/8</td>
|
|
90
90
|
<td data-value="100" class="pct high">100%</td>
|
|
91
|
-
<td data-value="
|
|
91
|
+
<td data-value="6" class="abs high">6/6</td>
|
|
92
92
|
<td data-value="100" class="pct high">100%</td>
|
|
93
|
-
<td data-value="
|
|
93
|
+
<td data-value="17" class="abs high">17/17</td>
|
|
94
94
|
</tr>
|
|
95
95
|
|
|
96
96
|
<tr>
|
|
@@ -114,13 +114,13 @@
|
|
|
114
114
|
<div class="chart"><div class="cover-fill cover-full" style="width: 100%"></div><div class="cover-empty" style="width: 0%"></div></div>
|
|
115
115
|
</td>
|
|
116
116
|
<td data-value="100" class="pct high">100%</td>
|
|
117
|
-
<td data-value="
|
|
117
|
+
<td data-value="59" class="abs high">59/59</td>
|
|
118
118
|
<td data-value="100" class="pct high">100%</td>
|
|
119
119
|
<td data-value="16" class="abs high">16/16</td>
|
|
120
120
|
<td data-value="100" class="pct high">100%</td>
|
|
121
|
-
<td data-value="
|
|
121
|
+
<td data-value="8" class="abs high">8/8</td>
|
|
122
122
|
<td data-value="100" class="pct high">100%</td>
|
|
123
|
-
<td data-value="
|
|
123
|
+
<td data-value="58" class="abs high">58/58</td>
|
|
124
124
|
</tr>
|
|
125
125
|
|
|
126
126
|
<tr>
|
|
@@ -129,7 +129,7 @@
|
|
|
129
129
|
<div class="chart"><div class="cover-fill cover-full" style="width: 100%"></div><div class="cover-empty" style="width: 0%"></div></div>
|
|
130
130
|
</td>
|
|
131
131
|
<td data-value="100" class="pct high">100%</td>
|
|
132
|
-
<td data-value="
|
|
132
|
+
<td data-value="48" class="abs high">48/48</td>
|
|
133
133
|
<td data-value="100" class="pct high">100%</td>
|
|
134
134
|
<td data-value="18" class="abs high">18/18</td>
|
|
135
135
|
<td data-value="100" class="pct high">100%</td>
|
|
@@ -174,13 +174,13 @@
|
|
|
174
174
|
<div class="chart"><div class="cover-fill cover-full" style="width: 100%"></div><div class="cover-empty" style="width: 0%"></div></div>
|
|
175
175
|
</td>
|
|
176
176
|
<td data-value="100" class="pct high">100%</td>
|
|
177
|
-
<td data-value="
|
|
177
|
+
<td data-value="48" class="abs high">48/48</td>
|
|
178
178
|
<td data-value="100" class="pct high">100%</td>
|
|
179
179
|
<td data-value="16" class="abs high">16/16</td>
|
|
180
180
|
<td data-value="100" class="pct high">100%</td>
|
|
181
181
|
<td data-value="10" class="abs high">10/10</td>
|
|
182
182
|
<td data-value="100" class="pct high">100%</td>
|
|
183
|
-
<td data-value="
|
|
183
|
+
<td data-value="48" class="abs high">48/48</td>
|
|
184
184
|
</tr>
|
|
185
185
|
|
|
186
186
|
<tr>
|
|
@@ -206,7 +206,7 @@
|
|
|
206
206
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
207
207
|
Code coverage generated by
|
|
208
208
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
209
|
-
at 2026-01-
|
|
209
|
+
at 2026-01-21T01:16:02.338Z
|
|
210
210
|
</div>
|
|
211
211
|
<script src="../prettify.js"></script>
|
|
212
212
|
<script>
|
|
@@ -163,7 +163,7 @@ export class DryRunExecutionStrategy<
|
|
|
163
163
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
164
164
|
Code coverage generated by
|
|
165
165
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
166
|
-
at 2026-01-
|
|
166
|
+
at 2026-01-21T01:16:02.338Z
|
|
167
167
|
</div>
|
|
168
168
|
<script src="../../prettify.js"></script>
|
|
169
169
|
<script>
|
|
@@ -358,7 +358,7 @@ export class RetryingExecutionStrategy<
|
|
|
358
358
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
359
359
|
Code coverage generated by
|
|
360
360
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
361
|
-
at 2026-01-
|
|
361
|
+
at 2026-01-21T01:16:02.338Z
|
|
362
362
|
</div>
|
|
363
363
|
<script src="../../prettify.js"></script>
|
|
364
364
|
<script>
|
|
@@ -175,7 +175,7 @@ export class StandardExecutionStrategy<
|
|
|
175
175
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
176
176
|
Code coverage generated by
|
|
177
177
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
178
|
-
at 2026-01-
|
|
178
|
+
at 2026-01-21T01:16:02.338Z
|
|
179
179
|
</div>
|
|
180
180
|
<script src="../../prettify.js"></script>
|
|
181
181
|
<script>
|
|
@@ -131,7 +131,7 @@
|
|
|
131
131
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
132
132
|
Code coverage generated by
|
|
133
133
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
134
|
-
at 2026-01-
|
|
134
|
+
at 2026-01-21T01:16:02.338Z
|
|
135
135
|
</div>
|
|
136
136
|
<script src="../../prettify.js"></script>
|
|
137
137
|
<script>
|
package/dist/EventBus.js
CHANGED
|
@@ -37,19 +37,28 @@ export class EventBus {
|
|
|
37
37
|
const listeners = this.listeners[event];
|
|
38
38
|
if (listeners) {
|
|
39
39
|
for (const listener of listeners) {
|
|
40
|
-
Promise.resolve().then(
|
|
40
|
+
// We use Promise.resolve().then() to schedule the listener on the microtask queue,
|
|
41
|
+
// ensuring the emit method remains non-blocking.
|
|
42
|
+
// The final .catch() ensures that any errors in the promise infrastructure itself are logged.
|
|
43
|
+
Promise.resolve()
|
|
44
|
+
.then(() => {
|
|
41
45
|
try {
|
|
42
46
|
const result = listener(data);
|
|
43
47
|
if (result instanceof Promise) {
|
|
48
|
+
// Handle async listener rejections
|
|
44
49
|
result.catch((error) => {
|
|
45
50
|
console.error(`Error in event listener for ${String(event)}:`, error);
|
|
46
51
|
});
|
|
47
52
|
}
|
|
48
53
|
}
|
|
49
54
|
catch (error) {
|
|
50
|
-
//
|
|
55
|
+
// Handle sync listener errors
|
|
51
56
|
console.error(`Error in event listener for ${String(event)}:`, error);
|
|
52
57
|
}
|
|
58
|
+
})
|
|
59
|
+
.catch((error) => {
|
|
60
|
+
// detailed handling for the promise chain itself
|
|
61
|
+
console.error(`Unexpected error in event bus execution for ${String(event)}:`, error);
|
|
53
62
|
});
|
|
54
63
|
}
|
|
55
64
|
}
|
package/dist/EventBus.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EventBus.js","sourceRoot":"","sources":["../src/EventBus.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,MAAM,OAAO,QAAQ;IACX,SAAS,GAA0B,EAAE,CAAC;IAE9C;;;;OAIG;IACI,EAAE,CACP,KAAQ,EACR,QAA0C;QAE1C,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,4EAA4E;YAC5E,iEAAiE;YACjE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,GAAG,EAAyC,CAAC;QAC3E,CAAC;QACD,oFAAoF;QACnF,IAAI,CAAC,SAAS,CAAC,KAAK,CAA2C,CAAC,GAAG,CAClE,QAAQ,CACT,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACI,GAAG,CACR,KAAQ,EACR,QAA0C;QAE1C,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,SAAS,CAAC,KAAK,CAA2C,CAAC,MAAM,CACrE,QAAQ,CACT,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;OAIG;IACI,IAAI,CACT,KAAQ,EACR,IAAsC;QAEtC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAEzB,CAAC;QACd,IAAI,SAAS,EAAE,CAAC;YACd,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;gBACjC,OAAO,CAAC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"EventBus.js","sourceRoot":"","sources":["../src/EventBus.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,MAAM,OAAO,QAAQ;IACX,SAAS,GAA0B,EAAE,CAAC;IAE9C;;;;OAIG;IACI,EAAE,CACP,KAAQ,EACR,QAA0C;QAE1C,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,4EAA4E;YAC5E,iEAAiE;YACjE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,GAAG,EAAyC,CAAC;QAC3E,CAAC;QACD,oFAAoF;QACnF,IAAI,CAAC,SAAS,CAAC,KAAK,CAA2C,CAAC,GAAG,CAClE,QAAQ,CACT,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACI,GAAG,CACR,KAAQ,EACR,QAA0C;QAE1C,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,SAAS,CAAC,KAAK,CAA2C,CAAC,MAAM,CACrE,QAAQ,CACT,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;OAIG;IACI,IAAI,CACT,KAAQ,EACR,IAAsC;QAEtC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAEzB,CAAC;QACd,IAAI,SAAS,EAAE,CAAC;YACd,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;gBACjC,mFAAmF;gBACnF,iDAAiD;gBACjD,8FAA8F;gBAC9F,OAAO,CAAC,OAAO,EAAE;qBACd,IAAI,CAAC,GAAG,EAAE;oBACT,IAAI,CAAC;wBACH,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;wBAC9B,IAAI,MAAM,YAAY,OAAO,EAAE,CAAC;4BAC9B,mCAAmC;4BACnC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;gCACrB,OAAO,CAAC,KAAK,CACX,+BAA+B,MAAM,CAAC,KAAK,CAAC,GAAG,EAC/C,KAAK,CACN,CAAC;4BACJ,CAAC,CAAC,CAAC;wBACL,CAAC;oBACH,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,8BAA8B;wBAC9B,OAAO,CAAC,KAAK,CACX,+BAA+B,MAAM,CAAC,KAAK,CAAC,GAAG,EAC/C,KAAK,CACN,CAAC;oBACJ,CAAC;gBACH,CAAC,CAAC;qBACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;oBACf,iDAAiD;oBACjD,OAAO,CAAC,KAAK,CACX,+CAA+C,MAAM,CAAC,KAAK,CAAC,GAAG,EAC/D,KAAK,CACN,CAAC;gBACJ,CAAC,CAAC,CAAC;YACP,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
|
|
@@ -19,5 +19,8 @@ export declare class TaskGraphValidator implements ITaskGraphValidator {
|
|
|
19
19
|
* @returns A formatted error string.
|
|
20
20
|
*/
|
|
21
21
|
createErrorMessage(result: ValidationResult): string;
|
|
22
|
+
private checkDuplicateTasks;
|
|
23
|
+
private checkMissingDependencies;
|
|
24
|
+
private checkCycles;
|
|
22
25
|
private detectCycle;
|
|
23
26
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ERROR_CYCLE, ERROR_DUPLICATE_TASK, ERROR_MISSING_DEPENDENCY, } from "./contracts/ErrorTypes.js";
|
|
1
2
|
export class TaskGraphValidator {
|
|
2
3
|
/**
|
|
3
4
|
* Validates a given task graph for structural integrity.
|
|
@@ -12,11 +13,35 @@ export class TaskGraphValidator {
|
|
|
12
13
|
validate(taskGraph) {
|
|
13
14
|
const errors = [];
|
|
14
15
|
// 1. Check for duplicate tasks
|
|
16
|
+
const taskIds = this.checkDuplicateTasks(taskGraph, errors);
|
|
17
|
+
// 2. Check for missing dependencies
|
|
18
|
+
this.checkMissingDependencies(taskGraph, taskIds, errors);
|
|
19
|
+
// 3. Check for cycles
|
|
20
|
+
// Only run cycle detection if there are no missing dependencies, otherwise we might chase non-existent nodes.
|
|
21
|
+
const hasMissingDependencies = errors.some((e) => e.type === ERROR_MISSING_DEPENDENCY);
|
|
22
|
+
if (!hasMissingDependencies) {
|
|
23
|
+
this.checkCycles(taskGraph, errors);
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
isValid: errors.length === 0,
|
|
27
|
+
errors,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Creates a human-readable error message from a validation result.
|
|
32
|
+
* @param result The validation result containing errors.
|
|
33
|
+
* @returns A formatted error string.
|
|
34
|
+
*/
|
|
35
|
+
createErrorMessage(result) {
|
|
36
|
+
const errorDetails = result.errors.map((e) => e.message);
|
|
37
|
+
return `Task graph validation failed: ${errorDetails.join("; ")}`;
|
|
38
|
+
}
|
|
39
|
+
checkDuplicateTasks(taskGraph, errors) {
|
|
15
40
|
const taskIds = new Set();
|
|
16
41
|
for (const task of taskGraph.tasks) {
|
|
17
42
|
if (taskIds.has(task.id)) {
|
|
18
43
|
errors.push({
|
|
19
|
-
type:
|
|
44
|
+
type: ERROR_DUPLICATE_TASK,
|
|
20
45
|
message: `Duplicate task detected with ID: ${task.id}`,
|
|
21
46
|
details: { taskId: task.id },
|
|
22
47
|
});
|
|
@@ -25,27 +50,22 @@ export class TaskGraphValidator {
|
|
|
25
50
|
taskIds.add(task.id);
|
|
26
51
|
}
|
|
27
52
|
}
|
|
28
|
-
|
|
53
|
+
return taskIds;
|
|
54
|
+
}
|
|
55
|
+
checkMissingDependencies(taskGraph, taskIds, errors) {
|
|
29
56
|
for (const task of taskGraph.tasks) {
|
|
30
57
|
for (const dependenceId of task.dependencies) {
|
|
31
58
|
if (!taskIds.has(dependenceId)) {
|
|
32
59
|
errors.push({
|
|
33
|
-
type:
|
|
60
|
+
type: ERROR_MISSING_DEPENDENCY,
|
|
34
61
|
message: `Task '${task.id}' depends on missing task '${dependenceId}'`,
|
|
35
62
|
details: { taskId: task.id, missingDependencyId: dependenceId },
|
|
36
63
|
});
|
|
37
64
|
}
|
|
38
65
|
}
|
|
39
66
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const hasMissingDependencies = errors.some((e) => e.type === "missing_dependency");
|
|
43
|
-
if (hasMissingDependencies) {
|
|
44
|
-
return {
|
|
45
|
-
isValid: errors.length === 0,
|
|
46
|
-
errors,
|
|
47
|
-
};
|
|
48
|
-
}
|
|
67
|
+
}
|
|
68
|
+
checkCycles(taskGraph, errors) {
|
|
49
69
|
// Build adjacency list
|
|
50
70
|
const adjacencyList = new Map();
|
|
51
71
|
for (const task of taskGraph.tasks) {
|
|
@@ -65,7 +85,7 @@ export class TaskGraphValidator {
|
|
|
65
85
|
const cycleStartIndex = path.indexOf(cycleStart);
|
|
66
86
|
const cyclePath = path.slice(cycleStartIndex);
|
|
67
87
|
errors.push({
|
|
68
|
-
type:
|
|
88
|
+
type: ERROR_CYCLE,
|
|
69
89
|
message: `Cycle detected: ${cyclePath.join(" -> ")}`,
|
|
70
90
|
details: { cyclePath },
|
|
71
91
|
});
|
|
@@ -73,19 +93,6 @@ export class TaskGraphValidator {
|
|
|
73
93
|
break;
|
|
74
94
|
}
|
|
75
95
|
}
|
|
76
|
-
return {
|
|
77
|
-
isValid: errors.length === 0,
|
|
78
|
-
errors,
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Creates a human-readable error message from a validation result.
|
|
83
|
-
* @param result The validation result containing errors.
|
|
84
|
-
* @returns A formatted error string.
|
|
85
|
-
*/
|
|
86
|
-
createErrorMessage(result) {
|
|
87
|
-
const errorDetails = result.errors.map((e) => e.message);
|
|
88
|
-
return `Task graph validation failed: ${errorDetails.join("; ")}`;
|
|
89
96
|
}
|
|
90
97
|
detectCycle(startTaskId, path, visited, recursionStack, adjacencyList) {
|
|
91
98
|
// Use an explicit stack to avoid maximum call stack size exceeded errors
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TaskGraphValidator.js","sourceRoot":"","sources":["../src/TaskGraphValidator.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TaskGraphValidator.js","sourceRoot":"","sources":["../src/TaskGraphValidator.ts"],"names":[],"mappings":"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"}
|
package/dist/TaskRunner.d.ts
CHANGED
|
@@ -57,4 +57,8 @@ export declare class TaskRunner<TContext> {
|
|
|
57
57
|
* and values are the corresponding TaskResult objects.
|
|
58
58
|
*/
|
|
59
59
|
execute(steps: TaskStep<TContext>[], config?: TaskRunnerExecutionConfig): Promise<Map<string, TaskResult>>;
|
|
60
|
+
/**
|
|
61
|
+
* Executes tasks with a timeout, ensuring resources are cleaned up.
|
|
62
|
+
*/
|
|
63
|
+
private executeWithTimeout;
|
|
60
64
|
}
|
package/dist/TaskRunner.js
CHANGED
|
@@ -56,21 +56,10 @@ export class TaskRunner {
|
|
|
56
56
|
*/
|
|
57
57
|
static getMermaidGraph(steps) {
|
|
58
58
|
const graphLines = ["graph TD"];
|
|
59
|
-
// Helper to sanitize node names or wrap them if needed
|
|
60
|
-
// For simplicity, we just wrap in quotes and use the name as ID if it's simple
|
|
61
|
-
// or generate an ID if strictly needed. Here we assume names are unique IDs.
|
|
62
|
-
// We will wrap names in quotes for the label, but use the name as the ID.
|
|
63
|
-
// Actually, Mermaid ID cannot have spaces without quotes.
|
|
64
|
-
const safeId = (name) => JSON.stringify(name);
|
|
65
59
|
const sanitize = (name) => this.sanitizeMermaidId(name);
|
|
66
|
-
// Add all nodes first to ensure they exist
|
|
67
60
|
for (const step of steps) {
|
|
68
|
-
|
|
69
|
-
// Format: ID["Label"]
|
|
70
|
-
// safeId returns a quoted string (e.g. "Task Name"), so we use it directly as the label
|
|
71
|
-
graphLines.push(` ${sanitize(step.name)}[${safeId(step.name)}]`);
|
|
61
|
+
graphLines.push(` ${sanitize(step.name)}[${JSON.stringify(step.name)}]`);
|
|
72
62
|
}
|
|
73
|
-
// Add edges
|
|
74
63
|
for (const step of steps) {
|
|
75
64
|
if (step.dependencies) {
|
|
76
65
|
for (const dep of step.dependencies) {
|
|
@@ -114,43 +103,48 @@ export class TaskRunner {
|
|
|
114
103
|
strategy = new DryRunExecutionStrategy();
|
|
115
104
|
}
|
|
116
105
|
const executor = new WorkflowExecutor(this.context, this.eventBus, stateManager, strategy, config?.concurrency);
|
|
117
|
-
// We need to handle the timeout cleanup properly.
|
|
118
106
|
if (config?.timeout !== undefined) {
|
|
119
|
-
|
|
120
|
-
const timeoutId = setTimeout(() => {
|
|
121
|
-
controller.abort(new Error(`Workflow timed out after ${config.timeout}ms`));
|
|
122
|
-
}, config.timeout);
|
|
123
|
-
let effectiveSignal = controller.signal;
|
|
124
|
-
let onAbort;
|
|
125
|
-
// Handle combination of signals if user provided one
|
|
126
|
-
if (config.signal) {
|
|
127
|
-
if (config.signal.aborted) {
|
|
128
|
-
// If already aborted, use it directly (WorkflowExecutor handles early abort)
|
|
129
|
-
// We can cancel timeout immediately
|
|
130
|
-
clearTimeout(timeoutId);
|
|
131
|
-
effectiveSignal = config.signal;
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
// Listen to user signal to abort our controller
|
|
135
|
-
onAbort = () => {
|
|
136
|
-
controller.abort(config.signal?.reason);
|
|
137
|
-
};
|
|
138
|
-
config.signal.addEventListener("abort", onAbort);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
try {
|
|
142
|
-
return await executor.execute(steps, effectiveSignal);
|
|
143
|
-
}
|
|
144
|
-
finally {
|
|
145
|
-
clearTimeout(timeoutId);
|
|
146
|
-
if (config.signal && onAbort) {
|
|
147
|
-
config.signal.removeEventListener("abort", onAbort);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
107
|
+
return this.executeWithTimeout(executor, steps, config.timeout, config.signal);
|
|
150
108
|
}
|
|
151
109
|
else {
|
|
152
110
|
return executor.execute(steps, config?.signal);
|
|
153
111
|
}
|
|
154
112
|
}
|
|
113
|
+
/**
|
|
114
|
+
* Executes tasks with a timeout, ensuring resources are cleaned up.
|
|
115
|
+
*/
|
|
116
|
+
async executeWithTimeout(executor, steps, timeout, signal) {
|
|
117
|
+
const controller = new AbortController();
|
|
118
|
+
const timeoutId = setTimeout(() => {
|
|
119
|
+
controller.abort(new Error(`Workflow timed out after ${timeout}ms`));
|
|
120
|
+
}, timeout);
|
|
121
|
+
let effectiveSignal = controller.signal;
|
|
122
|
+
let onAbort;
|
|
123
|
+
// Handle combination of signals if user provided one
|
|
124
|
+
if (signal) {
|
|
125
|
+
if (signal.aborted) {
|
|
126
|
+
// If already aborted, use it directly (WorkflowExecutor handles early abort)
|
|
127
|
+
// We can cancel timeout immediately
|
|
128
|
+
clearTimeout(timeoutId);
|
|
129
|
+
effectiveSignal = signal;
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
// Listen to user signal to abort our controller
|
|
133
|
+
onAbort = () => {
|
|
134
|
+
controller.abort(signal.reason);
|
|
135
|
+
};
|
|
136
|
+
signal.addEventListener("abort", onAbort);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
try {
|
|
140
|
+
return await executor.execute(steps, effectiveSignal);
|
|
141
|
+
}
|
|
142
|
+
finally {
|
|
143
|
+
clearTimeout(timeoutId);
|
|
144
|
+
if (signal && onAbort) {
|
|
145
|
+
signal.removeEventListener("abort", onAbort);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
155
149
|
}
|
|
156
150
|
//# sourceMappingURL=TaskRunner.js.map
|
package/dist/TaskRunner.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TaskRunner.js","sourceRoot":"","sources":["../src/TaskRunner.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAM7D,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAEzE,OAAO,EAAE,yBAAyB,EAAE,MAAM,2CAA2C,CAAC;AACtF,OAAO,EAAE,yBAAyB,EAAE,MAAM,2CAA2C,CAAC;AACtF,OAAO,EAAE,uBAAuB,EAAE,MAAM,yCAAyC,CAAC;AAKlF;;;;GAIG;AACH,MAAM,OAAO,UAAU;IASD;IARZ,QAAQ,GAAG,IAAI,QAAQ,EAAY,CAAC;IACpC,SAAS,GAAG,IAAI,kBAAkB,EAAE,CAAC;IACrC,iBAAiB,GACvB,IAAI,yBAAyB,CAAC,IAAI,yBAAyB,EAAE,CAAC,CAAC;IAEjE;;OAEG;IACH,YAAoB,OAAiB;QAAjB,YAAO,GAAP,OAAO,CAAU;IAAG,CAAC;IAEzC;;;;OAIG;IACI,EAAE,CACP,KAAQ,EACR,QAA0C;QAE1C,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACpC,CAAC;IAED;;;;OAIG;IACI,GAAG,CACR,KAAQ,EACR,QAA0C;QAE1C,sBAAsB;QACtB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACrC,CAAC;IAED;;;;OAIG;IACI,oBAAoB,CAAC,QAAsC;QAChE,sBAAsB;QACtB,IAAI,CAAC,iBAAiB,GAAG,QAAQ,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,eAAe,CAAI,KAAoB;QACnD,MAAM,UAAU,GAAG,CAAC,UAAU,CAAC,CAAC;QAEhC,
|
|
1
|
+
{"version":3,"file":"TaskRunner.js","sourceRoot":"","sources":["../src/TaskRunner.ts"],"names":[],"mappings":"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"}
|
package/dist/TaskStateManager.js
CHANGED
|
@@ -91,20 +91,16 @@ export class TaskStateManager {
|
|
|
91
91
|
for (const step of this.pendingSteps) {
|
|
92
92
|
// Also check running? No, running tasks are handled by AbortSignal in Executor.
|
|
93
93
|
// We only cancel what is pending and hasn't started.
|
|
94
|
-
/* v8 ignore next 1 */
|
|
95
94
|
if (!this.results.has(step.name) && !this.running.has(step.name)) {
|
|
96
95
|
const result = {
|
|
97
96
|
status: "cancelled",
|
|
98
97
|
message,
|
|
99
98
|
};
|
|
100
99
|
this.results.set(step.name, result);
|
|
100
|
+
this.eventBus.emit("taskEnd", { step, result });
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
// Clear pending set as they are now "done" (cancelled)
|
|
104
|
-
// Wait, if we clear pending steps, processDependencies won't pick them up.
|
|
105
|
-
// The loop in Executor relies on results.size or pendingSteps.
|
|
106
|
-
// The previous implementation iterated `steps` (all steps) to cancel.
|
|
107
|
-
// Here we iterate `pendingSteps`.
|
|
108
104
|
this.pendingSteps.clear();
|
|
109
105
|
}
|
|
110
106
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TaskStateManager.js","sourceRoot":"","sources":["../src/TaskStateManager.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"TaskStateManager.js","sourceRoot":"","sources":["../src/TaskStateManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ErrorTypes.js","sourceRoot":"","sources":["../../src/contracts/ErrorTypes.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,gBAAyB,CAAC;AAC9D,MAAM,CAAC,MAAM,wBAAwB,GAAG,oBAA6B,CAAC;AACtE,MAAM,CAAC,MAAM,WAAW,GAAG,OAAgB,CAAC"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { ERROR_CYCLE, ERROR_DUPLICATE_TASK, ERROR_MISSING_DEPENDENCY } from "./ErrorTypes.js";
|
|
1
2
|
/**
|
|
2
3
|
* Describes a specific validation error found in the task graph.
|
|
3
4
|
*/
|
|
4
5
|
export interface ValidationError {
|
|
5
6
|
/** The type of validation error. */
|
|
6
|
-
type:
|
|
7
|
+
type: typeof ERROR_CYCLE | typeof ERROR_MISSING_DEPENDENCY | typeof ERROR_DUPLICATE_TASK;
|
|
7
8
|
/** A human-readable message describing the error. */
|
|
8
9
|
message: string;
|
|
9
10
|
/** Optional detailed information about the error, e.g., the cycle path, or the task with a missing dependency. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@calmo/task-runner",
|
|
3
|
-
"version": "3.8.
|
|
3
|
+
"version": "3.8.2",
|
|
4
4
|
"description": "A lightweight, type-safe, and domain-agnostic task orchestration engine. It resolves a Directed Acyclic Graph (DAG) of steps, executes independent tasks in parallel, and manages a shared context across the pipeline.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
package/src/EventBus.ts
CHANGED
|
@@ -61,25 +61,37 @@ export class EventBus<TContext> {
|
|
|
61
61
|
| undefined;
|
|
62
62
|
if (listeners) {
|
|
63
63
|
for (const listener of listeners) {
|
|
64
|
-
Promise.resolve().then(
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
64
|
+
// We use Promise.resolve().then() to schedule the listener on the microtask queue,
|
|
65
|
+
// ensuring the emit method remains non-blocking.
|
|
66
|
+
// The final .catch() ensures that any errors in the promise infrastructure itself are logged.
|
|
67
|
+
Promise.resolve()
|
|
68
|
+
.then(() => {
|
|
69
|
+
try {
|
|
70
|
+
const result = listener(data);
|
|
71
|
+
if (result instanceof Promise) {
|
|
72
|
+
// Handle async listener rejections
|
|
73
|
+
result.catch((error) => {
|
|
74
|
+
console.error(
|
|
75
|
+
`Error in event listener for ${String(event)}:`,
|
|
76
|
+
error
|
|
77
|
+
);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
} catch (error) {
|
|
81
|
+
// Handle sync listener errors
|
|
82
|
+
console.error(
|
|
83
|
+
`Error in event listener for ${String(event)}:`,
|
|
84
|
+
error
|
|
85
|
+
);
|
|
74
86
|
}
|
|
75
|
-
}
|
|
76
|
-
|
|
87
|
+
})
|
|
88
|
+
.catch((error) => {
|
|
89
|
+
// detailed handling for the promise chain itself
|
|
77
90
|
console.error(
|
|
78
|
-
`
|
|
91
|
+
`Unexpected error in event bus execution for ${String(event)}:`,
|
|
79
92
|
error
|
|
80
93
|
);
|
|
81
|
-
}
|
|
82
|
-
});
|
|
94
|
+
});
|
|
83
95
|
}
|
|
84
96
|
}
|
|
85
97
|
}
|