@ronaldroe/micro-flow 2.0.0 → 3.0.0

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 (34) hide show
  1. package/dist/src/classes/base.js +2 -2
  2. package/dist/src/classes/base.js.map +2 -2
  3. package/dist/src/classes/index.js +1 -1
  4. package/dist/src/classes/index.js.map +2 -2
  5. package/dist/src/classes/instance_state.js +2 -0
  6. package/dist/src/classes/instance_state.js.map +7 -0
  7. package/dist/src/classes/state.js +1 -1
  8. package/dist/src/classes/state.js.map +3 -3
  9. package/dist/src/classes/steps/conditional_step.js +1 -1
  10. package/dist/src/classes/steps/conditional_step.js.map +3 -3
  11. package/dist/src/classes/steps/delay_step.js +1 -1
  12. package/dist/src/classes/steps/delay_step.js.map +3 -3
  13. package/dist/src/classes/steps/flow_control_step.js +1 -1
  14. package/dist/src/classes/steps/flow_control_step.js.map +3 -3
  15. package/dist/src/classes/steps/logic_step.js +1 -1
  16. package/dist/src/classes/steps/logic_step.js.map +3 -3
  17. package/dist/src/classes/steps/step.js +1 -1
  18. package/dist/src/classes/steps/step.js.map +2 -2
  19. package/dist/src/classes/steps/switch_step.js +1 -1
  20. package/dist/src/classes/steps/switch_step.js.map +3 -3
  21. package/dist/src/classes/workflow.js +1 -1
  22. package/dist/src/classes/workflow.js.map +3 -3
  23. package/package.json +1 -1
  24. package/src/classes/base.js +2 -1
  25. package/src/classes/index.js +2 -1
  26. package/src/classes/instance_state.js +277 -0
  27. package/src/classes/state.js +14 -313
  28. package/src/classes/steps/conditional_step.js +3 -2
  29. package/src/classes/steps/delay_step.js +5 -8
  30. package/src/classes/steps/flow_control_step.js +3 -2
  31. package/src/classes/steps/logic_step.js +38 -38
  32. package/src/classes/steps/step.js +12 -6
  33. package/src/classes/steps/switch_step.js +2 -1
  34. package/src/classes/workflow.js +52 -31
