@calmo/task-runner 1.0.1 → 1.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/CHANGELOG.md +14 -0
- package/coverage/TaskRunner.ts.html +373 -31
- package/coverage/coverage-final.json +1 -1
- package/coverage/index.html +9 -9
- package/dist/TaskRunner.d.ts +47 -0
- package/dist/TaskRunner.js +53 -2
- package/dist/TaskRunner.js.map +1 -1
- package/package.json +2 -2
- package/src/TaskRunner.ts +116 -2
- package/tsconfig.test.json +8 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## 1.1.0 (2026-01-18)
|
|
2
|
+
|
|
3
|
+
* Merge branch 'main' into feat/task-runner-observer-pattern-15088823676344229252 ([d38d6f8](https://github.com/thalesraymond/task-runner/commit/d38d6f8))
|
|
4
|
+
* Merge branch 'main' into feat/task-runner-observer-pattern-15088823676344229252 ([2638801](https://github.com/thalesraymond/task-runner/commit/2638801))
|
|
5
|
+
* Merge pull request #22 from thalesraymond/feat/task-runner-observer-pattern-15088823676344229252 ([06e0049](https://github.com/thalesraymond/task-runner/commit/06e0049)), closes [#22](https://github.com/thalesraymond/task-runner/issues/22)
|
|
6
|
+
* fix: add file extensions and types to test file to fix CI errors ([54b186f](https://github.com/thalesraymond/task-runner/commit/54b186f))
|
|
7
|
+
* fix: remove any type usage in TaskRunner to satisfy linter ([b0a21a7](https://github.com/thalesraymond/task-runner/commit/b0a21a7))
|
|
8
|
+
* fix: revert unauthorized changes to package.json and tsconfig.test.json ([cd44f9e](https://github.com/thalesraymond/task-runner/commit/cd44f9e))
|
|
9
|
+
* test: 💍 force 100% coverage ([2e489f0](https://github.com/thalesraymond/task-runner/commit/2e489f0))
|
|
10
|
+
* test: increase coverage to 100% ([5cd1a44](https://github.com/thalesraymond/task-runner/commit/5cd1a44))
|
|
11
|
+
* feat: implement Observer Pattern event system in TaskRunner ([d682983](https://github.com/thalesraymond/task-runner/commit/d682983))
|
|
12
|
+
* feat: implement Observer Pattern event system in TaskRunner ([48bd3d0](https://github.com/thalesraymond/task-runner/commit/48bd3d0))
|
|
13
|
+
* chore: add typescript check for tests ([9b6c5d4](https://github.com/thalesraymond/task-runner/commit/9b6c5d4))
|
|
14
|
+
|
|
1
15
|
## <small>1.0.1 (2026-01-17)</small>
|
|
2
16
|
|
|
3
17
|
* fix: 🐛 fixing commit script and adding a fix to test auto relea ([97cedf4](https://github.com/thalesraymond/task-runner/commit/97cedf4))
|
|
@@ -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'>51/51</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'>27/27</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'>12/12</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'>48/48</span>
|
|
50
50
|
</div>
|
|
51
51
|
|
|
52
52
|
|
|
@@ -149,7 +149,133 @@
|
|
|
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>
|
|
165
|
+
<a name='L100'></a><a href='#L100'>100</a>
|
|
166
|
+
<a name='L101'></a><a href='#L101'>101</a>
|
|
167
|
+
<a name='L102'></a><a href='#L102'>102</a>
|
|
168
|
+
<a name='L103'></a><a href='#L103'>103</a>
|
|
169
|
+
<a name='L104'></a><a href='#L104'>104</a>
|
|
170
|
+
<a name='L105'></a><a href='#L105'>105</a>
|
|
171
|
+
<a name='L106'></a><a href='#L106'>106</a>
|
|
172
|
+
<a name='L107'></a><a href='#L107'>107</a>
|
|
173
|
+
<a name='L108'></a><a href='#L108'>108</a>
|
|
174
|
+
<a name='L109'></a><a href='#L109'>109</a>
|
|
175
|
+
<a name='L110'></a><a href='#L110'>110</a>
|
|
176
|
+
<a name='L111'></a><a href='#L111'>111</a>
|
|
177
|
+
<a name='L112'></a><a href='#L112'>112</a>
|
|
178
|
+
<a name='L113'></a><a href='#L113'>113</a>
|
|
179
|
+
<a name='L114'></a><a href='#L114'>114</a>
|
|
180
|
+
<a name='L115'></a><a href='#L115'>115</a>
|
|
181
|
+
<a name='L116'></a><a href='#L116'>116</a>
|
|
182
|
+
<a name='L117'></a><a href='#L117'>117</a>
|
|
183
|
+
<a name='L118'></a><a href='#L118'>118</a>
|
|
184
|
+
<a name='L119'></a><a href='#L119'>119</a>
|
|
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>
|
|
193
|
+
<a name='L128'></a><a href='#L128'>128</a>
|
|
194
|
+
<a name='L129'></a><a href='#L129'>129</a>
|
|
195
|
+
<a name='L130'></a><a href='#L130'>130</a>
|
|
196
|
+
<a name='L131'></a><a href='#L131'>131</a>
|
|
197
|
+
<a name='L132'></a><a href='#L132'>132</a>
|
|
198
|
+
<a name='L133'></a><a href='#L133'>133</a>
|
|
199
|
+
<a name='L134'></a><a href='#L134'>134</a>
|
|
200
|
+
<a name='L135'></a><a href='#L135'>135</a>
|
|
201
|
+
<a name='L136'></a><a href='#L136'>136</a>
|
|
202
|
+
<a name='L137'></a><a href='#L137'>137</a>
|
|
203
|
+
<a name='L138'></a><a href='#L138'>138</a>
|
|
204
|
+
<a name='L139'></a><a href='#L139'>139</a>
|
|
205
|
+
<a name='L140'></a><a href='#L140'>140</a>
|
|
206
|
+
<a name='L141'></a><a href='#L141'>141</a>
|
|
207
|
+
<a name='L142'></a><a href='#L142'>142</a>
|
|
208
|
+
<a name='L143'></a><a href='#L143'>143</a>
|
|
209
|
+
<a name='L144'></a><a href='#L144'>144</a>
|
|
210
|
+
<a name='L145'></a><a href='#L145'>145</a>
|
|
211
|
+
<a name='L146'></a><a href='#L146'>146</a>
|
|
212
|
+
<a name='L147'></a><a href='#L147'>147</a>
|
|
213
|
+
<a name='L148'></a><a href='#L148'>148</a>
|
|
214
|
+
<a name='L149'></a><a href='#L149'>149</a>
|
|
215
|
+
<a name='L150'></a><a href='#L150'>150</a>
|
|
216
|
+
<a name='L151'></a><a href='#L151'>151</a>
|
|
217
|
+
<a name='L152'></a><a href='#L152'>152</a>
|
|
218
|
+
<a name='L153'></a><a href='#L153'>153</a>
|
|
219
|
+
<a name='L154'></a><a href='#L154'>154</a>
|
|
220
|
+
<a name='L155'></a><a href='#L155'>155</a>
|
|
221
|
+
<a name='L156'></a><a href='#L156'>156</a>
|
|
222
|
+
<a name='L157'></a><a href='#L157'>157</a>
|
|
223
|
+
<a name='L158'></a><a href='#L158'>158</a>
|
|
224
|
+
<a name='L159'></a><a href='#L159'>159</a>
|
|
225
|
+
<a name='L160'></a><a href='#L160'>160</a>
|
|
226
|
+
<a name='L161'></a><a href='#L161'>161</a>
|
|
227
|
+
<a name='L162'></a><a href='#L162'>162</a>
|
|
228
|
+
<a name='L163'></a><a href='#L163'>163</a>
|
|
229
|
+
<a name='L164'></a><a href='#L164'>164</a>
|
|
230
|
+
<a name='L165'></a><a href='#L165'>165</a>
|
|
231
|
+
<a name='L166'></a><a href='#L166'>166</a>
|
|
232
|
+
<a name='L167'></a><a href='#L167'>167</a>
|
|
233
|
+
<a name='L168'></a><a href='#L168'>168</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>
|
|
255
|
+
<a name='L190'></a><a href='#L190'>190</a>
|
|
256
|
+
<a name='L191'></a><a href='#L191'>191</a>
|
|
257
|
+
<a name='L192'></a><a href='#L192'>192</a>
|
|
258
|
+
<a name='L193'></a><a href='#L193'>193</a>
|
|
259
|
+
<a name='L194'></a><a href='#L194'>194</a>
|
|
260
|
+
<a name='L195'></a><a href='#L195'>195</a>
|
|
261
|
+
<a name='L196'></a><a href='#L196'>196</a>
|
|
262
|
+
<a name='L197'></a><a href='#L197'>197</a>
|
|
263
|
+
<a name='L198'></a><a href='#L198'>198</a>
|
|
264
|
+
<a name='L199'></a><a href='#L199'>199</a>
|
|
265
|
+
<a name='L200'></a><a href='#L200'>200</a>
|
|
266
|
+
<a name='L201'></a><a href='#L201'>201</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span>
|
|
267
|
+
<span class="cline-any cline-neutral"> </span>
|
|
268
|
+
<span class="cline-any cline-neutral"> </span>
|
|
269
|
+
<span class="cline-any cline-neutral"> </span>
|
|
270
|
+
<span class="cline-any cline-neutral"> </span>
|
|
271
|
+
<span class="cline-any cline-neutral"> </span>
|
|
272
|
+
<span class="cline-any cline-neutral"> </span>
|
|
273
|
+
<span class="cline-any cline-neutral"> </span>
|
|
274
|
+
<span class="cline-any cline-neutral"> </span>
|
|
275
|
+
<span class="cline-any cline-neutral"> </span>
|
|
276
|
+
<span class="cline-any cline-neutral"> </span>
|
|
277
|
+
<span class="cline-any cline-neutral"> </span>
|
|
278
|
+
<span class="cline-any cline-neutral"> </span>
|
|
153
279
|
<span class="cline-any cline-neutral"> </span>
|
|
154
280
|
<span class="cline-any cline-neutral"> </span>
|
|
155
281
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -158,12 +284,10 @@
|
|
|
158
284
|
<span class="cline-any cline-neutral"> </span>
|
|
159
285
|
<span class="cline-any cline-neutral"> </span>
|
|
160
286
|
<span class="cline-any cline-neutral"> </span>
|
|
161
|
-
<span class="cline-any cline-yes">12x</span>
|
|
162
287
|
<span class="cline-any cline-neutral"> </span>
|
|
163
288
|
<span class="cline-any cline-neutral"> </span>
|
|
164
289
|
<span class="cline-any cline-neutral"> </span>
|
|
165
290
|
<span class="cline-any cline-neutral"> </span>
|
|
166
|
-
<span class="cline-any cline-yes">12x</span>
|
|
167
291
|
<span class="cline-any cline-neutral"> </span>
|
|
168
292
|
<span class="cline-any cline-neutral"> </span>
|
|
169
293
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -173,36 +297,136 @@
|
|
|
173
297
|
<span class="cline-any cline-neutral"> </span>
|
|
174
298
|
<span class="cline-any cline-neutral"> </span>
|
|
175
299
|
<span class="cline-any cline-neutral"> </span>
|
|
176
|
-
<span class="cline-any cline-yes">12x</span>
|
|
177
300
|
<span class="cline-any cline-neutral"> </span>
|
|
178
|
-
<span class="cline-any cline-yes">12x</span>
|
|
179
|
-
<span class="cline-any cline-yes">19x</span>
|
|
180
|
-
<span class="cline-any cline-yes">69x</span>
|
|
181
301
|
<span class="cline-any cline-neutral"> </span>
|
|
182
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-neutral"> </span>
|
|
307
|
+
<span class="cline-any cline-neutral"> </span>
|
|
308
|
+
<span class="cline-any cline-neutral"> </span>
|
|
309
|
+
<span class="cline-any cline-neutral"> </span>
|
|
310
|
+
<span class="cline-any cline-neutral"> </span>
|
|
311
|
+
<span class="cline-any cline-neutral"> </span>
|
|
312
|
+
<span class="cline-any cline-neutral"> </span>
|
|
313
|
+
<span class="cline-any cline-neutral"> </span>
|
|
314
|
+
<span class="cline-any cline-neutral"> </span>
|
|
315
|
+
<span class="cline-any cline-neutral"> </span>
|
|
316
|
+
<span class="cline-any cline-neutral"> </span>
|
|
317
|
+
<span class="cline-any cline-yes">19x</span>
|
|
183
318
|
<span class="cline-any cline-yes">19x</span>
|
|
184
|
-
<span class="cline-any cline-yes">48x</span>
|
|
185
|
-
<span class="cline-any cline-yes">48x</span>
|
|
186
|
-
<span class="cline-any cline-yes">38x</span>
|
|
187
319
|
<span class="cline-any cline-neutral"> </span>
|
|
188
320
|
<span class="cline-any cline-neutral"> </span>
|
|
189
321
|
<span class="cline-any cline-neutral"> </span>
|
|
190
322
|
<span class="cline-any cline-neutral"> </span>
|
|
191
323
|
<span class="cline-any cline-yes">19x</span>
|
|
192
|
-
<span class="cline-any cline-yes">48x</span>
|
|
193
|
-
<span class="cline-any cline-yes">47x</span>
|
|
194
|
-
<span class="cline-any cline-yes">48x</span>
|
|
195
|
-
<span class="cline-any cline-yes">41x</span>
|
|
196
324
|
<span class="cline-any cline-neutral"> </span>
|
|
197
|
-
<span class="cline-any cline-yes">48x</span>
|
|
198
|
-
<span class="cline-any cline-yes">6x</span>
|
|
199
325
|
<span class="cline-any cline-neutral"> </span>
|
|
200
326
|
<span class="cline-any cline-neutral"> </span>
|
|
201
327
|
<span class="cline-any cline-neutral"> </span>
|
|
202
328
|
<span class="cline-any cline-neutral"> </span>
|
|
203
329
|
<span class="cline-any cline-neutral"> </span>
|
|
204
330
|
<span class="cline-any cline-neutral"> </span>
|
|
205
|
-
<span class="cline-any cline-
|
|
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-yes">12x</span>
|
|
335
|
+
<span class="cline-any cline-neutral"> </span>
|
|
336
|
+
<span class="cline-any cline-neutral"> </span>
|
|
337
|
+
<span class="cline-any cline-yes">11x</span>
|
|
338
|
+
<span class="cline-any cline-neutral"> </span>
|
|
339
|
+
<span class="cline-any cline-neutral"> </span>
|
|
340
|
+
<span class="cline-any cline-yes">12x</span>
|
|
341
|
+
<span class="cline-any cline-neutral"> </span>
|
|
342
|
+
<span class="cline-any cline-neutral"> </span>
|
|
343
|
+
<span class="cline-any cline-neutral"> </span>
|
|
344
|
+
<span class="cline-any cline-neutral"> </span>
|
|
345
|
+
<span class="cline-any cline-neutral"> </span>
|
|
346
|
+
<span class="cline-any cline-neutral"> </span>
|
|
347
|
+
<span class="cline-any cline-neutral"> </span>
|
|
348
|
+
<span class="cline-any cline-neutral"> </span>
|
|
349
|
+
<span class="cline-any cline-neutral"> </span>
|
|
350
|
+
<span class="cline-any cline-neutral"> </span>
|
|
351
|
+
<span class="cline-any cline-neutral"> </span>
|
|
352
|
+
<span class="cline-any cline-neutral"> </span>
|
|
353
|
+
<span class="cline-any cline-neutral"> </span>
|
|
354
|
+
<span class="cline-any cline-yes">2x</span>
|
|
355
|
+
<span class="cline-any cline-yes">1x</span>
|
|
356
|
+
<span class="cline-any cline-neutral"> </span>
|
|
357
|
+
<span class="cline-any cline-neutral"> </span>
|
|
358
|
+
<span class="cline-any cline-neutral"> </span>
|
|
359
|
+
<span class="cline-any cline-neutral"> </span>
|
|
360
|
+
<span class="cline-any cline-neutral"> </span>
|
|
361
|
+
<span class="cline-any cline-neutral"> </span>
|
|
362
|
+
<span class="cline-any cline-neutral"> </span>
|
|
363
|
+
<span class="cline-any cline-neutral"> </span>
|
|
364
|
+
<span class="cline-any cline-neutral"> </span>
|
|
365
|
+
<span class="cline-any cline-neutral"> </span>
|
|
366
|
+
<span class="cline-any cline-neutral"> </span>
|
|
367
|
+
<span class="cline-any cline-neutral"> </span>
|
|
368
|
+
<span class="cline-any cline-neutral"> </span>
|
|
369
|
+
<span class="cline-any cline-neutral"> </span>
|
|
370
|
+
<span class="cline-any cline-yes">94x</span>
|
|
371
|
+
<span class="cline-any cline-neutral"> </span>
|
|
372
|
+
<span class="cline-any cline-neutral"> </span>
|
|
373
|
+
<span class="cline-any cline-yes">94x</span>
|
|
374
|
+
<span class="cline-any cline-yes">13x</span>
|
|
375
|
+
<span class="cline-any cline-yes">13x</span>
|
|
376
|
+
<span class="cline-any cline-yes">13x</span>
|
|
377
|
+
<span class="cline-any cline-neutral"> </span>
|
|
378
|
+
<span class="cline-any cline-neutral"> </span>
|
|
379
|
+
<span class="cline-any cline-yes">1x</span>
|
|
380
|
+
<span class="cline-any cline-neutral"> </span>
|
|
381
|
+
<span class="cline-any cline-neutral"> </span>
|
|
382
|
+
<span class="cline-any cline-neutral"> </span>
|
|
383
|
+
<span class="cline-any cline-neutral"> </span>
|
|
384
|
+
<span class="cline-any cline-neutral"> </span>
|
|
385
|
+
<span class="cline-any cline-neutral"> </span>
|
|
386
|
+
<span class="cline-any cline-neutral"> </span>
|
|
387
|
+
<span class="cline-any cline-neutral"> </span>
|
|
388
|
+
<span class="cline-any cline-neutral"> </span>
|
|
389
|
+
<span class="cline-any cline-neutral"> </span>
|
|
390
|
+
<span class="cline-any cline-neutral"> </span>
|
|
391
|
+
<span class="cline-any cline-neutral"> </span>
|
|
392
|
+
<span class="cline-any cline-neutral"> </span>
|
|
393
|
+
<span class="cline-any cline-neutral"> </span>
|
|
394
|
+
<span class="cline-any cline-neutral"> </span>
|
|
395
|
+
<span class="cline-any cline-neutral"> </span>
|
|
396
|
+
<span class="cline-any cline-yes">18x</span>
|
|
397
|
+
<span class="cline-any cline-neutral"> </span>
|
|
398
|
+
<span class="cline-any cline-yes">18x</span>
|
|
399
|
+
<span class="cline-any cline-neutral"> </span>
|
|
400
|
+
<span class="cline-any cline-yes">18x</span>
|
|
401
|
+
<span class="cline-any cline-yes">26x</span>
|
|
402
|
+
<span class="cline-any cline-yes">80x</span>
|
|
403
|
+
<span class="cline-any cline-neutral"> </span>
|
|
404
|
+
<span class="cline-any cline-neutral"> </span>
|
|
405
|
+
<span class="cline-any cline-yes">26x</span>
|
|
406
|
+
<span class="cline-any cline-yes">57x</span>
|
|
407
|
+
<span class="cline-any cline-yes">57x</span>
|
|
408
|
+
<span class="cline-any cline-yes">42x</span>
|
|
409
|
+
<span class="cline-any cline-neutral"> </span>
|
|
410
|
+
<span class="cline-any cline-neutral"> </span>
|
|
411
|
+
<span class="cline-any cline-neutral"> </span>
|
|
412
|
+
<span class="cline-any cline-neutral"> </span>
|
|
413
|
+
<span class="cline-any cline-yes">26x</span>
|
|
414
|
+
<span class="cline-any cline-yes">57x</span>
|
|
415
|
+
<span class="cline-any cline-yes">56x</span>
|
|
416
|
+
<span class="cline-any cline-yes">57x</span>
|
|
417
|
+
<span class="cline-any cline-yes">45x</span>
|
|
418
|
+
<span class="cline-any cline-neutral"> </span>
|
|
419
|
+
<span class="cline-any cline-yes">57x</span>
|
|
420
|
+
<span class="cline-any cline-yes">7x</span>
|
|
421
|
+
<span class="cline-any cline-neutral"> </span>
|
|
422
|
+
<span class="cline-any cline-neutral"> </span>
|
|
423
|
+
<span class="cline-any cline-neutral"> </span>
|
|
424
|
+
<span class="cline-any cline-yes">7x</span>
|
|
425
|
+
<span class="cline-any cline-yes">7x</span>
|
|
426
|
+
<span class="cline-any cline-neutral"> </span>
|
|
427
|
+
<span class="cline-any cline-neutral"> </span>
|
|
428
|
+
<span class="cline-any cline-neutral"> </span>
|
|
429
|
+
<span class="cline-any cline-yes">26x</span>
|
|
206
430
|
<span class="cline-any cline-neutral"> </span>
|
|
207
431
|
<span class="cline-any cline-neutral"> </span>
|
|
208
432
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -214,30 +438,76 @@
|
|
|
214
438
|
<span class="cline-any cline-neutral"> </span>
|
|
215
439
|
<span class="cline-any cline-neutral"> </span>
|
|
216
440
|
<span class="cline-any cline-neutral"> </span>
|
|
217
|
-
<span class="cline-any cline-yes">
|
|
441
|
+
<span class="cline-any cline-yes">23x</span>
|
|
218
442
|
<span class="cline-any cline-neutral"> </span>
|
|
219
|
-
<span class="cline-any cline-yes">
|
|
220
|
-
<span class="cline-any cline-yes">
|
|
221
|
-
<span class="cline-any cline-yes">
|
|
222
|
-
<span class="cline-any cline-yes">
|
|
443
|
+
<span class="cline-any cline-yes">27x</span>
|
|
444
|
+
<span class="cline-any cline-yes">27x</span>
|
|
445
|
+
<span class="cline-any cline-yes">27x</span>
|
|
446
|
+
<span class="cline-any cline-yes">27x</span>
|
|
447
|
+
<span class="cline-any cline-yes">25x</span>
|
|
223
448
|
<span class="cline-any cline-neutral"> </span>
|
|
224
449
|
<span class="cline-any cline-yes">2x</span>
|
|
225
450
|
<span class="cline-any cline-neutral"> </span>
|
|
226
451
|
<span class="cline-any cline-neutral"> </span>
|
|
227
452
|
<span class="cline-any cline-neutral"> </span>
|
|
228
453
|
<span class="cline-any cline-neutral"> </span>
|
|
229
|
-
<span class="cline-any cline-yes">
|
|
454
|
+
<span class="cline-any cline-yes">27x</span>
|
|
455
|
+
<span class="cline-any cline-yes">27x</span>
|
|
456
|
+
<span class="cline-any cline-yes">27x</span>
|
|
230
457
|
<span class="cline-any cline-neutral"> </span>
|
|
231
458
|
<span class="cline-any cline-neutral"> </span>
|
|
232
459
|
<span class="cline-any cline-neutral"> </span>
|
|
233
460
|
<span class="cline-any cline-neutral"> </span>
|
|
234
461
|
<span class="cline-any cline-neutral"> </span>
|
|
235
|
-
<span class="cline-any cline-yes">
|
|
462
|
+
<span class="cline-any cline-yes">15x</span>
|
|
463
|
+
<span class="cline-any cline-yes">15x</span>
|
|
236
464
|
<span class="cline-any cline-neutral"> </span>
|
|
237
465
|
<span class="cline-any cline-neutral"> </span>
|
|
238
466
|
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">import { TaskStep } from "./TaskStep.js";
|
|
239
467
|
import { TaskResult } from "./TaskResult.js";
|
|
240
468
|
|
|
469
|
+
/**
|
|
470
|
+
* Define the payload for every possible event in the lifecycle.
|
|
471
|
+
*/
|
|
472
|
+
export interface RunnerEventPayloads<TContext> {
|
|
473
|
+
workflowStart: {
|
|
474
|
+
context: TContext;
|
|
475
|
+
steps: TaskStep<TContext>[];
|
|
476
|
+
};
|
|
477
|
+
workflowEnd: {
|
|
478
|
+
context: TContext;
|
|
479
|
+
results: Map<string, TaskResult>;
|
|
480
|
+
};
|
|
481
|
+
taskStart: {
|
|
482
|
+
step: TaskStep<TContext>;
|
|
483
|
+
};
|
|
484
|
+
taskEnd: {
|
|
485
|
+
step: TaskStep<TContext>;
|
|
486
|
+
result: TaskResult;
|
|
487
|
+
};
|
|
488
|
+
taskSkipped: {
|
|
489
|
+
step: TaskStep<TContext>;
|
|
490
|
+
result: TaskResult;
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
/**
|
|
495
|
+
* A generic listener type that maps the event key to its specific payload.
|
|
496
|
+
*/
|
|
497
|
+
export type RunnerEventListener<
|
|
498
|
+
TContext,
|
|
499
|
+
K extends keyof RunnerEventPayloads<TContext>,
|
|
500
|
+
> = (data: RunnerEventPayloads<TContext>[K]) => void | Promise<void>;
|
|
501
|
+
|
|
502
|
+
/**
|
|
503
|
+
* Helper type for the listeners map to avoid private access issues in generic contexts.
|
|
504
|
+
*/
|
|
505
|
+
type ListenerMap<TContext> = {
|
|
506
|
+
[K in keyof RunnerEventPayloads<TContext>]?: Set<
|
|
507
|
+
RunnerEventListener<TContext, K>
|
|
508
|
+
>;
|
|
509
|
+
};
|
|
510
|
+
|
|
241
511
|
/**
|
|
242
512
|
* The main class that orchestrates the execution of a list of tasks
|
|
243
513
|
* based on their dependencies, with support for parallel execution.
|
|
@@ -245,11 +515,75 @@ import { TaskResult } from "./TaskResult.js";
|
|
|
245
515
|
*/
|
|
246
516
|
export class TaskRunner<TContext> {
|
|
247
517
|
private running = new Set<string>();
|
|
518
|
+
private listeners: ListenerMap<TContext> = {};
|
|
248
519
|
|
|
249
520
|
/**
|
|
250
521
|
* @param context The shared context object to be passed to each task.
|
|
251
522
|
*/
|
|
252
523
|
constructor(private context: TContext) {}
|
|
524
|
+
|
|
525
|
+
/**
|
|
526
|
+
* Subscribe to an event.
|
|
527
|
+
* @param event The event name.
|
|
528
|
+
* @param callback The callback to execute when the event is emitted.
|
|
529
|
+
*/
|
|
530
|
+
public on<K extends keyof RunnerEventPayloads<TContext>>(
|
|
531
|
+
event: K,
|
|
532
|
+
callback: RunnerEventListener<TContext, K>
|
|
533
|
+
): void {
|
|
534
|
+
if (!this.listeners[event]) {
|
|
535
|
+
// Type assertion needed because TypeScript cannot verify that the generic K
|
|
536
|
+
// matches the specific key in the mapped type during assignment.
|
|
537
|
+
this.listeners[event] = new Set() as unknown as ListenerMap<TContext>[K];
|
|
538
|
+
}
|
|
539
|
+
// Type assertion needed to tell TS that this specific Set matches the callback type
|
|
540
|
+
(this.listeners[event] as Set<RunnerEventListener<TContext, K>>).add(
|
|
541
|
+
callback
|
|
542
|
+
);
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* Unsubscribe from an event.
|
|
547
|
+
* @param event The event name.
|
|
548
|
+
* @param callback The callback to remove.
|
|
549
|
+
*/
|
|
550
|
+
public off<K extends keyof RunnerEventPayloads<TContext>>(
|
|
551
|
+
event: K,
|
|
552
|
+
callback: RunnerEventListener<TContext, K>
|
|
553
|
+
): void {
|
|
554
|
+
if (this.listeners[event]) {
|
|
555
|
+
(this.listeners[event] as Set<RunnerEventListener<TContext, K>>).delete(
|
|
556
|
+
callback
|
|
557
|
+
);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/**
|
|
562
|
+
* Emit an event to all subscribers.
|
|
563
|
+
* @param event The event name.
|
|
564
|
+
* @param data The payload for the event.
|
|
565
|
+
*/
|
|
566
|
+
private emit<K extends keyof RunnerEventPayloads<TContext>>(
|
|
567
|
+
event: K,
|
|
568
|
+
data: RunnerEventPayloads<TContext>[K]
|
|
569
|
+
): void {
|
|
570
|
+
const listeners = this.listeners[event] as
|
|
571
|
+
| Set<RunnerEventListener<TContext, K>>
|
|
572
|
+
| undefined;
|
|
573
|
+
if (listeners) {
|
|
574
|
+
for (const listener of listeners) {
|
|
575
|
+
try {
|
|
576
|
+
listener(data);
|
|
577
|
+
} catch (error) {
|
|
578
|
+
// Prevent listener errors from bubbling up
|
|
579
|
+
console.error(
|
|
580
|
+
`Error in event listener for ${String(event)}:`,
|
|
581
|
+
error
|
|
582
|
+
);
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
}
|
|
253
587
|
|
|
254
588
|
/**
|
|
255
589
|
* Executes a list of tasks, respecting their dependencies and running
|
|
@@ -259,6 +593,8 @@ export class TaskRunner<TContext> {
|
|
|
259
593
|
* and values are the corresponding TaskResult objects.
|
|
260
594
|
*/
|
|
261
595
|
async execute(steps: TaskStep<TContext>[]): Promise<Map<string, TaskResult>> {
|
|
596
|
+
this.emit("workflowStart", { context: this.context, steps });
|
|
597
|
+
|
|
262
598
|
const results = new Map<string, TaskResult>();
|
|
263
599
|
|
|
264
600
|
while (results.size < steps.length) {
|
|
@@ -281,10 +617,12 @@ export class TaskRunner<TContext> {
|
|
|
281
617
|
(dep) => results.has(dep) && results.get(dep)?.status !== "success"
|
|
282
618
|
);
|
|
283
619
|
if (failedDep) {
|
|
284
|
-
|
|
620
|
+
const result: TaskResult = {
|
|
285
621
|
status: "skipped",
|
|
286
622
|
message: `Skipped due to failed dependency: ${failedDep}`,
|
|
287
|
-
}
|
|
623
|
+
};
|
|
624
|
+
results.set(step.name, result);
|
|
625
|
+
this.emit("taskSkipped", { step, result });
|
|
288
626
|
}
|
|
289
627
|
}
|
|
290
628
|
|
|
@@ -303,6 +641,7 @@ export class TaskRunner<TContext> {
|
|
|
303
641
|
await Promise.all(
|
|
304
642
|
readySteps.map(async (step) => {
|
|
305
643
|
this.running.add(step.name);
|
|
644
|
+
this.emit("taskStart", { step });
|
|
306
645
|
try {
|
|
307
646
|
const result = await step.run(this.context);
|
|
308
647
|
results.set(step.name, result);
|
|
@@ -313,11 +652,14 @@ export class TaskRunner<TContext> {
|
|
|
313
652
|
});
|
|
314
653
|
} finally {
|
|
315
654
|
this.running.delete(step.name);
|
|
655
|
+
const result = results.get(step.name)!;
|
|
656
|
+
this.emit("taskEnd", { step, result });
|
|
316
657
|
}
|
|
317
658
|
})
|
|
318
659
|
);
|
|
319
660
|
}
|
|
320
661
|
|
|
662
|
+
this.emit("workflowEnd", { context: this.context, results });
|
|
321
663
|
return results;
|
|
322
664
|
}
|
|
323
665
|
}
|
|
@@ -328,7 +670,7 @@ export class TaskRunner<TContext> {
|
|
|
328
670
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
329
671
|
Code coverage generated by
|
|
330
672
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
331
|
-
at 2026-01-
|
|
673
|
+
at 2026-01-18T01:05:27.353Z
|
|
332
674
|
</div>
|
|
333
675
|
<script src="prettify.js"></script>
|
|
334
676
|
<script>
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
{"/home/runner/work/task-runner/task-runner/src/TaskRunner.ts": {"path":"/home/runner/work/task-runner/task-runner/src/TaskRunner.ts","statementMap":{"0":{"start":{"line":10,"column":20},"end":{"line":10,"column":null}},"1":{"start":{"line":15,"column":22},"end":{"line":15,"column":41}},"2":{"start":{"line":25,"column":20},"end":{"line":25,"column":null}},"3":{"start":{"line":27,"column":4},"end":{"line":82,"column":null}},"4":{"start":{"line":28,"column":27},"end":{"line":30,"column":null}},"5":{"start":{"line":29,"column":18},"end":{"line":29,"column":null}},"6":{"start":{"line":32,"column":25},"end":{"line":37,"column":null}},"7":{"start":{"line":33,"column":21},"end":{"line":33,"column":null}},"8":{"start":{"line":34,"column":8},"end":{"line":36,"column":null}},"9":{"start":{"line":35,"column":19},"end":{"line":35,"column":null}},"10":{"start":{"line":40,"column":6},"end":{"line":52,"column":null}},"11":{"start":{"line":41,"column":8},"end":{"line":41,"column":null}},"12":{"start":{"line":41,"column":36},"end":{"line":41,"column":null}},"13":{"start":{"line":42,"column":21},"end":{"line":42,"column":null}},"14":{"start":{"line":43,"column":26},"end":{"line":45,"column":null}},"15":{"start":{"line":44,"column":19},"end":{"line":44,"column":null}},"16":{"start":{"line":46,"column":8},"end":{"line":51,"column":null}},"17":{"start":{"line":47,"column":10},"end":{"line":50,"column":null}},"18":{"start":{"line":54,"column":6},"end":{"line":64,"column":null}},"19":{"start":{"line":59,"column":32},"end":{"line":59,"column":null}},"20":{"start":{"line":59,"column":52},"end":{"line":59,"column":72}},"21":{"start":{"line":60,"column":36},"end":{"line":60,"column":null}},"22":{"start":{"line":60,"column":63},"end":{"line":60,"column":69}},"23":{"start":{"line":61,"column":8},"end":{"line":63,"column":null}},"24":{"start":{"line":66,"column":6},"end":{"line":81,"column":null}},"25":{"start":{"line":68,"column":10},"end":{"line":68,"column":null}},"26":{"start":{"line":69,"column":10},"end":{"line":79,"column":null}},"27":{"start":{"line":70,"column":27},"end":{"line":70,"column":null}},"28":{"start":{"line":71,"column":12},"end":{"line":71,"column":null}},"29":{"start":{"line":73,"column":12},"end":{"line":76,"column":null}},"30":{"start":{"line":78,"column":12},"end":{"line":78,"column":null}},"31":{"start":{"line":84,"column":4},"end":{"line":84,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":15,"column":2},"end":{"line":15,"column":22}},"loc":{"start":{"line":15,"column":41},"end":{"line":15,"column":null}},"line":15},"1":{"name":"(anonymous_1)","decl":{"start":{"line":24,"column":8},"end":{"line":24,"column":16}},"loc":{"start":{"line":24,"column":79},"end":{"line":85,"column":null}},"line":24},"2":{"name":"(anonymous_2)","decl":{"start":{"line":29,"column":8},"end":{"line":29,"column":9}},"loc":{"start":{"line":29,"column":18},"end":{"line":29,"column":null}},"line":29},"3":{"name":"(anonymous_3)","decl":{"start":{"line":32,"column":45},"end":{"line":32,"column":46}},"loc":{"start":{"line":32,"column":55},"end":{"line":37,"column":7}},"line":32},"4":{"name":"(anonymous_4)","decl":{"start":{"line":35,"column":10},"end":{"line":35,"column":11}},"loc":{"start":{"line":35,"column":19},"end":{"line":35,"column":null}},"line":35},"5":{"name":"(anonymous_5)","decl":{"start":{"line":44,"column":10},"end":{"line":44,"column":11}},"loc":{"start":{"line":44,"column":19},"end":{"line":44,"column":null}},"line":44},"6":{"name":"(anonymous_6)","decl":{"start":{"line":59,"column":45},"end":{"line":59,"column":46}},"loc":{"start":{"line":59,"column":52},"end":{"line":59,"column":72}},"line":59},"7":{"name":"(anonymous_7)","decl":{"start":{"line":60,"column":56},"end":{"line":60,"column":57}},"loc":{"start":{"line":60,"column":63},"end":{"line":60,"column":69}},"line":60},"8":{"name":"(anonymous_8)","decl":{"start":{"line":67,"column":23},"end":{"line":67,"column":30}},"loc":{"start":{"line":67,"column":39},"end":{"line":80,"column":9}},"line":67}},"branchMap":{"0":{"loc":{"start":{"line":29,"column":18},"end":{"line":29,"column":null}},"type":"binary-expr","locations":[{"start":{"line":29,"column":18},"end":{"line":29,"column":45}},{"start":{"line":29,"column":45},"end":{"line":29,"column":null}}],"line":29},"1":{"loc":{"start":{"line":33,"column":21},"end":{"line":33,"column":null}},"type":"binary-expr","locations":[{"start":{"line":33,"column":21},"end":{"line":33,"column":42}},{"start":{"line":33,"column":42},"end":{"line":33,"column":null}}],"line":33},"2":{"loc":{"start":{"line":35,"column":19},"end":{"line":35,"column":null}},"type":"binary-expr","locations":[{"start":{"line":35,"column":19},"end":{"line":35,"column":39}},{"start":{"line":35,"column":39},"end":{"line":35,"column":null}}],"line":35},"3":{"loc":{"start":{"line":41,"column":8},"end":{"line":41,"column":null}},"type":"if","locations":[{"start":{"line":41,"column":8},"end":{"line":41,"column":null}},{"start":{},"end":{}}],"line":41},"4":{"loc":{"start":{"line":42,"column":21},"end":{"line":42,"column":null}},"type":"binary-expr","locations":[{"start":{"line":42,"column":21},"end":{"line":42,"column":42}},{"start":{"line":42,"column":42},"end":{"line":42,"column":null}}],"line":42},"5":{"loc":{"start":{"line":44,"column":19},"end":{"line":44,"column":null}},"type":"binary-expr","locations":[{"start":{"line":44,"column":19},"end":{"line":44,"column":39}},{"start":{"line":44,"column":39},"end":{"line":44,"column":null}}],"line":44},"6":{"loc":{"start":{"line":46,"column":8},"end":{"line":51,"column":null}},"type":"if","locations":[{"start":{"line":46,"column":8},"end":{"line":51,"column":null}},{"start":{},"end":{}}],"line":46},"7":{"loc":{"start":{"line":54,"column":6},"end":{"line":64,"column":null}},"type":"if","locations":[{"start":{"line":54,"column":6},"end":{"line":64,"column":null}},{"start":{},"end":{}}],"line":54},"8":{"loc":{"start":{"line":55,"column":8},"end":{"line":57,"column":null}},"type":"binary-expr","locations":[{"start":{"line":55,"column":8},"end":{"line":55,"column":null}},{"start":{"line":56,"column":8},"end":{"line":56,"column":null}},{"start":{"line":57,"column":8},"end":{"line":57,"column":null}}],"line":55},"9":{"loc":{"start":{"line":75,"column":21},"end":{"line":75,"column":null}},"type":"cond-expr","locations":[{"start":{"line":75,"column":42},"end":{"line":75,"column":54}},{"start":{"line":75,"column":54},"end":{"line":75,"column":null}}],"line":75}},"s":{"0":12,"1":12,"2":12,"3":12,"4":19,"5":69,"6":19,"7":48,"8":48,"9":38,"10":19,"11":48,"12":1,"13":47,"14":48,"15":41,"16":48,"17":6,"18":19,"19":3,"20":6,"21":3,"22":3,"23":3,"24":16,"25":21,"26":21,"27":21,"28":19,"29":2,"30":21,"31":9},"f":{"0":12,"1":12,"2":69,"3":48,"4":38,"5":41,"6":6,"7":3,"8":21},"b":{"0":[69,48],"1":[48,14],"2":[38,17],"3":[1,47],"4":[47,14],"5":[41,17],"6":[6,42],"7":[3,16],"8":[19,5,5],"9":[1,1]},"meta":{"lastBranch":10,"lastFunction":9,"lastStatement":32,"seen":{"s:10:20:10:Infinity":0,"f:15:2:15:22":0,"s:15:22:15:41":1,"f:24:8:24:16":1,"s:25:20:25:Infinity":2,"s:27:4:82:Infinity":3,"s:28:27:30:Infinity":4,"f:29:8:29:9":2,"s:29:18:29:Infinity":5,"b:29:18:29:45:29:45:29:Infinity":0,"s:32:25:37:Infinity":6,"f:32:45:32:46":3,"s:33:21:33:Infinity":7,"b:33:21:33:42:33:42:33:Infinity":1,"s:34:8:36:Infinity":8,"f:35:10:35:11":4,"s:35:19:35:Infinity":9,"b:35:19:35:39:35:39:35:Infinity":2,"s:40:6:52:Infinity":10,"b:41:8:41:Infinity:undefined:undefined:undefined:undefined":3,"s:41:8:41:Infinity":11,"s:41:36:41:Infinity":12,"s:42:21:42:Infinity":13,"b:42:21:42:42:42:42:42:Infinity":4,"s:43:26:45:Infinity":14,"f:44:10:44:11":5,"s:44:19:44:Infinity":15,"b:44:19:44:39:44:39:44:Infinity":5,"b:46:8:51:Infinity:undefined:undefined:undefined:undefined":6,"s:46:8:51:Infinity":16,"s:47:10:50:Infinity":17,"b:54:6:64:Infinity:undefined:undefined:undefined:undefined":7,"s:54:6:64:Infinity":18,"b:55:8:55:Infinity:56:8:56:Infinity:57:8:57:Infinity":8,"s:59:32:59:Infinity":19,"f:59:45:59:46":6,"s:59:52:59:72":20,"s:60:36:60:Infinity":21,"f:60:56:60:57":7,"s:60:63:60:69":22,"s:61:8:63:Infinity":23,"s:66:6:81:Infinity":24,"f:67:23:67:30":8,"s:68:10:68:Infinity":25,"s:69:10:79:Infinity":26,"s:70:27:70:Infinity":27,"s:71:12:71:Infinity":28,"s:73:12:76:Infinity":29,"b:75:42:75:54:75:54:75:Infinity":9,"s:78:12:78:Infinity":30,"s:84:4:84:Infinity":31}}}
|
|
1
|
+
{"/home/runner/work/task-runner/task-runner/src/TaskRunner.ts": {"path":"/home/runner/work/task-runner/task-runner/src/TaskRunner.ts","statementMap":{"0":{"start":{"line":52,"column":20},"end":{"line":52,"column":null}},"1":{"start":{"line":53,"column":45},"end":{"line":53,"column":null}},"2":{"start":{"line":58,"column":22},"end":{"line":58,"column":41}},"3":{"start":{"line":69,"column":4},"end":{"line":73,"column":null}},"4":{"start":{"line":72,"column":6},"end":{"line":72,"column":null}},"5":{"start":{"line":75,"column":5},"end":{"line":77,"column":null}},"6":{"start":{"line":89,"column":4},"end":{"line":93,"column":null}},"7":{"start":{"line":90,"column":7},"end":{"line":92,"column":null}},"8":{"start":{"line":105,"column":22},"end":{"line":105,"column":null}},"9":{"start":{"line":108,"column":4},"end":{"line":120,"column":null}},"10":{"start":{"line":109,"column":6},"end":{"line":119,"column":null}},"11":{"start":{"line":110,"column":8},"end":{"line":118,"column":null}},"12":{"start":{"line":111,"column":10},"end":{"line":111,"column":null}},"13":{"start":{"line":114,"column":10},"end":{"line":117,"column":null}},"14":{"start":{"line":131,"column":4},"end":{"line":131,"column":null}},"15":{"start":{"line":133,"column":20},"end":{"line":133,"column":null}},"16":{"start":{"line":135,"column":4},"end":{"line":195,"column":null}},"17":{"start":{"line":136,"column":27},"end":{"line":138,"column":null}},"18":{"start":{"line":137,"column":18},"end":{"line":137,"column":null}},"19":{"start":{"line":140,"column":25},"end":{"line":145,"column":null}},"20":{"start":{"line":141,"column":21},"end":{"line":141,"column":null}},"21":{"start":{"line":142,"column":8},"end":{"line":144,"column":null}},"22":{"start":{"line":143,"column":19},"end":{"line":143,"column":null}},"23":{"start":{"line":148,"column":6},"end":{"line":162,"column":null}},"24":{"start":{"line":149,"column":8},"end":{"line":149,"column":null}},"25":{"start":{"line":149,"column":36},"end":{"line":149,"column":null}},"26":{"start":{"line":150,"column":21},"end":{"line":150,"column":null}},"27":{"start":{"line":151,"column":26},"end":{"line":153,"column":null}},"28":{"start":{"line":152,"column":19},"end":{"line":152,"column":null}},"29":{"start":{"line":154,"column":8},"end":{"line":161,"column":null}},"30":{"start":{"line":155,"column":37},"end":{"line":158,"column":null}},"31":{"start":{"line":159,"column":10},"end":{"line":159,"column":null}},"32":{"start":{"line":160,"column":10},"end":{"line":160,"column":null}},"33":{"start":{"line":164,"column":6},"end":{"line":174,"column":null}},"34":{"start":{"line":169,"column":32},"end":{"line":169,"column":null}},"35":{"start":{"line":169,"column":52},"end":{"line":169,"column":72}},"36":{"start":{"line":170,"column":36},"end":{"line":170,"column":null}},"37":{"start":{"line":170,"column":63},"end":{"line":170,"column":69}},"38":{"start":{"line":171,"column":8},"end":{"line":173,"column":null}},"39":{"start":{"line":176,"column":6},"end":{"line":194,"column":null}},"40":{"start":{"line":178,"column":10},"end":{"line":178,"column":null}},"41":{"start":{"line":179,"column":10},"end":{"line":179,"column":null}},"42":{"start":{"line":180,"column":10},"end":{"line":192,"column":null}},"43":{"start":{"line":181,"column":27},"end":{"line":181,"column":null}},"44":{"start":{"line":182,"column":12},"end":{"line":182,"column":null}},"45":{"start":{"line":184,"column":12},"end":{"line":187,"column":null}},"46":{"start":{"line":189,"column":12},"end":{"line":189,"column":null}},"47":{"start":{"line":190,"column":27},"end":{"line":190,"column":null}},"48":{"start":{"line":191,"column":12},"end":{"line":191,"column":null}},"49":{"start":{"line":197,"column":4},"end":{"line":197,"column":null}},"50":{"start":{"line":198,"column":4},"end":{"line":198,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":58,"column":2},"end":{"line":58,"column":22}},"loc":{"start":{"line":58,"column":41},"end":{"line":58,"column":null}},"line":58},"1":{"name":"(anonymous_1)","decl":{"start":{"line":65,"column":9},"end":{"line":65,"column":null}},"loc":{"start":{"line":68,"column":10},"end":{"line":78,"column":null}},"line":68},"2":{"name":"(anonymous_2)","decl":{"start":{"line":85,"column":9},"end":{"line":85,"column":null}},"loc":{"start":{"line":88,"column":10},"end":{"line":94,"column":null}},"line":88},"3":{"name":"(anonymous_3)","decl":{"start":{"line":101,"column":10},"end":{"line":101,"column":null}},"loc":{"start":{"line":104,"column":10},"end":{"line":121,"column":null}},"line":104},"4":{"name":"(anonymous_4)","decl":{"start":{"line":130,"column":8},"end":{"line":130,"column":16}},"loc":{"start":{"line":130,"column":79},"end":{"line":199,"column":null}},"line":130},"5":{"name":"(anonymous_5)","decl":{"start":{"line":137,"column":8},"end":{"line":137,"column":9}},"loc":{"start":{"line":137,"column":18},"end":{"line":137,"column":null}},"line":137},"6":{"name":"(anonymous_6)","decl":{"start":{"line":140,"column":45},"end":{"line":140,"column":46}},"loc":{"start":{"line":140,"column":55},"end":{"line":145,"column":7}},"line":140},"7":{"name":"(anonymous_7)","decl":{"start":{"line":143,"column":10},"end":{"line":143,"column":11}},"loc":{"start":{"line":143,"column":19},"end":{"line":143,"column":null}},"line":143},"8":{"name":"(anonymous_8)","decl":{"start":{"line":152,"column":10},"end":{"line":152,"column":11}},"loc":{"start":{"line":152,"column":19},"end":{"line":152,"column":null}},"line":152},"9":{"name":"(anonymous_9)","decl":{"start":{"line":169,"column":45},"end":{"line":169,"column":46}},"loc":{"start":{"line":169,"column":52},"end":{"line":169,"column":72}},"line":169},"10":{"name":"(anonymous_10)","decl":{"start":{"line":170,"column":56},"end":{"line":170,"column":57}},"loc":{"start":{"line":170,"column":63},"end":{"line":170,"column":69}},"line":170},"11":{"name":"(anonymous_11)","decl":{"start":{"line":177,"column":23},"end":{"line":177,"column":30}},"loc":{"start":{"line":177,"column":39},"end":{"line":193,"column":9}},"line":177}},"branchMap":{"0":{"loc":{"start":{"line":69,"column":4},"end":{"line":73,"column":null}},"type":"if","locations":[{"start":{"line":69,"column":4},"end":{"line":73,"column":null}},{"start":{},"end":{}}],"line":69},"1":{"loc":{"start":{"line":89,"column":4},"end":{"line":93,"column":null}},"type":"if","locations":[{"start":{"line":89,"column":4},"end":{"line":93,"column":null}},{"start":{},"end":{}}],"line":89},"2":{"loc":{"start":{"line":108,"column":4},"end":{"line":120,"column":null}},"type":"if","locations":[{"start":{"line":108,"column":4},"end":{"line":120,"column":null}},{"start":{},"end":{}}],"line":108},"3":{"loc":{"start":{"line":137,"column":18},"end":{"line":137,"column":null}},"type":"binary-expr","locations":[{"start":{"line":137,"column":18},"end":{"line":137,"column":45}},{"start":{"line":137,"column":45},"end":{"line":137,"column":null}}],"line":137},"4":{"loc":{"start":{"line":141,"column":21},"end":{"line":141,"column":null}},"type":"binary-expr","locations":[{"start":{"line":141,"column":21},"end":{"line":141,"column":42}},{"start":{"line":141,"column":42},"end":{"line":141,"column":null}}],"line":141},"5":{"loc":{"start":{"line":143,"column":19},"end":{"line":143,"column":null}},"type":"binary-expr","locations":[{"start":{"line":143,"column":19},"end":{"line":143,"column":39}},{"start":{"line":143,"column":39},"end":{"line":143,"column":null}}],"line":143},"6":{"loc":{"start":{"line":149,"column":8},"end":{"line":149,"column":null}},"type":"if","locations":[{"start":{"line":149,"column":8},"end":{"line":149,"column":null}},{"start":{},"end":{}}],"line":149},"7":{"loc":{"start":{"line":150,"column":21},"end":{"line":150,"column":null}},"type":"binary-expr","locations":[{"start":{"line":150,"column":21},"end":{"line":150,"column":42}},{"start":{"line":150,"column":42},"end":{"line":150,"column":null}}],"line":150},"8":{"loc":{"start":{"line":152,"column":19},"end":{"line":152,"column":null}},"type":"binary-expr","locations":[{"start":{"line":152,"column":19},"end":{"line":152,"column":39}},{"start":{"line":152,"column":39},"end":{"line":152,"column":null}}],"line":152},"9":{"loc":{"start":{"line":154,"column":8},"end":{"line":161,"column":null}},"type":"if","locations":[{"start":{"line":154,"column":8},"end":{"line":161,"column":null}},{"start":{},"end":{}}],"line":154},"10":{"loc":{"start":{"line":164,"column":6},"end":{"line":174,"column":null}},"type":"if","locations":[{"start":{"line":164,"column":6},"end":{"line":174,"column":null}},{"start":{},"end":{}}],"line":164},"11":{"loc":{"start":{"line":165,"column":8},"end":{"line":167,"column":null}},"type":"binary-expr","locations":[{"start":{"line":165,"column":8},"end":{"line":165,"column":null}},{"start":{"line":166,"column":8},"end":{"line":166,"column":null}},{"start":{"line":167,"column":8},"end":{"line":167,"column":null}}],"line":165},"12":{"loc":{"start":{"line":186,"column":21},"end":{"line":186,"column":null}},"type":"cond-expr","locations":[{"start":{"line":186,"column":42},"end":{"line":186,"column":54}},{"start":{"line":186,"column":54},"end":{"line":186,"column":null}}],"line":186}},"s":{"0":19,"1":19,"2":19,"3":12,"4":11,"5":12,"6":2,"7":1,"8":94,"9":94,"10":13,"11":13,"12":13,"13":1,"14":18,"15":18,"16":18,"17":26,"18":80,"19":26,"20":57,"21":57,"22":42,"23":26,"24":57,"25":1,"26":56,"27":57,"28":45,"29":57,"30":7,"31":7,"32":7,"33":26,"34":3,"35":6,"36":3,"37":3,"38":3,"39":23,"40":27,"41":27,"42":27,"43":27,"44":25,"45":2,"46":27,"47":27,"48":27,"49":15,"50":15},"f":{"0":19,"1":12,"2":2,"3":94,"4":18,"5":80,"6":57,"7":42,"8":45,"9":6,"10":3,"11":27},"b":{"0":[11,1],"1":[1,1],"2":[13,81],"3":[80,57],"4":[57,19],"5":[42,19],"6":[1,56],"7":[56,19],"8":[45,19],"9":[7,50],"10":[3,23],"11":[26,6,6],"12":[1,1]},"meta":{"lastBranch":13,"lastFunction":12,"lastStatement":51,"seen":{"s:52:20:52:Infinity":0,"s:53:45:53:Infinity":1,"f:58:2:58:22":0,"s:58:22:58:41":2,"f:65:9:65:Infinity":1,"b:69:4:73:Infinity:undefined:undefined:undefined:undefined":0,"s:69:4:73:Infinity":3,"s:72:6:72:Infinity":4,"s:75:5:77:Infinity":5,"f:85:9:85:Infinity":2,"b:89:4:93:Infinity:undefined:undefined:undefined:undefined":1,"s:89:4:93:Infinity":6,"s:90:7:92:Infinity":7,"f:101:10:101:Infinity":3,"s:105:22:105:Infinity":8,"b:108:4:120:Infinity:undefined:undefined:undefined:undefined":2,"s:108:4:120:Infinity":9,"s:109:6:119:Infinity":10,"s:110:8:118:Infinity":11,"s:111:10:111:Infinity":12,"s:114:10:117:Infinity":13,"f:130:8:130:16":4,"s:131:4:131:Infinity":14,"s:133:20:133:Infinity":15,"s:135:4:195:Infinity":16,"s:136:27:138:Infinity":17,"f:137:8:137:9":5,"s:137:18:137:Infinity":18,"b:137:18:137:45:137:45:137:Infinity":3,"s:140:25:145:Infinity":19,"f:140:45:140:46":6,"s:141:21:141:Infinity":20,"b:141:21:141:42:141:42:141:Infinity":4,"s:142:8:144:Infinity":21,"f:143:10:143:11":7,"s:143:19:143:Infinity":22,"b:143:19:143:39:143:39:143:Infinity":5,"s:148:6:162:Infinity":23,"b:149:8:149:Infinity:undefined:undefined:undefined:undefined":6,"s:149:8:149:Infinity":24,"s:149:36:149:Infinity":25,"s:150:21:150:Infinity":26,"b:150:21:150:42:150:42:150:Infinity":7,"s:151:26:153:Infinity":27,"f:152:10:152:11":8,"s:152:19:152:Infinity":28,"b:152:19:152:39:152:39:152:Infinity":8,"b:154:8:161:Infinity:undefined:undefined:undefined:undefined":9,"s:154:8:161:Infinity":29,"s:155:37:158:Infinity":30,"s:159:10:159:Infinity":31,"s:160:10:160:Infinity":32,"b:164:6:174:Infinity:undefined:undefined:undefined:undefined":10,"s:164:6:174:Infinity":33,"b:165:8:165:Infinity:166:8:166:Infinity:167:8:167:Infinity":11,"s:169:32:169:Infinity":34,"f:169:45:169:46":9,"s:169:52:169:72":35,"s:170:36:170:Infinity":36,"f:170:56:170:57":10,"s:170:63:170:69":37,"s:171:8:173:Infinity":38,"s:176:6:194:Infinity":39,"f:177:23:177:30":11,"s:178:10:178:Infinity":40,"s:179:10:179:Infinity":41,"s:180:10:192:Infinity":42,"s:181:27:181:Infinity":43,"s:182:12:182:Infinity":44,"s:184:12:187:Infinity":45,"b:186:42:186:54:186:54:186:Infinity":12,"s:189:12:189:Infinity":46,"s:190:27:190:Infinity":47,"s:191:12:191:Infinity":48,"s:197:4:197:Infinity":49,"s:198:4:198:Infinity":50}}}
|
|
2
2
|
}
|
package/coverage/index.html
CHANGED
|
@@ -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'>51/51</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'>27/27</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'>12/12</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'>48/48</span>
|
|
50
50
|
</div>
|
|
51
51
|
|
|
52
52
|
|
|
@@ -84,13 +84,13 @@
|
|
|
84
84
|
<div class="chart"><div class="cover-fill cover-full" style="width: 100%"></div><div class="cover-empty" style="width: 0%"></div></div>
|
|
85
85
|
</td>
|
|
86
86
|
<td data-value="100" class="pct high">100%</td>
|
|
87
|
-
<td data-value="
|
|
87
|
+
<td data-value="51" class="abs high">51/51</td>
|
|
88
88
|
<td data-value="100" class="pct high">100%</td>
|
|
89
|
-
<td data-value="
|
|
89
|
+
<td data-value="27" class="abs high">27/27</td>
|
|
90
90
|
<td data-value="100" class="pct high">100%</td>
|
|
91
|
-
<td data-value="
|
|
91
|
+
<td data-value="12" class="abs high">12/12</td>
|
|
92
92
|
<td data-value="100" class="pct high">100%</td>
|
|
93
|
-
<td data-value="
|
|
93
|
+
<td data-value="48" class="abs high">48/48</td>
|
|
94
94
|
</tr>
|
|
95
95
|
|
|
96
96
|
</tbody>
|
|
@@ -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-18T01:05:27.353Z
|
|
105
105
|
</div>
|
|
106
106
|
<script src="prettify.js"></script>
|
|
107
107
|
<script>
|
package/dist/TaskRunner.d.ts
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
import { TaskStep } from "./TaskStep.js";
|
|
2
2
|
import { TaskResult } from "./TaskResult.js";
|
|
3
|
+
/**
|
|
4
|
+
* Define the payload for every possible event in the lifecycle.
|
|
5
|
+
*/
|
|
6
|
+
export interface RunnerEventPayloads<TContext> {
|
|
7
|
+
workflowStart: {
|
|
8
|
+
context: TContext;
|
|
9
|
+
steps: TaskStep<TContext>[];
|
|
10
|
+
};
|
|
11
|
+
workflowEnd: {
|
|
12
|
+
context: TContext;
|
|
13
|
+
results: Map<string, TaskResult>;
|
|
14
|
+
};
|
|
15
|
+
taskStart: {
|
|
16
|
+
step: TaskStep<TContext>;
|
|
17
|
+
};
|
|
18
|
+
taskEnd: {
|
|
19
|
+
step: TaskStep<TContext>;
|
|
20
|
+
result: TaskResult;
|
|
21
|
+
};
|
|
22
|
+
taskSkipped: {
|
|
23
|
+
step: TaskStep<TContext>;
|
|
24
|
+
result: TaskResult;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* A generic listener type that maps the event key to its specific payload.
|
|
29
|
+
*/
|
|
30
|
+
export type RunnerEventListener<TContext, K extends keyof RunnerEventPayloads<TContext>> = (data: RunnerEventPayloads<TContext>[K]) => void | Promise<void>;
|
|
3
31
|
/**
|
|
4
32
|
* The main class that orchestrates the execution of a list of tasks
|
|
5
33
|
* based on their dependencies, with support for parallel execution.
|
|
@@ -8,10 +36,29 @@ import { TaskResult } from "./TaskResult.js";
|
|
|
8
36
|
export declare class TaskRunner<TContext> {
|
|
9
37
|
private context;
|
|
10
38
|
private running;
|
|
39
|
+
private listeners;
|
|
11
40
|
/**
|
|
12
41
|
* @param context The shared context object to be passed to each task.
|
|
13
42
|
*/
|
|
14
43
|
constructor(context: TContext);
|
|
44
|
+
/**
|
|
45
|
+
* Subscribe to an event.
|
|
46
|
+
* @param event The event name.
|
|
47
|
+
* @param callback The callback to execute when the event is emitted.
|
|
48
|
+
*/
|
|
49
|
+
on<K extends keyof RunnerEventPayloads<TContext>>(event: K, callback: RunnerEventListener<TContext, K>): void;
|
|
50
|
+
/**
|
|
51
|
+
* Unsubscribe from an event.
|
|
52
|
+
* @param event The event name.
|
|
53
|
+
* @param callback The callback to remove.
|
|
54
|
+
*/
|
|
55
|
+
off<K extends keyof RunnerEventPayloads<TContext>>(event: K, callback: RunnerEventListener<TContext, K>): void;
|
|
56
|
+
/**
|
|
57
|
+
* Emit an event to all subscribers.
|
|
58
|
+
* @param event The event name.
|
|
59
|
+
* @param data The payload for the event.
|
|
60
|
+
*/
|
|
61
|
+
private emit;
|
|
15
62
|
/**
|
|
16
63
|
* Executes a list of tasks, respecting their dependencies and running
|
|
17
64
|
* independent tasks in parallel.
|
package/dist/TaskRunner.js
CHANGED
|
@@ -6,12 +6,56 @@
|
|
|
6
6
|
export class TaskRunner {
|
|
7
7
|
context;
|
|
8
8
|
running = new Set();
|
|
9
|
+
listeners = {};
|
|
9
10
|
/**
|
|
10
11
|
* @param context The shared context object to be passed to each task.
|
|
11
12
|
*/
|
|
12
13
|
constructor(context) {
|
|
13
14
|
this.context = context;
|
|
14
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* Subscribe to an event.
|
|
18
|
+
* @param event The event name.
|
|
19
|
+
* @param callback The callback to execute when the event is emitted.
|
|
20
|
+
*/
|
|
21
|
+
on(event, callback) {
|
|
22
|
+
if (!this.listeners[event]) {
|
|
23
|
+
// Type assertion needed because TypeScript cannot verify that the generic K
|
|
24
|
+
// matches the specific key in the mapped type during assignment.
|
|
25
|
+
this.listeners[event] = new Set();
|
|
26
|
+
}
|
|
27
|
+
// Type assertion needed to tell TS that this specific Set matches the callback type
|
|
28
|
+
this.listeners[event].add(callback);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Unsubscribe from an event.
|
|
32
|
+
* @param event The event name.
|
|
33
|
+
* @param callback The callback to remove.
|
|
34
|
+
*/
|
|
35
|
+
off(event, callback) {
|
|
36
|
+
if (this.listeners[event]) {
|
|
37
|
+
this.listeners[event].delete(callback);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Emit an event to all subscribers.
|
|
42
|
+
* @param event The event name.
|
|
43
|
+
* @param data The payload for the event.
|
|
44
|
+
*/
|
|
45
|
+
emit(event, data) {
|
|
46
|
+
const listeners = this.listeners[event];
|
|
47
|
+
if (listeners) {
|
|
48
|
+
for (const listener of listeners) {
|
|
49
|
+
try {
|
|
50
|
+
listener(data);
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
// Prevent listener errors from bubbling up
|
|
54
|
+
console.error(`Error in event listener for ${String(event)}:`, error);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
15
59
|
/**
|
|
16
60
|
* Executes a list of tasks, respecting their dependencies and running
|
|
17
61
|
* independent tasks in parallel.
|
|
@@ -20,6 +64,7 @@ export class TaskRunner {
|
|
|
20
64
|
* and values are the corresponding TaskResult objects.
|
|
21
65
|
*/
|
|
22
66
|
async execute(steps) {
|
|
67
|
+
this.emit("workflowStart", { context: this.context, steps });
|
|
23
68
|
const results = new Map();
|
|
24
69
|
while (results.size < steps.length) {
|
|
25
70
|
const pendingSteps = steps.filter((step) => !results.has(step.name) && !this.running.has(step.name));
|
|
@@ -34,10 +79,12 @@ export class TaskRunner {
|
|
|
34
79
|
const deps = step.dependencies ?? [];
|
|
35
80
|
const failedDep = deps.find((dep) => results.has(dep) && results.get(dep)?.status !== "success");
|
|
36
81
|
if (failedDep) {
|
|
37
|
-
|
|
82
|
+
const result = {
|
|
38
83
|
status: "skipped",
|
|
39
84
|
message: `Skipped due to failed dependency: ${failedDep}`,
|
|
40
|
-
}
|
|
85
|
+
};
|
|
86
|
+
results.set(step.name, result);
|
|
87
|
+
this.emit("taskSkipped", { step, result });
|
|
41
88
|
}
|
|
42
89
|
}
|
|
43
90
|
if (readySteps.length === 0 &&
|
|
@@ -49,6 +96,7 @@ export class TaskRunner {
|
|
|
49
96
|
}
|
|
50
97
|
await Promise.all(readySteps.map(async (step) => {
|
|
51
98
|
this.running.add(step.name);
|
|
99
|
+
this.emit("taskStart", { step });
|
|
52
100
|
try {
|
|
53
101
|
const result = await step.run(this.context);
|
|
54
102
|
results.set(step.name, result);
|
|
@@ -61,9 +109,12 @@ export class TaskRunner {
|
|
|
61
109
|
}
|
|
62
110
|
finally {
|
|
63
111
|
this.running.delete(step.name);
|
|
112
|
+
const result = results.get(step.name);
|
|
113
|
+
this.emit("taskEnd", { step, result });
|
|
64
114
|
}
|
|
65
115
|
}));
|
|
66
116
|
}
|
|
117
|
+
this.emit("workflowEnd", { context: this.context, results });
|
|
67
118
|
return results;
|
|
68
119
|
}
|
|
69
120
|
}
|
package/dist/TaskRunner.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TaskRunner.js","sourceRoot":"","sources":["../src/TaskRunner.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TaskRunner.js","sourceRoot":"","sources":["../src/TaskRunner.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@calmo/task-runner",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"type": "module",
|
|
18
18
|
"scripts": {
|
|
19
19
|
"build": "tsc",
|
|
20
|
-
"test": "vitest run --coverage",
|
|
20
|
+
"test": "tsc --noEmit -p tsconfig.test.json && vitest run --coverage",
|
|
21
21
|
"lint": "eslint .",
|
|
22
22
|
"lint:fix": "eslint . --fix",
|
|
23
23
|
"format": "prettier --write .",
|
package/src/TaskRunner.ts
CHANGED
|
@@ -1,6 +1,48 @@
|
|
|
1
1
|
import { TaskStep } from "./TaskStep.js";
|
|
2
2
|
import { TaskResult } from "./TaskResult.js";
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Define the payload for every possible event in the lifecycle.
|
|
6
|
+
*/
|
|
7
|
+
export interface RunnerEventPayloads<TContext> {
|
|
8
|
+
workflowStart: {
|
|
9
|
+
context: TContext;
|
|
10
|
+
steps: TaskStep<TContext>[];
|
|
11
|
+
};
|
|
12
|
+
workflowEnd: {
|
|
13
|
+
context: TContext;
|
|
14
|
+
results: Map<string, TaskResult>;
|
|
15
|
+
};
|
|
16
|
+
taskStart: {
|
|
17
|
+
step: TaskStep<TContext>;
|
|
18
|
+
};
|
|
19
|
+
taskEnd: {
|
|
20
|
+
step: TaskStep<TContext>;
|
|
21
|
+
result: TaskResult;
|
|
22
|
+
};
|
|
23
|
+
taskSkipped: {
|
|
24
|
+
step: TaskStep<TContext>;
|
|
25
|
+
result: TaskResult;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* A generic listener type that maps the event key to its specific payload.
|
|
31
|
+
*/
|
|
32
|
+
export type RunnerEventListener<
|
|
33
|
+
TContext,
|
|
34
|
+
K extends keyof RunnerEventPayloads<TContext>,
|
|
35
|
+
> = (data: RunnerEventPayloads<TContext>[K]) => void | Promise<void>;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Helper type for the listeners map to avoid private access issues in generic contexts.
|
|
39
|
+
*/
|
|
40
|
+
type ListenerMap<TContext> = {
|
|
41
|
+
[K in keyof RunnerEventPayloads<TContext>]?: Set<
|
|
42
|
+
RunnerEventListener<TContext, K>
|
|
43
|
+
>;
|
|
44
|
+
};
|
|
45
|
+
|
|
4
46
|
/**
|
|
5
47
|
* The main class that orchestrates the execution of a list of tasks
|
|
6
48
|
* based on their dependencies, with support for parallel execution.
|
|
@@ -8,12 +50,76 @@ import { TaskResult } from "./TaskResult.js";
|
|
|
8
50
|
*/
|
|
9
51
|
export class TaskRunner<TContext> {
|
|
10
52
|
private running = new Set<string>();
|
|
53
|
+
private listeners: ListenerMap<TContext> = {};
|
|
11
54
|
|
|
12
55
|
/**
|
|
13
56
|
* @param context The shared context object to be passed to each task.
|
|
14
57
|
*/
|
|
15
58
|
constructor(private context: TContext) {}
|
|
16
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Subscribe to an event.
|
|
62
|
+
* @param event The event name.
|
|
63
|
+
* @param callback The callback to execute when the event is emitted.
|
|
64
|
+
*/
|
|
65
|
+
public on<K extends keyof RunnerEventPayloads<TContext>>(
|
|
66
|
+
event: K,
|
|
67
|
+
callback: RunnerEventListener<TContext, K>
|
|
68
|
+
): void {
|
|
69
|
+
if (!this.listeners[event]) {
|
|
70
|
+
// Type assertion needed because TypeScript cannot verify that the generic K
|
|
71
|
+
// matches the specific key in the mapped type during assignment.
|
|
72
|
+
this.listeners[event] = new Set() as unknown as ListenerMap<TContext>[K];
|
|
73
|
+
}
|
|
74
|
+
// Type assertion needed to tell TS that this specific Set matches the callback type
|
|
75
|
+
(this.listeners[event] as Set<RunnerEventListener<TContext, K>>).add(
|
|
76
|
+
callback
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Unsubscribe from an event.
|
|
82
|
+
* @param event The event name.
|
|
83
|
+
* @param callback The callback to remove.
|
|
84
|
+
*/
|
|
85
|
+
public off<K extends keyof RunnerEventPayloads<TContext>>(
|
|
86
|
+
event: K,
|
|
87
|
+
callback: RunnerEventListener<TContext, K>
|
|
88
|
+
): void {
|
|
89
|
+
if (this.listeners[event]) {
|
|
90
|
+
(this.listeners[event] as Set<RunnerEventListener<TContext, K>>).delete(
|
|
91
|
+
callback
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Emit an event to all subscribers.
|
|
98
|
+
* @param event The event name.
|
|
99
|
+
* @param data The payload for the event.
|
|
100
|
+
*/
|
|
101
|
+
private emit<K extends keyof RunnerEventPayloads<TContext>>(
|
|
102
|
+
event: K,
|
|
103
|
+
data: RunnerEventPayloads<TContext>[K]
|
|
104
|
+
): void {
|
|
105
|
+
const listeners = this.listeners[event] as
|
|
106
|
+
| Set<RunnerEventListener<TContext, K>>
|
|
107
|
+
| undefined;
|
|
108
|
+
if (listeners) {
|
|
109
|
+
for (const listener of listeners) {
|
|
110
|
+
try {
|
|
111
|
+
listener(data);
|
|
112
|
+
} catch (error) {
|
|
113
|
+
// Prevent listener errors from bubbling up
|
|
114
|
+
console.error(
|
|
115
|
+
`Error in event listener for ${String(event)}:`,
|
|
116
|
+
error
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
17
123
|
/**
|
|
18
124
|
* Executes a list of tasks, respecting their dependencies and running
|
|
19
125
|
* independent tasks in parallel.
|
|
@@ -22,6 +128,8 @@ export class TaskRunner<TContext> {
|
|
|
22
128
|
* and values are the corresponding TaskResult objects.
|
|
23
129
|
*/
|
|
24
130
|
async execute(steps: TaskStep<TContext>[]): Promise<Map<string, TaskResult>> {
|
|
131
|
+
this.emit("workflowStart", { context: this.context, steps });
|
|
132
|
+
|
|
25
133
|
const results = new Map<string, TaskResult>();
|
|
26
134
|
|
|
27
135
|
while (results.size < steps.length) {
|
|
@@ -44,10 +152,12 @@ export class TaskRunner<TContext> {
|
|
|
44
152
|
(dep) => results.has(dep) && results.get(dep)?.status !== "success"
|
|
45
153
|
);
|
|
46
154
|
if (failedDep) {
|
|
47
|
-
|
|
155
|
+
const result: TaskResult = {
|
|
48
156
|
status: "skipped",
|
|
49
157
|
message: `Skipped due to failed dependency: ${failedDep}`,
|
|
50
|
-
}
|
|
158
|
+
};
|
|
159
|
+
results.set(step.name, result);
|
|
160
|
+
this.emit("taskSkipped", { step, result });
|
|
51
161
|
}
|
|
52
162
|
}
|
|
53
163
|
|
|
@@ -66,6 +176,7 @@ export class TaskRunner<TContext> {
|
|
|
66
176
|
await Promise.all(
|
|
67
177
|
readySteps.map(async (step) => {
|
|
68
178
|
this.running.add(step.name);
|
|
179
|
+
this.emit("taskStart", { step });
|
|
69
180
|
try {
|
|
70
181
|
const result = await step.run(this.context);
|
|
71
182
|
results.set(step.name, result);
|
|
@@ -76,11 +187,14 @@ export class TaskRunner<TContext> {
|
|
|
76
187
|
});
|
|
77
188
|
} finally {
|
|
78
189
|
this.running.delete(step.name);
|
|
190
|
+
const result = results.get(step.name)!;
|
|
191
|
+
this.emit("taskEnd", { step, result });
|
|
79
192
|
}
|
|
80
193
|
})
|
|
81
194
|
);
|
|
82
195
|
}
|
|
83
196
|
|
|
197
|
+
this.emit("workflowEnd", { context: this.context, results });
|
|
84
198
|
return results;
|
|
85
199
|
}
|
|
86
200
|
}
|