@calmo/task-runner 1.2.3 → 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/.jules/sentinel.md +4 -0
- package/AGENTS.md +53 -1
- package/CHANGELOG.md +41 -15
- 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 +143 -62
- 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 +125 -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 +59 -14
- 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 +383 -184
- package/coverage/src/EventBus.ts.html +8 -8
- package/coverage/src/TaskGraphValidator.ts.html +143 -62
- 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 +125 -137
- package/coverage/src/contracts/RunnerEvents.ts.html +1 -1
- package/coverage/src/contracts/index.html +1 -1
- package/coverage/src/index.html +59 -14
- package/coverage/src/strategies/StandardExecutionStrategy.ts.html +190 -0
- package/coverage/src/strategies/index.html +116 -0
- package/dist/TaskGraphValidator.js +39 -16
- package/dist/TaskGraphValidator.js.map +1 -1
- 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 -10
- package/dist/WorkflowExecutor.js +64 -73
- 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/TaskGraphValidator.ts +46 -19
- 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 +75 -79
- package/src/index.ts +4 -0
- package/src/strategies/IExecutionStrategy.ts +21 -0
- package/src/strategies/StandardExecutionStrategy.ts +35 -0
- package/test-report.xml +121 -43
- package/GEMINI.md +0 -46
- 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,11 +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></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>
|
|
191
187
|
<span class="cline-any cline-neutral"> </span>
|
|
192
188
|
<span class="cline-any cline-neutral"> </span>
|
|
193
189
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -196,96 +192,88 @@
|
|
|
196
192
|
<span class="cline-any cline-neutral"> </span>
|
|
197
193
|
<span class="cline-any cline-neutral"> </span>
|
|
198
194
|
<span class="cline-any cline-neutral"> </span>
|
|
199
|
-
<span class="cline-any cline-yes">18x</span>
|
|
200
195
|
<span class="cline-any cline-neutral"> </span>
|
|
201
196
|
<span class="cline-any cline-neutral"> </span>
|
|
202
197
|
<span class="cline-any cline-neutral"> </span>
|
|
203
198
|
<span class="cline-any cline-neutral"> </span>
|
|
204
199
|
<span class="cline-any cline-neutral"> </span>
|
|
205
200
|
<span class="cline-any cline-neutral"> </span>
|
|
206
|
-
<span class="cline-any cline-yes">18x</span>
|
|
207
|
-
<span class="cline-any cline-yes">18x</span>
|
|
208
201
|
<span class="cline-any cline-neutral"> </span>
|
|
209
202
|
<span class="cline-any cline-neutral"> </span>
|
|
210
203
|
<span class="cline-any cline-neutral"> </span>
|
|
204
|
+
<span class="cline-any cline-yes">41x</span>
|
|
205
|
+
<span class="cline-any cline-yes">41x</span>
|
|
206
|
+
<span class="cline-any cline-yes">41x</span>
|
|
207
|
+
<span class="cline-any cline-yes">41x</span>
|
|
211
208
|
<span class="cline-any cline-neutral"> </span>
|
|
212
209
|
<span class="cline-any cline-neutral"> </span>
|
|
213
210
|
<span class="cline-any cline-neutral"> </span>
|
|
214
211
|
<span class="cline-any cline-neutral"> </span>
|
|
215
212
|
<span class="cline-any cline-neutral"> </span>
|
|
216
|
-
<span class="cline-any cline-yes">18x</span>
|
|
217
213
|
<span class="cline-any cline-neutral"> </span>
|
|
218
|
-
<span class="cline-any cline-yes">18x</span>
|
|
219
|
-
<span class="cline-any cline-yes">18x</span>
|
|
220
|
-
<span class="cline-any cline-yes">18x</span>
|
|
221
214
|
<span class="cline-any cline-neutral"> </span>
|
|
222
215
|
<span class="cline-any cline-neutral"> </span>
|
|
223
|
-
<span class="cline-any cline-yes">18x</span>
|
|
224
216
|
<span class="cline-any cline-neutral"> </span>
|
|
225
|
-
<span class="cline-any cline-yes">18x</span>
|
|
226
217
|
<span class="cline-any cline-neutral"> </span>
|
|
227
|
-
<span class="cline-any cline-yes">25x</span>
|
|
228
218
|
<span class="cline-any cline-neutral"> </span>
|
|
229
|
-
<span class="cline-any cline-yes">25x</span>
|
|
230
219
|
<span class="cline-any cline-neutral"> </span>
|
|
220
|
+
<span class="cline-any cline-yes">41x</span>
|
|
221
|
+
<span class="cline-any cline-yes">41x</span>
|
|
231
222
|
<span class="cline-any cline-neutral"> </span>
|
|
232
|
-
<span class="cline-any cline-yes">18x</span>
|
|
233
|
-
<span class="cline-any cline-yes">18x</span>
|
|
234
223
|
<span class="cline-any cline-neutral"> </span>
|
|
224
|
+
<span class="cline-any cline-yes">41x</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>
|
|
235
229
|
<span class="cline-any cline-neutral"> </span>
|
|
236
230
|
<span class="cline-any cline-neutral"> </span>
|
|
231
|
+
<span class="cline-any cline-yes">39x</span>
|
|
237
232
|
<span class="cline-any cline-neutral"> </span>
|
|
233
|
+
<span class="cline-any cline-yes">39x</span>
|
|
238
234
|
<span class="cline-any cline-neutral"> </span>
|
|
235
|
+
<span class="cline-any cline-yes">9x</span>
|
|
239
236
|
<span class="cline-any cline-neutral"> </span>
|
|
240
237
|
<span class="cline-any cline-neutral"> </span>
|
|
238
|
+
<span class="cline-any cline-yes">39x</span>
|
|
239
|
+
<span class="cline-any cline-yes">9x</span>
|
|
241
240
|
<span class="cline-any cline-neutral"> </span>
|
|
242
241
|
<span class="cline-any cline-neutral"> </span>
|
|
242
|
+
<span class="cline-any cline-yes">39x</span>
|
|
243
243
|
<span class="cline-any cline-neutral"> </span>
|
|
244
|
+
<span class="cline-any cline-yes">39x</span>
|
|
244
245
|
<span class="cline-any cline-neutral"> </span>
|
|
245
|
-
<span class="cline-any cline-yes">
|
|
246
|
-
<span class="cline-any cline-yes">43x</span>
|
|
246
|
+
<span class="cline-any cline-yes">39x</span>
|
|
247
247
|
<span class="cline-any cline-neutral"> </span>
|
|
248
|
-
<span class="cline-any cline-yes">43x</span>
|
|
249
|
-
<span class="cline-any cline-yes">57x</span>
|
|
250
|
-
<span class="cline-any cline-yes">57x</span>
|
|
251
248
|
<span class="cline-any cline-neutral"> </span>
|
|
252
249
|
<span class="cline-any cline-neutral"> </span>
|
|
253
|
-
<span class="cline-any cline-yes">57x</span>
|
|
254
|
-
<span class="cline-any cline-yes">43x</span>
|
|
255
|
-
<span class="cline-any cline-yes">43x</span>
|
|
256
250
|
<span class="cline-any cline-neutral"> </span>
|
|
257
|
-
<span class="cline-any cline-yes">23x</span>
|
|
258
|
-
<span class="cline-any cline-yes">20x</span>
|
|
259
|
-
<span class="cline-any cline-yes">7x</span>
|
|
260
|
-
<span class="cline-any cline-yes">7x</span>
|
|
261
251
|
<span class="cline-any cline-neutral"> </span>
|
|
262
252
|
<span class="cline-any cline-neutral"> </span>
|
|
253
|
+
<span class="cline-any cline-yes">75x</span>
|
|
254
|
+
<span class="cline-any cline-yes">1x</span>
|
|
263
255
|
<span class="cline-any cline-neutral"> </span>
|
|
264
|
-
<span class="cline-any cline-yes">57x</span>
|
|
265
|
-
<span class="cline-any cline-yes">7x</span>
|
|
266
256
|
<span class="cline-any cline-neutral"> </span>
|
|
257
|
+
<span class="cline-any cline-yes">74x</span>
|
|
267
258
|
<span class="cline-any cline-neutral"> </span>
|
|
268
259
|
<span class="cline-any cline-neutral"> </span>
|
|
269
|
-
<span class="cline-any cline-yes">
|
|
270
|
-
<span class="cline-any cline-yes">
|
|
271
|
-
<span class="cline-any cline-yes">7x</span>
|
|
272
|
-
<span class="cline-any cline-yes">50x</span>
|
|
273
|
-
<span class="cline-any cline-yes">31x</span>
|
|
274
|
-
<span class="cline-any cline-yes">31x</span>
|
|
260
|
+
<span class="cline-any cline-yes">74x</span>
|
|
261
|
+
<span class="cline-any cline-yes">9x</span>
|
|
275
262
|
<span class="cline-any cline-neutral"> </span>
|
|
276
263
|
<span class="cline-any cline-neutral"> </span>
|
|
264
|
+
<span class="cline-any cline-yes">65x</span>
|
|
277
265
|
<span class="cline-any cline-neutral"> </span>
|
|
278
266
|
<span class="cline-any cline-neutral"> </span>
|
|
279
|
-
<span class="cline-any cline-yes">43x</span>
|
|
280
|
-
<span class="cline-any cline-yes">38x</span>
|
|
281
267
|
<span class="cline-any cline-neutral"> </span>
|
|
282
268
|
<span class="cline-any cline-neutral"> </span>
|
|
269
|
+
<span class="cline-any cline-yes">39x</span>
|
|
283
270
|
<span class="cline-any cline-neutral"> </span>
|
|
284
|
-
<span class="cline-any cline-yes">
|
|
285
|
-
<span class="cline-any cline-yes">
|
|
286
|
-
<span class="cline-any cline-yes">
|
|
271
|
+
<span class="cline-any cline-yes">39x</span>
|
|
272
|
+
<span class="cline-any cline-yes">39x</span>
|
|
273
|
+
<span class="cline-any cline-yes">39x</span>
|
|
287
274
|
<span class="cline-any cline-neutral"> </span>
|
|
288
|
-
<span class="cline-any cline-yes">
|
|
275
|
+
<span class="cline-any cline-yes">39x</span>
|
|
276
|
+
<span class="cline-any cline-yes">9x</span>
|
|
289
277
|
<span class="cline-any cline-neutral"> </span>
|
|
290
278
|
<span class="cline-any cline-neutral"> </span>
|
|
291
279
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -293,145 +281,145 @@
|
|
|
293
281
|
<span class="cline-any cline-neutral"> </span>
|
|
294
282
|
<span class="cline-any cline-neutral"> </span>
|
|
295
283
|
<span class="cline-any cline-neutral"> </span>
|
|
296
|
-
<span class="cline-any cline-yes">31x</span>
|
|
297
|
-
<span class="cline-any cline-yes">31x</span>
|
|
298
284
|
<span class="cline-any cline-neutral"> </span>
|
|
299
|
-
<span class="cline-any cline-yes">31x</span>
|
|
300
|
-
<span class="cline-any cline-yes">31x</span>
|
|
301
|
-
<span class="cline-any cline-yes">29x</span>
|
|
302
285
|
<span class="cline-any cline-neutral"> </span>
|
|
303
|
-
<span class="cline-any cline-yes">2x</span>
|
|
304
286
|
<span class="cline-any cline-neutral"> </span>
|
|
305
287
|
<span class="cline-any cline-neutral"> </span>
|
|
288
|
+
<span class="cline-any cline-yes">104x</span>
|
|
289
|
+
<span class="cline-any cline-neutral"> </span>
|
|
290
|
+
<span class="cline-any cline-neutral"> </span>
|
|
291
|
+
<span class="cline-any cline-yes">104x</span>
|
|
292
|
+
<span class="cline-any cline-yes">101x</span>
|
|
293
|
+
<span class="cline-any cline-neutral"> </span>
|
|
294
|
+
<span class="cline-any cline-yes">101x</span>
|
|
295
|
+
<span class="cline-any cline-neutral"> </span>
|
|
296
|
+
<span class="cline-any cline-yes">101x</span>
|
|
297
|
+
<span class="cline-any cline-neutral"> </span>
|
|
306
298
|
<span class="cline-any cline-neutral"> </span>
|
|
299
|
+
<span class="cline-any cline-yes">101x</span>
|
|
307
300
|
<span class="cline-any cline-neutral"> </span>
|
|
308
|
-
<span class="cline-any cline-
|
|
309
|
-
<span class="cline-any cline-yes">
|
|
310
|
-
<span class="cline-any cline-yes">31x</span>
|
|
301
|
+
<span class="cline-any cline-neutral"> </span>
|
|
302
|
+
<span class="cline-any cline-yes">101x</span>
|
|
311
303
|
<span class="cline-any cline-neutral"> </span>
|
|
312
304
|
<span class="cline-any cline-neutral"> </span>
|
|
313
305
|
<span class="cline-any cline-neutral"> </span>
|
|
314
306
|
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">import { TaskStep } from "./TaskStep.js";
|
|
315
307
|
import { TaskResult } from "./TaskResult.js";
|
|
316
308
|
import { EventBus } from "./EventBus.js";
|
|
309
|
+
import { TaskStateManager } from "./TaskStateManager.js";
|
|
310
|
+
import { IExecutionStrategy } from "./strategies/IExecutionStrategy.js";
|
|
317
311
|
|
|
318
312
|
/**
|
|
319
313
|
* Handles the execution of the workflow steps.
|
|
320
314
|
* @template TContext The shape of the shared context object.
|
|
321
315
|
*/
|
|
322
316
|
export class WorkflowExecutor<TContext> {
|
|
323
|
-
private running = new Set<string>();
|
|
324
|
-
|
|
325
317
|
/**
|
|
326
318
|
* @param context The shared context object.
|
|
327
319
|
* @param eventBus The event bus to emit events.
|
|
320
|
+
* @param stateManager Manages execution state.
|
|
321
|
+
* @param strategy Execution strategy.
|
|
328
322
|
*/
|
|
329
323
|
constructor(
|
|
330
324
|
private context: TContext,
|
|
331
|
-
private eventBus: EventBus<TContext>
|
|
325
|
+
private eventBus: EventBus<TContext>,
|
|
326
|
+
private stateManager: TaskStateManager<TContext>,
|
|
327
|
+
private strategy: IExecutionStrategy<TContext>
|
|
332
328
|
) {}
|
|
333
329
|
|
|
334
330
|
/**
|
|
335
331
|
* Executes the given steps.
|
|
336
332
|
* @param steps The list of steps to execute.
|
|
333
|
+
* @param signal Optional AbortSignal for cancellation.
|
|
337
334
|
* @returns A Promise that resolves to a map of task results.
|
|
338
335
|
*/
|
|
339
|
-
async execute(
|
|
336
|
+
async execute(
|
|
337
|
+
steps: TaskStep<TContext>[],
|
|
338
|
+
signal?: AbortSignal
|
|
339
|
+
): Promise<Map<string, TaskResult>> {
|
|
340
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
|
+
}
|
|
341
350
|
|
|
342
|
-
const results = new Map<string, TaskResult>();
|
|
343
351
|
const executingPromises = new Set<Promise<void>>();
|
|
344
|
-
const pendingSteps = new Set(steps);
|
|
345
352
|
|
|
346
|
-
|
|
347
|
-
|
|
353
|
+
const onAbort = () => {
|
|
354
|
+
// Mark all pending tasks as cancelled
|
|
355
|
+
this.stateManager.cancelAllPending("Workflow cancelled.");
|
|
356
|
+
};
|
|
348
357
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
await Promise.race(executingPromises);
|
|
352
|
-
// After a task finishes, check for new work
|
|
353
|
-
this.processQueue(pendingSteps, results, executingPromises);
|
|
358
|
+
if (signal) {
|
|
359
|
+
signal.addEventListener("abort", onAbort);
|
|
354
360
|
}
|
|
355
361
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
/**
|
|
361
|
-
* Logic to identify tasks that can be started or must be skipped.
|
|
362
|
-
* Iterate only over pending steps to avoid O(N^2) checks on completed tasks.
|
|
363
|
-
*/
|
|
364
|
-
private processQueue(
|
|
365
|
-
pendingSteps: Set<TaskStep<TContext>>,
|
|
366
|
-
results: Map<string, TaskResult>,
|
|
367
|
-
executingPromises: Set<Promise<void>>
|
|
368
|
-
): void {
|
|
369
|
-
const toRemove: TaskStep<TContext>[] = [];
|
|
370
|
-
const toRun: TaskStep<TContext>[] = [];
|
|
371
|
-
|
|
372
|
-
for (const step of pendingSteps) {
|
|
373
|
-
const deps = step.dependencies ?? [];
|
|
374
|
-
let blocked = false;
|
|
375
|
-
let failedDep: string | undefined;
|
|
362
|
+
try {
|
|
363
|
+
// Initial pass
|
|
364
|
+
this.processLoop(executingPromises, signal);
|
|
376
365
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
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) {
|
|
384
374
|
break;
|
|
375
|
+
} else {
|
|
376
|
+
// Wait for the next task to finish
|
|
377
|
+
await Promise.race(executingPromises);
|
|
385
378
|
}
|
|
386
|
-
}
|
|
387
379
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
this.eventBus.emit("taskSkipped", { step, result });
|
|
395
|
-
toRemove.push(step);
|
|
396
|
-
} else if (!blocked) {
|
|
397
|
-
toRun.push(step);
|
|
398
|
-
toRemove.push(step);
|
|
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
|
+
}
|
|
399
386
|
}
|
|
400
|
-
}
|
|
401
387
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
pendingSteps.delete(step);
|
|
405
|
-
}
|
|
388
|
+
// Ensure everything is accounted for (e.g. if loop exited early)
|
|
389
|
+
this.stateManager.cancelAllPending("Workflow cancelled.");
|
|
406
390
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
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);
|
|
397
|
+
}
|
|
413
398
|
}
|
|
414
399
|
}
|
|
415
400
|
|
|
416
401
|
/**
|
|
417
|
-
*
|
|
402
|
+
* Logic to identify tasks that can be started and run them.
|
|
418
403
|
*/
|
|
419
|
-
private
|
|
420
|
-
|
|
421
|
-
|
|
404
|
+
private processLoop(
|
|
405
|
+
executingPromises: Set<Promise<void>>,
|
|
406
|
+
signal?: AbortSignal
|
|
407
|
+
): void {
|
|
408
|
+
const toRun = this.stateManager.processDependencies();
|
|
422
409
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
410
|
+
// Execute ready tasks
|
|
411
|
+
for (const step of toRun) {
|
|
412
|
+
this.stateManager.markRunning(step);
|
|
413
|
+
|
|
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
|
+
});
|
|
421
|
+
|
|
422
|
+
executingPromises.add(taskPromise);
|
|
435
423
|
}
|
|
436
424
|
}
|
|
437
425
|
}
|
|
@@ -442,7 +430,7 @@ export class WorkflowExecutor<TContext> {
|
|
|
442
430
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
443
431
|
Code coverage generated by
|
|
444
432
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
445
|
-
at 2026-01-
|
|
433
|
+
at 2026-01-18T16:53:50.068Z
|
|
446
434
|
</div>
|
|
447
435
|
<script src="../prettify.js"></script>
|
|
448
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-18T16:53:50.068Z
|
|
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-18T16:53:50.068Z
|
|
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'>203/203</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'>70/70</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'>38/38</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'>201/201</span>
|
|
50
50
|
</div>
|
|
51
51
|
|
|
52
52
|
|
|
@@ -99,13 +99,13 @@
|
|
|
99
99
|
<div class="chart"><div class="cover-fill cover-full" style="width: 100%"></div><div class="cover-empty" style="width: 0%"></div></div>
|
|
100
100
|
</td>
|
|
101
101
|
<td data-value="100" class="pct high">100%</td>
|
|
102
|
-
<td data-value="
|
|
102
|
+
<td data-value="56" class="abs high">56/56</td>
|
|
103
103
|
<td data-value="100" class="pct high">100%</td>
|
|
104
104
|
<td data-value="16" class="abs high">16/16</td>
|
|
105
105
|
<td data-value="100" class="pct high">100%</td>
|
|
106
106
|
<td data-value="5" class="abs high">5/5</td>
|
|
107
107
|
<td data-value="100" class="pct high">100%</td>
|
|
108
|
-
<td data-value="
|
|
108
|
+
<td data-value="54" class="abs high">54/54</td>
|
|
109
109
|
</tr>
|
|
110
110
|
|
|
111
111
|
<tr>
|
|
@@ -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="
|
|
117
|
+
<td data-value="33" class="abs high">33/33</td>
|
|
118
|
+
<td data-value="100" class="pct high">100%</td>
|
|
119
|
+
<td data-value="14" class="abs high">14/14</td>
|
|
120
|
+
<td data-value="100" class="pct high">100%</td>
|
|
121
|
+
<td data-value="8" class="abs high">8/8</td>
|
|
122
|
+
<td data-value="100" class="pct high">100%</td>
|
|
123
|
+
<td data-value="33" class="abs high">33/33</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>
|
|
118
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-18T16:53:50.068Z
|
|
150
195
|
</div>
|
|
151
196
|
<script src="../prettify.js"></script>
|
|
152
197
|
<script>
|