@statewalker/fsm 0.36.0 → 0.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +112 -0
  2. package/bin/cli.js +1 -1
  3. package/dist/bin/node-runner-UJp8T_oP.d.ts +16 -0
  4. package/dist/bin/node-runner-UJp8T_oP.d.ts.map +1 -0
  5. package/dist/bin/node-runner.js +40 -0
  6. package/dist/bin/node-runner.js.map +1 -0
  7. package/dist/index-vTjnkbGW.d.ts +129 -0
  8. package/dist/index-vTjnkbGW.d.ts.map +1 -0
  9. package/dist/index.js +38 -779
  10. package/dist/index.js.map +1 -1
  11. package/dist/launcher-6VUDviTj.d.ts +48 -0
  12. package/dist/launcher-6VUDviTj.d.ts.map +1 -0
  13. package/dist/launcher-CASrMAOa.js +443 -0
  14. package/dist/launcher-CASrMAOa.js.map +1 -0
  15. package/package.json +8 -8
  16. package/src/bin/node-runner.ts +57 -0
  17. package/src/core/fsm-base-class.ts +1 -26
  18. package/src/core/fsm-process.ts +14 -11
  19. package/src/core/fsm-state.ts +1 -21
  20. package/src/core/index.ts +1 -1
  21. package/src/index.ts +0 -3
  22. package/src/orchestrator/handler-registry.ts +108 -0
  23. package/src/orchestrator/index.ts +15 -9
  24. package/src/orchestrator/launcher.ts +42 -141
  25. package/src/orchestrator/start-process.ts +141 -26
  26. package/src/utils/index.ts +0 -2
  27. package/src/utils/printer.ts +5 -11
  28. package/src/utils/tracer.ts +1 -1
  29. package/CHANGELOG.md +0 -59
  30. package/dist/index.d.ts +0 -335
  31. package/src/core/new-fsm-process.ts +0 -83
  32. package/src/orchestrator/constants.ts +0 -130
  33. package/src/orchestrator/is-generator.ts +0 -12
  34. package/src/orchestrator/process-config-manager.ts +0 -70
  35. package/src/orchestrator/resolve-module-refs.ts +0 -52
  36. package/src/orchestrator/start-node-processes.ts +0 -19
  37. package/src/orchestrator/start-processes.ts +0 -32
  38. package/src/orchestrator/types.ts +0 -34
  39. package/src/utils/handlers.ts +0 -35
  40. package/src/utils/process.ts +0 -26
  41. package/src/utils/transitions.ts +0 -56
