codehooks-js 1.3.4 → 1.3.5

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/workflow/engine.mjs +60 -54
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codehooks-js",
3
- "version": "1.3.4",
3
+ "version": "1.3.5",
4
4
  "type": "module",
5
5
  "description": "Codehooks.io official library - provides express.JS like syntax",
6
6
  "main": "index.js",
@@ -143,62 +143,66 @@ class StepsEngine extends EventEmitter {
143
143
 
144
144
 
145
145
 
146
- // Get the next step function
147
- const func = StepsEngine.getInstance().getDefinition(stepsName, nextStep);
148
-
146
+
149
147
  try {
150
- // Call the next step function with the step context
151
- func.call(this, {...newState, instanceId: newState._id}, async function (nextStep, userState, options) {
152
- try {
153
-
154
- // Protect system-level properties
155
- const protectedState = {
156
- _id: newState._id,
157
- nextStep: newState.nextStep,
158
- createdAt: newState.createdAt,
159
- updatedAt: newState.updatedAt,
160
- instanceId: newState.instanceId,
161
- workflowName: newState.workflowName
162
- };
163
-
164
- // Merge states with userState taking precedence, but protecting system fields
165
- const mergedState = {
166
- //...newState,
167
- ...userState,
168
- ...protectedState
169
- };
148
+ // Get the next step function
149
+ const func = StepsEngine.getInstance().getDefinition(stepsName, nextStep);
170
150
 
171
- // If there is no next step, the workflow is completed
172
- if (nextStep === null) {
173
- delete mergedState._id;
174
- const completionTime = (new Date(mergedState.updatedAt) - new Date(mergedState.createdAt)) / 1000;
175
- console.log(`Workflow ${stepsName} ${instanceId} is completed in time: ${completionTime}s 🎉`);
176
- const db = await Datastore.open();
177
- await db.updateOne(StepsEngine.collectionName,
178
- { _id: instanceId },
179
- { $set: { ...mergedState, nextStep: null, updatedAt: new Date().toISOString() } });
180
- StepsEngine.getInstance().emit('completed', { message: 'Steps workflow completed', ...userState });
181
- return;
182
- }
151
+ // Wrap the callback in a Promise to ensure proper async handling
152
+ await new Promise((resolve, reject) => {
153
+ func({...newState, instanceId: newState._id}, async (nextStep, userState, options) => {
154
+ try {
155
+ // Protect system-level properties
156
+ const protectedState = {
157
+ _id: newState._id,
158
+ nextStep: newState.nextStep,
159
+ createdAt: newState.createdAt,
160
+ updatedAt: newState.updatedAt,
161
+ instanceId: newState.instanceId,
162
+ workflowName: newState.workflowName
163
+ };
164
+
165
+ // Merge states with userState taking precedence, but protecting system fields
166
+ const mergedState = {
167
+ ...userState,
168
+ ...protectedState
169
+ };
183
170
 
184
- // Enqueue the next step
185
- //console.log('enqueuing step', `${StepsEngine.queuePrefix}_${stepsName}_${nextStep}`);
186
- connection.enqueue(`${StepsEngine.queuePrefix}_${stepsName}_${nextStep}`, {
187
- stepsName: stepsName,
188
- goto: nextStep,
189
- state: mergedState,
190
- options: options,
191
- instanceId: instanceId
192
- });
193
-
194
- StepsEngine.getInstance().emit('stepEnqueued', { workflowName: stepsName, step: nextStep, state: newState, instanceId });
195
- } catch (error) {
196
- console.log('error', error.message);
197
- throw error;
198
- }
171
+ // If there is no next step, the workflow is completed
172
+ if (nextStep === null) {
173
+ delete mergedState._id;
174
+ const completionTime = (new Date(mergedState.updatedAt) - new Date(mergedState.createdAt)) / 1000;
175
+
176
+ const finalresult = await connection.updateOne(StepsEngine.collectionName,
177
+ { _id: instanceId },
178
+ { $set: { ...mergedState, nextStep: null, updatedAt: new Date().toISOString() } });
179
+ console.log(`Workflow ${stepsName} ${instanceId} is completed in time: ${completionTime}s 🎉`);
180
+ StepsEngine.getInstance().emit('completed', { ...finalresult});
181
+ resolve();
182
+ return;
183
+ }
184
+
185
+ // Enqueue the next step
186
+ console.debug('enqueuing step', nextStep, instanceId);
187
+ await connection.enqueue(`${StepsEngine.queuePrefix}_${stepsName}_${nextStep}`, {
188
+ stepsName: stepsName,
189
+ goto: nextStep,
190
+ state: mergedState,
191
+ options: options,
192
+ instanceId: instanceId
193
+ });
194
+
195
+ StepsEngine.getInstance().emit('stepEnqueued', { workflowName: stepsName, step: nextStep, state: newState, instanceId });
196
+ resolve();
197
+ } catch (error) {
198
+ console.error('error', error.message);
199
+ reject(error);
200
+ }
201
+ });
199
202
  });
200
203
  } catch (error) {
201
204
  console.error('Error in step function: '+nextStep, error.message);
205
+ StepsEngine.getInstance().emit('error', { workflowName: stepsName, step: nextStep, state: newState, instanceId, error: error.message });
202
206
  const connection = await Datastore.open();
203
207
  await connection.updateOne(StepsEngine.collectionName,
204
208
  { _id: instanceId },
@@ -228,9 +232,11 @@ class StepsEngine extends EventEmitter {
228
232
  try {
229
233
  if (stepName !== undefined) {
230
234
  //console.log('registering queue for step', `${StepsEngine.queuePrefix}_${name}_${stepName}`);
231
- app.worker(`${StepsEngine.queuePrefix}_${name}_${stepName}`, async (req, res) => {
232
- const { stepsName, goto, state, instanceId, options } = req.body.payload;
235
+ app.worker(`${StepsEngine.queuePrefix}_${name}_${stepName}`, async function(req, res) {
233
236
  try {
237
+
238
+ const { stepsName, goto, state, instanceId, options } = req.body.payload;
239
+ console.debug('worker job', stepName, instanceId);
234
240
  const qid = await StepsEngine.getInstance().handleNextStep(stepsName, goto, state, instanceId, options);
235
241
  } catch (error) {
236
242
  console.error('Error in step function: ' + stepName, error.message);
@@ -334,7 +340,7 @@ class StepsEngine extends EventEmitter {
334
340
  throw new Error(`No steps found with instanceId: ${instanceId}`);
335
341
  }
336
342
 
337
- console.log('continue state', state);
343
+ console.debug('continue state', state);
338
344
  StepsEngine.getInstance().emit('workflowContinued', { stepsName, step: state.nextStep, instanceId });
339
345
 
340
346
  return new Promise(async (resolve, reject) => {
@@ -372,7 +378,7 @@ class StepsEngine extends EventEmitter {
372
378
  return new Promise(async (resolve, reject) => {
373
379
  const connection = await Datastore.open();
374
380
  const states = await connection.find(StepsEngine.collectionName, filter).toArray();
375
- console.log('listSteps', StepsEngine.collectionName, filter, states.length);
381
+ console.debug('listSteps', StepsEngine.collectionName, filter, states.length);
376
382
  resolve(states);
377
383
  });
378
384
  }