@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.
@@ -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
- declare const KEY_HANDLERS = "handlers";
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 = 0;
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.20.2",
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
- "import": "./src/index.ts"
25
- }
23
+ ".": "./dist/index.js",
24
+ "./context": "./dist/context/index.js"
26
25
  },
27
26
  "devDependencies": {
28
27
  "@changesets/cli": "^2.27.7",
@@ -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 = 0;
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) {
@@ -1,4 +1,4 @@
1
- import { FsmState, FsmStateHandler } from "../FsmState.ts";
1
+ import type { FsmState, FsmStateHandler } from "../FsmState.ts";
2
2
 
3
3
  export const KEY_HANDLERS = "handlers";
4
4
 
@@ -1,5 +1,5 @@
1
- import { type FsmProcess } from "../FsmProcess.ts";
2
- import { type FsmState } from "../FsmState.ts";
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
  }
@@ -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
@@ -2,4 +2,3 @@ export * from "./FsmProcess.ts";
2
2
  export * from "./FsmState.ts";
3
3
  export * from "./FsmStateConfig.ts";
4
4
  export * from "./FsmStateDescriptor.ts";
5
- export * from "./context/index.ts";