codehooks-js 1.3.1 → 1.3.3

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/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {agg} from './aggregation/index.mjs';
2
2
  import {crudlify as crud} from './crudlify/index.mjs';
3
3
  import {serveStatic as ws, render as renderView} from './webserver.mjs';
4
- import {Steps, StepsConfig} from './workflow/index.mjs';
4
+ import {Steps as Workflow, StepsConfig as WorkflowConfig} from './workflow/index.mjs';
5
5
 
6
6
  function createRoute(str) {
7
7
  if(str instanceof RegExp) {
@@ -117,9 +117,9 @@ class Codehooks {
117
117
  })
118
118
  }
119
119
 
120
- createSteps = (name, description, steps, options={}) => {
121
- Steps.register(this, name, description, steps, options);
122
- return Steps;
120
+ createWorkflow = (name, description, steps, options={}) => {
121
+ Workflow.register(this, name, description, steps, options);
122
+ return Workflow;
123
123
  }
124
124
 
125
125
  init = (hook) => {
@@ -193,10 +193,10 @@ export const aggregation = agg;
193
193
  export const crudlify = crud;
194
194
  export const coho = _coho;
195
195
  export const app = _coho;
196
- export const stepsconfig = StepsConfig;
196
+ export const workflowconfig = WorkflowConfig;
197
197
  export {
198
- Steps,
199
- StepsConfig
198
+ Workflow,
199
+ WorkflowConfig
200
200
  };
201
201
  export const realtime = {
202
202
  createChannel: (path, ...hook) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codehooks-js",
3
- "version": "1.3.1",
3
+ "version": "1.3.3",
4
4
  "type": "module",
5
5
  "description": "Codehooks.io official library - provides express.JS like syntax",
6
6
  "main": "index.js",
package/types/index.d.ts CHANGED
@@ -4,7 +4,7 @@ export const aggregation: typeof agg;
4
4
  export const crudlify: typeof crud;
5
5
  export const coho: Codehooks;
6
6
  export const app: Codehooks;
7
- export const stepsconfig: {
7
+ export const workflowconfig: {
8
8
  setCollectionName: any;
9
9
  setQueuePrefix: any;
10
10
  };
@@ -62,8 +62,12 @@ declare class Codehooks {
62
62
  set: (key: any, val: any) => void;
63
63
  render: (view: any, data: any, cb: any) => Promise<void>;
64
64
  crudlify: (schema?: {}, options?: {}) => Promise<import("./crudlify/lib/eventhooks.mjs").EventHooks>;
65
- createSteps: (name: any, description: any, steps: any, options?: {}) => {
65
+ createWorkflow: (name: any, description: any, steps: any, options?: {}) => {
66
66
  definitions: Map<any, any>;
67
+ configure(config: {
68
+ collectionName: string;
69
+ queuePrefix: string;
70
+ }): void;
67
71
  getDefinition(stepsName: string, stepName: string): Function;
68
72
  validateStepDefinition(step: Function): void;
69
73
  handleNextStep(stepsName: string, nextStep: string | null, newState: any, instanceId: string, options: any): Promise<string | string[]>;
@@ -124,7 +128,7 @@ declare class Codehooks {
124
128
  };
125
129
  addListener: (observer: any) => void;
126
130
  }
127
- import { Steps } from './workflow/index.mjs';
128
- import { StepsConfig } from './workflow/index.mjs';
131
+ import { Steps as Workflow } from './workflow/index.mjs';
132
+ import { StepsConfig as WorkflowConfig } from './workflow/index.mjs';
129
133
  declare const _coho: Codehooks;
130
- export { Steps, StepsConfig };
134
+ export { Workflow, WorkflowConfig };
@@ -30,6 +30,16 @@ declare class StepsEngine extends EventEmitter<[never]> {
30
30
  static getInstance(): StepsEngine;
31
31
  constructor();
32
32
  definitions: Map<any, any>;
33
+ /**
34
+ * Configure the steps engine
35
+ * @param {Object} config - Configuration object
36
+ * @param {string} config.collectionName - Collection name
37
+ * @param {string} config.queuePrefix - Queue prefix
38
+ */
39
+ configure(config: {
40
+ collectionName: string;
41
+ queuePrefix: string;
42
+ }): void;
33
43
  /**
34
44
  * Get the step definition for a specific step
35
45
  * @param {string} stepsName - Name of the steps workflow
@@ -2,6 +2,10 @@ export namespace StepsConfig {
2
2
  export { setCollectionName };
3
3
  export { setQueuePrefix };
4
4
  }
5
+ export const configure: (config: {
6
+ collectionName: string;
7
+ queuePrefix: string;
8
+ }) => void;
5
9
  export { Steps };
6
10
  export default StepsEngine;
7
11
  import { setCollectionName } from './engine.mjs';
@@ -20,8 +20,8 @@ class StepsEngine extends EventEmitter {
20
20
  static instance = null;
21
21
 
22
22
  // Configuration
23
- static collectionName = 'stepsdata';
24
- static queuePrefix = 'stepsqueue';
23
+ static collectionName = 'workflowdata';
24
+ static queuePrefix = 'workflowqueue';
25
25
 
26
26
  /**
27
27
  * Set the collection name for storing steps data
@@ -47,6 +47,21 @@ class StepsEngine extends EventEmitter {
47
47
  StepsEngine.queuePrefix = prefix.trim();
48
48
  }
49
49
 
50
+ /**
51
+ * Configure the steps engine
52
+ * @param {Object} config - Configuration object
53
+ * @param {string} config.collectionName - Collection name
54
+ * @param {string} config.queuePrefix - Queue prefix
55
+ */
56
+ configure(config) {
57
+ if (config.collectionName) {
58
+ StepsEngine.setCollectionName(config.collectionName);
59
+ }
60
+ if (config.queuePrefix) {
61
+ StepsEngine.setQueuePrefix(config.queuePrefix);
62
+ }
63
+ }
64
+
50
65
  /**
51
66
  * Get the singleton instance of StepsEngine
52
67
  * @returns {StepsEngine} The singleton instance
@@ -114,58 +129,51 @@ class StepsEngine extends EventEmitter {
114
129
  return results;
115
130
  }
116
131
 
117
- const isFinished = nextStep === null;
118
-
119
132
  // Handle single next step
120
- StepsEngine.getInstance().emit('stepStarted', { stepsName, step: nextStep, state: newState, instanceId });
133
+ StepsEngine.getInstance().emit('stepStarted', { workflowName: stepsName, step: nextStep, state: newState, instanceId });
121
134
  const connection = await Datastore.open();
122
135
  // remove the _id from the newState
123
136
  delete newState._id;
124
137
  // Update the existing steps state in the database
125
138
  newState = await connection.updateOne(StepsEngine.collectionName,
126
139
  { _id: instanceId },
127
- { $set: { ...newState, nextStep: nextStep, updatedAt: new Date().toISOString(), isFinished: isFinished } });
140
+ { $set: { ...newState, nextStep: nextStep, updatedAt: new Date().toISOString() } });
128
141
 
129
- StepsEngine.getInstance().emit('stateUpdated', { stepsName, state: newState, instanceId });
142
+ StepsEngine.getInstance().emit('stateUpdated', { workflowName: stepsName, state: newState, instanceId });
130
143
 
131
- // Get the next step function
132
- const func = StepsEngine.getInstance().getDefinition(stepsName, nextStep);
133
-
134
- // Check if the step is waiting for input
135
- if (options && options.waitForInput === true) {
136
- console.log('Steps workflow is paused, waiting for input for at step', nextStep);
137
- this.emit('stepWaiting', { stepsName, step: nextStep, instanceId });
144
+ // If there is no next step, the workflow is completed
145
+ if (nextStep === null) {
146
+ console.log('No next step, steps workflow completed');
147
+ StepsEngine.getInstance().emit('completed', { message: 'Steps workflow completed', ...newState });
138
148
  return;
139
149
  }
150
+
151
+ // Get the next step function
152
+ const func = StepsEngine.getInstance().getDefinition(stepsName, nextStep);
140
153
 
141
154
  try {
142
155
  // Call the next step function with the step context
143
156
  func.call(this, {...newState, instanceId: newState._id}, async function (nextStep, userState, options) {
144
157
  try {
145
- if (nextStep === null) {
146
- console.log('No next step, steps workflow completed');
147
- StepsEngine.getInstance().emit('completed', { message: 'Steps workflow completed', ...userState });
148
- return;
149
- }
158
+
150
159
  // Protect system-level properties
151
160
  const protectedState = {
152
161
  _id: newState._id,
153
162
  nextStep: newState.nextStep,
154
163
  createdAt: newState.createdAt,
155
164
  updatedAt: newState.updatedAt,
156
- instanceId: newState.instanceId,
157
- isFinished: newState.isFinished
165
+ instanceId: newState.instanceId
158
166
  };
159
167
 
160
168
  // Merge states with userState taking precedence, but protecting system fields
161
169
  const mergedState = {
162
- ...newState,
170
+ //...newState,
163
171
  ...userState,
164
172
  ...protectedState
165
173
  };
166
174
 
167
175
  // Enqueue the next step
168
- const qres = connection.enqueue(`${StepsEngine.queuePrefix}`, {
176
+ const qres = connection.enqueue(`${StepsEngine.queuePrefix}_${stepsName}`, {
169
177
  stepsName: stepsName,
170
178
  goto: nextStep,
171
179
  state: mergedState,
@@ -173,14 +181,14 @@ class StepsEngine extends EventEmitter {
173
181
  instanceId: instanceId
174
182
  });
175
183
 
176
- StepsEngine.getInstance().emit('stepEnqueued', { stepsName, step: nextStep, state: newState, instanceId });
184
+ StepsEngine.getInstance().emit('stepEnqueued', { workflowName: stepsName, step: nextStep, state: newState, instanceId });
177
185
  } catch (error) {
178
186
  console.log('error', error.message);
179
187
  throw error;
180
188
  }
181
189
  });
182
190
  } catch (error) {
183
- console.error('Error in step function:', error.message);
191
+ console.error('Error in step function: '+nextStep, error.message);
184
192
  const connection = await Datastore.open();
185
193
  await connection.updateOne(StepsEngine.collectionName,
186
194
  { _id: instanceId },
@@ -203,18 +211,18 @@ class StepsEngine extends EventEmitter {
203
211
  * @throws {Error} If step definition is invalid
204
212
  */
205
213
  async register(app, name, description, definition) {
206
- StepsEngine.getInstance().emit('stepsRegistered', { name, description });
214
+ StepsEngine.getInstance().emit('workflowCreated', { name, description });
207
215
 
208
216
  // Validate each step in the definition
209
217
  for (const [stepName, step] of Object.entries(definition)) {
210
218
  try {
211
219
  if (stepName !== null) {
212
- app.worker(`${StepsEngine.queuePrefix}`, async (req, res) => {
220
+ app.worker(`${StepsEngine.queuePrefix}_${name}`, async (req, res) => {
213
221
  const { stepsName, goto, state, instanceId, options } = req.body.payload;
214
222
  try {
215
223
  const qid = await StepsEngine.getInstance().handleNextStep(stepsName, goto, state, instanceId, options);
216
224
  } catch (error) {
217
- console.error('Error in step function:', error.message);
225
+ console.error('Error in step function: ' + stepName, error.message);
218
226
  } finally {
219
227
  res.end();
220
228
  }
@@ -238,7 +246,7 @@ class StepsEngine extends EventEmitter {
238
246
  * @throws {Error} If starting steps fails
239
247
  */
240
248
  async start(name, initialState) {
241
- StepsEngine.getInstance().emit('stepsStarted', { name, initialState });
249
+ StepsEngine.getInstance().emit('workflowStarted', { name, initialState });
242
250
 
243
251
  return new Promise(async (resolve, reject) => {
244
252
  try {
@@ -253,7 +261,7 @@ class StepsEngine extends EventEmitter {
253
261
  // Create a new steps state in the database
254
262
  const newState = await connection.insertOne(StepsEngine.collectionName,
255
263
  { ...initialState, nextStep: firstStepName, createdAt: new Date().toISOString() });
256
- const { _id: ID } = await connection.enqueue(`${StepsEngine.queuePrefix}`, {
264
+ const { _id: ID } = await connection.enqueue(`${StepsEngine.queuePrefix}_${name}`, {
257
265
  stepsName: name,
258
266
  goto: firstStepName,
259
267
  state: newState,
@@ -316,7 +324,7 @@ class StepsEngine extends EventEmitter {
316
324
  }
317
325
 
318
326
  console.log('continue state', state);
319
- StepsEngine.getInstance().emit('stepContinued', { stepsName, step: state.nextStep, instanceId });
327
+ StepsEngine.getInstance().emit('workflowContinued', { stepsName, step: state.nextStep, instanceId });
320
328
 
321
329
  return new Promise(async (resolve, reject) => {
322
330
  const { _id: ID } = await connection.enqueue(`${StepsEngine.queuePrefix}`, {
@@ -364,7 +372,7 @@ class StepsEngine extends EventEmitter {
364
372
  * @returns {Promise<Object>} The cancellation result
365
373
  */
366
374
  async cancelSteps(id) {
367
- StepsEngine.getInstance().emit('stepsCancelled', { id });
375
+ StepsEngine.getInstance().emit('cancelled', { id });
368
376
  return new Promise(async (resolve, reject) => {
369
377
  const connection = await Datastore.open();
370
378
  const state = await connection.updateOne(StepsEngine.collectionName,
@@ -6,6 +6,9 @@ export const StepsConfig = {
6
6
  setQueuePrefix
7
7
  };
8
8
 
9
+ // Re-export the configure method
10
+ export const configure = StepsEngine.configure;
11
+
9
12
  // Re-export the workflow instance
10
13
  export { Steps };
11
14