@@ -1,2 +1,2 @@
1
- var c=Object.defineProperty;var n=(h,t)=>c(h,"name",{value:t,configurable:!0});import _ from"../base.js";import p from"../workflow.js";import{base_types as o,step_types as f}from"../../enums/index.js";const u={};class r extends _{static{n(this,"Step")}static step_name="step";#t=null;static callable_types={FUNCTION:"function",STEP:"step",WORKFLOW:"workflow"};constructor({name:t,callable:e=n(async()=>{},"callable"),callable_registry_key:s=null,max_retries:i=0,max_timeout_ms:a=3e4,step_type:l=f.ACTION,sub_step_type:y=null}){super({name:t,base_type:o.STEP}),this.callable=e,this.callable_registry_key=s,this.#t=e,this.max_retries=i,this.retry_count=0,this.max_timeout_ms=a,this.step_type=l,this.sub_step_type=y,this.errors=[],this.result=null,this.retry_results=[],this.timeout=null}async execute(){this.timeout||(this.timeout=new Promise((s,i)=>setTimeout(i,this.max_timeout_ms,new Error(`Step "${this.name}" timed out after ${this.max_timeout_ms}ms`)))),this.markAsRunning();try{this.result=await Promise.race([this._callable(),this.timeout])}catch(s){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()});else if(this.errors.push(s),this.markAsFailed(),this.getState("exit_on_error"))throw s}const{FAILED:t,COMPLETE:e}=this.getState("statuses")[this.base_type];return[t,e].includes(this.status)||this.markAsComplete(),["step","workflow"].includes(this.callable_type)?this.#t:this.prepareForSerialization()}getCallableType(t){return r.getCallableType(t)}static getCallableType(t){if(t&&t.base_type===o.WORKFLOW)return r.callable_types.WORKFLOW;if(t&&t.base_type===o.STEP)return r.callable_types.STEP;if(typeof t=="function")return r.callable_types.FUNCTION;throw new Error("Invalid callable type. Must be one of function, Step, or Workflow.")}static registerStepClass(t){u[t.step_name]=t}static resolveStepClass(t){return u[t]??r}static serializeCallableField(t){if(t==null)return null;const e=r.getCallableType(t);return e===r.callable_types.FUNCTION?{type:e,value:t.name}:{type:e,value:t.prepareForSerialization()}}static hydrateCallableField(t,e=null){if(t==null)return;if(typeof t=="function"||t instanceof r||t?.base_type)return t;const{type:s,value:i}=t;if(s===r.callable_types.FUNCTION){if(!e||!e.has(i))throw new Error(`Callable registry key "${i}" not found in registry or registry not provided.`);return e.get(i)}if(s===r.callable_types.STEP)return r.hydrateAny(i,e);if(s===r.callable_types.WORKFLOW)return p.hydrate(i,e);throw new Error(`Unknown callable type "${s}" encountered during hydration.`)}static hydrateAny(t,e=null){return r.resolveStepClass(t.class_name).hydrate(t,e)}prepareForSerialization(){const t={id:this.id,class_name:this.constructor.step_name,name:this.name,callable_type:this.callable_type,step_type:this.step_type,sub_step_type:this.sub_step_type,max_retries:this.max_retries,max_timeout_ms:this.max_timeout_ms,retry_count:this.retry_count,retry_results:this.retry_results,errors:this.errors,result:this.result,timing:this.timing,status:this.status,parent_workflow_id:this.parent_workflow_id};return t.callable=this.callable_registry_key?{type:r.callable_types.FUNCTION,value:this.callable_registry_key}:r.serializeCallableField(this.#t),t}setParentWorkflowValue(t,e,s){const i=this.getState("workflows")[t];if(!i)throw new Error(`Parent workflow with ID ${t} not found.`);i[e]=s}serialize(){return JSON.stringify(this.prepareForSerialization())}toJSON(){return this.prepareForSerialization()}set callable(t){this.callable_type=this.getCallableType(t),["step","workflow"].includes(this.callable_type)?(this.callable_type==="step"&&(t.parent_workflow_id=this.parent_workflow_id??null),this._callable=t.execute.bind(t)):this._callable=t.bind(this)}static hydrateSerialized(t,e=null){if(typeof t!="string")throw new Error("Invalid serialized step. Must be a string.");return r.hydrateAny(JSON.parse(t),e)}static hydrate(t,e=null){const s=t.callable,i=r.hydrateCallableField(s,e),a=s?.type===r.callable_types.FUNCTION?s.value:null,l=new this({...t,callable:i,callable_registry_key:a});return l.id=t.id,l.retry_count=t.retry_count??0,l.retry_results=t.retry_results??[],l.errors=t.errors??[],l.result=t.result??null,l.timing=t.timing,l.status=t.status,l.parent_workflow_id=t.parent_workflow_id??null,l}}r.registerStepClass(r);export{r as default};
1
+ var _=Object.defineProperty;var n=(y,t)=>_(y,"name",{value:t,configurable:!0});import p from"../base.js";import u from"../workflow.js";import{base_types as o,step_types as f}from"../../enums/index.js";const h={};class r extends p{static{n(this,"Step")}static step_name="step";#t=null;static callable_types={FUNCTION:"function",STEP:"step",WORKFLOW:"workflow"};constructor({name:t,callable:e=n(async()=>{},"callable"),callable_registry_key:s=null,max_retries:i=0,max_timeout_ms:a=3e4,step_type:l=f.ACTION,sub_step_type:c=null}){super({name:t,base_type:o.STEP}),this.callable=e,this.callable_registry_key=s,this.#t=e,this.max_retries=i,this.retry_count=0,this.max_timeout_ms=a,this.step_type=l,this.sub_step_type=c,this.errors=[],this.result=null,this.retry_results=[],this.timeout=null}async execute(){this.timeout||(this.timeout=new Promise((s,i)=>setTimeout(i,this.max_timeout_ms,new Error(`Step "${this.name}" timed out after ${this.max_timeout_ms}ms`)))),this.markAsRunning();try{this.result=await Promise.race([this._callable(),this.timeout])}catch(s){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()});else if(this.errors.push(s),this.markAsFailed(),this.getState("exit_on_error"))throw s}const{FAILED:t,COMPLETE:e}=u.statuses[this.base_type];return[t,e].includes(this.status)||this.markAsComplete(),["step","workflow"].includes(this.callable_type)?this.#t:this.prepareForSerialization()}getCallableType(t){return r.getCallableType(t)}static getCallableType(t){if(t&&t.base_type===o.WORKFLOW)return r.callable_types.WORKFLOW;if(t&&t.base_type===o.STEP)return r.callable_types.STEP;if(typeof t=="function")return r.callable_types.FUNCTION;throw new Error("Invalid callable type. Must be one of function, Step, or Workflow.")}static registerStepClass(t){h[t.step_name]=t}static resolveStepClass(t){return h[t]??r}static serializeCallableField(t){if(t==null)return null;const e=r.getCallableType(t);return e===r.callable_types.FUNCTION?{type:e,value:t.name}:{type:e,value:t.prepareForSerialization()}}static hydrateCallableField(t,e=null){if(t==null)return;if(typeof t=="function"||t instanceof r||t?.base_type)return t;const{type:s,value:i}=t;if(s===r.callable_types.FUNCTION){if(!e||!e.has(i))throw new Error(`Callable registry key "${i}" not found in registry or registry not provided.`);return e.get(i)}if(s===r.callable_types.STEP)return r.hydrateAny(i,e);if(s===r.callable_types.WORKFLOW)return u.hydrate(i,e);throw new Error(`Unknown callable type "${s}" encountered during hydration.`)}static hydrateAny(t,e=null){return r.resolveStepClass(t.class_name).hydrate(t,e)}prepareForSerialization(){const t={id:this.id,class_name:this.constructor.step_name,name:this.name,callable_type:this.callable_type,step_type:this.step_type,sub_step_type:this.sub_step_type,max_retries:this.max_retries,max_timeout_ms:this.max_timeout_ms,retry_count:this.retry_count,retry_results:this.retry_results,errors:this.errors,result:this.result,timing:this.timing,status:this.status,parent_workflow_id:this.parent_workflow_id};return t.callable=this.callable_registry_key?{type:r.callable_types.FUNCTION,value:this.callable_registry_key}:r.serializeCallableField(this.#t),t}setParentWorkflowValue(t,e,s){const i=this.use_state_singleton?this.getState("workflows")[t]:this.getState("workflow");if(!i||i.id!==t)throw new Error(`Parent workflow with ID ${t} not found.`);i[e]=s}serialize(){return JSON.stringify(this.prepareForSerialization())}toJSON(){return this.prepareForSerialization()}set callable(t){this.callable_type=this.getCallableType(t),["step","workflow"].includes(this.callable_type)?(this.callable_type==="step"&&(t.parent_workflow_id=this.parent_workflow_id??null),this._callable=t.execute.bind(t)):this._callable=t.bind(this)}static hydrateSerialized(t,e=null){if(typeof t!="string")throw new Error("Invalid serialized step. Must be a string.");return r.hydrateAny(JSON.parse(t),e)}static hydrate(t,e=null){const s=t.callable,i=r.hydrateCallableField(s,e),a=s?.type===r.callable_types.FUNCTION?s.value:null,l=new this({...t,callable:i,callable_registry_key:a});return l.id=t.id,l.retry_count=t.retry_count??0,l.retry_results=t.retry_results??[],l.errors=t.errors??[],l.result=t.result??null,l.timing=t.timing,l.status=t.status,l.parent_workflow_id=t.parent_workflow_id??null,l}}r.registerStepClass(r);export{r 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// Populated by each Step subclass file registering itself (see the bottom of\n// step.js and each subclass file) - keeps this file from importing every\n// subclass directly, which would create an import cycle through the hierarchy.\nconst step_class_registry = {};\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 static callable_types = {\n FUNCTION: 'function',\n STEP: 'step',\n WORKFLOW: 'workflow',\n }\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 callable_registry_key = null,\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 // Optional key to reference the callable to be rehydrated after serialization.\n this.callable_registry_key = callable_registry_key;\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 }\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(\n reject,\n this.max_timeout_ms,\n new Error(`Step \"${this.name}\" timed out after ${this.max_timeout_ms}ms`)\n )\n );\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 } else {\n this.errors.push(error);\n\n this.markAsFailed();\n\n if (this.getState('exit_on_error')) {\n throw error;\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.prepareForSerialization();\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 return Step.getCallableType(callable);\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 static getCallableType(callable) {\n if (callable && callable.base_type === base_types.WORKFLOW) {\n return Step.callable_types.WORKFLOW;\n } else if (callable && callable.base_type === base_types.STEP) {\n return Step.callable_types.STEP;\n } else if (typeof callable === 'function') {\n return Step.callable_types.FUNCTION;\n }\n\n throw new Error('Invalid callable type. Must be one of function, Step, or Workflow.');\n }\n\n /**\n * Registers a Step subclass so hydration can rebuild instances of the correct type.\n * Called as a side effect at the bottom of each step subclass file.\n * @param {typeof Step} StepClass - The Step subclass to register, keyed by its static `step_name`.\n */\n static registerStepClass(StepClass) {\n step_class_registry[StepClass.step_name] = StepClass;\n }\n\n /**\n * Resolves a `step_name` (as stored in `class_name` on a serialized step) to its class.\n * Falls back to the base `Step` class if the name is unknown.\n * @param {string} step_name - The step_name to resolve.\n * @returns {typeof Step} The resolved Step subclass.\n */\n static resolveStepClass(step_name) {\n return step_class_registry[step_name] ?? Step;\n }\n\n /**\n * Serializes a callable-like value (function, Step, or Workflow) into a plain, JSON-safe descriptor.\n * @param {Function|Step|Workflow|null} callable - The callable to serialize.\n * @returns {Object|null} A `{ type, value }` descriptor, or null if no callable was given.\n */\n static serializeCallableField(callable) {\n if (callable === null || callable === undefined) {\n return null;\n }\n\n const type = Step.getCallableType(callable);\n\n if (type === Step.callable_types.FUNCTION) {\n return { type, value: callable.name };\n }\n\n return { type, value: callable.prepareForSerialization() };\n }\n\n /**\n * Hydrates a callable-like descriptor (as produced by `serializeCallableField`) back into a\n * live function, Step, or Workflow. Idempotent - passing an already-hydrated value through\n * returns it unchanged, since subclass `hydrate` overrides may resolve a field before\n * delegating to a superclass `hydrate` that would otherwise try to resolve it again.\n * @param {Object|Function|Step|Workflow|null} serialized - The descriptor (or already-hydrated value) to hydrate.\n * @param {import('../callable_registry.js').default|null} [callable_registry] - Registry used to resolve function callables.\n * @returns {Function|Step|Workflow|undefined} The hydrated callable, or undefined if nothing was given.\n * @throws {Error} Throws if a function callable can't be found in the registry, or the descriptor type is unknown.\n */\n static hydrateCallableField(serialized, callable_registry = null) {\n if (serialized === null || serialized === undefined) {\n return undefined;\n }\n\n if (typeof serialized === 'function' || serialized instanceof Step || serialized?.base_type) {\n return serialized;\n }\n\n const { type, value } = serialized;\n\n if (type === Step.callable_types.FUNCTION) {\n if (!callable_registry || !callable_registry.has(value)) {\n throw new Error(`Callable registry key \"${value}\" not found in registry or registry not provided.`);\n }\n\n return callable_registry.get(value);\n }\n\n if (type === Step.callable_types.STEP) {\n return Step.hydrateAny(value, callable_registry);\n }\n\n if (type === Step.callable_types.WORKFLOW) {\n return Workflow.hydrate(value, callable_registry);\n }\n\n throw new Error(`Unknown callable type \"${type}\" encountered during hydration.`);\n }\n\n /**\n * Hydrates a parsed step object into an instance of its correct Step subclass,\n * resolved from its serialized `class_name`.\n * @param {Object} parsed_step - The parsed step object.\n * @param {import('../callable_registry.js').default|null} [callable_registry] - Registry used to resolve function callables.\n * @returns {Step} The hydrated Step (or subclass) instance.\n */\n static hydrateAny(parsed_step, callable_registry = null) {\n const StepClass = Step.resolveStepClass(parsed_step.class_name);\n\n return StepClass.hydrate(parsed_step, callable_registry);\n }\n\n /**\n * Inserts safely serializable properties of the step into a new object for serialization.\n * @returns {Object} An object containing the step's properties ready for serialization.\n */\n prepareForSerialization() {\n const serialized_step = {\n id: this.id,\n class_name: this.constructor.step_name,\n name: this.name,\n callable_type: this.callable_type,\n step_type: this.step_type,\n sub_step_type: this.sub_step_type,\n max_retries: this.max_retries,\n max_timeout_ms: this.max_timeout_ms,\n retry_count: this.retry_count,\n retry_results: this.retry_results,\n errors: this.errors,\n result: this.result,\n timing: this.timing,\n status: this.status,\n parent_workflow_id: this.parent_workflow_id,\n };\n\n serialized_step.callable = this.callable_registry_key\n ? { type: Step.callable_types.FUNCTION, value: this.callable_registry_key }\n : Step.serializeCallableField(this.#callable_object);\n\n return serialized_step;\n }\n\n /**\n * Sets a value in the parent workflow's state.\n * @param {string} workflow_id - 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(workflow_id, path, value) {\n const parent_workflow = this.getState('workflows')[workflow_id];\n\n if (!parent_workflow) {\n throw new Error(`Parent workflow with ID ${workflow_id} not found.`);\n }\n\n parent_workflow[path] = value;\n }\n\n /**\n * Serializes the step into a JSON string.\n * @returns {string} The JSON string representation of the step.\n */\n serialize() {\n return JSON.stringify(this.prepareForSerialization());\n }\n\n /**\n * Custom JSON serializer\n * @returns {Object} The JSON representation of the step.\n */\n toJSON() {\n return this.prepareForSerialization();\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.parent_workflow_id = this.parent_workflow_id ?? null;\n }\n\n this._callable = callable.execute.bind(callable);\n } else {\n this._callable = callable.bind(this);\n }\n }\n\n /**\n * Deserializes a JSON string into a Step instance and hydrates it, dispatching to the correct subclass.\n * @param {string} serialized_step - The JSON string representation of the step.\n * @param {import('../callable_registry.js').default|null} [callable_registry] - Registry used to resolve function callables.\n * @returns {Step} The hydrated Step (or subclass) instance.\n * @throws {Error} Throws if the serialized step is not a string.\n */\n static hydrateSerialized(serialized_step, callable_registry = null) {\n if (typeof serialized_step !== 'string') {\n throw new Error('Invalid serialized step. Must be a string.');\n }\n\n return Step.hydrateAny(JSON.parse(serialized_step), callable_registry);\n }\n\n /**\n * Hydrates a parsed step object into an instance of `this` class, resolving its callable\n * (and restoring execution metadata) from the serialized data.\n * Subclasses with extra callable-like fields (e.g. ConditionalStep's true_callable/false_callable)\n * should resolve those fields with `Step.hydrateCallableField` and delegate to `super.hydrate()`.\n * @param {Object} parsed_step - The parsed step object.\n * @param {import('../callable_registry.js').default|null} [callable_registry] - Registry used to resolve function callables.\n * @returns {Step} The hydrated Step instance.\n * @throws {Error} Throws if a callable registry key is specified but not found in the registry.\n */\n static hydrate(parsed_step, callable_registry = null) {\n const callable_descriptor = parsed_step.callable;\n const callable = Step.hydrateCallableField(callable_descriptor, callable_registry);\n const callable_registry_key = callable_descriptor?.type === Step.callable_types.FUNCTION\n ? callable_descriptor.value\n : null;\n\n const instance = new this({ ...parsed_step, callable, callable_registry_key });\n\n instance.id = parsed_step.id;\n instance.retry_count = parsed_step.retry_count ?? 0;\n instance.retry_results = parsed_step.retry_results ?? [];\n instance.errors = parsed_step.errors ?? [];\n instance.result = parsed_step.result ?? null;\n instance.timing = parsed_step.timing;\n instance.status = parsed_step.status;\n instance.parent_workflow_id = parsed_step.parent_workflow_id ?? null;\n\n return instance;\n }\n}\n\nStep.registerStepClass(Step);\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import Base from '../base.js';\nimport Workflow from '../workflow.js';\nimport { base_types, step_types } from '../../enums/index.js';\n\n// Populated by each Step subclass file registering itself (see the bottom of\n// step.js and each subclass file) - keeps this file from importing every\n// subclass directly, which would create an import cycle through the hierarchy.\nconst step_class_registry = {};\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 static callable_types = {\n FUNCTION: 'function',\n STEP: 'step',\n WORKFLOW: 'workflow',\n }\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 callable_registry_key = null,\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 // Optional key to reference the callable to be rehydrated after serialization.\n this.callable_registry_key = callable_registry_key;\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 }\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(\n reject,\n this.max_timeout_ms,\n new Error(`Step \"${this.name}\" timed out after ${this.max_timeout_ms}ms`)\n )\n );\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 } else {\n this.errors.push(error);\n\n this.markAsFailed();\n\n if (this.getState('exit_on_error')) {\n throw error;\n }\n }\n }\n\n const { FAILED, COMPLETE } = Workflow.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.prepareForSerialization();\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 return Step.getCallableType(callable);\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 static getCallableType(callable) {\n if (callable && callable.base_type === base_types.WORKFLOW) {\n return Step.callable_types.WORKFLOW;\n } else if (callable && callable.base_type === base_types.STEP) {\n return Step.callable_types.STEP;\n } else if (typeof callable === 'function') {\n return Step.callable_types.FUNCTION;\n }\n\n throw new Error('Invalid callable type. Must be one of function, Step, or Workflow.');\n }\n\n /**\n * Registers a Step subclass so hydration can rebuild instances of the correct type.\n * Called as a side effect at the bottom of each step subclass file.\n * @param {typeof Step} StepClass - The Step subclass to register, keyed by its static `step_name`.\n */\n static registerStepClass(StepClass) {\n step_class_registry[StepClass.step_name] = StepClass;\n }\n\n /**\n * Resolves a `step_name` (as stored in `class_name` on a serialized step) to its class.\n * Falls back to the base `Step` class if the name is unknown.\n * @param {string} step_name - The step_name to resolve.\n * @returns {typeof Step} The resolved Step subclass.\n */\n static resolveStepClass(step_name) {\n return step_class_registry[step_name] ?? Step;\n }\n\n /**\n * Serializes a callable-like value (function, Step, or Workflow) into a plain, JSON-safe descriptor.\n * @param {Function|Step|Workflow|null} callable - The callable to serialize.\n * @returns {Object|null} A `{ type, value }` descriptor, or null if no callable was given.\n */\n static serializeCallableField(callable) {\n if (callable === null || callable === undefined) {\n return null;\n }\n\n const type = Step.getCallableType(callable);\n\n if (type === Step.callable_types.FUNCTION) {\n return { type, value: callable.name };\n }\n\n return { type, value: callable.prepareForSerialization() };\n }\n\n /**\n * Hydrates a callable-like descriptor (as produced by `serializeCallableField`) back into a\n * live function, Step, or Workflow. Idempotent - passing an already-hydrated value through\n * returns it unchanged, since subclass `hydrate` overrides may resolve a field before\n * delegating to a superclass `hydrate` that would otherwise try to resolve it again.\n * @param {Object|Function|Step|Workflow|null} serialized - The descriptor (or already-hydrated value) to hydrate.\n * @param {import('../callable_registry.js').default|null} [callable_registry] - Registry used to resolve function callables.\n * @returns {Function|Step|Workflow|undefined} The hydrated callable, or undefined if nothing was given.\n * @throws {Error} Throws if a function callable can't be found in the registry, or the descriptor type is unknown.\n */\n static hydrateCallableField(serialized, callable_registry = null) {\n if (serialized === null || serialized === undefined) {\n return undefined;\n }\n\n if (typeof serialized === 'function' || serialized instanceof Step || serialized?.base_type) {\n return serialized;\n }\n\n const { type, value } = serialized;\n\n if (type === Step.callable_types.FUNCTION) {\n if (!callable_registry || !callable_registry.has(value)) {\n throw new Error(`Callable registry key \"${value}\" not found in registry or registry not provided.`);\n }\n\n return callable_registry.get(value);\n }\n\n if (type === Step.callable_types.STEP) {\n return Step.hydrateAny(value, callable_registry);\n }\n\n if (type === Step.callable_types.WORKFLOW) {\n return Workflow.hydrate(value, callable_registry);\n }\n\n throw new Error(`Unknown callable type \"${type}\" encountered during hydration.`);\n }\n\n /**\n * Hydrates a parsed step object into an instance of its correct Step subclass,\n * resolved from its serialized `class_name`.\n * @param {Object} parsed_step - The parsed step object.\n * @param {import('../callable_registry.js').default|null} [callable_registry] - Registry used to resolve function callables.\n * @returns {Step} The hydrated Step (or subclass) instance.\n */\n static hydrateAny(parsed_step, callable_registry = null) {\n const StepClass = Step.resolveStepClass(parsed_step.class_name);\n\n return StepClass.hydrate(parsed_step, callable_registry);\n }\n\n /**\n * Inserts safely serializable properties of the step into a new object for serialization.\n * @returns {Object} An object containing the step's properties ready for serialization.\n */\n prepareForSerialization() {\n const serialized_step = {\n id: this.id,\n class_name: this.constructor.step_name,\n name: this.name,\n callable_type: this.callable_type,\n step_type: this.step_type,\n sub_step_type: this.sub_step_type,\n max_retries: this.max_retries,\n max_timeout_ms: this.max_timeout_ms,\n retry_count: this.retry_count,\n retry_results: this.retry_results,\n errors: this.errors,\n result: this.result,\n timing: this.timing,\n status: this.status,\n parent_workflow_id: this.parent_workflow_id,\n };\n\n serialized_step.callable = this.callable_registry_key\n ? { type: Step.callable_types.FUNCTION, value: this.callable_registry_key }\n : Step.serializeCallableField(this.#callable_object);\n\n return serialized_step;\n }\n\n /**\n * Sets a value on the parent workflow instance itself. Normally this is the live object\n * shared via this step's own state under the `workflow` key (see `initializeWorkflowState()`\n * in `workflow.js`); when `use_state_singleton` is `true`, several unrelated workflows can\n * share the same process-wide state, so it's looked up by id in the singleton's `workflows`\n * registry instead.\n * @param {string} workflow_id - ID of the parent workflow.\n * @param {string} path - Property name to set on the workflow instance.\n * @param {*} value - Value to set at the specified path.\n * @throws {Error} Throws if the parent workflow is not found.\n */\n setParentWorkflowValue(workflow_id, path, value) {\n const parent_workflow = this.use_state_singleton\n ? this.getState('workflows')[workflow_id]\n : this.getState('workflow');\n\n if (!parent_workflow || parent_workflow.id !== workflow_id) {\n throw new Error(`Parent workflow with ID ${workflow_id} not found.`);\n }\n\n parent_workflow[path] = value;\n }\n\n /**\n * Serializes the step into a JSON string.\n * @returns {string} The JSON string representation of the step.\n */\n serialize() {\n return JSON.stringify(this.prepareForSerialization());\n }\n\n /**\n * Custom JSON serializer\n * @returns {Object} The JSON representation of the step.\n */\n toJSON() {\n return this.prepareForSerialization();\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.parent_workflow_id = this.parent_workflow_id ?? null;\n }\n\n this._callable = callable.execute.bind(callable);\n } else {\n this._callable = callable.bind(this);\n }\n }\n\n /**\n * Deserializes a JSON string into a Step instance and hydrates it, dispatching to the correct subclass.\n * @param {string} serialized_step - The JSON string representation of the step.\n * @param {import('../callable_registry.js').default|null} [callable_registry] - Registry used to resolve function callables.\n * @returns {Step} The hydrated Step (or subclass) instance.\n * @throws {Error} Throws if the serialized step is not a string.\n */\n static hydrateSerialized(serialized_step, callable_registry = null) {\n if (typeof serialized_step !== 'string') {\n throw new Error('Invalid serialized step. Must be a string.');\n }\n\n return Step.hydrateAny(JSON.parse(serialized_step), callable_registry);\n }\n\n /**\n * Hydrates a parsed step object into an instance of `this` class, resolving its callable\n * (and restoring execution metadata) from the serialized data.\n * Subclasses with extra callable-like fields (e.g. ConditionalStep's true_callable/false_callable)\n * should resolve those fields with `Step.hydrateCallableField` and delegate to `super.hydrate()`.\n * @param {Object} parsed_step - The parsed step object.\n * @param {import('../callable_registry.js').default|null} [callable_registry] - Registry used to resolve function callables.\n * @returns {Step} The hydrated Step instance.\n * @throws {Error} Throws if a callable registry key is specified but not found in the registry.\n */\n static hydrate(parsed_step, callable_registry = null) {\n const callable_descriptor = parsed_step.callable;\n const callable = Step.hydrateCallableField(callable_descriptor, callable_registry);\n const callable_registry_key = callable_descriptor?.type === Step.callable_types.FUNCTION\n ? callable_descriptor.value\n : null;\n\n const instance = new this({ ...parsed_step, callable, callable_registry_key });\n\n instance.id = parsed_step.id;\n instance.retry_count = parsed_step.retry_count ?? 0;\n instance.retry_results = parsed_step.retry_results ?? [];\n instance.errors = parsed_step.errors ?? [];\n instance.result = parsed_step.result ?? null;\n instance.timing = parsed_step.timing;\n instance.status = parsed_step.status;\n instance.parent_workflow_id = parsed_step.parent_workflow_id ?? null;\n\n return instance;\n }\n}\n\nStep.registerStepClass(Step);\n"],
5
+ "mappings": "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",
6
6
  "names": ["Base", "Workflow", "base_types", "step_types", "step_class_registry", "Step", "__name", "#callable_object", "name", "callable", "callable_registry_key", "max_retries", "max_timeout_ms", "step_type", "sub_step_type", "_", "reject", "error", "FAILED", "COMPLETE", "StepClass", "step_name", "type", "serialized", "callable_registry", "value", "parsed_step", "serialized_step", "workflow_id", "path", "parent_workflow", "callable_descriptor", "instance"]
7
7
  }
@@ -1,2 +1,2 @@
1
- var u=Object.defineProperty;var c=(r,e)=>u(r,"name",{value:e,configurable:!0});import s from"./step.js";class l extends s{static{c(this,"SwitchStep")}static step_name="switch";constructor({name:e,cases:a=[],default_callable:t=c(async()=>{},"default_callable"),subject:i=null,default_callable_registry_key:_=null}){super({name:e,step_type:l.step_name}),this.cases=a,this.default_callable_registry_key=_,this._default_callable_type=this.getCallableType(t),this._default_callable_raw=t,this.default_callable=this._default_callable_type==="function"?t.bind(this):t.execute.bind(t),this.subject=i,this.callable=this.switch.bind(this)}async switch(){const e=typeof this.subject=="function"?this.subject():this.subject;for(const t of this.cases)if(t.switch_subject=e,t.parent_workflow_id=this.parent_workflow_id,t.use_state_singleton=this.use_state_singleton,t.state=this.state,await t.checkCondition())return this.log(this.getState("events.step.event_names.SWITCH_CASE_MATCHED"),`Case matched for step: ${this.name}, executing case callable`),(await t.execute()).result;this._default_callable_type!=="function"&&(this._default_callable_raw.parent_workflow_id=this.parent_workflow_id,this._default_callable_raw.use_state_singleton=this.use_state_singleton,this._default_callable_raw.state=this.state);const a=await this.default_callable();return this._default_callable_type!=="function"?a.result:a}prepareForSerialization(){return{...super.prepareForSerialization(),callable:null,cases:this.cases.map(e=>e.prepareForSerialization()),default_callable:this.default_callable_registry_key?{type:s.callable_types.FUNCTION,value:this.default_callable_registry_key}:s.serializeCallableField(this._default_callable_raw),subject:typeof this.subject=="function"?null:this.subject}}static hydrate(e,a=null){const t=e.default_callable;return super.hydrate({...e,cases:(e.cases??[]).map(i=>s.hydrateAny(i,a)),default_callable:s.hydrateCallableField(t,a),default_callable_registry_key:t?.type===s.callable_types.FUNCTION?t.value:null},a)}}l.registerStepClass(l);export{l as default};
1
+ var u=Object.defineProperty;var c=(r,e)=>u(r,"name",{value:e,configurable:!0});import s from"./step.js";import{event_names as n}from"../instance_state.js";class l extends s{static{c(this,"SwitchStep")}static step_name="switch";constructor({name:e,cases:a=[],default_callable:t=c(async()=>{},"default_callable"),subject:i=null,default_callable_registry_key:_=null}){super({name:e,step_type:l.step_name}),this.cases=a,this.default_callable_registry_key=_,this._default_callable_type=this.getCallableType(t),this._default_callable_raw=t,this.default_callable=this._default_callable_type==="function"?t.bind(this):t.execute.bind(t),this.subject=i,this.callable=this.switch.bind(this)}async switch(){const e=typeof this.subject=="function"?this.subject():this.subject;for(const t of this.cases)if(t.switch_subject=e,t.parent_workflow_id=this.parent_workflow_id,t.use_state_singleton=this.use_state_singleton,t.state=this.state,await t.checkCondition())return this.log(n.step.SWITCH_CASE_MATCHED,`Case matched for step: ${this.name}, executing case callable`),(await t.execute()).result;this._default_callable_type!=="function"&&(this._default_callable_raw.parent_workflow_id=this.parent_workflow_id,this._default_callable_raw.use_state_singleton=this.use_state_singleton,this._default_callable_raw.state=this.state);const a=await this.default_callable();return this._default_callable_type!=="function"?a.result:a}prepareForSerialization(){return{...super.prepareForSerialization(),callable:null,cases:this.cases.map(e=>e.prepareForSerialization()),default_callable:this.default_callable_registry_key?{type:s.callable_types.FUNCTION,value:this.default_callable_registry_key}:s.serializeCallableField(this._default_callable_raw),subject:typeof this.subject=="function"?null:this.subject}}static hydrate(e,a=null){const t=e.default_callable;return super.hydrate({...e,cases:(e.cases??[]).map(i=>s.hydrateAny(i,a)),default_callable:s.hydrateCallableField(t,a),default_callable_registry_key:t?.type===s.callable_types.FUNCTION?t.value:null},a)}}l.registerStepClass(l);export{l as default};
2
2
  //# sourceMappingURL=switch_step.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/classes/steps/switch_step.js"],
4
- "sourcesContent": ["import Step from './step.js';\n\n/**\n * SwitchStep class for implementing switch/case logic in workflows.\n * Evaluates cases in order and executes the first matching case, or a default callable if no cases match.\n * @class SwitchStep\n * @extends Step\n */\nexport default class SwitchStep extends Step {\n static step_name = 'switch';\n\n /**\n * Creates a new SwitchStep instance.\n * @param {Object} options - Configuration options.\n * @param {string} [options.name] - Name of the step.\n * @param {Array<Case|LogicStep>} [options.cases=[]] - Array of Case or LogicStep instances to evaluate. LogicStep instances MUST have conditional.subject set.\n * @param {Function|Step|Workflow} [options.default_callable=async () => {}] - Function, Step, or Workflow to execute if no cases match.\n * @param {*|Function} [options.subject=null] - Subject value to evaluate against each case. Can be a function that returns the value.\n * @param {string|null} [options.default_callable_registry_key=null] - Optional key to reference default_callable to be rehydrated after serialization.\n */\n constructor({\n name,\n cases = [],\n default_callable = async () => {},\n subject = null,\n default_callable_registry_key = null,\n }) {\n super({\n name,\n step_type: SwitchStep.step_name,\n });\n\n this.cases = cases;\n this.default_callable_registry_key = default_callable_registry_key;\n this._default_callable_type = this.getCallableType(default_callable);\n this._default_callable_raw = default_callable;\n this.default_callable = this._default_callable_type === 'function'\n ? default_callable.bind(this)\n : default_callable.execute.bind(default_callable);\n this.subject = subject;\n\n this.callable = this.switch.bind(this);\n }\n\n /**\n * Executes the switch logic by evaluating each case in order.\n * Returns the result of the first matching case, or the default callable if no match.\n * Every `Case` (and, if it's a `Step`/`Workflow`, `default_callable`) is stamped with this\n * step's own `parent_workflow_id`/`use_state_singleton`/`state` before it runs, since `cases`\n * lives on this step rather than the parent workflow's `_steps`, so it never goes through\n * `Workflow.addStep()` to pick those up on its own.\n * @returns {Promise<*>} The result of the matched case or default callable.\n */\n async switch() {\n // Resolve subject once - call it if it's a function\n const resolved_subject = typeof this.subject === 'function' ? this.subject() : this.subject;\n \n for (const switch_case of this.cases) {\n switch_case.switch_subject = resolved_subject;\n // Cases live in `this.cases`, not the workflow's `_steps` array, so they never go through\n // Workflow.addStep() - stamp them here instead, mirroring what addStep() does.\n switch_case.parent_workflow_id = this.parent_workflow_id;\n switch_case.use_state_singleton = this.use_state_singleton;\n switch_case.state = this.state;\n\n const is_matched = await switch_case.checkCondition();\n\n if (is_matched) {\n this.log(\n this.getState('events.step.event_names.SWITCH_CASE_MATCHED'),\n `Case matched for step: ${this.name}, executing case callable`\n );\n\n // Return the case's result value directly, not the Case object.\n // This keeps result structure consistent: switchStep.result contains the\n // callable's return value, matching how Step.result works.\n const case_result = await switch_case.execute();\n return case_result.result;\n }\n }\n\n // Unwrap Step/Workflow results for consistency with case results\n if (this._default_callable_type !== 'function') {\n this._default_callable_raw.parent_workflow_id = this.parent_workflow_id;\n this._default_callable_raw.use_state_singleton = this.use_state_singleton;\n this._default_callable_raw.state = this.state;\n }\n\n const default_result = await this.default_callable();\n if (this._default_callable_type !== 'function') {\n return default_result.result;\n }\n return default_result;\n }\n\n /**\n * Inserts safely serializable properties of the step into a new object for serialization.\n * Note: a function-valued `subject` is not persisted, since there's no registry for it.\n * @returns {Object} An object containing the step's properties ready for serialization.\n */\n prepareForSerialization() {\n return {\n ...super.prepareForSerialization(),\n // The base `callable` is an internal wiring detail (the bound `switch` method) -\n // SwitchStep's constructor doesn't take a callable, so it isn't real data to persist.\n callable: null,\n cases: this.cases.map(switch_case => switch_case.prepareForSerialization()),\n default_callable: this.default_callable_registry_key\n ? { type: Step.callable_types.FUNCTION, value: this.default_callable_registry_key }\n : Step.serializeCallableField(this._default_callable_raw),\n subject: typeof this.subject === 'function' ? null : this.subject,\n };\n }\n\n /**\n * Hydrates a parsed step object into a SwitchStep instance, resolving its cases and default callable.\n * @param {Object} parsed_step - The parsed step object.\n * @param {import('../callable_registry.js').default|null} [callable_registry] - Registry used to resolve function callables.\n * @returns {SwitchStep} The hydrated SwitchStep instance.\n */\n static hydrate(parsed_step, callable_registry = null) {\n const default_descriptor = parsed_step.default_callable;\n\n return super.hydrate({\n ...parsed_step,\n cases: (parsed_step.cases ?? []).map(switch_case => Step.hydrateAny(switch_case, callable_registry)),\n default_callable: Step.hydrateCallableField(default_descriptor, callable_registry),\n default_callable_registry_key: default_descriptor?.type === Step.callable_types.FUNCTION\n ? default_descriptor.value\n : null,\n }, callable_registry);\n }\n}\n\nSwitchStep.registerStepClass(SwitchStep);\n"],
5
- "mappings": "+EAAA,OAAOA,MAAU,YAQjB,MAAOC,UAAiCD,CAAK,CAR7C,MAQ6C,CAAAE,EAAA,mBAC3C,OAAO,UAAY,SAWnB,YAAY,CACV,KAAAC,EACA,MAAAC,EAAQ,CAAC,EACT,iBAAAC,EAAmBH,EAAA,SAAY,CAAC,EAAb,oBACnB,QAAAI,EAAU,KACV,8BAAAC,EAAgC,IAClC,EAAG,CACD,MAAM,CACJ,KAAAJ,EACA,UAAWF,EAAW,SACxB,CAAC,EAED,KAAK,MAAQG,EACb,KAAK,8BAAgCG,EACrC,KAAK,uBAAyB,KAAK,gBAAgBF,CAAgB,EACnE,KAAK,sBAAwBA,EAC7B,KAAK,iBAAmB,KAAK,yBAA2B,WACpDA,EAAiB,KAAK,IAAI,EAC1BA,EAAiB,QAAQ,KAAKA,CAAgB,EAClD,KAAK,QAAUC,EAEf,KAAK,SAAW,KAAK,OAAO,KAAK,IAAI,CACvC,CAWA,MAAM,QAAS,CAEb,MAAME,EAAmB,OAAO,KAAK,SAAY,WAAa,KAAK,QAAQ,EAAI,KAAK,QAEpF,UAAWC,KAAe,KAAK,MAU7B,GATAA,EAAY,eAAiBD,EAG7BC,EAAY,mBAAqB,KAAK,mBACtCA,EAAY,oBAAsB,KAAK,oBACvCA,EAAY,MAAQ,KAAK,MAEN,MAAMA,EAAY,eAAe,EAGlD,YAAK,IACH,KAAK,SAAS,6CAA6C,EAC3D,0BAA0B,KAAK,IAAI,2BACrC,GAKoB,MAAMA,EAAY,QAAQ,GAC3B,OAKnB,KAAK,yBAA2B,aAClC,KAAK,sBAAsB,mBAAqB,KAAK,mBACrD,KAAK,sBAAsB,oBAAsB,KAAK,oBACtD,KAAK,sBAAsB,MAAQ,KAAK,OAG1C,MAAMC,EAAiB,MAAM,KAAK,iBAAiB,EACnD,OAAI,KAAK,yBAA2B,WAC3BA,EAAe,OAEjBA,CACT,CAOA,yBAA0B,CACxB,MAAO,CACL,GAAG,MAAM,wBAAwB,EAGjC,SAAU,KACV,MAAO,KAAK,MAAM,IAAID,GAAeA,EAAY,wBAAwB,CAAC,EAC1E,iBAAkB,KAAK,8BACnB,CAAE,KAAMT,EAAK,eAAe,SAAU,MAAO,KAAK,6BAA8B,EAChFA,EAAK,uBAAuB,KAAK,qBAAqB,EAC1D,QAAS,OAAO,KAAK,SAAY,WAAa,KAAO,KAAK,OAC5D,CACF,CAQA,OAAO,QAAQW,EAAaC,EAAoB,KAAM,CACpD,MAAMC,EAAqBF,EAAY,iBAEvC,OAAO,MAAM,QAAQ,CACnB,GAAGA,EACH,OAAQA,EAAY,OAAS,CAAC,GAAG,IAAIF,GAAeT,EAAK,WAAWS,EAAaG,CAAiB,CAAC,EACnG,iBAAkBZ,EAAK,qBAAqBa,EAAoBD,CAAiB,EACjF,8BAA+BC,GAAoB,OAASb,EAAK,eAAe,SAC5Ea,EAAmB,MACnB,IACN,EAAGD,CAAiB,CACtB,CACF,CAEAX,EAAW,kBAAkBA,CAAU",
6
- "names": ["Step", "SwitchStep", "__name", "name", "cases", "default_callable", "subject", "default_callable_registry_key", "resolved_subject", "switch_case", "default_result", "parsed_step", "callable_registry", "default_descriptor"]
4
+ "sourcesContent": ["import Step from './step.js';\nimport { event_names } from '../instance_state.js';\n\n/**\n * SwitchStep class for implementing switch/case logic in workflows.\n * Evaluates cases in order and executes the first matching case, or a default callable if no cases match.\n * @class SwitchStep\n * @extends Step\n */\nexport default class SwitchStep extends Step {\n static step_name = 'switch';\n\n /**\n * Creates a new SwitchStep instance.\n * @param {Object} options - Configuration options.\n * @param {string} [options.name] - Name of the step.\n * @param {Array<Case|LogicStep>} [options.cases=[]] - Array of Case or LogicStep instances to evaluate. LogicStep instances MUST have conditional.subject set.\n * @param {Function|Step|Workflow} [options.default_callable=async () => {}] - Function, Step, or Workflow to execute if no cases match.\n * @param {*|Function} [options.subject=null] - Subject value to evaluate against each case. Can be a function that returns the value.\n * @param {string|null} [options.default_callable_registry_key=null] - Optional key to reference default_callable to be rehydrated after serialization.\n */\n constructor({\n name,\n cases = [],\n default_callable = async () => {},\n subject = null,\n default_callable_registry_key = null,\n }) {\n super({\n name,\n step_type: SwitchStep.step_name,\n });\n\n this.cases = cases;\n this.default_callable_registry_key = default_callable_registry_key;\n this._default_callable_type = this.getCallableType(default_callable);\n this._default_callable_raw = default_callable;\n this.default_callable = this._default_callable_type === 'function'\n ? default_callable.bind(this)\n : default_callable.execute.bind(default_callable);\n this.subject = subject;\n\n this.callable = this.switch.bind(this);\n }\n\n /**\n * Executes the switch logic by evaluating each case in order.\n * Returns the result of the first matching case, or the default callable if no match.\n * Every `Case` (and, if it's a `Step`/`Workflow`, `default_callable`) is stamped with this\n * step's own `parent_workflow_id`/`use_state_singleton`/`state` before it runs, since `cases`\n * lives on this step rather than the parent workflow's `_steps`, so it never goes through\n * `Workflow.addStep()` to pick those up on its own.\n * @returns {Promise<*>} The result of the matched case or default callable.\n */\n async switch() {\n // Resolve subject once - call it if it's a function\n const resolved_subject = typeof this.subject === 'function' ? this.subject() : this.subject;\n \n for (const switch_case of this.cases) {\n switch_case.switch_subject = resolved_subject;\n // Cases live in `this.cases`, not the workflow's `_steps` array, so they never go through\n // Workflow.addStep() - stamp them here instead, mirroring what addStep() does.\n switch_case.parent_workflow_id = this.parent_workflow_id;\n switch_case.use_state_singleton = this.use_state_singleton;\n switch_case.state = this.state;\n\n const is_matched = await switch_case.checkCondition();\n\n if (is_matched) {\n this.log(\n event_names.step.SWITCH_CASE_MATCHED,\n `Case matched for step: ${this.name}, executing case callable`\n );\n\n // Return the case's result value directly, not the Case object.\n // This keeps result structure consistent: switchStep.result contains the\n // callable's return value, matching how Step.result works.\n const case_result = await switch_case.execute();\n return case_result.result;\n }\n }\n\n // Unwrap Step/Workflow results for consistency with case results\n if (this._default_callable_type !== 'function') {\n this._default_callable_raw.parent_workflow_id = this.parent_workflow_id;\n this._default_callable_raw.use_state_singleton = this.use_state_singleton;\n this._default_callable_raw.state = this.state;\n }\n\n const default_result = await this.default_callable();\n if (this._default_callable_type !== 'function') {\n return default_result.result;\n }\n return default_result;\n }\n\n /**\n * Inserts safely serializable properties of the step into a new object for serialization.\n * Note: a function-valued `subject` is not persisted, since there's no registry for it.\n * @returns {Object} An object containing the step's properties ready for serialization.\n */\n prepareForSerialization() {\n return {\n ...super.prepareForSerialization(),\n // The base `callable` is an internal wiring detail (the bound `switch` method) -\n // SwitchStep's constructor doesn't take a callable, so it isn't real data to persist.\n callable: null,\n cases: this.cases.map(switch_case => switch_case.prepareForSerialization()),\n default_callable: this.default_callable_registry_key\n ? { type: Step.callable_types.FUNCTION, value: this.default_callable_registry_key }\n : Step.serializeCallableField(this._default_callable_raw),\n subject: typeof this.subject === 'function' ? null : this.subject,\n };\n }\n\n /**\n * Hydrates a parsed step object into a SwitchStep instance, resolving its cases and default callable.\n * @param {Object} parsed_step - The parsed step object.\n * @param {import('../callable_registry.js').default|null} [callable_registry] - Registry used to resolve function callables.\n * @returns {SwitchStep} The hydrated SwitchStep instance.\n */\n static hydrate(parsed_step, callable_registry = null) {\n const default_descriptor = parsed_step.default_callable;\n\n return super.hydrate({\n ...parsed_step,\n cases: (parsed_step.cases ?? []).map(switch_case => Step.hydrateAny(switch_case, callable_registry)),\n default_callable: Step.hydrateCallableField(default_descriptor, callable_registry),\n default_callable_registry_key: default_descriptor?.type === Step.callable_types.FUNCTION\n ? default_descriptor.value\n : null,\n }, callable_registry);\n }\n}\n\nSwitchStep.registerStepClass(SwitchStep);\n"],
5
+ "mappings": "+EAAA,OAAOA,MAAU,YACjB,OAAS,eAAAC,MAAmB,uBAQ5B,MAAOC,UAAiCF,CAAK,CAT7C,MAS6C,CAAAG,EAAA,mBAC3C,OAAO,UAAY,SAWnB,YAAY,CACV,KAAAC,EACA,MAAAC,EAAQ,CAAC,EACT,iBAAAC,EAAmBH,EAAA,SAAY,CAAC,EAAb,oBACnB,QAAAI,EAAU,KACV,8BAAAC,EAAgC,IAClC,EAAG,CACD,MAAM,CACJ,KAAAJ,EACA,UAAWF,EAAW,SACxB,CAAC,EAED,KAAK,MAAQG,EACb,KAAK,8BAAgCG,EACrC,KAAK,uBAAyB,KAAK,gBAAgBF,CAAgB,EACnE,KAAK,sBAAwBA,EAC7B,KAAK,iBAAmB,KAAK,yBAA2B,WACpDA,EAAiB,KAAK,IAAI,EAC1BA,EAAiB,QAAQ,KAAKA,CAAgB,EAClD,KAAK,QAAUC,EAEf,KAAK,SAAW,KAAK,OAAO,KAAK,IAAI,CACvC,CAWA,MAAM,QAAS,CAEb,MAAME,EAAmB,OAAO,KAAK,SAAY,WAAa,KAAK,QAAQ,EAAI,KAAK,QAEpF,UAAWC,KAAe,KAAK,MAU7B,GATAA,EAAY,eAAiBD,EAG7BC,EAAY,mBAAqB,KAAK,mBACtCA,EAAY,oBAAsB,KAAK,oBACvCA,EAAY,MAAQ,KAAK,MAEN,MAAMA,EAAY,eAAe,EAGlD,YAAK,IACHT,EAAY,KAAK,oBACjB,0BAA0B,KAAK,IAAI,2BACrC,GAKoB,MAAMS,EAAY,QAAQ,GAC3B,OAKnB,KAAK,yBAA2B,aAClC,KAAK,sBAAsB,mBAAqB,KAAK,mBACrD,KAAK,sBAAsB,oBAAsB,KAAK,oBACtD,KAAK,sBAAsB,MAAQ,KAAK,OAG1C,MAAMC,EAAiB,MAAM,KAAK,iBAAiB,EACnD,OAAI,KAAK,yBAA2B,WAC3BA,EAAe,OAEjBA,CACT,CAOA,yBAA0B,CACxB,MAAO,CACL,GAAG,MAAM,wBAAwB,EAGjC,SAAU,KACV,MAAO,KAAK,MAAM,IAAID,GAAeA,EAAY,wBAAwB,CAAC,EAC1E,iBAAkB,KAAK,8BACnB,CAAE,KAAMV,EAAK,eAAe,SAAU,MAAO,KAAK,6BAA8B,EAChFA,EAAK,uBAAuB,KAAK,qBAAqB,EAC1D,QAAS,OAAO,KAAK,SAAY,WAAa,KAAO,KAAK,OAC5D,CACF,CAQA,OAAO,QAAQY,EAAaC,EAAoB,KAAM,CACpD,MAAMC,EAAqBF,EAAY,iBAEvC,OAAO,MAAM,QAAQ,CACnB,GAAGA,EACH,OAAQA,EAAY,OAAS,CAAC,GAAG,IAAIF,GAAeV,EAAK,WAAWU,EAAaG,CAAiB,CAAC,EACnG,iBAAkBb,EAAK,qBAAqBc,EAAoBD,CAAiB,EACjF,8BAA+BC,GAAoB,OAASd,EAAK,eAAe,SAC5Ec,EAAmB,MACnB,IACN,EAAGD,CAAiB,CACtB,CACF,CAEAX,EAAW,kBAAkBA,CAAU",
6
+ "names": ["Step", "event_names", "SwitchStep", "__name", "name", "cases", "default_callable", "subject", "default_callable_registry_key", "resolved_subject", "switch_case", "default_result", "parsed_step", "callable_registry", "default_descriptor"]
7
7
  }
