@alwatr/fsm 0.30.0 → 0.31.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/CHANGELOG.md CHANGED
@@ -3,6 +3,32 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [0.31.0](https://github.com/AliMD/alwatr/compare/v0.30.0...v0.31.0) (2023-05-08)
7
+
8
+ ### Bug Fixes
9
+
10
+ - **fms:** import path ([f6770a0](https://github.com/AliMD/alwatr/commit/f6770a07fdf6855ccd63a85822d44d5ef9c72dee))
11
+ - **fsm:** action maybe async ([50efffa](https://github.com/AliMD/alwatr/commit/50efffa34a2ea5a3515561d7425da0c109631f36))
12
+ - **fsm:** autoSignalUnsubscribe type ([f7db30b](https://github.com/AliMD/alwatr/commit/f7db30bf5a90ff3d163f036b313a412a5149ff2b))
13
+ - **fsm:** call render states function in there own this ([a950478](https://github.com/AliMD/alwatr/commit/a95047811366e375785b2cd8fb176b1176638cab))
14
+ - **fsm:** fix order of `initFsmInstance` args ([3b60138](https://github.com/AliMD/alwatr/commit/3b60138ecebcbcb4d732e4d1a3e79f5b8661ae47))
15
+ - **fsm:** initial exec actions ([e7dd5c8](https://github.com/AliMD/alwatr/commit/e7dd5c8aaf9760c9856e4392cc899020f7e796d9))
16
+ - **fsm:** last reported bugs in set state ([e7435c8](https://github.com/AliMD/alwatr/commit/e7435c870a054b0ec3e4004f13c6db7610610be0))
17
+ - **fsm:** review reset process ([af6e81c](https://github.com/AliMD/alwatr/commit/af6e81c068b467d8b3aa96f2431e13ac479f018c))
18
+ - **fsm:** run init entry actions ([777ae45](https://github.com/AliMD/alwatr/commit/777ae459f2b77f79696daf3a0ca355d6d78e57d3))
19
+ - new logger api ([9d83a7d](https://github.com/AliMD/alwatr/commit/9d83a7dc5c103bc3bb4282dacfd85fa998915300))
20
+
21
+ ### Features
22
+
23
+ - **fsm:** add `signalRecord` to config ([1a35291](https://github.com/AliMD/alwatr/commit/1a352915fba978da141513517655d1e07350c3ec))
24
+ - **fsm:** add unsubscribe ([85ed3c3](https://github.com/AliMD/alwatr/commit/85ed3c3439e1f40c2760f6011df112242f10be06))
25
+ - **fsm:** callback in provider signals ([772818b](https://github.com/AliMD/alwatr/commit/772818baa7953b6fbb4d4128fcee76733f42cc2d))
26
+ - **fsm:** custom signal callback ([47c22e9](https://github.com/AliMD/alwatr/commit/47c22e92a8a8085148b44b316d649b695ff8071a))
27
+ - **fsm:** destroy and expire api ([e1a1c15](https://github.com/AliMD/alwatr/commit/e1a1c150d81f4428718bd18f039235c7fce9caf2))
28
+ - **fsm:** new types ([2866e3b](https://github.com/AliMD/alwatr/commit/2866e3bd5ff56fd2b5bddcaed3673a5868bae4bb))
29
+ - **fsm:** rewrite state machine ([7f24695](https://github.com/AliMD/alwatr/commit/7f246959e5a80b21c1c4b21e895e75f8fbe56798))
30
+ - **fsm:** subscribe ([2af4f44](https://github.com/AliMD/alwatr/commit/2af4f44f0e8a2dee39cde10dcaa3281075632e6a))
31
+
6
32
  # [0.30.0](https://github.com/AliMD/alwatr/compare/v0.29.0...v0.30.0) (2023-03-06)
7
33
 
8
34
  ### Bug Fixes
package/README.md CHANGED
@@ -1,3 +1,3 @@
1
1
  # Alwatr Finite State Machines - `@alwatr/fsm`
2
2
 
3
- Managing invocations finite-state machines as actors written in tiny TypeScript module.
3
+ Managing invocations finite-state machines for lit-element written in tiny TypeScript module.
package/core.d.ts CHANGED
@@ -1,54 +1,158 @@
1
- import type { Stringifyable, StringifyableRecord } from '@alwatr/type';
2
- export interface MachineConfig<TState extends string, TEventId extends string, TContext extends Stringifyable> extends StringifyableRecord {
3
- /**
4
- * Machine ID (It is used in the state change signal identifier, so it must be unique).
5
- */
6
- id: string;
7
- /**
8
- * Initial state.
9
- */
10
- initial: TState;
11
- /**
12
- * Initial context.
13
- */
14
- context: TContext;
15
- /**
16
- * States list
17
- */
18
- states: {
19
- [S in TState | '$all']: {
20
- /**
21
- * An object mapping eventId (keys) to state.
22
- */
23
- on: {
24
- [E in TEventId]?: TState | '$self';
25
- };
26
- };
27
- };
28
- }
29
- export interface StateContext<TState extends string, TEventId extends string> {
30
- [T: string]: string;
31
- to: TState;
32
- from: TState | 'init';
33
- by: TEventId | 'INIT';
34
- }
35
- export declare class FiniteStateMachine<TState extends string = string, TEventId extends string = string, TContext extends StringifyableRecord = StringifyableRecord> {
36
- readonly config: Readonly<MachineConfig<TState, TEventId, TContext>>;
37
- state: StateContext<TState, TEventId>;
38
- context: TContext;
39
- signal: {
40
- readonly id: string;
41
- readonly getValue: () => StateContext<TState, TEventId> | undefined;
42
- readonly untilChange: () => Promise<StateContext<TState, TEventId>>;
43
- readonly subscribe: (listenerCallback: import("@alwatr/signal/type.js").ListenerFunction<StateContext<TState, TEventId>>, options?: Partial<import("@alwatr/signal/type.js").SubscribeOptions> | undefined) => import("@alwatr/signal").ListenerSpec;
44
- readonly unsubscribe: (listener: import("@alwatr/signal").ListenerSpec) => void;
45
- };
46
- protected _logger: import("@alwatr/logger").AlwatrLogger;
47
- protected setState(to: TState, by: TEventId | 'INIT'): void;
48
- constructor(config: Readonly<MachineConfig<TState, TEventId, TContext>>);
49
- /**
50
- * Machine transition.
51
- */
52
- transition(event: TEventId, context?: Partial<TContext>): TState | null;
53
- }
1
+ import { ListenerSpec } from '@alwatr/signal';
2
+ import { SubscribeOptions } from '@alwatr/signal/type.js';
3
+ import type { ActionRecord, FsmConstructor, FsmConstructorConfig, FsmConsumerInterface, FsmInstance, FsmState, SignalConfig } from './type.js';
4
+ import type { MaybePromise, SingleOrArray, StringifyableRecord } from '@alwatr/type';
5
+ export declare const defineConstructor: <TState extends string = string, TEventId extends string = string, TActionName extends string = string, TContext extends StringifyableRecord = StringifyableRecord>(id: string, config: FsmConstructorConfig<TState, TEventId, TActionName, TContext>) => FsmConstructorConfig<TState, TEventId, TActionName, TContext>;
6
+ /**
7
+ * Get finite state machine instance by id.
8
+ */
9
+ export declare const getFsmInstance: <TState extends string = string, TEventId extends string = string, TContext extends StringifyableRecord = StringifyableRecord>(instanceId: string) => FsmInstance<TState, TEventId, TContext>;
10
+ /**
11
+ * Get finite state machine constructor by id.
12
+ */
13
+ export declare const getFsmConstructor: (constructorId: string) => FsmConstructor;
14
+ /**
15
+ * Get current state of finite state machine instance.
16
+ */
17
+ export declare const getState: <TState extends string = string, TEventId extends string = string>(instanceId: string) => FsmState<TState, TEventId>;
18
+ /**
19
+ * Get current context of finite state machine instance.
20
+ */
21
+ export declare const getContext: <TContext extends StringifyableRecord = StringifyableRecord>(instanceId: string) => TContext;
22
+ /**
23
+ * Set context of finite state machine instance.
24
+ */
25
+ export declare const setContext: <TContext extends StringifyableRecord = StringifyableRecord>(instanceId: string, context: Partial<TContext>, notify?: boolean) => void;
26
+ /**
27
+ * Transition finite state machine instance to new state.
28
+ */
29
+ export declare const transition: <TEventId extends string = string, TContext extends StringifyableRecord = StringifyableRecord>(instanceId: string, event: TEventId, context?: Partial<TContext> | undefined) => void;
30
+ /**
31
+ * Define actions for finite state machine constructor.
32
+ */
33
+ export declare const defineActions: <T extends Readonly<{
34
+ TState: string;
35
+ TEventId: string;
36
+ TActionName: string;
37
+ TContext: StringifyableRecord;
38
+ }>>(constructorId: string, actionRecord: ActionRecord<T>) => void;
39
+ /**
40
+ * Execute all actions for current state.
41
+ */
42
+ export declare const _execAllActions: (constructor: FsmConstructor, state: FsmState, consumerInterface: FsmConsumerInterface) => void;
43
+ /**
44
+ * Execute single action.
45
+ */
46
+ export declare const _execAction: (constructor: FsmConstructor, actionNames: SingleOrArray<string> | undefined, finiteStateMachine: FsmConsumerInterface) => boolean | MaybePromise<void>;
47
+ /**
48
+ * Initialize new finite state machine instance.
49
+ */
50
+ export declare const initFsmInstance: (instanceId: string, constructorId: string) => void;
51
+ /**
52
+ * Subscribe to all defined signals for finite state machine instance.
53
+ */
54
+ export declare const subscribeSignals: (instanceId: string, signalList: Array<SignalConfig>, subscribeConstructorSignals?: boolean) => Array<ListenerSpec>;
55
+ /**
56
+ * Define signals for finite state machine constructor.
57
+ */
58
+ export declare const defineConstructorSignals: <T extends Readonly<{
59
+ TState: string;
60
+ TEventId: string;
61
+ TActionName: string;
62
+ TContext: StringifyableRecord;
63
+ }>>(constructorId: string, signalList: SignalConfig<T>[]) => void;
64
+ /**
65
+ * Define signals for finite state machine instance.
66
+ */
67
+ export declare const defineInstanceSignals: <T extends Readonly<{
68
+ TState: string;
69
+ TEventId: string;
70
+ TActionName: string;
71
+ TContext: StringifyableRecord;
72
+ }>>(instanceId: string, signalList: SignalConfig<T>[], subscribeConstructorSignals?: boolean) => Array<ListenerSpec>;
73
+ /**
74
+ * Render helper for use finite state machine instance in UI.
75
+ *
76
+ * Example:
77
+ *
78
+ * ```ts
79
+ * render('myFsm', {
80
+ * state1: () => html`<div>State 1 Render...</div>`,
81
+ * state2: () => html`<div>State 2 Render...</div>`,
82
+ * state3: 'state1',
83
+ * });
84
+ * ```
85
+ */
86
+ export declare const render: <TState extends string = string>(instanceId: string, states: { [P in TState]: TState | (() => unknown); }, thisArg?: unknown) => unknown;
87
+ /**
88
+ * Subscribe to finite state machine instance state changes.
89
+ */
90
+ export declare const subscribe: (instanceId: string, callback: () => void, options?: Partial<SubscribeOptions>) => ListenerSpec;
91
+ /**
92
+ * Destroy finite state machine instance object to clear memory.
93
+ */
94
+ export declare const destroy: (instanceId: string) => void;
95
+ /**
96
+ * Reset finite state machine instance to initial state and context.
97
+ */
98
+ export declare const reset: (instanceId: string) => void;
99
+ /**
100
+ * Finite state machine instance consumer.
101
+ * Lookup current finite state machine instance or initialize new one and return consumer object .
102
+ */
103
+ export declare const finiteStateMachineConsumer: <T extends Readonly<{
104
+ TState: string;
105
+ TEventId: string;
106
+ TActionName: string;
107
+ TContext: StringifyableRecord;
108
+ }>, TContext extends T["TContext"] = T["TContext"]>(instanceId: string, makeFromConstructor?: string) => {
109
+ /**
110
+ * Finite state machine instance id.
111
+ */
112
+ readonly id: string;
113
+ /**
114
+ * Finite state machine constructor id.
115
+ */
116
+ readonly constructorId: string;
117
+ /**
118
+ * Render helper for use finite state machine instance in UI.
119
+ */
120
+ readonly render: (states: { [P in T["TState"]]: (() => unknown) | T["TState"]; }, thisArg?: unknown) => unknown;
121
+ /**
122
+ * Subscribe to finite state machine instance state changes.
123
+ */
124
+ readonly subscribe: (callback: () => void, options?: Partial<SubscribeOptions> | undefined) => ListenerSpec;
125
+ /**
126
+ * Unsubscribe from finite state machine instance state changes.
127
+ */
128
+ readonly unsubscribe: (listener: ListenerSpec) => void;
129
+ /**
130
+ * Get current state of finite state machine instance.
131
+ */
132
+ readonly getState: () => FsmState<T["TState"], T["TEventId"]>;
133
+ /**
134
+ * Get current context of finite state machine instance.
135
+ */
136
+ readonly getContext: () => TContext;
137
+ /**
138
+ * Set context of finite state machine instance.
139
+ */
140
+ readonly setContext: (context: Partial<TContext>, notify?: boolean | undefined) => void;
141
+ /**
142
+ * Transition finite state machine instance to new state.
143
+ */
144
+ readonly transition: (event: T["TEventId"], context?: Partial<TContext> | undefined) => void;
145
+ /**
146
+ * Define signals for finite state machine instance.
147
+ */
148
+ readonly defineSignals: (signalList: SignalConfig<T>[], subscribeConstructorSignals?: boolean | undefined) => ListenerSpec[];
149
+ /**
150
+ * Reset finite state machine instance to initial state and context.
151
+ */
152
+ readonly reset: () => void;
153
+ /**
154
+ * Destroy finite state machine instance object to clear memory.
155
+ */
156
+ readonly destroy: () => void;
157
+ };
54
158
  //# sourceMappingURL=core.d.ts.map
package/core.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["src/core.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,aAAa,EAAE,mBAAmB,EAAC,MAAM,cAAc,CAAC;AAOrE,MAAM,WAAW,aAAa,CAAC,MAAM,SAAS,MAAM,EAAE,QAAQ,SAAS,MAAM,EAAE,QAAQ,SAAS,aAAa,CAC3G,SAAQ,mBAAmB;IAC3B;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,OAAO,EAAE,QAAQ,CAAC;IAElB;;OAEG;IACH,MAAM,EAAE;SACL,CAAC,IAAI,MAAM,GAAG,MAAM,GAAG;YACtB;;eAEG;YACH,EAAE,EAAE;iBACD,CAAC,IAAI,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO;aACnC,CAAC;SACH;KACF,CAAC;CACH;AAED,MAAM,WAAW,YAAY,CAAC,MAAM,SAAS,MAAM,EAAE,QAAQ,SAAS,MAAM;IAC1E,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,EAAE,EAAE,QAAQ,GAAG,MAAM,CAAC;CACvB;AAED,qBAAa,kBAAkB,CAC7B,MAAM,SAAS,MAAM,GAAG,MAAM,EAC9B,QAAQ,SAAS,MAAM,GAAG,MAAM,EAChC,QAAQ,SAAS,mBAAmB,GAAG,mBAAmB;aAqB9B,MAAM,EAAE,QAAQ,CAAC,aAAa,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAnBvF,KAAK,EAAE,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,CAInC;IACF,OAAO,WAAuB;IAC9B,MAAM;;;;;;MAAkG;IAExG,SAAS,CAAC,OAAO,wCAAgD;IAEjE,SAAS,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,GAAG,MAAM,GAAG,IAAI;gBAS/B,MAAM,EAAE,QAAQ,CAAC,aAAa,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAQvF;;OAEG;IACH,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM,GAAG,IAAI;CAoCxE"}
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["src/core.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,YAAY,EAAmC,MAAM,gBAAgB,CAAC;AAE9E,OAAO,EAAC,gBAAgB,EAAC,MAAM,wBAAwB,CAAC;AAExD,OAAO,KAAK,EACV,YAAY,EACZ,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,WAAW,EACX,QAAQ,EAER,YAAY,EACb,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAC,YAAY,EAAkB,aAAa,EAAE,mBAAmB,EAAC,MAAM,cAAc,CAAC;AAcnG,eAAO,MAAM,iBAAiB,0KAMtB,MAAM,yIAYb,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,cAAc,6IAKX,MAAM,4CAMrB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,iBAAiB,kBAAmB,MAAM,KAAG,cAKzD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,QAAQ,iFACP,MAAM,+BAInB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,UAAU,2EACT,MAAM,aAInB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,UAAU,2EACT,MAAM,uCAET,OAAO,KACf,IAWF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,UAAU,6GAIP,MAAM,+DAGjB,IAgDJ,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,aAAa;;;;;mBAA4C,MAAM,oCAAkC,IAO7G,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,gBACX,cAAc,SACpB,QAAQ,qBACI,oBAAoB,KACxC,IA0BF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,WAAW,gBACP,cAAc,eACd,cAAc,MAAM,CAAC,GAAG,SAAS,sBAC1B,oBAAoB,KACzC,OAAO,GAAG,aAAa,IAAI,CA4B7B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,eAAgB,MAAM,iBAAiB,MAAM,KAAG,IAgB3E,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,gBAAgB,eACb,MAAM,cACN,MAAM,YAAY,CAAC,4CAEhC,MAAM,YAAY,CAmCpB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,wBAAwB;;;;;mBACpB,MAAM,oCAEpB,IAIF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,qBAAqB;;;;;gBACpB,MAAM,2EAGjB,MAAM,YAAY,CAGpB,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,MAAM,+CACL,MAAM,2CACa,OAAO,gBAC7B,OAAO,KACf,OAcF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,SAAS,eACN,MAAM,YACR,MAAM,IAAI,YACV,QAAQ,gBAAgB,CAAC,KACpC,YAGF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,OAAO,eAAgB,MAAM,KAAG,IAG5C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,KAAK,eAAgB,MAAM,KAAG,IAK1C,CAAC;AAEF;;;GAGG;AAEH,eAAO,MAAM,0BAA0B;;;;;gEACzB,MAAM,wBACI,MAAM;IAc1B;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;2DAjF0B,OAAO;IAoFpC;;OAEG;yCA/Da,IAAI;IAkEpB;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;CAGN,CAAC"}
package/core.js CHANGED
@@ -1,63 +1,371 @@
1
1
  import { createLogger, globalAlwatr } from '@alwatr/logger';
2
- import { contextConsumer } from '@alwatr/signal';
3
- import { dispatch } from '@alwatr/signal/core.js';
2
+ import { contextProvider, contextConsumer } from '@alwatr/signal';
3
+ import { destroySignal, unsubscribe } from '@alwatr/signal/core.js';
4
4
  globalAlwatr.registeredList.push({
5
5
  name: '@alwatr/fsm',
6
6
  version: _ALWATR_VERSION_,
7
7
  });
8
- export class FiniteStateMachine {
9
- setState(to, by) {
10
- var _a, _b;
11
- this.state = {
12
- to,
13
- from: (_b = (_a = this.signal.getValue()) === null || _a === void 0 ? void 0 : _a.to) !== null && _b !== void 0 ? _b : 'init',
14
- by,
15
- };
16
- dispatch(this.signal.id, this.state, { debounce: 'NextCycle' });
8
+ const logger = createLogger(`alwatr/fsm`);
9
+ /**
10
+ * Finite state machine constructor storage.
11
+ */
12
+ const fsmConstructorStorage = {};
13
+ export const defineConstructor = (id, config) => {
14
+ var _a;
15
+ (_a = logger.logMethodArgs) === null || _a === void 0 ? void 0 : _a.call(logger, 'defineConstructor', { id, config });
16
+ if (fsmConstructorStorage[id] != null)
17
+ throw new Error('fsm_exist', { cause: { id } });
18
+ fsmConstructorStorage[id] = {
19
+ id,
20
+ config,
21
+ actionRecord: {},
22
+ signalList: [],
23
+ };
24
+ return config;
25
+ };
26
+ /**
27
+ * Get finite state machine instance by id.
28
+ */
29
+ export const getFsmInstance = (instanceId) => {
30
+ var _a;
31
+ (_a = logger.logMethodArgs) === null || _a === void 0 ? void 0 : _a.call(logger, '_getFsmInstance', instanceId);
32
+ const fsmInstance = contextConsumer.getValue(instanceId);
33
+ if (fsmInstance == null)
34
+ throw new Error('fsm_undefined', { cause: { instanceId } });
35
+ return fsmInstance;
36
+ };
37
+ /**
38
+ * Get finite state machine constructor by id.
39
+ */
40
+ export const getFsmConstructor = (constructorId) => {
41
+ var _a;
42
+ (_a = logger.logMethodArgs) === null || _a === void 0 ? void 0 : _a.call(logger, '_getFsmConstructor', constructorId);
43
+ const fsmConstructor = fsmConstructorStorage[constructorId];
44
+ if (fsmConstructor == null)
45
+ throw new Error('fsm_undefined', { cause: { constructorId: constructorId } });
46
+ return fsmConstructor;
47
+ };
48
+ /**
49
+ * Get current state of finite state machine instance.
50
+ */
51
+ export const getState = (instanceId) => {
52
+ var _a;
53
+ (_a = logger.logMethodArgs) === null || _a === void 0 ? void 0 : _a.call(logger, 'getState', instanceId);
54
+ return getFsmInstance(instanceId).state;
55
+ };
56
+ /**
57
+ * Get current context of finite state machine instance.
58
+ */
59
+ export const getContext = (instanceId) => {
60
+ var _a;
61
+ (_a = logger.logMethodArgs) === null || _a === void 0 ? void 0 : _a.call(logger, 'getContext', instanceId);
62
+ return getFsmInstance(instanceId).context;
63
+ };
64
+ /**
65
+ * Set context of finite state machine instance.
66
+ */
67
+ export const setContext = (instanceId, context, notify) => {
68
+ var _a;
69
+ (_a = logger.logMethodArgs) === null || _a === void 0 ? void 0 : _a.call(logger, 'setContext', { instanceId, context });
70
+ const fsmInstance = getFsmInstance(instanceId);
71
+ fsmInstance.context = {
72
+ ...fsmInstance.context,
73
+ ...context,
74
+ };
75
+ if (notify) {
76
+ contextProvider.setValue(instanceId, fsmInstance, { debounce: 'Timeout' });
17
77
  }
18
- constructor(config) {
19
- this.config = config;
20
- this.state = {
21
- to: this.config.initial,
22
- from: 'init',
23
- by: 'INIT',
78
+ };
79
+ /**
80
+ * Transition finite state machine instance to new state.
81
+ */
82
+ export const transition = (instanceId, event, context) => {
83
+ var _a, _b, _c, _d, _e, _f, _g;
84
+ const fsmInstance = getFsmInstance(instanceId);
85
+ const fsmConstructor = getFsmConstructor(fsmInstance.constructorId);
86
+ const fromState = fsmInstance.state.target;
87
+ const stateRecord = fsmConstructor.config.stateRecord;
88
+ const transitionConfig = (_b = (_a = stateRecord[fromState]) === null || _a === void 0 ? void 0 : _a.on[event]) !== null && _b !== void 0 ? _b : stateRecord.$all.on[event];
89
+ (_c = logger.logMethodArgs) === null || _c === void 0 ? void 0 : _c.call(logger, 'transition', { instanceId, fromState, event, context, target: transitionConfig === null || transitionConfig === void 0 ? void 0 : transitionConfig.target });
90
+ if (context !== undefined) {
91
+ fsmInstance.context = {
92
+ ...fsmInstance.context,
93
+ ...context,
24
94
  };
25
- this.context = this.config.context;
26
- this.signal = contextConsumer.bind('finite-state-machine-' + this.config.id);
27
- this._logger = createLogger(`alwatr/fsm:${this.config.id}`);
28
- this._logger.logMethodArgs('constructor', config);
29
- dispatch(this.signal.id, this.state, { debounce: 'NextCycle' });
30
- if (!config.states[config.initial]) {
31
- this._logger.error('constructor', 'invalid_initial_state', config);
32
- }
33
95
  }
34
- /**
35
- * Machine transition.
36
- */
37
- transition(event, context) {
38
- var _a, _b, _c, _d, _e, _f, _g;
39
- const fromState = this.state.to;
40
- let toState = (_c = (_b = (_a = this.config.states[fromState]) === null || _a === void 0 ? void 0 : _a.on) === null || _b === void 0 ? void 0 : _b[event]) !== null && _c !== void 0 ? _c : (_e = (_d = this.config.states.$all) === null || _d === void 0 ? void 0 : _d.on) === null || _e === void 0 ? void 0 : _e[event];
41
- if (toState === '$self') {
42
- toState = fromState;
43
- }
44
- this._logger.logMethodFull('transition', { fromState, event, context }, toState);
45
- if (context !== undefined) {
46
- this.context = {
47
- ...this.context,
48
- ...context,
49
- };
50
- }
51
- if (toState == null) {
52
- this._logger.incident('transition', 'invalid_target_state', 'Defined target state for this event not found in state config', {
53
- fromState,
54
- event,
55
- events: { ...(_f = this.config.states.$all) === null || _f === void 0 ? void 0 : _f.on, ...(_g = this.config.states[fromState]) === null || _g === void 0 ? void 0 : _g.on },
96
+ if (transitionConfig == null) {
97
+ (_d = logger.incident) === null || _d === void 0 ? void 0 : _d.call(logger, 'transition', 'invalid_target_state', 'Defined target state for this event not found in state config', {
98
+ fromState,
99
+ event,
100
+ events: {
101
+ ...(_e = stateRecord.$all) === null || _e === void 0 ? void 0 : _e.on,
102
+ ...(_f = stateRecord[fromState]) === null || _f === void 0 ? void 0 : _f.on,
103
+ },
104
+ });
105
+ return;
106
+ }
107
+ const consumerInterface = finiteStateMachineConsumer(instanceId);
108
+ if (transitionConfig.condition) {
109
+ if (_execAction(fsmConstructor, transitionConfig.condition, consumerInterface) === false)
110
+ return;
111
+ }
112
+ fsmInstance.state = {
113
+ target: (_g = transitionConfig.target) !== null && _g !== void 0 ? _g : fromState,
114
+ from: fromState,
115
+ by: event,
116
+ };
117
+ contextProvider.setValue(instanceId, fsmInstance, { debounce: 'Timeout' });
118
+ _execAllActions(fsmConstructor, fsmInstance.state, consumerInterface);
119
+ };
120
+ /**
121
+ * Define actions for finite state machine constructor.
122
+ */
123
+ export const defineActions = (constructorId, actionRecord) => {
124
+ var _a;
125
+ (_a = logger.logMethodArgs) === null || _a === void 0 ? void 0 : _a.call(logger, 'defineActions', { constructorId, actionRecord });
126
+ const fmsConstructor = getFsmConstructor(constructorId);
127
+ fmsConstructor.actionRecord = {
128
+ ...fmsConstructor.actionRecord,
129
+ ...actionRecord,
130
+ };
131
+ };
132
+ /**
133
+ * Execute all actions for current state.
134
+ */
135
+ export const _execAllActions = (constructor, state, consumerInterface) => {
136
+ var _a, _b, _c, _d, _e, _f, _g;
137
+ (_a = logger.logMethodArgs) === null || _a === void 0 ? void 0 : _a.call(logger, '_execAllActions', consumerInterface.id);
138
+ const stateRecord = constructor.config.stateRecord;
139
+ if (state.by === 'INIT') {
140
+ _execAction(constructor, stateRecord.$all.entry, consumerInterface);
141
+ _execAction(constructor, (_b = stateRecord[state.target]) === null || _b === void 0 ? void 0 : _b.entry, consumerInterface);
142
+ return;
143
+ }
144
+ // else
145
+ if (state.from !== state.target) {
146
+ _execAction(constructor, stateRecord.$all.exit, consumerInterface);
147
+ _execAction(constructor, (_c = stateRecord[state.from]) === null || _c === void 0 ? void 0 : _c.exit, consumerInterface);
148
+ _execAction(constructor, stateRecord.$all.entry, consumerInterface);
149
+ _execAction(constructor, (_d = stateRecord[state.target]) === null || _d === void 0 ? void 0 : _d.entry, consumerInterface);
150
+ }
151
+ _execAction(constructor, ((_e = stateRecord[state.from]) === null || _e === void 0 ? void 0 : _e.on[state.by]) != null
152
+ ? (_f = stateRecord[state.from].on[state.by]) === null || _f === void 0 ? void 0 : _f.actions
153
+ : (_g = stateRecord.$all.on[state.by]) === null || _g === void 0 ? void 0 : _g.actions, consumerInterface);
154
+ };
155
+ /**
156
+ * Execute single action.
157
+ */
158
+ export const _execAction = (constructor, actionNames, finiteStateMachine) => {
159
+ var _a;
160
+ if (actionNames == null)
161
+ return;
162
+ (_a = logger.logMethodArgs) === null || _a === void 0 ? void 0 : _a.call(logger, 'execAction', { constructorId: constructor.id, actionNames });
163
+ if (Array.isArray(actionNames)) {
164
+ return actionNames
165
+ .map((actionName) => _execAction(constructor, actionName, finiteStateMachine))
166
+ .every((r) => r === true);
167
+ }
168
+ try {
169
+ const actionFn = constructor.actionRecord[actionNames];
170
+ if (actionFn == null) {
171
+ return logger.error('execAction', 'action_not_found', {
172
+ actionNames,
173
+ constructorId: constructor.id,
174
+ instanceId: finiteStateMachine.id,
56
175
  });
57
- return null;
58
176
  }
59
- this.setState(toState, event);
60
- return toState;
177
+ return actionFn(finiteStateMachine);
178
+ }
179
+ catch (error) {
180
+ return logger.error('execAction', 'action_error', error, {
181
+ actionNames,
182
+ constructorId: constructor.id,
183
+ instanceId: finiteStateMachine.id,
184
+ });
185
+ }
186
+ };
187
+ /**
188
+ * Initialize new finite state machine instance.
189
+ */
190
+ export const initFsmInstance = (instanceId, constructorId) => {
191
+ var _a;
192
+ (_a = logger.logMethodArgs) === null || _a === void 0 ? void 0 : _a.call(logger, 'initializeMachine', { constructorId, instanceId });
193
+ const constructor = getFsmConstructor(constructorId);
194
+ const { initial, context } = constructor.config;
195
+ const newInstance = {
196
+ constructorId,
197
+ state: {
198
+ target: initial,
199
+ from: initial,
200
+ by: 'INIT',
201
+ },
202
+ context,
203
+ };
204
+ contextProvider.setValue(instanceId, newInstance, { debounce: 'NextCycle' });
205
+ _execAllActions(constructor, newInstance.state, finiteStateMachineConsumer(instanceId));
206
+ };
207
+ /**
208
+ * Subscribe to all defined signals for finite state machine instance.
209
+ */
210
+ export const subscribeSignals = (instanceId, signalList, subscribeConstructorSignals = true) => {
211
+ var _a, _b, _c;
212
+ (_a = logger.logMethodArgs) === null || _a === void 0 ? void 0 : _a.call(logger, 'subscribeSignals', { instanceId, signalList });
213
+ const listenerList = [];
214
+ if (subscribeConstructorSignals) {
215
+ signalList = signalList.concat(getFsmConstructor(getFsmInstance(instanceId).constructorId).signalList);
216
+ }
217
+ for (const signalConfig of signalList) {
218
+ (_b = signalConfig.signalId) !== null && _b !== void 0 ? _b : (signalConfig.signalId = instanceId);
219
+ listenerList.push(contextConsumer.subscribe(signalConfig.signalId, (signalDetail) => {
220
+ var _a;
221
+ (_a = logger.logMethodArgs) === null || _a === void 0 ? void 0 : _a.call(logger, 'execSignalCallback', { instanceId, signalId: signalConfig.signalId, signalDetail });
222
+ if (signalConfig.callback) {
223
+ signalConfig.callback(signalDetail, finiteStateMachineConsumer(instanceId));
224
+ }
225
+ else {
226
+ // prettier-ignore
227
+ transition(instanceId, signalConfig.transition, signalConfig.contextName == null ? undefined : {
228
+ [signalConfig.contextName]: signalDetail,
229
+ });
230
+ }
231
+ }, { receivePrevious: (_c = signalConfig.receivePrevious) !== null && _c !== void 0 ? _c : 'No' }));
232
+ }
233
+ return listenerList;
234
+ };
235
+ /**
236
+ * Define signals for finite state machine constructor.
237
+ */
238
+ export const defineConstructorSignals = (constructorId, signalList) => {
239
+ var _a;
240
+ (_a = logger.logMethodArgs) === null || _a === void 0 ? void 0 : _a.call(logger, 'defineSignals', { constructorId, signalList: signalList });
241
+ const fsmConstructor = getFsmConstructor(constructorId);
242
+ fsmConstructor.signalList = fsmConstructor.signalList.concat(signalList);
243
+ };
244
+ /**
245
+ * Define signals for finite state machine instance.
246
+ */
247
+ export const defineInstanceSignals = (instanceId, signalList, subscribeConstructorSignals = true) => {
248
+ var _a;
249
+ (_a = logger.logMethodArgs) === null || _a === void 0 ? void 0 : _a.call(logger, 'defineSignals', { instanceId, signals: signalList });
250
+ return subscribeSignals(instanceId, signalList, subscribeConstructorSignals);
251
+ };
252
+ /**
253
+ * Render helper for use finite state machine instance in UI.
254
+ *
255
+ * Example:
256
+ *
257
+ * ```ts
258
+ * render('myFsm', {
259
+ * state1: () => html`<div>State 1 Render...</div>`,
260
+ * state2: () => html`<div>State 2 Render...</div>`,
261
+ * state3: 'state1',
262
+ * });
263
+ * ```
264
+ */
265
+ export const render = (instanceId, states, thisArg = null) => {
266
+ var _a;
267
+ const state = getFsmInstance(instanceId).state;
268
+ (_a = logger.logMethodArgs) === null || _a === void 0 ? void 0 : _a.call(logger, 'render', { instanceId, state: state.target });
269
+ let renderFn = states[state.target];
270
+ if (typeof renderFn === 'string') {
271
+ renderFn = states[renderFn];
272
+ }
273
+ if (typeof renderFn === 'function') {
274
+ return renderFn.call(thisArg);
275
+ }
276
+ return;
277
+ };
278
+ /**
279
+ * Subscribe to finite state machine instance state changes.
280
+ */
281
+ export const subscribe = (instanceId, callback, options) => {
282
+ var _a;
283
+ (_a = logger.logMethodArgs) === null || _a === void 0 ? void 0 : _a.call(logger, 'subscribe', instanceId);
284
+ return contextConsumer.subscribe(instanceId, callback, options);
285
+ };
286
+ /**
287
+ * Destroy finite state machine instance object to clear memory.
288
+ */
289
+ export const destroy = (instanceId) => {
290
+ var _a;
291
+ (_a = logger.logMethodArgs) === null || _a === void 0 ? void 0 : _a.call(logger, 'destroy', instanceId);
292
+ destroySignal(instanceId);
293
+ };
294
+ /**
295
+ * Reset finite state machine instance to initial state and context.
296
+ */
297
+ export const reset = (instanceId) => {
298
+ var _a;
299
+ (_a = logger.logMethodArgs) === null || _a === void 0 ? void 0 : _a.call(logger, 'reset', instanceId);
300
+ const constructorId = getFsmInstance(instanceId).constructorId;
301
+ // contextProvider.expire(instanceId);
302
+ initFsmInstance(instanceId, constructorId);
303
+ };
304
+ /**
305
+ * Finite state machine instance consumer.
306
+ * Lookup current finite state machine instance or initialize new one and return consumer object .
307
+ */
308
+ // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
309
+ export const finiteStateMachineConsumer = (instanceId, makeFromConstructor) => {
310
+ var _a, _b;
311
+ (_a = logger.logMethodArgs) === null || _a === void 0 ? void 0 : _a.call(logger, 'stateMachineLookup', instanceId);
312
+ const machineInstance = contextConsumer.getValue(instanceId);
313
+ if (machineInstance == null) {
314
+ // instance not initialized.
315
+ if (makeFromConstructor == null) {
316
+ throw new Error('fsm_undefined', { cause: { instanceId } });
317
+ }
318
+ initFsmInstance(instanceId, makeFromConstructor);
61
319
  }
62
- }
320
+ return {
321
+ /**
322
+ * Finite state machine instance id.
323
+ */
324
+ id: instanceId,
325
+ /**
326
+ * Finite state machine constructor id.
327
+ */
328
+ constructorId: (_b = machineInstance === null || machineInstance === void 0 ? void 0 : machineInstance.constructorId) !== null && _b !== void 0 ? _b : makeFromConstructor,
329
+ /**
330
+ * Render helper for use finite state machine instance in UI.
331
+ */
332
+ render: render.bind(null, instanceId),
333
+ /**
334
+ * Subscribe to finite state machine instance state changes.
335
+ */
336
+ subscribe: subscribe.bind(null, instanceId),
337
+ /**
338
+ * Unsubscribe from finite state machine instance state changes.
339
+ */
340
+ unsubscribe: unsubscribe,
341
+ /**
342
+ * Get current state of finite state machine instance.
343
+ */
344
+ getState: getState.bind(null, instanceId),
345
+ /**
346
+ * Get current context of finite state machine instance.
347
+ */
348
+ getContext: getContext.bind(null, instanceId),
349
+ /**
350
+ * Set context of finite state machine instance.
351
+ */
352
+ setContext: setContext.bind(null, instanceId),
353
+ /**
354
+ * Transition finite state machine instance to new state.
355
+ */
356
+ transition: transition.bind(null, instanceId),
357
+ /**
358
+ * Define signals for finite state machine instance.
359
+ */
360
+ defineSignals: defineInstanceSignals.bind(null, instanceId),
361
+ /**
362
+ * Reset finite state machine instance to initial state and context.
363
+ */
364
+ reset: reset.bind(null, instanceId),
365
+ /**
366
+ * Destroy finite state machine instance object to clear memory.
367
+ */
368
+ destroy: destroy.bind(null, instanceId),
369
+ };
370
+ };
63
371
  //# sourceMappingURL=core.js.map
package/core.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"core.js","sourceRoot":"","sources":["src/core.ts"],"names":[],"mappings":"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","sourcesContent":["import {createLogger, globalAlwatr} from '@alwatr/logger';\nimport {contextConsumer} from '@alwatr/signal';\nimport {dispatch} from '@alwatr/signal/core.js';\n\nimport type {Stringifyable, StringifyableRecord} from '@alwatr/type';\n\nglobalAlwatr.registeredList.push({\n name: '@alwatr/fsm',\n version: _ALWATR_VERSION_,\n});\n\nexport interface MachineConfig<TState extends string, TEventId extends string, TContext extends Stringifyable>\n extends StringifyableRecord {\n /**\n * Machine ID (It is used in the state change signal identifier, so it must be unique).\n */\n id: string;\n\n /**\n * Initial state.\n */\n initial: TState;\n\n /**\n * Initial context.\n */\n context: TContext;\n\n /**\n * States list\n */\n states: {\n [S in TState | '$all']: {\n /**\n * An object mapping eventId (keys) to state.\n */\n on: {\n [E in TEventId]?: TState | '$self';\n };\n };\n };\n}\n\nexport interface StateContext<TState extends string, TEventId extends string> {\n [T: string]: string;\n to: TState;\n from: TState | 'init';\n by: TEventId | 'INIT';\n}\n\nexport class FiniteStateMachine<\n TState extends string = string,\n TEventId extends string = string,\n TContext extends StringifyableRecord = StringifyableRecord\n> {\n state: StateContext<TState, TEventId> = {\n to: this.config.initial,\n from: 'init',\n by: 'INIT',\n };\n context = this.config.context;\n signal = contextConsumer.bind<StateContext<TState, TEventId>>('finite-state-machine-' + this.config.id);\n\n protected _logger = createLogger(`alwatr/fsm:${this.config.id}`);\n\n protected setState(to: TState, by: TEventId | 'INIT'): void {\n this.state = {\n to,\n from: this.signal.getValue()?.to ?? 'init',\n by,\n };\n dispatch<StateContext<TState, TEventId>>(this.signal.id, this.state, {debounce: 'NextCycle'});\n }\n\n constructor(public readonly config: Readonly<MachineConfig<TState, TEventId, TContext>>) {\n this._logger.logMethodArgs('constructor', config);\n dispatch<StateContext<TState, TEventId>>(this.signal.id, this.state, {debounce: 'NextCycle'});\n if (!config.states[config.initial]) {\n this._logger.error('constructor', 'invalid_initial_state', config);\n }\n }\n\n /**\n * Machine transition.\n */\n transition(event: TEventId, context?: Partial<TContext>): TState | null {\n const fromState = this.state.to;\n\n let toState: TState | '$self' | undefined =\n this.config.states[fromState]?.on?.[event] ?? this.config.states.$all?.on?.[event];\n\n if (toState === '$self') {\n toState = fromState;\n }\n\n this._logger.logMethodFull('transition', {fromState, event, context}, toState);\n\n if (context !== undefined) {\n this.context = {\n ...this.context,\n ...context,\n };\n }\n\n if (toState == null) {\n this._logger.incident(\n 'transition',\n 'invalid_target_state',\n 'Defined target state for this event not found in state config',\n {\n fromState,\n event,\n events: {...this.config.states.$all?.on, ...this.config.states[fromState]?.on},\n },\n );\n return null;\n }\n\n this.setState(toState, event);\n return toState;\n }\n}\n"]}
1
+ {"version":3,"file":"core.js","sourceRoot":"","sources":["src/core.ts"],"names":[],"mappings":"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","sourcesContent":["import {createLogger, globalAlwatr} from '@alwatr/logger';\nimport {ListenerSpec, contextProvider, contextConsumer} from '@alwatr/signal';\nimport {destroySignal, unsubscribe} from '@alwatr/signal/core.js';\nimport {SubscribeOptions} from '@alwatr/signal/type.js';\n\nimport type {\n ActionRecord,\n FsmConstructor,\n FsmConstructorConfig,\n FsmConsumerInterface,\n FsmInstance,\n FsmState,\n FsmTypeHelper,\n SignalConfig,\n} from './type.js';\nimport type {MaybePromise, OmitFirstParam, SingleOrArray, StringifyableRecord} from '@alwatr/type';\n\nglobalAlwatr.registeredList.push({\n name: '@alwatr/fsm',\n version: _ALWATR_VERSION_,\n});\n\nconst logger = createLogger(`alwatr/fsm`);\n\n/**\n * Finite state machine constructor storage.\n */\nconst fsmConstructorStorage: Record<string, FsmConstructor | undefined> = {};\n\nexport const defineConstructor = <\n TState extends string = string,\n TEventId extends string = string,\n TActionName extends string = string,\n TContext extends StringifyableRecord = StringifyableRecord\n>(\n id: string,\n config: FsmConstructorConfig<TState, TEventId, TActionName, TContext>,\n ): FsmConstructorConfig<TState, TEventId, TActionName, TContext> => {\n logger.logMethodArgs?.('defineConstructor', {id, config});\n if (fsmConstructorStorage[id] != null) throw new Error('fsm_exist', {cause: {id}});\n fsmConstructorStorage[id] = {\n id,\n config,\n actionRecord: {},\n signalList: [],\n };\n return config;\n};\n\n/**\n * Get finite state machine instance by id.\n */\nexport const getFsmInstance = <\n TState extends string = string,\n TEventId extends string = string,\n TContext extends StringifyableRecord = StringifyableRecord\n>(\n instanceId: string,\n ): FsmInstance<TState, TEventId, TContext> => {\n logger.logMethodArgs?.('_getFsmInstance', instanceId);\n const fsmInstance = contextConsumer.getValue<FsmInstance<TState, TEventId, TContext>>(instanceId);\n if (fsmInstance == null) throw new Error('fsm_undefined', {cause: {instanceId}});\n return fsmInstance;\n};\n\n/**\n * Get finite state machine constructor by id.\n */\nexport const getFsmConstructor = (constructorId: string): FsmConstructor => {\n logger.logMethodArgs?.('_getFsmConstructor', constructorId);\n const fsmConstructor = fsmConstructorStorage[constructorId];\n if (fsmConstructor == null) throw new Error('fsm_undefined', {cause: {constructorId: constructorId}});\n return fsmConstructor;\n};\n\n/**\n * Get current state of finite state machine instance.\n */\nexport const getState = <TState extends string = string, TEventId extends string = string>(\n instanceId: string,\n): FsmState<TState, TEventId> => {\n logger.logMethodArgs?.('getState', instanceId);\n return getFsmInstance<TState, TEventId>(instanceId).state;\n};\n\n/**\n * Get current context of finite state machine instance.\n */\nexport const getContext = <TContext extends StringifyableRecord = StringifyableRecord>(\n instanceId: string,\n): TContext => {\n logger.logMethodArgs?.('getContext', instanceId);\n return getFsmInstance<string, string, TContext>(instanceId).context;\n};\n\n/**\n * Set context of finite state machine instance.\n */\nexport const setContext = <TContext extends StringifyableRecord = StringifyableRecord>(\n instanceId: string,\n context: Partial<TContext>,\n notify?: boolean,\n): void => {\n logger.logMethodArgs?.('setContext', {instanceId, context});\n const fsmInstance = getFsmInstance(instanceId);\n fsmInstance.context = {\n ...fsmInstance.context,\n ...context,\n };\n\n if (notify) {\n contextProvider.setValue(instanceId, fsmInstance, {debounce: 'Timeout'});\n }\n};\n\n/**\n * Transition finite state machine instance to new state.\n */\nexport const transition = <\n TEventId extends string = string,\n TContext extends StringifyableRecord = StringifyableRecord\n>(\n instanceId: string,\n event: TEventId,\n context?: Partial<TContext>,\n ): void => {\n const fsmInstance = getFsmInstance(instanceId);\n const fsmConstructor = getFsmConstructor(fsmInstance.constructorId);\n const fromState = fsmInstance.state.target;\n const stateRecord = fsmConstructor.config.stateRecord;\n const transitionConfig = stateRecord[fromState]?.on[event] ?? stateRecord.$all.on[event];\n\n logger.logMethodArgs?.('transition', {instanceId, fromState, event, context, target: transitionConfig?.target});\n\n if (context !== undefined) {\n fsmInstance.context = {\n ...fsmInstance.context,\n ...context,\n };\n }\n\n if (transitionConfig == null) {\n logger.incident?.(\n 'transition',\n 'invalid_target_state',\n 'Defined target state for this event not found in state config',\n {\n fromState,\n event,\n events: {\n ...stateRecord.$all?.on,\n ...stateRecord[fromState]?.on,\n },\n },\n );\n return;\n }\n\n const consumerInterface = finiteStateMachineConsumer(instanceId);\n\n if (transitionConfig.condition) {\n if (_execAction(fsmConstructor, transitionConfig.condition, consumerInterface) === false) return;\n }\n\n fsmInstance.state = {\n target: transitionConfig.target ?? fromState,\n from: fromState,\n by: event,\n };\n\n contextProvider.setValue(instanceId, fsmInstance, {debounce: 'Timeout'});\n\n _execAllActions(fsmConstructor, fsmInstance.state, consumerInterface);\n};\n\n/**\n * Define actions for finite state machine constructor.\n */\nexport const defineActions = <T extends FsmTypeHelper>(constructorId: string, actionRecord: ActionRecord<T>): void => {\n logger.logMethodArgs?.('defineActions', {constructorId, actionRecord});\n const fmsConstructor = getFsmConstructor(constructorId);\n fmsConstructor.actionRecord = {\n ...fmsConstructor.actionRecord,\n ...actionRecord,\n };\n};\n\n/**\n * Execute all actions for current state.\n */\nexport const _execAllActions = (\n constructor: FsmConstructor,\n state: FsmState,\n consumerInterface: FsmConsumerInterface,\n): void => {\n logger.logMethodArgs?.('_execAllActions', consumerInterface.id);\n\n const stateRecord = constructor.config.stateRecord;\n\n if (state.by === 'INIT') {\n _execAction(constructor, stateRecord.$all.entry, consumerInterface);\n _execAction(constructor, stateRecord[state.target]?.entry, consumerInterface);\n return;\n }\n\n // else\n if (state.from !== state.target) {\n _execAction(constructor, stateRecord.$all.exit, consumerInterface);\n _execAction(constructor, stateRecord[state.from]?.exit, consumerInterface);\n _execAction(constructor, stateRecord.$all.entry, consumerInterface);\n _execAction(constructor, stateRecord[state.target]?.entry, consumerInterface);\n }\n\n _execAction(\n constructor,\n stateRecord[state.from]?.on[state.by] != null\n ? stateRecord[state.from].on[state.by]?.actions\n : stateRecord.$all.on[state.by]?.actions,\n consumerInterface,\n );\n};\n\n/**\n * Execute single action.\n */\nexport const _execAction = (\n constructor: FsmConstructor,\n actionNames: SingleOrArray<string> | undefined,\n finiteStateMachine: FsmConsumerInterface,\n): boolean | MaybePromise<void> => {\n if (actionNames == null) return;\n logger.logMethodArgs?.('execAction', {constructorId: constructor.id, actionNames});\n\n if (Array.isArray(actionNames)) {\n return actionNames\n .map((actionName) => _execAction(constructor, actionName, finiteStateMachine))\n .every((r) => r === true);\n }\n\n try {\n const actionFn = constructor.actionRecord[actionNames];\n if (actionFn == null) {\n return logger.error('execAction', 'action_not_found', {\n actionNames,\n constructorId: constructor.id,\n instanceId: finiteStateMachine.id,\n });\n }\n return actionFn(finiteStateMachine);\n }\n catch (error) {\n return logger.error('execAction', 'action_error', error, {\n actionNames,\n constructorId: constructor.id,\n instanceId: finiteStateMachine.id,\n });\n }\n};\n\n/**\n * Initialize new finite state machine instance.\n */\nexport const initFsmInstance = (instanceId: string, constructorId: string): void => {\n logger.logMethodArgs?.('initializeMachine', {constructorId, instanceId});\n const constructor = getFsmConstructor(constructorId);\n const {initial, context} = constructor.config;\n const newInstance: FsmInstance = {\n constructorId,\n state: {\n target: initial,\n from: initial,\n by: 'INIT',\n },\n context,\n };\n contextProvider.setValue<FsmInstance>(instanceId, newInstance, {debounce: 'NextCycle'});\n\n _execAllActions(constructor, newInstance.state, finiteStateMachineConsumer(instanceId));\n};\n\n/**\n * Subscribe to all defined signals for finite state machine instance.\n */\nexport const subscribeSignals = (\n instanceId: string,\n signalList: Array<SignalConfig>,\n subscribeConstructorSignals = true,\n): Array<ListenerSpec> => {\n logger.logMethodArgs?.('subscribeSignals', {instanceId, signalList});\n const listenerList: Array<ListenerSpec> = [];\n\n if (subscribeConstructorSignals) {\n signalList = signalList.concat(getFsmConstructor(getFsmInstance(instanceId).constructorId).signalList);\n }\n\n for (const signalConfig of signalList) {\n signalConfig.signalId ??= instanceId;\n listenerList.push(\n contextConsumer.subscribe(\n signalConfig.signalId,\n (signalDetail: StringifyableRecord): void => {\n logger.logMethodArgs?.('execSignalCallback', {instanceId, signalId: signalConfig.signalId, signalDetail});\n if (signalConfig.callback) {\n signalConfig.callback(signalDetail, finiteStateMachineConsumer(instanceId));\n }\n else {\n // prettier-ignore\n transition(\n instanceId,\n signalConfig.transition,\n signalConfig.contextName == null ? undefined : {\n [signalConfig.contextName]: signalDetail,\n },\n );\n }\n },\n {receivePrevious: signalConfig.receivePrevious ?? 'No'},\n ),\n );\n }\n\n return listenerList;\n};\n\n/**\n * Define signals for finite state machine constructor.\n */\nexport const defineConstructorSignals = <T extends FsmTypeHelper>(\n constructorId: string,\n signalList: Array<SignalConfig<T>>,\n): void => {\n logger.logMethodArgs?.('defineSignals', {constructorId, signalList: signalList});\n const fsmConstructor = getFsmConstructor(constructorId);\n fsmConstructor.signalList = fsmConstructor.signalList.concat(signalList as Array<SignalConfig>);\n};\n\n/**\n * Define signals for finite state machine instance.\n */\nexport const defineInstanceSignals = <T extends FsmTypeHelper>(\n instanceId: string,\n signalList: Array<SignalConfig<T>>,\n subscribeConstructorSignals = true,\n): Array<ListenerSpec> => {\n logger.logMethodArgs?.('defineSignals', {instanceId, signals: signalList});\n return subscribeSignals(instanceId, signalList as Array<SignalConfig>, subscribeConstructorSignals);\n};\n\n/**\n * Render helper for use finite state machine instance in UI.\n *\n * Example:\n *\n * ```ts\n * render('myFsm', {\n * state1: () => html`<div>State 1 Render...</div>`,\n * state2: () => html`<div>State 2 Render...</div>`,\n * state3: 'state1',\n * });\n * ```\n */\nexport const render = <TState extends string = string>(\n instanceId: string,\n states: {[P in TState]: (() => unknown) | TState},\n thisArg: unknown = null,\n): unknown => {\n const state = getFsmInstance(instanceId).state;\n logger.logMethodArgs?.('render', {instanceId, state: state.target});\n let renderFn = states[state.target as TState];\n\n if (typeof renderFn === 'string') {\n renderFn = states[renderFn as TState];\n }\n\n if (typeof renderFn === 'function') {\n return renderFn.call(thisArg);\n }\n\n return;\n};\n\n/**\n * Subscribe to finite state machine instance state changes.\n */\nexport const subscribe = (\n instanceId: string,\n callback: () => void,\n options?: Partial<SubscribeOptions>,\n): ListenerSpec => {\n logger.logMethodArgs?.('subscribe', instanceId);\n return contextConsumer.subscribe(instanceId, callback, options);\n};\n\n/**\n * Destroy finite state machine instance object to clear memory.\n */\nexport const destroy = (instanceId: string): void => {\n logger.logMethodArgs?.('destroy', instanceId);\n destroySignal(instanceId);\n};\n\n/**\n * Reset finite state machine instance to initial state and context.\n */\nexport const reset = (instanceId: string): void => {\n logger.logMethodArgs?.('reset', instanceId);\n const constructorId = getFsmInstance(instanceId).constructorId;\n // contextProvider.expire(instanceId);\n initFsmInstance(instanceId, constructorId);\n};\n\n/**\n * Finite state machine instance consumer.\n * Lookup current finite state machine instance or initialize new one and return consumer object .\n */\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nexport const finiteStateMachineConsumer = <T extends FsmTypeHelper, TContext extends T['TContext'] = T['TContext']>(\n instanceId: string,\n makeFromConstructor?: string,\n) => {\n logger.logMethodArgs?.('stateMachineLookup', instanceId);\n\n const machineInstance = contextConsumer.getValue<FsmInstance>(instanceId);\n if (machineInstance == null) {\n // instance not initialized.\n if (makeFromConstructor == null) {\n throw new Error('fsm_undefined', {cause: {instanceId}});\n }\n initFsmInstance(instanceId, makeFromConstructor);\n }\n\n return {\n /**\n * Finite state machine instance id.\n */\n id: instanceId,\n\n /**\n * Finite state machine constructor id.\n */\n constructorId: <string>machineInstance?.constructorId ?? makeFromConstructor,\n\n /**\n * Render helper for use finite state machine instance in UI.\n */\n render: render.bind(null, instanceId) as OmitFirstParam<typeof render<T['TState']>>,\n\n /**\n * Subscribe to finite state machine instance state changes.\n */\n subscribe: subscribe.bind(null, instanceId) as OmitFirstParam<typeof subscribe>,\n\n /**\n * Unsubscribe from finite state machine instance state changes.\n */\n unsubscribe: unsubscribe,\n\n /**\n * Get current state of finite state machine instance.\n */\n getState: getState.bind(null, instanceId) as OmitFirstParam<typeof getState<T['TState'], T['TEventId']>>,\n\n /**\n * Get current context of finite state machine instance.\n */\n getContext: getContext.bind(null, instanceId) as OmitFirstParam<typeof getContext<TContext>>,\n\n /**\n * Set context of finite state machine instance.\n */\n setContext: setContext.bind(null, instanceId) as OmitFirstParam<typeof setContext<TContext>>,\n\n /**\n * Transition finite state machine instance to new state.\n */\n transition: transition.bind(null, instanceId) as OmitFirstParam<typeof transition<T['TEventId'], TContext>>,\n\n /**\n * Define signals for finite state machine instance.\n */\n defineSignals: defineInstanceSignals.bind(null, instanceId) as OmitFirstParam<typeof defineInstanceSignals<T>>,\n\n /**\n * Reset finite state machine instance to initial state and context.\n */\n reset: reset.bind(null, instanceId) as OmitFirstParam<typeof reset>,\n\n /**\n * Destroy finite state machine instance object to clear memory.\n */\n destroy: destroy.bind(null, instanceId) as OmitFirstParam<typeof destroy>,\n } as const;\n};\n"]}
package/index.d.ts ADDED
@@ -0,0 +1,22 @@
1
+ export { finiteStateMachineConsumer } from './core.js';
2
+ /**
3
+ * Finite State Machine Provider.
4
+ */
5
+ export declare const finiteStateMachineProvider: {
6
+ readonly defineConstructor: <TState extends string = string, TEventId extends string = string, TActionName extends string = string, TContext extends import("@alwatr/type").StringifyableRecord = import("@alwatr/type").StringifyableRecord>(id: string, config: import("./type.js").FsmConstructorConfig<TState, TEventId, TActionName, TContext>) => import("./type.js").FsmConstructorConfig<TState, TEventId, TActionName, TContext>;
7
+ readonly defineActions: <T extends Readonly<{
8
+ TState: string;
9
+ TEventId: string;
10
+ TActionName: string;
11
+ TContext: import("@alwatr/type").StringifyableRecord;
12
+ }>>(constructorId: string, actionRecord: import("./type.js").ActionRecord<T>) => void;
13
+ readonly defineSignals: <T_1 extends Readonly<{
14
+ TState: string;
15
+ TEventId: string;
16
+ TActionName: string;
17
+ TContext: import("@alwatr/type").StringifyableRecord;
18
+ }>>(constructorId: string, signalList: import("./type.js").SignalConfig<T_1>[]) => void;
19
+ readonly subscribe: (instanceId: string, callback: () => void, options?: Partial<import("@alwatr/signal/type.js").SubscribeOptions> | undefined) => import("@alwatr/signal").ListenerSpec;
20
+ };
21
+ export type { FsmTypeHelper, FsmConstructorConfig, FsmConsumerInterface } from './type.js';
22
+ //# sourceMappingURL=index.d.ts.map
package/index.d.ts.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,0BAA0B,EAAC,MAAM,WAAW,CAAC;AAErD;;GAEG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;CAK7B,CAAC;AAEX,YAAY,EAAC,aAAa,EAAE,oBAAoB,EAAE,oBAAoB,EAAC,MAAM,WAAW,CAAC"}
package/index.js ADDED
@@ -0,0 +1,12 @@
1
+ import { defineActions, defineConstructor, defineConstructorSignals, subscribe } from './core.js';
2
+ export { finiteStateMachineConsumer } from './core.js';
3
+ /**
4
+ * Finite State Machine Provider.
5
+ */
6
+ export const finiteStateMachineProvider = {
7
+ defineConstructor,
8
+ defineActions,
9
+ defineSignals: defineConstructorSignals,
10
+ subscribe,
11
+ };
12
+ //# sourceMappingURL=index.js.map
package/index.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,SAAS,EAAC,MAAM,WAAW,CAAC;AAEhG,OAAO,EAAC,0BAA0B,EAAC,MAAM,WAAW,CAAC;AAErD;;GAEG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,iBAAiB;IACjB,aAAa;IACb,aAAa,EAAE,wBAAwB;IACvC,SAAS;CACD,CAAC","sourcesContent":["import {defineActions, defineConstructor, defineConstructorSignals, subscribe} from './core.js';\n\nexport {finiteStateMachineConsumer} from './core.js';\n\n/**\n * Finite State Machine Provider.\n */\nexport const finiteStateMachineProvider = {\n defineConstructor,\n defineActions,\n defineSignals: defineConstructorSignals,\n subscribe,\n} as const;\n\nexport type {FsmTypeHelper, FsmConstructorConfig, FsmConsumerInterface} from './type.js';\n"]}
package/package.json CHANGED
@@ -1,18 +1,21 @@
1
1
  {
2
2
  "name": "@alwatr/fsm",
3
- "version": "0.30.0",
4
- "description": "Managing invocations finite-state machines as actors written in tiny TypeScript module.",
3
+ "version": "0.31.0",
4
+ "description": "Managing invocations finite-state machines for lit-element written in tiny TypeScript module.",
5
5
  "keywords": [
6
6
  "state",
7
7
  "finite",
8
8
  "machine",
9
+ "lit",
10
+ "lit-element",
11
+ "lit-html",
9
12
  "typescript",
10
13
  "esm",
11
14
  "alwatr"
12
15
  ],
13
- "main": "core.js",
16
+ "main": "index.js",
14
17
  "type": "module",
15
- "types": "core.d.ts",
18
+ "types": "index.d.ts",
16
19
  "author": "S. Ali Mihandoost <ali.mihandoost@gmail.com>",
17
20
  "license": "MIT",
18
21
  "files": [
@@ -31,10 +34,10 @@
31
34
  "url": "https://github.com/AliMD/alwatr/issues"
32
35
  },
33
36
  "dependencies": {
34
- "@alwatr/logger": "^0.30.0",
35
- "@alwatr/signal": "^0.30.0",
36
- "@alwatr/type": "^0.30.0",
37
+ "@alwatr/logger": "^0.31.0",
38
+ "@alwatr/signal": "^0.31.0",
39
+ "@alwatr/type": "^0.31.0",
37
40
  "tslib": "^2.5.0"
38
41
  },
39
- "gitHead": "36f55780ccdcb1acc07400b0cdb3fe7b0df56cca"
42
+ "gitHead": "896e64b58eed6e9048e870557ecf399d42705612"
40
43
  }
package/type.d.ts ADDED
@@ -0,0 +1,107 @@
1
+ import type { finiteStateMachineConsumer } from './core.js';
2
+ import type { DebounceType } from '@alwatr/signal';
3
+ import type { ArrayItems, MaybePromise, SingleOrArray, StringifyableRecord } from '@alwatr/type';
4
+ export interface FsmConstructor {
5
+ /**
6
+ * Constructor id.
7
+ */
8
+ readonly id: string;
9
+ readonly config: FsmConstructorConfig;
10
+ actionRecord: ActionRecord;
11
+ signalList: Array<SignalConfig>;
12
+ }
13
+ export interface FsmConstructorConfig<TState extends string = string, TEventId extends string = string, TActionName extends string = string, TContext extends StringifyableRecord = StringifyableRecord> extends StringifyableRecord {
14
+ /**
15
+ * Initial context.
16
+ */
17
+ readonly context: TContext;
18
+ /**
19
+ * Initial state.
20
+ */
21
+ readonly initial: TState;
22
+ /**
23
+ * Define state list
24
+ */
25
+ readonly stateRecord: StateRecord<TState, TEventId, TActionName>;
26
+ }
27
+ export type StateRecord<TState extends string = string, TEventId extends string = string, TActionName extends string = string> = {
28
+ readonly [S in TState | '$all']: {
29
+ /**
30
+ * On state exit actions
31
+ */
32
+ readonly exit?: SingleOrArray<TActionName>;
33
+ /**
34
+ * On state entry actions
35
+ */
36
+ readonly entry?: SingleOrArray<TActionName>;
37
+ /**
38
+ * An object mapping eventId to state.
39
+ *
40
+ * Example:
41
+ *
42
+ * ```ts
43
+ * stateRecord: {
44
+ * on: {
45
+ * TIMER: {
46
+ * target: 'green',
47
+ * condition: () => car.gas > 0,
48
+ * actions: () => car.go(),
49
+ * }
50
+ * }
51
+ * }
52
+ * ```
53
+ */
54
+ readonly on: {
55
+ readonly [E in TEventId]?: TransitionConfig<TState, TActionName> | undefined;
56
+ };
57
+ };
58
+ };
59
+ export interface FsmState<TState extends string = string, TEventId extends string = string> extends StringifyableRecord {
60
+ /**
61
+ * Current state
62
+ */
63
+ target: TState;
64
+ /**
65
+ * Last state
66
+ */
67
+ from: TState;
68
+ /**
69
+ * Transition event
70
+ */
71
+ by: TEventId | 'INIT';
72
+ }
73
+ export interface TransitionConfig<TState extends string = string, TActionName extends string = string> extends StringifyableRecord {
74
+ readonly target?: TState;
75
+ readonly condition?: TActionName;
76
+ readonly actions?: SingleOrArray<TActionName>;
77
+ }
78
+ export interface FsmInstance<TState extends string = string, TEventId extends string = string, TContext extends StringifyableRecord = StringifyableRecord> extends StringifyableRecord {
79
+ readonly constructorId: string;
80
+ state: FsmState<TState, TEventId>;
81
+ context: TContext;
82
+ }
83
+ export type ActionRecord<T extends FsmTypeHelper = FsmTypeHelper> = {
84
+ readonly [P in T['TActionName']]?: (finiteStateMachine: FsmConsumerInterface<T>) => MaybePromise<void> | boolean;
85
+ };
86
+ export type SignalConfig<T extends FsmTypeHelper = FsmTypeHelper> = {
87
+ signalId?: string;
88
+ /**
89
+ * @default `No`
90
+ */
91
+ receivePrevious?: DebounceType;
92
+ } & ({
93
+ transition: T['TEventId'];
94
+ contextName?: keyof T['TContext'];
95
+ callback?: never;
96
+ } | {
97
+ callback: (detail: any, fsmInstance: FsmConsumerInterface<T>) => void;
98
+ transition?: never;
99
+ });
100
+ export type FsmTypeHelper<T extends FsmConstructorConfig = FsmConstructorConfig> = Readonly<{
101
+ TState: Exclude<keyof T['stateRecord'], '$all'>;
102
+ TEventId: keyof T['stateRecord'][FsmTypeHelper<T>['TState']]['on'];
103
+ TActionName: NonNullable<ArrayItems<T['stateRecord'][FsmTypeHelper<T>['TState']]['entry']>>;
104
+ TContext: T['context'];
105
+ }>;
106
+ export type FsmConsumerInterface<T extends FsmTypeHelper = FsmTypeHelper, TContext extends T['TContext'] = T['TContext']> = ReturnType<typeof finiteStateMachineConsumer<T, TContext>>;
107
+ //# sourceMappingURL=type.d.ts.map
package/type.d.ts.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type.d.ts","sourceRoot":"","sources":["src/type.ts"],"names":[],"mappings":"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"}
package/type.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=type.js.map
package/type.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type.js","sourceRoot":"","sources":["src/type.ts"],"names":[],"mappings":"","sourcesContent":["import type {finiteStateMachineConsumer} from './core.js';\nimport type {DebounceType} from '@alwatr/signal';\nimport type {ArrayItems, MaybePromise, SingleOrArray, StringifyableRecord} from '@alwatr/type';\n\nexport interface FsmConstructor {\n /**\n * Constructor id.\n */\n readonly id: string;\n readonly config: FsmConstructorConfig;\n actionRecord: ActionRecord;\n signalList: Array<SignalConfig>;\n}\n\nexport interface FsmConstructorConfig<\n TState extends string = string,\n TEventId extends string = string,\n TActionName extends string = string,\n TContext extends StringifyableRecord = StringifyableRecord\n> extends StringifyableRecord {\n /**\n * Initial context.\n */\n readonly context: TContext;\n\n /**\n * Initial state.\n */\n readonly initial: TState;\n\n /**\n * Define state list\n */\n readonly stateRecord: StateRecord<TState, TEventId, TActionName>;\n}\n\nexport type StateRecord<\n TState extends string = string,\n TEventId extends string = string,\n TActionName extends string = string\n> = {\n readonly [S in TState | '$all']: {\n /**\n * On state exit actions\n */\n readonly exit?: SingleOrArray<TActionName>;\n\n /**\n * On state entry actions\n */\n readonly entry?: SingleOrArray<TActionName>;\n\n /**\n * An object mapping eventId to state.\n *\n * Example:\n *\n * ```ts\n * stateRecord: {\n * on: {\n * TIMER: {\n * target: 'green',\n * condition: () => car.gas > 0,\n * actions: () => car.go(),\n * }\n * }\n * }\n * ```\n */\n readonly on: {\n readonly [E in TEventId]?: TransitionConfig<TState, TActionName> | undefined;\n };\n };\n};\n\nexport interface FsmState<TState extends string = string, TEventId extends string = string>\n extends StringifyableRecord {\n /**\n * Current state\n */\n target: TState;\n /**\n * Last state\n */\n from: TState;\n /**\n * Transition event\n */\n by: TEventId | 'INIT';\n}\n\nexport interface TransitionConfig<TState extends string = string, TActionName extends string = string>\n extends StringifyableRecord {\n readonly target?: TState;\n readonly condition?: TActionName;\n readonly actions?: SingleOrArray<TActionName>;\n}\n\nexport interface FsmInstance<\n TState extends string = string,\n TEventId extends string = string,\n TContext extends StringifyableRecord = StringifyableRecord\n> extends StringifyableRecord {\n readonly constructorId: string;\n state: FsmState<TState, TEventId>;\n context: TContext;\n}\n\nexport type ActionRecord<T extends FsmTypeHelper = FsmTypeHelper> = {\n readonly [P in T['TActionName']]?: (finiteStateMachine: FsmConsumerInterface<T>) => MaybePromise<void> | boolean;\n};\n\nexport type SignalConfig<T extends FsmTypeHelper = FsmTypeHelper> = {\n signalId?: string;\n /**\n * @default `No`\n */\n receivePrevious?: DebounceType;\n} & (\n | {\n transition: T['TEventId'];\n contextName?: keyof T['TContext'];\n callback?: never;\n }\n | {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n callback: (detail: any, fsmInstance: FsmConsumerInterface<T>) => void;\n transition?: never;\n }\n);\n\n// type helper\nexport type FsmTypeHelper<T extends FsmConstructorConfig = FsmConstructorConfig> = Readonly<{\n TState: Exclude<keyof T['stateRecord'], '$all'>;\n TEventId: keyof T['stateRecord'][FsmTypeHelper<T>['TState']]['on'];\n TActionName: NonNullable<ArrayItems<T['stateRecord'][FsmTypeHelper<T>['TState']]['entry']>>;\n TContext: T['context'];\n}>;\n\nexport type FsmConsumerInterface<\n T extends FsmTypeHelper = FsmTypeHelper,\n TContext extends T['TContext'] = T['TContext']\n> = ReturnType<typeof finiteStateMachineConsumer<T, TContext>>;\n"]}