@ronaldroe/micro-flow 1.3.9 β 2.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.
- package/README.md +51 -10
- package/dist/src/classes/base.js +2 -2
- package/dist/src/classes/base.js.map +3 -3
- package/dist/src/classes/callable_registry.js +1 -1
- package/dist/src/classes/callable_registry.js.map +2 -2
- package/dist/src/classes/events/event.js +1 -1
- package/dist/src/classes/events/event.js.map +3 -3
- package/dist/src/classes/index.js +1 -1
- package/dist/src/classes/index.js.map +3 -3
- package/dist/src/classes/state.js +1 -1
- package/dist/src/classes/state.js.map +3 -3
- package/dist/src/classes/steps/case.js +1 -1
- package/dist/src/classes/steps/case.js.map +3 -3
- package/dist/src/classes/steps/conditional_step.js +1 -1
- package/dist/src/classes/steps/conditional_step.js.map +3 -3
- package/dist/src/classes/steps/delay_step.js +1 -1
- package/dist/src/classes/steps/delay_step.js.map +2 -2
- package/dist/src/classes/steps/flow_control_step.js +1 -1
- package/dist/src/classes/steps/flow_control_step.js.map +2 -2
- package/dist/src/classes/steps/logic_step.js +1 -1
- package/dist/src/classes/steps/logic_step.js.map +3 -3
- package/dist/src/classes/steps/loop_step.js +1 -1
- package/dist/src/classes/steps/loop_step.js.map +3 -3
- package/dist/src/classes/steps/step.js +1 -1
- package/dist/src/classes/steps/step.js.map +3 -3
- package/dist/src/classes/steps/switch_step.js +1 -1
- package/dist/src/classes/steps/switch_step.js.map +3 -3
- package/dist/src/classes/workflow.js +1 -1
- package/dist/src/classes/workflow.js.map +3 -3
- package/dist/src/enums/delay_types.js.map +1 -1
- package/dist/src/enums/logic_step_types.js.map +3 -3
- package/dist/src/enums/sub_step_types.js +1 -1
- package/dist/src/enums/sub_step_types.js.map +2 -2
- package/package.json +1 -1
- package/src/classes/base.js +42 -11
- package/src/classes/callable_registry.js +82 -0
- package/src/classes/events/event.js +3 -3
- package/src/classes/index.js +2 -1
- package/src/classes/state.js +278 -8
- package/src/classes/steps/case.js +34 -4
- package/src/classes/steps/conditional_step.js +69 -3
- package/src/classes/steps/delay_step.js +18 -0
- package/src/classes/steps/flow_control_step.js +18 -2
- package/src/classes/steps/logic_step.js +26 -8
- package/src/classes/steps/loop_step.js +88 -3
- package/src/classes/steps/step.js +228 -16
- package/src/classes/steps/switch_step.js +66 -8
- package/src/classes/workflow.js +237 -40
- package/src/enums/delay_types.js +1 -1
- package/src/enums/logic_step_types.js +2 -2
- 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** -
|
|
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
|
-
|
|
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 {
|
|
242
|
+
import { Workflow, Step } from 'micro-flow';
|
|
213
243
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
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
|
-
|
|
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)
|
package/dist/src/classes/base.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var
|
|
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,{InstanceState as l}from"./state.js";class p{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 l,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}`,
|
|
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{p 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
|
|
5
|
-
"mappings": "+EAAA,OAAOA,MAAY,SACnB,OAAS,cAAAC,MAAkB,oBAC3B,OAAOC,
|
|
6
|
-
"names": ["crypto", "base_types", "State", "Base", "__name", "name", "base_type", "event_name", "message", "
|
|
4
|
+
"sourcesContent": ["import crypto from 'crypto';\nimport { base_types } from '../enums/index.js';\nimport State, { InstanceState } 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 * @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
|
|
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
|
|
5
|
-
"mappings": "+EAIA,MAAOA,CAA+B,CAJtC,MAIsC,CAAAC,EAAA,yBACpCC,GAKA,aAAc,CACZ,
|
|
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=(
|
|
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
|
|
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,
|
|
6
|
-
"names": ["warnings", "Event", "__name", "event_names", "event_name", "data", "bubbles", "cancelable", "seen", "
|
|
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
|
|
1
|
+
export*from"./events/index.js";import{default as o}from"./base.js";import{default as f}from"./callable_registry.js";import{default as s,InstanceState as m}from"./state.js";import{default as x}from"./workflow.js";export*from"./steps/index.js";export{o as Base,f as CallableRegistry,m as InstanceState,s as State,x 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,
|
|
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, InstanceState } 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,MAAmC,yBAC5C,OAAoB,WAAXA,EAAkB,iBAAAC,MAAqB,aAChD,OAAoB,WAAXD,MAA2B,gBACpC,WAAc",
|
|
6
|
+
"names": ["default", "InstanceState"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
1
|
+
var P=Object.defineProperty;var l=(a,t)=>P(a,"name",{value:t,configurable:!0});import{errors as m,warnings as T}from"../enums/errors.js";import{StepEvent as b,WorkflowEvent as d,StateEvent as A}from"./events/index.js";import{base_types as O,conditional_step_comparators as j,state_event_names as v,step_event_names as k,step_statuses as S,step_types as I,sub_step_types as R,workflow_event_names as x,workflow_statuses as L}from"../enums/index.js";const f={messages:{errors:m,warnings:T},statuses:{workflow:L,step:S},event_names:{workflow:x,step:k,state:v},events:{workflow:new d,step:new b,state:new A},types:{base_types:O,step_types:I,sub_step_types:R},workflows:{},conditional_step_comparators:j};let n={...f};const c=n.events,i=n.event_names;function _(a){const t=a.match(/[^.[\]]+|(?<=\[)([^\]]+)(?=\])/g);return t?t.map(s=>s.replace(/^['"]|['"]$/g,"")):[]}l(_,"parsePath");function y(a,t){const s=_(t);let r=a;for(const e of s)if(r&&Object.prototype.hasOwnProperty.call(r,e))r=r[e];else return;return r}l(y,"getAtPath");function E(a,t,s){const r=_(t);let e=a;for(let o=0;o<r.length-1;o++){const p=r[o],h=r[o+1];if(!Object.prototype.hasOwnProperty.call(e,p)||typeof e[p]!="object"){const w=/^\d+$/.test(h);e[p]=w?[]:{}}e=e[p]}e[r[r.length-1]]=s}l(E,"setAtPath");function N(a,t){const s=_(t);let r=a;for(let e=0;e<s.length-1;e++){const o=s[e];if(!Object.prototype.hasOwnProperty.call(r,o)||typeof r[o]!="object")return;r=r[o]}delete r[s[s.length-1]]}l(N,"deleteAtPath");function H(a,t){if(!t)return a;try{switch(t){case"string":return String(a);case"number":return Number(a);case"boolean":return!!a;default:return a}}catch(s){return console.error("Error converting state value: ",s),a}}l(H,"convertType");function D(){return{messages:f.messages,statuses:f.statuses,event_names:f.event_names,events:f.events,types:f.types,conditional_step_comparators:f.conditional_step_comparators,workflows:{}}}l(D,"createInstanceStateData");class z{static{l(this,"InstanceState")}constructor(t=D()){this.data=t}get(t,s=null,r=null){if(!t||["*",""].includes(t))return this.data??s;const e=y(this.data,t)??s;return H(e,r)??s}set(t,s){if(!t)throw new Error(m.INVALID_STATE_PATH);E(this.data,t,s)}getStateFromPropertyPath(t){return y(this.data,t)}parseStatePath(t){return _(t)}setStateToPropertyPath(t,s){E(this.data,t,s)}delete(t){if(!t)throw new Error(m.INVALID_STATE_PATH);N(this.data,t)}merge(t){return this.data={...this.data,...t},this.data}async each(t,s){const r=this.get(t);if(Array.isArray(r))for(const[e,o]of r.entries())await s(o,e);else if(typeof r=="object"&&Object.prototype.toString.call(r)==="[object Object]")for(const e of Object.keys(r))await s(r[e],e);else throw new Error(m.VALUE_NOT_ITERABLE)}}class u{static{l(this,"State")}static delete(t){if(!t)throw new Error(m.INVALID_STATE_PATH);const s=u.parsePath(t);let r=n;for(let e=0;e<s.length-1;e++){const o=s[e];if(!Object.prototype.hasOwnProperty.call(r,o)||typeof r[o]!="object")return;r=r[o]}delete r[s[s.length-1]],c.state.emit(i.state.DELETED,{state:n})}static async each(t,s){const r=u.get(t);if(Array.isArray(r))for(const[e,o]of r.entries())c.state.emit(i.state.EACH,{state:n}),await s(o,e);else if(typeof r=="object"&&Object.prototype.toString.call(r)==="[object Object]")for(const e of Object.keys(r))c.state.emit(i.state.EACH,{state:n}),await s(r[e],e);else throw new Error(m.VALUE_NOT_ITERABLE)}static freeze(){const t=Object.freeze(n);return c.state.emit(i.state.FROZEN,{state:n}),t}static get(t,s=null,r=null){let e=n;if(!t||["*",""].includes(t))return c.state.emit(i.state.GET,{state:e??s}),e;if(e=u.getFromPropertyPath(t,!1)??s,r)try{switch(r){case"string":e=String(e);break;case"number":e=Number(e);break;case"boolean":e=!!e;break;default:break}}catch(o){console.error("Error converting state value: ",o)}return c.state.emit(i.state.GET,{state:e}),e??s}static getFromPropertyPath(t,s=!0){const r=u.parsePath(t);let e=n;for(const o of r)if(e&&Object.prototype.hasOwnProperty.call(e,o))e=e[o];else return;return s&&c.state.emit(i.state.GET_FROM_PROPERTY_PATH,{state:n}),e}static getState(){return c.state.emit(i.state.GET_STATE,{state:n}),n}static merge(t){return n={...n,...t},c.state.emit(i.state.MERGE,{state:n}),n}static parsePath(t){const s=t.match(/[^.[\]]+|(?<=\[)([^\]]+)(?=\])/g);return s?s.map(r=>r.replace(/^['"]|['"]$/g,"")):[]}static reset(){return n={...f,workflows:{}},c.state.emit(i.state.RESET,{state:n}),n}static set(t,s){if(!t)throw new Error(m.INVALID_STATE_PATH);c.state.emit(i.state.SET,{state:n}),u.setToPropertyPath(t,s,!1)}static setToPropertyPath(t,s,r=!0){const e=u.parsePath(t);let o=n;for(let p=0;p<e.length-1;p++){const h=e[p],w=e[p+1];if(!Object.prototype.hasOwnProperty.call(o,h)||typeof o[h]!="object"){const g=/^\d+$/.test(w);o[h]=g?[]:{}}o=o[h]}r&&c.state.emit(i.state.SET_TO_PROPERTY_PATH,{state:n}),o[e[e.length-1]]=s}}var C=u;export{z as InstanceState,D as createInstanceStateData,C as default};
|
|
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": "+EAAA,OAAS,UAAAA,EAAQ,YAAAC,MAAgB,qBACjC,OAAS,aAAAC,EAAW,iBAAAC,EAAe,cAAAC,MAAkB,oBACrD,OACE,cAAAC,EACA,gCAAAC,EACA,qBAAAC,EACA,oBAAAC,EACA,iBAAAC,EACA,cAAAC,EACA,kBAAAC,EACA,wBAAAC,EACA,qBAAAC,MACK,oBAEP,MAAMC,
|
|
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", "
|
|
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 default_state = {\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 = { ...default_state };\n\n// Module-level shortcuts for events and event_names\nconst events = state.events;\nconst event_names = state.event_names;\n\n/**\n * Parses a property path string into an array of keys, supporting both dot notation\n * and bracket notation. Shared by both the deprecated singleton `State` and per-instance\n * `InstanceState`.\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 * Builds a fresh data object for a `Workflow`/`Step` instance's own state, seeded with the\n * same framework constants (statuses, event enums, event emitters, comparators) the deprecated\n * `State` singleton used to provide - but with its own independent, empty `workflows` registry\n * rather than sharing the process-wide one.\n *\n * The event emitters (and other constant objects) are shared by reference with the singleton's\n * defaults so that `on()`/`off()` listeners registered via `State.get('events.workflow')` keep\n * receiving events regardless of whether a given `Workflow`/`Step` has opted back into\n * `use_state_singleton`.\n *\n * @returns {Object} A fresh instance-state data object.\n */\nexport function createInstanceStateData() {\n return {\n messages: default_state.messages,\n statuses: default_state.statuses,\n event_names: default_state.event_names,\n events: default_state.events,\n types: default_state.types,\n conditional_step_comparators: default_state.conditional_step_comparators,\n workflows: {},\n };\n}\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.\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, defaults to a fresh `createInstanceStateData()` result.\n */\n constructor(initial = createInstanceStateData()) {\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\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", "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", "default_state", "state", "events", "event_names", "parsePath", "path", "matches", "part", "__name", "getAtPath", "target", "parts", "current", "setAtPath", "value", "i", "next_part", "is_next_part_numeric", "deleteAtPath", "convertType", "type", "error", "createInstanceStateData", "InstanceState", "initial", "defaultValue", "gotten", "newState", "callback", "collection", "index", "item", "key", "State", "frozen_state", "emit", "state_default"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var a=Object.defineProperty;var o=(
|
|
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
|
|
5
|
-
"mappings": "+EAAA,OAAOA,MAAe,kBACtB,MAA6C,uBAQ7C,MAAOC,UAA2BD,CAAU,CAT5C,MAS4C,CAAAE,EAAA,aAC1C,OAAO,UAAY,
|
|
6
|
-
"names": ["LogicStep", "Case", "__name", "name", "conditional", "callable", "force_subject_override", "subject", "
|
|
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
|
|
1
|
+
var c=Object.defineProperty;var i=(n,e)=>c(n,"name",{value:e,configurable:!0});import s from"./step.js";import u from"./logic_step.js";import"../../enums/index.js";class r extends u{static{i(this,"ConditionalStep")}static step_name="conditional";constructor({name:e,conditional:l={subject:null,operator:null,value:null},true_callable:t=i(async()=>{},"true_callable"),false_callable:a=i(async()=>{},"false_callable"),true_callable_registry_key:_=null,false_callable_registry_key:o=null}){super({name:e,conditional:l}),this.true_callable_registry_key=_,this.false_callable_registry_key=o,this._true_callable_raw=t,this._false_callable_raw=a,typeof t=="function"?this.true_callable=t.bind(this):this.true_callable=t,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,l=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.parent_workflow_id=this.parent_workflow_id,e.use_state_singleton=this.use_state_singleton,e.state=this.state,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 l=="function"?t=await l():(l.parent_workflow_id=this.parent_workflow_id,l.use_state_singleton=this.use_state_singleton,l.state=this.state,t=await l.execute())),{message:`Conditional step ${this.name} completed`,result:t}}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,l=null){const t=e.true_callable,a=e.false_callable;return super.hydrate({...e,true_callable:s.hydrateCallableField(t,l),false_callable:s.hydrateCallableField(a,l),true_callable_registry_key:t?.type===s.callable_types.FUNCTION?t.value:null,false_callable_registry_key:a?.type===s.callable_types.FUNCTION?a.value:null},l)}}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.
|
|
5
|
-
"mappings": "+EAAA,OAAOA,MAAe,kBACtB,MAA6C,uBAO7C,MAAOC,UAAsCD,CAAU,
|
|
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';\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 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.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 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.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,uBAO7C,MAAOC,UAAsCD,CAAU,CATvD,MASuD,CAAAE,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,IACH,KAAK,SAAS,0DAA0D,EACxE,2BAA2B,KAAK,IAAI,yBACtC,EAEI,OAAOJ,GAAkB,WAC3BI,EAAS,MAAMJ,EAAc,GAE7BA,EAAc,mBAAqB,KAAK,mBACxCA,EAAc,oBAAsB,KAAK,oBACzCA,EAAc,MAAQ,KAAK,MAC3BI,EAAS,MAAMJ,EAAc,QAAQ,KAGvC,KAAK,IACH,KAAK,SAAS,2DAA2D,EACzE,+BAA+B,KAAK,IAAI,0BAC1C,EAEI,OAAOC,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,KAAMV,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,QAAQW,EAAaC,EAAoB,KAAM,CACpD,MAAMC,EAAkBF,EAAY,cAC9BG,EAAmBH,EAAY,eAErC,OAAO,MAAM,QAAQ,CACnB,GAAGA,EACH,cAAeX,EAAK,qBAAqBa,EAAiBD,CAAiB,EAC3E,eAAgBZ,EAAK,qBAAqBc,EAAkBF,CAAiB,EAC7E,2BAA4BC,GAAiB,OAASb,EAAK,eAAe,SACtEa,EAAgB,MAChB,KACJ,4BAA6BC,GAAkB,OAASd,EAAK,eAAe,SACxEc,EAAiB,MACjB,IACN,EAAGF,CAAiB,CACtB,CACF,CAEAV,EAAgB,kBAAkBA,CAAe",
|
|
6
|
+
"names": ["Step", "LogicStep", "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
|
|
1
|
+
var r=Object.defineProperty;var n=(i,e)=>r(i,"name",{value:e,configurable:!0});import p from"./step.js";import{delay_types as o,step_types as _}from"../../enums/index.js";import y from"node-schedule";import{addMilliseconds as m}from"date-fns";class a extends p{static{n(this,"DelayStep")}static step_name="delay";constructor({name:e,absolute_timestamp:t=new Date,relative_delay_ms:s=0,delay_type:l=o.RELATIVE}){super({name:e,step_type:_.DELAY}),this.delay_type=l,this.absolute_timestamp=new Date(t),this.relative_delay_ms=s,this.callable=this[l].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=m(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}}}a.registerStepClass(a);export{a as default};
|
|
2
2
|
//# sourceMappingURL=delay_step.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/classes/steps/delay_step.js"],
|
|
4
|
-
"sourcesContent": ["import Step from './step.js';\nimport { delay_types, step_types } from '../../enums/index.js';\nimport schedule from 'node-schedule';\nimport { addMilliseconds } from 'date-fns';\n\n/**\n * DelayStep class for introducing delays in workflow execution.\n * Supports both absolute and relative delays.\n * @class DelayStep\n * @extends Step\n */\nexport default class DelayStep extends Step {\n static step_name = 'delay';\n\n /**\n * Creates a new DelayStep instance.\n * @param {Object} options - Configuration options.\n * @param {string} [options.name] - Name of the step.\n * @param {Date|string} [options.absolute_timestamp=new Date()] - Absolute timestamp to delay until.\n * @param {number} [options.relative_delay_ms=0] - Relative delay in milliseconds.\n * @param {string} [options.delay_type=delay_types.RELATIVE] - Type of delay ('absolute' or 'relative').\n */\n constructor({\n name,\n absolute_timestamp = new Date(),\n relative_delay_ms = 0,\n delay_type = delay_types.RELATIVE\n }) {\n super({\n name,\n step_type: step_types.DELAY,\n });\n\n this.delay_type = delay_type;\n this.absolute_timestamp = new Date(absolute_timestamp);\n this.relative_delay_ms = relative_delay_ms;\n\n this.callable = this[delay_type].bind(this);\n }\n\n /**\n * Executes an absolute delay until the specified timestamp. If the timestamp is in the past, it continues immediately.\n * @returns {Promise<Object>} Resolves with delay completion info when delay completes.\n */\n async absolute() {\n const now = new Date();\n\n if (this.absolute_timestamp.getTime() <= now.getTime()) {\n this.log(\n this.getState('events.step.event_names.DELAY_STEP_ABSOLUTE_COMPLETE'),\n `No delay for step: ${this.name}. Continuing.`\n );\n return { delayed: false, delay_type: this.delay_type, timestamp: now.toISOString() };\n }\n\n return this.delay(this.absolute_timestamp);\n }\n\n /** Schedules a delay until the specified date and time.\n * @param {Date} delay_until - The date and time to delay until.\n * @returns {Promise<Object>} Resolves with delay completion info when delay completes.\n */\n async delay(delay_until) {\n return new Promise((resolve) => {\n this.log(\n this.getState(\n `events.step.event_names.DELAY_STEP_${this.delay_type.toUpperCase()}_SCHEDULED`\n ),\n `Delay scheduled for step: ${this.name} until ${delay_until.toISOString()}`\n );\n\n const job = schedule.scheduleJob(delay_until, () => {\n this.log(\n this.getState(\n `events.step.event_names.DELAY_STEP_${this.delay_type.toUpperCase()}_COMPLETE`\n ),\n `Delay complete for step: ${this.name}. Continuing.`\n );\n resolve({ delayed: true, delay_type: this.delay_type, timestamp: new Date().toISOString() });\n });\n\n this.scheduled_job = job;\n });\n }\n\n /**\n * Executes a relative delay for the specified duration. If the delay duration is zero or negative, it continues immediately.\n * @returns {Promise<Object>} Resolves with delay completion info when delay completes.\n */\n async relative() {\n if (this.relative_delay_ms <= 0) {\n this.log(\n this.getState('events.step.event_names.DELAY_STEP_RELATIVE_COMPLETE'),\n `No delay for step: ${this.name}. Continuing.`\n );\n return { delayed: false, delay_type: this.delay_type, timestamp: new Date().toISOString() };\n }\n\n const delay_until = addMilliseconds(new Date(), this.relative_delay_ms);\n\n return this.delay(delay_until);\n }\n}\n"],
|
|
5
|
-
"mappings": "+EAAA,OAAOA,MAAU,YACjB,OAAS,eAAAC,EAAa,cAAAC,MAAkB,uBACxC,OAAOC,MAAc,gBACrB,OAAS,mBAAAC,MAAuB,WAQhC,MAAOC,UAAgCL,CAAK,CAX5C,MAW4C,CAAAM,EAAA,kBAC1C,OAAO,UAAY,QAUnB,YAAY,CACV,KAAAC,EACA,mBAAAC,EAAqB,IAAI,KACzB,kBAAAC,EAAoB,EACpB,WAAAC,EAAaT,EAAY,QAC3B,EAAG,CACD,MAAM,CACJ,KAAAM,EACA,UAAWL,EAAW,KACxB,CAAC,EAED,KAAK,WAAaQ,EAClB,KAAK,mBAAqB,IAAI,KAAKF,CAAkB,EACrD,KAAK,kBAAoBC,EAEzB,KAAK,SAAW,KAAKC,CAAU,EAAE,KAAK,IAAI,CAC5C,CAMA,MAAM,UAAW,CACf,MAAMC,EAAM,IAAI,KAEhB,OAAI,KAAK,mBAAmB,QAAQ,GAAKA,EAAI,QAAQ,GACnD,KAAK,IACH,KAAK,SAAS,sDAAsD,EACpE,sBAAsB,KAAK,IAAI,eACjC,EACO,CAAE,QAAS,GAAO,WAAY,KAAK,WAAY,UAAWA,EAAI,YAAY,CAAE,GAG9E,KAAK,MAAM,KAAK,kBAAkB,CAC3C,CAMA,MAAM,MAAMC,EAAa,CACvB,OAAO,IAAI,QAASC,GAAY,CAC9B,KAAK,IACH,KAAK,SACH,sCAAsC,KAAK,WAAW,YAAY,CAAC,YACrE,EACA,6BAA6B,KAAK,IAAI,UAAUD,EAAY,YAAY,CAAC,EAC3E,EAEA,MAAME,EAAMX,EAAS,YAAYS,EAAa,IAAM,CAClD,KAAK,IACH,KAAK,SACH,sCAAsC,KAAK,WAAW,YAAY,CAAC,WACrE,EACA,4BAA4B,KAAK,IAAI,eACvC,EACAC,EAAQ,CAAE,QAAS,GAAM,WAAY,KAAK,WAAY,UAAW,IAAI,KAAK,EAAE,YAAY,CAAE,CAAC,CAC7F,CAAC,EAED,KAAK,cAAgBC,CACvB,CAAC,CACH,CAMA,MAAM,UAAW,CACf,GAAI,KAAK,mBAAqB,EAC5B,YAAK,IACH,KAAK,SAAS,sDAAsD,EACpE,sBAAsB,KAAK,IAAI,eACjC,EACO,CAAE,QAAS,GAAO,WAAY,KAAK,WAAY,UAAW,IAAI,KAAK,EAAE,YAAY,CAAE,EAG5F,MAAMF,EAAcR,EAAgB,IAAI,KAAQ,KAAK,iBAAiB,EAEtE,OAAO,KAAK,MAAMQ,CAAW,CAC/B,CACF",
|
|
4
|
+
"sourcesContent": ["import Step from './step.js';\nimport { delay_types, step_types } from '../../enums/index.js';\nimport schedule from 'node-schedule';\nimport { addMilliseconds } from 'date-fns';\n\n/**\n * DelayStep class for introducing delays in workflow execution.\n * Supports both absolute and relative delays.\n * @class DelayStep\n * @extends Step\n */\nexport default class DelayStep extends Step {\n static step_name = 'delay';\n\n /**\n * Creates a new DelayStep instance.\n * @param {Object} options - Configuration options.\n * @param {string} [options.name] - Name of the step.\n * @param {Date|string} [options.absolute_timestamp=new Date()] - Absolute timestamp to delay until.\n * @param {number} [options.relative_delay_ms=0] - Relative delay in milliseconds.\n * @param {string} [options.delay_type=delay_types.RELATIVE] - Type of delay ('absolute' or 'relative').\n */\n constructor({\n name,\n absolute_timestamp = new Date(),\n relative_delay_ms = 0,\n delay_type = delay_types.RELATIVE\n }) {\n super({\n name,\n step_type: step_types.DELAY,\n });\n\n this.delay_type = delay_type;\n this.absolute_timestamp = new Date(absolute_timestamp);\n this.relative_delay_ms = relative_delay_ms;\n\n this.callable = this[delay_type].bind(this);\n }\n\n /**\n * Executes an absolute delay until the specified timestamp. If the timestamp is in the past, it continues immediately.\n * @returns {Promise<Object>} Resolves with delay completion info when delay completes.\n */\n async absolute() {\n const now = new Date();\n\n if (this.absolute_timestamp.getTime() <= now.getTime()) {\n this.log(\n this.getState('events.step.event_names.DELAY_STEP_ABSOLUTE_COMPLETE'),\n `No delay for step: ${this.name}. Continuing.`\n );\n return { delayed: false, delay_type: this.delay_type, timestamp: now.toISOString() };\n }\n\n return this.delay(this.absolute_timestamp);\n }\n\n /** Schedules a delay until the specified date and time.\n * @param {Date} delay_until - The date and time to delay until.\n * @returns {Promise<Object>} Resolves with delay completion info when delay completes.\n */\n async delay(delay_until) {\n return new Promise((resolve) => {\n this.log(\n this.getState(\n `events.step.event_names.DELAY_STEP_${this.delay_type.toUpperCase()}_SCHEDULED`\n ),\n `Delay scheduled for step: ${this.name} until ${delay_until.toISOString()}`\n );\n\n const job = schedule.scheduleJob(delay_until, () => {\n this.log(\n this.getState(\n `events.step.event_names.DELAY_STEP_${this.delay_type.toUpperCase()}_COMPLETE`\n ),\n `Delay complete for step: ${this.name}. Continuing.`\n );\n resolve({ delayed: true, delay_type: this.delay_type, timestamp: new Date().toISOString() });\n });\n\n this.scheduled_job = job;\n });\n }\n\n /**\n * Executes a relative delay for the specified duration. If the delay duration is zero or negative, it continues immediately.\n * @returns {Promise<Object>} Resolves with delay completion info when delay completes.\n */\n async relative() {\n if (this.relative_delay_ms <= 0) {\n this.log(\n this.getState('events.step.event_names.DELAY_STEP_RELATIVE_COMPLETE'),\n `No delay for step: ${this.name}. Continuing.`\n );\n return { delayed: false, delay_type: this.delay_type, timestamp: new Date().toISOString() };\n }\n\n const delay_until = addMilliseconds(new Date(), this.relative_delay_ms);\n\n return this.delay(delay_until);\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 absolute/relative method) -\n // DelayStep's constructor doesn't take a callable, so it isn't real data to persist.\n callable: null,\n delay_type: this.delay_type,\n absolute_timestamp: this.absolute_timestamp,\n relative_delay_ms: this.relative_delay_ms,\n };\n }\n}\n\nDelayStep.registerStepClass(DelayStep);\n"],
|
|
5
|
+
"mappings": "+EAAA,OAAOA,MAAU,YACjB,OAAS,eAAAC,EAAa,cAAAC,MAAkB,uBACxC,OAAOC,MAAc,gBACrB,OAAS,mBAAAC,MAAuB,WAQhC,MAAOC,UAAgCL,CAAK,CAX5C,MAW4C,CAAAM,EAAA,kBAC1C,OAAO,UAAY,QAUnB,YAAY,CACV,KAAAC,EACA,mBAAAC,EAAqB,IAAI,KACzB,kBAAAC,EAAoB,EACpB,WAAAC,EAAaT,EAAY,QAC3B,EAAG,CACD,MAAM,CACJ,KAAAM,EACA,UAAWL,EAAW,KACxB,CAAC,EAED,KAAK,WAAaQ,EAClB,KAAK,mBAAqB,IAAI,KAAKF,CAAkB,EACrD,KAAK,kBAAoBC,EAEzB,KAAK,SAAW,KAAKC,CAAU,EAAE,KAAK,IAAI,CAC5C,CAMA,MAAM,UAAW,CACf,MAAMC,EAAM,IAAI,KAEhB,OAAI,KAAK,mBAAmB,QAAQ,GAAKA,EAAI,QAAQ,GACnD,KAAK,IACH,KAAK,SAAS,sDAAsD,EACpE,sBAAsB,KAAK,IAAI,eACjC,EACO,CAAE,QAAS,GAAO,WAAY,KAAK,WAAY,UAAWA,EAAI,YAAY,CAAE,GAG9E,KAAK,MAAM,KAAK,kBAAkB,CAC3C,CAMA,MAAM,MAAMC,EAAa,CACvB,OAAO,IAAI,QAASC,GAAY,CAC9B,KAAK,IACH,KAAK,SACH,sCAAsC,KAAK,WAAW,YAAY,CAAC,YACrE,EACA,6BAA6B,KAAK,IAAI,UAAUD,EAAY,YAAY,CAAC,EAC3E,EAEA,MAAME,EAAMX,EAAS,YAAYS,EAAa,IAAM,CAClD,KAAK,IACH,KAAK,SACH,sCAAsC,KAAK,WAAW,YAAY,CAAC,WACrE,EACA,4BAA4B,KAAK,IAAI,eACvC,EACAC,EAAQ,CAAE,QAAS,GAAM,WAAY,KAAK,WAAY,UAAW,IAAI,KAAK,EAAE,YAAY,CAAE,CAAC,CAC7F,CAAC,EAED,KAAK,cAAgBC,CACvB,CAAC,CACH,CAMA,MAAM,UAAW,CACf,GAAI,KAAK,mBAAqB,EAC5B,YAAK,IACH,KAAK,SAAS,sDAAsD,EACpE,sBAAsB,KAAK,IAAI,eACjC,EACO,CAAE,QAAS,GAAO,WAAY,KAAK,WAAY,UAAW,IAAI,KAAK,EAAE,YAAY,CAAE,EAG5F,MAAMF,EAAcR,EAAgB,IAAI,KAAQ,KAAK,iBAAiB,EAEtE,OAAO,KAAK,MAAMQ,CAAW,CAC/B,CAMA,yBAA0B,CACxB,MAAO,CACL,GAAG,MAAM,wBAAwB,EAGjC,SAAU,KACV,WAAY,KAAK,WACjB,mBAAoB,KAAK,mBACzB,kBAAmB,KAAK,iBAC1B,CACF,CACF,CAEAP,EAAU,kBAAkBA,CAAS",
|
|
6
6
|
"names": ["Step", "delay_types", "step_types", "schedule", "addMilliseconds", "DelayStep", "__name", "name", "absolute_timestamp", "relative_delay_ms", "delay_type", "now", "delay_until", "resolve", "job"]
|
|
7
7
|
}
|