@ronaldroe/micro-flow 1.3.9 β†’ 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 (54) hide show
  1. package/README.md +51 -10
  2. package/dist/src/classes/base.js +2 -2
  3. package/dist/src/classes/base.js.map +3 -3
  4. package/dist/src/classes/callable_registry.js +1 -1
  5. package/dist/src/classes/callable_registry.js.map +2 -2
  6. package/dist/src/classes/events/event.js +1 -1
  7. package/dist/src/classes/events/event.js.map +3 -3
  8. package/dist/src/classes/index.js +1 -1
  9. package/dist/src/classes/index.js.map +3 -3
  10. package/dist/src/classes/instance_state.js +2 -0
  11. package/dist/src/classes/instance_state.js.map +7 -0
  12. package/dist/src/classes/state.js +1 -1
  13. package/dist/src/classes/state.js.map +3 -3
  14. package/dist/src/classes/steps/case.js +1 -1
  15. package/dist/src/classes/steps/case.js.map +3 -3
  16. package/dist/src/classes/steps/conditional_step.js +1 -1
  17. package/dist/src/classes/steps/conditional_step.js.map +3 -3
  18. package/dist/src/classes/steps/delay_step.js +1 -1
  19. package/dist/src/classes/steps/delay_step.js.map +3 -3
  20. package/dist/src/classes/steps/flow_control_step.js +1 -1
  21. package/dist/src/classes/steps/flow_control_step.js.map +3 -3
  22. package/dist/src/classes/steps/logic_step.js +1 -1
  23. package/dist/src/classes/steps/logic_step.js.map +3 -3
  24. package/dist/src/classes/steps/loop_step.js +1 -1
  25. package/dist/src/classes/steps/loop_step.js.map +3 -3
  26. package/dist/src/classes/steps/step.js +1 -1
  27. package/dist/src/classes/steps/step.js.map +3 -3
  28. package/dist/src/classes/steps/switch_step.js +1 -1
  29. package/dist/src/classes/steps/switch_step.js.map +3 -3
  30. package/dist/src/classes/workflow.js +1 -1
  31. package/dist/src/classes/workflow.js.map +3 -3
  32. package/dist/src/enums/delay_types.js.map +1 -1
  33. package/dist/src/enums/logic_step_types.js.map +3 -3
  34. package/dist/src/enums/sub_step_types.js +1 -1
  35. package/dist/src/enums/sub_step_types.js.map +2 -2
  36. package/package.json +1 -1
  37. package/src/classes/base.js +42 -10
  38. package/src/classes/callable_registry.js +82 -0
  39. package/src/classes/events/event.js +3 -3
  40. package/src/classes/index.js +2 -0
  41. package/src/classes/instance_state.js +277 -0
  42. package/src/classes/state.js +20 -49
  43. package/src/classes/steps/case.js +34 -4
  44. package/src/classes/steps/conditional_step.js +72 -5
  45. package/src/classes/steps/delay_step.js +23 -8
  46. package/src/classes/steps/flow_control_step.js +21 -4
  47. package/src/classes/steps/logic_step.js +63 -45
  48. package/src/classes/steps/loop_step.js +88 -3
  49. package/src/classes/steps/step.js +238 -20
  50. package/src/classes/steps/switch_step.js +68 -9
  51. package/src/classes/workflow.js +280 -62
  52. package/src/enums/delay_types.js +1 -1
  53. package/src/enums/logic_step_types.js +2 -2
  54. package/src/enums/sub_step_types.js +10 -10
package/README.md CHANGED
@@ -14,9 +14,10 @@ Micro-Flow treats logic as a first-class object. Instead of managing one monolit
14
14
 
15
15
  - πŸ” **Zero-Effort Observability** - Lifecycle events (`STEP_FAILED`, `WORKFLOW_COMPLETE`) emit automatically β€” eliminate manual log-sprinkling.
16
16
  - ⏸️ **Pause, Resume, & Rewind** - Suspend any logic flow mid-pipeline and resume it later without losing local state.
17
+ - πŸ—„οΈ **Durable Persistence** - Serialize any `Workflow` or `Step` to JSON β€” even mid-pause β€” and hydrate it back later, in the same process or a different one.
17
18
  - 🌿 **Declarative Branching** - Use `ConditionalStep` and `SwitchStep` to keep complex branching logic out of your callables and in the workflow structure.
18
19
  - 🎯 **Dynamic Flow Control** - Break out of or skip steps dynamically at runtime.