package/dist/index.d.ts DELETED
@@ -1,335 +0,0 @@
1
- type Handler<P extends unknown[] = unknown[], R = unknown> = (...args: P) => R;
2
- declare class FsmBaseClass {
3
- handlers: Record<string, Handler[]>;
4
- data: Record<string, unknown>;
5
- constructor();
6
- setData<T>(key: string, value: T): this;
7
- getData<T>(key: string): T | undefined;
8
- protected _addHandler<T>(type: string, handler: T, direct?: boolean): () => void;
9
- protected _removeHandler<T>(type: string, handler: T): void;
10
- _runHandlerParallel(type: string, ...args: unknown[]): Promise<void>;
11
- _runHandler(type: string, ...args: unknown[]): Promise<void>;
12
- _handleError(error: Error | unknown): Promise<void>;
13
- }
14
-
15
- declare const STATE_ANY = "*";
16
- declare const STATE_INITIAL = "";
17
- declare const STATE_FINAL = "";
18
- declare const EVENT_ANY = "*";
19
- declare const EVENT_EMPTY = "";
20
- type FsmStateKey = string;
21
- type FsmEventKey = string;
22
- type FsmStateConfig = {
23
- key: FsmStateKey;
24
- transitions?: [from: FsmStateKey, event: FsmEventKey, to: FsmStateKey][];
25
- states?: FsmStateConfig[];
26
- } & Record<string, unknown>;
27
-
28
- declare class FsmStateDescriptor {
29
- transitions: Record<string, Record<string, string>>;
30
- states: Record<string, FsmStateDescriptor>;
31
- static build(config: FsmStateConfig): FsmStateDescriptor;
32
- getTargetStateKey(stateKey: string, eventKey: string): string;
33
- }
34
-
35
- type FsmStateDump = Record<string, unknown> & {
36
- key: string;
37
- data: Record<string, unknown>;
38
- };
39
- type FsmStateHandler = (state: FsmState, ...args: unknown[]) => void | Promise<void>;
40
- type FsmStateDumpHandler = (state: FsmState, dump: FsmStateDump) => void | Promise<void>;
41
- type FsmStateErrorHandler = (state: FsmState, error: unknown) => void | Promise<void>;
42
- declare class FsmState extends FsmBaseClass {
43
- process: FsmProcess;
44
- key: string;
45
- parent?: FsmState;
46
- descriptor?: FsmStateDescriptor;
47
- constructor(process: FsmProcess, parent: FsmState | undefined, key: string, descriptor?: FsmStateDescriptor);
48
- onEnter(handler: FsmStateHandler): () => void;
49
- onExit(handler: FsmStateHandler): () => void;
50
- onStateError(handler: FsmStateErrorHandler): () => void;
51
- dump(handler: FsmStateDumpHandler): () => void;
52
- restore(handler: FsmStateDumpHandler): () => void;
53
- getData<T>(key: string, recursive?: boolean): T | undefined;
54
- useData<T>(key: string): (((recursive?: boolean) => T | undefined) | ((value: T) => this))[];
55
- _handleError(error: Error | unknown): Promise<void>;
56
- }
57
-
58
- declare const STATUS_NONE = 0;
59
- declare const STATUS_FIRST = 1;
60
- declare const STATUS_NEXT = 2;
61
- declare const STATUS_LEAF = 4;
62
- declare const STATUS_LAST = 8;
63
- declare const STATUS_FINISHED = 16;
64
- declare const STATUS_ENTER: number;
65
- declare const STATUS_EXIT: number;
66
- type FsmProcessHandler = (process: FsmProcess, ...args: unknown[]) => void | Promise<void>;
67
- type FsmProcessDump = Record<string, unknown> & {
68
- status: number;
69
- event?: string;
70
- stack: FsmStateDump[];
71
- };
72
- type FsmProcessDumpHandler = (process: FsmProcess, dump: FsmProcessDump) => void | Promise<void>;
73
- declare class FsmProcess extends FsmBaseClass {
74
- state?: FsmState;
75
- event?: string;
76
- nextEvent?: string;
77
- running: boolean;
78
- mask: number;
79
- status: number;
80
- config: FsmStateConfig;
81
- rootDescriptor: FsmStateDescriptor;
82
- constructor(config: FsmStateConfig);
83
- shutdown(event?: string): Promise<void>;
84
- dispatch(event: string): Promise<boolean>;
85
- dump(...args: unknown[]): Promise<FsmProcessDump>;
86
- restore(dump: FsmProcessDump, ...args: unknown[]): Promise<this>;
87
- onStateCreate(handler: FsmStateHandler): () => void;
88
- onStateError(handler: (state: FsmState, error: unknown) => void | Promise<void>): () => void;
89
- _handleStateError(state: FsmState, error: Error | unknown): Promise<void>;
90
- _newState(parent: FsmState | undefined, key: string, descriptor: FsmStateDescriptor | undefined): FsmState;
91
- _getSubstate(parent: FsmState | undefined, prevStateKey: string | undefined): FsmState | undefined;
92
- _newSubstate(parent: FsmState | undefined, toState: string): FsmState;
93
- _update(): boolean;
94
- }
95
-
96
- type Module<C = unknown> = (context: C) => void | (() => void | Promise<void>) | Promise<void | (() => void | Promise<void>)> | Generator<string> | AsyncGenerator<string>;
97
- declare function newFsmProcess<C>(context: C, config: FsmStateConfig, load: (state: string, event: undefined | string) => undefined | Module<C> | Module<C>[] | Promise<undefined | Module<C> | Module<C>[]>): [
98
- dispatch: (event: string) => Promise<boolean>,
99
- shutdown: () => Promise<void>
100
- ];
101
-
102
- /**
103
- * Key used to bind the dispatch function to the process context.
104
- * The dispatch function allows triggering state transitions by dispatching events.
105
- *
106
- * Example usage:
107
- * ```typescript
108
- * const context: Record<string, unknown> = {};
109
- * // Initialize the FSM process using `startFsmProcess`
110
- * const dispatch = context["fsm:dispatch"] as (event: string) => Promise<void>;
111
- * await dispatch("someEvent");
112
- */
113
- declare const KEY_DISPATCH: "fsm:dispatch";
114
- /**
115
- * Key used to bind the terminate function to the process context.
116
- * The terminate function is used to gracefully shut down the FSM process.
117
- * It returns a Promise that resolves when the process has been fully terminated.
118
- * Example usage:
119
- * ```typescript
120
- * const context: Record<string, unknown> = {};
121
- * // Initialize the FSM process using `startFsmProcess`
122
- * const terminate = context["fsm:terminate"] as () => Promise<void>;
123
- * await terminate();
124
- * ```
125
- */
126
- declare const KEY_TERMINATE: "fsm:terminate";
127
- /**
128
- * Key used to bind the current stack of active states to the process context.
129
- * This provides a snapshot of the states the FSM process has entered.
130
- * It is represented as an array of strings -- state keys.
131
- *
132
- * Example usage:
133
- * ```typescript
134
- * const context: Record<string, unknown> = {};
135
- * // Initialize the FSM process using `startFsmProcess`
136
- * const states = context["fsm:states"] as string[];
137
- * console.log("Current active states:", states);
138
- * ```
139
- */
140
- declare const KEY_STATES: "fsm:states";
141
- /**
142
- * Key used to bind the current event being processed to the process context.
143
- * This represents the event that triggered the current state transition.
144
- * It is represented as a string.
145
- * Example usage:
146
- * ```typescript
147
- * const context: Record<string, unknown> = {};
148
- * // Initialize the FSM process using `startFsmProcess`
149
- * const event = context["fsm:event"] as string;
150
- * console.log("Current event:", event);
151
- * ```
152
- */
153
- declare const KEY_EVENT: "fsm:event";
154
- /**
155
- * Key used to register a new FSM process configuration in the process context.
156
- * This key is associated with a function that allows adding new FSM configurations.
157
- * The function takes a process name and its configuration, and returns a cleanup function
158
- * to remove the registered configuration.
159
- * Example usage:
160
- * ```typescript
161
- * const context: Record<string, unknown> = {};
162
- * initProcessManager(context); // Initialize the process manager in the context
163
- * ...
164
- * type StateConfig = { key: string; transitions?: string[][]; states?: StateConfig[] };
165
- * const registerConfig = context["fsm:sys:registerConfig"] as (name: string, config: StateConfig) => () => void;
166
- * const unregister = registerConfig("myProcess", { key: "Main", transitions: [...] });
167
- * // To unregister the configuration later
168
- * unregister();
169
- * ```
170
- */
171
- declare const KEY_REGISTER_CONFIG: "fsm:sys:registerConfig";
172
- /**
173
- * Key used to register state and event handlers for FSM processes in the process context.
174
- * This key is associated with a function that allows adding handler modules for a specific process.
175
- * The function takes a process name and a variable number of handler modules, returning a cleanup function
176
- * to remove the registered handlers.
177
- * Example usage:
178
- * ```typescript
179
- * const context: Record<string, unknown> = {};
180
- * initProcessManager(context); // Initialize the process manager in the context
181
- * ...
182
- * const registerHandlers = context["fsm:sys:registerHandlers"] as (name: string, ...modules: unknown[]) => () => void;
183
- * const handlerModule1 = {
184
- * Main: async (context) => { ... },
185
- * SomeState: async (context) => { ... },
186
- * }
187
- * // Views layer can be defined in the same or separate modules
188
- * const handlerModule3 = {
189
- * MainView: async (context) => { ... },
190
- * SomeStateView: async (context) => { ... },
191
- * }
192
- * // A common handler function to call for all states
193
- * const handlerModule2 = (context) => { ... };
194
- * const unregister = registerHandlers(
195
- * "myProcess",
196
- * handlerModule1,
197
- * handlerModule2,
198
- * handlerModule3
199
- * );
200
- * // To unregister the handlers later
201
- * unregister();
202
- * ```
203
- */
204
- declare const KEY_REGISTER_HANDLERS: "fsm:sys:registerHandlers";
205
- /**
206
- * Key used to launch an FSM process in the process context.
207
- * This key is associated with a function that initiates the FSM process based on its name and context.
208
- * The function takes the process name and context, returning either nothing, a cleanup function,
209
- * or a Promise that resolves to either nothing or a cleanup function.
210
- * Example usage:
211
- * ```typescript
212
- * const context: Record<string, unknown> = {};
213
- * initProcessManager(context); // Initialize the process manager in the context
214
- * // Register process configurations and handlers as needed
215
- *
216
- * const launchProcess = context["fsm:sys:launch"] as (name: string, context: Record<string, unknown>) => () => Promise<void>;
217
- * const terminate = await launchProcess("myProcess", context);
218
- * // To terminate the process later
219
- * terminate?.();
220
- * ```
221
- */
222
- declare const KEY_LAUNCH_PROCESS: "fsm:sys:launch";
223
-
224
- type StageHandler<C = Record<string, unknown>> = (context: C) => void | (() => void | Promise<void>) | Promise<void | (() => void | Promise<void>)> | AsyncGenerator<string, void, unknown> | Generator<string, void, unknown>;
225
- declare function toStageHandlers<C>(value: unknown, accept: (key: string, value: unknown) => boolean): StageHandler<C>[];
226
-
227
- type ProcessConfig = {
228
- name: string;
229
- config?: FsmStateConfig;
230
- } & ({
231
- handler?: StageHandler;
232
- } | {
233
- handlers?: StageHandler | (StageHandler | {
234
- [state: string]: StageHandler | StageHandler[];
235
- })[];
236
- } | {
237
- default?: StageHandler | (StageHandler | {
238
- [state: string]: StageHandler | StageHandler[];
239
- })[];
240
- });
241
- declare function launcher(options: unknown): Promise<() => Promise<void>>;
242
-
243
- interface IProcessConfigManager {
244
- getProcessConfig(processName: string): FsmStateConfig;
245
- getHandlersLoader<C = unknown>(processName: string): (state: string, event: undefined | string) => StageHandler<C>[];
246
- registerConfig(name: string, config: FsmStateConfig): () => void;
247
- registerHandlers(name: string, ...modules: unknown[]): () => void;
248
- }
249
- declare class ProcessConfigManager implements IProcessConfigManager {
250
- protected configs: Record<string, FsmStateConfig>;
251
- protected handlers: Record<string, unknown[]>;
252
- getProcessConfig(processName: string): FsmStateConfig;
253
- getHandlersLoader<C = unknown>(processName: string): (state: string, event: undefined | string) => StageHandler<C>[];
254
- registerConfig(name: string, config: FsmStateConfig): () => void;
255
- registerHandlers(name: string, ...modules: unknown[]): () => void;
256
- }
257
-
258
- /**
259
- * Resolve module paths relative to a base URL.
260
- * This is useful for converting relative paths to absolute URLs.
261
- *
262
- * @param baseUrl - The base URL to resolve against.
263
- * @param refs - An array of module references (relative or absolute).
264
- * @returns An array of resolved absolute module URLs as strings.
265
- * @example
266
- * ```ts
267
- * const urls = resolveModulesUrls(
268
- * 'file:///home/user/project/', // base URL
269
- * 'https://example.com/js/my-module.js', // absolute URL
270
- * './module1.js', // relative path
271
- * '../module2.js' // relative path
272
- * );
273
- * console.log(urls);
274
- * // Output: [
275
- * // 'https://example.com/js/my-module.js',
276
- * // 'file:///home/user/project/module1.js',
277
- * // 'file:///home/user/module2.js'
278
- * // ] *
279
- * ```
280
- */
281
- declare function resolveModulesUrls(baseUrl: URL | string, ...refs: (URL | string)[]): string[];
282
- /**
283
- * Resolves module paths relative to a base URL.
284
- * This is useful for converting relative paths to absolute file system paths.
285
- * @param baseUrl - The base URL to resolve against
286
- * @param refs - An array of module references (relative or absolute)
287
- * @returns - An array of resolved absolute module paths as strings
288
- * @example
289
- * ```ts
290
- * const paths = resolveModulesPaths('file:///home/user/project/', './module1.js', '../module2.js');
291
- * console.log(paths);
292
- * // Output: [
293
- * // '/home/user/project/module1.js',
294
- * // '/home/user/module2.js'
295
- * // ]
296
- * ```
297
- */
298
- declare function resolveModulesPaths(baseUrl: URL | string, ...refs: (URL | string)[]): string[];
299
-
300
- declare function startNodeProcesses(modules?: string[]): Promise<void>;
301
-
302
- declare function startFsmProcess<C = unknown>(context: C, config: FsmStateConfig, load: (state: string, event: undefined | string) => StageHandler<C>[] | Promise<StageHandler<C>[]>, startEvent?: string): Promise<() => Promise<void>>;
303
-
304
- declare function startProcesses({ onExit, modules, init, }: {
305
- onExit?: () => Promise<void> | void;
306
- modules: unknown[];
307
- init?: (context: Record<string, unknown>) => Promise<Record<string, unknown>> | Record<string, unknown>;
308
- }): Promise<() => Promise<void>>;
309
-
310
- type Printer = (...args: unknown[]) => void;
311
- type PrinterConfig = {
312
- prefix?: string;
313
- print?: (...args: unknown[]) => void;
314
- lineNumbers?: boolean;
315
- };
316
- declare const KEY_PRINTER = "printer";
317
- declare function preparePrinter(process: FsmProcess, { prefix, print, lineNumbers }: PrinterConfig): Printer;
318
- declare function setPrinter(state: FsmState, config?: PrinterConfig): void;
319
- declare function setProcessPrinter(process: FsmProcess, config?: PrinterConfig): void;
320
- declare function getProcessPrinter(process: FsmProcess): Printer;
321
- declare function getPrinter(state: FsmState): Printer;
322
-
323
- declare function newProcess(config: FsmStateConfig, { prefix, print, lineNumbers, }: {
324
- prefix?: string;
325
- print?: (...args: any[]) => void;
326
- lineNumbers?: boolean;
327
- }): FsmProcess;
328
-
329
- declare function setProcessTracer(process: FsmProcess, print?: Printer): () => void;
330
- declare function setStateTracer(state: FsmState, print?: Printer): void;
331
-
332
- declare function isStateTransitionEnabled(process: FsmProcess, event: string): boolean;
333
- declare function getStateTransitions(state?: FsmState): [from: string, event: string, to: string][];
334
-
335
- export { EVENT_ANY, EVENT_EMPTY, type FsmEventKey, FsmProcess, type FsmProcessDump, type FsmProcessDumpHandler, type FsmProcessHandler, FsmState, type FsmStateConfig, FsmStateDescriptor, type FsmStateDump, type FsmStateDumpHandler, type FsmStateErrorHandler, type FsmStateHandler, type FsmStateKey, type IProcessConfigManager, KEY_DISPATCH, KEY_EVENT, KEY_LAUNCH_PROCESS, KEY_PRINTER, KEY_REGISTER_CONFIG, KEY_REGISTER_HANDLERS, KEY_STATES, KEY_TERMINATE, type Module, type Printer, type PrinterConfig, type ProcessConfig, ProcessConfigManager, STATE_ANY, STATE_FINAL, STATE_INITIAL, STATUS_ENTER, STATUS_EXIT, STATUS_FINISHED, STATUS_FIRST, STATUS_LAST, STATUS_LEAF, STATUS_NEXT, STATUS_NONE, type StageHandler, startNodeProcesses as default, getPrinter, getProcessPrinter, getStateTransitions, isStateTransitionEnabled, launcher, newFsmProcess, newProcess, preparePrinter, resolveModulesPaths, resolveModulesUrls, setPrinter, setProcessPrinter, setProcessTracer, setStateTracer, startFsmProcess, startNodeProcesses, startProcesses, toStageHandlers };
@@ -1,83 +0,0 @@
1
- import { isStateTransitionEnabled } from "../utils/transitions.ts";
2
- import { FsmProcess } from "./fsm-process.ts";
3
- import type { FsmStateConfig } from "./fsm-state-config.ts";
4
-
5
- export type Module<C = unknown> = (context: C) =>
6
- | void
7
- | (() => void | Promise<void>)
8
- | Promise<void | (() => void | Promise<void>)>
9
- // Event emitters / triggers
10
- | Generator<string>
11
- | AsyncGenerator<string>;
12
-
13
- export function newFsmProcess<C>(
14
- context: C,
15
- config: FsmStateConfig,
16
- load: (
17
- state: string,
18
- event: undefined | string,
19
- ) =>
20
- | undefined
21
- | Module<C>
22
- | Module<C>[]
23
- | Promise<undefined | Module<C> | Module<C>[]>,
24
- ): [
25
- dispatch: (event: string) => Promise<boolean>,
26
- shutdown: () => Promise<void>,
27
- ] {
28
- let started = false;
29
- let terminated = false;
30
- const process = new FsmProcess(config);
31
- async function dispatch(event: string): Promise<boolean> {
32
- return terminated ||
33
- (event !== undefined &&
34
- (!started || isStateTransitionEnabled(process, event)))
35
- ? process.dispatch(event)
36
- : false;
37
- }
38
- process.onStateCreate((state) => {
39
- started = true;
40
- state.onEnter(async () => {
41
- const modules = (await load(state.key, process.event)) ?? [];
42
- for (const module of Array.isArray(modules) ? modules : [modules]) {
43
- const result = await module?.(context);
44
- if (isGenerator(result)) {
45
- state.onExit(() => {
46
- result.return?.(void 0);
47
- });
48
- (async () => {
49
- for await (const event of result) {
50
- if (terminated) {
51
- break;
52
- }
53
- await dispatch(event);
54
- if (terminated) {
55
- break;
56
- }
57
- }
58
- })();
59
- } else if (typeof result === "function") {
60
- state.onExit(result);
61
- }
62
- }
63
- });
64
- });
65
- async function shutdown(): Promise<void> {
66
- await process.shutdown();
67
- terminated = true;
68
- }
69
- return [dispatch, shutdown] as const;
70
-
71
- function isGenerator(
72
- value: unknown,
73
- ): value is
74
- | Generator<string, void, unknown>
75
- | AsyncGenerator<string, void, unknown> {
76
- return (
77
- typeof value === "object" &&
78
- value !== null &&
79
- "next" in value &&
80
- typeof (value as Generator<string, void, unknown>).next === "function"
81
- );
82
- }
83
- }
@@ -1,130 +0,0 @@
1
- /**
2
- * Key used to bind the dispatch function to the process context.
3
- * The dispatch function allows triggering state transitions by dispatching events.
4
- *
5
- * Example usage:
6
- * ```typescript
7
- * const context: Record<string, unknown> = {};
8
- * // Initialize the FSM process using `startFsmProcess`
9
- * const dispatch = context["fsm:dispatch"] as (event: string) => Promise<void>;
10
- * await dispatch("someEvent");
11
- */
12
- export const KEY_DISPATCH = "fsm:dispatch" as const;
13
-
14
- /**
15
- * Key used to bind the terminate function to the process context.
16
- * The terminate function is used to gracefully shut down the FSM process.
17
- * It returns a Promise that resolves when the process has been fully terminated.
18
- * Example usage:
19
- * ```typescript
20
- * const context: Record<string, unknown> = {};
21
- * // Initialize the FSM process using `startFsmProcess`
22
- * const terminate = context["fsm:terminate"] as () => Promise<void>;
23
- * await terminate();
24
- * ```
25
- */
26
- export const KEY_TERMINATE = "fsm:terminate" as const;
27
-
28
- /**
29
- * Key used to bind the current stack of active states to the process context.
30
- * This provides a snapshot of the states the FSM process has entered.
31
- * It is represented as an array of strings -- state keys.
32
- *
33
- * Example usage:
34
- * ```typescript
35
- * const context: Record<string, unknown> = {};
36
- * // Initialize the FSM process using `startFsmProcess`
37
- * const states = context["fsm:states"] as string[];
38
- * console.log("Current active states:", states);
39
- * ```
40
- */
41
- export const KEY_STATES = "fsm:states" as const;
42
-
43
- /**
44
- * Key used to bind the current event being processed to the process context.
45
- * This represents the event that triggered the current state transition.
46
- * It is represented as a string.
47
- * Example usage:
48
- * ```typescript
49
- * const context: Record<string, unknown> = {};
50
- * // Initialize the FSM process using `startFsmProcess`
51
- * const event = context["fsm:event"] as string;
52
- * console.log("Current event:", event);
53
- * ```
54
- */
55
- export const KEY_EVENT = "fsm:event" as const;
56
-
57
- //-------------------------------------------------
58
-
59
- // export const KEY_START_PROCESS = "fsm:sys:start" as const;
60
- /**
61
- * Key used to register a new FSM process configuration in the process context.
62
- * This key is associated with a function that allows adding new FSM configurations.
63
- * The function takes a process name and its configuration, and returns a cleanup function
64
- * to remove the registered configuration.
65
- * Example usage:
66
- * ```typescript
67
- * const context: Record<string, unknown> = {};
68
- * initProcessManager(context); // Initialize the process manager in the context
69
- * ...
70
- * type StateConfig = { key: string; transitions?: string[][]; states?: StateConfig[] };
71
- * const registerConfig = context["fsm:sys:registerConfig"] as (name: string, config: StateConfig) => () => void;
72
- * const unregister = registerConfig("myProcess", { key: "Main", transitions: [...] });
73
- * // To unregister the configuration later
74
- * unregister();
75
- * ```
76
- */
77
- export const KEY_REGISTER_CONFIG = "fsm:sys:registerConfig" as const;
78
-
79
- /**
80
- * Key used to register state and event handlers for FSM processes in the process context.
81
- * This key is associated with a function that allows adding handler modules for a specific process.
82
- * The function takes a process name and a variable number of handler modules, returning a cleanup function
83
- * to remove the registered handlers.
84
- * Example usage:
85
- * ```typescript
86
- * const context: Record<string, unknown> = {};
87
- * initProcessManager(context); // Initialize the process manager in the context
88
- * ...
89
- * const registerHandlers = context["fsm:sys:registerHandlers"] as (name: string, ...modules: unknown[]) => () => void;
90
- * const handlerModule1 = {
91
- * Main: async (context) => { ... },
92
- * SomeState: async (context) => { ... },
93
- * }
94
- * // Views layer can be defined in the same or separate modules
95
- * const handlerModule3 = {
96
- * MainView: async (context) => { ... },
97
- * SomeStateView: async (context) => { ... },
98
- * }
99
- * // A common handler function to call for all states
100
- * const handlerModule2 = (context) => { ... };
101
- * const unregister = registerHandlers(
102
- * "myProcess",
103
- * handlerModule1,
104
- * handlerModule2,
105
- * handlerModule3
106
- * );
107
- * // To unregister the handlers later
108
- * unregister();
109
- * ```
110
- */
111
- export const KEY_REGISTER_HANDLERS = "fsm:sys:registerHandlers" as const;
112
-
113
- /**
114
- * Key used to launch an FSM process in the process context.
115
- * This key is associated with a function that initiates the FSM process based on its name and context.
116
- * The function takes the process name and context, returning either nothing, a cleanup function,
117
- * or a Promise that resolves to either nothing or a cleanup function.
118
- * Example usage:
119
- * ```typescript
120
- * const context: Record<string, unknown> = {};
121
- * initProcessManager(context); // Initialize the process manager in the context
122
- * // Register process configurations and handlers as needed
123
- *
124
- * const launchProcess = context["fsm:sys:launch"] as (name: string, context: Record<string, unknown>) => () => Promise<void>;
125
- * const terminate = await launchProcess("myProcess", context);
126
- * // To terminate the process later
127
- * terminate?.();
128
- * ```
129
- */
130
- export const KEY_LAUNCH_PROCESS = "fsm:sys:launch" as const;
@@ -1,12 +0,0 @@
1
- export function isGenerator(
2
- value: unknown,
3
- ): value is
4
- | Generator<string, void, unknown>
5
- | AsyncGenerator<string, void, unknown> {
6
- return (
7
- typeof value === "object" &&
8
- value !== null &&
9
- "next" in value &&
10
- typeof (value as Generator<string, void, unknown>).next === "function"
11
- );
12
- }
@@ -1,70 +0,0 @@
1
- import type { FsmStateConfig } from "../core/fsm-state-config.ts";
2
- import { type StageHandler, toStageHandlers } from "./types.ts";
3
-
4
- export interface IProcessConfigManager {
5
- getProcessConfig(processName: string): FsmStateConfig;
6
- getHandlersLoader<C = unknown>(
7
- processName: string,
8
- ): (state: string, event: undefined | string) => StageHandler<C>[];
9
- registerConfig(name: string, config: FsmStateConfig): () => void;
10
- registerHandlers(name: string, ...modules: unknown[]): () => void;
11
- }
12
-
13
- export class ProcessConfigManager implements IProcessConfigManager {
14
- protected configs: Record<string, FsmStateConfig> = {};
15
- protected handlers: Record<string, unknown[]> = {};
16
-
17
- getProcessConfig(processName: string): FsmStateConfig {
18
- return this.configs[processName] ?? { key: "Main" };
19
- }
20
-
21
- getHandlersLoader<C = unknown>(
22
- processName: string,
23
- ): (state: string, event: undefined | string) => StageHandler<C>[] {
24
- const config = this.getProcessConfig(processName);
25
- return (stateKey: string) => {
26
- const modulesKeys: string[] = [];
27
- if (stateKey === config.key) {
28
- modulesKeys.push("default");
29
- }
30
- modulesKeys.push(
31
- stateKey,
32
- `${stateKey}Controller`,
33
- `${stateKey}StateController`,
34
- `${stateKey}View`,
35
- `${stateKey}StateView`,
36
- `${stateKey}Trigger`,
37
- `${stateKey}StateTrigger`,
38
- `${stateKey}Test`,
39
- `${stateKey}StateTest`,
40
- );
41
- const keysSet = new Set(modulesKeys);
42
- const processHandlers = this.handlers[processName] ?? [];
43
- const handlers = toStageHandlers(processHandlers, (key: string) =>
44
- keysSet.has(key),
45
- );
46
- return handlers;
47
- };
48
- }
49
-
50
- registerConfig(name: string, config: FsmStateConfig): () => void {
51
- this.configs[name] = config;
52
- return () => {
53
- delete this.configs[name];
54
- };
55
- }
56
-
57
- registerHandlers(name: string, ...modules: unknown[]): () => void {
58
- let list: unknown[] = this.handlers[name];
59
- if (!list) {
60
- list = this.handlers[name] = [];
61
- }
62
- list.push(modules);
63
- return () => {
64
- list = list.filter((v) => v !== modules);
65
- if (list.length === 0) {
66
- delete this.handlers[name];
67
- }
68
- };
69
- }
70
- }
@@ -1,52 +0,0 @@
1
- /**
2
- * Resolve module paths relative to a base URL.
3
- * This is useful for converting relative paths to absolute URLs.
4
- *
5
- * @param baseUrl - The base URL to resolve against.
6
- * @param refs - An array of module references (relative or absolute).
7
- * @returns An array of resolved absolute module URLs as strings.
8
- * @example
9
- * ```ts
10
- * const urls = resolveModulesUrls(
11
- * 'file:///home/user/project/', // base URL
12
- * 'https://example.com/js/my-module.js', // absolute URL
13
- * './module1.js', // relative path
14
- * '../module2.js' // relative path
15
- * );
16
- * console.log(urls);
17
- * // Output: [
18
- * // 'https://example.com/js/my-module.js',
19
- * // 'file:///home/user/project/module1.js',
20
- * // 'file:///home/user/module2.js'
21
- * // ] *
22
- * ```
23
- */
24
- export function resolveModulesUrls(
25
- baseUrl: URL | string,
26
- ...refs: (URL | string)[]
27
- ): string[] {
28
- return refs.map((ref) => new URL(ref, baseUrl).href);
29
- }
30
-
31
- /**
32
- * Resolves module paths relative to a base URL.
33
- * This is useful for converting relative paths to absolute file system paths.
34
- * @param baseUrl - The base URL to resolve against
35
- * @param refs - An array of module references (relative or absolute)
36
- * @returns - An array of resolved absolute module paths as strings
37
- * @example
38
- * ```ts
39
- * const paths = resolveModulesPaths('file:///home/user/project/', './module1.js', '../module2.js');
40
- * console.log(paths);
41
- * // Output: [
42
- * // '/home/user/project/module1.js',
43
- * // '/home/user/module2.js'
44
- * // ]
45
- * ```
46
- */
47
- export function resolveModulesPaths(
48
- baseUrl: URL | string,
49
- ...refs: (URL | string)[]
50
- ): string[] {
51
- return refs.map((ref) => new URL(ref, baseUrl).pathname);
52
- }