@statewalker/fsm 0.31.0 → 0.32.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/dist/index.d.ts +9 -2
- package/dist/index.js +40 -13
- package/package.json +1 -1
- package/src/orchestrator/launcher.ts +74 -38
package/dist/index.d.ts
CHANGED
|
@@ -227,10 +227,17 @@ declare function toStageHandlers<C>(value: unknown, accept: (key: string, value:
|
|
|
227
227
|
type ProcessConfig = {
|
|
228
228
|
name: string;
|
|
229
229
|
config?: FsmStateConfig;
|
|
230
|
-
|
|
230
|
+
} & ({
|
|
231
|
+
handler?: StageHandler;
|
|
232
|
+
} | {
|
|
233
|
+
handlers?: StageHandler | (StageHandler | {
|
|
231
234
|
[state: string]: StageHandler | StageHandler[];
|
|
232
235
|
})[];
|
|
233
|
-
}
|
|
236
|
+
} | {
|
|
237
|
+
default?: StageHandler | (StageHandler | {
|
|
238
|
+
[state: string]: StageHandler | StageHandler[];
|
|
239
|
+
})[];
|
|
240
|
+
});
|
|
234
241
|
declare function launcher(options: unknown): Promise<() => Promise<void>>;
|
|
235
242
|
|
|
236
243
|
interface IProcessConfigManager {
|
package/dist/index.js
CHANGED
|
@@ -610,6 +610,11 @@ async function startFsmProcess(context, config, load, startEvent = "") {
|
|
|
610
610
|
}
|
|
611
611
|
|
|
612
612
|
// src/orchestrator/launcher.ts
|
|
613
|
+
function asArray(value, filter = (v) => v) {
|
|
614
|
+
if (value === void 0) return [];
|
|
615
|
+
const array = Array.isArray(value) ? value : [value];
|
|
616
|
+
return array.filter(Boolean).map(filter).filter(Boolean);
|
|
617
|
+
}
|
|
613
618
|
async function launcher(options) {
|
|
614
619
|
const configsManager = new ProcessConfigManager();
|
|
615
620
|
async function launch(processName, context, startEvent = "start") {
|
|
@@ -632,17 +637,24 @@ async function launcher(options) {
|
|
|
632
637
|
);
|
|
633
638
|
}
|
|
634
639
|
if (processConfig) {
|
|
635
|
-
configsManager2.registerConfig(
|
|
640
|
+
configsManager2.registerConfig(processName, processConfig);
|
|
636
641
|
}
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
642
|
+
const processHandlers = asArray(
|
|
643
|
+
process.handlers ?? process.handler ?? process.default,
|
|
644
|
+
(v, idx) => {
|
|
645
|
+
if (typeof v === "function") return v;
|
|
646
|
+
if (typeof v === "object" && v !== null) return v;
|
|
640
647
|
throw new Error(
|
|
641
|
-
|
|
648
|
+
[
|
|
649
|
+
`Invalid process configuration:`,
|
|
650
|
+
`a process handler is not object nor function in process ${processName} at index ${idx}`,
|
|
651
|
+
`Recieved: ${v === null ? "null" : typeof v}`
|
|
652
|
+
].join("\n")
|
|
642
653
|
);
|
|
643
654
|
}
|
|
644
|
-
|
|
645
|
-
|
|
655
|
+
);
|
|
656
|
+
if (processHandlers.length > 0) {
|
|
657
|
+
configsManager2.registerHandlers(processName, ...processHandlers);
|
|
646
658
|
}
|
|
647
659
|
}
|
|
648
660
|
const rootContext = { "fsm:launch": launch };
|
|
@@ -651,16 +663,31 @@ async function launcher(options) {
|
|
|
651
663
|
if (typeof config !== "object" || !config) {
|
|
652
664
|
throw new Error("Invalid launcher configuration");
|
|
653
665
|
}
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
666
|
+
const processes = asArray(
|
|
667
|
+
config.processes ?? config.process ?? config.default,
|
|
668
|
+
(v) => {
|
|
669
|
+
if (typeof v === "function") {
|
|
670
|
+
return {
|
|
671
|
+
name: v.name || "",
|
|
672
|
+
handler: v
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
if (typeof v !== "object") {
|
|
676
|
+
throw new Error(
|
|
677
|
+
"Invalid launcher configuration: process is not an object"
|
|
678
|
+
);
|
|
679
|
+
}
|
|
680
|
+
return v;
|
|
681
|
+
}
|
|
682
|
+
);
|
|
659
683
|
for (const process of processes) {
|
|
660
684
|
registerProcess(configsManager, process);
|
|
661
685
|
}
|
|
662
686
|
const shutdowns = [];
|
|
663
|
-
|
|
687
|
+
let startProcesses = asArray(config.start);
|
|
688
|
+
if (startProcesses.length === 0) {
|
|
689
|
+
startProcesses = processes.map((p) => p.name).filter(Boolean);
|
|
690
|
+
}
|
|
664
691
|
let initContext = (context) => context;
|
|
665
692
|
const configContext = config.context ?? config.init;
|
|
666
693
|
if (configContext) {
|
package/package.json
CHANGED
|
@@ -6,26 +6,40 @@ import type { StageHandler } from "./types.ts";
|
|
|
6
6
|
export type ProcessConfig = {
|
|
7
7
|
name: string;
|
|
8
8
|
config?: FsmStateConfig;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
9
|
+
} & (
|
|
10
|
+
| {
|
|
11
|
+
handler?: StageHandler;
|
|
12
|
+
}
|
|
13
|
+
| {
|
|
14
|
+
handlers?:
|
|
15
|
+
| StageHandler
|
|
16
|
+
| (
|
|
17
|
+
| StageHandler
|
|
18
|
+
| {
|
|
19
|
+
[state: string]: StageHandler | StageHandler[];
|
|
20
|
+
}
|
|
21
|
+
)[];
|
|
22
|
+
}
|
|
23
|
+
| {
|
|
24
|
+
default?:
|
|
25
|
+
| StageHandler
|
|
26
|
+
| (
|
|
27
|
+
| StageHandler
|
|
28
|
+
| {
|
|
29
|
+
[state: string]: StageHandler | StageHandler[];
|
|
30
|
+
}
|
|
31
|
+
)[];
|
|
32
|
+
}
|
|
33
|
+
);
|
|
21
34
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
35
|
+
function asArray<T>(
|
|
36
|
+
value: T | T[] | undefined,
|
|
37
|
+
filter: (v: T, idx: number) => T | undefined = (v) => v,
|
|
38
|
+
): T[] {
|
|
39
|
+
if (value === undefined) return [];
|
|
40
|
+
const array = Array.isArray(value) ? value : [value];
|
|
41
|
+
return array.filter(Boolean).map(filter).filter(Boolean) as T[];
|
|
42
|
+
}
|
|
29
43
|
|
|
30
44
|
export async function launcher(options: unknown) {
|
|
31
45
|
const configsManager = new ProcessConfigManager();
|
|
@@ -42,7 +56,7 @@ export async function launcher(options: unknown) {
|
|
|
42
56
|
|
|
43
57
|
function registerProcess(
|
|
44
58
|
configsManager: ProcessConfigManager,
|
|
45
|
-
process:
|
|
59
|
+
process: Record<string, unknown>,
|
|
46
60
|
) {
|
|
47
61
|
if (!process || typeof process !== "object") {
|
|
48
62
|
throw new Error("Invalid process configuration: not an object");
|
|
@@ -52,26 +66,32 @@ export async function launcher(options: unknown) {
|
|
|
52
66
|
throw new Error("Invalid process configuration: missing or invalid name");
|
|
53
67
|
}
|
|
54
68
|
|
|
55
|
-
const processConfig = process.config;
|
|
69
|
+
const processConfig = process.config as FsmStateConfig | undefined;
|
|
56
70
|
if (processConfig && typeof processConfig !== "object") {
|
|
57
71
|
throw new Error(
|
|
58
72
|
`Invalid process configuration: config is not an object in process ${process.name}`,
|
|
59
73
|
);
|
|
60
74
|
}
|
|
61
75
|
if (processConfig) {
|
|
62
|
-
configsManager.registerConfig(
|
|
76
|
+
configsManager.registerConfig(processName, processConfig);
|
|
63
77
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
78
|
+
|
|
79
|
+
const processHandlers = asArray(
|
|
80
|
+
process.handlers ?? process.handler ?? process.default,
|
|
81
|
+
(v, idx) => {
|
|
82
|
+
if (typeof v === "function") return v;
|
|
83
|
+
if (typeof v === "object" && v !== null) return v;
|
|
67
84
|
throw new Error(
|
|
68
|
-
|
|
85
|
+
[
|
|
86
|
+
`Invalid process configuration:`,
|
|
87
|
+
`a process handler is not object nor function in process ${processName} at index ${idx}`,
|
|
88
|
+
`Recieved: ${v === null ? "null" : typeof v}`,
|
|
89
|
+
].join("\n"),
|
|
69
90
|
);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
configsManager.registerHandlers(process.name, ...processHandlers);
|
|
91
|
+
},
|
|
92
|
+
);
|
|
93
|
+
if (processHandlers.length > 0) {
|
|
94
|
+
configsManager.registerHandlers(processName, ...processHandlers);
|
|
75
95
|
}
|
|
76
96
|
}
|
|
77
97
|
|
|
@@ -81,21 +101,37 @@ export async function launcher(options: unknown) {
|
|
|
81
101
|
if (typeof config !== "object" || !config) {
|
|
82
102
|
throw new Error("Invalid launcher configuration");
|
|
83
103
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
104
|
+
|
|
105
|
+
const processes = asArray(
|
|
106
|
+
config.processes ?? config.process ?? config.default,
|
|
107
|
+
(v) => {
|
|
108
|
+
if (typeof v === "function") {
|
|
109
|
+
return {
|
|
110
|
+
name: v.name || "",
|
|
111
|
+
handler: v,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
if (typeof v !== "object") {
|
|
115
|
+
throw new Error(
|
|
116
|
+
"Invalid launcher configuration: process is not an object",
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
return v;
|
|
120
|
+
},
|
|
121
|
+
);
|
|
89
122
|
for (const process of processes) {
|
|
90
123
|
registerProcess(configsManager, process);
|
|
91
124
|
}
|
|
92
125
|
|
|
93
126
|
const shutdowns: (() => Promise<void>)[] = [];
|
|
94
|
-
|
|
127
|
+
let startProcesses = asArray<string>(config.start);
|
|
128
|
+
if (startProcesses.length === 0) {
|
|
129
|
+
startProcesses = processes.map((p) => p.name).filter(Boolean) as string[];
|
|
130
|
+
}
|
|
131
|
+
|
|
95
132
|
let initContext: (
|
|
96
133
|
parent: Record<string, unknown>,
|
|
97
134
|
) => Record<string, unknown> = (context) => context;
|
|
98
|
-
|
|
99
135
|
const configContext = config.context ?? config.init;
|
|
100
136
|
if (configContext) {
|
|
101
137
|
if (typeof configContext === "function") {
|