@calmo/task-runner 2.0.0 → 3.1.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/.jules/nexus.md +5 -0
- package/AGENTS.md +49 -0
- package/CHANGELOG.md +33 -0
- package/README.md +1 -1
- package/coverage/coverage-final.json +9 -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 +377 -20
- package/coverage/lcov-report/src/TaskRunnerBuilder.ts.html +313 -0
- package/coverage/lcov-report/src/TaskRunnerExecutionConfig.ts.html +139 -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 +56 -11
- package/coverage/lcov-report/src/strategies/DryRunExecutionStrategy.ts.html +178 -0
- package/coverage/lcov-report/src/strategies/StandardExecutionStrategy.ts.html +190 -0
- package/coverage/lcov-report/src/strategies/index.html +131 -0
- package/coverage/lcov.info +419 -204
- package/coverage/src/EventBus.ts.html +8 -8
- package/coverage/src/TaskGraphValidator.ts.html +53 -53
- package/coverage/src/TaskRunner.ts.html +377 -20
- package/coverage/src/TaskRunnerBuilder.ts.html +313 -0
- package/coverage/src/TaskRunnerExecutionConfig.ts.html +139 -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 +56 -11
- package/coverage/src/strategies/DryRunExecutionStrategy.ts.html +178 -0
- package/coverage/src/strategies/StandardExecutionStrategy.ts.html +190 -0
- package/coverage/src/strategies/index.html +131 -0
- package/dist/TaskRunner.d.ts +24 -2
- package/dist/TaskRunner.js +99 -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 +18 -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/DryRunExecutionStrategy.d.ts +16 -0
- package/dist/strategies/DryRunExecutionStrategy.js +25 -0
- package/dist/strategies/DryRunExecutionStrategy.js.map +1 -0
- 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 +16 -0
- package/openspec/changes/add-task-retry-policy/tasks.md +10 -0
- package/openspec/changes/add-workflow-preview/proposal.md +13 -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/openspec/changes/feat-per-task-timeout/proposal.md +25 -0
- package/openspec/changes/feat-per-task-timeout/tasks.md +27 -0
- package/package.json +1 -1
- package/src/TaskRunner.ts +123 -4
- package/src/TaskRunnerBuilder.ts +76 -0
- package/src/TaskRunnerExecutionConfig.ts +18 -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/DryRunExecutionStrategy.ts +31 -0
- package/src/strategies/IExecutionStrategy.ts +21 -0
- package/src/strategies/StandardExecutionStrategy.ts +35 -0
- package/test-report.xml +139 -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
|
@@ -25,28 +25,28 @@
|
|
|
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'>38/38</span>
|
|
29
29
|
</div>
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
<div class='fl pad1y space-right2'>
|
|
33
33
|
<span class="strong">100% </span>
|
|
34
34
|
<span class="quiet">Branches</span>
|
|
35
|
-
<span class='fraction'>
|
|
35
|
+
<span class='fraction'>12/12</span>
|
|
36
36
|
</div>
|
|
37
37
|
|
|
38
38
|
|
|
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'>6/6</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'>38/38</span>
|
|
50
50
|
</div>
|
|
51
51
|
|
|
52
52
|
|
|
@@ -183,13 +183,7 @@
|
|
|
183
183
|
<a name='L118'></a><a href='#L118'>118</a>
|
|
184
184
|
<a name='L119'></a><a href='#L119'>119</a>
|
|
185
185
|
<a name='L120'></a><a href='#L120'>120</a>
|
|
186
|
-
<a name='L121'></a><a href='#L121'>121</a>
|
|
187
|
-
<a name='L122'></a><a href='#L122'>122</a>
|
|
188
|
-
<a name='L123'></a><a href='#L123'>123</a>
|
|
189
|
-
<a name='L124'></a><a href='#L124'>124</a>
|
|
190
|
-
<a name='L125'></a><a href='#L125'>125</a>
|
|
191
|
-
<a name='L126'></a><a href='#L126'>126</a>
|
|
192
|
-
<a name='L127'></a><a href='#L127'>127</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span>
|
|
186
|
+
<a name='L121'></a><a href='#L121'>121</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span>
|
|
193
187
|
<span class="cline-any cline-neutral"> </span>
|
|
194
188
|
<span class="cline-any cline-neutral"> </span>
|
|
195
189
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -198,246 +192,234 @@
|
|
|
198
192
|
<span class="cline-any cline-neutral"> </span>
|
|
199
193
|
<span class="cline-any cline-neutral"> </span>
|
|
200
194
|
<span class="cline-any cline-neutral"> </span>
|
|
201
|
-
<span class="cline-any cline-yes">18x</span>
|
|
202
195
|
<span class="cline-any cline-neutral"> </span>
|
|
203
196
|
<span class="cline-any cline-neutral"> </span>
|
|
204
197
|
<span class="cline-any cline-neutral"> </span>
|
|
205
198
|
<span class="cline-any cline-neutral"> </span>
|
|
206
199
|
<span class="cline-any cline-neutral"> </span>
|
|
207
200
|
<span class="cline-any cline-neutral"> </span>
|
|
208
|
-
<span class="cline-any cline-yes">18x</span>
|
|
209
|
-
<span class="cline-any cline-yes">18x</span>
|
|
210
201
|
<span class="cline-any cline-neutral"> </span>
|
|
211
202
|
<span class="cline-any cline-neutral"> </span>
|
|
212
203
|
<span class="cline-any cline-neutral"> </span>
|
|
204
|
+
<span class="cline-any cline-yes">43x</span>
|
|
205
|
+
<span class="cline-any cline-yes">43x</span>
|
|
206
|
+
<span class="cline-any cline-yes">43x</span>
|
|
207
|
+
<span class="cline-any cline-yes">43x</span>
|
|
213
208
|
<span class="cline-any cline-neutral"> </span>
|
|
214
209
|
<span class="cline-any cline-neutral"> </span>
|
|
215
210
|
<span class="cline-any cline-neutral"> </span>
|
|
216
211
|
<span class="cline-any cline-neutral"> </span>
|
|
217
212
|
<span class="cline-any cline-neutral"> </span>
|
|
218
|
-
<span class="cline-any cline-yes">18x</span>
|
|
219
213
|
<span class="cline-any cline-neutral"> </span>
|
|
220
|
-
<span class="cline-any cline-yes">18x</span>
|
|
221
|
-
<span class="cline-any cline-yes">18x</span>
|
|
222
214
|
<span class="cline-any cline-neutral"> </span>
|
|
223
215
|
<span class="cline-any cline-neutral"> </span>
|
|
224
|
-
<span class="cline-any cline-yes">18x</span>
|
|
225
216
|
<span class="cline-any cline-neutral"> </span>
|
|
226
|
-
<span class="cline-any cline-yes">18x</span>
|
|
227
217
|
<span class="cline-any cline-neutral"> </span>
|
|
228
|
-
<span class="cline-any cline-yes">25x</span>
|
|
229
218
|
<span class="cline-any cline-neutral"> </span>
|
|
230
|
-
<span class="cline-any cline-yes">25x</span>
|
|
231
219
|
<span class="cline-any cline-neutral"> </span>
|
|
220
|
+
<span class="cline-any cline-yes">43x</span>
|
|
221
|
+
<span class="cline-any cline-yes">43x</span>
|
|
232
222
|
<span class="cline-any cline-neutral"> </span>
|
|
233
|
-
<span class="cline-any cline-yes">18x</span>
|
|
234
|
-
<span class="cline-any cline-yes">18x</span>
|
|
235
223
|
<span class="cline-any cline-neutral"> </span>
|
|
224
|
+
<span class="cline-any cline-yes">43x</span>
|
|
225
|
+
<span class="cline-any cline-yes">2x</span>
|
|
226
|
+
<span class="cline-any cline-yes">2x</span>
|
|
227
|
+
<span class="cline-any cline-yes">2x</span>
|
|
228
|
+
<span class="cline-any cline-yes">2x</span>
|
|
236
229
|
<span class="cline-any cline-neutral"> </span>
|
|
237
230
|
<span class="cline-any cline-neutral"> </span>
|
|
231
|
+
<span class="cline-any cline-yes">41x</span>
|
|
238
232
|
<span class="cline-any cline-neutral"> </span>
|
|
233
|
+
<span class="cline-any cline-yes">41x</span>
|
|
239
234
|
<span class="cline-any cline-neutral"> </span>
|
|
235
|
+
<span class="cline-any cline-yes">9x</span>
|
|
240
236
|
<span class="cline-any cline-neutral"> </span>
|
|
241
237
|
<span class="cline-any cline-neutral"> </span>
|
|
238
|
+
<span class="cline-any cline-yes">41x</span>
|
|
239
|
+
<span class="cline-any cline-yes">9x</span>
|
|
242
240
|
<span class="cline-any cline-neutral"> </span>
|
|
243
241
|
<span class="cline-any cline-neutral"> </span>
|
|
242
|
+
<span class="cline-any cline-yes">41x</span>
|
|
244
243
|
<span class="cline-any cline-neutral"> </span>
|
|
245
|
-
<span class="cline-any cline-yes">
|
|
244
|
+
<span class="cline-any cline-yes">41x</span>
|
|
246
245
|
<span class="cline-any cline-neutral"> </span>
|
|
247
|
-
<span class="cline-any cline-yes">
|
|
248
|
-
<span class="cline-any cline-neutral"> </span>
|
|
249
|
-
<span class="cline-any cline-yes">43x</span>
|
|
250
|
-
<span class="cline-any cline-yes">31x</span>
|
|
251
|
-
<span class="cline-any cline-yes">31x</span>
|
|
252
|
-
<span class="cline-any cline-neutral"> </span>
|
|
253
|
-
<span class="cline-any cline-yes">31x</span>
|
|
246
|
+
<span class="cline-any cline-yes">41x</span>
|
|
254
247
|
<span class="cline-any cline-neutral"> </span>
|
|
255
248
|
<span class="cline-any cline-neutral"> </span>
|
|
256
249
|
<span class="cline-any cline-neutral"> </span>
|
|
257
250
|
<span class="cline-any cline-neutral"> </span>
|
|
258
251
|
<span class="cline-any cline-neutral"> </span>
|
|
259
252
|
<span class="cline-any cline-neutral"> </span>
|
|
253
|
+
<span class="cline-any cline-yes">79x</span>
|
|
254
|
+
<span class="cline-any cline-yes">1x</span>
|
|
260
255
|
<span class="cline-any cline-neutral"> </span>
|
|
261
|
-
<span class="cline-any cline-yes">43x</span>
|
|
262
|
-
<span class="cline-any cline-yes">114x</span>
|
|
263
256
|
<span class="cline-any cline-neutral"> </span>
|
|
257
|
+
<span class="cline-any cline-yes">78x</span>
|
|
264
258
|
<span class="cline-any cline-neutral"> </span>
|
|
265
|
-
<span class="cline-any cline-yes">43x</span>
|
|
266
|
-
<span class="cline-any cline-yes">57x</span>
|
|
267
|
-
<span class="cline-any cline-yes">57x</span>
|
|
268
|
-
<span class="cline-any cline-yes">43x</span>
|
|
269
259
|
<span class="cline-any cline-neutral"> </span>
|
|
260
|
+
<span class="cline-any cline-yes">78x</span>
|
|
261
|
+
<span class="cline-any cline-yes">9x</span>
|
|
270
262
|
<span class="cline-any cline-neutral"> </span>
|
|
271
|
-
<span class="cline-any cline-yes">57x</span>
|
|
272
|
-
<span class="cline-any cline-yes">7x</span>
|
|
273
263
|
<span class="cline-any cline-neutral"> </span>
|
|
264
|
+
<span class="cline-any cline-yes">69x</span>
|
|
274
265
|
<span class="cline-any cline-neutral"> </span>
|
|
275
266
|
<span class="cline-any cline-neutral"> </span>
|
|
276
|
-
<span class="cline-any cline-yes">7x</span>
|
|
277
|
-
<span class="cline-any cline-yes">7x</span>
|
|
278
267
|
<span class="cline-any cline-neutral"> </span>
|
|
279
268
|
<span class="cline-any cline-neutral"> </span>
|
|
269
|
+
<span class="cline-any cline-yes">41x</span>
|
|
280
270
|
<span class="cline-any cline-neutral"> </span>
|
|
271
|
+
<span class="cline-any cline-yes">41x</span>
|
|
272
|
+
<span class="cline-any cline-yes">41x</span>
|
|
273
|
+
<span class="cline-any cline-yes">41x</span>
|
|
281
274
|
<span class="cline-any cline-neutral"> </span>
|
|
275
|
+
<span class="cline-any cline-yes">41x</span>
|
|
276
|
+
<span class="cline-any cline-yes">9x</span>
|
|
282
277
|
<span class="cline-any cline-neutral"> </span>
|
|
283
278
|
<span class="cline-any cline-neutral"> </span>
|
|
284
279
|
<span class="cline-any cline-neutral"> </span>
|
|
285
280
|
<span class="cline-any cline-neutral"> </span>
|
|
286
|
-
<span class="cline-any cline-yes">43x</span>
|
|
287
|
-
<span class="cline-any cline-yes">114x</span>
|
|
288
281
|
<span class="cline-any cline-neutral"> </span>
|
|
289
|
-
<span class="cline-any cline-yes">50x</span>
|
|
290
|
-
<span class="cline-any cline-yes">114x</span>
|
|
291
|
-
<span class="cline-any cline-yes">32x</span>
|
|
292
282
|
<span class="cline-any cline-neutral"> </span>
|
|
293
283
|
<span class="cline-any cline-neutral"> </span>
|
|
294
284
|
<span class="cline-any cline-neutral"> </span>
|
|
295
285
|
<span class="cline-any cline-neutral"> </span>
|
|
296
286
|
<span class="cline-any cline-neutral"> </span>
|
|
297
287
|
<span class="cline-any cline-neutral"> </span>
|
|
288
|
+
<span class="cline-any cline-yes">110x</span>
|
|
298
289
|
<span class="cline-any cline-neutral"> </span>
|
|
299
290
|
<span class="cline-any cline-neutral"> </span>
|
|
300
|
-
<span class="cline-any cline-yes">
|
|
301
|
-
<span class="cline-any cline-yes">
|
|
291
|
+
<span class="cline-any cline-yes">110x</span>
|
|
292
|
+
<span class="cline-any cline-yes">105x</span>
|
|
302
293
|
<span class="cline-any cline-neutral"> </span>
|
|
303
|
-
<span class="cline-any cline-yes">
|
|
304
|
-
<span class="cline-any cline-yes">31x</span>
|
|
305
|
-
<span class="cline-any cline-yes">29x</span>
|
|
294
|
+
<span class="cline-any cline-yes">105x</span>
|
|
306
295
|
<span class="cline-any cline-neutral"> </span>
|
|
307
|
-
<span class="cline-any cline-yes">
|
|
296
|
+
<span class="cline-any cline-yes">105x</span>
|
|
308
297
|
<span class="cline-any cline-neutral"> </span>
|
|
309
298
|
<span class="cline-any cline-neutral"> </span>
|
|
299
|
+
<span class="cline-any cline-yes">105x</span>
|
|
310
300
|
<span class="cline-any cline-neutral"> </span>
|
|
311
301
|
<span class="cline-any cline-neutral"> </span>
|
|
312
|
-
<span class="cline-any cline-yes">
|
|
313
|
-
<span class="cline-any cline-yes">31x</span>
|
|
314
|
-
<span class="cline-any cline-yes">31x</span>
|
|
302
|
+
<span class="cline-any cline-yes">105x</span>
|
|
315
303
|
<span class="cline-any cline-neutral"> </span>
|
|
316
304
|
<span class="cline-any cline-neutral"> </span>
|
|
317
305
|
<span class="cline-any cline-neutral"> </span>
|
|
318
306
|
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">import { TaskStep } from "./TaskStep.js";
|
|
319
307
|
import { TaskResult } from "./TaskResult.js";
|
|
320
308
|
import { EventBus } from "./EventBus.js";
|
|
309
|
+
import { TaskStateManager } from "./TaskStateManager.js";
|
|
310
|
+
import { IExecutionStrategy } from "./strategies/IExecutionStrategy.js";
|
|
321
311
|
|
|
322
312
|
/**
|
|
323
313
|
* Handles the execution of the workflow steps.
|
|
324
314
|
* @template TContext The shape of the shared context object.
|
|
325
315
|
*/
|
|
326
316
|
export class WorkflowExecutor<TContext> {
|
|
327
|
-
private running = new Set<string>();
|
|
328
|
-
|
|
329
317
|
/**
|
|
330
318
|
* @param context The shared context object.
|
|
331
319
|
* @param eventBus The event bus to emit events.
|
|
320
|
+
* @param stateManager Manages execution state.
|
|
321
|
+
* @param strategy Execution strategy.
|
|
332
322
|
*/
|
|
333
323
|
constructor(
|
|
334
324
|
private context: TContext,
|
|
335
|
-
private eventBus: EventBus<TContext>
|
|
325
|
+
private eventBus: EventBus<TContext>,
|
|
326
|
+
private stateManager: TaskStateManager<TContext>,
|
|
327
|
+
private strategy: IExecutionStrategy<TContext>
|
|
336
328
|
) {}
|
|
337
329
|
|
|
338
330
|
/**
|
|
339
331
|
* Executes the given steps.
|
|
340
332
|
* @param steps The list of steps to execute.
|
|
333
|
+
* @param signal Optional AbortSignal for cancellation.
|
|
341
334
|
* @returns A Promise that resolves to a map of task results.
|
|
342
335
|
*/
|
|
343
|
-
async execute(
|
|
336
|
+
async execute(
|
|
337
|
+
steps: TaskStep<TContext>[],
|
|
338
|
+
signal?: AbortSignal
|
|
339
|
+
): Promise<Map<string, TaskResult>> {
|
|
344
340
|
this.eventBus.emit("workflowStart", { context: this.context, steps });
|
|
341
|
+
this.stateManager.initialize(steps);
|
|
342
|
+
|
|
343
|
+
// Check if already aborted
|
|
344
|
+
if (signal?.aborted) {
|
|
345
|
+
this.stateManager.cancelAllPending("Workflow cancelled before execution started.");
|
|
346
|
+
const results = this.stateManager.getResults();
|
|
347
|
+
this.eventBus.emit("workflowEnd", { context: this.context, results });
|
|
348
|
+
return results;
|
|
349
|
+
}
|
|
345
350
|
|
|
346
|
-
const results = new Map<string, TaskResult>();
|
|
347
351
|
const executingPromises = new Set<Promise<void>>();
|
|
348
352
|
|
|
349
|
-
|
|
350
|
-
|
|
353
|
+
const onAbort = () => {
|
|
354
|
+
// Mark all pending tasks as cancelled
|
|
355
|
+
this.stateManager.cancelAllPending("Workflow cancelled.");
|
|
356
|
+
};
|
|
351
357
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
await Promise.race(executingPromises);
|
|
355
|
-
// After a task finishes, check for new work
|
|
356
|
-
this.processQueue(steps, results, executingPromises);
|
|
358
|
+
if (signal) {
|
|
359
|
+
signal.addEventListener("abort", onAbort);
|
|
357
360
|
}
|
|
358
361
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
/**
|
|
364
|
-
* Logic to identify tasks that can be started or must be skipped.
|
|
365
|
-
*/
|
|
366
|
-
private processQueue(
|
|
367
|
-
steps: TaskStep<TContext>[],
|
|
368
|
-
results: Map<string, TaskResult>,
|
|
369
|
-
executingPromises: Set<Promise<void>>
|
|
370
|
-
): void {
|
|
371
|
-
this.handleSkippedTasks(steps, results);
|
|
372
|
-
|
|
373
|
-
const readySteps = this.getReadySteps(steps, results);
|
|
362
|
+
try {
|
|
363
|
+
// Initial pass
|
|
364
|
+
this.processLoop(executingPromises, signal);
|
|
374
365
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
366
|
+
while (
|
|
367
|
+
this.stateManager.hasPendingTasks() ||
|
|
368
|
+
this.stateManager.hasRunningTasks()
|
|
369
|
+
) {
|
|
370
|
+
// Safety check: if no tasks are running and we still have pending tasks,
|
|
371
|
+
// it means we are stuck (e.g. cycle or unhandled dependency).
|
|
372
|
+
// Since valid graphs shouldn't have this, we break to avoid infinite loop.
|
|
373
|
+
if (executingPromises.size === 0) {
|
|
374
|
+
break;
|
|
375
|
+
} else {
|
|
376
|
+
// Wait for the next task to finish
|
|
377
|
+
await Promise.race(executingPromises);
|
|
378
|
+
}
|
|
382
379
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
380
|
+
if (signal?.aborted) {
|
|
381
|
+
this.stateManager.cancelAllPending("Workflow cancelled.");
|
|
382
|
+
} else {
|
|
383
|
+
// After a task finishes, check for new work
|
|
384
|
+
this.processLoop(executingPromises, signal);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
390
387
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
const failedDep = deps.find(
|
|
394
|
-
(dep) => results.has(dep) && results.get(dep)?.status !== "success"
|
|
395
|
-
);
|
|
388
|
+
// Ensure everything is accounted for (e.g. if loop exited early)
|
|
389
|
+
this.stateManager.cancelAllPending("Workflow cancelled.");
|
|
396
390
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
this.eventBus.emit("taskSkipped", { step, result });
|
|
391
|
+
const results = this.stateManager.getResults();
|
|
392
|
+
this.eventBus.emit("workflowEnd", { context: this.context, results });
|
|
393
|
+
return results;
|
|
394
|
+
} finally {
|
|
395
|
+
if (signal) {
|
|
396
|
+
signal.removeEventListener("abort", onAbort);
|
|
404
397
|
}
|
|
405
398
|
}
|
|
406
399
|
}
|
|
407
400
|
|
|
408
401
|
/**
|
|
409
|
-
*
|
|
402
|
+
* Logic to identify tasks that can be started and run them.
|
|
410
403
|
*/
|
|
411
|
-
private
|
|
412
|
-
|
|
413
|
-
|
|
404
|
+
private processLoop(
|
|
405
|
+
executingPromises: Set<Promise<void>>,
|
|
406
|
+
signal?: AbortSignal
|
|
407
|
+
): void {
|
|
408
|
+
const toRun = this.stateManager.processDependencies();
|
|
414
409
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
);
|
|
419
|
-
});
|
|
420
|
-
}
|
|
410
|
+
// Execute ready tasks
|
|
411
|
+
for (const step of toRun) {
|
|
412
|
+
this.stateManager.markRunning(step);
|
|
421
413
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
414
|
+
const taskPromise = this.strategy.execute(step, this.context, signal)
|
|
415
|
+
.then((result) => {
|
|
416
|
+
this.stateManager.markCompleted(step, result);
|
|
417
|
+
})
|
|
418
|
+
.finally(() => {
|
|
419
|
+
executingPromises.delete(taskPromise);
|
|
420
|
+
});
|
|
428
421
|
|
|
429
|
-
|
|
430
|
-
const result = await step.run(this.context);
|
|
431
|
-
results.set(step.name, result);
|
|
432
|
-
} catch (e) {
|
|
433
|
-
results.set(step.name, {
|
|
434
|
-
status: "failure",
|
|
435
|
-
error: e instanceof Error ? e.message : String(e),
|
|
436
|
-
});
|
|
437
|
-
} finally {
|
|
438
|
-
this.running.delete(step.name);
|
|
439
|
-
const result = results.get(step.name)!;
|
|
440
|
-
this.eventBus.emit("taskEnd", { step, result });
|
|
422
|
+
executingPromises.add(taskPromise);
|
|
441
423
|
}
|
|
442
424
|
}
|
|
443
425
|
}
|
|
@@ -448,7 +430,7 @@ export class WorkflowExecutor<TContext> {
|
|
|
448
430
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
449
431
|
Code coverage generated by
|
|
450
432
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
451
|
-
at 2026-01-
|
|
433
|
+
at 2026-01-18T18:12:39.258Z
|
|
452
434
|
</div>
|
|
453
435
|
<script src="../prettify.js"></script>
|
|
454
436
|
<script>
|
|
@@ -202,7 +202,7 @@ export type ListenerMap<TContext> = {
|
|
|
202
202
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
203
203
|
Code coverage generated by
|
|
204
204
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
205
|
-
at 2026-01-
|
|
205
|
+
at 2026-01-18T18:12:39.258Z
|
|
206
206
|
</div>
|
|
207
207
|
<script src="../../prettify.js"></script>
|
|
208
208
|
<script>
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
102
102
|
Code coverage generated by
|
|
103
103
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
104
|
-
at 2026-01-
|
|
104
|
+
at 2026-01-18T18:12:39.258Z
|
|
105
105
|
</div>
|
|
106
106
|
<script src="../../prettify.js"></script>
|
|
107
107
|
<script>
|
|
@@ -25,28 +25,28 @@
|
|
|
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'>219/219</span>
|
|
29
29
|
</div>
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
<div class='fl pad1y space-right2'>
|
|
33
33
|
<span class="strong">100% </span>
|
|
34
34
|
<span class="quiet">Branches</span>
|
|
35
|
-
<span class='fraction'>
|
|
35
|
+
<span class='fraction'>74/74</span>
|
|
36
36
|
</div>
|
|
37
37
|
|
|
38
38
|
|
|
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'>42/42</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'>215/215</span>
|
|
50
50
|
</div>
|
|
51
51
|
|
|
52
52
|
|
|
@@ -114,13 +114,58 @@
|
|
|
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="49" class="abs high">49/49</td>
|
|
118
|
+
<td data-value="100" class="pct high">100%</td>
|
|
119
|
+
<td data-value="18" class="abs high">18/18</td>
|
|
120
|
+
<td data-value="100" class="pct high">100%</td>
|
|
117
121
|
<td data-value="12" class="abs high">12/12</td>
|
|
118
122
|
<td data-value="100" class="pct high">100%</td>
|
|
123
|
+
<td data-value="47" class="abs high">47/47</td>
|
|
124
|
+
</tr>
|
|
125
|
+
|
|
126
|
+
<tr>
|
|
127
|
+
<td class="file high" data-value="TaskRunnerBuilder.ts"><a href="TaskRunnerBuilder.ts.html">TaskRunnerBuilder.ts</a></td>
|
|
128
|
+
<td data-value="100" class="pic high">
|
|
129
|
+
<div class="chart"><div class="cover-fill cover-full" style="width: 100%"></div><div class="cover-empty" style="width: 0%"></div></div>
|
|
130
|
+
</td>
|
|
131
|
+
<td data-value="100" class="pct high">100%</td>
|
|
132
|
+
<td data-value="16" class="abs high">16/16</td>
|
|
133
|
+
<td data-value="100" class="pct high">100%</td>
|
|
119
134
|
<td data-value="4" class="abs high">4/4</td>
|
|
120
135
|
<td data-value="100" class="pct high">100%</td>
|
|
121
|
-
<td data-value="
|
|
136
|
+
<td data-value="6" class="abs high">6/6</td>
|
|
122
137
|
<td data-value="100" class="pct high">100%</td>
|
|
123
|
-
<td data-value="
|
|
138
|
+
<td data-value="16" class="abs high">16/16</td>
|
|
139
|
+
</tr>
|
|
140
|
+
|
|
141
|
+
<tr>
|
|
142
|
+
<td class="file empty" data-value="TaskRunnerExecutionConfig.ts"><a href="TaskRunnerExecutionConfig.ts.html">TaskRunnerExecutionConfig.ts</a></td>
|
|
143
|
+
<td data-value="0" class="pic empty">
|
|
144
|
+
<div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div>
|
|
145
|
+
</td>
|
|
146
|
+
<td data-value="0" class="pct empty">0%</td>
|
|
147
|
+
<td data-value="0" class="abs empty">0/0</td>
|
|
148
|
+
<td data-value="0" class="pct empty">0%</td>
|
|
149
|
+
<td data-value="0" class="abs empty">0/0</td>
|
|
150
|
+
<td data-value="0" class="pct empty">0%</td>
|
|
151
|
+
<td data-value="0" class="abs empty">0/0</td>
|
|
152
|
+
<td data-value="0" class="pct empty">0%</td>
|
|
153
|
+
<td data-value="0" class="abs empty">0/0</td>
|
|
154
|
+
</tr>
|
|
155
|
+
|
|
156
|
+
<tr>
|
|
157
|
+
<td class="file high" data-value="TaskStateManager.ts"><a href="TaskStateManager.ts.html">TaskStateManager.ts</a></td>
|
|
158
|
+
<td data-value="100" class="pic high">
|
|
159
|
+
<div class="chart"><div class="cover-fill cover-full" style="width: 100%"></div><div class="cover-empty" style="width: 0%"></div></div>
|
|
160
|
+
</td>
|
|
161
|
+
<td data-value="100" class="pct high">100%</td>
|
|
162
|
+
<td data-value="45" class="abs high">45/45</td>
|
|
163
|
+
<td data-value="100" class="pct high">100%</td>
|
|
164
|
+
<td data-value="16" class="abs high">16/16</td>
|
|
165
|
+
<td data-value="100" class="pct high">100%</td>
|
|
166
|
+
<td data-value="9" class="abs high">9/9</td>
|
|
167
|
+
<td data-value="100" class="pct high">100%</td>
|
|
168
|
+
<td data-value="45" class="abs high">45/45</td>
|
|
124
169
|
</tr>
|
|
125
170
|
|
|
126
171
|
<tr>
|
|
@@ -129,13 +174,13 @@
|
|
|
129
174
|
<div class="chart"><div class="cover-fill cover-full" style="width: 100%"></div><div class="cover-empty" style="width: 0%"></div></div>
|
|
130
175
|
</td>
|
|
131
176
|
<td data-value="100" class="pct high">100%</td>
|
|
132
|
-
<td data-value="
|
|
177
|
+
<td data-value="38" class="abs high">38/38</td>
|
|
133
178
|
<td data-value="100" class="pct high">100%</td>
|
|
134
|
-
<td data-value="
|
|
179
|
+
<td data-value="12" class="abs high">12/12</td>
|
|
135
180
|
<td data-value="100" class="pct high">100%</td>
|
|
136
|
-
<td data-value="
|
|
181
|
+
<td data-value="6" class="abs high">6/6</td>
|
|
137
182
|
<td data-value="100" class="pct high">100%</td>
|
|
138
|
-
<td data-value="
|
|
183
|
+
<td data-value="38" class="abs high">38/38</td>
|
|
139
184
|
</tr>
|
|
140
185
|
|
|
141
186
|
</tbody>
|
|
@@ -146,7 +191,7 @@
|
|
|
146
191
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
147
192
|
Code coverage generated by
|
|
148
193
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
149
|
-
at 2026-01-
|
|
194
|
+
at 2026-01-18T18:12:39.258Z
|
|
150
195
|
</div>
|
|
151
196
|
<script src="../prettify.js"></script>
|
|
152
197
|
<script>
|