@@ -1,2 +1,2 @@
1
- var u=Object.defineProperty;var h=(_,t)=>u(_,"name",{value:t,configurable:!0});import d from"crypto";import m from"./base.js";import f from"./callable_registry.js";import c from"./steps/step.js";import o from"./state.js";import{base_types as w}from"../enums/index.js";class a extends m{static{h(this,"Workflow")}constructor({name:t,callable_registry:s=null,exit_on_error:e=!1,result_per_step:i=!1,result_per_step_function:r=null,steps:n=[],throw_on_empty:p=!1,use_state_singleton:l=!1}){super({name:t,base_type:w.WORKFLOW,use_state_singleton:l}),this.callable_registry=s??new f,this.current_session_id=null,this.exit_on_error=e,this.result_per_step=i,this.sessions={},this.throw_on_empty=p,this.result_per_step_function=r,this._steps=[],this.steps_by_id={},this.addSteps(n),this.initializeWorkflowState()}async execute(){if(this.current_session_id||(this.current_session_id=d.randomUUID()),this.isEmpty()){if(this.throw_on_empty)throw new Error("Cannot execute an empty workflow");return this.markAsComplete(),await this.prepareResult("Workflow is empty",null),this}const t=this.status===this.getState("statuses.workflow").PAUSED,s=this._steps.findIndex(i=>i.id===this.current_step),e=t?s+1:0;this.markAsRunning();for(let i=e;i<this._steps.length;i++){if(this.should_break){this.log(this.getState("event_names.workflow").WORKFLOW_BREAK_EXECUTED,`Workflow "${this.name}" execution broken at step ${this._steps[i].name} - ${this._steps[i].id}.`);break}if(this.should_skip){this.log(this.getState("events.workflow.event_names.WORKFLOW_STEP_SKIPPED"),`Workflow "${this.name}" skipping step ${this._steps[i].name} - ${this._steps[i].id}.`),this.should_skip=!1;continue}this.current_step=this._steps[i].id;try{const r=await this.step();await this.prepareResult("Success",r)}catch(r){if(this.markAsFailed(),await this.prepareResult(`Workflow execution failed at step ${this.steps_by_id[this.current_step].name} - ${this.current_step}`,{error:r}),this.exit_on_error)return this}if(this.should_pause)return this.markAsPaused(),this.should_pause=!1,this}return this.markAsComplete(),this.prepareForSerialization()}async resume(){return this.should_pause=!1,this.timing.resume_time=new Date,this.getState("events.workflow").emit(this.getState("event_names.workflow").WORKFLOW_RESUMED,this.getState()),this.execute()}async step(){const t=this.steps_by_id[this.current_step],s=await t.execute();if(t.status===this.getState("statuses.step.FAILED"))throw t.errors[t.errors.length-1]??new Error(`Step "${t.name}" failed`);return s}addStep(t){if(typeof t.getCallableType!="function")throw new Error("Invalid input. Must be an instance of Step.");Array.isArray(this._steps)||(this._steps=[]),(!this.steps_by_id||typeof this.steps_by_id!="object")&&(this.steps_by_id={}),this.steps_by_id[t.id]=t,t.parent_workflow_id=this.id,t.parent_workflow=this.prepareForSerialization(),t.use_state_singleton=this.use_state_singleton,t.state=this.state,this._steps.push(t)}addStepAtIndex(t,s){(!this.steps_by_id||typeof this.steps_by_id!="object")&&(this.steps_by_id={}),this.steps_by_id[t.id]=t,t.parent_workflow_id=this.id,t.parent_workflow=this.prepareForSerialization(),t.use_state_singleton=this.use_state_singleton,t.state=this.state,this._steps.splice(s,0,t)}addSteps(t){if(!Array.isArray(t))throw new Error("Invalid input. Must be an array of Step instances.");t.forEach(s=>this.addStep(s))}clearSteps(){this._steps=[],this.steps_by_id={}}closeCurrentSession(){this.current_session_id&&(this.sessions[this.current_session_id]={results:[...this.results],status:this.status,timing:{...this.timing},closed_at:new Date},this.current_session_id=null)}deleteStep(t){Array.isArray(this._steps)||(this._steps=[]),this._steps=this._steps.filter(s=>s.id!==t)}deleteStepByIndex(t){Array.isArray(this._steps)||(this._steps=[]),this._steps.splice(t,1)}getStateFromPropertyPath(t,s=!0){return this.use_state_singleton?(console.warn("The state singleton has been deprecated. Use the .prepareForSerialization() method on the workflow instance instead."),o.getFromPropertyPath(t,s)):this.state.getStateFromPropertyPath(t)}initializeWorkflowState(){this.current_step=this.isEmpty()?null:this._steps[0].id,this.results=this.results??[],this.sessions=this.sessions??{},this.should_break=this.should_break??!1,this.should_continue=this.should_continue??!1,this.should_pause=this.should_pause??!1,this.should_skip=this.should_skip??!1,this.status=this.status??this.getState("statuses.workflow").CREATED,this.timing={...this.timing,create_time:this.timing?.create_time??new Date,pause_time:this.timing?.pause_time??null,resume_time:this.timing?.resume_time??null};const t=this.getState("workflows");t[this.id]=this,this.setState("workflows",t),this.log(this.getState("event_names.workflow").WORKFLOW_CREATED,`Workflow "${this.name}" initialized.`)}isEmpty(){return!Array.isArray(this._steps)||!this._steps.length}markAsComplete(){super.markAsComplete(),this.closeCurrentSession()}markAsCreated(){return this.timing.create_time=new Date,this.log(this.getState("event_names.workflow").WORKFLOW_CREATED,`Workflow "${this.name}" created.`),this.getState("statuses.workflow").CREATED}markAsFailed(){super.markAsFailed(),this.closeCurrentSession()}markAsPaused(){this.timing.pause_time=new Date,this.status=this.getState("statuses.workflow").PAUSED,this.getState("events.workflow").emit(this.getState("event_names.workflow").WORKFLOW_PAUSED,this.getState())}markAsResumed(){this.timing.resume_time=new Date,this.status=this.getState("statuses.workflow").RUNNING,this.getState("events.workflow").emit(this.getState("event_names.workflow").WORKFLOW_RESUMED,this.getState())}moveStep(t,s){const[e]=this._steps.splice(t,1);this._steps.splice(s,0,e),this.getState("events.workflow").emit(this.getState("event_names.workflow").WORKFLOW_STEP_MOVED,this.getState())}parseStatePath(t){return this.use_state_singleton?o.parsePath(t):this.state.parseStatePath(t)}pause(){this.should_pause=!0,this.timing.pause_time=new Date,this.getState("events.workflow").emit(this.getState("event_names.workflow").WORKFLOW_PAUSED,this.getState())}popStep(){return this._steps.pop()}prepareForSerialization(){return{id:this.id,current_session_id:this.current_session_id,current_step:this.current_step,exit_on_error:this.exit_on_error,name:this.name,sessions:this.sessions,status:this.status,steps:this._steps.map(s=>s.prepareForSerialization()),throw_on_empty:this.throw_on_empty,timing:this.timing,results:this.results,use_state_singleton:this.use_state_singleton}}async prepareResult(t,s){this.result_per_step&&typeof this.result_per_step_function=="function"&&await this.result_per_step_function(this.prepareForSerialization());const e={message:t,data:s};this.results.push(e)}pushStep(t){this.addStep(t)}pushSteps(t){t.forEach(s=>this.addStep(s))}serialize(){return JSON.stringify(this.prepareForSerialization())}setStateToPropertyPath(t,s,e=!0){if(this.use_state_singleton){console.warn("The state singleton has been deprecated. Use the .prepareForSerialization() method on the workflow instance instead."),o.setToPropertyPath(t,s,e);return}this.state.setStateToPropertyPath(t,s)}shiftStep(){return this._steps.shift()}unshiftStep(t){if(typeof t.getCallableType!="function")throw new Error("Invalid step type. Must be an instance of Step.");(!this.steps_by_id||typeof this.steps_by_id!="object")&&(this.steps_by_id={}),this.steps_by_id[t.id]=t,t.parent_workflow_id=this.id,t.use_state_singleton=this.use_state_singleton,t.state=this.state,this._steps.unshift(t)}toJSON(){return this.prepareForSerialization()}get steps(){return this._steps}set steps(t){this.addSteps(t)}static hydrateSerialized(t,s=null){if(typeof t!="string")throw new Error("Invalid serialized workflow. Must be a string.");const e=JSON.parse(t);return a.hydrate(e,s)}static hydrate(t,s=null){if(typeof t!="object"||t===null)throw new Error("Invalid parsed workflow. Must be a valid object.");const e=new a({name:t.name,callable_registry:s,exit_on_error:t.exit_on_error,steps:t.steps.map(n=>c.hydrateAny(n,s)),throw_on_empty:t.throw_on_empty,use_state_singleton:t.use_state_singleton??!1}),i=e.id;e.id=t.id;const r=e.getState("workflows");return delete r[i],r[e.id]=e,e.setState("workflows",r),e.steps.forEach(n=>{n.parent_workflow_id=e.id}),e.current_session_id=t.current_session_id,e.current_step=t.current_step??e.current_step,e.sessions=t.sessions??{},e.status=t.status,e.timing=t.timing,e.results=t.results,e}}export{a as default};
1
+ var m=Object.defineProperty;var p=(l,t)=>m(l,"name",{value:t,configurable:!0});import c from"crypto";import w from"./base.js";import y from"./callable_registry.js";import S from"./steps/step.js";import _ from"./state.js";import{statuses as a,event_names as n,events as h,types as g,conditional_step_comparators as k,messages as b}from"./instance_state.js";import{base_types as E}from"../enums/index.js";class o extends w{static{p(this,"Workflow")}constructor({name:t,callable_registry:s=null,exit_on_error:e=!1,result_per_step:i=!1,result_per_step_function:r=null,steps:u=[],throw_on_empty:d=!1,use_state_singleton:f=!1}){super({name:t,base_type:E.WORKFLOW,use_state_singleton:f}),this.callable_registry=s??new y,this.current_session_id=null,this.exit_on_error=e,this.result_per_step=i,this.sessions={},this.throw_on_empty=d,this.result_per_step_function=r,this._steps=[],this.steps_by_id={},this.addSteps(u),this.initializeWorkflowState()}async execute(){if(this.current_session_id||(this.current_session_id=c.randomUUID()),this.isEmpty()){if(this.throw_on_empty)throw new Error("Cannot execute an empty workflow");return this.markAsComplete(),await this.prepareResult("Workflow is empty",null),this}const t=this.status===a.workflow.PAUSED,s=this._steps.findIndex(i=>i.id===this.current_step),e=t?s+1:0;this.markAsRunning();for(let i=e;i<this._steps.length;i++){if(this.should_break){this.log(n.workflow.WORKFLOW_BREAK_EXECUTED,`Workflow "${this.name}" execution broken at step ${this._steps[i].name} - ${this._steps[i].id}.`);break}if(this.should_skip){this.log(n.workflow.WORKFLOW_STEP_SKIPPED,`Workflow "${this.name}" skipping step ${this._steps[i].name} - ${this._steps[i].id}.`),this.should_skip=!1;continue}this.current_step=this._steps[i].id;try{const r=await this.step();await this.prepareResult("Success",r)}catch(r){if(this.markAsFailed(),await this.prepareResult(`Workflow execution failed at step ${this.steps_by_id[this.current_step].name} - ${this.current_step}`,{error:r}),this.exit_on_error)return this}if(this.should_pause)return this.markAsPaused(),this.should_pause=!1,this}return this.markAsComplete(),this.prepareForSerialization()}async resume(){return this.should_pause=!1,this.timing.resume_time=new Date,h.workflow.emit(n.workflow.WORKFLOW_RESUMED,this.getState()),this.execute()}async step(){const t=this.steps_by_id[this.current_step],s=await t.execute();if(t.status===a.step.FAILED)throw t.errors[t.errors.length-1]??new Error(`Step "${t.name}" failed`);return s}addStep(t){if(typeof t.getCallableType!="function")throw new Error("Invalid input. Must be an instance of Step.");Array.isArray(this._steps)||(this._steps=[]),(!this.steps_by_id||typeof this.steps_by_id!="object")&&(this.steps_by_id={}),this.steps_by_id[t.id]=t,t.parent_workflow_id=this.id,t.parent_workflow=this.prepareForSerialization(),t.use_state_singleton=this.use_state_singleton,t.state=this.state,this._steps.push(t)}addStepAtIndex(t,s){(!this.steps_by_id||typeof this.steps_by_id!="object")&&(this.steps_by_id={}),this.steps_by_id[t.id]=t,t.parent_workflow_id=this.id,t.parent_workflow=this.prepareForSerialization(),t.use_state_singleton=this.use_state_singleton,t.state=this.state,this._steps.splice(s,0,t)}addSteps(t){if(!Array.isArray(t))throw new Error("Invalid input. Must be an array of Step instances.");t.forEach(s=>this.addStep(s))}clearSteps(){this._steps=[],this.steps_by_id={}}closeCurrentSession(){this.current_session_id&&(this.sessions[this.current_session_id]={results:[...this.results],status:this.status,timing:{...this.timing},closed_at:new Date},this.current_session_id=null)}deleteStep(t){Array.isArray(this._steps)||(this._steps=[]),this._steps=this._steps.filter(s=>s.id!==t)}deleteStepByIndex(t){Array.isArray(this._steps)||(this._steps=[]),this._steps.splice(t,1)}getStateFromPropertyPath(t,s=!0){return this.use_state_singleton?(console.warn("The state singleton has been deprecated. Use the .prepareForSerialization() method on the workflow instance instead."),_.getFromPropertyPath(t,s)):this.state.getStateFromPropertyPath(t)}initializeWorkflowState(){if(this.current_step=this.isEmpty()?null:this._steps[0].id,this.results=this.results??[],this.sessions=this.sessions??{},this.should_break=this.should_break??!1,this.should_continue=this.should_continue??!1,this.should_pause=this.should_pause??!1,this.should_skip=this.should_skip??!1,this.status=this.status??a.workflow.CREATED,this.timing={...this.timing,create_time:this.timing?.create_time??new Date,pause_time:this.timing?.pause_time??null,resume_time:this.timing?.resume_time??null},this.use_state_singleton){const t=this.getState("workflows");t[this.id]=this,this.setState("workflows",t)}else this.setState("workflow",this);this.log(n.workflow.WORKFLOW_CREATED,`Workflow "${this.name}" initialized.`)}isEmpty(){return!Array.isArray(this._steps)||!this._steps.length}markAsComplete(){super.markAsComplete(),this.closeCurrentSession()}markAsCreated(){return this.timing.create_time=new Date,this.log(n.workflow.WORKFLOW_CREATED,`Workflow "${this.name}" created.`),a.workflow.CREATED}markAsFailed(){super.markAsFailed(),this.closeCurrentSession()}markAsPaused(){this.timing.pause_time=new Date,this.status=a.workflow.PAUSED,h.workflow.emit(n.workflow.WORKFLOW_PAUSED,this.getState())}markAsResumed(){this.timing.resume_time=new Date,this.status=a.workflow.RUNNING,h.workflow.emit(n.workflow.WORKFLOW_RESUMED,this.getState())}moveStep(t,s){const[e]=this._steps.splice(t,1);this._steps.splice(s,0,e),h.workflow.emit(n.workflow.WORKFLOW_STEP_MOVED,this.getState())}parseStatePath(t){return this.use_state_singleton?_.parsePath(t):this.state.parseStatePath(t)}pause(){this.should_pause=!0,this.timing.pause_time=new Date,h.workflow.emit(n.workflow.WORKFLOW_PAUSED,this.getState())}popStep(){return this._steps.pop()}prepareForSerialization(){return{id:this.id,current_session_id:this.current_session_id,current_step:this.current_step,exit_on_error:this.exit_on_error,name:this.name,sessions:this.sessions,status:this.status,steps:this._steps.map(s=>s.prepareForSerialization()),throw_on_empty:this.throw_on_empty,timing:this.timing,results:this.results,use_state_singleton:this.use_state_singleton}}async prepareResult(t,s){this.result_per_step&&typeof this.result_per_step_function=="function"&&await this.result_per_step_function(this.prepareForSerialization());const e={message:t,data:s};this.results.push(e)}pushStep(t){this.addStep(t)}pushSteps(t){t.forEach(s=>this.addStep(s))}serialize(){return JSON.stringify(this.prepareForSerialization())}setStateToPropertyPath(t,s,e=!0){if(this.use_state_singleton){console.warn("The state singleton has been deprecated. Use the .prepareForSerialization() method on the workflow instance instead."),_.setToPropertyPath(t,s,e);return}this.state.setStateToPropertyPath(t,s)}shiftStep(){return this._steps.shift()}unshiftStep(t){if(typeof t.getCallableType!="function")throw new Error("Invalid step type. Must be an instance of Step.");(!this.steps_by_id||typeof this.steps_by_id!="object")&&(this.steps_by_id={}),this.steps_by_id[t.id]=t,t.parent_workflow_id=this.id,t.use_state_singleton=this.use_state_singleton,t.state=this.state,this._steps.unshift(t)}toJSON(){return this.prepareForSerialization()}get steps(){return this._steps}set steps(t){this.addSteps(t)}static hydrateSerialized(t,s=null){if(typeof t!="string")throw new Error("Invalid serialized workflow. Must be a string.");const e=JSON.parse(t);return o.hydrate(e,s)}static hydrate(t,s=null){if(typeof t!="object"||t===null)throw new Error("Invalid parsed workflow. Must be a valid object.");const e=new o({name:t.name,callable_registry:s,exit_on_error:t.exit_on_error,steps:t.steps.map(r=>S.hydrateAny(r,s)),throw_on_empty:t.throw_on_empty,use_state_singleton:t.use_state_singleton??!1}),i=e.id;if(e.id=t.id,e.use_state_singleton){const r=e.getState("workflows");delete r[i],r[e.id]=e,e.setState("workflows",r)}return e.steps.forEach(r=>{r.parent_workflow_id=e.id}),e.current_session_id=t.current_session_id,e.current_step=t.current_step??e.current_step,e.sessions=t.sessions??{},e.status=t.status,e.timing=t.timing,e.results=t.results,e}}o.statuses=a,o.event_names=n,o.events=h,o.types=g,o.conditional_step_comparators=k,o.messages=b;export{o as default};
2
2
  //# sourceMappingURL=workflow.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/classes/workflow.js"],