19
- - πŸ’Ύ **Namespaced State Management** - Access global state through a namespaced singleton with dot-notation support β€” eliminate data-threading through arguments.
20
+ - πŸ’Ύ **Namespaced State Management** - Every `Workflow` (and the steps it owns) gets its own namespaced, dot-notation state β€” eliminate data-threading through arguments. _(The process-wide `State` singleton this replaced is deprecated β€” see [State Management](#state-management).)_
20
21
  - ✨ **Cross-Tab/Worker Sync** - Broadcast events automatically via `BroadcastChannel` to reach other tabs and workers with zero configuration.
21
22
  - 🌍 **Isomorphic by Design** - Run the same API in Node.js (β‰₯18) and all modern browsers.
22
23
  - 🎨 **Framework Agnostic** - Integrate seamlessly with React, Vue, Svelte, or vanilla JS.
@@ -75,6 +76,32 @@ State.get('events.workflow').on('sync-event', (data) => {
75
76
  State.get('events.workflow').emit('sync-event', { status: 'updated' });
76
77
  ```
77
78
 
79
+ ### πŸ—„οΈ Feature Spotlight: Persistence
80
+ Save a workflow definition β€” or a paused, in-progress one β€” and reload it later. Function callables round-trip through a `CallableRegistry` (raw functions can't be serialized), while `Step`/`Workflow` callables serialize recursively as their own object graph:
81
+
82
+ ```javascript
83
+ import { Workflow, Step, CallableRegistry } from 'micro-flow';
84
+
85
+ const registry = new CallableRegistry();
86
+ registry.register('chargeCard', async function chargeCard() {
87
+ return { charged: true };
88
+ });
89
+
90
+ const workflow = new Workflow({
91
+ name: 'checkout',
92
+ callable_registry: registry,
93
+ steps: [
94
+ new Step({ name: 'charge', callable: registry.get('chargeCard'), callable_registry_key: 'chargeCard' }),
95
+ ],
96
+ });
97
+
98
+ const saved = workflow.serialize(); // -> store this JSON string anywhere
99
+
100
+ // Later, in this process or a fresh one (after re-registering 'chargeCard'):
101
+ const reloaded = Workflow.hydrateSerialized(saved, registry);
102
+ await reloaded.execute();
103
+ ```
104
+
78
105
  ### Browser: Coordinating UI Logic
79
106
 
80
107
  ```javascript
@@ -206,23 +233,35 @@ Orchestrate functions, other steps, or entire workflows as individual units of w
206
233
  Define logic using callables. Assign any async function, step, or workflow to a step's `callable` parameter. This flexibility enables everything from simple logic chains to modularized, enterprise-scale flows.
207
234
 
208
235
  ### State Management
209
- Manage namespaced global state across all workflows and steps:
236
+
237
+ > **Deprecated:** The `State` singleton shown below is deprecated and will be removed in the next major version. By default, every `Workflow` (and the `Step`s it owns) now has its own namespaced state via the same `this.getState()`/`this.setState()` calls β€” no global singleton required. See [Deprecation: continuing to use `State`](docs/classes/state.md#deprecation-continuing-to-use-state) for how to opt back into the old, process-wide behavior in the meantime.
238
+
239
+ Manage namespaced state, scoped to a workflow and the steps it owns:
210
240
 
211
241
  ```javascript
212
- import { State } from 'micro-flow';
242
+ import { Workflow, Step } from 'micro-flow';
213
243
 
214
- // Set and get values with dot-notation
215
- State.set('user.name', 'John Doe');
216
- const timeout = State.get('config.timeout', 3000);
244
+ const workflow = new Workflow({
245
+ steps: [
246
+ new Step({
247
+ callable: async function () {
248
+ // Set and get values with dot-notation
249
+ this.setState('user.name', 'John Doe');
250
+ const timeout = this.getState('config.timeout') ?? 3000;
251
+ },
252
+ }),
253
+ ],
254
+ });
217
255
 
218
- // Merge or iterate over collections
219
- State.merge({ settings: { theme: 'dark' } });
220
- State.each('users', (user) => console.log(user.name));
256
+ await workflow.execute();
221
257
  ```
222
258
 
223
259
  ### Events
224
260
  Monitor lifecycle events for workflows, steps, and state. Use Node's EventEmitter syntax or the browser's CustomEvent syntaxβ€”both support all environments.
225
261
 
262
+ ### Persistence
263
+ Turn a `Workflow` (or `Step`) into a JSON string with `serialize()`, and rebuild it with `Workflow.hydrateSerialized()` / `Step.hydrateSerialized()` β€” including which subclass each step actually is (`ConditionalStep`, `LoopStep`, `SwitchStep`, etc. all come back as themselves). Function callables need a `CallableRegistry` to resolve by name after hydration; `Step`/`Workflow` callables need nothing extra, since they serialize recursively as their own object graph.
264
+
226
265
  ## Use Cases
227
266
 
228
267
  ### Power Backend Processes (Node.js)
@@ -236,10 +275,12 @@ Monitor lifecycle events for workflows, steps, and state. Use Node's EventEmitte
236
275
  - **Data Fetching** - Coordinate sequential API calls with caching.
237
276
  - **Animations** - Sequence complex UI animations.
238
277
  - **State Sync** - Sync auth state and shopping carts across tabs instantly.
278
+ - **Game Logic and Behaviors** - Manage NPC behavior states or enemy actions, such as idle behavior vs attack behavior.
239
279
 
240
280
  ## Documentation
241
281
  Explore the full documentation in the [docs](docs/) directory:
242
282
  - [API Reference](docs/index.md)
243
283
  - [Workflow API](docs/classes/workflow.md)
244
284
  - [Step API](docs/classes/steps/step.md)
245
- - [State Management](docs/classes/state.md)
285
+ - [State Management](docs/classes/state.md) _(the `State` singleton documented here is deprecated)_
286
+ - [CallableRegistry API (Persistence)](docs/classes/callable_registry.md)
@@ -1,4 +1,4 @@
1
- var h=Object.defineProperty;var a=(i,t)=>h(i,"name",{value:t,configurable:!0});import p from"crypto";import{base_types as o}from"../enums/index.js";import e from"./state.js";class r{static{a(this,"Base")}constructor({name:t,base_type:s=o.STEP}){this.id=p.randomUUID(),this.name=t??`${s}-${this.id}`,this.base_type=s,this.timing={cancel_time:null,complete_time:null,execution_time_ms:null,start_time:null}}async execute(){throw new Error("Execute method not implemented")}log(t,s=null){if(!t||!e.get(`events.${this.base_type}`))throw new Error("Invalid event name or event emitter not found");if(e.get(`events.${this.base_type}`).emit(t,this),e.get("log_suppress"))return;const n=s?`
1
+ var r=Object.defineProperty;var o=(n,t)=>r(n,"name",{value:t,configurable:!0});import h from"crypto";import{base_types as m}from"../enums/index.js";import e from"./state.js";import{InstanceState as p}from"./instance_state.js";class l{static{o(this,"Base")}constructor({name:t,base_type:s=m.STEP,use_state_singleton:i=!1,state:a=null}){this.id=h.randomUUID(),this.name=t??`${s}-${this.id}`,this.base_type=s,this.use_state_singleton=i,this.state=i?null:a??new p,this.timing={cancel_time:null,complete_time:null,execution_time_ms:null,start_time:null}}async execute(){throw new Error("Execute method not implemented")}log(t,s=null){if(!t||!e.get(`events.${this.base_type}`))throw new Error("Invalid event name or event emitter not found");if(e.get(`events.${this.base_type}`).emit(t,this),e.get("log_suppress"))return;const i=s?`
2
2
  [${this.base_type.toUpperCase()} - ${this.name}] ${s}`:`
3
- [${this.base_type.toUpperCase()} - ${this.name}] Event: ${t}`,m=t.endsWith("_failed")?"error":"log";console[m](n)}markAsComplete(){this.timing.complete_time=new Date,this.status=e.get("statuses")[this.base_type].COMPLETE,this.timing.execution_time_ms=this.timing.complete_time-this.timing.start_time,this.steps_by_id&&delete this.steps_by_id,this.log(e.get(`event_names.${this.base_type}`)[`${this.base_type.toUpperCase()}_COMPLETE`],`${this.base_type.charAt(0).toUpperCase()+this.base_type.slice(1)} "${this.name}" complete.`)}markAsFailed(){this.timing.complete_time=new Date,this.status=e.get("statuses")[this.base_type].FAILED,this.timing.execution_time_ms=this.timing.complete_time-this.timing.start_time,this.log(e.get(`event_names.${this.base_type}`)[`${this.base_type.toUpperCase()}_FAILED`],`${this.base_type.charAt(0).toUpperCase()+this.base_type.slice(1)} "${this.name}" failed.`)}markAsWaiting(){}markAsPending(){}markAsRunning(){this.timing.start_time=this.timing.start_time??new Date,this.status=e.get("statuses")[this.base_type].RUNNING,this.log(e.get(`event_names.${this.base_type}`)[`${this.base_type.toUpperCase()}_RUNNING`],`${this.base_type.charAt(0).toUpperCase()+this.base_type.slice(1)} "${this.name}" started.`)}getState(t){return e.get(t)}setState(t,s){e.set(t,s)}deleteState(t){e.delete(t)}}export{r as default};
3
+ [${this.base_type.toUpperCase()} - ${this.name}] Event: ${t}`,a=t.endsWith("_failed")?"error":"log";console[a](i)}markAsComplete(){this.timing.complete_time=new Date,this.status=e.get("statuses")[this.base_type].COMPLETE,this.timing.execution_time_ms=this.timing.complete_time-this.timing.start_time,this.steps_by_id&&delete this.steps_by_id,this.log(e.get(`event_names.${this.base_type}`)[`${this.base_type.toUpperCase()}_COMPLETE`],`${this.base_type.charAt(0).toUpperCase()+this.base_type.slice(1)} "${this.name}" complete.`)}markAsFailed(){this.timing.complete_time=new Date,this.status=e.get("statuses")[this.base_type].FAILED,this.timing.execution_time_ms=this.timing.complete_time-this.timing.start_time,this.log(e.get(`event_names.${this.base_type}`)[`${this.base_type.toUpperCase()}_FAILED`],`${this.base_type.charAt(0).toUpperCase()+this.base_type.slice(1)} "${this.name}" failed.`)}markAsWaiting(){}markAsPending(){}markAsRunning(){this.timing.start_time=this.timing.start_time??new Date,this.status=e.get("statuses")[this.base_type].RUNNING,this.log(e.get(`event_names.${this.base_type}`)[`${this.base_type.toUpperCase()}_RUNNING`],`${this.base_type.charAt(0).toUpperCase()+this.base_type.slice(1)} "${this.name}" started.`)}getState(t){return this.use_state_singleton?(console.warn("The state singleton has been deprecated. Use the .prepareForSerialization() method on the workflow instance instead."),e.get(t)):this.state.get(t)}setState(t,s){if(this.use_state_singleton){console.warn("The state singleton has been deprecated. Use the .prepareForSerialization() method on the workflow instance instead."),e.set(t,s);return}this.state.set(t,s)}deleteState(t){if(this.use_state_singleton){console.warn("The state singleton has been deprecated. Use the .prepareForSerialization() method on the workflow instance instead."),e.delete(t);return}this.state.delete(t)}}export{l as default};
4
4
  //# sourceMappingURL=base.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/classes/base.js"],
4
- "sourcesContent": ["import crypto from 'crypto';\nimport { base_types } from '../enums/index.js';\nimport State from './state.js';\n\n/**\n * Base class for workflows and steps.\n * Provides common functionality for timing, status management, logging, and state access.\n * @class Base\n */\nexport default class Base {\n /**\n * Creates a new Base instance.\n * @param {Object} options - Configuration options.\n * @param {string} [options.name] - Name of the instance.\n * @param {string} [options.base_type=base_types.STEP] - Type of the base instance.\n */\n constructor({ name, base_type = base_types.STEP }) {\n this.id = crypto.randomUUID();\n this.name = name ?? `${base_type}-${this.id}`;\n\n this.base_type = base_type;\n this.timing = {\n cancel_time: null,\n complete_time: null,\n execution_time_ms: null,\n start_time: null,\n }\n }\n\n /**\n * Executes the instance. Must be overridden by subclasses.\n * @async\n * @throws {Error} Throws if not implemented in subclass.\n */\n async execute() {\n throw new Error('Execute method not implemented');\n }\n\n /**\n * Logs an event and emits it to the appropriate event emitter.\n * @param {string} event_name - Name of the event to log.\n * @param {string} [message=null] - Optional message to log.\n * @throws {Error} Throws if event name is invalid or event emitter not found.\n */\n log(event_name, message = null) {\n if (!event_name || !State.get(`events.${this.base_type}`)) {\n throw new Error('Invalid event name or event emitter not found');\n }\n\n State.get(`events.${this.base_type}`).emit(event_name, this);\n if (State.get('log_suppress')) {\n return;\n }\n\n const logMessage = message ? `\\n[${this.base_type.toUpperCase()} - ${this.name}] ${message}` : `\\n[${this.base_type.toUpperCase()} - ${this.name}] Event: ${event_name}`;\n const logType = event_name.endsWith('_failed') ? 'error' : 'log';\n\n console[logType](logMessage);\n }\n\n /**\n * Marks the instance as complete and calculates execution time.\n */\n markAsComplete() {\n this.timing.complete_time = new Date();\n this.status = State.get('statuses')[this.base_type].COMPLETE;\n this.timing.execution_time_ms = this.timing.complete_time - this.timing.start_time;\n\n if (this.steps_by_id) {\n delete this.steps_by_id;\n }\n\n this.log(\n State.get(`event_names.${this.base_type}`)[`${this.base_type.toUpperCase()}_COMPLETE`],\n `${this.base_type.charAt(0).toUpperCase() + this.base_type.slice(1)} \"${this.name}\" complete.`\n );\n }\n\n /**\n * Marks the instance as failed and calculates execution time.\n */\n markAsFailed() {\n this.timing.complete_time = new Date();\n this.status = State.get('statuses')[this.base_type].FAILED;\n this.timing.execution_time_ms = this.timing.complete_time - this.timing.start_time;\n\n this.log(\n State.get(`event_names.${this.base_type}`)[`${this.base_type.toUpperCase()}_FAILED`],\n `${this.base_type.charAt(0).toUpperCase() + this.base_type.slice(1)} \"${this.name}\" failed.`\n );\n }\n\n /**\n * Marks the instance as waiting. To be implemented by subclasses.\n */\n markAsWaiting() { }\n\n /**\n * Marks the instance as pending. To be implemented by subclasses.\n */\n markAsPending() { }\n\n /**\n * Marks the instance as running and sets the start time.\n */\n markAsRunning() {\n this.timing.start_time = this.timing.start_time ?? new Date();\n this.status = State.get('statuses')[this.base_type].RUNNING;\n\n this.log(\n State.get(`event_names.${this.base_type}`)[`${this.base_type.toUpperCase()}_RUNNING`],\n `${this.base_type.charAt(0).toUpperCase() + this.base_type.slice(1)} \"${this.name}\" started.`\n );\n }\n\n // State management methods\n /**\n * Gets a value from the global state.\n * @param {string} path - Path to the state property.\n * @returns {*} The state value at the specified path.\n */\n getState(path) {\n return State.get(path);\n }\n\n /**\n * Sets a value in the global state.\n * @param {string} path - Path to the state property.\n * @param {*} value - Value to set.\n */\n setState(path, value) {\n State.set(path, value);\n }\n\n /**\n * Deletes a property from the global state.\n * @param {string} path - Path to the state property to delete.\n */\n deleteState(path) {\n State.delete(path);\n }\n}\n"],
5
- "mappings": "+EAAA,OAAOA,MAAY,SACnB,OAAS,cAAAC,MAAkB,oBAC3B,OAAOC,MAAW,aAOlB,MAAOC,CAAmB,CAT1B,MAS0B,CAAAC,EAAA,aAOxB,YAAY,CAAE,KAAAC,EAAM,UAAAC,EAAYL,EAAW,IAAK,EAAG,CACjD,KAAK,GAAKD,EAAO,WAAW,EAC5B,KAAK,KAAOK,GAAQ,GAAGC,CAAS,IAAI,KAAK,EAAE,GAE3C,KAAK,UAAYA,EACjB,KAAK,OAAS,CACZ,YAAa,KACb,cAAe,KACf,kBAAmB,KACnB,WAAY,IACd,CACF,CAOA,MAAM,SAAU,CACd,MAAM,IAAI,MAAM,gCAAgC,CAClD,CAQA,IAAIC,EAAYC,EAAU,KAAM,CAC9B,GAAI,CAACD,GAAc,CAACL,EAAM,IAAI,UAAU,KAAK,SAAS,EAAE,EACtD,MAAM,IAAI,MAAM,+CAA+C,EAIjE,GADAA,EAAM,IAAI,UAAU,KAAK,SAAS,EAAE,EAAE,KAAKK,EAAY,IAAI,EACvDL,EAAM,IAAI,cAAc,EAC1B,OAGF,MAAMO,EAAaD,EAAU;AAAA,GAAM,KAAK,UAAU,YAAY,CAAC,MAAM,KAAK,IAAI,KAAKA,CAAO,GAAK;AAAA,GAAM,KAAK,UAAU,YAAY,CAAC,MAAM,KAAK,IAAI,YAAYD,CAAU,GAChKG,EAAUH,EAAW,SAAS,SAAS,EAAI,QAAU,MAE3D,QAAQG,CAAO,EAAED,CAAU,CAC7B,CAKA,gBAAiB,CACf,KAAK,OAAO,cAAgB,IAAI,KAChC,KAAK,OAASP,EAAM,IAAI,UAAU,EAAE,KAAK,SAAS,EAAE,SACpD,KAAK,OAAO,kBAAoB,KAAK,OAAO,cAAgB,KAAK,OAAO,WAEpE,KAAK,aACP,OAAO,KAAK,YAGd,KAAK,IACHA,EAAM,IAAI,eAAe,KAAK,SAAS,EAAE,EAAE,GAAG,KAAK,UAAU,YAAY,CAAC,WAAW,EACrF,GAAG,KAAK,UAAU,OAAO,CAAC,EAAE,YAAY,EAAI,KAAK,UAAU,MAAM,CAAC,CAAC,KAAK,KAAK,IAAI,aACnF,CACF,CAKA,cAAe,CACb,KAAK,OAAO,cAAgB,IAAI,KAChC,KAAK,OAASA,EAAM,IAAI,UAAU,EAAE,KAAK,SAAS,EAAE,OACpD,KAAK,OAAO,kBAAoB,KAAK,OAAO,cAAgB,KAAK,OAAO,WAExE,KAAK,IACHA,EAAM,IAAI,eAAe,KAAK,SAAS,EAAE,EAAE,GAAG,KAAK,UAAU,YAAY,CAAC,SAAS,EACnF,GAAG,KAAK,UAAU,OAAO,CAAC,EAAE,YAAY,EAAI,KAAK,UAAU,MAAM,CAAC,CAAC,KAAK,KAAK,IAAI,WACnF,CACF,CAKA,eAAgB,CAAE,CAKlB,eAAgB,CAAE,CAKlB,eAAgB,CACd,KAAK,OAAO,WAAa,KAAK,OAAO,YAAc,IAAI,KACvD,KAAK,OAASA,EAAM,IAAI,UAAU,EAAE,KAAK,SAAS,EAAE,QAEpD,KAAK,IACHA,EAAM,IAAI,eAAe,KAAK,SAAS,EAAE,EAAE,GAAG,KAAK,UAAU,YAAY,CAAC,UAAU,EACpF,GAAG,KAAK,UAAU,OAAO,CAAC,EAAE,YAAY,EAAI,KAAK,UAAU,MAAM,CAAC,CAAC,KAAK,KAAK,IAAI,YACnF,CACF,CAQA,SAASS,EAAM,CACb,OAAOT,EAAM,IAAIS,CAAI,CACvB,CAOA,SAASA,EAAMC,EAAO,CACpBV,EAAM,IAAIS,EAAMC,CAAK,CACvB,CAMA,YAAYD,EAAM,CAChBT,EAAM,OAAOS,CAAI,CACnB,CACF",
6
- "names": ["crypto", "base_types", "State", "Base", "__name", "name", "base_type", "event_name", "message", "logMessage", "logType", "path", "value"]
4
+ "sourcesContent": ["import crypto from 'crypto';\nimport { base_types } from '../enums/index.js';\nimport State from './state.js';\nimport { InstanceState } from './instance_state.js';\n\n/**\n * Base class for workflows and steps.\n * Provides common functionality for timing, status management, logging, and state access.\n * @class Base\n */\nexport default class Base {\n /**\n * Creates a new Base instance.\n * @param {Object} options - Configuration options.\n * @param {string} [options.name] - Name of the instance.\n * @param {string} [options.base_type=base_types.STEP] - Type of the base instance.\n * @param {boolean} [options.use_state_singleton=false] - Deprecated. When true, `getState`/`setState`/`deleteState`\n * fall back to the process-wide `State` singleton instead of this instance's own state. `Workflow` passes this\n * value down to every `Step` it owns, so it only needs to be set once, on the workflow.\n * @param {InstanceState|null} [options.state=null] - The `InstanceState` this instance's `getState`/`setState`/\n * `deleteState` calls should read and write. `Workflow` creates its own on construction and shares it with its\n * `Step`s; a `Step` created standalone (not yet added to a workflow) gets its own until it's added to one.\n */\n constructor({ name, base_type = base_types.STEP, use_state_singleton = false, state = null }) {\n this.id = crypto.randomUUID();\n this.name = name ?? `${base_type}-${this.id}`;\n\n this.base_type = base_type;\n this.use_state_singleton = use_state_singleton;\n this.state = use_state_singleton ? null : (state ?? new InstanceState());\n this.timing = {\n cancel_time: null,\n complete_time: null,\n execution_time_ms: null,\n start_time: null,\n }\n }\n\n /**\n * Executes the instance. Must be overridden by subclasses.\n * @async\n * @throws {Error} Throws if not implemented in subclass.\n */\n async execute() {\n throw new Error('Execute method not implemented');\n }\n\n /**\n * Logs an event and emits it to the appropriate event emitter.\n * @param {string} event_name - Name of the event to log.\n * @param {string} [message=null] - Optional message to log.\n * @throws {Error} Throws if event name is invalid or event emitter not found.\n */\n log(event_name, message = null) {\n if (!event_name || !State.get(`events.${this.base_type}`)) {\n throw new Error('Invalid event name or event emitter not found');\n }\n\n State.get(`events.${this.base_type}`).emit(event_name, this);\n if (State.get('log_suppress')) {\n return;\n }\n\n const log_message = message ? `\\n[${this.base_type.toUpperCase()} - ${this.name}] ${message}` : `\\n[${this.base_type.toUpperCase()} - ${this.name}] Event: ${event_name}`;\n const log_type = event_name.endsWith('_failed') ? 'error' : 'log';\n\n console[log_type](log_message);\n }\n\n /**\n * Marks the instance as complete and calculates execution time.\n */\n markAsComplete() {\n this.timing.complete_time = new Date();\n this.status = State.get('statuses')[this.base_type].COMPLETE;\n this.timing.execution_time_ms = this.timing.complete_time - this.timing.start_time;\n\n if (this.steps_by_id) {\n delete this.steps_by_id;\n }\n\n this.log(\n State.get(`event_names.${this.base_type}`)[`${this.base_type.toUpperCase()}_COMPLETE`],\n `${this.base_type.charAt(0).toUpperCase() + this.base_type.slice(1)} \"${this.name}\" complete.`\n );\n }\n\n /**\n * Marks the instance as failed and calculates execution time.\n */\n markAsFailed() {\n this.timing.complete_time = new Date();\n this.status = State.get('statuses')[this.base_type].FAILED;\n this.timing.execution_time_ms = this.timing.complete_time - this.timing.start_time;\n\n this.log(\n State.get(`event_names.${this.base_type}`)[`${this.base_type.toUpperCase()}_FAILED`],\n `${this.base_type.charAt(0).toUpperCase() + this.base_type.slice(1)} \"${this.name}\" failed.`\n );\n }\n\n /**\n * Marks the instance as waiting. To be implemented by subclasses.\n */\n markAsWaiting() { }\n\n /**\n * Marks the instance as pending. To be implemented by subclasses.\n */\n markAsPending() { }\n\n /**\n * Marks the instance as running and sets the start time.\n */\n markAsRunning() {\n this.timing.start_time = this.timing.start_time ?? new Date();\n this.status = State.get('statuses')[this.base_type].RUNNING;\n\n this.log(\n State.get(`event_names.${this.base_type}`)[`${this.base_type.toUpperCase()}_RUNNING`],\n `${this.base_type.charAt(0).toUpperCase() + this.base_type.slice(1)} \"${this.name}\" started.`\n );\n }\n\n // State management methods\n /**\n * Gets a value from this instance's own state (the `Workflow`'s state, shared with its `Step`s).\n * Set `use_state_singleton: true` (on the owning `Workflow`) to instead read from the\n * deprecated, process-wide `State` singleton.\n * @param {string} path - Path to the state property.\n * @returns {*} The state value at the specified path.\n */\n getState(path) {\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.get(path);\n }\n\n return this.state.get(path);\n }\n\n /**\n * Sets a value in this instance's own state (the `Workflow`'s state, shared with its `Step`s).\n * Set `use_state_singleton: true` (on the owning `Workflow`) to instead write to the\n * deprecated, process-wide `State` singleton.\n * @param {string} path - Path to the state property.\n * @param {*} value - Value to set.\n */\n setState(path, value) {\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.set(path, value);\n return;\n }\n\n this.state.set(path, value);\n }\n\n /**\n * Deletes a property from this instance's own state (the `Workflow`'s state, shared with its `Step`s).\n * Set `use_state_singleton: true` (on the owning `Workflow`) to instead delete from the\n * deprecated, process-wide `State` singleton.\n * @param {string} path - Path to the state property to delete.\n */\n deleteState(path) {\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.delete(path);\n return;\n }\n\n this.state.delete(path);\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["crypto", "base_types", "State", "InstanceState", "Base", "__name", "name", "base_type", "use_state_singleton", "state", "event_name", "message", "log_message", "log_type", "path", "value"]
7
7
  }
@@ -1,2 +1,2 @@
1
- var h=Object.defineProperty;var s=(t,e)=>h(t,"name",{value:e,configurable:!0});class a{static{s(this,"CallableRegistry")}#e;constructor(){this.#e={}}clear(){this.#e={}}deregister(e){if(!this.has(e))throw new Error(`No callable registered under the name "${e}".`);delete this.#e[e]}get(e){if(!this.has(e))throw new Error(`No callable registered under the name "${e}".`);return this.#e[e]}has(e){return Object.hasOwn(this.#e,e)}register(e,r){if(typeof r!="function")throw new Error("Only functions can be registered as callables.");this.#e[e]=r}registerMany(e){for(const[r,i]of Object.entries(e))this.register(r,i)}}export{a as default};
1
+ var a=Object.defineProperty;var s=(t,e)=>a(t,"name",{value:e,configurable:!0});class h{static{s(this,"CallableRegistry")}#e;constructor(){this.clear()}clear(){this.#e={}}deregister(e){if(!this.has(e))throw new Error(`No callable registered under the name "${e}".`);delete this.#e[e]}get(e){if(!this.has(e))throw new Error(`No callable registered under the name "${e}".`);return this.#e[e]}has(e){return Object.hasOwn(this.#e,e)}register(e,r){if(typeof r!="function")throw new Error("Only functions can be registered as callables.");this.#e[e]=r}registerMany(e){for(const[r,i]of Object.entries(e))this.register(r,i)}}export{h as default};
2
2
  //# sourceMappingURL=callable_registry.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/classes/callable_registry.js"],
4
- "sourcesContent": ["/**\n * Provides a registry for callable functions to be used with persistence mode.\n * This class allows you to register, retrieve, check for, and deregister callable functions by name.\n */\nexport default class CallableRegistry {\n #registry;\n\n /**\n * Registry for callable functions to be used with persistence mode.\n */\n constructor() {\n this.#registry = {};\n }\n\n /**\n * Clears all callable entries from the registry.\n */\n clear() {\n this.#registry = {};\n }\n\n /**\n * Removes a callable from the registry.\n * @param {string} name - The name of the callable to remove.\n * @throws Will throw an error if no callable is registered under the given name.\n */\n deregister(name) {\n if (!this.has(name)) {\n throw new Error(`No callable registered under the name \"${name}\".`);\n }\n\n delete this.#registry[name];\n }\n\n /**\n * Retrieves a callable from the registry.\n * @param {string} name - The name of the callable to retrieve.\n * @returns {Function} The callable function registered under the given name.\n * @throws Will throw an error if no callable is registered under the given name.\n */\n get(name) {\n if (!this.has(name)) {\n throw new Error(`No callable registered under the name \"${name}\".`);\n }\n\n return this.#registry[name];\n }\n\n /**\n * Checks if a callable is registered under the given name.\n * @param {string} name - The name of the callable to check.\n * @returns {boolean} True if a callable is registered under the given name, false otherwise.\n */\n has(name) {\n return Object.hasOwn(this.#registry, name);\n }\n\n /**\n * Registers a callable function under a given name.\n * @param {string} name - The name to register the callable under.\n * @param {Function} callable - The function to register as a callable.\n * @throws Will throw an error if the provided callable is not a function.\n */\n register(name, callable) {\n if (typeof callable !== 'function') {\n throw new Error('Only functions can be registered as callables.');\n }\n\n this.#registry[name] = callable;\n }\n\n /**\n * Registers multiple callables from an object mapping names to functions.\n * @param {Object} callables - An object where keys are names and values are functions to register.\n * @throws Will throw an error if any of the provided callables is not a function.\n */\n registerMany(callables) {\n for (const [name, callable] of Object.entries(callables)) {\n this.register(name, callable);\n }\n }\n}\n"],
5
- "mappings": "+EAIA,MAAOA,CAA+B,CAJtC,MAIsC,CAAAC,EAAA,yBACpCC,GAKA,aAAc,CACZ,KAAKA,GAAY,CAAC,CACpB,CAKA,OAAQ,CACN,KAAKA,GAAY,CAAC,CACpB,CAOA,WAAWC,EAAM,CACf,GAAI,CAAC,KAAK,IAAIA,CAAI,EAChB,MAAM,IAAI,MAAM,0CAA0CA,CAAI,IAAI,EAGpE,OAAO,KAAKD,GAAUC,CAAI,CAC5B,CAQA,IAAIA,EAAM,CACR,GAAI,CAAC,KAAK,IAAIA,CAAI,EAChB,MAAM,IAAI,MAAM,0CAA0CA,CAAI,IAAI,EAGpE,OAAO,KAAKD,GAAUC,CAAI,CAC5B,CAOA,IAAIA,EAAM,CACR,OAAO,OAAO,OAAO,KAAKD,GAAWC,CAAI,CAC3C,CAQA,SAASA,EAAMC,EAAU,CACvB,GAAI,OAAOA,GAAa,WACtB,MAAM,IAAI,MAAM,gDAAgD,EAGlE,KAAKF,GAAUC,CAAI,EAAIC,CACzB,CAOA,aAAaC,EAAW,CACtB,SAAW,CAACF,EAAMC,CAAQ,IAAK,OAAO,QAAQC,CAAS,EACrD,KAAK,SAASF,EAAMC,CAAQ,CAEhC,CACF",
4
+ "sourcesContent": ["/**\n * Provides a registry for callable functions to be used with persistence mode.\n * This class allows you to register, retrieve, check for, and deregister callable functions by name.\n */\nexport default class CallableRegistry {\n #registry;\n\n /**\n * Registry for callable functions to be used with persistence mode.\n */\n constructor() {\n this.clear();\n }\n\n /**\n * Clears all callable entries from the registry.\n */\n clear() {\n this.#registry = {};\n }\n\n /**\n * Removes a callable from the registry.\n * @param {string} name - The name of the callable to remove.\n * @throws Will throw an error if no callable is registered under the given name.\n */\n deregister(name) {\n if (!this.has(name)) {\n throw new Error(`No callable registered under the name \"${name}\".`);\n }\n\n delete this.#registry[name];\n }\n\n /**\n * Retrieves a callable from the registry.\n * @param {string} name - The name of the callable to retrieve.\n * @returns {Function} The callable function registered under the given name.\n * @throws Will throw an error if no callable is registered under the given name.\n */\n get(name) {\n if (!this.has(name)) {\n throw new Error(`No callable registered under the name \"${name}\".`);\n }\n\n return this.#registry[name];\n }\n\n /**\n * Checks if a callable is registered under the given name.\n * @param {string} name - The name of the callable to check.\n * @returns {boolean} True if a callable is registered under the given name, false otherwise.\n */\n has(name) {\n return Object.hasOwn(this.#registry, name);\n }\n\n /**\n * Registers a callable function under a given name.\n * @param {string} name - The name to register the callable under.\n * @param {Function} callable - The function to register as a callable.\n * @throws Will throw an error if the provided callable is not a function.\n */\n register(name, callable) {\n if (typeof callable !== 'function') {\n throw new Error('Only functions can be registered as callables.');\n }\n\n this.#registry[name] = callable;\n }\n\n /**\n * Registers multiple callables from an object mapping names to functions.\n * @param {Object} callables - An object where keys are names and values are functions to register.\n * @throws Will throw an error if any of the provided callables is not a function.\n */\n registerMany(callables) {\n for (const [name, callable] of Object.entries(callables)) {\n this.register(name, callable);\n }\n }\n}\n"],
5
+ "mappings": "+EAIA,MAAOA,CAA+B,CAJtC,MAIsC,CAAAC,EAAA,yBACpCC,GAKA,aAAc,CACZ,KAAK,MAAM,CACb,CAKA,OAAQ,CACN,KAAKA,GAAY,CAAC,CACpB,CAOA,WAAWC,EAAM,CACf,GAAI,CAAC,KAAK,IAAIA,CAAI,EAChB,MAAM,IAAI,MAAM,0CAA0CA,CAAI,IAAI,EAGpE,OAAO,KAAKD,GAAUC,CAAI,CAC5B,CAQA,IAAIA,EAAM,CACR,GAAI,CAAC,KAAK,IAAIA,CAAI,EAChB,MAAM,IAAI,MAAM,0CAA0CA,CAAI,IAAI,EAGpE,OAAO,KAAKD,GAAUC,CAAI,CAC5B,CAOA,IAAIA,EAAM,CACR,OAAO,OAAO,OAAO,KAAKD,GAAWC,CAAI,CAC3C,CAQA,SAASA,EAAMC,EAAU,CACvB,GAAI,OAAOA,GAAa,WACtB,MAAM,IAAI,MAAM,gDAAgD,EAGlE,KAAKF,GAAUC,CAAI,EAAIC,CACzB,CAOA,aAAaC,EAAW,CACtB,SAAW,CAACF,EAAMC,CAAQ,IAAK,OAAO,QAAQC,CAAS,EACrD,KAAK,SAASF,EAAMC,CAAQ,CAEhC,CACF",
6
6
  "names": ["CallableRegistry", "__name", "#registry", "name", "callable", "callables"]
7
7
  }
@@ -1,2 +1,2 @@
1
- var u=Object.defineProperty;var a=(d,e)=>u(d,"name",{value:e,configurable:!0});import{warnings as f}from"../../enums/index.js";class i extends EventTarget{static{a(this,"Event")}constructor(){super(),this.events={},this._listener_map=new Map}registerEvents(e){for(const t of Object.values(e))this.events[t]=new i}emit(e,t,s=!1,n=!0){const c=new WeakSet,h=JSON.parse(JSON.stringify(t,(r,o)=>{if(typeof o=="object"&&o!==null){if(c.has(o))return;c.add(o)}return o})),p=new CustomEvent(e,{detail:h,bubbles:s,cancelable:n}),l=this.dispatchEvent(p);try{const r=new BroadcastChannel(e);r.postMessage(h),r.close()}catch(r){console.warn(f.BROADCAST_FAILED,r)}return l}onBroadcast(e,t){const s=new BroadcastChannel(e);return s.onmessage=n=>{t(n.data)},s.send=n=>{s.postMessage(n)},s.destroy=()=>{s.close()},s}onAny(e,t){this.on(e,t);const s=this.onBroadcast(e,t);return{event:this,broadcast:s}}on(e,t){const s=a(n=>{t(n.detail)},"wrapped_listener");return this._listener_map.set(t,s),this.addEventListener(e,s),this}once(e,t){const s=a(n=>{t(n.detail)},"wrapped_listener");return this.addEventListener(e,s,{once:!0}),this}off(e,t){if(this._listener_map&&this._listener_map.has(t)){const s=this._listener_map.get(t);this.removeEventListener(e,s),this._listener_map.delete(t)}return this}removeListener(e,t){return this.off(e,t)}}var g=i;export{g as default};
1
+ var u=Object.defineProperty;var a=(h,e)=>u(h,"name",{value:e,configurable:!0});import{warnings as _}from"../../enums/index.js";class i extends EventTarget{static{a(this,"Event")}constructor(){super(),this.events={},this._listener_map=new Map}registerEvents(e){for(const t of Object.values(e))this.events[t]=new i}emit(e,t,s=!1,n=!0){const c=new WeakSet,d=JSON.parse(JSON.stringify(t,(r,o)=>{if(typeof o=="object"&&o!==null){if(c.has(o))return;c.add(o)}return o})),p=new CustomEvent(e,{detail:d,bubbles:s,cancelable:n}),l=this.dispatchEvent(p);try{const r=new BroadcastChannel(e);r.postMessage(d),r.close()}catch(r){console.warn(_.BROADCAST_FAILED,r)}return l}onBroadcast(e,t){const s=new BroadcastChannel(e);return s.onmessage=n=>{t(n.data)},s.send=n=>{s.postMessage(n)},s.destroy=()=>{s.close()},s}onAny(e,t){this.on(e,t);const s=this.onBroadcast(e,t);return{event:this,broadcast:s}}on(e,t){const s=a(n=>{t(n.detail)},"wrapped_listener");return this._listener_map.set(t,s),this.addEventListener(e,s),this}once(e,t){const s=a(n=>{t(n.detail)},"wrapped_listener");return this.addEventListener(e,s,{once:!0}),this}off(e,t){if(this._listener_map&&this._listener_map.has(t)){const s=this._listener_map.get(t);this.removeEventListener(e,s),this._listener_map.delete(t)}return this}removeListener(e,t){return this.off(e,t)}}var g=i;export{g as default};
2
2
  //# sourceMappingURL=event.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/classes/events/event.js"],
4
- "sourcesContent": ["import { errors, warnings } from '../../enums/index.js';\n\n/**\n * Event class for micro-flow\n * Provides a simple event emitter implementation for workflow steps and state changes.\n *\n * This class is used for emitting and listening to events within workflows and steps.\n * For broadcasting events across multiple workflows or listeners, it uses BroadcastChannel.\n */\nclass Event extends EventTarget {\n /**\n * Creates a new Event instance.\n * @constructor\n */\n constructor() {\n super();\n this.events = {};\n this._listener_map = new Map();\n }\n\n /**\n * Registers multiple events by creating Event instances for each event name.\n * @param {Object} event_names - An object containing event name constants.\n * @returns {void}\n */\n registerEvents(event_names) {\n for (const event_name of Object.values(event_names)) {\n this.events[event_name] = new Event();\n }\n }\n\n /**\n * Emits a custom event with optional data payload.\n * This method maintains API compatibility with EventEmitter while using CustomEvent.\n * @param {string} event_name - The name of the event to emit.\n * @param {*} [data] - Optional data to pass with the event in the detail property.\n * @param {boolean} [bubbles=false] - Whether the event should bubble up through the DOM.\n * @param {boolean} [cancelable=true] - Whether the event is cancelable.\n * @returns {boolean} True if the event was not cancelled, false if it was cancelled.\n */\n emit(event_name, data, bubbles = false, cancelable = true) {\n const seen = new WeakSet();\n const workingData = JSON.parse(JSON.stringify(data, (key, value) => {\n if (typeof value === 'object' && value !== null) {\n if (seen.has(value)) return undefined;\n seen.add(value);\n }\n return value;\n }));\n\n const custom_event = new CustomEvent(event_name, {\n detail: workingData,\n bubbles,\n cancelable\n });\n const result = this.dispatchEvent(custom_event);\n\n try {\n const channel = new BroadcastChannel(event_name);\n channel.postMessage(workingData);\n channel.close();\n } catch (e) {\n console.warn(warnings.BROADCAST_FAILED, e);\n }\n return result;\n }\n\n /**\n * Listen for broadcasts on a given event name (channel).\n * @param {string} event_name - The event name/channel to listen for.\n * @param {Function} listener - Callback for broadcasted data.\n * @returns {BroadcastChannel} Returns the channel with send() and destroy() aliases.\n */\n onBroadcast(event_name, listener) {\n const channel = new BroadcastChannel(event_name);\n channel.onmessage = (event) => {\n listener(event.data);\n };\n channel.send = (data) => {\n channel.postMessage(data);\n };\n channel.destroy = () => {\n channel.close();\n };\n return channel;\n }\n\n /**\n * Listen for both local and broadcast events.\n * @param {string} event_name - The event name/channel to listen for.\n * @param {Function} listener - Callback for event data.\n * @returns {Object} Returns { event: this, broadcast: BroadcastChannel }\n */\n onAny(event_name, listener) {\n this.on(event_name, listener);\n const broadcast = this.onBroadcast(event_name, listener);\n return { event: this, broadcast };\n }\n\n /**\n * Adds an event listener with EventEmitter-style API.\n * Maintains compatibility with the original API while using addEventListener.\n * @param {string} event_name - The name of the event to listen for.\n * @param {Function} listener - The callback function to execute when the event fires.\n * @returns {Event} Returns this for chaining.\n */\n on(event_name, listener) {\n const wrapped_listener = (event) => {\n // Call the listener with the detail (data) from CustomEvent\n listener(event.detail);\n };\n // Store the original listener reference for removeListener\n this._listener_map.set(listener, wrapped_listener);\n this.addEventListener(event_name, wrapped_listener);\n return this;\n }\n\n /**\n * Adds a one-time event listener with EventEmitter-style API.\n * @param {string} event_name - The name of the event to listen for.\n * @param {Function} listener - The callback function to execute when the event fires.\n * @returns {Event} Returns this for chaining.\n */\n once(event_name, listener) {\n const wrapped_listener = (event) => {\n listener(event.detail);\n };\n this.addEventListener(event_name, wrapped_listener, { once: true });\n return this;\n }\n\n /**\n * Removes an event listener with EventEmitter-style API.\n * @param {string} event_name - The name of the event.\n * @param {Function} listener - The callback function to remove.\n * @returns {Event} Returns this for chaining.\n */\n off(event_name, listener) {\n if (this._listener_map && this._listener_map.has(listener)) {\n const wrapped_listener = this._listener_map.get(listener);\n this.removeEventListener(event_name, wrapped_listener);\n this._listener_map.delete(listener);\n }\n return this;\n }\n\n /**\n * Alias for off() to maintain EventEmitter API compatibility.\n * @param {string} event_name - The name of the event.\n * @param {Function} listener - The callback function to remove.\n * @returns {Event} Returns this for chaining.\n */\n removeListener(event_name, listener) {\n return this.off(event_name, listener);\n }\n}\n\nexport default Event;\n"],
5
- "mappings": "+EAAA,OAAiB,YAAAA,MAAgB,uBASjC,MAAMC,UAAc,WAAY,CAThC,MASgC,CAAAC,EAAA,cAK9B,aAAc,CACZ,MAAM,EACN,KAAK,OAAS,CAAC,EACf,KAAK,cAAgB,IAAI,GAC3B,CAOA,eAAeC,EAAa,CAC1B,UAAWC,KAAc,OAAO,OAAOD,CAAW,EAChD,KAAK,OAAOC,CAAU,EAAI,IAAIH,CAElC,CAWA,KAAKG,EAAYC,EAAMC,EAAU,GAAOC,EAAa,GAAM,CACzD,MAAMC,EAAO,IAAI,QACXC,EAAc,KAAK,MAAM,KAAK,UAAUJ,EAAM,CAACK,EAAKC,IAAU,CAClE,GAAI,OAAOA,GAAU,UAAYA,IAAU,KAAM,CAC/C,GAAIH,EAAK,IAAIG,CAAK,EAAG,OACrBH,EAAK,IAAIG,CAAK,CAChB,CACA,OAAOA,CACT,CAAC,CAAC,EAEIC,EAAe,IAAI,YAAYR,EAAY,CAC/C,OAAQK,EACR,QAAAH,EACA,WAAAC,CACF,CAAC,EACKM,EAAS,KAAK,cAAcD,CAAY,EAE9C,GAAI,CACF,MAAME,EAAU,IAAI,iBAAiBV,CAAU,EAC/CU,EAAQ,YAAYL,CAAW,EAC/BK,EAAQ,MAAM,CAChB,OAASC,EAAG,CACV,QAAQ,KAAKf,EAAS,iBAAkBe,CAAC,CAC3C,CACA,OAAOF,CACT,CAQA,YAAYT,EAAYY,EAAU,CAChC,MAAMF,EAAU,IAAI,iBAAiBV,CAAU,EAC/C,OAAAU,EAAQ,UAAaG,GAAU,CAC7BD,EAASC,EAAM,IAAI,CACrB,EACAH,EAAQ,KAAQT,GAAS,CACvBS,EAAQ,YAAYT,CAAI,CAC1B,EACAS,EAAQ,QAAU,IAAM,CACtBA,EAAQ,MAAM,CAChB,EACOA,CACT,CAQA,MAAMV,EAAYY,EAAU,CAC1B,KAAK,GAAGZ,EAAYY,CAAQ,EAC5B,MAAME,EAAY,KAAK,YAAYd,EAAYY,CAAQ,EACvD,MAAO,CAAE,MAAO,KAAM,UAAAE,CAAU,CAClC,CASA,GAAGd,EAAYY,EAAU,CACvB,MAAMG,EAAmBjB,EAACe,GAAU,CAElCD,EAASC,EAAM,MAAM,CACvB,EAHyB,oBAKzB,YAAK,cAAc,IAAID,EAAUG,CAAgB,EACjD,KAAK,iBAAiBf,EAAYe,CAAgB,EAC3C,IACT,CAQA,KAAKf,EAAYY,EAAU,CACzB,MAAMG,EAAmBjB,EAACe,GAAU,CAClCD,EAASC,EAAM,MAAM,CACvB,EAFyB,oBAGzB,YAAK,iBAAiBb,EAAYe,EAAkB,CAAE,KAAM,EAAK,CAAC,EAC3D,IACT,CAQA,IAAIf,EAAYY,EAAU,CACxB,GAAI,KAAK,eAAiB,KAAK,cAAc,IAAIA,CAAQ,EAAG,CAC1D,MAAMG,EAAmB,KAAK,cAAc,IAAIH,CAAQ,EACxD,KAAK,oBAAoBZ,EAAYe,CAAgB,EACrD,KAAK,cAAc,OAAOH,CAAQ,CACpC,CACA,OAAO,IACT,CAQA,eAAeZ,EAAYY,EAAU,CACnC,OAAO,KAAK,IAAIZ,EAAYY,CAAQ,CACtC,CACF,CAEA,IAAOI,EAAQnB",
6
- "names": ["warnings", "Event", "__name", "event_names", "event_name", "data", "bubbles", "cancelable", "seen", "workingData", "key", "value", "custom_event", "result", "channel", "e", "listener", "event", "broadcast", "wrapped_listener", "event_default"]
4
+ "sourcesContent": ["import { errors, warnings } from '../../enums/index.js';\n\n/**\n * Event class for micro-flow\n * Provides a simple event emitter implementation for workflow steps and state changes.\n *\n * This class is used for emitting and listening to events within workflows and steps.\n * For broadcasting events across multiple workflows or listeners, it uses BroadcastChannel.\n */\nclass Event extends EventTarget {\n /**\n * Creates a new Event instance.\n * @constructor\n */\n constructor() {\n super();\n this.events = {};\n this._listener_map = new Map();\n }\n\n /**\n * Registers multiple events by creating Event instances for each event name.\n * @param {Object} event_names - An object containing event name constants.\n * @returns {void}\n */\n registerEvents(event_names) {\n for (const event_name of Object.values(event_names)) {\n this.events[event_name] = new Event();\n }\n }\n\n /**\n * Emits a custom event with optional data payload.\n * This method maintains API compatibility with EventEmitter while using CustomEvent.\n * @param {string} event_name - The name of the event to emit.\n * @param {*} [data] - Optional data to pass with the event in the detail property.\n * @param {boolean} [bubbles=false] - Whether the event should bubble up through the DOM.\n * @param {boolean} [cancelable=true] - Whether the event is cancelable.\n * @returns {boolean} True if the event was not cancelled, false if it was cancelled.\n */\n emit(event_name, data, bubbles = false, cancelable = true) {\n const seen = new WeakSet();\n const working_data = JSON.parse(JSON.stringify(data, (key, value) => {\n if (typeof value === 'object' && value !== null) {\n if (seen.has(value)) return undefined;\n seen.add(value);\n }\n return value;\n }));\n\n const custom_event = new CustomEvent(event_name, {\n detail: working_data,\n bubbles,\n cancelable\n });\n const result = this.dispatchEvent(custom_event);\n\n try {\n const channel = new BroadcastChannel(event_name);\n channel.postMessage(working_data);\n channel.close();\n } catch (e) {\n console.warn(warnings.BROADCAST_FAILED, e);\n }\n return result;\n }\n\n /**\n * Listen for broadcasts on a given event name (channel).\n * @param {string} event_name - The event name/channel to listen for.\n * @param {Function} listener - Callback for broadcasted data.\n * @returns {BroadcastChannel} Returns the channel with send() and destroy() aliases.\n */\n onBroadcast(event_name, listener) {\n const channel = new BroadcastChannel(event_name);\n channel.onmessage = (event) => {\n listener(event.data);\n };\n channel.send = (data) => {\n channel.postMessage(data);\n };\n channel.destroy = () => {\n channel.close();\n };\n return channel;\n }\n\n /**\n * Listen for both local and broadcast events.\n * @param {string} event_name - The event name/channel to listen for.\n * @param {Function} listener - Callback for event data.\n * @returns {Object} Returns { event: this, broadcast: BroadcastChannel }\n */\n onAny(event_name, listener) {\n this.on(event_name, listener);\n const broadcast = this.onBroadcast(event_name, listener);\n return { event: this, broadcast };\n }\n\n /**\n * Adds an event listener with EventEmitter-style API.\n * Maintains compatibility with the original API while using addEventListener.\n * @param {string} event_name - The name of the event to listen for.\n * @param {Function} listener - The callback function to execute when the event fires.\n * @returns {Event} Returns this for chaining.\n */\n on(event_name, listener) {\n const wrapped_listener = (event) => {\n // Call the listener with the detail (data) from CustomEvent\n listener(event.detail);\n };\n // Store the original listener reference for removeListener\n this._listener_map.set(listener, wrapped_listener);\n this.addEventListener(event_name, wrapped_listener);\n return this;\n }\n\n /**\n * Adds a one-time event listener with EventEmitter-style API.\n * @param {string} event_name - The name of the event to listen for.\n * @param {Function} listener - The callback function to execute when the event fires.\n * @returns {Event} Returns this for chaining.\n */\n once(event_name, listener) {\n const wrapped_listener = (event) => {\n listener(event.detail);\n };\n this.addEventListener(event_name, wrapped_listener, { once: true });\n return this;\n }\n\n /**\n * Removes an event listener with EventEmitter-style API.\n * @param {string} event_name - The name of the event.\n * @param {Function} listener - The callback function to remove.\n * @returns {Event} Returns this for chaining.\n */\n off(event_name, listener) {\n if (this._listener_map && this._listener_map.has(listener)) {\n const wrapped_listener = this._listener_map.get(listener);\n this.removeEventListener(event_name, wrapped_listener);\n this._listener_map.delete(listener);\n }\n return this;\n }\n\n /**\n * Alias for off() to maintain EventEmitter API compatibility.\n * @param {string} event_name - The name of the event.\n * @param {Function} listener - The callback function to remove.\n * @returns {Event} Returns this for chaining.\n */\n removeListener(event_name, listener) {\n return this.off(event_name, listener);\n }\n}\n\nexport default Event;\n"],
5
+ "mappings": "+EAAA,OAAiB,YAAAA,MAAgB,uBASjC,MAAMC,UAAc,WAAY,CAThC,MASgC,CAAAC,EAAA,cAK9B,aAAc,CACZ,MAAM,EACN,KAAK,OAAS,CAAC,EACf,KAAK,cAAgB,IAAI,GAC3B,CAOA,eAAeC,EAAa,CAC1B,UAAWC,KAAc,OAAO,OAAOD,CAAW,EAChD,KAAK,OAAOC,CAAU,EAAI,IAAIH,CAElC,CAWA,KAAKG,EAAYC,EAAMC,EAAU,GAAOC,EAAa,GAAM,CACzD,MAAMC,EAAO,IAAI,QACXC,EAAe,KAAK,MAAM,KAAK,UAAUJ,EAAM,CAACK,EAAKC,IAAU,CACnE,GAAI,OAAOA,GAAU,UAAYA,IAAU,KAAM,CAC/C,GAAIH,EAAK,IAAIG,CAAK,EAAG,OACrBH,EAAK,IAAIG,CAAK,CAChB,CACA,OAAOA,CACT,CAAC,CAAC,EAEIC,EAAe,IAAI,YAAYR,EAAY,CAC/C,OAAQK,EACR,QAAAH,EACA,WAAAC,CACF,CAAC,EACKM,EAAS,KAAK,cAAcD,CAAY,EAE9C,GAAI,CACF,MAAME,EAAU,IAAI,iBAAiBV,CAAU,EAC/CU,EAAQ,YAAYL,CAAY,EAChCK,EAAQ,MAAM,CAChB,OAASC,EAAG,CACV,QAAQ,KAAKf,EAAS,iBAAkBe,CAAC,CAC3C,CACA,OAAOF,CACT,CAQA,YAAYT,EAAYY,EAAU,CAChC,MAAMF,EAAU,IAAI,iBAAiBV,CAAU,EAC/C,OAAAU,EAAQ,UAAaG,GAAU,CAC7BD,EAASC,EAAM,IAAI,CACrB,EACAH,EAAQ,KAAQT,GAAS,CACvBS,EAAQ,YAAYT,CAAI,CAC1B,EACAS,EAAQ,QAAU,IAAM,CACtBA,EAAQ,MAAM,CAChB,EACOA,CACT,CAQA,MAAMV,EAAYY,EAAU,CAC1B,KAAK,GAAGZ,EAAYY,CAAQ,EAC5B,MAAME,EAAY,KAAK,YAAYd,EAAYY,CAAQ,EACvD,MAAO,CAAE,MAAO,KAAM,UAAAE,CAAU,CAClC,CASA,GAAGd,EAAYY,EAAU,CACvB,MAAMG,EAAmBjB,EAACe,GAAU,CAElCD,EAASC,EAAM,MAAM,CACvB,EAHyB,oBAKzB,YAAK,cAAc,IAAID,EAAUG,CAAgB,EACjD,KAAK,iBAAiBf,EAAYe,CAAgB,EAC3C,IACT,CAQA,KAAKf,EAAYY,EAAU,CACzB,MAAMG,EAAmBjB,EAACe,GAAU,CAClCD,EAASC,EAAM,MAAM,CACvB,EAFyB,oBAGzB,YAAK,iBAAiBb,EAAYe,EAAkB,CAAE,KAAM,EAAK,CAAC,EAC3D,IACT,CAQA,IAAIf,EAAYY,EAAU,CACxB,GAAI,KAAK,eAAiB,KAAK,cAAc,IAAIA,CAAQ,EAAG,CAC1D,MAAMG,EAAmB,KAAK,cAAc,IAAIH,CAAQ,EACxD,KAAK,oBAAoBZ,EAAYe,CAAgB,EACrD,KAAK,cAAc,OAAOH,CAAQ,CACpC,CACA,OAAO,IACT,CAQA,eAAeZ,EAAYY,EAAU,CACnC,OAAO,KAAK,IAAIZ,EAAYY,CAAQ,CACtC,CACF,CAEA,IAAOI,EAAQnB",
6
+ "names": ["warnings", "Event", "__name", "event_names", "event_name", "data", "bubbles", "cancelable", "seen", "working_data", "key", "value", "custom_event", "result", "channel", "e", "listener", "event", "broadcast", "wrapped_listener", "event_default"]
7
7
  }
@@ -1,2 +1,2 @@
1
- export*from"./events/index.js";import{default as t}from"./base.js";import{default as a}from"./state.js";import{default as p}from"./workflow.js";export*from"./steps/index.js";export{t as Base,a as State,p as Workflow};
1
+ export*from"./events/index.js";import{default as r}from"./base.js";import{default as f}from"./callable_registry.js";import{default as m}from"./state.js";import{InstanceState as s}from"./instance_state.js";import{default as d}from"./workflow.js";export*from"./steps/index.js";export{r as Base,f as CallableRegistry,s as InstanceState,m as State,d as Workflow};
2
2
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/classes/index.js"],
4
- "sourcesContent": ["export * from './events/index.js';\nexport { default as Base } from './base.js';\nexport { default as State } from './state.js';\nexport { default as Workflow } from './workflow.js';\nexport * from './steps/index.js';\n"],
5
- "mappings": "AAAA,WAAc,oBACd,OAAoB,WAAXA,MAAuB,YAChC,OAAoB,WAAXA,MAAwB,aACjC,OAAoB,WAAXA,MAA2B,gBACpC,WAAc",
6
- "names": ["default"]
4
+ "sourcesContent": ["export * from './events/index.js';\nexport { default as Base } from './base.js';\nexport { default as CallableRegistry } from './callable_registry.js';\nexport { default as State } from './state.js';\nexport { InstanceState } from './instance_state.js';\nexport { default as Workflow } from './workflow.js';\nexport * from './steps/index.js';\n"],
5
+ "mappings": "AAAA,WAAc,oBACd,OAAoB,WAAXA,MAAuB,YAChC,OAAoB,WAAXA,MAAmC,yBAC5C,OAAoB,WAAXA,MAAwB,aACjC,OAAS,iBAAAC,MAAqB,sBAC9B,OAAoB,WAAXD,MAA2B,gBACpC,WAAc",
6
+ "names": ["default", "InstanceState"]
7
7
  }
@@ -0,0 +1,2 @@
1
+ var w=Object.defineProperty;var a=(n,t)=>w(n,"name",{value:t,configurable:!0});import{errors as i,warnings as _}from"../enums/errors.js";import{StepEvent as y,WorkflowEvent as m,StateEvent as d}from"./events/index.js";import{base_types as g,conditional_step_comparators as b,state_event_names as P,step_event_names as A,step_statuses as E,step_types as j,sub_step_types as x,workflow_event_names as O,workflow_statuses as S}from"../enums/index.js";function p(n){const t=n.match(/[^.[\]]+|(?<=\[)([^\]]+)(?=\])/g);return t?t.map(r=>r.replace(/^['"]|['"]$/g,"")):[]}a(p,"parsePath");function f(n,t){const r=p(t);let e=n;for(const o of r)if(e&&Object.prototype.hasOwnProperty.call(e,o))e=e[o];else return;return e}a(f,"getAtPath");function l(n,t,r){const e=p(t);let o=n;for(let s=0;s<e.length-1;s++){const c=e[s],h=e[s+1];if(!Object.prototype.hasOwnProperty.call(o,c)||typeof o[c]!="object"){const u=/^\d+$/.test(h);o[c]=u?[]:{}}o=o[c]}o[e[e.length-1]]=r}a(l,"setAtPath");function T(n,t){const r=p(t);let e=n;for(let o=0;o<r.length-1;o++){const s=r[o];if(!Object.prototype.hasOwnProperty.call(e,s)||typeof e[s]!="object")return;e=e[s]}delete e[r[r.length-1]]}a(T,"deleteAtPath");function k(n,t){if(!t)return n;try{switch(t){case"string":return String(n);case"number":return Number(n);case"boolean":return!!n;default:return n}}catch(r){return console.error("Error converting state value: ",r),n}}a(k,"convertType");const B={errors:i,warnings:_},D={workflow:S,step:E},H={workflow:O,step:A,state:P},$={workflow:new m,step:new y,state:new d},F={base_types:g,step_types:j,sub_step_types:x};class R{static{a(this,"InstanceState")}constructor(t={}){this.data=t}get(t,r=null,e=null){if(!t||["*",""].includes(t))return this.data??r;const o=f(this.data,t)??r;return k(o,e)??r}set(t,r){if(!t)throw new Error(i.INVALID_STATE_PATH);l(this.data,t,r)}getStateFromPropertyPath(t){return f(this.data,t)}parseStatePath(t){return p(t)}setStateToPropertyPath(t,r){l(this.data,t,r)}delete(t){if(!t)throw new Error(i.INVALID_STATE_PATH);T(this.data,t)}merge(t){return this.data={...this.data,...t},this.data}async each(t,r){const e=this.get(t);if(Array.isArray(e))for(const[o,s]of e.entries())await r(s,o);else if(typeof e=="object"&&Object.prototype.toString.call(e)==="[object Object]")for(const o of Object.keys(e))await r(e[o],o);else throw new Error(i.VALUE_NOT_ITERABLE)}}export{R as InstanceState,b as conditional_step_comparators,H as event_names,$ as events,B as messages,D as statuses,F as types};
2
+ //# sourceMappingURL=instance_state.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/classes/instance_state.js"],
4
+ "sourcesContent": ["import { errors, warnings } from '../enums/errors.js';\nimport { StepEvent, WorkflowEvent, StateEvent } from './events/index.js';\nimport {\n base_types,\n conditional_step_comparators,\n state_event_names,\n step_event_names,\n step_statuses,\n step_types,\n sub_step_types,\n workflow_event_names,\n workflow_statuses,\n} from '../enums/index.js';\n\n/**\n * Parses a property path string into an array of keys, supporting both dot notation\n * and bracket notation.\n *\n * @param {string} path - The path to parse (e.g., \"user.profile.name\", \"users[0].name\", \"data['key-name']\").\n * @returns {string[]} Array of property keys.\n */\nfunction parsePath(path) {\n const matches = path.match(/[^.[\\]]+|(?<=\\[)([^\\]]+)(?=\\])/g);\n\n if (!matches) {\n return [];\n }\n\n return matches.map(part => part.replace(/^['\"]|['\"]$/g, ''));\n}\n\n/**\n * Resolves a nested property path within an arbitrary object.\n * @param {Object} target - The object to read from.\n * @param {string} path - The path to the property.\n * @returns {*} The value at the specified path, or undefined if not found.\n */\nfunction getAtPath(target, path) {\n const parts = parsePath(path);\n let current = target;\n\n for (const part of parts) {\n if (current && Object.prototype.hasOwnProperty.call(current, part)) {\n current = current[part];\n } else {\n return undefined;\n }\n }\n\n return current;\n}\n\n/**\n * Sets a nested property value within an arbitrary object based on a path.\n * Creates intermediate objects/arrays as needed.\n * @param {Object} target - The object to write to.\n * @param {string} path - The path to the property.\n * @param {*} value - The value to set at the specified path.\n */\nfunction setAtPath(target, path, value) {\n const parts = parsePath(path);\n let current = target;\n\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i];\n const next_part = parts[i + 1];\n\n if (!Object.prototype.hasOwnProperty.call(current, part) || typeof current[part] !== 'object') {\n const is_next_part_numeric = /^\\d+$/.test(next_part);\n current[part] = is_next_part_numeric ? [] : {};\n }\n current = current[part];\n }\n\n current[parts[parts.length - 1]] = value;\n}\n\n/**\n * Deletes a property from an arbitrary object using a path.\n * @param {Object} target - The object to delete from.\n * @param {string} path - The path of the property to delete.\n */\nfunction deleteAtPath(target, path) {\n const parts = parsePath(path);\n let current = target;\n\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i];\n\n if (!Object.prototype.hasOwnProperty.call(current, part) || typeof current[part] !== 'object') {\n return;\n }\n\n current = current[part];\n }\n\n delete current[parts[parts.length - 1]];\n}\n\n/**\n * Converts a resolved state value to the requested output type.\n * @param {*} value - The value to convert.\n * @param {string|null} type - One of \"string\", \"number\", \"boolean\".\n * @returns {*} The converted value, or the original value if conversion fails or type is unrecognized.\n */\nfunction convertType(value, type) {\n if (!type) {\n return value;\n }\n\n try {\n switch (type) {\n case 'string':\n return String(value);\n case 'number':\n return Number(value);\n case 'boolean':\n return Boolean(value);\n default:\n return value;\n }\n } catch (error) {\n console.error('Error converting state value: ', error);\n return value;\n }\n}\n\n/**\n * Framework constants, built once here as the single canonical source. `Workflow` (see\n * `workflow.js`) assigns these as its own static members - the public surface library\n * consumers should reach them through - while step classes that need one directly may import\n * the named export straight from this module instead of going through `Workflow` (avoiding an\n * import cycle). The deprecated `State` singleton (`state.js`) also builds its `default_state`\n * from these same values, so the `events.*` instances stay identical (by reference) regardless\n * of whether a given `Workflow`/`Step` has opted into `use_state_singleton` - listeners\n * registered via `State.get('events.workflow')` keep receiving events either way.\n */\nexport const messages = { errors, warnings };\nexport const statuses = { workflow: workflow_statuses, step: step_statuses };\nexport const event_names = { workflow: workflow_event_names, step: step_event_names, state: state_event_names };\nexport const events = { workflow: new WorkflowEvent(), step: new StepEvent(), state: new StateEvent() };\nexport const types = { base_types, step_types, sub_step_types };\nexport { conditional_step_comparators };\n\n/**\n * Per-instance replacement for the deprecated `State` singleton. Each `Workflow` owns one of\n * these (created in its constructor), and shares it with every `Step` added to it, so that\n * `getState()`/`setState()`/`deleteState()` calls made anywhere in that workflow's tree read and\n * write the same, workflow-scoped data instead of a single process-wide object. A `Workflow`\n * registers itself under the `workflow` key of its own `InstanceState` (see\n * `initializeWorkflowState()` in `workflow.js`), so `getState('workflow')` resolves to the live\n * owning `Workflow` instance; any other path is arbitrary user data set via `setState()`.\n *\n * Supports the same dot-notation/bracket-notation path access as `State`.\n *\n * @class InstanceState\n */\nexport class InstanceState {\n /**\n * Creates a new InstanceState.\n * @param {Object} [initial={}] - Initial data.\n */\n constructor(initial = {}) {\n this.data = initial;\n }\n\n /**\n * Gets the value of a state property using dot-notation or bracket-notation path access.\n * @param {string} path - The path of the state property to get. Falsy values, or \"*\", return the entire state.\n * @param {*} [defaultValue=null] - Default value to return if the path doesn't exist.\n * @param {string|null} [type=null] - The output type to convert the value to (\"string\", \"number\", \"boolean\").\n * @returns {*} The value of the state property, or defaultValue if not found.\n */\n get(path, defaultValue = null, type = null) {\n if (!path || ['*', ''].includes(path)) {\n return this.data ?? defaultValue;\n }\n\n const gotten = getAtPath(this.data, path) ?? defaultValue;\n\n return convertType(gotten, type) ?? defaultValue;\n }\n\n /**\n * Sets the value of a state property using dot-notation or bracket-notation path access.\n * Creates intermediate objects if they don't exist.\n * @param {string} path - The path of the state property to set.\n * @param {*} value - The value to set for the state property.\n * @throws {Error} Throws if path is empty or invalid.\n */\n set(path, value) {\n if (!path) {\n throw new Error(errors.INVALID_STATE_PATH);\n }\n\n setAtPath(this.data, path, value);\n }\n\n /**\n * Resolves a nested property path within this instance's data. Low-level counterpart to\n * `get()` - unlike `get()`, a falsy/`'*'` path is not special-cased to mean \"entire state\".\n * @param {string} path - The path to the property.\n * @returns {*} The value at the specified path, or undefined if not found.\n */\n getStateFromPropertyPath(path) {\n return getAtPath(this.data, path);\n }\n\n /**\n * Parses a property path string into an array of keys, supporting both dot notation\n * and bracket notation.\n * @param {string} path - The path to parse.\n * @returns {string[]} Array of property keys.\n */\n parseStatePath(path) {\n return parsePath(path);\n }\n\n /**\n * Sets a nested property value within this instance's data based on a path. Low-level\n * counterpart to `set()` - unlike `set()`, does not throw on an empty path.\n * @param {string} path - The path to the property.\n * @param {*} value - The value to set at the specified path.\n */\n setStateToPropertyPath(path, value) {\n setAtPath(this.data, path, value);\n }\n\n /**\n * Deletes a state property using dot-notation or bracket-notation path access.\n * @param {string} path - The path of the state property to delete.\n * @throws {Error} Throws if path is empty or invalid.\n */\n delete(path) {\n if (!path) {\n throw new Error(errors.INVALID_STATE_PATH);\n }\n\n deleteAtPath(this.data, path);\n }\n\n /**\n * Merges an object into the current instance state.\n * @param {Object} newState - The object to merge in.\n * @returns {Object} The updated state data.\n */\n merge(newState) {\n this.data = { ...this.data, ...newState };\n return this.data;\n }\n\n /**\n * Iterates over a collection (array or object) located at the specified path,\n * executing a callback function for each item.\n * @param {string} path - The path of the property to iterate over.\n * @param {Function} callback - The function to execute for each item in the collection.\n * @throws {Error} Throws if the value at the path is not an array or object.\n */\n async each(path, callback) {\n const collection = this.get(path);\n\n if (Array.isArray(collection)) {\n for (const [index, item] of collection.entries()) {\n await callback(item, index);\n }\n } else if (\n typeof collection === 'object' &&\n Object.prototype.toString.call(collection) === '[object Object]'\n ) {\n for (const key of Object.keys(collection)) {\n await callback(collection[key], key);\n }\n } else {\n throw new Error(errors.VALUE_NOT_ITERABLE);\n }\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["errors", "warnings", "StepEvent", "WorkflowEvent", "StateEvent", "base_types", "conditional_step_comparators", "state_event_names", "step_event_names", "step_statuses", "step_types", "sub_step_types", "workflow_event_names", "workflow_statuses", "parsePath", "path", "matches", "part", "__name", "getAtPath", "target", "parts", "current", "setAtPath", "value", "i", "next_part", "is_next_part_numeric", "deleteAtPath", "convertType", "type", "error", "messages", "statuses", "event_names", "events", "types", "InstanceState", "initial", "defaultValue", "gotten", "newState", "callback", "collection", "index", "item", "key"]
7
+ }
@@ -1,2 +1,2 @@
1
- var T=Object.defineProperty;var m=(E,e)=>T(E,"name",{value:e,configurable:!0});import{errors as f,warnings as _}from"../enums/errors.js";import{StepEvent as y,WorkflowEvent as b,StateEvent as g}from"./events/index.js";import{base_types as h,conditional_step_comparators as O,state_event_names as A,step_event_names as v,step_statuses as k,step_types as j,sub_step_types as d,workflow_event_names as R,workflow_statuses as S}from"../enums/index.js";const w={messages:{errors:f,warnings:_},statuses:{workflow:S,step:k},event_names:{workflow:R,step:v,state:A},events:{workflow:new b,step:new y,state:new g},types:{base_types:h,step_types:j,sub_step_types:d},workflows:{},conditional_step_comparators:O};let s={...w};const n=s.events,c=s.event_names;class i{static{m(this,"State")}static delete(e){if(!e)throw new Error(f.INVALID_STATE_PATH);const a=i.parsePath(e);let r=s;for(let t=0;t<a.length-1;t++){const o=a[t];if(!Object.prototype.hasOwnProperty.call(r,o)||typeof r[o]!="object")return;r=r[o]}delete r[a[a.length-1]],n.state.emit(c.state.DELETED,{state:s})}static async each(e,a){const r=i.get(e);if(Array.isArray(r))for(const[t,o]of r.entries())n.state.emit(c.state.EACH,{state:s}),await a(o,t);else if(typeof r=="object"&&Object.prototype.toString.call(r)==="[object Object]")for(const t of Object.keys(r))n.state.emit(c.state.EACH,{state:s}),await a(r[t],t);else throw new Error(f.VALUE_NOT_ITERABLE)}static freeze(){const e=Object.freeze(s);return n.state.emit(c.state.FROZEN,{state:s}),e}static get(e,a=null,r=null){let t=s;if(!e||["*",""].includes(e))return n.state.emit(c.state.GET,{state:t??a}),t;if(t=i.getFromPropertyPath(e,!1)??a,r)try{switch(r){case"string":t=String(t);break;case"number":t=Number(t);break;case"boolean":t=!!t;break;default:break}}catch(o){console.error("Error converting state value: ",o)}return n.state.emit(c.state.GET,{state:t}),t??a}static getFromPropertyPath(e,a=!0){const r=i.parsePath(e);let t=s;for(const o of r)if(t&&Object.prototype.hasOwnProperty.call(t,o))t=t[o];else return;return a&&n.state.emit(c.state.GET_FROM_PROPERTY_PATH,{state:s}),t}static getState(){return n.state.emit(c.state.GET_STATE,{state:s}),s}static merge(e){return s={...s,...e},n.state.emit(c.state.MERGE,{state:s}),s}static parsePath(e){const a=e.match(/[^.[\]]+|(?<=\[)([^\]]+)(?=\])/g);return a?a.map(r=>r.replace(/^['"]|['"]$/g,"")):[]}static reset(){return s={...w,workflows:{}},n.state.emit(c.state.RESET,{state:s}),s}static set(e,a){if(!e)throw new Error(f.INVALID_STATE_PATH);n.state.emit(c.state.SET,{state:s}),i.setToPropertyPath(e,a,!1)}static setToPropertyPath(e,a,r=!0){const t=i.parsePath(e);let o=s;for(let l=0;l<t.length-1;l++){const p=t[l],u=t[l+1];if(!Object.prototype.hasOwnProperty.call(o,p)||typeof o[p]!="object"){const P=/^\d+$/.test(u);o[p]=P?[]:{}}o=o[p]}r&&n.state.emit(c.state.SET_TO_PROPERTY_PATH,{state:s}),o[t[t.length-1]]=a}}var L=i;export{L as default};
1
+ var y=Object.defineProperty;var m=(T,e)=>y(T,"name",{value:e,configurable:!0});import{errors as p}from"../enums/errors.js";import{messages as h,statuses as g,event_names as n,events as c,types as b,conditional_step_comparators as w}from"./instance_state.js";const E={messages:h,statuses:g,event_names:n,events:c,types:b,workflows:{},conditional_step_comparators:w};let s={...E};class i{static{m(this,"State")}static delete(e){if(!e)throw new Error(p.INVALID_STATE_PATH);const a=i.parsePath(e);let r=s;for(let t=0;t<a.length-1;t++){const o=a[t];if(!Object.prototype.hasOwnProperty.call(r,o)||typeof r[o]!="object")return;r=r[o]}delete r[a[a.length-1]],c.state.emit(n.state.DELETED,{state:s})}static async each(e,a){const r=i.get(e);if(Array.isArray(r))for(const[t,o]of r.entries())c.state.emit(n.state.EACH,{state:s}),await a(o,t);else if(typeof r=="object"&&Object.prototype.toString.call(r)==="[object Object]")for(const t of Object.keys(r))c.state.emit(n.state.EACH,{state:s}),await a(r[t],t);else throw new Error(p.VALUE_NOT_ITERABLE)}static freeze(){const e=Object.freeze(s);return c.state.emit(n.state.FROZEN,{state:s}),e}static get(e,a=null,r=null){let t=s;if(!e||["*",""].includes(e))return c.state.emit(n.state.GET,{state:t??a}),t;if(t=i.getFromPropertyPath(e,!1)??a,r)try{switch(r){case"string":t=String(t);break;case"number":t=Number(t);break;case"boolean":t=!!t;break;default:break}}catch(o){console.error("Error converting state value: ",o)}return c.state.emit(n.state.GET,{state:t}),t??a}static getFromPropertyPath(e,a=!0){const r=i.parsePath(e);let t=s;for(const o of r)if(t&&Object.prototype.hasOwnProperty.call(t,o))t=t[o];else return;return a&&c.state.emit(n.state.GET_FROM_PROPERTY_PATH,{state:s}),t}static getState(){return c.state.emit(n.state.GET_STATE,{state:s}),s}static merge(e){return s={...s,...e},c.state.emit(n.state.MERGE,{state:s}),s}static parsePath(e){const a=e.match(/[^.[\]]+|(?<=\[)([^\]]+)(?=\])/g);return a?a.map(r=>r.replace(/^['"]|['"]$/g,"")):[]}static reset(){return s={...E,workflows:{}},c.state.emit(n.state.RESET,{state:s}),s}static set(e,a){if(!e)throw new Error(p.INVALID_STATE_PATH);c.state.emit(n.state.SET,{state:s}),i.setToPropertyPath(e,a,!1)}static setToPropertyPath(e,a,r=!0){const t=i.parsePath(e);let o=s;for(let l=0;l<t.length-1;l++){const f=t[l],u=t[l+1];if(!Object.prototype.hasOwnProperty.call(o,f)||typeof o[f]!="object"){const P=/^\d+$/.test(u);o[f]=P?[]:{}}o=o[f]}r&&c.state.emit(n.state.SET_TO_PROPERTY_PATH,{state:s}),o[t[t.length-1]]=a}}var j=i;export{j as default,E as default_state};
2
2
  //# sourceMappingURL=state.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/classes/state.js"],
4
- "sourcesContent": ["import { errors, warnings } from '../enums/errors.js';\nimport { StepEvent, WorkflowEvent, StateEvent } from './events/index.js';\nimport {\n base_types,\n conditional_step_comparators,\n state_event_names,\n step_event_names,\n step_statuses,\n step_types,\n sub_step_types,\n workflow_event_names,\n workflow_statuses,\n} from '../enums/index.js';\n\nconst defaultState = {\n messages: {\n errors,\n warnings,\n },\n statuses: {\n workflow: workflow_statuses,\n step: step_statuses\n },\n event_names: {\n workflow: workflow_event_names,\n step: step_event_names,\n state: state_event_names,\n },\n events: {\n workflow: new WorkflowEvent(),\n step: new StepEvent(),\n state: new StateEvent(),\n },\n types: {\n base_types,\n step_types,\n sub_step_types,\n },\n workflows: {},\n conditional_step_comparators\n};\n\nlet state = { ...defaultState };\n\n// Module-level shortcuts for events and event_names\nconst events = state.events;\nconst event_names = state.event_names;\n\n/**\n * Singleton class representing the global state for workflows, steps, and processes.\n * Provides methods for managing state with getter/setter functionality, nested path access,\n * and immutability options. The state is shared across all workflow and step instances.\n * \n * @class State\n */\nclass State {\n /**\n * Deletes a state property using dot-notation or bracket-notation path access.\n * \n * @param {string} path - The path of the state property to delete (e.g., \"user.profile.email\" or \"users[0].email\").\n * @returns {void}\n * @throws {Error} Throws if path is empty or invalid.\n */\n static delete(path) {\n if (!path) {\n throw new Error(errors.INVALID_STATE_PATH);\n }\n \n const parts = State.parsePath(path);\n let current = state;\n \n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i];\n \n if (!Object.prototype.hasOwnProperty.call(current, part) || typeof current[part] !== 'object') {\n return;\n }\n \n current = current[part];\n }\n \n delete current[parts[parts.length - 1]];\n\n events.state.emit(event_names.state.DELETED, { state });\n }\n\n /**\n * Iterates over a collection (array or object) located at the specified state path,\n * executing a callback function for each item.\n * \n * @param {string} path - The path of the state property to iterate over.\n * @param {Function} callback - The function to execute for each item in the collection.\n * @throws {Error} Throws if the state property at the path is not an array or object.\n */\n static async each(path, callback) {\n const collection = State.get(path);\n \n if (Array.isArray(collection)) {\n for (const [index, item] of collection.entries()) {\n events.state.emit(event_names.state.EACH, { state });\n await callback(item, index);\n }\n } else if (\n typeof collection === 'object' &&\n Object.prototype.toString.call(collection) === '[object Object]'\n ) {\n for (const key of Object.keys(collection)) {\n events.state.emit(event_names.state.EACH, { state });\n await callback(collection[key], key);\n }\n } else {\n throw new Error(errors.VALUE_NOT_ITERABLE);\n }\n }\n\n /**\n * Freezes the entire state object, making it immutable.\n * @returns {void}\n */\n static freeze() {\n const frozenState = Object.freeze(state);\n events.state.emit(event_names.state.FROZEN, { state });\n return frozenState;\n }\n\n /**\n * Gets the value of a state property using dot-notation or bracket-notation path access.\n * \n * @param {string} path - The path of the state property to get. Supports both dot notation\n * (e.g., \"user.profile.name\") and bracket notation (e.g., \"users[0].name\" or \"data['key-name']\").\n * Special values:\n * - Falsy values (null, undefined, false, \"\"): Returns entire state object\n * - \"*\": Returns entire state object\n * @param {*} [defaultValue=null] - Default value to return if the path doesn't exist.\n * @param {string} [type='string'] - The output type to convert the value to.\n * Supported types: \"string\", \"number\", \"boolean\".\n * @returns {*} The value of the state property, or defaultValue if not found. null if not found\n * and no defaultValue provided.\n * @throws {Error} Throws if the value cannot be converted to the specified type.\n */\n static get(path, defaultValue = null, type = null) {\n let gotten = state;\n if (!path || ['*', ''].includes(path)) {\n events.state.emit(event_names.state.GET, { state: gotten ?? defaultValue });\n return gotten;\n }\n\n gotten = State.getFromPropertyPath(path, false) ?? defaultValue;\n\n if (type) {\n try {\n switch (type) {\n case 'string':\n gotten = String(gotten);\n break;\n case 'number':\n gotten = Number(gotten);\n break;\n case 'boolean':\n gotten = Boolean(gotten);\n break;\n default:\n break;\n }\n } catch (error) {\n console.error(\"Error converting state value: \", error);\n }\n }\n\n events.state.emit(event_names.state.GET, { state: gotten });\n\n return gotten ?? defaultValue;\n }\n\n /**\n * Resolves a nested property path within the state object.\n * Supports both dot notation and bracket notation.\n * \n * @param {string} path - The path to the property (e.g., \"user.profile.name\", \"users[0].name\", \"data['key-name']\").\n * @param {boolean} [emit=true] - Whether to emit the GET_FROM_PROPERTY_PATH event.\n * @returns {*} The value at the specified path, or undefined if not found.\n */\n static getFromPropertyPath(path, emit = true) {\n const parts = State.parsePath(path);\n let current = state;\n\n for (const part of parts) {\n if (current && Object.prototype.hasOwnProperty.call(current, part)) {\n current = current[part];\n } else {\n return undefined;\n }\n }\n\n if (emit) {\n events.state.emit(event_names.state.GET_FROM_PROPERTY_PATH, { state });\n }\n\n return current;\n }\n\n /**\n * Gets the entire state object.\n * @returns {Object} The entire state object.\n */\n static getState() {\n events.state.emit(event_names.state.GET_STATE, { state });\n return state;\n }\n\n /**\n * Merges an object into the current State.\n * @param {Object} newState - The object to merge into the current State.\n * @returns {object} The updated state object.\n */\n static merge(newState) {\n state = { ...state, ...newState };\n events.state.emit(event_names.state.MERGE, { state });\n return state;\n }\n\n /**\n * Parses a property path string into an array of keys, supporting both dot notation\n * and bracket notation.\n * \n * @param {string} path - The path to parse (e.g., \"user.profile.name\", \"users[0].name\", \"data['key-name']\").\n * @returns {string[]} Array of property keys.\n */\n static parsePath(path) {\n const matches = path.match(/[^.[\\]]+|(?<=\\[)([^\\]]+)(?=\\])/g);\n \n if (!matches) {\n return [];\n }\n\n return matches.map(part => part.replace(/^['\"]|['\"]$/g, ''));\n }\n\n /**\n * Resets the state to its default values.\n * @returns {object} The reset state object.\n */\n static reset() {\n state = { \n ...defaultState,\n workflows: {}, // Always create fresh to avoid shared reference mutation\n };\n events.state.emit(event_names.state.RESET, { state });\n return state;\n }\n\n /**\n * Sets the value of a state property using dot-notation or bracket-notation path access.\n * Creates intermediate objects if they don't exist.\n * \n * @param {string} path - The path of the state property to set. Supports both dot notation\n * (e.g., \"user.profile.name\") and bracket notation (e.g., \"users[0].name\" or \"data['key-name']\").\n * @param {*} value - The value to set for the state property.\n * @returns {void}\n * @throws {Error} Throws if path is empty or invalid.\n */\n static set(path, value) {\n if (!path) {\n throw new Error(errors.INVALID_STATE_PATH);\n }\n\n events.state.emit(event_names.state.SET, { state });\n\n State.setToPropertyPath(path, value, false);\n }\n\n /**\n * Sets a nested property value within the state object based on a path.\n * Supports both dot notation and bracket notation. Creates intermediate objects/arrays as needed.\n * \n * @param {string} path - The path to the property (e.g., \"user.profile.name\", \"users[0].name\", \"data['key-name']\").\n * @param {*} value - The value to set at the specified path.\n * @param {boolean} [emit=true] - Whether to emit the SET_TO_PROPERTY_PATH event.\n */\n static setToPropertyPath(path, value, emit = true) {\n const parts = State.parsePath(path);\n let current = state;\n \n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i];\n const nextPart = parts[i + 1];\n \n if (!Object.prototype.hasOwnProperty.call(current, part) || typeof current[part] !== 'object') {\n // Determine if next part is an array index (numeric)\n const isNextPartNumeric = /^\\d+$/.test(nextPart);\n current[part] = isNextPartNumeric ? [] : {};\n }\n current = current[part];\n }\n \n if (emit) {\n events.state.emit(event_names.state.SET_TO_PROPERTY_PATH, { state });\n }\n\n current[parts[parts.length - 1]] = value;\n }\n}\n\nexport default State;\n"],
5
- "mappings": "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",
6
- "names": ["errors", "warnings", "StepEvent", "WorkflowEvent", "StateEvent", "base_types", "conditional_step_comparators", "state_event_names", "step_event_names", "step_statuses", "step_types", "sub_step_types", "workflow_event_names", "workflow_statuses", "defaultState", "state", "events", "event_names", "State", "__name", "path", "parts", "current", "i", "part", "callback", "collection", "index", "item", "key", "frozenState", "defaultValue", "type", "gotten", "error", "emit", "newState", "matches", "value", "nextPart", "isNextPartNumeric", "state_default"]
4
+ "sourcesContent": ["import { errors } from '../enums/errors.js';\nimport { messages, statuses, event_names, events, types, conditional_step_comparators } from './instance_state.js';\n\n// Built from the same constants `Workflow` exposes as static members (see instance_state.js),\n// so `events.*` stays the same instance regardless of whether a given Workflow/Step has opted\n// into `use_state_singleton`. Only `workflows` is singleton-only - it was never meant to be\n// copied into per-instance state.\nexport const default_state = {\n messages,\n statuses,\n event_names,\n events,\n types,\n workflows: {},\n conditional_step_comparators,\n};\n\nlet state = { ...default_state };\n\n/**\n * Singleton class representing the global state for workflows, steps, and processes.\n * Provides methods for managing state with getter/setter functionality, nested path access,\n * and immutability options. The state is shared across all workflow and step instances.\n * \n * @class State\n */\nclass State {\n /**\n * Deletes a state property using dot-notation or bracket-notation path access.\n * \n * @param {string} path - The path of the state property to delete (e.g., \"user.profile.email\" or \"users[0].email\").\n * @returns {void}\n * @throws {Error} Throws if path is empty or invalid.\n */\n static delete(path) {\n if (!path) {\n throw new Error(errors.INVALID_STATE_PATH);\n }\n \n const parts = State.parsePath(path);\n let current = state;\n \n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i];\n \n if (!Object.prototype.hasOwnProperty.call(current, part) || typeof current[part] !== 'object') {\n return;\n }\n \n current = current[part];\n }\n \n delete current[parts[parts.length - 1]];\n\n events.state.emit(event_names.state.DELETED, { state });\n }\n\n /**\n * Iterates over a collection (array or object) located at the specified state path,\n * executing a callback function for each item.\n * \n * @param {string} path - The path of the state property to iterate over.\n * @param {Function} callback - The function to execute for each item in the collection.\n * @throws {Error} Throws if the state property at the path is not an array or object.\n */\n static async each(path, callback) {\n const collection = State.get(path);\n \n if (Array.isArray(collection)) {\n for (const [index, item] of collection.entries()) {\n events.state.emit(event_names.state.EACH, { state });\n await callback(item, index);\n }\n } else if (\n typeof collection === 'object' &&\n Object.prototype.toString.call(collection) === '[object Object]'\n ) {\n for (const key of Object.keys(collection)) {\n events.state.emit(event_names.state.EACH, { state });\n await callback(collection[key], key);\n }\n } else {\n throw new Error(errors.VALUE_NOT_ITERABLE);\n }\n }\n\n /**\n * Freezes the entire state object, making it immutable.\n * @returns {void}\n */\n static freeze() {\n const frozen_state = Object.freeze(state);\n events.state.emit(event_names.state.FROZEN, { state });\n return frozen_state;\n }\n\n /**\n * Gets the value of a state property using dot-notation or bracket-notation path access.\n * \n * @param {string} path - The path of the state property to get. Supports both dot notation\n * (e.g., \"user.profile.name\") and bracket notation (e.g., \"users[0].name\" or \"data['key-name']\").\n * Special values:\n * - Falsy values (null, undefined, false, \"\"): Returns entire state object\n * - \"*\": Returns entire state object\n * @param {*} [defaultValue=null] - Default value to return if the path doesn't exist.\n * @param {string} [type='string'] - The output type to convert the value to.\n * Supported types: \"string\", \"number\", \"boolean\".\n * @returns {*} The value of the state property, or defaultValue if not found. null if not found\n * and no defaultValue provided.\n * @throws {Error} Throws if the value cannot be converted to the specified type.\n */\n static get(path, defaultValue = null, type = null) {\n let gotten = state;\n if (!path || ['*', ''].includes(path)) {\n events.state.emit(event_names.state.GET, { state: gotten ?? defaultValue });\n return gotten;\n }\n\n gotten = State.getFromPropertyPath(path, false) ?? defaultValue;\n\n if (type) {\n try {\n switch (type) {\n case 'string':\n gotten = String(gotten);\n break;\n case 'number':\n gotten = Number(gotten);\n break;\n case 'boolean':\n gotten = Boolean(gotten);\n break;\n default:\n break;\n }\n } catch (error) {\n console.error(\"Error converting state value: \", error);\n }\n }\n\n events.state.emit(event_names.state.GET, { state: gotten });\n\n return gotten ?? defaultValue;\n }\n\n /**\n * Resolves a nested property path within the state object.\n * Supports both dot notation and bracket notation.\n * \n * @param {string} path - The path to the property (e.g., \"user.profile.name\", \"users[0].name\", \"data['key-name']\").\n * @param {boolean} [emit=true] - Whether to emit the GET_FROM_PROPERTY_PATH event.\n * @returns {*} The value at the specified path, or undefined if not found.\n */\n static getFromPropertyPath(path, emit = true) {\n const parts = State.parsePath(path);\n let current = state;\n\n for (const part of parts) {\n if (current && Object.prototype.hasOwnProperty.call(current, part)) {\n current = current[part];\n } else {\n return undefined;\n }\n }\n\n if (emit) {\n events.state.emit(event_names.state.GET_FROM_PROPERTY_PATH, { state });\n }\n\n return current;\n }\n\n /**\n * Gets the entire state object.\n * @returns {Object} The entire state object.\n */\n static getState() {\n events.state.emit(event_names.state.GET_STATE, { state });\n return state;\n }\n\n /**\n * Merges an object into the current State.\n * @param {Object} newState - The object to merge into the current State.\n * @returns {object} The updated state object.\n */\n static merge(newState) {\n state = { ...state, ...newState };\n events.state.emit(event_names.state.MERGE, { state });\n return state;\n }\n\n /**\n * Parses a property path string into an array of keys, supporting both dot notation\n * and bracket notation.\n * \n * @param {string} path - The path to parse (e.g., \"user.profile.name\", \"users[0].name\", \"data['key-name']\").\n * @returns {string[]} Array of property keys.\n */\n static parsePath(path) {\n const matches = path.match(/[^.[\\]]+|(?<=\\[)([^\\]]+)(?=\\])/g);\n \n if (!matches) {\n return [];\n }\n\n return matches.map(part => part.replace(/^['\"]|['\"]$/g, ''));\n }\n\n /**\n * Resets the state to its default values.\n * @returns {object} The reset state object.\n */\n static reset() {\n state = { \n ...default_state,\n workflows: {}, // Always create fresh to avoid shared reference mutation\n };\n events.state.emit(event_names.state.RESET, { state });\n return state;\n }\n\n /**\n * Sets the value of a state property using dot-notation or bracket-notation path access.\n * Creates intermediate objects if they don't exist.\n * \n * @param {string} path - The path of the state property to set. Supports both dot notation\n * (e.g., \"user.profile.name\") and bracket notation (e.g., \"users[0].name\" or \"data['key-name']\").\n * @param {*} value - The value to set for the state property.\n * @returns {void}\n * @throws {Error} Throws if path is empty or invalid.\n */\n static set(path, value) {\n if (!path) {\n throw new Error(errors.INVALID_STATE_PATH);\n }\n\n events.state.emit(event_names.state.SET, { state });\n\n State.setToPropertyPath(path, value, false);\n }\n\n /**\n * Sets a nested property value within the state object based on a path.\n * Supports both dot notation and bracket notation. Creates intermediate objects/arrays as needed.\n * \n * @param {string} path - The path to the property (e.g., \"user.profile.name\", \"users[0].name\", \"data['key-name']\").\n * @param {*} value - The value to set at the specified path.\n * @param {boolean} [emit=true] - Whether to emit the SET_TO_PROPERTY_PATH event.\n */\n static setToPropertyPath(path, value, emit = true) {\n const parts = State.parsePath(path);\n let current = state;\n \n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i];\n const next_part = parts[i + 1];\n \n if (!Object.prototype.hasOwnProperty.call(current, part) || typeof current[part] !== 'object') {\n // Determine if next part is an array index (numeric)\n const is_next_part_numeric = /^\\d+$/.test(next_part);\n current[part] = is_next_part_numeric ? [] : {};\n }\n current = current[part];\n }\n \n if (emit) {\n events.state.emit(event_names.state.SET_TO_PROPERTY_PATH, { state });\n }\n\n current[parts[parts.length - 1]] = value;\n }\n}\n\nexport default State;\n"],
5
+ "mappings": "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",
6
+ "names": ["errors", "messages", "statuses", "event_names", "events", "types", "conditional_step_comparators", "default_state", "state", "State", "__name", "path", "parts", "current", "i", "part", "callback", "collection", "index", "item", "key", "frozen_state", "defaultValue", "type", "gotten", "error", "emit", "newState", "matches", "value", "next_part", "is_next_part_numeric", "state_default"]
7
7
  }
@@ -1,2 +1,2 @@
1
- var a=Object.defineProperty;var o=(n,t)=>a(n,"name",{value:t,configurable:!0});import r from"./logic_step.js";import"../../enums/index.js";class s extends r{static{o(this,"Case")}static step_name="case";constructor({name:t,conditional:e={subject:null,operator:null,value:null},callable:i=o(async()=>{},"callable"),force_subject_override:c=!1}){super({name:t,step_type:s.step_name,callable:i}),this.conditional_config=e,this.force_subject_override=c,this.is_matched=!1}set switch_subject(t){const e=t!=null,i=this.conditional_config.subject!==null&&this.conditional_config.subject!==void 0;if(!e&&!i)throw new Error(`No subject set for case step: ${this.name}, using default equality check`);if(e&&(!i||this.force_subject_override)&&(this.conditional_config.subject=t),!this.conditionalIsValid())throw new Error(`Invalid conditional configuration for case step: ${this.name}`)}}export{s as default};
1
+ var a=Object.defineProperty;var o=(r,e)=>a(r,"name",{value:e,configurable:!0});import l from"./logic_step.js";import"../../enums/index.js";class s extends l{static{o(this,"Case")}static step_name="case";constructor({name:e,conditional:i={subject:null,operator:null,value:null},callable:t=o(async()=>{},"callable"),callable_registry_key:n=null,force_subject_override:c=!1}){super({name:e,step_type:s.step_name,callable:t,callable_registry_key:n}),this.conditional_config=i,this.force_subject_override=c,this.is_matched=!1}set switch_subject(e){const i=e!=null,t=this.conditional_config.subject!==null&&this.conditional_config.subject!==void 0;if(!i&&!t)throw new Error(`No subject set for case step: ${this.name}, using default equality check`);if(i&&(!t||this.force_subject_override)&&(this.conditional_config.subject=e),!this.conditionalIsValid())throw new Error(`Invalid conditional configuration for case step: ${this.name}`)}prepareForSerialization(){return{...super.prepareForSerialization(),force_subject_override:this.force_subject_override,is_matched:this.is_matched}}static hydrate(e,i=null){const t=super.hydrate(e,i);return t.is_matched=e.is_matched??!1,t}}s.registerStepClass(s);export{s as default};
2
2
  //# sourceMappingURL=case.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/classes/steps/case.js"],
4
- "sourcesContent": ["import LogicStep from './logic_step.js';\nimport { conditional_step_comparators } from '../../enums/index.js';\n\n/**\n * Case class representing a single case in a switch statement.\n * Used in conjunction with SwitchStep to create switch/case logic.\n * @class Case\n * @extends LogicStep\n */\nexport default class Case extends LogicStep {\n static step_name = 'case';\n\n /**\n * Creates a new Case instance.\n * Note: Plain LogicStep instances can be used in place of Case, but they MUST have conditional.subject set.\n * @param {Object} options - Configuration options.\n * @param {string} [options.name] - Name of the case.\n * @param {Object} [options.conditional] - Conditional configuration.\n * @param {*|Function} [options.conditional.subject=null] - Subject to evaluate (typically set by SwitchStep). Can be a function.\n * @param {conditional_step_comparators|string} [options.conditional.operator=null] - Comparison operator.\n * @param {*|Function} [options.conditional.value=null] - Value to compare against. Can be a function that returns the value.\n * @param {Function|Step|Workflow} [options.callable=async () => {}] - Function, Step, or Workflow to execute when case matches.\n * @param {boolean} [options.force_subject_override=false] - Force override of subject even if already set.\n */\n constructor({\n name,\n conditional = {\n subject: null,\n operator: null,\n value: null,\n },\n callable = async () => {},\n force_subject_override = false,\n }) {\n super({\n name,\n step_type: Case.step_name,\n callable,\n });\n\n this.conditional_config = conditional;\n this.force_subject_override = force_subject_override;\n\n this.is_matched = false;\n }\n\n /**\n * Sets the switch subject from the parent SwitchStep.\n * Automatically sets the conditional subject if not already set or if force_subject_override is true.\n * @param {*} subject - The subject value from the SwitchStep.\n * @throws {Error} If no subject is provided and conditional.subject is not set.\n * @throws {Error} If the resulting conditional configuration is invalid.\n */\n set switch_subject(subject) {\n const subjectProvided = subject !== null && subject !== undefined;\n const hasExistingSubject = this.conditional_config.subject !== null && this.conditional_config.subject !== undefined;\n\n if (!subjectProvided && !hasExistingSubject) {\n throw new Error(`No subject set for case step: ${this.name}, using default equality check`);\n }\n\n if (subjectProvided && (!hasExistingSubject || this.force_subject_override)) {\n this.conditional_config.subject = subject;\n }\n\n if (!this.conditionalIsValid()) {\n throw new Error(`Invalid conditional configuration for case step: ${this.name}`);\n }\n }\n}\n"],
5
- "mappings": "+EAAA,OAAOA,MAAe,kBACtB,MAA6C,uBAQ7C,MAAOC,UAA2BD,CAAU,CAT5C,MAS4C,CAAAE,EAAA,aAC1C,OAAO,UAAY,OAcnB,YAAY,CACV,KAAAC,EACA,YAAAC,EAAc,CACZ,QAAS,KACT,SAAU,KACV,MAAO,IACT,EACA,SAAAC,EAAWH,EAAA,SAAY,CAAC,EAAb,YACX,uBAAAI,EAAyB,EAC3B,EAAG,CACD,MAAM,CACJ,KAAAH,EACA,UAAWF,EAAK,UAChB,SAAAI,CACF,CAAC,EAED,KAAK,mBAAqBD,EAC1B,KAAK,uBAAyBE,EAE9B,KAAK,WAAa,EACpB,CASA,IAAI,eAAeC,EAAS,CAC1B,MAAMC,EAAkBD,GAAY,KAC9BE,EAAqB,KAAK,mBAAmB,UAAY,MAAQ,KAAK,mBAAmB,UAAY,OAE3G,GAAI,CAACD,GAAmB,CAACC,EACvB,MAAM,IAAI,MAAM,iCAAiC,KAAK,IAAI,gCAAgC,EAO5F,GAJID,IAAoB,CAACC,GAAsB,KAAK,0BAClD,KAAK,mBAAmB,QAAUF,GAGhC,CAAC,KAAK,mBAAmB,EAC3B,MAAM,IAAI,MAAM,oDAAoD,KAAK,IAAI,EAAE,CAEnF,CACF",
6
- "names": ["LogicStep", "Case", "__name", "name", "conditional", "callable", "force_subject_override", "subject", "subjectProvided", "hasExistingSubject"]
4
+ "sourcesContent": ["import LogicStep from './logic_step.js';\nimport { conditional_step_comparators } from '../../enums/index.js';\n\n/**\n * Case class representing a single case in a switch statement.\n * Used in conjunction with SwitchStep to create switch/case logic.\n * @class Case\n * @extends LogicStep\n */\nexport default class Case extends LogicStep {\n static step_name = 'case';\n\n /**\n * Creates a new Case instance.\n * Note: Plain LogicStep instances can be used in place of Case, but they MUST have conditional.subject set.\n * @param {Object} options - Configuration options.\n * @param {string} [options.name] - Name of the case.\n * @param {Object} [options.conditional] - Conditional configuration.\n * @param {*|Function} [options.conditional.subject=null] - Subject to evaluate (typically set by SwitchStep). Can be a function.\n * @param {conditional_step_comparators|string} [options.conditional.operator=null] - Comparison operator.\n * @param {*|Function} [options.conditional.value=null] - Value to compare against. Can be a function that returns the value.\n * @param {Function|Step|Workflow} [options.callable=async () => {}] - Function, Step, or Workflow to execute when case matches.\n * @param {string|null} [options.callable_registry_key=null] - Optional key to reference the callable to be rehydrated after serialization.\n * @param {boolean} [options.force_subject_override=false] - Force override of subject even if already set.\n */\n constructor({\n name,\n conditional = {\n subject: null,\n operator: null,\n value: null,\n },\n callable = async () => {},\n callable_registry_key = null,\n force_subject_override = false,\n }) {\n super({\n name,\n step_type: Case.step_name,\n callable,\n callable_registry_key,\n });\n\n this.conditional_config = conditional;\n this.force_subject_override = force_subject_override;\n\n this.is_matched = false;\n }\n\n /**\n * Sets the switch subject from the parent SwitchStep.\n * Automatically sets the conditional subject if not already set or if force_subject_override is true.\n * @param {*} subject - The subject value from the SwitchStep.\n * @throws {Error} If no subject is provided and conditional.subject is not set.\n * @throws {Error} If the resulting conditional configuration is invalid.\n */\n set switch_subject(subject) {\n const subject_provided = subject !== null && subject !== undefined;\n const has_existing_subject = this.conditional_config.subject !== null && this.conditional_config.subject !== undefined;\n\n if (!subject_provided && !has_existing_subject) {\n throw new Error(`No subject set for case step: ${this.name}, using default equality check`);\n }\n\n if (subject_provided && (!has_existing_subject || this.force_subject_override)) {\n this.conditional_config.subject = subject;\n }\n\n if (!this.conditionalIsValid()) {\n throw new Error(`Invalid conditional configuration for case step: ${this.name}`);\n }\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 return {\n ...super.prepareForSerialization(),\n force_subject_override: this.force_subject_override,\n is_matched: this.is_matched,\n };\n }\n\n /**\n * Hydrates a parsed step object into a Case instance, restoring match state.\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 {Case} The hydrated Case instance.\n */\n static hydrate(parsed_step, callable_registry = null) {\n const instance = super.hydrate(parsed_step, callable_registry);\n instance.is_matched = parsed_step.is_matched ?? false;\n\n return instance;\n }\n}\n\nCase.registerStepClass(Case);\n"],
5
+ "mappings": "+EAAA,OAAOA,MAAe,kBACtB,MAA6C,uBAQ7C,MAAOC,UAA2BD,CAAU,CAT5C,MAS4C,CAAAE,EAAA,aAC1C,OAAO,UAAY,OAenB,YAAY,CACV,KAAAC,EACA,YAAAC,EAAc,CACZ,QAAS,KACT,SAAU,KACV,MAAO,IACT,EACA,SAAAC,EAAWH,EAAA,SAAY,CAAC,EAAb,YACX,sBAAAI,EAAwB,KACxB,uBAAAC,EAAyB,EAC3B,EAAG,CACD,MAAM,CACJ,KAAAJ,EACA,UAAWF,EAAK,UAChB,SAAAI,EACA,sBAAAC,CACF,CAAC,EAED,KAAK,mBAAqBF,EAC1B,KAAK,uBAAyBG,EAE9B,KAAK,WAAa,EACpB,CASA,IAAI,eAAeC,EAAS,CAC1B,MAAMC,EAAmBD,GAAY,KAC/BE,EAAuB,KAAK,mBAAmB,UAAY,MAAQ,KAAK,mBAAmB,UAAY,OAE7G,GAAI,CAACD,GAAoB,CAACC,EACxB,MAAM,IAAI,MAAM,iCAAiC,KAAK,IAAI,gCAAgC,EAO5F,GAJID,IAAqB,CAACC,GAAwB,KAAK,0BACrD,KAAK,mBAAmB,QAAUF,GAGhC,CAAC,KAAK,mBAAmB,EAC3B,MAAM,IAAI,MAAM,oDAAoD,KAAK,IAAI,EAAE,CAEnF,CAMA,yBAA0B,CACxB,MAAO,CACL,GAAG,MAAM,wBAAwB,EACjC,uBAAwB,KAAK,uBAC7B,WAAY,KAAK,UACnB,CACF,CAQA,OAAO,QAAQG,EAAaC,EAAoB,KAAM,CACpD,MAAMC,EAAW,MAAM,QAAQF,EAAaC,CAAiB,EAC7D,OAAAC,EAAS,WAAaF,EAAY,YAAc,GAEzCE,CACT,CACF,CAEAZ,EAAK,kBAAkBA,CAAI",
6
+ "names": ["LogicStep", "Case", "__name", "name", "conditional", "callable", "callable_registry_key", "force_subject_override", "subject", "subject_provided", "has_existing_subject", "parsed_step", "callable_registry", "instance"]
7
7
  }
@@ -1,2 +1,2 @@
1
- var a=Object.defineProperty;var n=(o,e)=>a(o,"name",{value:e,configurable:!0});import l from"./logic_step.js";import"../../enums/index.js";class c extends l{static{n(this,"ConditionalStep")}static step_name="conditional";constructor({name:e,conditional:i={subject:null,operator:null,value:null},true_callable:t=n(async()=>{},"true_callable"),false_callable:s=n(async()=>{},"false_callable")}){super({name:e,conditional:i}),typeof t=="function"?this.true_callable=t.bind(this):this.true_callable=t,typeof s=="function"?this.false_callable=s.bind(this):this.false_callable=s,this.callable=this.conditional.bind(this)}async conditional(){const e=this.true_callable,i=this.false_callable;let t=null;return this.checkCondition()?(this.log(this.getState("events.step.event_names.CONDITIONAL_TRUE_BRANCH_EXECUTED"),`Condition met for step: ${this.name}, executing true branch`),typeof e=="function"?t=await e():(e.parentWorkflowId=this.parentWorkflowId,t=await e.execute())):(this.log(this.getState("events.step.event_names.CONDITIONAL_FALSE_BRANCH_EXECUTED"),`Condition not met for step: ${this.name}, executing false branch`),typeof i=="function"?t=await i():(i.parentWorkflowId=this.parentWorkflowId,t=await i.execute())),{message:`Conditional step ${this.name} completed`,result:t}}}export{c as default};
1
+ var u=Object.defineProperty;var i=(n,e)=>u(n,"name",{value:e,configurable:!0});import s from"./step.js";import h from"./logic_step.js";import"../../enums/index.js";import{event_names as _}from"../instance_state.js";class r extends h{static{i(this,"ConditionalStep")}static step_name="conditional";constructor({name:e,conditional:t={subject:null,operator:null,value:null},true_callable:l=i(async()=>{},"true_callable"),false_callable:a=i(async()=>{},"false_callable"),true_callable_registry_key:o=null,false_callable_registry_key:c=null}){super({name:e,conditional:t}),this.true_callable_registry_key=o,this.false_callable_registry_key=c,this._true_callable_raw=l,this._false_callable_raw=a,typeof l=="function"?this.true_callable=l.bind(this):this.true_callable=l,typeof a=="function"?this.false_callable=a.bind(this):this.false_callable=a,this.callable=this.conditional.bind(this)}async conditional(){const e=this.true_callable,t=this.false_callable;let l=null;return this.checkCondition()?(this.log(_.step.CONDITIONAL_TRUE_BRANCH_EXECUTED,`Condition met for step: ${this.name}, executing true branch`),typeof e=="function"?l=await e():(e.parent_workflow_id=this.parent_workflow_id,e.use_state_singleton=this.use_state_singleton,e.state=this.state,l=await e.execute())):(this.log(_.step.CONDITIONAL_FALSE_BRANCH_EXECUTED,`Condition not met for step: ${this.name}, executing false branch`),typeof t=="function"?l=await t():(t.parent_workflow_id=this.parent_workflow_id,t.use_state_singleton=this.use_state_singleton,t.state=this.state,l=await t.execute())),{message:`Conditional step ${this.name} completed`,result:l}}prepareForSerialization(){return{...super.prepareForSerialization(),callable:null,true_callable:this.true_callable_registry_key?{type:s.callable_types.FUNCTION,value:this.true_callable_registry_key}:s.serializeCallableField(this._true_callable_raw),false_callable:this.false_callable_registry_key?{type:s.callable_types.FUNCTION,value:this.false_callable_registry_key}:s.serializeCallableField(this._false_callable_raw)}}static hydrate(e,t=null){const l=e.true_callable,a=e.false_callable;return super.hydrate({...e,true_callable:s.hydrateCallableField(l,t),false_callable:s.hydrateCallableField(a,t),true_callable_registry_key:l?.type===s.callable_types.FUNCTION?l.value:null,false_callable_registry_key:a?.type===s.callable_types.FUNCTION?a.value:null},t)}}r.registerStepClass(r);export{r as default};
2
2
  //# sourceMappingURL=conditional_step.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/classes/steps/conditional_step.js"],
4
- "sourcesContent": ["import LogicStep from './logic_step.js';\nimport { conditional_step_comparators } from '../../enums/index.js';\n\n/**\n * ConditionalStep class for branching logic based on conditions.\n * @class ConditionalStep\n * @extends LogicStep\n */\nexport default class ConditionalStep extends LogicStep {\n static step_name = 'conditional';\n\n /**\n * Creates a new ConditionalStep instance.\n * @param {Object} options - Configuration options.\n * @param {string} [options.name] - Name of the step.\n * @param {Object} [options.conditional] - Conditional configuration.\n * @param {*|Function} [options.conditional.subject] - Subject to evaluate. Can be a function that returns the value.\n * @param {conditional_step_comparators|string} [options.conditional.operator] - Comparison operator.\n * @param {*|Function} [options.conditional.value] - Value to compare against. Can be a function that returns the value.\n * @param {Function|Step|Workflow} [options.true_callable=async () => {}] - Callable to execute if condition is true.\n * @param {Function|Step|Workflow} [options.false_callable=async () => {}] - Callable to execute if condition is false.\n */\n constructor({\n name,\n conditional = {\n subject: null,\n operator: null,\n value: null,\n },\n true_callable = async () => {},\n false_callable = async () => {},\n }) {\n super({\n name,\n conditional\n });\n\n // Bind function callables to this step instance for state access\n if (typeof true_callable === 'function') {\n this.true_callable = true_callable.bind(this);\n } else {\n this.true_callable = true_callable;\n }\n\n if (typeof false_callable === 'function') {\n this.false_callable = false_callable.bind(this);\n } else {\n this.false_callable = false_callable;\n }\n\n this.callable = this.conditional.bind(this);\n }\n\n /**\n * Executes the appropriate branch based on the condition evaluation.\n * @async\n * @returns {Promise<*>} The result of the executed branch.\n */\n async conditional() {\n const true_callable = this.true_callable;\n const false_callable = this.false_callable;\n\n let result = null;\n\n if (this.checkCondition()) {\n this.log(\n this.getState('events.step.event_names.CONDITIONAL_TRUE_BRANCH_EXECUTED'),\n `Condition met for step: ${this.name}, executing true branch`\n );\n\n if (typeof true_callable === 'function') {\n result = await true_callable();\n } else {\n true_callable.parentWorkflowId = this.parentWorkflowId;\n result = await true_callable.execute();\n }\n } else {\n this.log(\n this.getState('events.step.event_names.CONDITIONAL_FALSE_BRANCH_EXECUTED'),\n `Condition not met for step: ${this.name}, executing false branch`\n );\n\n if (typeof false_callable === 'function') {\n result = await false_callable();\n } else {\n false_callable.parentWorkflowId = this.parentWorkflowId;\n result = await false_callable.execute();\n }\n }\n\n return { message: `Conditional step ${this.name} completed`, result };\n }\n}\n"],
5
- "mappings": "+EAAA,OAAOA,MAAe,kBACtB,MAA6C,uBAO7C,MAAOC,UAAsCD,CAAU,CARvD,MAQuD,CAAAE,EAAA,wBACrD,OAAO,UAAY,cAanB,YAAY,CACV,KAAAC,EACA,YAAAC,EAAc,CACZ,QAAS,KACT,SAAU,KACV,MAAO,IACT,EACA,cAAAC,EAAgBH,EAAA,SAAY,CAAC,EAAb,iBAChB,eAAAI,EAAiBJ,EAAA,SAAY,CAAC,EAAb,iBACnB,EAAG,CACD,MAAM,CACJ,KAAAC,EACA,YAAAC,CACF,CAAC,EAGG,OAAOC,GAAkB,WAC3B,KAAK,cAAgBA,EAAc,KAAK,IAAI,EAE5C,KAAK,cAAgBA,EAGnB,OAAOC,GAAmB,WAC5B,KAAK,eAAiBA,EAAe,KAAK,IAAI,EAE9C,KAAK,eAAiBA,EAGxB,KAAK,SAAW,KAAK,YAAY,KAAK,IAAI,CAC5C,CAOA,MAAM,aAAc,CAClB,MAAMD,EAAgB,KAAK,cACrBC,EAAiB,KAAK,eAE5B,IAAIC,EAAS,KAEb,OAAI,KAAK,eAAe,GACtB,KAAK,IACH,KAAK,SAAS,0DAA0D,EACxE,2BAA2B,KAAK,IAAI,yBACtC,EAEI,OAAOF,GAAkB,WAC3BE,EAAS,MAAMF,EAAc,GAE7BA,EAAc,iBAAmB,KAAK,iBACtCE,EAAS,MAAMF,EAAc,QAAQ,KAGvC,KAAK,IACH,KAAK,SAAS,2DAA2D,EACzE,+BAA+B,KAAK,IAAI,0BAC1C,EAEI,OAAOC,GAAmB,WAC5BC,EAAS,MAAMD,EAAe,GAE9BA,EAAe,iBAAmB,KAAK,iBACvCC,EAAS,MAAMD,EAAe,QAAQ,IAInC,CAAE,QAAS,oBAAoB,KAAK,IAAI,aAAc,OAAAC,CAAO,CACtE,CACF",
6
- "names": ["LogicStep", "ConditionalStep", "__name", "name", "conditional", "true_callable", "false_callable", "result"]
4
+ "sourcesContent": ["import Step from './step.js';\nimport LogicStep from './logic_step.js';\nimport { conditional_step_comparators } from '../../enums/index.js';\nimport { event_names } from '../instance_state.js';\n\n/**\n * ConditionalStep class for branching logic based on conditions.\n * @class ConditionalStep\n * @extends LogicStep\n */\nexport default class ConditionalStep extends LogicStep {\n static step_name = 'conditional';\n\n /**\n * Creates a new ConditionalStep instance.\n * @param {Object} options - Configuration options.\n * @param {string} [options.name] - Name of the step.\n * @param {Object} [options.conditional] - Conditional configuration.\n * @param {*|Function} [options.conditional.subject] - Subject to evaluate. Can be a function that returns the value.\n * @param {conditional_step_comparators|string} [options.conditional.operator] - Comparison operator.\n * @param {*|Function} [options.conditional.value] - Value to compare against. Can be a function that returns the value.\n * @param {Function|Step|Workflow} [options.true_callable=async () => {}] - Callable to execute if condition is true.\n * @param {Function|Step|Workflow} [options.false_callable=async () => {}] - Callable to execute if condition is false.\n * @param {string|null} [options.true_callable_registry_key=null] - Optional key to reference true_callable to be rehydrated after serialization.\n * @param {string|null} [options.false_callable_registry_key=null] - Optional key to reference false_callable to be rehydrated after serialization.\n */\n constructor({\n name,\n conditional = {\n subject: null,\n operator: null,\n value: null,\n },\n true_callable = async () => {},\n false_callable = async () => {},\n true_callable_registry_key = null,\n false_callable_registry_key = null,\n }) {\n super({\n name,\n conditional\n });\n\n // Optional keys to reference true_callable/false_callable to be rehydrated after serialization.\n this.true_callable_registry_key = true_callable_registry_key;\n this.false_callable_registry_key = false_callable_registry_key;\n\n // Keep the raw (unbound) originals for serialization - binding renames a function\n // (e.g. \"falseBranch\" -> \"bound falseBranch\"), which would break registry lookups on hydrate.\n this._true_callable_raw = true_callable;\n this._false_callable_raw = false_callable;\n\n // Bind function callables to this step instance for state access\n if (typeof true_callable === 'function') {\n this.true_callable = true_callable.bind(this);\n } else {\n this.true_callable = true_callable;\n }\n\n if (typeof false_callable === 'function') {\n this.false_callable = false_callable.bind(this);\n } else {\n this.false_callable = false_callable;\n }\n\n this.callable = this.conditional.bind(this);\n }\n\n /**\n * Executes the appropriate branch based on the condition evaluation. When the executed branch\n * is a `Step`/`Workflow` (not a plain function), it is stamped with this step's own\n * `parent_workflow_id`/`use_state_singleton`/`state` first - true/false_callable are never\n * added to the parent workflow via `addStep()`, so this is the only way they end up sharing\n * its state instead of their own, independent one.\n * @async\n * @returns {Promise<*>} The result of the executed branch.\n */\n async conditional() {\n const true_callable = this.true_callable;\n const false_callable = this.false_callable;\n\n let result = null;\n\n if (this.checkCondition()) {\n this.log(\n event_names.step.CONDITIONAL_TRUE_BRANCH_EXECUTED,\n `Condition met for step: ${this.name}, executing true branch`\n );\n\n if (typeof true_callable === 'function') {\n result = await true_callable();\n } else {\n true_callable.parent_workflow_id = this.parent_workflow_id;\n true_callable.use_state_singleton = this.use_state_singleton;\n true_callable.state = this.state;\n result = await true_callable.execute();\n }\n } else {\n this.log(\n event_names.step.CONDITIONAL_FALSE_BRANCH_EXECUTED,\n `Condition not met for step: ${this.name}, executing false branch`\n );\n\n if (typeof false_callable === 'function') {\n result = await false_callable();\n } else {\n false_callable.parent_workflow_id = this.parent_workflow_id;\n false_callable.use_state_singleton = this.use_state_singleton;\n false_callable.state = this.state;\n result = await false_callable.execute();\n }\n }\n\n return { message: `Conditional step ${this.name} completed`, result };\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 return {\n ...super.prepareForSerialization(),\n // The base `callable` is an internal wiring detail (the bound `conditional` method) -\n // ConditionalStep's constructor doesn't take a callable, so it isn't real data to persist.\n callable: null,\n true_callable: this.true_callable_registry_key\n ? { type: Step.callable_types.FUNCTION, value: this.true_callable_registry_key }\n : Step.serializeCallableField(this._true_callable_raw),\n false_callable: this.false_callable_registry_key\n ? { type: Step.callable_types.FUNCTION, value: this.false_callable_registry_key }\n : Step.serializeCallableField(this._false_callable_raw),\n };\n }\n\n /**\n * Hydrates a parsed step object into a ConditionalStep instance, resolving the true/false branch callables.\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 {ConditionalStep} The hydrated ConditionalStep instance.\n */\n static hydrate(parsed_step, callable_registry = null) {\n const true_descriptor = parsed_step.true_callable;\n const false_descriptor = parsed_step.false_callable;\n\n return super.hydrate({\n ...parsed_step,\n true_callable: Step.hydrateCallableField(true_descriptor, callable_registry),\n false_callable: Step.hydrateCallableField(false_descriptor, callable_registry),\n true_callable_registry_key: true_descriptor?.type === Step.callable_types.FUNCTION\n ? true_descriptor.value\n : null,\n false_callable_registry_key: false_descriptor?.type === Step.callable_types.FUNCTION\n ? false_descriptor.value\n : null,\n }, callable_registry);\n }\n}\n\nConditionalStep.registerStepClass(ConditionalStep);\n"],
5
+ "mappings": "+EAAA,OAAOA,MAAU,YACjB,OAAOC,MAAe,kBACtB,MAA6C,uBAC7C,OAAS,eAAAC,MAAmB,uBAO5B,MAAOC,UAAsCF,CAAU,CAVvD,MAUuD,CAAAG,EAAA,wBACrD,OAAO,UAAY,cAenB,YAAY,CACV,KAAAC,EACA,YAAAC,EAAc,CACZ,QAAS,KACT,SAAU,KACV,MAAO,IACT,EACA,cAAAC,EAAgBH,EAAA,SAAY,CAAC,EAAb,iBAChB,eAAAI,EAAiBJ,EAAA,SAAY,CAAC,EAAb,kBACjB,2BAAAK,EAA6B,KAC7B,4BAAAC,EAA8B,IAChC,EAAG,CACD,MAAM,CACJ,KAAAL,EACA,YAAAC,CACF,CAAC,EAGD,KAAK,2BAA6BG,EAClC,KAAK,4BAA8BC,EAInC,KAAK,mBAAqBH,EAC1B,KAAK,oBAAsBC,EAGvB,OAAOD,GAAkB,WAC3B,KAAK,cAAgBA,EAAc,KAAK,IAAI,EAE5C,KAAK,cAAgBA,EAGnB,OAAOC,GAAmB,WAC5B,KAAK,eAAiBA,EAAe,KAAK,IAAI,EAE9C,KAAK,eAAiBA,EAGxB,KAAK,SAAW,KAAK,YAAY,KAAK,IAAI,CAC5C,CAWA,MAAM,aAAc,CAClB,MAAMD,EAAgB,KAAK,cACrBC,EAAiB,KAAK,eAE5B,IAAIG,EAAS,KAEb,OAAI,KAAK,eAAe,GACtB,KAAK,IACHT,EAAY,KAAK,iCACjB,2BAA2B,KAAK,IAAI,yBACtC,EAEI,OAAOK,GAAkB,WAC3BI,EAAS,MAAMJ,EAAc,GAE7BA,EAAc,mBAAqB,KAAK,mBACxCA,EAAc,oBAAsB,KAAK,oBACzCA,EAAc,MAAQ,KAAK,MAC3BI,EAAS,MAAMJ,EAAc,QAAQ,KAGvC,KAAK,IACHL,EAAY,KAAK,kCACjB,+BAA+B,KAAK,IAAI,0BAC1C,EAEI,OAAOM,GAAmB,WAC5BG,EAAS,MAAMH,EAAe,GAE9BA,EAAe,mBAAqB,KAAK,mBACzCA,EAAe,oBAAsB,KAAK,oBAC1CA,EAAe,MAAQ,KAAK,MAC5BG,EAAS,MAAMH,EAAe,QAAQ,IAInC,CAAE,QAAS,oBAAoB,KAAK,IAAI,aAAc,OAAAG,CAAO,CACtE,CAMA,yBAA0B,CACxB,MAAO,CACL,GAAG,MAAM,wBAAwB,EAGjC,SAAU,KACV,cAAe,KAAK,2BAChB,CAAE,KAAMX,EAAK,eAAe,SAAU,MAAO,KAAK,0BAA2B,EAC7EA,EAAK,uBAAuB,KAAK,kBAAkB,EACvD,eAAgB,KAAK,4BACjB,CAAE,KAAMA,EAAK,eAAe,SAAU,MAAO,KAAK,2BAA4B,EAC9EA,EAAK,uBAAuB,KAAK,mBAAmB,CAC1D,CACF,CAQA,OAAO,QAAQY,EAAaC,EAAoB,KAAM,CACpD,MAAMC,EAAkBF,EAAY,cAC9BG,EAAmBH,EAAY,eAErC,OAAO,MAAM,QAAQ,CACnB,GAAGA,EACH,cAAeZ,EAAK,qBAAqBc,EAAiBD,CAAiB,EAC3E,eAAgBb,EAAK,qBAAqBe,EAAkBF,CAAiB,EAC7E,2BAA4BC,GAAiB,OAASd,EAAK,eAAe,SACtEc,EAAgB,MAChB,KACJ,4BAA6BC,GAAkB,OAASf,EAAK,eAAe,SACxEe,EAAiB,MACjB,IACN,EAAGF,CAAiB,CACtB,CACF,CAEAV,EAAgB,kBAAkBA,CAAe",
6
+ "names": ["Step", "LogicStep", "event_names", "ConditionalStep", "__name", "name", "conditional", "true_callable", "false_callable", "true_callable_registry_key", "false_callable_registry_key", "result", "parsed_step", "callable_registry", "true_descriptor", "false_descriptor"]
7
7
  }
@@ -1,2 +1,2 @@
1
- var l=Object.defineProperty;var n=(a,e)=>l(a,"name",{value:e,configurable:!0});import o from"./step.js";import{delay_types as p,step_types as r}from"../../enums/index.js";import y from"node-schedule";import{addMilliseconds as _}from"date-fns";class d extends o{static{n(this,"DelayStep")}static step_name="delay";constructor({name:e,absolute_timestamp:t=new Date,relative_delay_ms:s=0,delay_type:i=p.RELATIVE}){super({name:e,step_type:r.DELAY}),this.delay_type=i,this.absolute_timestamp=new Date(t),this.relative_delay_ms=s,this.callable=this[i].bind(this)}async absolute(){const e=new Date;return this.absolute_timestamp.getTime()<=e.getTime()?(this.log(this.getState("events.step.event_names.DELAY_STEP_ABSOLUTE_COMPLETE"),`No delay for step: ${this.name}. Continuing.`),{delayed:!1,delay_type:this.delay_type,timestamp:e.toISOString()}):this.delay(this.absolute_timestamp)}async delay(e){return new Promise(t=>{this.log(this.getState(`events.step.event_names.DELAY_STEP_${this.delay_type.toUpperCase()}_SCHEDULED`),`Delay scheduled for step: ${this.name} until ${e.toISOString()}`);const s=y.scheduleJob(e,()=>{this.log(this.getState(`events.step.event_names.DELAY_STEP_${this.delay_type.toUpperCase()}_COMPLETE`),`Delay complete for step: ${this.name}. Continuing.`),t({delayed:!0,delay_type:this.delay_type,timestamp:new Date().toISOString()})});this.scheduled_job=s})}async relative(){if(this.relative_delay_ms<=0)return this.log(this.getState("events.step.event_names.DELAY_STEP_RELATIVE_COMPLETE"),`No delay for step: ${this.name}. Continuing.`),{delayed:!1,delay_type:this.delay_type,timestamp:new Date().toISOString()};const e=_(new Date,this.relative_delay_ms);return this.delay(e)}}export{d as default};
1
+ var p=Object.defineProperty;var o=(l,e)=>p(l,"name",{value:e,configurable:!0});import n from"./step.js";import{delay_types as y,step_types as _}from"../../enums/index.js";import{event_names as t}from"../instance_state.js";import m from"node-schedule";import{addMilliseconds as d}from"date-fns";class i extends n{static{o(this,"DelayStep")}static step_name="delay";constructor({name:e,absolute_timestamp:s=new Date,relative_delay_ms:a=0,delay_type:r=y.RELATIVE}){super({name:e,step_type:_.DELAY}),this.delay_type=r,this.absolute_timestamp=new Date(s),this.relative_delay_ms=a,this.callable=this[r].bind(this)}async absolute(){const e=new Date;return this.absolute_timestamp.getTime()<=e.getTime()?(this.log(t.step.DELAY_STEP_ABSOLUTE_COMPLETE,`No delay for step: ${this.name}. Continuing.`),{delayed:!1,delay_type:this.delay_type,timestamp:e.toISOString()}):this.delay(this.absolute_timestamp)}async delay(e){return new Promise(s=>{this.log(t.step[`DELAY_STEP_${this.delay_type.toUpperCase()}_SCHEDULED`],`Delay scheduled for step: ${this.name} until ${e.toISOString()}`);const a=m.scheduleJob(e,()=>{this.log(t.step[`DELAY_STEP_${this.delay_type.toUpperCase()}_COMPLETE`],`Delay complete for step: ${this.name}. Continuing.`),s({delayed:!0,delay_type:this.delay_type,timestamp:new Date().toISOString()})});this.scheduled_job=a})}async relative(){if(this.relative_delay_ms<=0)return this.log(t.step.DELAY_STEP_RELATIVE_COMPLETE,`No delay for step: ${this.name}. Continuing.`),{delayed:!1,delay_type:this.delay_type,timestamp:new Date().toISOString()};const e=d(new Date,this.relative_delay_ms);return this.delay(e)}prepareForSerialization(){return{...super.prepareForSerialization(),callable:null,delay_type:this.delay_type,absolute_timestamp:this.absolute_timestamp,relative_delay_ms:this.relative_delay_ms}}}i.registerStepClass(i);export{i as default};
2
2
  //# sourceMappingURL=delay_step.js.map