codehooks-js 1.3.15 → 1.3.17
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/package.json +1 -1
- package/types/index.d.ts +30 -0
- package/types/workflow/engine.d.mts +18 -0
- package/workflow/engine.mjs +76 -49
package/package.json
CHANGED
package/types/index.d.ts
CHANGED
|
@@ -513,6 +513,10 @@ export type httpRequest = {
|
|
|
513
513
|
* - JSON payload
|
|
514
514
|
*/
|
|
515
515
|
body: any;
|
|
516
|
+
/**
|
|
517
|
+
* - Get the raw unparsed request body as a string
|
|
518
|
+
*/
|
|
519
|
+
rawBody: string;
|
|
516
520
|
/**
|
|
517
521
|
* - Get the URL full path, e.g. /dev/myroute
|
|
518
522
|
*/
|
|
@@ -622,6 +626,11 @@ export type httpResponse = {
|
|
|
622
626
|
|
|
623
627
|
export type nextFunction = (error?: string) => void;
|
|
624
628
|
|
|
629
|
+
// Aliases for developers familiar with Express.js conventions
|
|
630
|
+
export type Request = httpRequest;
|
|
631
|
+
export type Response = httpResponse;
|
|
632
|
+
export type NextFunction = nextFunction;
|
|
633
|
+
|
|
625
634
|
export type Filesystem = {
|
|
626
635
|
/**
|
|
627
636
|
* - Get binary file input stream. Takes a path (string) to file (e.g. /static/logo.png) and an options object (Object) for future use. Returns a Promise resolving to a binary data stream emitter.
|
|
@@ -1309,6 +1318,27 @@ export type Workflow = {
|
|
|
1309
1318
|
*/
|
|
1310
1319
|
cancelSteps: (id: string) => Promise<any>;
|
|
1311
1320
|
|
|
1321
|
+
/**
|
|
1322
|
+
* Get the status of a workflow instance (alias for getStepsStatus)
|
|
1323
|
+
* @param id - ID of the workflow instance
|
|
1324
|
+
* @returns Promise with the workflow status
|
|
1325
|
+
*/
|
|
1326
|
+
getWorkflowStatus: (id: string) => Promise<any>;
|
|
1327
|
+
|
|
1328
|
+
/**
|
|
1329
|
+
* Get the state of a workflow instance (alias for getStepsStatus)
|
|
1330
|
+
* @param id - ID of the workflow instance
|
|
1331
|
+
* @returns Promise with the workflow state
|
|
1332
|
+
*/
|
|
1333
|
+
getState: (id: string) => Promise<any>;
|
|
1334
|
+
|
|
1335
|
+
/**
|
|
1336
|
+
* Cancel a workflow instance (alias for cancelSteps)
|
|
1337
|
+
* @param id - ID of the workflow instance to cancel
|
|
1338
|
+
* @returns Promise with the cancellation result
|
|
1339
|
+
*/
|
|
1340
|
+
cancelWorkflow: (id: string) => Promise<any>;
|
|
1341
|
+
|
|
1312
1342
|
/**
|
|
1313
1343
|
* Register an event listener
|
|
1314
1344
|
* @param event - Name of the event to listen for
|
|
@@ -117,5 +117,23 @@ declare class StepsEngine {
|
|
|
117
117
|
* @returns {Promise<Object>} The cancellation result
|
|
118
118
|
*/
|
|
119
119
|
cancelSteps(id: string): Promise<any>;
|
|
120
|
+
/**
|
|
121
|
+
* Get the status of a workflow instance (alias for getStepsStatus)
|
|
122
|
+
* @param {string} id - ID of the workflow instance
|
|
123
|
+
* @returns {Promise<Object>} The workflow status
|
|
124
|
+
*/
|
|
125
|
+
getWorkflowStatus(id: string): Promise<any>;
|
|
126
|
+
/**
|
|
127
|
+
* Get the state of a workflow instance (alias for getStepsStatus)
|
|
128
|
+
* @param {string} id - ID of the workflow instance
|
|
129
|
+
* @returns {Promise<Object>} The workflow state
|
|
130
|
+
*/
|
|
131
|
+
getState(id: string): Promise<any>;
|
|
132
|
+
/**
|
|
133
|
+
* Cancel a workflow instance (alias for cancelSteps)
|
|
134
|
+
* @param {string} id - ID of the workflow instance to cancel
|
|
135
|
+
* @returns {Promise<Object>} The cancellation result
|
|
136
|
+
*/
|
|
137
|
+
cancelWorkflow(id: string): Promise<any>;
|
|
120
138
|
}
|
|
121
139
|
//# sourceMappingURL=engine.d.mts.map
|
package/workflow/engine.mjs
CHANGED
|
@@ -38,7 +38,7 @@ class Workflow extends EventEmitter {
|
|
|
38
38
|
this.#definitions = new Map();
|
|
39
39
|
this.#name = name;
|
|
40
40
|
this.#description = description;
|
|
41
|
-
|
|
41
|
+
|
|
42
42
|
// Apply any configuration options
|
|
43
43
|
if (options) {
|
|
44
44
|
this.configure(options);
|
|
@@ -120,7 +120,7 @@ class Workflow extends EventEmitter {
|
|
|
120
120
|
* @throws {Error} If maxStepCount is not a positive number
|
|
121
121
|
*/
|
|
122
122
|
setMaxStepCount(maxStepCount) {
|
|
123
|
-
if (typeof maxStepCount !== 'number' || maxStepCount <= 0) {
|
|
123
|
+
if (typeof maxStepCount !== 'number' || maxStepCount <= 0) {
|
|
124
124
|
throw new Error('Maximum step count must be a positive number');
|
|
125
125
|
}
|
|
126
126
|
this.#maxStepCount = maxStepCount;
|
|
@@ -226,13 +226,13 @@ class Workflow extends EventEmitter {
|
|
|
226
226
|
* @throws {Error} If step execution fails
|
|
227
227
|
*/
|
|
228
228
|
async handleNextStep(stepsName, nextStep, newState, instanceId, options) {
|
|
229
|
-
|
|
229
|
+
|
|
230
230
|
// open the connection to the database
|
|
231
|
-
const connection = await DB.open();
|
|
231
|
+
const connection = await DB.open();
|
|
232
232
|
|
|
233
233
|
// Handle single next step
|
|
234
234
|
this.emit('stepStarted', { workflowName: stepsName, step: nextStep, state: newState, instanceId });
|
|
235
|
-
|
|
235
|
+
|
|
236
236
|
// remove the _id from the newState
|
|
237
237
|
delete newState._id;
|
|
238
238
|
// increment the step count
|
|
@@ -247,9 +247,9 @@ class Workflow extends EventEmitter {
|
|
|
247
247
|
newState = await connection.updateOne(this.#collectionName,
|
|
248
248
|
{ _id: instanceId },
|
|
249
249
|
{ $set: { ...newState, nextStep: nextStep, updatedAt: new Date().toISOString(), stepCount: newState.stepCount } });
|
|
250
|
-
|
|
251
|
-
this.emit('stateUpdated', { workflowName: stepsName, state: newState, instanceId });
|
|
252
|
-
|
|
250
|
+
|
|
251
|
+
this.emit('stateUpdated', { workflowName: stepsName, state: newState, instanceId });
|
|
252
|
+
|
|
253
253
|
try {
|
|
254
254
|
// Get the next step function
|
|
255
255
|
const func = this.getDefinition(stepsName, nextStep);
|
|
@@ -267,14 +267,14 @@ class Workflow extends EventEmitter {
|
|
|
267
267
|
console.debug('waiter', state);
|
|
268
268
|
await connection.updateOne(this.#collectionName,
|
|
269
269
|
{ _id: instanceId },
|
|
270
|
-
{ $set: { ...state, updatedAt: new Date().toISOString() } });
|
|
270
|
+
{ $set: { ...state, updatedAt: new Date().toISOString() } });
|
|
271
271
|
resolve();
|
|
272
272
|
return;
|
|
273
273
|
} else {
|
|
274
274
|
resolve(); // no state update
|
|
275
275
|
}
|
|
276
276
|
}
|
|
277
|
-
await func({...newState, instanceId: newState._id}, async (nextStep, userState, options) => {
|
|
277
|
+
await func({ ...newState, instanceId: newState._id }, async (nextStep, userState, options) => {
|
|
278
278
|
try {
|
|
279
279
|
// Protect system-level properties
|
|
280
280
|
const protectedState = {
|
|
@@ -288,7 +288,7 @@ class Workflow extends EventEmitter {
|
|
|
288
288
|
parallelSteps: newState.parallelSteps,
|
|
289
289
|
previousStep: newState.nextStep
|
|
290
290
|
};
|
|
291
|
-
|
|
291
|
+
|
|
292
292
|
// Merge states with userState taking precedence, but protecting system fields
|
|
293
293
|
const mergedState = {
|
|
294
294
|
...userState,
|
|
@@ -302,14 +302,14 @@ class Workflow extends EventEmitter {
|
|
|
302
302
|
// update the parallel steps metadata
|
|
303
303
|
if (mergedState.parallelSteps && mergedState.parallelSteps[mergedState.nextStep]) {
|
|
304
304
|
// get a fresh copy of the parallel steps
|
|
305
|
-
const fresh = await connection.findOne(this.#collectionName, { _id: instanceId });
|
|
305
|
+
const fresh = await connection.findOne(this.#collectionName, { _id: instanceId });
|
|
306
306
|
fresh.parallelSteps[mergedState.nextStep].done = true;
|
|
307
307
|
fresh.parallelSteps[mergedState.nextStep].nextStep = nextStep;
|
|
308
308
|
//fresh.parallelSteps[mergedState.nextStep].previousStep = mergedState.previousStep || null;
|
|
309
309
|
delete fresh._id;
|
|
310
310
|
const updated = await connection.updateOne(this.#collectionName,
|
|
311
311
|
{ _id: instanceId },
|
|
312
|
-
{ $set: { ...fresh, parallelSteps: fresh.parallelSteps } });
|
|
312
|
+
{ $set: { ...fresh, parallelSteps: fresh.parallelSteps } });
|
|
313
313
|
//console.debug('updated', updated.parallelSteps);
|
|
314
314
|
mergedState.parallelSteps = fresh.parallelSteps;
|
|
315
315
|
// Check if all parallel steps are done
|
|
@@ -335,12 +335,12 @@ class Workflow extends EventEmitter {
|
|
|
335
335
|
if (nextStep === null) {
|
|
336
336
|
delete mergedState._id;
|
|
337
337
|
const completionTime = (new Date(mergedState.updatedAt) - new Date(mergedState.createdAt));
|
|
338
|
-
|
|
338
|
+
|
|
339
339
|
const finalresult = await connection.updateOne(this.#collectionName,
|
|
340
340
|
{ _id: instanceId },
|
|
341
|
-
{ $set: { ...mergedState, nextStep: null, updatedAt: new Date().toISOString(), totalTime: completionTime } });
|
|
341
|
+
{ $set: { ...mergedState, nextStep: null, updatedAt: new Date().toISOString(), totalTime: completionTime } });
|
|
342
342
|
console.log(`Workflow ${stepsName} ${instanceId} is completed in time: ${completionTime / 1000}s 🎉`);
|
|
343
|
-
this.emit('completed', { ...finalresult});
|
|
343
|
+
this.emit('completed', { ...finalresult });
|
|
344
344
|
resolve();
|
|
345
345
|
return;
|
|
346
346
|
}
|
|
@@ -370,13 +370,13 @@ class Workflow extends EventEmitter {
|
|
|
370
370
|
} else {
|
|
371
371
|
console.debug('enqueue step', nextStep, instanceId);
|
|
372
372
|
await connection.enqueue(`${this.#queuePrefix}_${stepsName}_${nextStep}`, {
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
}
|
|
373
|
+
stepsName: stepsName,
|
|
374
|
+
goto: nextStep,
|
|
375
|
+
state: mergedState,
|
|
376
|
+
options: options,
|
|
377
|
+
instanceId: instanceId
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
380
|
this.emit('stepEnqueued', { workflowName: stepsName, step: nextStep, state: newState, instanceId });
|
|
381
381
|
resolve();
|
|
382
382
|
} catch (error) {
|
|
@@ -393,7 +393,7 @@ class Workflow extends EventEmitter {
|
|
|
393
393
|
} catch (error) {
|
|
394
394
|
console.error('error in handleNextStep outer', error.message);
|
|
395
395
|
throw error;
|
|
396
|
-
}
|
|
396
|
+
}
|
|
397
397
|
}
|
|
398
398
|
|
|
399
399
|
/**
|
|
@@ -424,15 +424,15 @@ class Workflow extends EventEmitter {
|
|
|
424
424
|
* @private
|
|
425
425
|
*/
|
|
426
426
|
async registerWithApp(app, name, description, definition) {
|
|
427
|
-
this.emit('workflowCreated', { name, description });
|
|
427
|
+
this.emit('workflowCreated', { name, description });
|
|
428
428
|
|
|
429
429
|
// Validate each step in the definition
|
|
430
430
|
for (const [stepName, step] of Object.entries(definition)) {
|
|
431
431
|
try {
|
|
432
432
|
if (stepName !== undefined) {
|
|
433
433
|
console.debug('registering queue for step', `${this.#queuePrefix}_${name}_${stepName}`);
|
|
434
|
-
app.worker(`${this.#queuePrefix}_${name}_${stepName}`, async (req, res) => {
|
|
435
|
-
try {
|
|
434
|
+
app.worker(`${this.#queuePrefix}_${name}_${stepName}`, async (req, res) => {
|
|
435
|
+
try {
|
|
436
436
|
const { stepsName, goto, state, instanceId, options } = req.body.payload;
|
|
437
437
|
console.debug('dequeue step', stepName, instanceId);
|
|
438
438
|
const qid = await this.handleNextStep(stepsName, goto, state, instanceId, options);
|
|
@@ -460,7 +460,7 @@ class Workflow extends EventEmitter {
|
|
|
460
460
|
}
|
|
461
461
|
|
|
462
462
|
// Store the definition
|
|
463
|
-
this.#definitions.set(name, definition);
|
|
463
|
+
this.#definitions.set(name, definition);
|
|
464
464
|
|
|
465
465
|
return name;
|
|
466
466
|
}
|
|
@@ -472,13 +472,13 @@ class Workflow extends EventEmitter {
|
|
|
472
472
|
* @throws {Error} If starting steps fails
|
|
473
473
|
*/
|
|
474
474
|
async start(initialState) {
|
|
475
|
-
this.emit('workflowStarted', { name: this.#name, initialState });
|
|
475
|
+
this.emit('workflowStarted', { name: this.#name, initialState });
|
|
476
476
|
|
|
477
477
|
return new Promise(async (resolve, reject) => {
|
|
478
478
|
try {
|
|
479
479
|
console.debug('Starting workflow', this.#name);
|
|
480
480
|
const funcs = this.#definitions.get(this.#name);
|
|
481
|
-
|
|
481
|
+
|
|
482
482
|
if (!funcs) {
|
|
483
483
|
reject(new Error(`No workflow definition found for: ${this.#name}`));
|
|
484
484
|
return;
|
|
@@ -486,7 +486,7 @@ class Workflow extends EventEmitter {
|
|
|
486
486
|
|
|
487
487
|
const firstStepName = Object.keys(funcs)[0];
|
|
488
488
|
const firstStep = funcs[firstStepName];
|
|
489
|
-
|
|
489
|
+
|
|
490
490
|
if (!firstStep) {
|
|
491
491
|
reject(new Error('No start step defined in workflow'));
|
|
492
492
|
return;
|
|
@@ -495,7 +495,7 @@ class Workflow extends EventEmitter {
|
|
|
495
495
|
const connection = await DB.open();
|
|
496
496
|
// Create a new workflow state in the database
|
|
497
497
|
const newState = await connection.insertOne(this.#collectionName,
|
|
498
|
-
{ ...initialState, nextStep: firstStepName, createdAt: new Date().toISOString(), workflowName: this.#name, stepCount: {
|
|
498
|
+
{ ...initialState, nextStep: firstStepName, createdAt: new Date().toISOString(), workflowName: this.#name, stepCount: {} });
|
|
499
499
|
const { _id: ID } = await connection.enqueue(`${this.#queuePrefix}_${this.#name}_${firstStepName}`, {
|
|
500
500
|
stepsName: this.#name,
|
|
501
501
|
goto: firstStepName,
|
|
@@ -518,17 +518,17 @@ class Workflow extends EventEmitter {
|
|
|
518
518
|
* @param {Object} options - Options for the update, { continue: false } to avoid continuing the the step
|
|
519
519
|
* @returns {Promise<Object>} The updated state
|
|
520
520
|
*/
|
|
521
|
-
async updateState(instanceId, state, options={continue: true}) {
|
|
521
|
+
async updateState(instanceId, state, options = { continue: true }) {
|
|
522
522
|
this.emit('stepsStateUpdating', { name: this.#name, instanceId, state });
|
|
523
523
|
const connection = await DB.open();
|
|
524
524
|
return new Promise(async (resolve, reject) => {
|
|
525
|
-
const doc = await connection.updateOne(this.#collectionName,
|
|
526
|
-
{ _id: instanceId },
|
|
525
|
+
const doc = await connection.updateOne(this.#collectionName,
|
|
526
|
+
{ _id: instanceId },
|
|
527
527
|
{ $set: { ...state, updatedAt: new Date().toISOString() } });
|
|
528
528
|
if (options.continue) {
|
|
529
529
|
await this.continue(instanceId, false);
|
|
530
|
-
}
|
|
531
|
-
resolve({ ...doc });
|
|
530
|
+
}
|
|
531
|
+
resolve({ ...doc });
|
|
532
532
|
});
|
|
533
533
|
}
|
|
534
534
|
|
|
@@ -549,7 +549,7 @@ class Workflow extends EventEmitter {
|
|
|
549
549
|
* @returns {Promise<{qId: string}>} Queue ID for the continued step
|
|
550
550
|
* @throws {Error} If steps instance not found
|
|
551
551
|
*/
|
|
552
|
-
async continue(instanceId, reset=false) {
|
|
552
|
+
async continue(instanceId, reset = false) {
|
|
553
553
|
const connection = await DB.open();
|
|
554
554
|
const state = await connection.findOne(this.#collectionName, { _id: instanceId });
|
|
555
555
|
if (!state) {
|
|
@@ -565,10 +565,10 @@ class Workflow extends EventEmitter {
|
|
|
565
565
|
// update the step count
|
|
566
566
|
state.stepCount[state.nextStep] = { visits: 0, startTime: new Date().toISOString() };
|
|
567
567
|
}
|
|
568
|
-
|
|
568
|
+
|
|
569
569
|
await connection.updateOne(this.#collectionName, { _id: instanceId }, { $set: { stepCount: state.stepCount } });
|
|
570
570
|
console.debug('continue state', state);
|
|
571
|
-
this.emit('workflowContinued', { name: this.#name, step: state.nextStep, instanceId });
|
|
571
|
+
this.emit('workflowContinued', { name: this.#name, step: state.nextStep, instanceId });
|
|
572
572
|
|
|
573
573
|
return new Promise(async (resolve, reject) => {
|
|
574
574
|
const { _id: ID } = await connection.enqueue(`${this.#queuePrefix}_${this.#name}_${state.nextStep}`, {
|
|
@@ -589,7 +589,7 @@ class Workflow extends EventEmitter {
|
|
|
589
589
|
*/
|
|
590
590
|
async continueAllTimedOut() {
|
|
591
591
|
const db = await DB.open();
|
|
592
|
-
const timedOutWorkflows = await db.collection(this.#collectionName).find({nextStep: {$ne: null}}).toArray();
|
|
592
|
+
const timedOutWorkflows = await db.collection(this.#collectionName).find({ nextStep: { $ne: null } }).toArray();
|
|
593
593
|
const now = new Date();
|
|
594
594
|
const results = [];
|
|
595
595
|
for (const workflow of timedOutWorkflows) {
|
|
@@ -598,7 +598,7 @@ class Workflow extends EventEmitter {
|
|
|
598
598
|
if (diffMillis > this.#timeout) {
|
|
599
599
|
const diffMinutes = diffMillis / (1000 * 60);
|
|
600
600
|
console.log('Timed out:', workflow._id, workflow.nextStep, `(${diffMinutes.toFixed(1)} minutes old)`);
|
|
601
|
-
const result = await this.continue(workflow._id, true);
|
|
601
|
+
const result = await this.continue(workflow._id, true);
|
|
602
602
|
console.log('Continued:', result._id);
|
|
603
603
|
results.push(result);
|
|
604
604
|
}
|
|
@@ -642,13 +642,40 @@ class Workflow extends EventEmitter {
|
|
|
642
642
|
this.emit('cancelled', { id });
|
|
643
643
|
return new Promise(async (resolve, reject) => {
|
|
644
644
|
const connection = await DB.open();
|
|
645
|
-
const state = await connection.updateOne(this.#collectionName,
|
|
646
|
-
{ _id: id },
|
|
647
|
-
{ $set: { status: 'cancelled' } });
|
|
645
|
+
const state = await connection.updateOne(this.#collectionName,
|
|
646
|
+
{ _id: id },
|
|
647
|
+
{ $set: { status: 'cancelled' } });
|
|
648
648
|
resolve(state);
|
|
649
649
|
});
|
|
650
650
|
}
|
|
651
651
|
|
|
652
|
+
/**
|
|
653
|
+
* Get the status of a workflow instance (alias for getStepsStatus)
|
|
654
|
+
* @param {string} id - ID of the workflow instance
|
|
655
|
+
* @returns {Promise<Object>} The workflow status
|
|
656
|
+
*/
|
|
657
|
+
async getWorkflowStatus(id) {
|
|
658
|
+
return this.getStepsStatus(id);
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
/**
|
|
662
|
+
* Get the state of a workflow instance (alias for getStepsStatus)
|
|
663
|
+
* @param {string} id - ID of the workflow instance
|
|
664
|
+
* @returns {Promise<Object>} The workflow state
|
|
665
|
+
*/
|
|
666
|
+
async getState(id) {
|
|
667
|
+
return this.getStepsStatus(id);
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
/**
|
|
671
|
+
* Cancel a workflow instance (alias for cancelSteps)
|
|
672
|
+
* @param {string} id - ID of the workflow instance to cancel
|
|
673
|
+
* @returns {Promise<Object>} The cancellation result
|
|
674
|
+
*/
|
|
675
|
+
async cancelWorkflow(id) {
|
|
676
|
+
return this.cancelSteps(id);
|
|
677
|
+
}
|
|
678
|
+
|
|
652
679
|
/**
|
|
653
680
|
* Check if a specific step in a workflow instance has timed out
|
|
654
681
|
* @param {Object} workflow - The workflow instance
|
|
@@ -658,7 +685,7 @@ class Workflow extends EventEmitter {
|
|
|
658
685
|
isStepTimedOut(workflow) {
|
|
659
686
|
// Use previousStep if no stepName provided
|
|
660
687
|
const stepToCheck = workflow.nextStep;
|
|
661
|
-
|
|
688
|
+
|
|
662
689
|
if (!stepToCheck || !workflow.stepCount || !workflow.stepCount[stepToCheck]) {
|
|
663
690
|
console.debug('no step', stepToCheck, workflow.stepCount);
|
|
664
691
|
return {
|
|
@@ -669,12 +696,12 @@ class Workflow extends EventEmitter {
|
|
|
669
696
|
}
|
|
670
697
|
|
|
671
698
|
const step = workflow.stepCount[stepToCheck];
|
|
672
|
-
|
|
699
|
+
|
|
673
700
|
// Get the timeout value for this step
|
|
674
701
|
// First try step-specific config, then default options, finally fallback to global timeout
|
|
675
702
|
const stepConfig = this.#steps[stepToCheck];
|
|
676
703
|
const stepTimeout = stepConfig?.timeout ?? this.#defaultStepOptions.timeout ?? this.#timeout;
|
|
677
|
-
|
|
704
|
+
|
|
678
705
|
// If the step hasn't finished, check if it's been running too long
|
|
679
706
|
console.debug('isStepTimedOut', stepToCheck, stepTimeout);
|
|
680
707
|
if (!step.finishTime) {
|
|
@@ -716,7 +743,7 @@ class Workflow extends EventEmitter {
|
|
|
716
743
|
*/
|
|
717
744
|
async findTimedOutSteps(filter = {}) {
|
|
718
745
|
const db = await DB.open();
|
|
719
|
-
const workflows = await db.getMany(this.#collectionName, {"nextStep": {$ne: null}}).toArray();
|
|
746
|
+
const workflows = await db.getMany(this.#collectionName, { "nextStep": { $ne: null } }).toArray();
|
|
720
747
|
if (workflows.length > 0) {
|
|
721
748
|
console.debug('TimedOutSteps', workflows.length);
|
|
722
749
|
}
|