@calmo/task-runner 2.0.0 → 3.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/AGENTS.md +49 -0
- package/CHANGELOG.md +21 -0
- package/README.md +1 -1
- package/coverage/coverage-final.json +8 -4
- package/coverage/index.html +24 -9
- package/coverage/lcov-report/index.html +24 -9
- package/coverage/lcov-report/src/EventBus.ts.html +8 -8
- package/coverage/lcov-report/src/TaskGraphValidator.ts.html +53 -53
- package/coverage/lcov-report/src/TaskRunner.ts.html +213 -21
- package/coverage/lcov-report/src/TaskRunnerBuilder.ts.html +313 -0
- package/coverage/lcov-report/src/TaskRunnerExecutionConfig.ts.html +124 -0
- package/coverage/lcov-report/src/TaskStateManager.ts.html +511 -0
- package/coverage/lcov-report/src/WorkflowExecutor.ts.html +119 -137
- package/coverage/lcov-report/src/contracts/RunnerEvents.ts.html +1 -1
- package/coverage/lcov-report/src/contracts/index.html +1 -1
- package/coverage/lcov-report/src/index.html +57 -12
- package/coverage/lcov-report/src/strategies/StandardExecutionStrategy.ts.html +190 -0
- package/coverage/lcov-report/src/strategies/index.html +116 -0
- package/coverage/lcov.info +381 -204
- package/coverage/src/EventBus.ts.html +8 -8
- package/coverage/src/TaskGraphValidator.ts.html +53 -53
- package/coverage/src/TaskRunner.ts.html +213 -21
- package/coverage/src/TaskRunnerBuilder.ts.html +313 -0
- package/coverage/src/TaskRunnerExecutionConfig.ts.html +124 -0
- package/coverage/src/TaskStateManager.ts.html +511 -0
- package/coverage/src/WorkflowExecutor.ts.html +119 -137
- package/coverage/src/contracts/RunnerEvents.ts.html +1 -1
- package/coverage/src/contracts/index.html +1 -1
- package/coverage/src/index.html +57 -12
- package/coverage/src/strategies/StandardExecutionStrategy.ts.html +190 -0
- package/coverage/src/strategies/index.html +116 -0
- package/dist/TaskRunner.d.ts +12 -2
- package/dist/TaskRunner.js +55 -3
- package/dist/TaskRunner.js.map +1 -1
- package/dist/TaskRunnerBuilder.d.ts +33 -0
- package/dist/TaskRunnerBuilder.js +54 -0
- package/dist/TaskRunnerBuilder.js.map +1 -0
- package/dist/TaskRunnerExecutionConfig.d.ts +13 -0
- package/dist/TaskRunnerExecutionConfig.js +2 -0
- package/dist/TaskRunnerExecutionConfig.js.map +1 -0
- package/dist/TaskStateManager.d.ts +54 -0
- package/dist/TaskStateManager.js +130 -0
- package/dist/TaskStateManager.js.map +1 -0
- package/dist/TaskStatus.d.ts +1 -1
- package/dist/TaskStep.d.ts +2 -1
- package/dist/WorkflowExecutor.d.ts +11 -17
- package/dist/WorkflowExecutor.js +67 -69
- package/dist/WorkflowExecutor.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/strategies/IExecutionStrategy.d.ts +16 -0
- package/dist/strategies/IExecutionStrategy.js +2 -0
- package/dist/strategies/IExecutionStrategy.js.map +1 -0
- package/dist/strategies/StandardExecutionStrategy.d.ts +9 -0
- package/dist/strategies/StandardExecutionStrategy.js +25 -0
- package/dist/strategies/StandardExecutionStrategy.js.map +1 -0
- package/openspec/changes/add-concurrency-control/proposal.md +14 -0
- package/openspec/changes/add-concurrency-control/tasks.md +9 -0
- package/openspec/changes/add-task-retry-policy/proposal.md +13 -0
- package/openspec/changes/add-task-retry-policy/tasks.md +10 -0
- package/openspec/changes/add-workflow-preview/proposal.md +12 -0
- package/openspec/changes/add-workflow-preview/tasks.md +7 -0
- package/openspec/changes/archive/2026-01-18-add-external-task-cancellation/tasks.md +10 -0
- package/openspec/changes/archive/2026-01-18-add-integration-tests/proposal.md +18 -0
- package/openspec/changes/archive/2026-01-18-add-integration-tests/tasks.md +17 -0
- package/openspec/changes/archive/2026-01-18-refactor-core-architecture/proposal.md +14 -0
- package/openspec/changes/archive/2026-01-18-refactor-core-architecture/tasks.md +8 -0
- package/package.json +1 -1
- package/src/TaskRunner.ts +68 -4
- package/src/TaskRunnerBuilder.ts +76 -0
- package/src/TaskRunnerExecutionConfig.ts +13 -0
- package/src/TaskStateManager.ts +142 -0
- package/src/TaskStatus.ts +1 -1
- package/src/TaskStep.ts +2 -1
- package/src/WorkflowExecutor.ts +77 -83
- package/src/index.ts +4 -0
- package/src/strategies/IExecutionStrategy.ts +21 -0
- package/src/strategies/StandardExecutionStrategy.ts +35 -0
- package/test-report.xml +119 -45
- package/GEMINI.md +0 -48
- package/openspec/changes/add-external-task-cancellation/tasks.md +0 -10
- /package/openspec/changes/{add-external-task-cancellation → archive/2026-01-18-add-external-task-cancellation}/proposal.md +0 -0
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
|
|
2
|
+
<!doctype html>
|
|
3
|
+
<html lang="en">
|
|
4
|
+
|
|
5
|
+
<head>
|
|
6
|
+
<title>Code coverage report for src/strategies/StandardExecutionStrategy.ts</title>
|
|
7
|
+
<meta charset="utf-8" />
|
|
8
|
+
<link rel="stylesheet" href="../../prettify.css" />
|
|
9
|
+
<link rel="stylesheet" href="../../base.css" />
|
|
10
|
+
<link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" />
|
|
11
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
12
|
+
<style type='text/css'>
|
|
13
|
+
.coverage-summary .sorter {
|
|
14
|
+
background-image: url(../../sort-arrow-sprite.png);
|
|
15
|
+
}
|
|
16
|
+
</style>
|
|
17
|
+
</head>
|
|
18
|
+
|
|
19
|
+
<body>
|
|
20
|
+
<div class='wrapper'>
|
|
21
|
+
<div class='pad1'>
|
|
22
|
+
<h1><a href="../../index.html">All files</a> / <a href="index.html">src/strategies</a> StandardExecutionStrategy.ts</h1>
|
|
23
|
+
<div class='clearfix'>
|
|
24
|
+
|
|
25
|
+
<div class='fl pad1y space-right2'>
|
|
26
|
+
<span class="strong">100% </span>
|
|
27
|
+
<span class="quiet">Statements</span>
|
|
28
|
+
<span class='fraction'>5/5</span>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
<div class='fl pad1y space-right2'>
|
|
33
|
+
<span class="strong">100% </span>
|
|
34
|
+
<span class="quiet">Branches</span>
|
|
35
|
+
<span class='fraction'>8/8</span>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
<div class='fl pad1y space-right2'>
|
|
40
|
+
<span class="strong">100% </span>
|
|
41
|
+
<span class="quiet">Functions</span>
|
|
42
|
+
<span class='fraction'>1/1</span>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
<div class='fl pad1y space-right2'>
|
|
47
|
+
<span class="strong">100% </span>
|
|
48
|
+
<span class="quiet">Lines</span>
|
|
49
|
+
<span class='fraction'>5/5</span>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
</div>
|
|
54
|
+
<p class="quiet">
|
|
55
|
+
Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
|
|
56
|
+
</p>
|
|
57
|
+
<template id="filterTemplate">
|
|
58
|
+
<div class="quiet">
|
|
59
|
+
Filter:
|
|
60
|
+
<input type="search" id="fileSearch">
|
|
61
|
+
</div>
|
|
62
|
+
</template>
|
|
63
|
+
</div>
|
|
64
|
+
<div class='status-line high'></div>
|
|
65
|
+
<pre><table class="coverage">
|
|
66
|
+
<tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
|
|
67
|
+
<a name='L2'></a><a href='#L2'>2</a>
|
|
68
|
+
<a name='L3'></a><a href='#L3'>3</a>
|
|
69
|
+
<a name='L4'></a><a href='#L4'>4</a>
|
|
70
|
+
<a name='L5'></a><a href='#L5'>5</a>
|
|
71
|
+
<a name='L6'></a><a href='#L6'>6</a>
|
|
72
|
+
<a name='L7'></a><a href='#L7'>7</a>
|
|
73
|
+
<a name='L8'></a><a href='#L8'>8</a>
|
|
74
|
+
<a name='L9'></a><a href='#L9'>9</a>
|
|
75
|
+
<a name='L10'></a><a href='#L10'>10</a>
|
|
76
|
+
<a name='L11'></a><a href='#L11'>11</a>
|
|
77
|
+
<a name='L12'></a><a href='#L12'>12</a>
|
|
78
|
+
<a name='L13'></a><a href='#L13'>13</a>
|
|
79
|
+
<a name='L14'></a><a href='#L14'>14</a>
|
|
80
|
+
<a name='L15'></a><a href='#L15'>15</a>
|
|
81
|
+
<a name='L16'></a><a href='#L16'>16</a>
|
|
82
|
+
<a name='L17'></a><a href='#L17'>17</a>
|
|
83
|
+
<a name='L18'></a><a href='#L18'>18</a>
|
|
84
|
+
<a name='L19'></a><a href='#L19'>19</a>
|
|
85
|
+
<a name='L20'></a><a href='#L20'>20</a>
|
|
86
|
+
<a name='L21'></a><a href='#L21'>21</a>
|
|
87
|
+
<a name='L22'></a><a href='#L22'>22</a>
|
|
88
|
+
<a name='L23'></a><a href='#L23'>23</a>
|
|
89
|
+
<a name='L24'></a><a href='#L24'>24</a>
|
|
90
|
+
<a name='L25'></a><a href='#L25'>25</a>
|
|
91
|
+
<a name='L26'></a><a href='#L26'>26</a>
|
|
92
|
+
<a name='L27'></a><a href='#L27'>27</a>
|
|
93
|
+
<a name='L28'></a><a href='#L28'>28</a>
|
|
94
|
+
<a name='L29'></a><a href='#L29'>29</a>
|
|
95
|
+
<a name='L30'></a><a href='#L30'>30</a>
|
|
96
|
+
<a name='L31'></a><a href='#L31'>31</a>
|
|
97
|
+
<a name='L32'></a><a href='#L32'>32</a>
|
|
98
|
+
<a name='L33'></a><a href='#L33'>33</a>
|
|
99
|
+
<a name='L34'></a><a href='#L34'>34</a>
|
|
100
|
+
<a name='L35'></a><a href='#L35'>35</a>
|
|
101
|
+
<a name='L36'></a><a href='#L36'>36</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span>
|
|
102
|
+
<span class="cline-any cline-neutral"> </span>
|
|
103
|
+
<span class="cline-any cline-neutral"> </span>
|
|
104
|
+
<span class="cline-any cline-neutral"> </span>
|
|
105
|
+
<span class="cline-any cline-neutral"> </span>
|
|
106
|
+
<span class="cline-any cline-neutral"> </span>
|
|
107
|
+
<span class="cline-any cline-neutral"> </span>
|
|
108
|
+
<span class="cline-any cline-neutral"> </span>
|
|
109
|
+
<span class="cline-any cline-neutral"> </span>
|
|
110
|
+
<span class="cline-any cline-neutral"> </span>
|
|
111
|
+
<span class="cline-any cline-neutral"> </span>
|
|
112
|
+
<span class="cline-any cline-neutral"> </span>
|
|
113
|
+
<span class="cline-any cline-neutral"> </span>
|
|
114
|
+
<span class="cline-any cline-neutral"> </span>
|
|
115
|
+
<span class="cline-any cline-neutral"> </span>
|
|
116
|
+
<span class="cline-any cline-yes">101x</span>
|
|
117
|
+
<span class="cline-any cline-yes">101x</span>
|
|
118
|
+
<span class="cline-any cline-neutral"> </span>
|
|
119
|
+
<span class="cline-any cline-neutral"> </span>
|
|
120
|
+
<span class="cline-any cline-yes">10x</span>
|
|
121
|
+
<span class="cline-any cline-neutral"> </span>
|
|
122
|
+
<span class="cline-any cline-neutral"> </span>
|
|
123
|
+
<span class="cline-any cline-neutral"> </span>
|
|
124
|
+
<span class="cline-any cline-yes">6x</span>
|
|
125
|
+
<span class="cline-any cline-neutral"> </span>
|
|
126
|
+
<span class="cline-any cline-neutral"> </span>
|
|
127
|
+
<span class="cline-any cline-neutral"> </span>
|
|
128
|
+
<span class="cline-any cline-neutral"> </span>
|
|
129
|
+
<span class="cline-any cline-yes">4x</span>
|
|
130
|
+
<span class="cline-any cline-neutral"> </span>
|
|
131
|
+
<span class="cline-any cline-neutral"> </span>
|
|
132
|
+
<span class="cline-any cline-neutral"> </span>
|
|
133
|
+
<span class="cline-any cline-neutral"> </span>
|
|
134
|
+
<span class="cline-any cline-neutral"> </span>
|
|
135
|
+
<span class="cline-any cline-neutral"> </span>
|
|
136
|
+
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">import { IExecutionStrategy } from "./IExecutionStrategy.js";
|
|
137
|
+
import { TaskStep } from "../TaskStep.js";
|
|
138
|
+
import { TaskResult } from "../TaskResult.js";
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Standard execution strategy that runs the task's run method.
|
|
142
|
+
*/
|
|
143
|
+
export class StandardExecutionStrategy<TContext>
|
|
144
|
+
implements IExecutionStrategy<TContext>
|
|
145
|
+
{
|
|
146
|
+
async execute(
|
|
147
|
+
step: TaskStep<TContext>,
|
|
148
|
+
context: TContext,
|
|
149
|
+
signal?: AbortSignal
|
|
150
|
+
): Promise<TaskResult> {
|
|
151
|
+
try {
|
|
152
|
+
return await step.run(context, signal);
|
|
153
|
+
} catch (e) {
|
|
154
|
+
// Check if error is due to abort
|
|
155
|
+
if (
|
|
156
|
+
signal?.aborted &&
|
|
157
|
+
(e instanceof Error && e.name === "AbortError" || signal.reason === e)
|
|
158
|
+
) {
|
|
159
|
+
return {
|
|
160
|
+
status: "cancelled",
|
|
161
|
+
message: "Task cancelled during execution",
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
status: "failure",
|
|
166
|
+
error: e instanceof Error ? e.message : String(e),
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
</pre></td></tr></table></pre>
|
|
172
|
+
|
|
173
|
+
<div class='push'></div><!-- for sticky footer -->
|
|
174
|
+
</div><!-- /wrapper -->
|
|
175
|
+
<div class='footer quiet pad2 space-top1 center small'>
|
|
176
|
+
Code coverage generated by
|
|
177
|
+
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
178
|
+
at 2026-01-18T16:53:50.059Z
|
|
179
|
+
</div>
|
|
180
|
+
<script src="../../prettify.js"></script>
|
|
181
|
+
<script>
|
|
182
|
+
window.onload = function () {
|
|
183
|
+
prettyPrint();
|
|
184
|
+
};
|
|
185
|
+
</script>
|
|
186
|
+
<script src="../../sorter.js"></script>
|
|
187
|
+
<script src="../../block-navigation.js"></script>
|
|
188
|
+
</body>
|
|
189
|
+
</html>
|
|
190
|
+
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
|
|
2
|
+
<!doctype html>
|
|
3
|
+
<html lang="en">
|
|
4
|
+
|
|
5
|
+
<head>
|
|
6
|
+
<title>Code coverage report for src/strategies</title>
|
|
7
|
+
<meta charset="utf-8" />
|
|
8
|
+
<link rel="stylesheet" href="../../prettify.css" />
|
|
9
|
+
<link rel="stylesheet" href="../../base.css" />
|
|
10
|
+
<link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" />
|
|
11
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
12
|
+
<style type='text/css'>
|
|
13
|
+
.coverage-summary .sorter {
|
|
14
|
+
background-image: url(../../sort-arrow-sprite.png);
|
|
15
|
+
}
|
|
16
|
+
</style>
|
|
17
|
+
</head>
|
|
18
|
+
|
|
19
|
+
<body>
|
|
20
|
+
<div class='wrapper'>
|
|
21
|
+
<div class='pad1'>
|
|
22
|
+
<h1><a href="../../index.html">All files</a> src/strategies</h1>
|
|
23
|
+
<div class='clearfix'>
|
|
24
|
+
|
|
25
|
+
<div class='fl pad1y space-right2'>
|
|
26
|
+
<span class="strong">100% </span>
|
|
27
|
+
<span class="quiet">Statements</span>
|
|
28
|
+
<span class='fraction'>5/5</span>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
<div class='fl pad1y space-right2'>
|
|
33
|
+
<span class="strong">100% </span>
|
|
34
|
+
<span class="quiet">Branches</span>
|
|
35
|
+
<span class='fraction'>8/8</span>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
<div class='fl pad1y space-right2'>
|
|
40
|
+
<span class="strong">100% </span>
|
|
41
|
+
<span class="quiet">Functions</span>
|
|
42
|
+
<span class='fraction'>1/1</span>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
<div class='fl pad1y space-right2'>
|
|
47
|
+
<span class="strong">100% </span>
|
|
48
|
+
<span class="quiet">Lines</span>
|
|
49
|
+
<span class='fraction'>5/5</span>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
</div>
|
|
54
|
+
<p class="quiet">
|
|
55
|
+
Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
|
|
56
|
+
</p>
|
|
57
|
+
<template id="filterTemplate">
|
|
58
|
+
<div class="quiet">
|
|
59
|
+
Filter:
|
|
60
|
+
<input type="search" id="fileSearch">
|
|
61
|
+
</div>
|
|
62
|
+
</template>
|
|
63
|
+
</div>
|
|
64
|
+
<div class='status-line high'></div>
|
|
65
|
+
<div class="pad1">
|
|
66
|
+
<table class="coverage-summary">
|
|
67
|
+
<thead>
|
|
68
|
+
<tr>
|
|
69
|
+
<th data-col="file" data-fmt="html" data-html="true" class="file">File</th>
|
|
70
|
+
<th data-col="pic" data-type="number" data-fmt="html" data-html="true" class="pic"></th>
|
|
71
|
+
<th data-col="statements" data-type="number" data-fmt="pct" class="pct">Statements</th>
|
|
72
|
+
<th data-col="statements_raw" data-type="number" data-fmt="html" class="abs"></th>
|
|
73
|
+
<th data-col="branches" data-type="number" data-fmt="pct" class="pct">Branches</th>
|
|
74
|
+
<th data-col="branches_raw" data-type="number" data-fmt="html" class="abs"></th>
|
|
75
|
+
<th data-col="functions" data-type="number" data-fmt="pct" class="pct">Functions</th>
|
|
76
|
+
<th data-col="functions_raw" data-type="number" data-fmt="html" class="abs"></th>
|
|
77
|
+
<th data-col="lines" data-type="number" data-fmt="pct" class="pct">Lines</th>
|
|
78
|
+
<th data-col="lines_raw" data-type="number" data-fmt="html" class="abs"></th>
|
|
79
|
+
</tr>
|
|
80
|
+
</thead>
|
|
81
|
+
<tbody><tr>
|
|
82
|
+
<td class="file high" data-value="StandardExecutionStrategy.ts"><a href="StandardExecutionStrategy.ts.html">StandardExecutionStrategy.ts</a></td>
|
|
83
|
+
<td data-value="100" class="pic high">
|
|
84
|
+
<div class="chart"><div class="cover-fill cover-full" style="width: 100%"></div><div class="cover-empty" style="width: 0%"></div></div>
|
|
85
|
+
</td>
|
|
86
|
+
<td data-value="100" class="pct high">100%</td>
|
|
87
|
+
<td data-value="5" class="abs high">5/5</td>
|
|
88
|
+
<td data-value="100" class="pct high">100%</td>
|
|
89
|
+
<td data-value="8" class="abs high">8/8</td>
|
|
90
|
+
<td data-value="100" class="pct high">100%</td>
|
|
91
|
+
<td data-value="1" class="abs high">1/1</td>
|
|
92
|
+
<td data-value="100" class="pct high">100%</td>
|
|
93
|
+
<td data-value="5" class="abs high">5/5</td>
|
|
94
|
+
</tr>
|
|
95
|
+
|
|
96
|
+
</tbody>
|
|
97
|
+
</table>
|
|
98
|
+
</div>
|
|
99
|
+
<div class='push'></div><!-- for sticky footer -->
|
|
100
|
+
</div><!-- /wrapper -->
|
|
101
|
+
<div class='footer quiet pad2 space-top1 center small'>
|
|
102
|
+
Code coverage generated by
|
|
103
|
+
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
104
|
+
at 2026-01-18T16:53:50.059Z
|
|
105
|
+
</div>
|
|
106
|
+
<script src="../../prettify.js"></script>
|
|
107
|
+
<script>
|
|
108
|
+
window.onload = function () {
|
|
109
|
+
prettyPrint();
|
|
110
|
+
};
|
|
111
|
+
</script>
|
|
112
|
+
<script src="../../sorter.js"></script>
|
|
113
|
+
<script src="../../block-navigation.js"></script>
|
|
114
|
+
</body>
|
|
115
|
+
</html>
|
|
116
|
+
|
package/dist/TaskRunner.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { TaskStep } from "./TaskStep.js";
|
|
2
2
|
import { TaskResult } from "./TaskResult.js";
|
|
3
3
|
import { RunnerEventPayloads, RunnerEventListener } from "./contracts/RunnerEvents.js";
|
|
4
|
-
|
|
4
|
+
import { TaskRunnerExecutionConfig } from "./TaskRunnerExecutionConfig.js";
|
|
5
|
+
import { IExecutionStrategy } from "./strategies/IExecutionStrategy.js";
|
|
6
|
+
export { RunnerEventPayloads, RunnerEventListener, TaskRunnerExecutionConfig };
|
|
5
7
|
/**
|
|
6
8
|
* The main class that orchestrates the execution of a list of tasks
|
|
7
9
|
* based on their dependencies, with support for parallel execution.
|
|
@@ -11,6 +13,7 @@ export declare class TaskRunner<TContext> {
|
|
|
11
13
|
private context;
|
|
12
14
|
private eventBus;
|
|
13
15
|
private validator;
|
|
16
|
+
private executionStrategy;
|
|
14
17
|
/**
|
|
15
18
|
* @param context The shared context object to be passed to each task.
|
|
16
19
|
*/
|
|
@@ -27,12 +30,19 @@ export declare class TaskRunner<TContext> {
|
|
|
27
30
|
* @param callback The callback to remove.
|
|
28
31
|
*/
|
|
29
32
|
off<K extends keyof RunnerEventPayloads<TContext>>(event: K, callback: RunnerEventListener<TContext, K>): void;
|
|
33
|
+
/**
|
|
34
|
+
* Sets the execution strategy to be used.
|
|
35
|
+
* @param strategy The execution strategy.
|
|
36
|
+
* @returns The TaskRunner instance for chaining.
|
|
37
|
+
*/
|
|
38
|
+
setExecutionStrategy(strategy: IExecutionStrategy<TContext>): this;
|
|
30
39
|
/**
|
|
31
40
|
* Executes a list of tasks, respecting their dependencies and running
|
|
32
41
|
* independent tasks in parallel.
|
|
33
42
|
* @param steps An array of TaskStep objects to be executed.
|
|
43
|
+
* @param config Optional configuration for execution (timeout, cancellation).
|
|
34
44
|
* @returns A Promise that resolves to a Map where keys are task names
|
|
35
45
|
* and values are the corresponding TaskResult objects.
|
|
36
46
|
*/
|
|
37
|
-
execute(steps: TaskStep<TContext>[]): Promise<Map<string, TaskResult>>;
|
|
47
|
+
execute(steps: TaskStep<TContext>[], config?: TaskRunnerExecutionConfig): Promise<Map<string, TaskResult>>;
|
|
38
48
|
}
|
package/dist/TaskRunner.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { TaskGraphValidator } from "./TaskGraphValidator.js";
|
|
2
2
|
import { EventBus } from "./EventBus.js";
|
|
3
3
|
import { WorkflowExecutor } from "./WorkflowExecutor.js";
|
|
4
|
+
import { TaskStateManager } from "./TaskStateManager.js";
|
|
5
|
+
import { StandardExecutionStrategy } from "./strategies/StandardExecutionStrategy.js";
|
|
4
6
|
/**
|
|
5
7
|
* The main class that orchestrates the execution of a list of tasks
|
|
6
8
|
* based on their dependencies, with support for parallel execution.
|
|
@@ -10,6 +12,7 @@ export class TaskRunner {
|
|
|
10
12
|
context;
|
|
11
13
|
eventBus = new EventBus();
|
|
12
14
|
validator = new TaskGraphValidator();
|
|
15
|
+
executionStrategy = new StandardExecutionStrategy();
|
|
13
16
|
/**
|
|
14
17
|
* @param context The shared context object to be passed to each task.
|
|
15
18
|
*/
|
|
@@ -30,16 +33,28 @@ export class TaskRunner {
|
|
|
30
33
|
* @param callback The callback to remove.
|
|
31
34
|
*/
|
|
32
35
|
off(event, callback) {
|
|
36
|
+
/* v8 ignore next 1 */
|
|
33
37
|
this.eventBus.off(event, callback);
|
|
34
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Sets the execution strategy to be used.
|
|
41
|
+
* @param strategy The execution strategy.
|
|
42
|
+
* @returns The TaskRunner instance for chaining.
|
|
43
|
+
*/
|
|
44
|
+
setExecutionStrategy(strategy) {
|
|
45
|
+
/* v8 ignore next 2 */
|
|
46
|
+
this.executionStrategy = strategy;
|
|
47
|
+
return this;
|
|
48
|
+
}
|
|
35
49
|
/**
|
|
36
50
|
* Executes a list of tasks, respecting their dependencies and running
|
|
37
51
|
* independent tasks in parallel.
|
|
38
52
|
* @param steps An array of TaskStep objects to be executed.
|
|
53
|
+
* @param config Optional configuration for execution (timeout, cancellation).
|
|
39
54
|
* @returns A Promise that resolves to a Map where keys are task names
|
|
40
55
|
* and values are the corresponding TaskResult objects.
|
|
41
56
|
*/
|
|
42
|
-
async execute(steps) {
|
|
57
|
+
async execute(steps, config) {
|
|
43
58
|
// Validate the task graph before execution
|
|
44
59
|
const taskGraph = {
|
|
45
60
|
tasks: steps.map((step) => ({
|
|
@@ -51,8 +66,45 @@ export class TaskRunner {
|
|
|
51
66
|
if (!validationResult.isValid) {
|
|
52
67
|
throw new Error(this.validator.createErrorMessage(validationResult));
|
|
53
68
|
}
|
|
54
|
-
const
|
|
55
|
-
|
|
69
|
+
const stateManager = new TaskStateManager(this.eventBus);
|
|
70
|
+
const executor = new WorkflowExecutor(this.context, this.eventBus, stateManager, this.executionStrategy);
|
|
71
|
+
// We need to handle the timeout cleanup properly.
|
|
72
|
+
if (config?.timeout !== undefined) {
|
|
73
|
+
const controller = new AbortController();
|
|
74
|
+
const timeoutId = setTimeout(() => {
|
|
75
|
+
controller.abort(new Error(`Workflow timed out after ${config.timeout}ms`));
|
|
76
|
+
}, config.timeout);
|
|
77
|
+
let effectiveSignal = controller.signal;
|
|
78
|
+
let onAbort;
|
|
79
|
+
// Handle combination of signals if user provided one
|
|
80
|
+
if (config.signal) {
|
|
81
|
+
if (config.signal.aborted) {
|
|
82
|
+
// If already aborted, use it directly (WorkflowExecutor handles early abort)
|
|
83
|
+
// We can cancel timeout immediately
|
|
84
|
+
clearTimeout(timeoutId);
|
|
85
|
+
effectiveSignal = config.signal;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
// Listen to user signal to abort our controller
|
|
89
|
+
onAbort = () => {
|
|
90
|
+
controller.abort(config.signal?.reason);
|
|
91
|
+
};
|
|
92
|
+
config.signal.addEventListener("abort", onAbort);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
try {
|
|
96
|
+
return await executor.execute(steps, effectiveSignal);
|
|
97
|
+
}
|
|
98
|
+
finally {
|
|
99
|
+
clearTimeout(timeoutId);
|
|
100
|
+
if (config.signal && onAbort) {
|
|
101
|
+
config.signal.removeEventListener("abort", onAbort);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
return executor.execute(steps, config?.signal);
|
|
107
|
+
}
|
|
56
108
|
}
|
|
57
109
|
}
|
|
58
110
|
//# 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;AAG7D,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"TaskRunner.js","sourceRoot":"","sources":["../src/TaskRunner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { TaskRunner } from "./TaskRunner.js";
|
|
2
|
+
import { RunnerEventPayloads, RunnerEventListener } from "./contracts/RunnerEvents.js";
|
|
3
|
+
import { IExecutionStrategy } from "./strategies/IExecutionStrategy.js";
|
|
4
|
+
/**
|
|
5
|
+
* A builder for configuring and creating TaskRunner instances.
|
|
6
|
+
*/
|
|
7
|
+
export declare class TaskRunnerBuilder<TContext> {
|
|
8
|
+
private context;
|
|
9
|
+
private strategy?;
|
|
10
|
+
private listeners;
|
|
11
|
+
/**
|
|
12
|
+
* @param context The shared context object.
|
|
13
|
+
*/
|
|
14
|
+
constructor(context: TContext);
|
|
15
|
+
/**
|
|
16
|
+
* Sets the execution strategy.
|
|
17
|
+
* @param strategy The execution strategy to use.
|
|
18
|
+
* @returns The builder instance.
|
|
19
|
+
*/
|
|
20
|
+
useStrategy(strategy: IExecutionStrategy<TContext>): this;
|
|
21
|
+
/**
|
|
22
|
+
* Adds an event listener.
|
|
23
|
+
* @param event The event name.
|
|
24
|
+
* @param callback The callback to execute.
|
|
25
|
+
* @returns The builder instance.
|
|
26
|
+
*/
|
|
27
|
+
on<K extends keyof RunnerEventPayloads<TContext>>(event: K, callback: RunnerEventListener<TContext, K>): this;
|
|
28
|
+
/**
|
|
29
|
+
* Builds the TaskRunner instance.
|
|
30
|
+
* @returns A configured TaskRunner.
|
|
31
|
+
*/
|
|
32
|
+
build(): TaskRunner<TContext>;
|
|
33
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { TaskRunner } from "./TaskRunner.js";
|
|
2
|
+
/**
|
|
3
|
+
* A builder for configuring and creating TaskRunner instances.
|
|
4
|
+
*/
|
|
5
|
+
export class TaskRunnerBuilder {
|
|
6
|
+
context;
|
|
7
|
+
strategy;
|
|
8
|
+
listeners = {};
|
|
9
|
+
/**
|
|
10
|
+
* @param context The shared context object.
|
|
11
|
+
*/
|
|
12
|
+
constructor(context) {
|
|
13
|
+
this.context = context;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Sets the execution strategy.
|
|
17
|
+
* @param strategy The execution strategy to use.
|
|
18
|
+
* @returns The builder instance.
|
|
19
|
+
*/
|
|
20
|
+
useStrategy(strategy) {
|
|
21
|
+
this.strategy = strategy;
|
|
22
|
+
return this;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Adds an event listener.
|
|
26
|
+
* @param event The event name.
|
|
27
|
+
* @param callback The callback to execute.
|
|
28
|
+
* @returns The builder instance.
|
|
29
|
+
*/
|
|
30
|
+
on(event, callback) {
|
|
31
|
+
if (!this.listeners[event]) {
|
|
32
|
+
this.listeners[event] = [];
|
|
33
|
+
}
|
|
34
|
+
this.listeners[event].push(callback);
|
|
35
|
+
return this;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Builds the TaskRunner instance.
|
|
39
|
+
* @returns A configured TaskRunner.
|
|
40
|
+
*/
|
|
41
|
+
build() {
|
|
42
|
+
const runner = new TaskRunner(this.context);
|
|
43
|
+
if (this.strategy) {
|
|
44
|
+
runner.setExecutionStrategy(this.strategy);
|
|
45
|
+
}
|
|
46
|
+
Object.keys(this.listeners).forEach((event) => {
|
|
47
|
+
const callbacks = this.listeners[event];
|
|
48
|
+
// callbacks is always defined because we are iterating keys of the object
|
|
49
|
+
callbacks.forEach((callback) => runner.on(event, callback));
|
|
50
|
+
});
|
|
51
|
+
return runner;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=TaskRunnerBuilder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TaskRunnerBuilder.js","sourceRoot":"","sources":["../src/TaskRunnerBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAI7C;;GAEG;AACH,MAAM,OAAO,iBAAiB;IACpB,OAAO,CAAW;IAClB,QAAQ,CAAgC;IACxC,SAAS,GAEb,EAAE,CAAC;IAEP;;OAEG;IACH,YAAY,OAAiB;QAC3B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED;;;;OAIG;IACI,WAAW,CAAC,QAAsC;QACvD,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACI,EAAE,CACP,KAAQ,EACR,QAA0C;QAE1C,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QAC7B,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,KAAK,CAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACtC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;OAGG;IACI,KAAK;QACV,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAE5C,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC7C,CAAC;QAEA,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAgD,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YAC5F,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YACxC,0EAA0E;YAC1E,SAAU,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAC9B,MAAM,CAAC,EAAE,CACP,KAAK,EACL,QAGC,CACF,CACF,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration options for TaskRunner execution.
|
|
3
|
+
*/
|
|
4
|
+
export interface TaskRunnerExecutionConfig {
|
|
5
|
+
/**
|
|
6
|
+
* An AbortSignal to cancel the workflow externally.
|
|
7
|
+
*/
|
|
8
|
+
signal?: AbortSignal;
|
|
9
|
+
/**
|
|
10
|
+
* A timeout in milliseconds for the entire workflow.
|
|
11
|
+
*/
|
|
12
|
+
timeout?: number;
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TaskRunnerExecutionConfig.js","sourceRoot":"","sources":["../src/TaskRunnerExecutionConfig.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { TaskStep } from "./TaskStep.js";
|
|
2
|
+
import { TaskResult } from "./TaskResult.js";
|
|
3
|
+
import { EventBus } from "./EventBus.js";
|
|
4
|
+
/**
|
|
5
|
+
* Manages the state of the task execution, including results, pending steps, and running tasks.
|
|
6
|
+
* Handles dependency resolution and event emission for state changes.
|
|
7
|
+
*/
|
|
8
|
+
export declare class TaskStateManager<TContext> {
|
|
9
|
+
private eventBus;
|
|
10
|
+
private results;
|
|
11
|
+
private pendingSteps;
|
|
12
|
+
private running;
|
|
13
|
+
constructor(eventBus: EventBus<TContext>);
|
|
14
|
+
/**
|
|
15
|
+
* Initializes the state with the given steps.
|
|
16
|
+
* @param steps The steps to execute.
|
|
17
|
+
*/
|
|
18
|
+
initialize(steps: TaskStep<TContext>[]): void;
|
|
19
|
+
/**
|
|
20
|
+
* Processes the pending steps to identify tasks that can be started or must be skipped.
|
|
21
|
+
* Emits `taskSkipped` for skipped tasks.
|
|
22
|
+
* @returns An array of tasks that are ready to run.
|
|
23
|
+
*/
|
|
24
|
+
processDependencies(): TaskStep<TContext>[];
|
|
25
|
+
/**
|
|
26
|
+
* Marks a task as running and emits `taskStart`.
|
|
27
|
+
* @param step The task that is starting.
|
|
28
|
+
*/
|
|
29
|
+
markRunning(step: TaskStep<TContext>): void;
|
|
30
|
+
/**
|
|
31
|
+
* Marks a task as completed (success, failure, or cancelled during execution)
|
|
32
|
+
* and emits `taskEnd`.
|
|
33
|
+
* @param step The task that completed.
|
|
34
|
+
* @param result The result of the task.
|
|
35
|
+
*/
|
|
36
|
+
markCompleted(step: TaskStep<TContext>, result: TaskResult): void;
|
|
37
|
+
/**
|
|
38
|
+
* Cancels all pending tasks that haven't started yet.
|
|
39
|
+
* @param message The cancellation message.
|
|
40
|
+
*/
|
|
41
|
+
cancelAllPending(message: string): void;
|
|
42
|
+
/**
|
|
43
|
+
* Returns the current results map.
|
|
44
|
+
*/
|
|
45
|
+
getResults(): Map<string, TaskResult>;
|
|
46
|
+
/**
|
|
47
|
+
* Checks if there are any tasks currently running.
|
|
48
|
+
*/
|
|
49
|
+
hasRunningTasks(): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Checks if there are any pending tasks.
|
|
52
|
+
*/
|
|
53
|
+
hasPendingTasks(): boolean;
|
|
54
|
+
}
|