@ronaldroe/micro-flow 1.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.
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Enumeration of delay types for DelayStep.
3
+ *
4
+ * @enum {string}
5
+ * @readonly
6
+ * @example
7
+ * import delay_types from 'micro-flow';
8
+ *
9
+ * const delayStep = new DelayStep({
10
+ * name: 'wait-5-seconds',
11
+ * delay_type: delay_types.RELATIVE,
12
+ * delay_duration: 5000
13
+ * });
14
+ */
15
+ const delay_types = {
16
+ /**
17
+ * Delay until a specific absolute timestamp or Date.
18
+ * Use with delay_timestamp property.
19
+ * @type {string}
20
+ */
21
+ ABSOLUTE: 'absolute',
22
+
23
+ /**
24
+ * Delay using a cron expression for scheduled execution.
25
+ * Use with cron_expression property.
26
+ * @type {string}
27
+ */
28
+ CRON: 'cron',
29
+
30
+ /**
31
+ * Delay for a relative duration in milliseconds.
32
+ * Use with delay_duration property.
33
+ * @type {string}
34
+ */
35
+ RELATIVE: 'relative',
36
+ };
37
+
38
+ export default delay_types;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Error messages used in the micro-flow library.
3
+ *
4
+ * @enum {string}
5
+ * @readonly
6
+ */
7
+ const errors = {
8
+ INVALID_STATE_PATH: 'The provided state path is invalid.\n',
9
+ INVALID_CONDITIONAL: 'Conditional properties are required for LogicStep.',
10
+ };
11
+
12
+ /**
13
+ * Warning messages used in the micro-flow library.
14
+ * These are typically logged to the console to alert developers of potential issues.
15
+ *
16
+ * @enum {string}
17
+ * @readonly
18
+ */
19
+ const warnings = {
20
+ DO_NOT_SET_STEPS_DIRECTLY: 'Using this.setState("steps", ...) is not recommended. ' +
21
+ 'State will not be initialized correctly. Use workflow methods to manage steps instead.',
22
+ BROADCAST_FAILED: 'Broadcast failed or is not supported in this environment. The error has more detail:\n',
23
+ };
24
+
25
+ export { errors, warnings };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Enumeration of flow control types for breaking or continuing execution.
3
+ *
4
+ * @enum {string}
5
+ * @readonly
6
+ */
7
+ const flow_control_types = {
8
+ BREAK: 'break',
9
+ SKIP: 'skip'
10
+ };
11
+
12
+ export default flow_control_types;
@@ -0,0 +1,13 @@
1
+ export { default as conditional_step_comparators } from './conditional_step_comparators.js';
2
+ export { default as delay_types } from './delay_types.js';
3
+ export * from './errors.js';
4
+ export { default as flow_control_types } from './flow_control_types.js';
5
+ export { default as logic_step_types } from './logic_step_types.js';
6
+ export { default as loop_types } from './loop_types.js';
7
+ export { default as step_event_names } from './step_event_names.js';
8
+ export { default as step_statuses } from './step_statuses.js';
9
+ export { default as step_types } from './step_types.js';
10
+ export { default as sub_step_types } from './sub_step_types.js';
11
+ export { default as workflow_event_names } from './workflow_event_names.js';
12
+ export { default as workflow_statuses } from './workflow_statuses.js';
13
+ export { default as base_types } from './base_types.js';
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Enumeration of logic step types for control flow operations.
3
+ * These types define different kinds of logic-based workflow steps.
4
+ *
5
+ * @enum {string}
6
+ * @readonly
7
+ */
8
+ const LogicStepTypes = {
9
+ CONDITIONAL: 'conditional',
10
+ LOOP: 'loop',
11
+ FLOW_CONTROL: 'flow_control',
12
+ SWITCH: 'switch',
13
+ SKIP: 'skip'
14
+ };
15
+
16
+ export default LogicStepTypes;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Enumeration of loop types for LoopStep.
3
+ *
4
+ * @enum {string}
5
+ * @readonly
6
+ */
7
+ const loop_types = {
8
+ WHILE: 'while',
9
+ FOR_EACH: 'for_each'
10
+ };
11
+
12
+ export default loop_types;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Enumeration of step lifecycle event names.
3
+ * Steps emit these events during their execution lifecycle.
4
+ *
5
+ * @enum {string}
6
+ * @readonly
7
+ */
8
+ const step_event_names = {
9
+ CONDITIONAL_FALSE_BRANCH_EXECUTED: 'conditional_false_branch_executed',
10
+ CONDITIONAL_TRUE_BRANCH_EXECUTED: 'conditional_true_branch_executed',
11
+ DELAY_STEP_ABSOLUTE_COMPLETE: 'delay_step_absolute_complete',
12
+ DELAY_STEP_RELATIVE_COMPLETE: 'delay_step_relative_complete',
13
+ LOOP_ITERATION_COMPLETE: 'loop_iteration_complete',
14
+ STEP_COMPLETE: 'step_complete',
15
+ STEP_FAILED: 'step_failed',
16
+ STEP_RUNNING: 'step_running',
17
+ STEP_PENDING: 'step_pending',
18
+ STEP_WAITING: 'step_waiting',
19
+ STEP_RETRYING: 'step_retrying',
20
+ }
21
+
22
+ export default step_event_names;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Enumeration of possible step execution statuses.
3
+ * Steps transition through these statuses during their lifecycle.
4
+ *
5
+ * @enum {string}
6
+ * @readonly
7
+ */
8
+ const step_statuses = {
9
+ COMPLETE: 'complete',
10
+ FAILED: 'failed',
11
+ PENDING: 'pending',
12
+ QUEUED: 'queued',
13
+ RUNNING: 'running',
14
+ WAITING: 'waiting',
15
+ };
16
+
17
+ export default step_statuses;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Enumeration of step types used throughout the workflow system.
3
+ * These types categorize steps by their primary function.
4
+ *
5
+ * @enum {string}
6
+ * @readonly
7
+ */
8
+ const step_types = {
9
+ ACTION: 'action',
10
+ LOGIC: 'logic',
11
+ DELAY: 'delay',
12
+ };
13
+
14
+ export default step_types;
@@ -0,0 +1,130 @@
1
+ import { readdirSync, readFileSync } from 'fs';
2
+ import { fileURLToPath } from 'url';
3
+ import { dirname, join } from 'path';
4
+ import logic_step_types from './logic_step_types.js';
5
+ import step_types from './step_types.js';
6
+ import { sub } from 'date-fns';
7
+
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = dirname(__filename);
10
+
11
+ /**
12
+ * Generates a mapping of Step class names to their step_name identifiers by reading
13
+ * class files from the filesystem. This approach avoids circular dependencies that would
14
+ * occur if we imported the Step classes directly.
15
+ *
16
+ * The function parses each class file to extract:
17
+ * - The class name from the export statement
18
+ * - The static step_name property value
19
+ *
20
+ * When step_name references an enum (e.g., logic_step_types.CONDITIONAL), the function
21
+ * resolves the actual string value from the imported enum objects.
22
+ *
23
+ * The built-in classes directory is always scanned. Additional directories can be provided
24
+ * to scan for custom step classes. This is typically used via the workflow's sub_step_type_paths
25
+ * configuration option.
26
+ *
27
+ * @function generate_sub_step_types
28
+ * @param {string[]} [directories=[]] - An array of additional directory paths to scan for class files.
29
+ * The built-in classes directory is always included. Defaults to an empty array.
30
+ * @returns {Object.<string, string|null>} An object mapping class names to their step_name values.
31
+ * Classes without a step_name property are mapped to null.
32
+ * @example
33
+ * // Default usage (scans built-in classes only)
34
+ * const types = generate_sub_step_types();
35
+ * // Returns:
36
+ * // {
37
+ * // "Step": null,
38
+ * // "ConditionalStep": "conditional",
39
+ * // "LogicStep": "logic",
40
+ * // "DelayStep": "delay",
41
+ * // ...
42
+ * // }
43
+ *
44
+ * // With custom directories
45
+ * const types = generate_sub_step_types(['/path/to/custom/steps']);
46
+ */
47
+ const generate_sub_step_types = (directories = []) => {
48
+ const types = {};
49
+
50
+ // Always include the classes directory, then append any additional directories
51
+ directories.push(join(__dirname, '../classes'));
52
+
53
+ // Combine all enums into one lookup object
54
+ const allEnums = {
55
+ logic_step_types,
56
+ step_types
57
+ };
58
+
59
+ // Scan each directory in the array
60
+ for (const dir of directories) {
61
+ // Read all files in the current directory
62
+ const files = readdirSync(dir).filter(file => file.endsWith('.js') && file !== 'index.js');
63
+
64
+ for (const file of files) {
65
+ const filePath = join(dir, file);
66
+ const content = readFileSync(filePath, 'utf-8');
67
+
68
+ // Extract class name from the file content
69
+ const classNameMatch = content.match(/export default class (\w+)/);
70
+ if (!classNameMatch) continue;
71
+
72
+ const className = classNameMatch[1];
73
+
74
+ // Extract static step_name value
75
+ const stepNameMatch = content.match(/static step_name\s*=\s*['"`]?([^'"`;\n]+)['"`]?/);
76
+
77
+ if (stepNameMatch) {
78
+ let stepName = stepNameMatch[1].trim();
79
+
80
+ // Handle cases where step_name references an enum
81
+ // e.g., logic_step_types.CONDITIONAL or step_types.ACTION
82
+ if (stepName.includes('.')) {
83
+ const [enumName, enumKey] = stepName.split('.');
84
+
85
+ // Look up the actual value from the imported enums
86
+ if (allEnums[enumName] && allEnums[enumName][enumKey]) {
87
+ stepName = allEnums[enumName][enumKey];
88
+ } else {
89
+ stepName = null;
90
+ }
91
+ }
92
+
93
+ types[className] = stepName;
94
+ } else {
95
+ types[className] = null;
96
+ }
97
+ }
98
+ }
99
+
100
+ return types;
101
+ }
102
+
103
+ /**
104
+ * Pre-generated mapping of all built-in Step class names to their step_name identifiers.
105
+ * This is a singleton object exported as the default export.
106
+ *
107
+ * **Changed in recent version:** Previously exported as a function, now exported as a
108
+ * pre-generated object for improved performance and consistency.
109
+ *
110
+ * @constant {Object.<string, string|null>}
111
+ * @example
112
+ * import sub_step_types from 'micro-flow';
113
+ *
114
+ * console.log(sub_step_types);
115
+ * // {
116
+ * // "Step": null,
117
+ * // "ConditionalStep": "conditional",
118
+ * // "DelayStep": "delay",
119
+ * // "LoopStep": "loop",
120
+ * // ...
121
+ * // }
122
+ *
123
+ * // Check if a class name is a registered step type
124
+ * if (sub_step_types['ConditionalStep']) {
125
+ * console.log('ConditionalStep is a registered step type');
126
+ * }
127
+ */
128
+ const sub_step_types = generate_sub_step_types();
129
+
130
+ export default sub_step_types;
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Enumeration of workflow lifecycle event names.
3
+ * Workflows emit these events during their creation and execution lifecycle.
4
+ *
5
+ * @enum {string}
6
+ * @readonly
7
+ */
8
+ const workflow_event_names = {
9
+ WORKFLOW_CANCELLED: 'workflow_cancelled',
10
+ WORKFLOW_COMPLETE: 'workflow_complete',
11
+ WORKFLOW_CREATED: 'workflow_created',
12
+ WORKFLOW_ERRORED: 'workflow_errored',
13
+ WORKFLOW_FAILED: 'workflow_failed',
14
+ WORKFLOW_PAUSED: 'workflow_paused',
15
+ WORKFLOW_RESUMED: 'workflow_resumed',
16
+ WORKFLOW_RUNNING: 'workflow_running',
17
+ WORKFLOW_STEP_ADDED: 'workflow_step_added',
18
+ WORKFLOW_STEP_MOVED: 'workflow_step_moved',
19
+ WORKFLOW_STEP_REMOVED: 'workflow_step_removed',
20
+ WORKFLOW_STEP_SHIFTED: 'workflow_step_shifted',
21
+ WORKFLOW_STEP_SKIPPED: 'workflow_step_skipped',
22
+ WORKFLOW_STEPS_ADDED: 'workflow_steps_added',
23
+ WORKFLOW_STEPS_CLEARED: 'workflow_steps_cleared',
24
+ }
25
+
26
+ export default workflow_event_names;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Enumeration of possible workflow execution statuses.
3
+ * Workflows transition through these statuses during their lifecycle.
4
+ *
5
+ * @enum {string}
6
+ * @readonly
7
+ */
8
+ const workflow_statuses = {
9
+ CANCELLED: 'cancelled',
10
+ COMPLETE: 'complete',
11
+ CREATED: 'created',
12
+ ERRORED: 'errored',
13
+ FROZEN: 'frozen',
14
+ FAILED: 'failed',
15
+ PAUSED: 'paused',
16
+ PENDING: 'pending',
17
+ RUNNING: 'running',
18
+ SKIPPED: 'skipped'
19
+ };
20
+
21
+ export default workflow_statuses;
package/src/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export * from './classes/index.js';
2
+ export * from './enums/index.js';