@statewalker/fsm 0.29.0 → 0.30.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 +170 -13
- package/dist/index.js +267 -92
- package/package.json +8 -9
- package/src/FsmBaseClass.ts +13 -6
- package/src/FsmProcess.ts +7 -3
- package/src/FsmState.ts +7 -7
- package/src/FsmStateDescriptor.ts +8 -5
- package/src/index.ts +2 -2
- package/src/newFsmProcess.ts +46 -17
- package/src/orchestrator/ProcessConfigManager.ts +70 -0
- package/src/orchestrator/constants.ts +130 -0
- package/src/orchestrator/index.ts +6 -0
- package/src/orchestrator/isGenerator.ts +12 -0
- package/src/orchestrator/launcher.ts +72 -0
- package/src/orchestrator/startFsmProcess.ts +73 -0
- package/src/orchestrator/types.ts +34 -0
- package/src/utils/handlers.ts +9 -4
- package/src/utils/newFsmStateHandler.ts +7 -3
- package/src/utils/printer.ts +1 -1
- package/src/startFsmProcess copy 2.ts +0 -74
- package/src/startFsmProcess copy.ts +0 -77
- package/src/startFsmProcess.ts +0 -78
|
@@ -7,7 +7,7 @@ export function newModuleLoader<T>(baseUrl: string) {
|
|
|
7
7
|
return (cache[path] =
|
|
8
8
|
cache[path] ||
|
|
9
9
|
(async () => {
|
|
10
|
-
const suffixes = ["/", "", ".
|
|
10
|
+
const suffixes = ["/", "", ".ts", "/index.ts"];
|
|
11
11
|
for (const suffix of suffixes) {
|
|
12
12
|
const url = new URL(path + suffix, baseUrl).pathname;
|
|
13
13
|
try {
|
|
@@ -70,7 +70,9 @@ export type FsmStateModule<
|
|
|
70
70
|
> = {
|
|
71
71
|
context?:
|
|
72
72
|
| ((...stack: FsmStateStore[]) => FsmStateContext)
|
|
73
|
-
| (new (
|
|
73
|
+
| (new (
|
|
74
|
+
...stack: FsmStateStore[]
|
|
75
|
+
) => FsmStateContext);
|
|
74
76
|
// trigger?: (context: FsmStateContext) => AsyncGenerator<string>;
|
|
75
77
|
trigger?: (context: FsmStateContext) => AsyncIterator<string>;
|
|
76
78
|
handler?: (
|
|
@@ -97,7 +99,9 @@ function isFunction<T extends Array<unknown>, R = unknown>(
|
|
|
97
99
|
}
|
|
98
100
|
function isClass<T extends Array<unknown>, R = unknown>(
|
|
99
101
|
value: unknown,
|
|
100
|
-
): value is new (
|
|
102
|
+
): value is new (
|
|
103
|
+
...args: T
|
|
104
|
+
) => R {
|
|
101
105
|
if (!isFunction(value)) return false;
|
|
102
106
|
return value?.prototype?.constructor?.toString().match(/^class/);
|
|
103
107
|
}
|
package/src/utils/printer.ts
CHANGED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import type { FsmStateConfig } from "./FsmStateConfig.js";
|
|
2
|
-
import { type Module, newFsmProcess } from "./newFsmProcess.js";
|
|
3
|
-
|
|
4
|
-
export type ModuleOrTrigger<C = unknown> =
|
|
5
|
-
| Module<C>
|
|
6
|
-
| AsyncGenerator<string, void, unknown>
|
|
7
|
-
| Generator<string, void, unknown>;
|
|
8
|
-
export function startFsmProcess<C>(
|
|
9
|
-
context: C,
|
|
10
|
-
config: FsmStateConfig,
|
|
11
|
-
load: (
|
|
12
|
-
state: string,
|
|
13
|
-
event: undefined | string,
|
|
14
|
-
) =>
|
|
15
|
-
| undefined
|
|
16
|
-
| ModuleOrTrigger<C>
|
|
17
|
-
| ModuleOrTrigger<C>[]
|
|
18
|
-
| Promise<undefined | ModuleOrTrigger<C> | ModuleOrTrigger<C>[]>,
|
|
19
|
-
startEvent = "",
|
|
20
|
-
) {
|
|
21
|
-
function validateModule(
|
|
22
|
-
module: ModuleOrTrigger<C> | undefined,
|
|
23
|
-
): Module<C> | undefined {
|
|
24
|
-
if (module === undefined) {
|
|
25
|
-
return undefined;
|
|
26
|
-
}
|
|
27
|
-
if (isGeneratorFunction<string, [C]>(module)) {
|
|
28
|
-
const generator = module as (context: C) => AsyncGenerator<string>;
|
|
29
|
-
return async (context: C) => {
|
|
30
|
-
const iterator = generator(context);
|
|
31
|
-
console.warn('INIT', module, iterator);
|
|
32
|
-
(async () => {
|
|
33
|
-
for await (const event of iterator) {
|
|
34
|
-
await dispatch(event);
|
|
35
|
-
}
|
|
36
|
-
})();
|
|
37
|
-
return () => {
|
|
38
|
-
console.warn('DONE', module, iterator);
|
|
39
|
-
iterator.return?.(void 0);
|
|
40
|
-
};
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
return module as Module<C>;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const [dispatch, terminate] = newFsmProcess(
|
|
47
|
-
context,
|
|
48
|
-
config,
|
|
49
|
-
async (state, event) => {
|
|
50
|
-
const modules = (await load(state, event)) ?? [];
|
|
51
|
-
const modulesList = Array.isArray(modules) ? modules : [modules];
|
|
52
|
-
return modulesList
|
|
53
|
-
.map(validateModule)
|
|
54
|
-
.flat()
|
|
55
|
-
.filter(Boolean) as Module<C>[];
|
|
56
|
-
},
|
|
57
|
-
);
|
|
58
|
-
dispatch(startEvent);
|
|
59
|
-
return terminate;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const AsyncGeneratorFunction = async function* () {}.constructor;
|
|
63
|
-
const GeneratorFunction = function* () {}.constructor;
|
|
64
|
-
|
|
65
|
-
function isGeneratorFunction<T, P extends unknown[] = []>(
|
|
66
|
-
value: unknown,
|
|
67
|
-
): value is
|
|
68
|
-
| ((...args: P) => AsyncGenerator<T>)
|
|
69
|
-
| ((...args: P) => Generator<T>) {
|
|
70
|
-
return (
|
|
71
|
-
value instanceof AsyncGeneratorFunction ||
|
|
72
|
-
value instanceof GeneratorFunction
|
|
73
|
-
);
|
|
74
|
-
}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { FsmProcess } from "./FsmProcess.js";
|
|
2
|
-
import type { FsmStateConfig } from "./FsmStateConfig.js";
|
|
3
|
-
import { isStateTransitionEnabled } from "./utils/transitions.js";
|
|
4
|
-
|
|
5
|
-
export type Module<C = unknown> = (
|
|
6
|
-
context: C,
|
|
7
|
-
) =>
|
|
8
|
-
| void
|
|
9
|
-
| (() => void | Promise<void>)
|
|
10
|
-
| Promise<void | (() => void | Promise<void>)>
|
|
11
|
-
| AsyncGenerator<string, void, unknown>
|
|
12
|
-
| Generator<string, void, unknown>;
|
|
13
|
-
|
|
14
|
-
export function startFsmProcess<C>(
|
|
15
|
-
context: C,
|
|
16
|
-
config: FsmStateConfig,
|
|
17
|
-
load: (
|
|
18
|
-
state: string,
|
|
19
|
-
event: undefined | string,
|
|
20
|
-
) =>
|
|
21
|
-
| undefined
|
|
22
|
-
| Module<C>
|
|
23
|
-
| Module<C>[]
|
|
24
|
-
| Promise<undefined | Module<C> | Module<C>[]>,
|
|
25
|
-
startEvent = ""
|
|
26
|
-
): () => Promise<void> {
|
|
27
|
-
let started = false;
|
|
28
|
-
let terminated = false;
|
|
29
|
-
const process = new FsmProcess(config);
|
|
30
|
-
process.onStateCreate((state) => {
|
|
31
|
-
started = true;
|
|
32
|
-
state.onEnter(async () => {
|
|
33
|
-
const modules = (await load(state.key, process.event)) ?? [];
|
|
34
|
-
for (const module of Array.isArray(modules) ? modules : [modules]) {
|
|
35
|
-
const result = await module(context);
|
|
36
|
-
if (isGenerator(result)) {
|
|
37
|
-
state.onExit(() => {
|
|
38
|
-
result.return?.(void 0);
|
|
39
|
-
});
|
|
40
|
-
(async () => {
|
|
41
|
-
for await (const event of result) {
|
|
42
|
-
await dispatch(event);
|
|
43
|
-
}
|
|
44
|
-
})();
|
|
45
|
-
} else if (typeof result === "function") {
|
|
46
|
-
state.onExit(result);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
function isGenerator(
|
|
53
|
-
value: unknown,
|
|
54
|
-
): value is
|
|
55
|
-
| Generator<string, void, unknown>
|
|
56
|
-
| AsyncGenerator<string, void, unknown> {
|
|
57
|
-
return (
|
|
58
|
-
typeof value === "object" &&
|
|
59
|
-
value !== null &&
|
|
60
|
-
"next" in value &&
|
|
61
|
-
typeof (value as Generator<string, void, unknown>).next === "function"
|
|
62
|
-
);
|
|
63
|
-
}
|
|
64
|
-
async function dispatch(event: string): Promise<boolean> {
|
|
65
|
-
return terminated ||
|
|
66
|
-
(event !== undefined &&
|
|
67
|
-
(!started || isStateTransitionEnabled(process, event)))
|
|
68
|
-
? process.dispatch(event)
|
|
69
|
-
: false;
|
|
70
|
-
}
|
|
71
|
-
async function shutdown(): Promise<void> {
|
|
72
|
-
await process.shutdown();
|
|
73
|
-
terminated = true;
|
|
74
|
-
}
|
|
75
|
-
dispatch(startEvent);
|
|
76
|
-
return shutdown;
|
|
77
|
-
}
|
package/src/startFsmProcess.ts
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { FsmProcess } from "./FsmProcess.js";
|
|
2
|
-
import type { FsmStateConfig } from "./FsmStateConfig.js";
|
|
3
|
-
import { isStateTransitionEnabled } from "./utils/transitions.js";
|
|
4
|
-
|
|
5
|
-
export type ModuleOrTrigger<C = unknown> = (
|
|
6
|
-
context: C,
|
|
7
|
-
) =>
|
|
8
|
-
| void
|
|
9
|
-
| (() => void | Promise<void>)
|
|
10
|
-
| Promise<void | (() => void | Promise<void>)>
|
|
11
|
-
| AsyncGenerator<string, void, unknown>
|
|
12
|
-
| Generator<string, void, unknown>;
|
|
13
|
-
|
|
14
|
-
export function startFsmProcess<C>(
|
|
15
|
-
context: C,
|
|
16
|
-
config: FsmStateConfig,
|
|
17
|
-
load: (
|
|
18
|
-
state: string,
|
|
19
|
-
event: undefined | string,
|
|
20
|
-
) =>
|
|
21
|
-
| undefined
|
|
22
|
-
| ModuleOrTrigger<C>
|
|
23
|
-
| ModuleOrTrigger<C>[]
|
|
24
|
-
| Promise<undefined | ModuleOrTrigger<C> | ModuleOrTrigger<C>[]>,
|
|
25
|
-
startEvent = "",
|
|
26
|
-
): () => Promise<void> {
|
|
27
|
-
let started = false;
|
|
28
|
-
let terminated = false;
|
|
29
|
-
const process = new FsmProcess(config);
|
|
30
|
-
process.onStateCreate((state) => {
|
|
31
|
-
started = true;
|
|
32
|
-
state.onEnter(async () => {
|
|
33
|
-
const modules = (await load(state.key, process.event)) ?? [];
|
|
34
|
-
for (const module of Array.isArray(modules) ? modules : [modules]) {
|
|
35
|
-
const result = await module?.(context);
|
|
36
|
-
if (isGenerator(result)) {
|
|
37
|
-
state.onExit(() => {
|
|
38
|
-
result.return?.(void 0);
|
|
39
|
-
});
|
|
40
|
-
(async () => {
|
|
41
|
-
for await (const event of result) {
|
|
42
|
-
if (terminated) {
|
|
43
|
-
break;
|
|
44
|
-
}
|
|
45
|
-
if (
|
|
46
|
-
event !== undefined &&
|
|
47
|
-
isStateTransitionEnabled(process, event)
|
|
48
|
-
) {
|
|
49
|
-
await process.dispatch(event);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
})();
|
|
53
|
-
} else if (typeof result === "function") {
|
|
54
|
-
state.onExit(result);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
function isGenerator(
|
|
61
|
-
value: unknown,
|
|
62
|
-
): value is
|
|
63
|
-
| Generator<string, void, unknown>
|
|
64
|
-
| AsyncGenerator<string, void, unknown> {
|
|
65
|
-
return (
|
|
66
|
-
typeof value === "object" &&
|
|
67
|
-
value !== null &&
|
|
68
|
-
"next" in value &&
|
|
69
|
-
typeof (value as Generator<string, void, unknown>).next === "function"
|
|
70
|
-
);
|
|
71
|
-
}
|
|
72
|
-
async function shutdown(): Promise<void> {
|
|
73
|
-
await process.shutdown();
|
|
74
|
-
terminated = true;
|
|
75
|
-
}
|
|
76
|
-
process.dispatch(startEvent);
|
|
77
|
-
return shutdown;
|
|
78
|
-
}
|