@ronaldroe/micro-flow 0.2.0 → 0.2.1
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/README.md
CHANGED
|
@@ -219,7 +219,7 @@ const workflow = new Workflow({
|
|
|
219
219
|
|
|
220
220
|
### Steps
|
|
221
221
|
|
|
222
|
-
Steps are individual units of work that execute functions, other steps, or even entire workflows
|
|
222
|
+
Steps are individual units of work that execute functions, other steps, or even entire workflows. Steps have retry and timeout mechanisms.
|
|
223
223
|
|
|
224
224
|
```javascript
|
|
225
225
|
import { Step } from 'micro-flow';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var m=Object.defineProperty;var r=(
|
|
1
|
+
var m=Object.defineProperty;var r=(n,t)=>m(n,"name",{value:t,configurable:!0});import u from"../base.js";import"../workflow.js";import{base_types as o,step_types as l}from"../../enums/index.js";class _ extends u{static{r(this,"Step")}static step_name="step";#t=null;constructor({name:t,callable:s=r(async()=>{},"callable"),max_retries:e=0,max_timeout_ms:i=3e4,step_type:h=l.ACTION,sub_step_type:a=null}){super({name:t,base_type:o.STEP}),this.callable=s,this.#t=s,this.max_retries=e,this.retry_count=0,this.max_timeout_ms=i,this.step_type=h,this.sub_step_type=a,this.errors=[],this.result=null,this.retry_results=[],this.timeout=null,this.start_time=null}async execute(){this.timeout||(this.timeout=new Promise((e,i)=>setTimeout(i,this.max_timeout_ms,new Error(`Step "${this.name}" timed out after ${this.max_timeout_ms}ms`)))),this.start_time||(this.start_time=new Date),this.markAsRunning();try{this.result=await Promise.race([this._callable(),this.timeout])}catch(e){if(this.max_retries&&this.retry_count<this.max_retries)this.retry_count++,this.retry_results.push({retry_count:this.retry_count,result:await this.execute()}),this.timing.end_time=new Date,this.timing.execution_time_ms=this.timing.end_time-this.timing.start_time;else if(this.errors.push(e),this.timing.end_time=new Date,this.timing.execution_time_ms=this.timing.end_time-this.timing.start_time,this.markAsFailed(),this.getState("exit_on_error"))throw e}const{FAILED:t,COMPLETE:s}=this.getState("statuses")[this.base_type];return[t,s].includes(this.status)||this.markAsComplete(),["step","workflow"].includes(this.callable_type)?this.#t:this}getCallableType(t){if(t&&t.base_type===o.WORKFLOW)return"workflow";if(t&&t.base_type===o.STEP)return"step";if(typeof t=="function")return"function";throw new Error("Invalid callable type. Must be one of function, Step, or Workflow.")}setParentWorkflowValue(t,s,e){const i=this.getState("workflows")[t];if(!i)throw new Error(`Parent workflow with ID ${t} not found.`);i[s]=e}set callable(t){this.callable_type=this.getCallableType(t),["step","workflow"].includes(this.callable_type)?(this.callable_type==="step"&&(t.parentWorkflowId=this.parentWorkflowId??null),this._callable=t.execute.bind(t)):this._callable=t.bind(this)}}export{_ as default};
|
|
2
2
|
//# sourceMappingURL=step.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/classes/steps/step.js"],
|
|
4
|
-
"sourcesContent": ["import Base from '../base.js';\nimport Workflow from '../workflow.js';\nimport { base_types, step_types } from '../../enums/index.js';\n\n/**\n * Step class representing an executable unit within a workflow.\n * @class Step\n * @extends Base\n */\nexport default class Step extends Base {\n static step_name = 'step';\n #callable_object = null;\n\n /**\n * Creates a new Step instance.\n * @param {Object} options - Configuration options.\n * @param {string} [options.name] - Name of the step.\n * @param {Function|Step|Workflow} [options.callable=async () => {}] - Function, Step, or Workflow to execute.\n * @param {number} [options.max_retries=0] - Maximum number of retries on failure.\n * @param {number} [options.max_timeout_ms=30000] - Maximum execution time in milliseconds before timing out.\n * @param {string} [options.step_type=step_types.ACTION] - Type of the step.\n * @param {sub_step_types|null} [options.sub_step_type=null] - Sub-type of the step (use values from the sub_step_types enum).\n */\n constructor({\n name,\n callable = async () => {},\n max_retries = 0,\n max_timeout_ms = 30000,\n step_type = step_types.ACTION,\n sub_step_type = null,\n }) {\n super({ name, base_type: base_types.STEP });\n\n this.callable = callable;\n\n // Store off the original callable object, because if it's a Step or Workflow,\n // this.callable is set to the execute method of that object, but we may need to access its properties later.\n this.#callable_object = callable;\n\n this.max_retries = max_retries;\n this.retry_count = 0;\n this.max_timeout_ms = max_timeout_ms;\n this.step_type = step_type;\n this.sub_step_type = sub_step_type;\n\n this.errors = [];\n this.result = null;\n this.retry_results = [];\n this.timeout = null;\n this.start_time = null;\n }\n\n /**\n * Executes the step's callable function, Step, or Workflow.\n * @async\n * @returns {Promise<Step>} The step instance with execution results.\n */\n async execute() {\n if (!this.timeout ) {\n this.timeout = new Promise((_, reject) =>\n setTimeout(reject, this.max_timeout_ms, new Error(`Step \"${this.name}\" timed out after ${this.max_timeout_ms}ms`))\n );\n }\n\n if (!this.start_time) {\n this.start_time = new Date();\n }\n\n this.markAsRunning();\n\n try {\n this.result = await Promise.race([this._callable(), this.timeout]);\n } catch (error) {\n if (this.max_retries && this.retry_count < this.max_retries) {\n this.retry_count++;\n this.retry_results.push({\n retry_count: this.retry_count,\n result: await this.execute(),\n });\n\n this.timing.end_time = new Date();\n this.timing.execution_time_ms = this.timing.end_time - this.timing.start_time;\n } else {\n this.errors.push(error);\n\n this.timing.end_time = new Date();\n this.timing.execution_time_ms = this.timing.end_time - this.timing.start_time;\n\n this.markAsFailed();\n\n if (this.getState('exit_on_error')) {\n throw error;\n }\n }\n\n }\n\n
|
|
5
|
-
"mappings": "+EAAA,OAAOA,MAAU,aACjB,MAAqB,iBACrB,OAAS,cAAAC,EAAY,cAAAC,MAAkB,uBAOvC,MAAOC,UAA2BH,CAAK,CATvC,MASuC,CAAAI,EAAA,aACrC,OAAO,UAAY,OACnBC,GAAmB,KAYnB,YAAY,CACV,KAAAC,EACA,SAAAC,EAAWH,EAAA,SAAY,CAAC,EAAb,YACX,YAAAI,EAAc,EACd,eAAAC,EAAiB,IACjB,UAAAC,EAAYR,EAAW,OACvB,cAAAS,EAAgB,IAClB,EAAG,CACD,MAAM,CAAE,KAAAL,EAAM,UAAWL,EAAW,IAAK,CAAC,EAE1C,KAAK,SAAWM,EAIhB,KAAKF,GAAmBE,EAExB,KAAK,YAAcC,EACnB,KAAK,YAAc,EACnB,KAAK,eAAiBC,EACtB,KAAK,UAAYC,EACjB,KAAK,cAAgBC,EAErB,KAAK,OAAS,CAAC,EACf,KAAK,OAAS,KACd,KAAK,cAAgB,CAAC,EACtB,KAAK,QAAU,KACf,KAAK,WAAa,IACpB,CAOA,MAAM,SAAU,CACT,KAAK,UACR,KAAK,QAAU,IAAI,QAAQ,CAACC,EAAGC,IAC7B,WAAWA,EAAQ,KAAK,eAAgB,IAAI,MAAM,SAAS,KAAK,IAAI,qBAAqB,KAAK,cAAc,IAAI,CAAC,CACnH,GAGG,KAAK,aACR,KAAK,WAAa,IAAI,MAGxB,KAAK,cAAc,EAEnB,GAAI,CACF,KAAK,OAAS,MAAM,QAAQ,KAAK,CAAC,KAAK,UAAU,EAAG,KAAK,OAAO,CAAC,CACnE,OAASC,EAAO,CACd,GAAI,KAAK,aAAe,KAAK,YAAc,KAAK,YAC9C,KAAK,cACL,KAAK,cAAc,KAAK,CACtB,YAAa,KAAK,YAClB,OAAQ,MAAM,KAAK,QAAQ,CAC7B,CAAC,EAED,KAAK,OAAO,SAAW,IAAI,KAC3B,KAAK,OAAO,kBAAoB,KAAK,OAAO,SAAW,KAAK,OAAO,mBAEnE,KAAK,OAAO,KAAKA,CAAK,EAEtB,KAAK,OAAO,SAAW,IAAI,KAC3B,KAAK,OAAO,kBAAoB,KAAK,OAAO,SAAW,KAAK,OAAO,WAEnE,KAAK,aAAa,EAEd,KAAK,SAAS,eAAe,EAC/B,MAAMA,CAIZ,
|
|
6
|
-
"names": ["Base", "base_types", "step_types", "Step", "__name", "#callable_object", "name", "callable", "max_retries", "max_timeout_ms", "step_type", "sub_step_type", "_", "reject", "error", "workflowId", "path", "value", "parentWorkflow"]
|
|
4
|
+
"sourcesContent": ["import Base from '../base.js';\nimport Workflow from '../workflow.js';\nimport { base_types, step_types } from '../../enums/index.js';\n\n/**\n * Step class representing an executable unit within a workflow.\n * @class Step\n * @extends Base\n */\nexport default class Step extends Base {\n static step_name = 'step';\n #callable_object = null;\n\n /**\n * Creates a new Step instance.\n * @param {Object} options - Configuration options.\n * @param {string} [options.name] - Name of the step.\n * @param {Function|Step|Workflow} [options.callable=async () => {}] - Function, Step, or Workflow to execute.\n * @param {number} [options.max_retries=0] - Maximum number of retries on failure.\n * @param {number} [options.max_timeout_ms=30000] - Maximum execution time in milliseconds before timing out.\n * @param {string} [options.step_type=step_types.ACTION] - Type of the step.\n * @param {sub_step_types|null} [options.sub_step_type=null] - Sub-type of the step (use values from the sub_step_types enum).\n */\n constructor({\n name,\n callable = async () => {},\n max_retries = 0,\n max_timeout_ms = 30000,\n step_type = step_types.ACTION,\n sub_step_type = null,\n }) {\n super({ name, base_type: base_types.STEP });\n\n this.callable = callable;\n\n // Store off the original callable object, because if it's a Step or Workflow,\n // this.callable is set to the execute method of that object, but we may need to access its properties later.\n this.#callable_object = callable;\n\n this.max_retries = max_retries;\n this.retry_count = 0;\n this.max_timeout_ms = max_timeout_ms;\n this.step_type = step_type;\n this.sub_step_type = sub_step_type;\n\n this.errors = [];\n this.result = null;\n this.retry_results = [];\n this.timeout = null;\n this.start_time = null;\n }\n\n /**\n * Executes the step's callable function, Step, or Workflow.\n * @async\n * @returns {Promise<Step>} The step instance with execution results.\n */\n async execute() {\n if (!this.timeout ) {\n this.timeout = new Promise((_, reject) =>\n setTimeout(reject, this.max_timeout_ms, new Error(`Step \"${this.name}\" timed out after ${this.max_timeout_ms}ms`))\n );\n }\n\n if (!this.start_time) {\n this.start_time = new Date();\n }\n\n this.markAsRunning();\n\n try {\n this.result = await Promise.race([this._callable(), this.timeout]);\n } catch (error) {\n if (this.max_retries && this.retry_count < this.max_retries) {\n this.retry_count++;\n this.retry_results.push({\n retry_count: this.retry_count,\n result: await this.execute(),\n });\n\n this.timing.end_time = new Date();\n this.timing.execution_time_ms = this.timing.end_time - this.timing.start_time;\n } else {\n this.errors.push(error);\n\n this.timing.end_time = new Date();\n this.timing.execution_time_ms = this.timing.end_time - this.timing.start_time;\n\n this.markAsFailed();\n\n if (this.getState('exit_on_error')) {\n throw error;\n }\n }\n\n }\n\n const { FAILED, COMPLETE } = this.getState('statuses')[this.base_type];\n\n if (! [FAILED, COMPLETE].includes(this.status)) {\n this.markAsComplete();\n }\n\n if (['step', 'workflow'].includes(this.callable_type)) {\n return this.#callable_object;\n }\n\n return this;\n }\n\n /**\n * Determines the type of the callable (function, step, or workflow).\n * @param {Function|Step|Workflow} callable - The callable to check.\n * @returns {string} The type: 'function', 'step', or 'workflow'.\n * @throws {Error} Throws if callable type is invalid.\n */\n getCallableType(callable) {\n if (callable && callable.base_type === base_types.WORKFLOW) {\n return 'workflow';\n } else if (callable && callable.base_type === base_types.STEP) {\n return 'step';\n } else if (typeof callable === 'function') {\n return 'function';\n } \n\n throw new Error('Invalid callable type. Must be one of function, Step, or Workflow.');\n }\n\n /**\n * Sets a value in the parent workflow's state.\n * @param {string} workflowId - ID of the parent workflow.\n * @param {string} path - Path in the workflow state to set.\n * @param {*} value - Value to set at the specified path.\n * @throws {Error} Throws if parent workflow is not found.\n */\n setParentWorkflowValue(workflowId, path, value) {\n const parentWorkflow = this.getState('workflows')[workflowId];\n\n if (!parentWorkflow) {\n throw new Error(`Parent workflow with ID ${workflowId} not found.`);\n }\n\n parentWorkflow[path] = value;\n }\n\n /**\n * Sets the callable for the step and determines its type.\n * @param {Function|Step|Workflow} callable - The callable to set.\n */\n set callable(callable) {\n this.callable_type = this.getCallableType(callable);\n\n if (['step', 'workflow'].includes(this.callable_type)) {\n if (this.callable_type === 'step') {\n callable.parentWorkflowId = this.parentWorkflowId ?? null;\n }\n\n this._callable = callable.execute.bind(callable);\n } else {\n this._callable = callable.bind(this);\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "+EAAA,OAAOA,MAAU,aACjB,MAAqB,iBACrB,OAAS,cAAAC,EAAY,cAAAC,MAAkB,uBAOvC,MAAOC,UAA2BH,CAAK,CATvC,MASuC,CAAAI,EAAA,aACrC,OAAO,UAAY,OACnBC,GAAmB,KAYnB,YAAY,CACV,KAAAC,EACA,SAAAC,EAAWH,EAAA,SAAY,CAAC,EAAb,YACX,YAAAI,EAAc,EACd,eAAAC,EAAiB,IACjB,UAAAC,EAAYR,EAAW,OACvB,cAAAS,EAAgB,IAClB,EAAG,CACD,MAAM,CAAE,KAAAL,EAAM,UAAWL,EAAW,IAAK,CAAC,EAE1C,KAAK,SAAWM,EAIhB,KAAKF,GAAmBE,EAExB,KAAK,YAAcC,EACnB,KAAK,YAAc,EACnB,KAAK,eAAiBC,EACtB,KAAK,UAAYC,EACjB,KAAK,cAAgBC,EAErB,KAAK,OAAS,CAAC,EACf,KAAK,OAAS,KACd,KAAK,cAAgB,CAAC,EACtB,KAAK,QAAU,KACf,KAAK,WAAa,IACpB,CAOA,MAAM,SAAU,CACT,KAAK,UACR,KAAK,QAAU,IAAI,QAAQ,CAACC,EAAGC,IAC7B,WAAWA,EAAQ,KAAK,eAAgB,IAAI,MAAM,SAAS,KAAK,IAAI,qBAAqB,KAAK,cAAc,IAAI,CAAC,CACnH,GAGG,KAAK,aACR,KAAK,WAAa,IAAI,MAGxB,KAAK,cAAc,EAEnB,GAAI,CACF,KAAK,OAAS,MAAM,QAAQ,KAAK,CAAC,KAAK,UAAU,EAAG,KAAK,OAAO,CAAC,CACnE,OAASC,EAAO,CACd,GAAI,KAAK,aAAe,KAAK,YAAc,KAAK,YAC9C,KAAK,cACL,KAAK,cAAc,KAAK,CACtB,YAAa,KAAK,YAClB,OAAQ,MAAM,KAAK,QAAQ,CAC7B,CAAC,EAED,KAAK,OAAO,SAAW,IAAI,KAC3B,KAAK,OAAO,kBAAoB,KAAK,OAAO,SAAW,KAAK,OAAO,mBAEnE,KAAK,OAAO,KAAKA,CAAK,EAEtB,KAAK,OAAO,SAAW,IAAI,KAC3B,KAAK,OAAO,kBAAoB,KAAK,OAAO,SAAW,KAAK,OAAO,WAEnE,KAAK,aAAa,EAEd,KAAK,SAAS,eAAe,EAC/B,MAAMA,CAIZ,CAEA,KAAM,CAAE,OAAAC,EAAQ,SAAAC,CAAS,EAAI,KAAK,SAAS,UAAU,EAAE,KAAK,SAAS,EAMrE,MAJM,CAACD,EAAQC,CAAQ,EAAE,SAAS,KAAK,MAAM,GAC3C,KAAK,eAAe,EAGlB,CAAC,OAAQ,UAAU,EAAE,SAAS,KAAK,aAAa,EAC3C,KAAKX,GAGP,IACT,CAQA,gBAAgBE,EAAU,CACxB,GAAIA,GAAYA,EAAS,YAAcN,EAAW,SAChD,MAAO,WACF,GAAIM,GAAYA,EAAS,YAAcN,EAAW,KACvD,MAAO,OACF,GAAI,OAAOM,GAAa,WAC7B,MAAO,WAGT,MAAM,IAAI,MAAM,oEAAoE,CACtF,CASA,uBAAuBU,EAAYC,EAAMC,EAAO,CAC9C,MAAMC,EAAiB,KAAK,SAAS,WAAW,EAAEH,CAAU,EAE5D,GAAI,CAACG,EACH,MAAM,IAAI,MAAM,2BAA2BH,CAAU,aAAa,EAGpEG,EAAeF,CAAI,EAAIC,CACzB,CAMA,IAAI,SAASZ,EAAU,CACrB,KAAK,cAAgB,KAAK,gBAAgBA,CAAQ,EAE9C,CAAC,OAAQ,UAAU,EAAE,SAAS,KAAK,aAAa,GAC9C,KAAK,gBAAkB,SACzBA,EAAS,iBAAmB,KAAK,kBAAoB,MAGvD,KAAK,UAAYA,EAAS,QAAQ,KAAKA,CAAQ,GAE/C,KAAK,UAAYA,EAAS,KAAK,IAAI,CAEvC,CACF",
|
|
6
|
+
"names": ["Base", "base_types", "step_types", "Step", "__name", "#callable_object", "name", "callable", "max_retries", "max_timeout_ms", "step_type", "sub_step_type", "_", "reject", "error", "FAILED", "COMPLETE", "workflowId", "path", "value", "parentWorkflow"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ronaldroe/micro-flow",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "A lightweight, flexible workflow orchestration library for Node.js and browser environments. Build complex, sequential processes with ease using an intuitive API that supports conditional logic, flow control, event handling, and state management.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -95,10 +95,9 @@ export default class Step extends Base {
|
|
|
95
95
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
) {
|
|
98
|
+
const { FAILED, COMPLETE } = this.getState('statuses')[this.base_type];
|
|
99
|
+
|
|
100
|
+
if (! [FAILED, COMPLETE].includes(this.status)) {
|
|
102
101
|
this.markAsComplete();
|
|
103
102
|
}
|
|
104
103
|
|