4
- "sourcesContent": ["import crypto from 'crypto';\nimport Base from './base.js';\nimport CallableRegistry from './callable_registry.js';\nimport Step from './steps/step.js';\nimport State from './state.js';\nimport { base_types } from '../enums/index.js';\n\n/**\n * Workflow class for managing and executing a sequence of steps.\n * @class Workflow\n * @extends Base\n */\nexport default class Workflow extends Base {\n /**\n * Creates a new Workflow instance.\n * @param {Object} options - Configuration options.\n * @param {string} [options.name] - Name of the workflow.\n * @param {CallableRegistry|null} [options.callable_registry=null] - Registry for callable objects.\n * @param {boolean} [options.exit_on_error=false] - Whether to exit on error.\n * @param {Array<Step>} [options.steps=[]] - Array of steps to add to the workflow.\n * @param {boolean} [options.throw_on_empty=false] - Whether to throw error if workflow is empty.\n * @param {boolean} [options.use_state_singleton=false] - Deprecated. When true, this workflow (and every\n * `Step` it owns) reads/writes `getState`/`setState`/`deleteState` calls through the process-wide `State`\n * singleton instead of this workflow's own state.\n */\n constructor({\n name,\n callable_registry = null,\n exit_on_error = false,\n result_per_step = false,\n result_per_step_function = null,\n steps = [],\n throw_on_empty = false,\n use_state_singleton = false,\n }) {\n super({ name, base_type: base_types.WORKFLOW, use_state_singleton });\n\n this.callable_registry = callable_registry ?? new CallableRegistry();\n this.current_session_id = null;\n this.exit_on_error = exit_on_error;\n this.result_per_step = result_per_step;\n this.sessions = {};\n this.throw_on_empty = throw_on_empty;\n this.result_per_step_function = result_per_step_function;\n\n // _steps/steps_by_id must exist before initializeWorkflowState(): it reads this._steps\n // (to set current_step) and logs, which serializes `this` - both need this._steps to\n // already be an array, even when no steps are passed (addSteps([]) never calls addStep,\n // so it wouldn't otherwise get initialized).\n this._steps = [];\n this.steps_by_id = {};\n this.addSteps(steps);\n this.initializeWorkflowState();\n }\n\n /**\n * Executes the workflow by running all steps in sequence.\n * If the workflow is currently `paused`, resumes from the step after the one\n * that was running when it paused, rather than starting over from the beginning.\n * @async\n * @returns {Promise<Workflow>} The workflow instance with execution results.\n * @throws {Error} Throws if workflow is empty and throw_on_empty is true.\n */\n async execute() {\n if (!this.current_session_id) {\n this.current_session_id = crypto.randomUUID();\n }\n\n if (this.isEmpty()) {\n if (this.throw_on_empty) {\n throw new Error('Cannot execute an empty workflow');\n }\n\n this.markAsComplete();\n await this.prepareResult('Workflow is empty', null);\n return this;\n }\n\n const is_resuming = this.status === this.getState('statuses.workflow').PAUSED;\n const paused_at_index = this._steps.findIndex(step => step.id === this.current_step);\n const start_index = is_resuming ? paused_at_index + 1 : 0;\n\n this.markAsRunning();\n\n for (let i = start_index; i < this._steps.length; i++) {\n if (this.should_break) {\n this.log(this.getState('event_names.workflow').WORKFLOW_BREAK_EXECUTED, `Workflow \"${this.name}\" execution broken at step ${this._steps[i].name} - ${this._steps[i].id}.`);\n break;\n }\n\n if (this.should_skip) {\n this.log(\n this.getState('events.workflow.event_names.WORKFLOW_STEP_SKIPPED'),\n `Workflow \"${this.name}\" skipping step ${this._steps[i].name} - ${this._steps[i].id}.`\n );\n this.should_skip = false;\n continue;\n }\n\n this.current_step = this._steps[i].id;\n\n try {\n const step_result = await this.step();\n await this.prepareResult('Success', step_result);\n } catch (error) {\n this.markAsFailed();\n await this.prepareResult(`Workflow execution failed at step ${this.steps_by_id[this.current_step].name} - ${this.current_step}`, { error });\n \n if (this.exit_on_error) {\n return this;\n }\n }\n\n if (this.should_pause) {\n this.markAsPaused();\n this.should_pause = false;\n return this;\n }\n }\n\n this.markAsComplete();\n return this.prepareForSerialization();\n }\n\n /**\n * Resumes a paused workflow.\n * @async\n * @returns {Promise<Workflow>} The workflow instance.\n */\n async resume() {\n this.should_pause = false;\n this.timing.resume_time = new Date();\n\n this.getState('events.workflow').emit(\n this.getState('event_names.workflow').WORKFLOW_RESUMED,\n this.getState()\n );\n return this.execute();\n }\n\n /**\n * Executes a single step in the workflow.\n * @async\n * @returns {Promise<*>} The result of the step execution.\n */\n async step() {\n const step = this.steps_by_id[this.current_step];\n\n const result = await step.execute();\n\n if (step.status === this.getState('statuses.step.FAILED')) {\n throw step.errors[step.errors.length - 1] ?? new Error(`Step \"${step.name}\" failed`);\n }\n\n return result;\n }\n\n /**\n * Adds a step to the workflow.\n * @param {Step} step - The step to add.\n * @throws {Error} Throws if step is not a valid Step instance.\n */\n addStep(step) {\n // This check only ensures that the getCallableType method exists,\n // which is a characteristic of Step instances\n if (typeof step.getCallableType !== 'function') {\n throw new Error('Invalid input. Must be an instance of Step.');\n }\n\n if (!Array.isArray(this._steps)) {\n this._steps = [];\n }\n\n if (!this.steps_by_id || typeof this.steps_by_id !== 'object') {\n this.steps_by_id = {};\n }\n\n this.steps_by_id[step.id] = step;\n\n step.parent_workflow_id = this.id;\n step.parent_workflow = this.prepareForSerialization();\n step.use_state_singleton = this.use_state_singleton;\n step.state = this.state;\n this._steps.push(step);\n }\n\n /**\n * Adds a step at a specific index in the workflow.\n * @param {Step} step - The step to add.\n * @param {number} index - The index at which to insert the step.\n */\n addStepAtIndex(step, index) {\n if (!this.steps_by_id || typeof this.steps_by_id !== 'object') {\n this.steps_by_id = {};\n }\n\n this.steps_by_id[step.id] = step;\n step.parent_workflow_id = this.id;\n step.parent_workflow = this.prepareForSerialization();\n step.use_state_singleton = this.use_state_singleton;\n step.state = this.state;\n this._steps.splice(index, 0, step);\n }\n\n /**\n * Adds multiple steps to the workflow.\n * @param {Step[]} steps - Array of steps to add.\n */\n addSteps(steps) {\n if (!Array.isArray(steps)) {\n throw new Error('Invalid input. Must be an array of Step instances.');\n }\n\n steps.forEach(step => this.addStep(step));\n }\n\n /**\n * Clears all steps from the workflow.\n */\n clearSteps() {\n this._steps = [];\n this.steps_by_id = {};\n }\n\n /**\n * Closes the current session and stores a snapshot of the workflow state.\n */\n closeCurrentSession() {\n if (!this.current_session_id) {\n return;\n }\n\n this.sessions[this.current_session_id] = {\n results: [...this.results],\n status: this.status,\n timing: { ...this.timing },\n closed_at: new Date()\n };\n this.current_session_id = null;\n }\n\n /**\n * Deletes a step from the workflow by its ID.\n * @param {string} stepId - The ID of the step to delete.\n */\n deleteStep(stepId) {\n if (!Array.isArray(this._steps)) {\n this._steps = [];\n }\n\n this._steps = this._steps.filter(step => step.id !== stepId);\n }\n\n /**\n * Deletes a step from the workflow by its index.\n * @param {number} index - The index of the step to delete.\n */\n deleteStepByIndex(index) {\n if (!Array.isArray(this._steps)) {\n this._steps = [];\n }\n\n this._steps.splice(index, 1);\n }\n\n /**\n * Resolves a nested property path within this workflow's own state - the low-level counterpart\n * to `getState()`. Falls back to the deprecated `State` singleton's resolver when\n * `use_state_singleton` is `true`.\n * @param {string} path - Path to the state property.\n * @param {boolean} [emit=true] - Only meaningful when `use_state_singleton` is `true`; whether\n * to emit the singleton's `GET_FROM_PROPERTY_PATH` state event.\n * @returns {*} The value at the specified path, or undefined if not found.\n */\n getStateFromPropertyPath(path, emit = true) {\n if (this.use_state_singleton) {\n console.warn('The state singleton has been deprecated. Use the .prepareForSerialization() method on the workflow instance instead.');\n return State.getFromPropertyPath(path, emit);\n }\n\n return this.state.getStateFromPropertyPath(path);\n }\n\n /**\n * Initializes the workflow state with default values.\n */\n initializeWorkflowState() {\n this.current_step = ! this.isEmpty() ? this._steps[0].id : null;\n this.results = this.results ?? [];\n this.sessions = this.sessions ?? {};\n this.should_break = this.should_break ?? false;\n this.should_continue = this.should_continue ?? false;\n this.should_pause = this.should_pause ?? false;\n this.should_skip = this.should_skip ?? false;\n this.status = this.status ?? this.getState('statuses.workflow').CREATED;\n this.timing = {\n ...this.timing,\n create_time: this.timing?.create_time ?? new Date(),\n pause_time: this.timing?.pause_time ?? null,\n resume_time: this.timing?.resume_time ?? null,\n }\n\n const workflows = this.getState('workflows');\n workflows[this.id] = this;\n this.setState('workflows', workflows);\n\n this.log(\n this.getState('event_names.workflow').WORKFLOW_CREATED,\n `Workflow \"${this.name}\" initialized.`\n );\n }\n\n /**\n * Checks if the workflow has no steps.\n * @returns {boolean} True if the workflow is empty.\n */\n isEmpty() {\n return !Array.isArray(this._steps) || !this._steps.length;\n }\n\n /**\n * Marks the workflow as complete and closes the current session.\n */\n markAsComplete() {\n super.markAsComplete();\n this.closeCurrentSession();\n }\n\n /**\n * Marks the workflow as created.\n * @returns {string} The CREATED status.\n */\n markAsCreated() {\n this.timing.create_time = new Date();\n \n this.log(\n this.getState('event_names.workflow').WORKFLOW_CREATED,\n `Workflow \"${this.name}\" created.`\n );\n\n return this.getState('statuses.workflow').CREATED;\n }\n\n /**\n * Marks the workflow as failed and closes the current session.\n */\n markAsFailed() {\n super.markAsFailed();\n this.closeCurrentSession();\n }\n\n /**\n * Marks the workflow as paused.\n */\n markAsPaused() {\n this.timing.pause_time = new Date();\n this.status = this.getState('statuses.workflow').PAUSED;\n\n this.getState('events.workflow').emit(\n this.getState('event_names.workflow').WORKFLOW_PAUSED,\n this.getState()\n );\n }\n \n /**\n * Marks the workflow as resumed.\n */\n markAsResumed() {\n this.timing.resume_time = new Date();\n this.status = this.getState('statuses.workflow').RUNNING;\n\n this.getState('events.workflow').emit(\n this.getState('event_names.workflow').WORKFLOW_RESUMED,\n this.getState()\n );\n }\n\n /**\n * Moves a step from one index to another.\n * @param {number} fromIndex - The current index of the step.\n * @param {number} toIndex - The target index for the step.\n */\n moveStep(fromIndex, toIndex) {\n const [step] = this._steps.splice(fromIndex, 1);\n this._steps.splice(toIndex, 0, step);\n\n this.getState('events.workflow').emit(\n this.getState('event_names.workflow').WORKFLOW_STEP_MOVED,\n this.getState()\n );\n }\n\n /**\n * Parses a property path string into an array of keys, supporting both dot notation and\n * bracket notation (e.g. `\"users[0].name\"`). Pure utility - not affected by `use_state_singleton`.\n * @param {string} path - The path to parse.\n * @returns {string[]} Array of property keys.\n */\n parseStatePath(path) {\n return this.use_state_singleton ? State.parsePath(path) : this.state.parseStatePath(path);\n }\n\n /**\n * Pauses the workflow execution.\n */\n pause() {\n this.should_pause = true;\n this.timing.pause_time = new Date();\n\n this.getState('events.workflow').emit(\n this.getState('event_names.workflow').WORKFLOW_PAUSED,\n this.getState()\n );\n }\n\n /**\n * Removes and returns the last step from the workflow.\n * @returns {Step} The last step.\n */\n popStep() {\n return this._steps.pop();\n }\n\n /**\n * Inserts safely serializable properties of the workflow into a new object for serialization.\n * @returns {Object} An object containing the workflow's properties ready for serialization.\n */\n prepareForSerialization() {\n const serialized_workflow = {\n id: this.id,\n current_session_id: this.current_session_id,\n current_step: this.current_step,\n exit_on_error: this.exit_on_error,\n name: this.name,\n sessions: this.sessions,\n status: this.status,\n steps: this._steps.map(step => step.prepareForSerialization()),\n throw_on_empty: this.throw_on_empty,\n timing: this.timing,\n results: this.results,\n use_state_singleton: this.use_state_singleton,\n };\n\n return serialized_workflow;\n }\n\n /**\n * Prepares a result object and adds it to the results array.\n * @param {string} message - Result message.\n * @param {*} data - Result data.\n */\n async prepareResult(message, data) {\n if (this.result_per_step && typeof this.result_per_step_function === 'function') {\n await this.result_per_step_function(this.prepareForSerialization());\n }\n\n const result = { message, data };\n this.results.push(result);\n }\n\n /**\n * Adds a step to the end of the workflow.\n * @param {Step} step - The step to add.\n */\n pushStep(step) {\n this.addStep(step);\n }\n\n /**\n * Adds multiple steps to the end of the workflow.\n * @param {Step[]} steps - Array of steps to add.\n */\n pushSteps(steps) {\n steps.forEach(step => this.addStep(step));\n }\n\n /**\n * Serializes the workflow into a JSON string.\n * @returns {string} The JSON string representation of the workflow.\n */\n serialize() {\n return JSON.stringify(this.prepareForSerialization());\n }\n\n /**\n * Sets a nested property value within this workflow's own state, creating intermediate\n * objects/arrays as needed - the low-level counterpart to `setState()`. Falls back to the\n * deprecated `State` singleton's setter when `use_state_singleton` is `true`.\n * @param {string} path - Path to the state property.\n * @param {*} value - The value to set at the specified path.\n * @param {boolean} [emit=true] - Only meaningful when `use_state_singleton` is `true`; whether\n * to emit the singleton's `SET_TO_PROPERTY_PATH` state event.\n */\n setStateToPropertyPath(path, value, emit = true) {\n if (this.use_state_singleton) {\n console.warn('The state singleton has been deprecated. Use the .prepareForSerialization() method on the workflow instance instead.');\n State.setToPropertyPath(path, value, emit);\n return;\n }\n\n this.state.setStateToPropertyPath(path, value);\n }\n\n /**\n * Removes and returns the first step from the workflow.\n * @returns {Step} The first step.\n */\n shiftStep() {\n return this._steps.shift();\n }\n\n /**\n * Adds a step to the beginning of the workflow.\n * @param {Step} step - The step to add.\n * @throws {Error} Throws if step is not a valid Step instance.\n */\n unshiftStep(step) {\n if (typeof step.getCallableType !== 'function') {\n throw new Error('Invalid step type. Must be an instance of Step.');\n }\n\n if (!this.steps_by_id || typeof this.steps_by_id !== 'object') {\n this.steps_by_id = {};\n }\n\n this.steps_by_id[step.id] = step;\n\n step.parent_workflow_id = this.id;\n step.use_state_singleton = this.use_state_singleton;\n step.state = this.state;\n this._steps.unshift(step);\n }\n\n /**\n * Custom JSON serializer\n * @returns {Object} The JSON representation of the workflow.\n */\n toJSON() {\n return this.prepareForSerialization();\n }\n\n /**\n * Gets the array of steps in the workflow.\n * @returns {Step[]} Array of steps.\n */\n get steps() {\n return this._steps;\n }\n\n /**\n * Sets the steps array by adding multiple steps.\n * @param {Step[]} steps - Array of steps to add.\n */\n set steps(steps) {\n this.addSteps(steps);\n }\n\n /**\n * Deserializes a JSON string into a Workflow instance and hydrates it.\n * @param {string} serialized_workflow - The JSON string representation of the workflow.\n * @param {CallableRegistry|null} [callable_registry] - Registry used to resolve function callables in the workflow's steps.\n * @returns {Workflow} The hydrated Workflow instance.\n * @throws {Error} Throws if the serialized workflow is not a string.\n */\n static hydrateSerialized(serialized_workflow, callable_registry = null) {\n // TODO: Validate structure of serialized workflow\n if (typeof serialized_workflow !== 'string') {\n throw new Error('Invalid serialized workflow. Must be a string.');\n }\n\n const parsed = JSON.parse(serialized_workflow);\n\n return Workflow.hydrate(parsed, callable_registry);\n }\n\n /**\n * Hydrates a parsed workflow object into a Workflow instance.\n * @param {Object} parsed_workflow - The parsed workflow object.\n * @param {CallableRegistry|null} [callable_registry] - Registry used to resolve function callables in the workflow's steps.\n * @returns {Workflow} The hydrated Workflow instance.\n * @throws {Error} Throws if the parsed workflow is not a valid object.\n */\n static hydrate(parsed_workflow, callable_registry = null) {\n // TODO: Validate structure of serialized workflow\n // TODO: Use event system to handle errors?\n if (typeof parsed_workflow !== 'object' || parsed_workflow === null) {\n throw new Error('Invalid parsed workflow. Must be a valid object.');\n }\n\n const hydrated_workflow = new Workflow({\n name: parsed_workflow.name,\n callable_registry,\n exit_on_error: parsed_workflow.exit_on_error,\n steps: parsed_workflow.steps.map(step => Step.hydrateAny(step, callable_registry)),\n throw_on_empty: parsed_workflow.throw_on_empty,\n use_state_singleton: parsed_workflow.use_state_singleton ?? false,\n });\n\n // The constructor above (via Base) always generates a fresh id, and addStep() has\n // already stamped that fresh id onto each step's parent_workflow_id and registered\n // the workflow under it in its own state's `workflows` registry. Restoring the real id\n // below would otherwise leave both of those referencing a discarded id, so fix them up here too.\n const stale_id = hydrated_workflow.id;\n hydrated_workflow.id = parsed_workflow.id;\n\n const workflows = hydrated_workflow.getState('workflows');\n delete workflows[stale_id];\n workflows[hydrated_workflow.id] = hydrated_workflow;\n hydrated_workflow.setState('workflows', workflows);\n\n hydrated_workflow.steps.forEach(step => {\n step.parent_workflow_id = hydrated_workflow.id;\n });\n\n hydrated_workflow.current_session_id = parsed_workflow.current_session_id;\n hydrated_workflow.current_step = parsed_workflow.current_step ?? hydrated_workflow.current_step;\n hydrated_workflow.sessions = parsed_workflow.sessions ?? {};\n hydrated_workflow.status = parsed_workflow.status;\n hydrated_workflow.timing = parsed_workflow.timing;\n hydrated_workflow.results = parsed_workflow.results;\n\n return hydrated_workflow;\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["crypto", "Base", "CallableRegistry", "Step", "State", "base_types", "Workflow", "__name", "name", "callable_registry", "exit_on_error", "result_per_step", "result_per_step_function", "steps", "throw_on_empty", "use_state_singleton", "is_resuming", "paused_at_index", "step", "start_index", "step_result", "error", "result", "index", "stepId", "path", "emit", "workflows", "fromIndex", "toIndex", "message", "data", "value", "serialized_workflow", "parsed", "parsed_workflow", "hydrated_workflow", "stale_id"]
4
+ "sourcesContent": ["import crypto from 'crypto';\nimport Base from './base.js';\nimport CallableRegistry from './callable_registry.js';\nimport Step from './steps/step.js';\nimport State from './state.js';\nimport { statuses, event_names, events, types, conditional_step_comparators, messages } from './instance_state.js';\nimport { base_types } from '../enums/index.js';\n\n/**\n * Workflow class for managing and executing a sequence of steps.\n * @class Workflow\n * @extends Base\n */\nexport default class Workflow extends Base {\n /**\n * Creates a new Workflow instance.\n * @param {Object} options - Configuration options.\n * @param {string} [options.name] - Name of the workflow.\n * @param {CallableRegistry|null} [options.callable_registry=null] - Registry for callable objects.\n * @param {boolean} [options.exit_on_error=false] - Whether to exit on error.\n * @param {Array<Step>} [options.steps=[]] - Array of steps to add to the workflow.\n * @param {boolean} [options.throw_on_empty=false] - Whether to throw error if workflow is empty.\n * @param {boolean} [options.use_state_singleton=false] - Deprecated. When true, this workflow (and every\n * `Step` it owns) reads/writes `getState`/`setState`/`deleteState` calls through the process-wide `State`\n * singleton instead of this workflow's own state.\n */\n constructor({\n name,\n callable_registry = null,\n exit_on_error = false,\n result_per_step = false,\n result_per_step_function = null,\n steps = [],\n throw_on_empty = false,\n use_state_singleton = false,\n }) {\n super({ name, base_type: base_types.WORKFLOW, use_state_singleton });\n\n this.callable_registry = callable_registry ?? new CallableRegistry();\n this.current_session_id = null;\n this.exit_on_error = exit_on_error;\n this.result_per_step = result_per_step;\n this.sessions = {};\n this.throw_on_empty = throw_on_empty;\n this.result_per_step_function = result_per_step_function;\n\n // _steps/steps_by_id must exist before initializeWorkflowState(): it reads this._steps\n // (to set current_step) and logs, which serializes `this` - both need this._steps to\n // already be an array, even when no steps are passed (addSteps([]) never calls addStep,\n // so it wouldn't otherwise get initialized).\n this._steps = [];\n this.steps_by_id = {};\n this.addSteps(steps);\n this.initializeWorkflowState();\n }\n\n /**\n * Executes the workflow by running all steps in sequence.\n * If the workflow is currently `paused`, resumes from the step after the one\n * that was running when it paused, rather than starting over from the beginning.\n * @async\n * @returns {Promise<Workflow>} The workflow instance with execution results.\n * @throws {Error} Throws if workflow is empty and throw_on_empty is true.\n */\n async execute() {\n if (!this.current_session_id) {\n this.current_session_id = crypto.randomUUID();\n }\n\n if (this.isEmpty()) {\n if (this.throw_on_empty) {\n throw new Error('Cannot execute an empty workflow');\n }\n\n this.markAsComplete();\n await this.prepareResult('Workflow is empty', null);\n return this;\n }\n\n const is_resuming = this.status === statuses.workflow.PAUSED;\n const paused_at_index = this._steps.findIndex(step => step.id === this.current_step);\n const start_index = is_resuming ? paused_at_index + 1 : 0;\n\n this.markAsRunning();\n\n for (let i = start_index; i < this._steps.length; i++) {\n if (this.should_break) {\n this.log(event_names.workflow.WORKFLOW_BREAK_EXECUTED, `Workflow \"${this.name}\" execution broken at step ${this._steps[i].name} - ${this._steps[i].id}.`);\n break;\n }\n\n if (this.should_skip) {\n this.log(\n event_names.workflow.WORKFLOW_STEP_SKIPPED,\n `Workflow \"${this.name}\" skipping step ${this._steps[i].name} - ${this._steps[i].id}.`\n );\n this.should_skip = false;\n continue;\n }\n\n this.current_step = this._steps[i].id;\n\n try {\n const step_result = await this.step();\n await this.prepareResult('Success', step_result);\n } catch (error) {\n this.markAsFailed();\n await this.prepareResult(`Workflow execution failed at step ${this.steps_by_id[this.current_step].name} - ${this.current_step}`, { error });\n \n if (this.exit_on_error) {\n return this;\n }\n }\n\n if (this.should_pause) {\n this.markAsPaused();\n this.should_pause = false;\n return this;\n }\n }\n\n this.markAsComplete();\n return this.prepareForSerialization();\n }\n\n /**\n * Resumes a paused workflow.\n * @async\n * @returns {Promise<Workflow>} The workflow instance.\n */\n async resume() {\n this.should_pause = false;\n this.timing.resume_time = new Date();\n\n events.workflow.emit(\n event_names.workflow.WORKFLOW_RESUMED,\n this.getState()\n );\n return this.execute();\n }\n\n /**\n * Executes a single step in the workflow.\n * @async\n * @returns {Promise<*>} The result of the step execution.\n */\n async step() {\n const step = this.steps_by_id[this.current_step];\n\n const result = await step.execute();\n\n if (step.status === statuses.step.FAILED) {\n throw step.errors[step.errors.length - 1] ?? new Error(`Step \"${step.name}\" failed`);\n }\n\n return result;\n }\n\n /**\n * Adds a step to the workflow.\n * @param {Step} step - The step to add.\n * @throws {Error} Throws if step is not a valid Step instance.\n */\n addStep(step) {\n // This check only ensures that the getCallableType method exists,\n // which is a characteristic of Step instances\n if (typeof step.getCallableType !== 'function') {\n throw new Error('Invalid input. Must be an instance of Step.');\n }\n\n if (!Array.isArray(this._steps)) {\n this._steps = [];\n }\n\n if (!this.steps_by_id || typeof this.steps_by_id !== 'object') {\n this.steps_by_id = {};\n }\n\n this.steps_by_id[step.id] = step;\n\n step.parent_workflow_id = this.id;\n step.parent_workflow = this.prepareForSerialization();\n step.use_state_singleton = this.use_state_singleton;\n step.state = this.state;\n this._steps.push(step);\n }\n\n /**\n * Adds a step at a specific index in the workflow.\n * @param {Step} step - The step to add.\n * @param {number} index - The index at which to insert the step.\n */\n addStepAtIndex(step, index) {\n if (!this.steps_by_id || typeof this.steps_by_id !== 'object') {\n this.steps_by_id = {};\n }\n\n this.steps_by_id[step.id] = step;\n step.parent_workflow_id = this.id;\n step.parent_workflow = this.prepareForSerialization();\n step.use_state_singleton = this.use_state_singleton;\n step.state = this.state;\n this._steps.splice(index, 0, step);\n }\n\n /**\n * Adds multiple steps to the workflow.\n * @param {Step[]} steps - Array of steps to add.\n */\n addSteps(steps) {\n if (!Array.isArray(steps)) {\n throw new Error('Invalid input. Must be an array of Step instances.');\n }\n\n steps.forEach(step => this.addStep(step));\n }\n\n /**\n * Clears all steps from the workflow.\n */\n clearSteps() {\n this._steps = [];\n this.steps_by_id = {};\n }\n\n /**\n * Closes the current session and stores a snapshot of the workflow state.\n */\n closeCurrentSession() {\n if (!this.current_session_id) {\n return;\n }\n\n this.sessions[this.current_session_id] = {\n results: [...this.results],\n status: this.status,\n timing: { ...this.timing },\n closed_at: new Date()\n };\n this.current_session_id = null;\n }\n\n /**\n * Deletes a step from the workflow by its ID.\n * @param {string} stepId - The ID of the step to delete.\n */\n deleteStep(stepId) {\n if (!Array.isArray(this._steps)) {\n this._steps = [];\n }\n\n this._steps = this._steps.filter(step => step.id !== stepId);\n }\n\n /**\n * Deletes a step from the workflow by its index.\n * @param {number} index - The index of the step to delete.\n */\n deleteStepByIndex(index) {\n if (!Array.isArray(this._steps)) {\n this._steps = [];\n }\n\n this._steps.splice(index, 1);\n }\n\n /**\n * Resolves a nested property path within this workflow's own state - the low-level counterpart\n * to `getState()`. Falls back to the deprecated `State` singleton's resolver when\n * `use_state_singleton` is `true`.\n * @param {string} path - Path to the state property.\n * @param {boolean} [emit=true] - Only meaningful when `use_state_singleton` is `true`; whether\n * to emit the singleton's `GET_FROM_PROPERTY_PATH` state event.\n * @returns {*} The value at the specified path, or undefined if not found.\n */\n getStateFromPropertyPath(path, emit = true) {\n if (this.use_state_singleton) {\n console.warn('The state singleton has been deprecated. Use the .prepareForSerialization() method on the workflow instance instead.');\n return State.getFromPropertyPath(path, emit);\n }\n\n return this.state.getStateFromPropertyPath(path);\n }\n\n /**\n * Initializes the workflow state with default values.\n */\n initializeWorkflowState() {\n this.current_step = ! this.isEmpty() ? this._steps[0].id : null;\n this.results = this.results ?? [];\n this.sessions = this.sessions ?? {};\n this.should_break = this.should_break ?? false;\n this.should_continue = this.should_continue ?? false;\n this.should_pause = this.should_pause ?? false;\n this.should_skip = this.should_skip ?? false;\n this.status = this.status ?? statuses.workflow.CREATED;\n this.timing = {\n ...this.timing,\n create_time: this.timing?.create_time ?? new Date(),\n pause_time: this.timing?.pause_time ?? null,\n resume_time: this.timing?.resume_time ?? null,\n }\n\n if (this.use_state_singleton) {\n // The deprecated `State` singleton is shared by every workflow that opts into it, so it\n // still needs an id-keyed registry (unlike per-instance state, which only ever has one\n // workflow to represent and can just reference it directly - see the else branch).\n const workflows = this.getState('workflows');\n workflows[this.id] = this;\n this.setState('workflows', workflows);\n } else {\n this.setState('workflow', this);\n }\n\n this.log(\n event_names.workflow.WORKFLOW_CREATED,\n `Workflow \"${this.name}\" initialized.`\n );\n }\n\n /**\n * Checks if the workflow has no steps.\n * @returns {boolean} True if the workflow is empty.\n */\n isEmpty() {\n return !Array.isArray(this._steps) || !this._steps.length;\n }\n\n /**\n * Marks the workflow as complete and closes the current session.\n */\n markAsComplete() {\n super.markAsComplete();\n this.closeCurrentSession();\n }\n\n /**\n * Marks the workflow as created.\n * @returns {string} The CREATED status.\n */\n markAsCreated() {\n this.timing.create_time = new Date();\n \n this.log(\n event_names.workflow.WORKFLOW_CREATED,\n `Workflow \"${this.name}\" created.`\n );\n\n return statuses.workflow.CREATED;\n }\n\n /**\n * Marks the workflow as failed and closes the current session.\n */\n markAsFailed() {\n super.markAsFailed();\n this.closeCurrentSession();\n }\n\n /**\n * Marks the workflow as paused.\n */\n markAsPaused() {\n this.timing.pause_time = new Date();\n this.status = statuses.workflow.PAUSED;\n\n events.workflow.emit(\n event_names.workflow.WORKFLOW_PAUSED,\n this.getState()\n );\n }\n\n /**\n * Marks the workflow as resumed.\n */\n markAsResumed() {\n this.timing.resume_time = new Date();\n this.status = statuses.workflow.RUNNING;\n\n events.workflow.emit(\n event_names.workflow.WORKFLOW_RESUMED,\n this.getState()\n );\n }\n\n /**\n * Moves a step from one index to another.\n * @param {number} fromIndex - The current index of the step.\n * @param {number} toIndex - The target index for the step.\n */\n moveStep(fromIndex, toIndex) {\n const [step] = this._steps.splice(fromIndex, 1);\n this._steps.splice(toIndex, 0, step);\n\n events.workflow.emit(\n event_names.workflow.WORKFLOW_STEP_MOVED,\n this.getState()\n );\n }\n\n /**\n * Parses a property path string into an array of keys, supporting both dot notation and\n * bracket notation (e.g. `\"users[0].name\"`). Pure utility - not affected by `use_state_singleton`.\n * @param {string} path - The path to parse.\n * @returns {string[]} Array of property keys.\n */\n parseStatePath(path) {\n return this.use_state_singleton ? State.parsePath(path) : this.state.parseStatePath(path);\n }\n\n /**\n * Pauses the workflow execution.\n */\n pause() {\n this.should_pause = true;\n this.timing.pause_time = new Date();\n\n events.workflow.emit(\n event_names.workflow.WORKFLOW_PAUSED,\n this.getState()\n );\n }\n\n /**\n * Removes and returns the last step from the workflow.\n * @returns {Step} The last step.\n */\n popStep() {\n return this._steps.pop();\n }\n\n /**\n * Inserts safely serializable properties of the workflow into a new object for serialization.\n * @returns {Object} An object containing the workflow's properties ready for serialization.\n */\n prepareForSerialization() {\n const serialized_workflow = {\n id: this.id,\n current_session_id: this.current_session_id,\n current_step: this.current_step,\n exit_on_error: this.exit_on_error,\n name: this.name,\n sessions: this.sessions,\n status: this.status,\n steps: this._steps.map(step => step.prepareForSerialization()),\n throw_on_empty: this.throw_on_empty,\n timing: this.timing,\n results: this.results,\n use_state_singleton: this.use_state_singleton,\n };\n\n return serialized_workflow;\n }\n\n /**\n * Prepares a result object and adds it to the results array.\n * @param {string} message - Result message.\n * @param {*} data - Result data.\n */\n async prepareResult(message, data) {\n if (this.result_per_step && typeof this.result_per_step_function === 'function') {\n await this.result_per_step_function(this.prepareForSerialization());\n }\n\n const result = { message, data };\n this.results.push(result);\n }\n\n /**\n * Adds a step to the end of the workflow.\n * @param {Step} step - The step to add.\n */\n pushStep(step) {\n this.addStep(step);\n }\n\n /**\n * Adds multiple steps to the end of the workflow.\n * @param {Step[]} steps - Array of steps to add.\n */\n pushSteps(steps) {\n steps.forEach(step => this.addStep(step));\n }\n\n /**\n * Serializes the workflow into a JSON string.\n * @returns {string} The JSON string representation of the workflow.\n */\n serialize() {\n return JSON.stringify(this.prepareForSerialization());\n }\n\n /**\n * Sets a nested property value within this workflow's own state, creating intermediate\n * objects/arrays as needed - the low-level counterpart to `setState()`. Falls back to the\n * deprecated `State` singleton's setter when `use_state_singleton` is `true`.\n * @param {string} path - Path to the state property.\n * @param {*} value - The value to set at the specified path.\n * @param {boolean} [emit=true] - Only meaningful when `use_state_singleton` is `true`; whether\n * to emit the singleton's `SET_TO_PROPERTY_PATH` state event.\n */\n setStateToPropertyPath(path, value, emit = true) {\n if (this.use_state_singleton) {\n console.warn('The state singleton has been deprecated. Use the .prepareForSerialization() method on the workflow instance instead.');\n State.setToPropertyPath(path, value, emit);\n return;\n }\n\n this.state.setStateToPropertyPath(path, value);\n }\n\n /**\n * Removes and returns the first step from the workflow.\n * @returns {Step} The first step.\n */\n shiftStep() {\n return this._steps.shift();\n }\n\n /**\n * Adds a step to the beginning of the workflow.\n * @param {Step} step - The step to add.\n * @throws {Error} Throws if step is not a valid Step instance.\n */\n unshiftStep(step) {\n if (typeof step.getCallableType !== 'function') {\n throw new Error('Invalid step type. Must be an instance of Step.');\n }\n\n if (!this.steps_by_id || typeof this.steps_by_id !== 'object') {\n this.steps_by_id = {};\n }\n\n this.steps_by_id[step.id] = step;\n\n step.parent_workflow_id = this.id;\n step.use_state_singleton = this.use_state_singleton;\n step.state = this.state;\n this._steps.unshift(step);\n }\n\n /**\n * Custom JSON serializer\n * @returns {Object} The JSON representation of the workflow.\n */\n toJSON() {\n return this.prepareForSerialization();\n }\n\n /**\n * Gets the array of steps in the workflow.\n * @returns {Step[]} Array of steps.\n */\n get steps() {\n return this._steps;\n }\n\n /**\n * Sets the steps array by adding multiple steps.\n * @param {Step[]} steps - Array of steps to add.\n */\n set steps(steps) {\n this.addSteps(steps);\n }\n\n /**\n * Deserializes a JSON string into a Workflow instance and hydrates it.\n * @param {string} serialized_workflow - The JSON string representation of the workflow.\n * @param {CallableRegistry|null} [callable_registry] - Registry used to resolve function callables in the workflow's steps.\n * @returns {Workflow} The hydrated Workflow instance.\n * @throws {Error} Throws if the serialized workflow is not a string.\n */\n static hydrateSerialized(serialized_workflow, callable_registry = null) {\n // TODO: Validate structure of serialized workflow\n if (typeof serialized_workflow !== 'string') {\n throw new Error('Invalid serialized workflow. Must be a string.');\n }\n\n const parsed = JSON.parse(serialized_workflow);\n\n return Workflow.hydrate(parsed, callable_registry);\n }\n\n /**\n * Hydrates a parsed workflow object into a Workflow instance.\n * @param {Object} parsed_workflow - The parsed workflow object.\n * @param {CallableRegistry|null} [callable_registry] - Registry used to resolve function callables in the workflow's steps.\n * @returns {Workflow} The hydrated Workflow instance.\n * @throws {Error} Throws if the parsed workflow is not a valid object.\n */\n static hydrate(parsed_workflow, callable_registry = null) {\n // TODO: Validate structure of serialized workflow\n // TODO: Use event system to handle errors?\n if (typeof parsed_workflow !== 'object' || parsed_workflow === null) {\n throw new Error('Invalid parsed workflow. Must be a valid object.');\n }\n\n const hydrated_workflow = new Workflow({\n name: parsed_workflow.name,\n callable_registry,\n exit_on_error: parsed_workflow.exit_on_error,\n steps: parsed_workflow.steps.map(step => Step.hydrateAny(step, callable_registry)),\n throw_on_empty: parsed_workflow.throw_on_empty,\n use_state_singleton: parsed_workflow.use_state_singleton ?? false,\n });\n\n // The constructor above (via Base) always generates a fresh id, and addStep() has\n // already stamped that fresh id onto each step's parent_workflow_id and (in singleton mode)\n // registered the workflow under it in the singleton's `workflows` registry. Restoring the\n // real id below would otherwise leave both referencing a discarded id, so fix them up here\n // too. Per-instance state needs no such fixup for its `workflow` key - it's the same live\n // object, so the id mutation below is reflected automatically.\n const stale_id = hydrated_workflow.id;\n hydrated_workflow.id = parsed_workflow.id;\n\n if (hydrated_workflow.use_state_singleton) {\n const workflows = hydrated_workflow.getState('workflows');\n delete workflows[stale_id];\n workflows[hydrated_workflow.id] = hydrated_workflow;\n hydrated_workflow.setState('workflows', workflows);\n }\n\n hydrated_workflow.steps.forEach(step => {\n step.parent_workflow_id = hydrated_workflow.id;\n });\n\n hydrated_workflow.current_session_id = parsed_workflow.current_session_id;\n hydrated_workflow.current_step = parsed_workflow.current_step ?? hydrated_workflow.current_step;\n hydrated_workflow.sessions = parsed_workflow.sessions ?? {};\n hydrated_workflow.status = parsed_workflow.status;\n hydrated_workflow.timing = parsed_workflow.timing;\n hydrated_workflow.results = parsed_workflow.results;\n\n return hydrated_workflow;\n }\n}\n\n// Framework constants, exposed as static members rather than duplicated into every\n// Workflow's own state (see instance_state.js, the canonical source for these values).\nWorkflow.statuses = statuses;\nWorkflow.event_names = event_names;\nWorkflow.events = events;\nWorkflow.types = types;\nWorkflow.conditional_step_comparators = conditional_step_comparators;\nWorkflow.messages = messages;\n"],
5
+ "mappings": "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",
6
+ "names": ["crypto", "Base", "CallableRegistry", "Step", "State", "statuses", "event_names", "events", "types", "conditional_step_comparators", "messages", "base_types", "Workflow", "__name", "name", "callable_registry", "exit_on_error", "result_per_step", "result_per_step_function", "steps", "throw_on_empty", "use_state_singleton", "is_resuming", "paused_at_index", "step", "start_index", "step_result", "error", "result", "index", "stepId", "path", "emit", "workflows", "fromIndex", "toIndex", "message", "data", "value", "serialized_workflow", "parsed", "parsed_workflow", "hydrated_workflow", "stale_id"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ronaldroe/micro-flow",
3
- "version": "2.0.0",
3
+ "version": "3.0.0",
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": {
@@ -1,6 +1,7 @@
1
1
  import crypto from 'crypto';
2
2
  import { base_types } from '../enums/index.js';
3
- import State, { InstanceState } from './state.js';
3
+ import State from './state.js';
4
+ import { InstanceState } from './instance_state.js';
4
5
 
5
6
  /**
6
7
  * Base class for workflows and steps.
@@ -1,6 +1,7 @@
1
1
  export * from './events/index.js';
2
2
  export { default as Base } from './base.js';
3
3
  export { default as CallableRegistry } from './callable_registry.js';
4
- export { default as State, InstanceState } from './state.js';
4
+ export { default as State } from './state.js';
5
+ export { InstanceState } from './instance_state.js';
5
6
  export { default as Workflow } from './workflow.js';
6
7
  export * from './steps/index.js';