@calmo/task-runner 3.8.0 → 3.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/coverage/coverage-final.json +5 -4
- package/coverage/index.html +18 -18
- package/coverage/lcov-report/index.html +18 -18
- package/coverage/lcov-report/src/EventBus.ts.html +70 -34
- package/coverage/lcov-report/src/TaskGraphValidationError.ts.html +1 -1
- package/coverage/lcov-report/src/TaskGraphValidator.ts.html +120 -60
- package/coverage/lcov-report/src/TaskRunner.ts.html +78 -63
- package/coverage/lcov-report/src/TaskRunnerBuilder.ts.html +1 -1
- package/coverage/lcov-report/src/TaskRunnerExecutionConfig.ts.html +1 -1
- package/coverage/lcov-report/src/TaskStateManager.ts.html +17 -29
- package/coverage/lcov-report/src/WorkflowExecutor.ts.html +1 -1
- package/coverage/lcov-report/src/contracts/ErrorTypes.ts.html +103 -0
- package/coverage/lcov-report/src/contracts/RunnerEvents.ts.html +1 -1
- package/coverage/lcov-report/src/contracts/index.html +23 -8
- package/coverage/lcov-report/src/index.html +13 -13
- package/coverage/lcov-report/src/strategies/DryRunExecutionStrategy.ts.html +1 -1
- package/coverage/lcov-report/src/strategies/RetryingExecutionStrategy.ts.html +1 -1
- package/coverage/lcov-report/src/strategies/StandardExecutionStrategy.ts.html +1 -1
- package/coverage/lcov-report/src/strategies/index.html +1 -1
- package/coverage/lcov.info +238 -213
- package/coverage/src/EventBus.ts.html +70 -34
- package/coverage/src/TaskGraphValidationError.ts.html +1 -1
- package/coverage/src/TaskGraphValidator.ts.html +120 -60
- package/coverage/src/TaskRunner.ts.html +78 -63
- package/coverage/src/TaskRunnerBuilder.ts.html +1 -1
- package/coverage/src/TaskRunnerExecutionConfig.ts.html +1 -1
- package/coverage/src/TaskStateManager.ts.html +17 -29
- package/coverage/src/WorkflowExecutor.ts.html +1 -1
- package/coverage/src/contracts/ErrorTypes.ts.html +103 -0
- package/coverage/src/contracts/RunnerEvents.ts.html +1 -1
- package/coverage/src/contracts/index.html +23 -8
- package/coverage/src/index.html +13 -13
- package/coverage/src/strategies/DryRunExecutionStrategy.ts.html +1 -1
- package/coverage/src/strategies/RetryingExecutionStrategy.ts.html +1 -1
- package/coverage/src/strategies/StandardExecutionStrategy.ts.html +1 -1
- package/coverage/src/strategies/index.html +1 -1
- package/dist/EventBus.js +11 -2
- package/dist/EventBus.js.map +1 -1
- package/dist/TaskGraphValidator.d.ts +3 -0
- package/dist/TaskGraphValidator.js +33 -26
- package/dist/TaskGraphValidator.js.map +1 -1
- package/dist/TaskRunner.d.ts +4 -0
- package/dist/TaskRunner.js +38 -44
- package/dist/TaskRunner.js.map +1 -1
- package/dist/TaskStateManager.js +1 -5
- package/dist/TaskStateManager.js.map +1 -1
- package/dist/contracts/ErrorTypes.d.ts +6 -0
- package/dist/contracts/ErrorTypes.js +7 -0
- package/dist/contracts/ErrorTypes.js.map +1 -0
- package/dist/contracts/ValidationError.d.ts +2 -1
- package/package.json +1 -1
- package/src/EventBus.ts +27 -15
- package/src/TaskGraphValidator.ts +52 -32
- package/src/TaskRunner.ts +51 -46
- package/src/TaskStateManager.ts +1 -5
- package/src/contracts/ErrorTypes.ts +6 -0
- package/src/contracts/ValidationError.ts +10 -1
- package/test-report.xml +152 -128
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
<div class='fl pad1y space-right2'>
|
|
26
26
|
<span class="strong">100% </span>
|
|
27
27
|
<span class="quiet">Statements</span>
|
|
28
|
-
<span class='fraction'>
|
|
28
|
+
<span class='fraction'>302/302</span>
|
|
29
29
|
</div>
|
|
30
30
|
|
|
31
31
|
|
|
@@ -39,14 +39,14 @@
|
|
|
39
39
|
<div class='fl pad1y space-right2'>
|
|
40
40
|
<span class="strong">100% </span>
|
|
41
41
|
<span class="quiet">Functions</span>
|
|
42
|
-
<span class='fraction'>
|
|
42
|
+
<span class='fraction'>60/60</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'>299/299</span>
|
|
50
50
|
</div>
|
|
51
51
|
|
|
52
52
|
|
|
@@ -84,28 +84,28 @@
|
|
|
84
84
|
<div class="chart"><div class="cover-fill cover-full" style="width: 100%"></div><div class="cover-empty" style="width: 0%"></div></div>
|
|
85
85
|
</td>
|
|
86
86
|
<td data-value="100" class="pct high">100%</td>
|
|
87
|
-
<td data-value="
|
|
87
|
+
<td data-value="257" class="abs high">257/257</td>
|
|
88
88
|
<td data-value="100" class="pct high">100%</td>
|
|
89
89
|
<td data-value="97" class="abs high">97/97</td>
|
|
90
90
|
<td data-value="100" class="pct high">100%</td>
|
|
91
|
-
<td data-value="
|
|
91
|
+
<td data-value="51" class="abs high">51/51</td>
|
|
92
92
|
<td data-value="100" class="pct high">100%</td>
|
|
93
|
-
<td data-value="
|
|
93
|
+
<td data-value="254" class="abs high">254/254</td>
|
|
94
94
|
</tr>
|
|
95
95
|
|
|
96
96
|
<tr>
|
|
97
|
-
<td class="file
|
|
98
|
-
<td data-value="
|
|
99
|
-
<div class="chart"><div class="cover-fill" style="width:
|
|
97
|
+
<td class="file high" data-value="src/contracts"><a href="src/contracts/index.html">src/contracts</a></td>
|
|
98
|
+
<td data-value="100" class="pic high">
|
|
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
|
-
<td data-value="
|
|
102
|
-
<td data-value="
|
|
103
|
-
<td data-value="
|
|
104
|
-
<td data-value="0" class="abs
|
|
105
|
-
<td data-value="
|
|
106
|
-
<td data-value="0" class="abs
|
|
107
|
-
<td data-value="
|
|
108
|
-
<td data-value="
|
|
101
|
+
<td data-value="100" class="pct high">100%</td>
|
|
102
|
+
<td data-value="3" class="abs high">3/3</td>
|
|
103
|
+
<td data-value="100" class="pct high">100%</td>
|
|
104
|
+
<td data-value="0" class="abs high">0/0</td>
|
|
105
|
+
<td data-value="100" class="pct high">100%</td>
|
|
106
|
+
<td data-value="0" class="abs high">0/0</td>
|
|
107
|
+
<td data-value="100" class="pct high">100%</td>
|
|
108
|
+
<td data-value="3" class="abs high">3/3</td>
|
|
109
109
|
</tr>
|
|
110
110
|
|
|
111
111
|
<tr>
|
|
@@ -131,7 +131,7 @@
|
|
|
131
131
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
132
132
|
Code coverage generated by
|
|
133
133
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
134
|
-
at 2026-01-
|
|
134
|
+
at 2026-01-21T01:16:02.348Z
|
|
135
135
|
</div>
|
|
136
136
|
<script src="prettify.js"></script>
|
|
137
137
|
<script>
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
<div class='fl pad1y space-right2'>
|
|
26
26
|
<span class="strong">100% </span>
|
|
27
27
|
<span class="quiet">Statements</span>
|
|
28
|
-
<span class='fraction'>
|
|
28
|
+
<span class='fraction'>17/17</span>
|
|
29
29
|
</div>
|
|
30
30
|
|
|
31
31
|
|
|
@@ -39,14 +39,14 @@
|
|
|
39
39
|
<div class='fl pad1y space-right2'>
|
|
40
40
|
<span class="strong">100% </span>
|
|
41
41
|
<span class="quiet">Functions</span>
|
|
42
|
-
<span class='fraction'>
|
|
42
|
+
<span class='fraction'>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'>17/17</span>
|
|
50
50
|
</div>
|
|
51
51
|
|
|
52
52
|
|
|
@@ -149,7 +149,19 @@
|
|
|
149
149
|
<a name='L84'></a><a href='#L84'>84</a>
|
|
150
150
|
<a name='L85'></a><a href='#L85'>85</a>
|
|
151
151
|
<a name='L86'></a><a href='#L86'>86</a>
|
|
152
|
-
<a name='L87'></a><a href='#L87'>87</a
|
|
152
|
+
<a name='L87'></a><a href='#L87'>87</a>
|
|
153
|
+
<a name='L88'></a><a href='#L88'>88</a>
|
|
154
|
+
<a name='L89'></a><a href='#L89'>89</a>
|
|
155
|
+
<a name='L90'></a><a href='#L90'>90</a>
|
|
156
|
+
<a name='L91'></a><a href='#L91'>91</a>
|
|
157
|
+
<a name='L92'></a><a href='#L92'>92</a>
|
|
158
|
+
<a name='L93'></a><a href='#L93'>93</a>
|
|
159
|
+
<a name='L94'></a><a href='#L94'>94</a>
|
|
160
|
+
<a name='L95'></a><a href='#L95'>95</a>
|
|
161
|
+
<a name='L96'></a><a href='#L96'>96</a>
|
|
162
|
+
<a name='L97'></a><a href='#L97'>97</a>
|
|
163
|
+
<a name='L98'></a><a href='#L98'>98</a>
|
|
164
|
+
<a name='L99'></a><a href='#L99'>99</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span>
|
|
153
165
|
<span class="cline-any cline-neutral"> </span>
|
|
154
166
|
<span class="cline-any cline-neutral"> </span>
|
|
155
167
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -160,7 +172,7 @@
|
|
|
160
172
|
<span class="cline-any cline-neutral"> </span>
|
|
161
173
|
<span class="cline-any cline-neutral"> </span>
|
|
162
174
|
<span class="cline-any cline-neutral"> </span>
|
|
163
|
-
<span class="cline-any cline-yes">
|
|
175
|
+
<span class="cline-any cline-yes">90x</span>
|
|
164
176
|
<span class="cline-any cline-neutral"> </span>
|
|
165
177
|
<span class="cline-any cline-neutral"> </span>
|
|
166
178
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -171,13 +183,13 @@
|
|
|
171
183
|
<span class="cline-any cline-neutral"> </span>
|
|
172
184
|
<span class="cline-any cline-neutral"> </span>
|
|
173
185
|
<span class="cline-any cline-neutral"> </span>
|
|
174
|
-
<span class="cline-any cline-yes">
|
|
186
|
+
<span class="cline-any cline-yes">24x</span>
|
|
175
187
|
<span class="cline-any cline-neutral"> </span>
|
|
176
188
|
<span class="cline-any cline-neutral"> </span>
|
|
177
|
-
<span class="cline-any cline-yes">
|
|
189
|
+
<span class="cline-any cline-yes">21x</span>
|
|
178
190
|
<span class="cline-any cline-neutral"> </span>
|
|
179
191
|
<span class="cline-any cline-neutral"> </span>
|
|
180
|
-
<span class="cline-any cline-yes">
|
|
192
|
+
<span class="cline-any cline-yes">24x</span>
|
|
181
193
|
<span class="cline-any cline-neutral"> </span>
|
|
182
194
|
<span class="cline-any cline-neutral"> </span>
|
|
183
195
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -191,8 +203,11 @@
|
|
|
191
203
|
<span class="cline-any cline-neutral"> </span>
|
|
192
204
|
<span class="cline-any cline-neutral"> </span>
|
|
193
205
|
<span class="cline-any cline-neutral"> </span>
|
|
194
|
-
<span class="cline-any cline-yes">
|
|
195
|
-
<span class="cline-any cline-yes">
|
|
206
|
+
<span class="cline-any cline-yes">8x</span>
|
|
207
|
+
<span class="cline-any cline-yes">6x</span>
|
|
208
|
+
<span class="cline-any cline-neutral"> </span>
|
|
209
|
+
<span class="cline-any cline-neutral"> </span>
|
|
210
|
+
<span class="cline-any cline-neutral"> </span>
|
|
196
211
|
<span class="cline-any cline-neutral"> </span>
|
|
197
212
|
<span class="cline-any cline-neutral"> </span>
|
|
198
213
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -204,18 +219,20 @@
|
|
|
204
219
|
<span class="cline-any cline-neutral"> </span>
|
|
205
220
|
<span class="cline-any cline-neutral"> </span>
|
|
206
221
|
<span class="cline-any cline-neutral"> </span>
|
|
222
|
+
<span class="cline-any cline-yes">443x</span>
|
|
207
223
|
<span class="cline-any cline-neutral"> </span>
|
|
208
224
|
<span class="cline-any cline-neutral"> </span>
|
|
225
|
+
<span class="cline-any cline-yes">443x</span>
|
|
226
|
+
<span class="cline-any cline-yes">19x</span>
|
|
209
227
|
<span class="cline-any cline-neutral"> </span>
|
|
210
|
-
<span class="cline-any cline-yes">430x</span>
|
|
211
228
|
<span class="cline-any cline-neutral"> </span>
|
|
212
229
|
<span class="cline-any cline-neutral"> </span>
|
|
213
|
-
<span class="cline-any cline-yes">
|
|
214
|
-
<span class="cline-any cline-
|
|
215
|
-
<span class="cline-any cline-yes">
|
|
216
|
-
<span class="cline-any cline-yes">
|
|
217
|
-
<span class="cline-any cline-yes">
|
|
218
|
-
<span class="cline-any cline-
|
|
230
|
+
<span class="cline-any cline-yes">19x</span>
|
|
231
|
+
<span class="cline-any cline-neutral"> </span>
|
|
232
|
+
<span class="cline-any cline-yes">19x</span>
|
|
233
|
+
<span class="cline-any cline-yes">19x</span>
|
|
234
|
+
<span class="cline-any cline-yes">19x</span>
|
|
235
|
+
<span class="cline-any cline-neutral"> </span>
|
|
219
236
|
<span class="cline-any cline-yes">1x</span>
|
|
220
237
|
<span class="cline-any cline-yes">1x</span>
|
|
221
238
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -225,7 +242,7 @@
|
|
|
225
242
|
<span class="cline-any cline-neutral"> </span>
|
|
226
243
|
<span class="cline-any cline-neutral"> </span>
|
|
227
244
|
<span class="cline-any cline-neutral"> </span>
|
|
228
|
-
<span class="cline-any cline-yes">
|
|
245
|
+
<span class="cline-any cline-yes">3x</span>
|
|
229
246
|
<span class="cline-any cline-neutral"> </span>
|
|
230
247
|
<span class="cline-any cline-neutral"> </span>
|
|
231
248
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -233,6 +250,13 @@
|
|
|
233
250
|
<span class="cline-any cline-neutral"> </span>
|
|
234
251
|
<span class="cline-any cline-neutral"> </span>
|
|
235
252
|
<span class="cline-any cline-neutral"> </span>
|
|
253
|
+
<span class="cline-any cline-yes">1x</span>
|
|
254
|
+
<span class="cline-any cline-neutral"> </span>
|
|
255
|
+
<span class="cline-any cline-neutral"> </span>
|
|
256
|
+
<span class="cline-any cline-neutral"> </span>
|
|
257
|
+
<span class="cline-any cline-neutral"> </span>
|
|
258
|
+
<span class="cline-any cline-neutral"> </span>
|
|
259
|
+
<span class="cline-any cline-neutral"> </span>
|
|
236
260
|
<span class="cline-any cline-neutral"> </span>
|
|
237
261
|
<span class="cline-any cline-neutral"> </span>
|
|
238
262
|
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">import {
|
|
@@ -298,25 +322,37 @@ export class EventBus<TContext> {
|
|
|
298
322
|
| undefined;
|
|
299
323
|
if (listeners) {
|
|
300
324
|
for (const listener of listeners) {
|
|
301
|
-
Promise.resolve().then(
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
325
|
+
// We use Promise.resolve().then() to schedule the listener on the microtask queue,
|
|
326
|
+
// ensuring the emit method remains non-blocking.
|
|
327
|
+
// The final .catch() ensures that any errors in the promise infrastructure itself are logged.
|
|
328
|
+
Promise.resolve()
|
|
329
|
+
.then(() => {
|
|
330
|
+
try {
|
|
331
|
+
const result = listener(data);
|
|
332
|
+
if (result instanceof Promise) {
|
|
333
|
+
// Handle async listener rejections
|
|
334
|
+
result.catch((error) => {
|
|
335
|
+
console.error(
|
|
336
|
+
`Error in event listener for ${String(event)}:`,
|
|
337
|
+
error
|
|
338
|
+
);
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
} catch (error) {
|
|
342
|
+
// Handle sync listener errors
|
|
343
|
+
console.error(
|
|
344
|
+
`Error in event listener for ${String(event)}:`,
|
|
345
|
+
error
|
|
346
|
+
);
|
|
311
347
|
}
|
|
312
|
-
}
|
|
313
|
-
|
|
348
|
+
})
|
|
349
|
+
.catch((error) => {
|
|
350
|
+
// detailed handling for the promise chain itself
|
|
314
351
|
console.error(
|
|
315
|
-
`
|
|
352
|
+
`Unexpected error in event bus execution for ${String(event)}:`,
|
|
316
353
|
error
|
|
317
354
|
);
|
|
318
|
-
}
|
|
319
|
-
});
|
|
355
|
+
});
|
|
320
356
|
}
|
|
321
357
|
}
|
|
322
358
|
}
|
|
@@ -328,7 +364,7 @@ export class EventBus<TContext> {
|
|
|
328
364
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
329
365
|
Code coverage generated by
|
|
330
366
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
331
|
-
at 2026-01-
|
|
367
|
+
at 2026-01-21T01:16:02.348Z
|
|
332
368
|
</div>
|
|
333
369
|
<script src="../prettify.js"></script>
|
|
334
370
|
<script>
|
|
@@ -115,7 +115,7 @@ export class TaskGraphValidationError extends Error {
|
|
|
115
115
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
116
116
|
Code coverage generated by
|
|
117
117
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
118
|
-
at 2026-01-
|
|
118
|
+
at 2026-01-21T01:16:02.348Z
|
|
119
119
|
</div>
|
|
120
120
|
<script src="../prettify.js"></script>
|
|
121
121
|
<script>
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
<div class='fl pad1y space-right2'>
|
|
26
26
|
<span class="strong">100% </span>
|
|
27
27
|
<span class="quiet">Statements</span>
|
|
28
|
-
<span class='fraction'>
|
|
28
|
+
<span class='fraction'>59/59</span>
|
|
29
29
|
</div>
|
|
30
30
|
|
|
31
31
|
|
|
@@ -39,14 +39,14 @@
|
|
|
39
39
|
<div class='fl pad1y space-right2'>
|
|
40
40
|
<span class="strong">100% </span>
|
|
41
41
|
<span class="quiet">Functions</span>
|
|
42
|
-
<span class='fraction'>
|
|
42
|
+
<span class='fraction'>8/8</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'>58/58</span>
|
|
50
50
|
</div>
|
|
51
51
|
|
|
52
52
|
|
|
@@ -231,7 +231,32 @@
|
|
|
231
231
|
<a name='L166'></a><a href='#L166'>166</a>
|
|
232
232
|
<a name='L167'></a><a href='#L167'>167</a>
|
|
233
233
|
<a name='L168'></a><a href='#L168'>168</a>
|
|
234
|
-
<a name='L169'></a><a href='#L169'>169</a
|
|
234
|
+
<a name='L169'></a><a href='#L169'>169</a>
|
|
235
|
+
<a name='L170'></a><a href='#L170'>170</a>
|
|
236
|
+
<a name='L171'></a><a href='#L171'>171</a>
|
|
237
|
+
<a name='L172'></a><a href='#L172'>172</a>
|
|
238
|
+
<a name='L173'></a><a href='#L173'>173</a>
|
|
239
|
+
<a name='L174'></a><a href='#L174'>174</a>
|
|
240
|
+
<a name='L175'></a><a href='#L175'>175</a>
|
|
241
|
+
<a name='L176'></a><a href='#L176'>176</a>
|
|
242
|
+
<a name='L177'></a><a href='#L177'>177</a>
|
|
243
|
+
<a name='L178'></a><a href='#L178'>178</a>
|
|
244
|
+
<a name='L179'></a><a href='#L179'>179</a>
|
|
245
|
+
<a name='L180'></a><a href='#L180'>180</a>
|
|
246
|
+
<a name='L181'></a><a href='#L181'>181</a>
|
|
247
|
+
<a name='L182'></a><a href='#L182'>182</a>
|
|
248
|
+
<a name='L183'></a><a href='#L183'>183</a>
|
|
249
|
+
<a name='L184'></a><a href='#L184'>184</a>
|
|
250
|
+
<a name='L185'></a><a href='#L185'>185</a>
|
|
251
|
+
<a name='L186'></a><a href='#L186'>186</a>
|
|
252
|
+
<a name='L187'></a><a href='#L187'>187</a>
|
|
253
|
+
<a name='L188'></a><a href='#L188'>188</a>
|
|
254
|
+
<a name='L189'></a><a href='#L189'>189</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span>
|
|
255
|
+
<span class="cline-any cline-neutral"> </span>
|
|
256
|
+
<span class="cline-any cline-neutral"> </span>
|
|
257
|
+
<span class="cline-any cline-neutral"> </span>
|
|
258
|
+
<span class="cline-any cline-neutral"> </span>
|
|
259
|
+
<span class="cline-any cline-neutral"> </span>
|
|
235
260
|
<span class="cline-any cline-neutral"> </span>
|
|
236
261
|
<span class="cline-any cline-neutral"> </span>
|
|
237
262
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -252,39 +277,69 @@
|
|
|
252
277
|
<span class="cline-any cline-neutral"> </span>
|
|
253
278
|
<span class="cline-any cline-neutral"> </span>
|
|
254
279
|
<span class="cline-any cline-yes">67x</span>
|
|
280
|
+
<span class="cline-any cline-neutral"> </span>
|
|
281
|
+
<span class="cline-any cline-neutral"> </span>
|
|
255
282
|
<span class="cline-any cline-yes">67x</span>
|
|
256
|
-
<span class="cline-any cline-yes">20178x</span>
|
|
257
|
-
<span class="cline-any cline-yes">3x</span>
|
|
258
283
|
<span class="cline-any cline-neutral"> </span>
|
|
259
284
|
<span class="cline-any cline-neutral"> </span>
|
|
260
285
|
<span class="cline-any cline-neutral"> </span>
|
|
286
|
+
<span class="cline-any cline-yes">67x</span>
|
|
287
|
+
<span class="cline-any cline-yes">9x</span>
|
|
261
288
|
<span class="cline-any cline-neutral"> </span>
|
|
262
289
|
<span class="cline-any cline-neutral"> </span>
|
|
263
|
-
<span class="cline-any cline-yes">
|
|
290
|
+
<span class="cline-any cline-yes">67x</span>
|
|
291
|
+
<span class="cline-any cline-yes">61x</span>
|
|
292
|
+
<span class="cline-any cline-neutral"> </span>
|
|
293
|
+
<span class="cline-any cline-neutral"> </span>
|
|
294
|
+
<span class="cline-any cline-yes">67x</span>
|
|
295
|
+
<span class="cline-any cline-neutral"> </span>
|
|
296
|
+
<span class="cline-any cline-neutral"> </span>
|
|
297
|
+
<span class="cline-any cline-neutral"> </span>
|
|
298
|
+
<span class="cline-any cline-neutral"> </span>
|
|
299
|
+
<span class="cline-any cline-neutral"> </span>
|
|
300
|
+
<span class="cline-any cline-neutral"> </span>
|
|
301
|
+
<span class="cline-any cline-neutral"> </span>
|
|
302
|
+
<span class="cline-any cline-neutral"> </span>
|
|
303
|
+
<span class="cline-any cline-neutral"> </span>
|
|
304
|
+
<span class="cline-any cline-neutral"> </span>
|
|
305
|
+
<span class="cline-any cline-neutral"> </span>
|
|
306
|
+
<span class="cline-any cline-yes">11x</span>
|
|
307
|
+
<span class="cline-any cline-yes">10x</span>
|
|
308
|
+
<span class="cline-any cline-neutral"> </span>
|
|
264
309
|
<span class="cline-any cline-neutral"> </span>
|
|
265
310
|
<span class="cline-any cline-neutral"> </span>
|
|
266
311
|
<span class="cline-any cline-neutral"> </span>
|
|
267
312
|
<span class="cline-any cline-neutral"> </span>
|
|
313
|
+
<span class="cline-any cline-neutral"> </span>
|
|
314
|
+
<span class="cline-any cline-yes">67x</span>
|
|
268
315
|
<span class="cline-any cline-yes">67x</span>
|
|
269
316
|
<span class="cline-any cline-yes">20178x</span>
|
|
270
|
-
<span class="cline-any cline-yes">
|
|
271
|
-
<span class="cline-any cline-
|
|
317
|
+
<span class="cline-any cline-yes">3x</span>
|
|
318
|
+
<span class="cline-any cline-neutral"> </span>
|
|
319
|
+
<span class="cline-any cline-neutral"> </span>
|
|
272
320
|
<span class="cline-any cline-neutral"> </span>
|
|
273
321
|
<span class="cline-any cline-neutral"> </span>
|
|
274
322
|
<span class="cline-any cline-neutral"> </span>
|
|
323
|
+
<span class="cline-any cline-yes">20175x</span>
|
|
275
324
|
<span class="cline-any cline-neutral"> </span>
|
|
276
325
|
<span class="cline-any cline-neutral"> </span>
|
|
326
|
+
<span class="cline-any cline-yes">67x</span>
|
|
277
327
|
<span class="cline-any cline-neutral"> </span>
|
|
278
328
|
<span class="cline-any cline-neutral"> </span>
|
|
279
329
|
<span class="cline-any cline-neutral"> </span>
|
|
280
330
|
<span class="cline-any cline-neutral"> </span>
|
|
281
331
|
<span class="cline-any cline-neutral"> </span>
|
|
282
|
-
<span class="cline-any cline-yes">67x</span>
|
|
283
|
-
<span class="cline-any cline-yes">9x</span>
|
|
284
332
|
<span class="cline-any cline-neutral"> </span>
|
|
285
333
|
<span class="cline-any cline-neutral"> </span>
|
|
286
334
|
<span class="cline-any cline-yes">67x</span>
|
|
287
|
-
<span class="cline-any cline-yes">
|
|
335
|
+
<span class="cline-any cline-yes">20178x</span>
|
|
336
|
+
<span class="cline-any cline-yes">20172x</span>
|
|
337
|
+
<span class="cline-any cline-yes">7x</span>
|
|
338
|
+
<span class="cline-any cline-neutral"> </span>
|
|
339
|
+
<span class="cline-any cline-neutral"> </span>
|
|
340
|
+
<span class="cline-any cline-neutral"> </span>
|
|
341
|
+
<span class="cline-any cline-neutral"> </span>
|
|
342
|
+
<span class="cline-any cline-neutral"> </span>
|
|
288
343
|
<span class="cline-any cline-neutral"> </span>
|
|
289
344
|
<span class="cline-any cline-neutral"> </span>
|
|
290
345
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -324,21 +379,6 @@
|
|
|
324
379
|
<span class="cline-any cline-neutral"> </span>
|
|
325
380
|
<span class="cline-any cline-neutral"> </span>
|
|
326
381
|
<span class="cline-any cline-neutral"> </span>
|
|
327
|
-
<span class="cline-any cline-yes">61x</span>
|
|
328
|
-
<span class="cline-any cline-neutral"> </span>
|
|
329
|
-
<span class="cline-any cline-neutral"> </span>
|
|
330
|
-
<span class="cline-any cline-neutral"> </span>
|
|
331
|
-
<span class="cline-any cline-neutral"> </span>
|
|
332
|
-
<span class="cline-any cline-neutral"> </span>
|
|
333
|
-
<span class="cline-any cline-neutral"> </span>
|
|
334
|
-
<span class="cline-any cline-neutral"> </span>
|
|
335
|
-
<span class="cline-any cline-neutral"> </span>
|
|
336
|
-
<span class="cline-any cline-neutral"> </span>
|
|
337
|
-
<span class="cline-any cline-neutral"> </span>
|
|
338
|
-
<span class="cline-any cline-neutral"> </span>
|
|
339
|
-
<span class="cline-any cline-yes">9x</span>
|
|
340
|
-
<span class="cline-any cline-yes">9x</span>
|
|
341
|
-
<span class="cline-any cline-neutral"> </span>
|
|
342
382
|
<span class="cline-any cline-neutral"> </span>
|
|
343
383
|
<span class="cline-any cline-neutral"> </span>
|
|
344
384
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -403,6 +443,11 @@
|
|
|
403
443
|
import { ValidationResult } from "./contracts/ValidationResult.js";
|
|
404
444
|
import { ValidationError } from "./contracts/ValidationError.js";
|
|
405
445
|
import { TaskGraph } from "./TaskGraph.js";
|
|
446
|
+
import {
|
|
447
|
+
ERROR_CYCLE,
|
|
448
|
+
ERROR_DUPLICATE_TASK,
|
|
449
|
+
ERROR_MISSING_DEPENDENCY,
|
|
450
|
+
} from "./contracts/ErrorTypes.js";
|
|
406
451
|
|
|
407
452
|
export class TaskGraphValidator implements ITaskGraphValidator {
|
|
408
453
|
/**
|
|
@@ -419,11 +464,46 @@ export class TaskGraphValidator implements ITaskGraphValidator {
|
|
|
419
464
|
const errors: ValidationError[] = [];
|
|
420
465
|
|
|
421
466
|
// 1. Check for duplicate tasks
|
|
467
|
+
const taskIds = this.checkDuplicateTasks(taskGraph, errors);
|
|
468
|
+
|
|
469
|
+
// 2. Check for missing dependencies
|
|
470
|
+
this.checkMissingDependencies(taskGraph, taskIds, errors);
|
|
471
|
+
|
|
472
|
+
// 3. Check for cycles
|
|
473
|
+
// Only run cycle detection if there are no missing dependencies, otherwise we might chase non-existent nodes.
|
|
474
|
+
const hasMissingDependencies = errors.some(
|
|
475
|
+
(e) => e.type === ERROR_MISSING_DEPENDENCY
|
|
476
|
+
);
|
|
477
|
+
|
|
478
|
+
if (!hasMissingDependencies) {
|
|
479
|
+
this.checkCycles(taskGraph, errors);
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
return {
|
|
483
|
+
isValid: errors.length === 0,
|
|
484
|
+
errors,
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* Creates a human-readable error message from a validation result.
|
|
490
|
+
* @param result The validation result containing errors.
|
|
491
|
+
* @returns A formatted error string.
|
|
492
|
+
*/
|
|
493
|
+
createErrorMessage(result: ValidationResult): string {
|
|
494
|
+
const errorDetails = result.errors.map((e) => e.message);
|
|
495
|
+
return `Task graph validation failed: ${errorDetails.join("; ")}`;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
private checkDuplicateTasks(
|
|
499
|
+
taskGraph: TaskGraph,
|
|
500
|
+
errors: ValidationError[]
|
|
501
|
+
): Set<string> {
|
|
422
502
|
const taskIds = new Set<string>();
|
|
423
503
|
for (const task of taskGraph.tasks) {
|
|
424
504
|
if (taskIds.has(task.id)) {
|
|
425
505
|
errors.push({
|
|
426
|
-
type:
|
|
506
|
+
type: ERROR_DUPLICATE_TASK,
|
|
427
507
|
message: `Duplicate task detected with ID: ${task.id}`,
|
|
428
508
|
details: { taskId: task.id },
|
|
429
509
|
});
|
|
@@ -431,33 +511,28 @@ export class TaskGraphValidator implements ITaskGraphValidator {
|
|
|
431
511
|
taskIds.add(task.id);
|
|
432
512
|
}
|
|
433
513
|
}
|
|
514
|
+
return taskIds;
|
|
515
|
+
}
|
|
434
516
|
|
|
435
|
-
|
|
517
|
+
private checkMissingDependencies(
|
|
518
|
+
taskGraph: TaskGraph,
|
|
519
|
+
taskIds: Set<string>,
|
|
520
|
+
errors: ValidationError[]
|
|
521
|
+
): void {
|
|
436
522
|
for (const task of taskGraph.tasks) {
|
|
437
523
|
for (const dependenceId of task.dependencies) {
|
|
438
524
|
if (!taskIds.has(dependenceId)) {
|
|
439
525
|
errors.push({
|
|
440
|
-
type:
|
|
526
|
+
type: ERROR_MISSING_DEPENDENCY,
|
|
441
527
|
message: `Task '${task.id}' depends on missing task '${dependenceId}'`,
|
|
442
528
|
details: { taskId: task.id, missingDependencyId: dependenceId },
|
|
443
529
|
});
|
|
444
530
|
}
|
|
445
531
|
}
|
|
446
532
|
}
|
|
533
|
+
}
|
|
447
534
|
|
|
448
|
-
|
|
449
|
-
// Only run cycle detection if there are no missing dependencies, otherwise we might chase non-existent nodes.
|
|
450
|
-
const hasMissingDependencies = errors.some(
|
|
451
|
-
(e) => e.type === "missing_dependency"
|
|
452
|
-
);
|
|
453
|
-
|
|
454
|
-
if (hasMissingDependencies) {
|
|
455
|
-
return {
|
|
456
|
-
isValid: errors.length === 0,
|
|
457
|
-
errors,
|
|
458
|
-
};
|
|
459
|
-
}
|
|
460
|
-
|
|
535
|
+
private checkCycles(taskGraph: TaskGraph, errors: ValidationError[]): void {
|
|
461
536
|
// Build adjacency list
|
|
462
537
|
const adjacencyList = new Map<string, string[]>();
|
|
463
538
|
for (const task of taskGraph.tasks) {
|
|
@@ -483,7 +558,7 @@ export class TaskGraphValidator implements ITaskGraphValidator {
|
|
|
483
558
|
const cyclePath = path.slice(cycleStartIndex);
|
|
484
559
|
|
|
485
560
|
errors.push({
|
|
486
|
-
type:
|
|
561
|
+
type: ERROR_CYCLE,
|
|
487
562
|
message: `Cycle detected: ${cyclePath.join(" -> ")}`,
|
|
488
563
|
details: { cyclePath },
|
|
489
564
|
});
|
|
@@ -491,21 +566,6 @@ export class TaskGraphValidator implements ITaskGraphValidator {
|
|
|
491
566
|
break;
|
|
492
567
|
}
|
|
493
568
|
}
|
|
494
|
-
|
|
495
|
-
return {
|
|
496
|
-
isValid: errors.length === 0,
|
|
497
|
-
errors,
|
|
498
|
-
};
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
/**
|
|
502
|
-
* Creates a human-readable error message from a validation result.
|
|
503
|
-
* @param result The validation result containing errors.
|
|
504
|
-
* @returns A formatted error string.
|
|
505
|
-
*/
|
|
506
|
-
createErrorMessage(result: ValidationResult): string {
|
|
507
|
-
const errorDetails = result.errors.map((e) => e.message);
|
|
508
|
-
return `Task graph validation failed: ${errorDetails.join("; ")}`;
|
|
509
569
|
}
|
|
510
570
|
|
|
511
571
|
private detectCycle(
|
|
@@ -574,7 +634,7 @@ export class TaskGraphValidator implements ITaskGraphValidator {
|
|
|
574
634
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
575
635
|
Code coverage generated by
|
|
576
636
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
577
|
-
at 2026-01-
|
|
637
|
+
at 2026-01-21T01:16:02.348Z
|
|
578
638
|
</div>
|
|
579
639
|
<script src="../prettify.js"></script>
|
|
580
640
|
<script>
|