@statewalker/fsm 0.20.2 → 0.21.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/context/index.d.ts +23 -0
- package/dist/context/index.js +78 -0
- package/dist/index.d.ts +2 -20
- package/dist/index.js +15 -77
- package/package.json +3 -4
- package/src/FsmBaseClass.ts +4 -2
- package/src/FsmProcess.ts +12 -6
- package/src/context/handlers.ts +1 -1
- package/src/context/printer.ts +7 -7
- package/src/context/tracer.ts +2 -2
- package/src/index.ts +0 -1
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { FsmState, FsmStateHandler, FsmProcess } from '../index.js';
|
|
2
|
+
|
|
3
|
+
declare const KEY_HANDLERS = "handlers";
|
|
4
|
+
declare function callStateHandlers(state: FsmState): void;
|
|
5
|
+
declare function addSubstateHandlers(state: FsmState, handlers: Record<string, FsmStateHandler>): void;
|
|
6
|
+
|
|
7
|
+
type Printer = (...args: any[]) => void;
|
|
8
|
+
type PrinterConfig = {
|
|
9
|
+
prefix?: string;
|
|
10
|
+
print?: (...args: any[]) => void;
|
|
11
|
+
lineNumbers?: boolean;
|
|
12
|
+
};
|
|
13
|
+
declare const KEY_PRINTER = "printer";
|
|
14
|
+
declare function preparePrinter(process: FsmProcess, { prefix, print, lineNumbers }: PrinterConfig): Printer;
|
|
15
|
+
declare function setPrinter(state: FsmState, config?: PrinterConfig): void;
|
|
16
|
+
declare function setProcessPrinter(process: FsmProcess, config?: PrinterConfig): void;
|
|
17
|
+
declare function getProcessPrinter(process: FsmProcess): Printer;
|
|
18
|
+
declare function getPrinter(state: FsmState): Printer;
|
|
19
|
+
|
|
20
|
+
declare function setProcessTracer(process: FsmProcess, print?: Printer): () => void;
|
|
21
|
+
declare function setStateTracer(state: FsmState, print?: Printer): void;
|
|
22
|
+
|
|
23
|
+
export { KEY_HANDLERS, KEY_PRINTER, type Printer, type PrinterConfig, addSubstateHandlers, callStateHandlers, getPrinter, getProcessPrinter, preparePrinter, setPrinter, setProcessPrinter, setProcessTracer, setStateTracer };
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// src/context/handlers.ts
|
|
2
|
+
var KEY_HANDLERS = "handlers";
|
|
3
|
+
function callStateHandlers(state) {
|
|
4
|
+
const key = state.key;
|
|
5
|
+
for (let parent = state.parent; !!parent; parent = parent?.parent) {
|
|
6
|
+
const handlers = parent.getData(KEY_HANDLERS)?.[key];
|
|
7
|
+
handlers?.forEach((handler) => handler(state));
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
function addSubstateHandlers(state, handlers) {
|
|
11
|
+
const oldIndex = state.getData(KEY_HANDLERS);
|
|
12
|
+
const index = oldIndex ? { ...oldIndex } : {};
|
|
13
|
+
for (const [key, handler] of Object.entries(handlers)) {
|
|
14
|
+
const list = index[key] = index[key] || [];
|
|
15
|
+
list.push(handler);
|
|
16
|
+
}
|
|
17
|
+
state.setData(KEY_HANDLERS, index);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// src/context/printer.ts
|
|
21
|
+
var KEY_PRINTER = "printer";
|
|
22
|
+
function preparePrinter(process, { prefix = "", print = console.log, lineNumbers = false }) {
|
|
23
|
+
let lineCounter = 0;
|
|
24
|
+
const shift = () => {
|
|
25
|
+
let prefix2 = "";
|
|
26
|
+
for (let s = process.state?.parent; !!s; s = s.parent) {
|
|
27
|
+
prefix2 += " ";
|
|
28
|
+
}
|
|
29
|
+
return prefix2;
|
|
30
|
+
};
|
|
31
|
+
const getPrefix = lineNumbers ? () => `[${++lineCounter}]${shift()}` : shift;
|
|
32
|
+
const printer = (...args) => print(prefix, getPrefix(), ...args);
|
|
33
|
+
return printer;
|
|
34
|
+
}
|
|
35
|
+
function setPrinter(state, config = {}) {
|
|
36
|
+
const printer = preparePrinter(state.process, config);
|
|
37
|
+
state.setData(KEY_PRINTER, printer);
|
|
38
|
+
}
|
|
39
|
+
function setProcessPrinter(process, config = {}) {
|
|
40
|
+
const printer = preparePrinter(process, config);
|
|
41
|
+
process.setData(KEY_PRINTER, printer);
|
|
42
|
+
}
|
|
43
|
+
function getProcessPrinter(process) {
|
|
44
|
+
return process.getData(KEY_PRINTER) || console.log;
|
|
45
|
+
}
|
|
46
|
+
function getPrinter(state) {
|
|
47
|
+
return state.getData(KEY_PRINTER, true) || getProcessPrinter(state.process);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// src/context/tracer.ts
|
|
51
|
+
function setProcessTracer(process, print) {
|
|
52
|
+
return process.onStateCreate((state) => {
|
|
53
|
+
setStateTracer(state, print);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
function setStateTracer(state, print) {
|
|
57
|
+
state.onEnter(() => {
|
|
58
|
+
const printLine = print || getPrinter(state);
|
|
59
|
+
printLine(`<${state?.key} event="${state.process.event}">`);
|
|
60
|
+
});
|
|
61
|
+
state.onExit(() => {
|
|
62
|
+
const printLine = print || getPrinter(state);
|
|
63
|
+
printLine(`</${state.key}> <!-- event="${state.process.event}" -->`);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
export {
|
|
67
|
+
KEY_HANDLERS,
|
|
68
|
+
KEY_PRINTER,
|
|
69
|
+
addSubstateHandlers,
|
|
70
|
+
callStateHandlers,
|
|
71
|
+
getPrinter,
|
|
72
|
+
getProcessPrinter,
|
|
73
|
+
preparePrinter,
|
|
74
|
+
setPrinter,
|
|
75
|
+
setProcessPrinter,
|
|
76
|
+
setProcessTracer,
|
|
77
|
+
setStateTracer
|
|
78
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -77,6 +77,7 @@ declare class FsmProcess extends FsmBaseClass {
|
|
|
77
77
|
config: FsmStateConfig;
|
|
78
78
|
rootDescriptor: FsmStateDescriptor;
|
|
79
79
|
constructor(config: FsmStateConfig);
|
|
80
|
+
shutdown(event?: string): Promise<void>;
|
|
80
81
|
dispatch(event: string, mask?: number): Promise<boolean>;
|
|
81
82
|
dump(...args: unknown[]): Promise<FsmProcessDump>;
|
|
82
83
|
restore(dump: FsmProcessDump, ...args: unknown[]): Promise<this>;
|
|
@@ -89,23 +90,4 @@ declare class FsmProcess extends FsmBaseClass {
|
|
|
89
90
|
_update(): boolean;
|
|
90
91
|
}
|
|
91
92
|
|
|
92
|
-
|
|
93
|
-
declare function callStateHandlers(state: FsmState): void;
|
|
94
|
-
declare function addSubstateHandlers(state: FsmState, handlers: Record<string, FsmStateHandler>): void;
|
|
95
|
-
|
|
96
|
-
type Printer = (...args: any[]) => void;
|
|
97
|
-
type PrinterConfig = {
|
|
98
|
-
prefix?: string;
|
|
99
|
-
print?: (...args: any[]) => void;
|
|
100
|
-
lineNumbers?: boolean;
|
|
101
|
-
};
|
|
102
|
-
declare const KEY_PRINTER = "printer";
|
|
103
|
-
declare function preparePrinter(process: FsmProcess, { prefix, print, lineNumbers }: PrinterConfig): Printer;
|
|
104
|
-
declare function setPrinter(state: FsmState, config?: PrinterConfig): void;
|
|
105
|
-
declare function setProcessPrinter(process: FsmProcess, config?: PrinterConfig): void;
|
|
106
|
-
declare function getPrinter(state: FsmState): Printer;
|
|
107
|
-
|
|
108
|
-
declare function setProcessTracer(process: FsmProcess, print?: Printer): () => void;
|
|
109
|
-
declare function setStateTracer(state: FsmState, print?: Printer): void;
|
|
110
|
-
|
|
111
|
-
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 FsmStateSyncHandler, KEY_HANDLERS, KEY_PRINTER, type Printer, type PrinterConfig, STATE_ANY, STATE_FINAL, STATE_INITIAL, STATUS_ENTER, STATUS_EXIT, STATUS_FINISHED, STATUS_FIRST, STATUS_LAST, STATUS_LEAF, STATUS_NEXT, STATUS_NONE, addSubstateHandlers, callStateHandlers, getPrinter, preparePrinter, setPrinter, setProcessPrinter, setProcessTracer, setStateTracer };
|
|
93
|
+
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 FsmStateSyncHandler, STATE_ANY, STATE_FINAL, STATE_INITIAL, STATUS_ENTER, STATUS_EXIT, STATUS_FINISHED, STATUS_FIRST, STATUS_LAST, STATUS_LEAF, STATUS_NEXT, STATUS_NONE };
|
package/dist/index.js
CHANGED
|
@@ -9,9 +9,11 @@ function bindMethods(obj, ...methods) {
|
|
|
9
9
|
|
|
10
10
|
// src/FsmBaseClass.ts
|
|
11
11
|
var FsmBaseClass = class {
|
|
12
|
-
handlers
|
|
13
|
-
data
|
|
12
|
+
handlers;
|
|
13
|
+
data;
|
|
14
14
|
constructor() {
|
|
15
|
+
this.handlers = {};
|
|
16
|
+
this.data = {};
|
|
15
17
|
bindMethods(this, "setData", "getData");
|
|
16
18
|
}
|
|
17
19
|
setData(key, value) {
|
|
@@ -163,15 +165,24 @@ var STATUS_EXIT = STATUS_LEAF | STATUS_LAST;
|
|
|
163
165
|
var FsmProcess = class extends FsmBaseClass {
|
|
164
166
|
state;
|
|
165
167
|
event;
|
|
166
|
-
status
|
|
168
|
+
status;
|
|
167
169
|
config;
|
|
168
170
|
rootDescriptor;
|
|
169
171
|
constructor(config) {
|
|
170
172
|
super();
|
|
173
|
+
this.status = 0;
|
|
171
174
|
this.rootDescriptor = FsmStateDescriptor.build(config);
|
|
172
175
|
this.config = config;
|
|
173
176
|
bindMethods(this, "dispatch", "dump", "restore");
|
|
174
177
|
}
|
|
178
|
+
async shutdown(event) {
|
|
179
|
+
while (this.state) {
|
|
180
|
+
this.event = event;
|
|
181
|
+
this.status = STATUS_FINISHED;
|
|
182
|
+
await this.state?._runHandler("onExit", this.state);
|
|
183
|
+
this.state = this.state.parent;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
175
186
|
async dispatch(event, mask = STATUS_LEAF) {
|
|
176
187
|
this.event = event;
|
|
177
188
|
while (true) {
|
|
@@ -272,77 +283,12 @@ var FsmProcess = class extends FsmBaseClass {
|
|
|
272
283
|
return !(this.status & STATUS_FINISHED);
|
|
273
284
|
}
|
|
274
285
|
};
|
|
275
|
-
|
|
276
|
-
// src/context/handlers.ts
|
|
277
|
-
var KEY_HANDLERS = "handlers";
|
|
278
|
-
function callStateHandlers(state) {
|
|
279
|
-
const key = state.key;
|
|
280
|
-
for (let parent = state.parent; !!parent; parent = parent?.parent) {
|
|
281
|
-
const handlers = parent.getData(KEY_HANDLERS)?.[key];
|
|
282
|
-
handlers?.forEach((handler) => handler(state));
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
function addSubstateHandlers(state, handlers) {
|
|
286
|
-
const oldIndex = state.getData(KEY_HANDLERS);
|
|
287
|
-
const index = oldIndex ? { ...oldIndex } : {};
|
|
288
|
-
for (const [key, handler] of Object.entries(handlers)) {
|
|
289
|
-
const list = index[key] = index[key] || [];
|
|
290
|
-
list.push(handler);
|
|
291
|
-
}
|
|
292
|
-
state.setData(KEY_HANDLERS, index);
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
// src/context/printer.ts
|
|
296
|
-
var KEY_PRINTER = "printer";
|
|
297
|
-
function preparePrinter(process, { prefix = "", print = console.log, lineNumbers = false }) {
|
|
298
|
-
let lineCounter = 0;
|
|
299
|
-
const shift = () => {
|
|
300
|
-
let prefix2 = "";
|
|
301
|
-
for (let s = process.state?.parent; !!s; s = s.parent) {
|
|
302
|
-
prefix2 += " ";
|
|
303
|
-
}
|
|
304
|
-
return prefix2;
|
|
305
|
-
};
|
|
306
|
-
const getPrefix = lineNumbers ? () => `[${++lineCounter}]${shift()}` : shift;
|
|
307
|
-
const printer = (...args) => print(prefix, getPrefix(), ...args);
|
|
308
|
-
return printer;
|
|
309
|
-
}
|
|
310
|
-
function setPrinter(state, config = {}) {
|
|
311
|
-
const printer = preparePrinter(state.process, config);
|
|
312
|
-
state.setData(KEY_PRINTER, printer);
|
|
313
|
-
}
|
|
314
|
-
function setProcessPrinter(process, config = {}) {
|
|
315
|
-
const printer = preparePrinter(process, config);
|
|
316
|
-
process.setData(KEY_PRINTER, printer);
|
|
317
|
-
}
|
|
318
|
-
function getPrinter(state) {
|
|
319
|
-
return state.getData(KEY_PRINTER, true) || state.process.getData(KEY_PRINTER) || console.log;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
// src/context/tracer.ts
|
|
323
|
-
function setProcessTracer(process, print) {
|
|
324
|
-
return process.onStateCreate((state) => {
|
|
325
|
-
setStateTracer(state, print);
|
|
326
|
-
});
|
|
327
|
-
}
|
|
328
|
-
function setStateTracer(state, print) {
|
|
329
|
-
state.onEnter(() => {
|
|
330
|
-
const printLine = print || getPrinter(state);
|
|
331
|
-
printLine(`<${state?.key} event="${state.process.event}">`);
|
|
332
|
-
});
|
|
333
|
-
state.onExit(() => {
|
|
334
|
-
const printLine = print || getPrinter(state);
|
|
335
|
-
printLine(`</${state.key}> <!-- event="${state.process.event}" -->`);
|
|
336
|
-
});
|
|
337
|
-
}
|
|
338
286
|
export {
|
|
339
287
|
EVENT_ANY,
|
|
340
288
|
EVENT_EMPTY,
|
|
341
289
|
FsmProcess,
|
|
342
290
|
FsmState,
|
|
343
291
|
FsmStateDescriptor,
|
|
344
|
-
KEY_HANDLERS,
|
|
345
|
-
KEY_PRINTER,
|
|
346
292
|
STATE_ANY,
|
|
347
293
|
STATE_FINAL,
|
|
348
294
|
STATE_INITIAL,
|
|
@@ -353,13 +299,5 @@ export {
|
|
|
353
299
|
STATUS_LAST,
|
|
354
300
|
STATUS_LEAF,
|
|
355
301
|
STATUS_NEXT,
|
|
356
|
-
STATUS_NONE
|
|
357
|
-
addSubstateHandlers,
|
|
358
|
-
callStateHandlers,
|
|
359
|
-
getPrinter,
|
|
360
|
-
preparePrinter,
|
|
361
|
-
setPrinter,
|
|
362
|
-
setProcessPrinter,
|
|
363
|
-
setProcessTracer,
|
|
364
|
-
setStateTracer
|
|
302
|
+
STATUS_NONE
|
|
365
303
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@statewalker/fsm",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"description": "HFSM Implementation",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"homepage": "https://github.com/statewalker/statewalker-fsm",
|
|
@@ -20,9 +20,8 @@
|
|
|
20
20
|
"unpkg": "./dist/index.js",
|
|
21
21
|
"types": "./dist/index.d.ts",
|
|
22
22
|
"exports": {
|
|
23
|
-
".":
|
|
24
|
-
|
|
25
|
-
}
|
|
23
|
+
".": "./dist/index.js",
|
|
24
|
+
"./context": "./dist/context/index.js"
|
|
26
25
|
},
|
|
27
26
|
"devDependencies": {
|
|
28
27
|
"@changesets/cli": "^2.27.7",
|
package/src/FsmBaseClass.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { bindMethods } from "./utils/bindMethods.ts";
|
|
2
2
|
|
|
3
3
|
export class FsmBaseClass {
|
|
4
|
-
handlers: Record<string, Function[]
|
|
5
|
-
data: Record<string, unknown
|
|
4
|
+
handlers: Record<string, Function[]>;
|
|
5
|
+
data: Record<string, unknown>;
|
|
6
6
|
constructor() {
|
|
7
|
+
this.handlers = {};
|
|
8
|
+
this.data = {};
|
|
7
9
|
bindMethods(this, "setData", "getData");
|
|
8
10
|
}
|
|
9
11
|
setData<T>(key: string, value: T) {
|
package/src/FsmProcess.ts
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import { bindMethods } from "./utils/bindMethods.ts";
|
|
2
2
|
import { FsmBaseClass } from "./FsmBaseClass.ts";
|
|
3
|
-
import {
|
|
4
|
-
FsmState,
|
|
5
|
-
FsmStateDump,
|
|
6
|
-
FsmStateSyncHandler,
|
|
7
|
-
} from "./FsmState.ts";
|
|
3
|
+
import { FsmState, FsmStateDump, FsmStateSyncHandler } from "./FsmState.ts";
|
|
8
4
|
import {
|
|
9
5
|
EVENT_EMPTY,
|
|
10
6
|
FsmStateConfig,
|
|
@@ -43,17 +39,27 @@ export type FsmProcessDumpHandler = (
|
|
|
43
39
|
export class FsmProcess extends FsmBaseClass {
|
|
44
40
|
state?: FsmState;
|
|
45
41
|
event?: string;
|
|
46
|
-
status: number
|
|
42
|
+
status: number;
|
|
47
43
|
config: FsmStateConfig;
|
|
48
44
|
rootDescriptor: FsmStateDescriptor;
|
|
49
45
|
|
|
50
46
|
constructor(config: FsmStateConfig) {
|
|
51
47
|
super();
|
|
48
|
+
this.status = 0;
|
|
52
49
|
this.rootDescriptor = FsmStateDescriptor.build(config);
|
|
53
50
|
this.config = config;
|
|
54
51
|
bindMethods(this, "dispatch", "dump", "restore");
|
|
55
52
|
}
|
|
56
53
|
|
|
54
|
+
async shutdown(event?: string) {
|
|
55
|
+
while (this.state) {
|
|
56
|
+
this.event = event;
|
|
57
|
+
this.status = STATUS_FINISHED;
|
|
58
|
+
await this.state?._runHandler("onExit", this.state);
|
|
59
|
+
this.state = this.state.parent;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
57
63
|
async dispatch(event: string, mask: number = STATUS_LEAF) {
|
|
58
64
|
this.event = event;
|
|
59
65
|
while (true) {
|
package/src/context/handlers.ts
CHANGED
package/src/context/printer.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import type { FsmProcess } from "../FsmProcess.ts";
|
|
2
|
+
import type { FsmState } from "../FsmState.ts";
|
|
3
3
|
export type Printer = (...args: any[]) => void;
|
|
4
4
|
export type PrinterConfig = {
|
|
5
5
|
prefix?: string;
|
|
@@ -39,10 +39,10 @@ export function setProcessPrinter(
|
|
|
39
39
|
process.setData(KEY_PRINTER, printer);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
export function getProcessPrinter(process: FsmProcess): Printer {
|
|
43
|
+
return process.getData(KEY_PRINTER) || console.log;
|
|
44
|
+
}
|
|
45
|
+
|
|
42
46
|
export function getPrinter(state: FsmState): Printer {
|
|
43
|
-
return (
|
|
44
|
-
state.getData(KEY_PRINTER, true) ||
|
|
45
|
-
state.process.getData(KEY_PRINTER) ||
|
|
46
|
-
console.log
|
|
47
|
-
);
|
|
47
|
+
return state.getData(KEY_PRINTER, true) || getProcessPrinter(state.process);
|
|
48
48
|
}
|
package/src/context/tracer.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { FsmProcess } from "../FsmProcess.ts";
|
|
2
|
-
import { FsmState } from "../FsmState.ts";
|
|
1
|
+
import type { FsmProcess } from "../FsmProcess.ts";
|
|
2
|
+
import type { FsmState } from "../FsmState.ts";
|
|
3
3
|
import { getPrinter, type Printer } from "./printer.ts";
|
|
4
4
|
|
|
5
5
|
export function setProcessTracer(process: FsmProcess, print?: Printer) {
|
package/src/index.ts
CHANGED