codehooks-js 1.3.22 → 1.3.24

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codehooks-js",
3
- "version": "1.3.22",
3
+ "version": "1.3.24",
4
4
  "type": "module",
5
5
  "description": "Codehooks.io official library - provides express.JS like syntax",
6
6
  "main": "index.js",
@@ -22,7 +22,8 @@
22
22
  "tsconfig.json"
23
23
  ],
24
24
  "scripts": {
25
- "test": "echo \"Warning: no tests specified\""
25
+ "test": "echo \"Warning: no tests specified\"",
26
+ "generate-monaco-types": "node scripts/generate-monaco-types.cjs"
26
27
  },
27
28
  "author": "Codehooks",
28
29
  "license": "ISC",
package/types/index.d.ts CHANGED
@@ -198,13 +198,19 @@ export type keyvalOptions = {
198
198
  */
199
199
  export type NoSQLAPI = {
200
200
  /**
201
- * - Get object by ID, returns a Promise with the object
201
+ * - Get object by ID (objectID) or query (NoSQL query {...}), returns a Promise with the object
202
+ * @throws {Error} Rejects if the object is not found
202
203
  */
203
204
  getOne: (query: string | object) => Promise<object>;
204
205
  /**
205
- * - Get object by ID, returns a Promise with the object - alias for getOne
206
+ * - Get object by ID (objectID) or query (NoSQL query {...}), returns a Promise with the object - alias for getOne
207
+ * @throws {Error} Rejects if the object is not found
206
208
  */
207
209
  findOne: (query: string | object) => Promise<object>;
210
+ /**
211
+ * - Get object by ID (objectID) or query (NoSQL query {...}), returns a Promise with the object or null if not found
212
+ */
213
+ findOneOrNull: (query: string | object) => Promise<object | null>;
208
214
  /**
209
215
  * - Get stream of objects by query
210
216
  * https://codehooks.io/docs/nosql-database-api#getmanycollection-query-options
@@ -306,7 +312,7 @@ export type DatastoreAPI = {
306
312
  */
307
313
  collection: (collection: string) => NoSQLAPI;
308
314
  /**
309
- * - Get object by ID, returns a Promise with the object
315
+ * - Get object by ID (objectID) or query (NoSQL query {...}), returns a Promise with the object
310
316
  */
311
317
  getOne: (collection: string, query: string | object) => Promise<any>;
312
318
  /**
@@ -315,9 +321,13 @@ export type DatastoreAPI = {
315
321
  */
316
322
  getMany: (collection: string, query?: object, options?: object) => DataStream;
317
323
  /**
318
- * - Get object by ID, returns a Promise with the object (alias for getOne)
324
+ * - Get object by ID (objectID) or query (NoSQL query {...}), returns a Promise with the object (alias for getOne)
319
325
  */
320
326
  findOne: (collection: string, query: string | object) => Promise<any>;
327
+ /**
328
+ * - Get object by ID (objectID) or query (NoSQL query {...}), returns a Promise with the object or null if not found
329
+ */
330
+ findOneOrNull: (collection: string, query: string | object) => Promise<any>;
321
331
  /**
322
332
  * - Alias for getMany
323
333
  * https://codehooks.io/docs/nosql-database-api#getmanycollection-query-options
@@ -165,6 +165,16 @@ class Workflow extends EventEmitter {
165
165
  return stepConfig?.workers ?? this.#defaultStepOptions.workers ?? 1;
166
166
  }
167
167
 
168
+ /**
169
+ * Get the timeout for a specific step
170
+ * @param {string} stepName - Name of the step
171
+ * @returns {number} The timeout in milliseconds for the step
172
+ */
173
+ getTimeoutForStep(stepName) {
174
+ const stepConfig = this.#steps[stepName];
175
+ return stepConfig?.timeout ?? this.#defaultStepOptions.timeout ?? this.#timeout;
176
+ }
177
+
168
178
  /**
169
179
  * Set the default number of workers for steps
170
180
  * @param {number} workers - Number of workers
@@ -185,6 +195,26 @@ class Workflow extends EventEmitter {
185
195
  return this.#defaultStepOptions.workers;
186
196
  }
187
197
 
198
+ /**
199
+ * Set the default timeout for steps
200
+ * @param {number} timeout - Timeout in milliseconds
201
+ * @throws {Error} If timeout is not a positive number
202
+ */
203
+ setDefaultTimeout(timeout) {
204
+ if (typeof timeout !== 'number' || timeout <= 0) {
205
+ throw new Error('Timeout must be a positive number');
206
+ }
207
+ this.#defaultStepOptions.timeout = timeout;
208
+ }
209
+
210
+ /**
211
+ * Get the default timeout for steps
212
+ * @returns {number} The default timeout in milliseconds
213
+ */
214
+ getDefaultTimeout() {
215
+ return this.#defaultStepOptions.timeout;
216
+ }
217
+
188
218
  /**
189
219
  * Configure the steps engine
190
220
  * @param {Object} config - Configuration object
@@ -204,6 +234,7 @@ class Workflow extends EventEmitter {
204
234
  }
205
235
  if (config.timeout) {
206
236
  this.setTimeout(config.timeout);
237
+ this.setDefaultTimeout(config.timeout);
207
238
  }
208
239
  if (config.maxStepCount) {
209
240
  this.setMaxStepCount(config.maxStepCount);
@@ -405,7 +436,7 @@ class Workflow extends EventEmitter {
405
436
  state: mergedState,
406
437
  options: options,
407
438
  instanceId: instanceId
408
- }, { workers: this.getWorkersForStep(step) });
439
+ }, { workers: this.getWorkersForStep(step), timeout: this.getTimeoutForStep(step) });
409
440
  }
410
441
  } else {
411
442
  console.debug('enqueue step', nextStep, instanceId);
@@ -415,7 +446,7 @@ class Workflow extends EventEmitter {
415
446
  state: mergedState,
416
447
  options: options,
417
448
  instanceId: instanceId
418
- }, { workers: this.getWorkersForStep(nextStep) });
449
+ }, { workers: this.getWorkersForStep(nextStep), timeout: this.getTimeoutForStep(nextStep) });
419
450
  }
420
451
  this.emit('stepEnqueued', { workflowName: stepsName, step: nextStep, state: newState, instanceId });
421
452
  resolve();
@@ -469,6 +500,7 @@ class Workflow extends EventEmitter {
469
500
  // Log current configuration state at registration time
470
501
  console.debug('Workflow registration config:', {
471
502
  defaultWorkers: this.#defaultStepOptions.workers,
503
+ defaultTimeout: this.#defaultStepOptions.timeout,
472
504
  stepsConfig: this.#steps
473
505
  });
474
506
 
@@ -478,7 +510,8 @@ class Workflow extends EventEmitter {
478
510
  // Skip null, undefined, or invalid step names
479
511
  if (stepName !== undefined && stepName !== null && stepName !== 'null' && stepName.trim() !== '') {
480
512
  const workerCount = this.getWorkersForStep(stepName);
481
- console.debug('registering queue for step', `${this.#queuePrefix}_${name}_${stepName}`, { workers: workerCount, stepConfig: this.#steps[stepName] });
513
+ const timeoutMs = this.getTimeoutForStep(stepName);
514
+ console.debug('registering queue for step', `${this.#queuePrefix}_${name}_${stepName}`, { workers: workerCount, timeout: timeoutMs, stepConfig: this.#steps[stepName] });
482
515
  app.worker(`${this.#queuePrefix}_${name}_${stepName}`, async (req, res) => {
483
516
  try {
484
517
  const { stepsName, goto, state, instanceId, options } = req.body.payload;
@@ -499,7 +532,7 @@ class Workflow extends EventEmitter {
499
532
  //console.debug('Worker res.end', stepName);
500
533
  res.end();
501
534
  }
502
- }, { workers: workerCount });
535
+ }, { workers: workerCount, timeout: timeoutMs });
503
536
  }
504
537
  } catch (error) {
505
538
  console.error(`Invalid step definition '${stepName}': ${error.message}`);
@@ -550,7 +583,7 @@ class Workflow extends EventEmitter {
550
583
  state: newState,
551
584
  instanceId: newState._id,
552
585
  options: {}
553
- }, { workers: this.getWorkersForStep(firstStepName) });
586
+ }, { workers: this.getWorkersForStep(firstStepName), timeout: this.getTimeoutForStep(firstStepName) });
554
587
  resolve(newState);
555
588
  } catch (error) {
556
589
  console.error('Error starting workflow:', error.message);
@@ -631,7 +664,7 @@ class Workflow extends EventEmitter {
631
664
  state: state,
632
665
  options: {},
633
666
  instanceId: instanceId
634
- }, { workers: this.getWorkersForStep(state.nextStep) });
667
+ }, { workers: this.getWorkersForStep(state.nextStep), timeout: this.getTimeoutForStep(state.nextStep) });
635
668
 
636
669
  resolve({ instanceId });
637
670
  });
@@ -751,10 +784,9 @@ class Workflow extends EventEmitter {
751
784
 
752
785
  const step = workflow.stepCount[stepToCheck];
753
786
 
754
- // Get the timeout value for this step
755
- // First try step-specific config, then default options, finally fallback to global timeout
787
+ // Get the timeout value for this step using the helper method
756
788
  const stepConfig = this.#steps[stepToCheck];
757
- const stepTimeout = stepConfig?.timeout ?? this.#defaultStepOptions.timeout ?? this.#timeout;
789
+ const stepTimeout = this.getTimeoutForStep(stepToCheck);
758
790
 
759
791
  // If the step hasn't finished, check if it's been running too long
760
792
  console.debug('isStepTimedOut', stepToCheck, stepTimeout);
@@ -770,7 +802,7 @@ class Workflow extends EventEmitter {
770
802
  step: stepToCheck,
771
803
  startTime: step.startTime,
772
804
  currentTime: now.toISOString(),
773
- timeoutSource: stepConfig ? 'stepConfig' : (this.#defaultStepOptions.timeout ? 'defaultOptions' : 'globalTimeout')
805
+ timeoutSource: stepConfig?.timeout ? 'stepConfig' : (this.#defaultStepOptions.timeout !== 30000 ? 'defaultOptions' : 'globalTimeout')
774
806
  };
775
807
  }
776
808
 
@@ -786,7 +818,7 @@ class Workflow extends EventEmitter {
786
818
  step: stepToCheck,
787
819
  startTime: step.startTime,
788
820
  finishTime: step.finishTime,
789
- timeoutSource: stepConfig ? 'stepConfig' : (this.#defaultStepOptions.timeout ? 'defaultOptions' : 'globalTimeout')
821
+ timeoutSource: stepConfig?.timeout ? 'stepConfig' : (this.#defaultStepOptions.timeout !== 30000 ? 'defaultOptions' : 'globalTimeout')
790
822
  };
791
823
  }
792
824