@alwatr/fsm 3.2.2 → 4.0.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,25 @@
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
+ ## [4.0.0](https://github.com/Alwatr/flux/compare/v3.2.2...v4.0.0) (2024-11-06)
7
+
8
+ ### ⚠ BREAKING CHANGES
9
+
10
+ * **fsm:** all name of type ActionName in class `actionRecord_` changed
11
+ * **fsm:** event 'reset' fired on calling resetToInitialState and the first time in class constructor
12
+
13
+ ### Bug Fixes
14
+
15
+ * **fsm:** run postTransition__ in resetToInitialState_ and constructor ([00ca9c1](https://github.com/Alwatr/flux/commit/00ca9c156b4a75883bad3e7d1c8907d370fd2b71)) by @AliMD
16
+
17
+ ### Code Refactoring
18
+
19
+ * **fsm:** update action naming conventions and enhance event handling in state transitions ([c3a4094](https://github.com/Alwatr/flux/commit/c3a40940c0a5dee11dbb0fbaaa45d811603e5ff7)) by @AliMD
20
+
21
+ ### Dependencies update
22
+
23
+ * update ([a0c4014](https://github.com/Alwatr/flux/commit/a0c40144c50ba69083864bd4403b7c0dab388a2f)) by @AliMD
24
+
6
25
  ## [3.2.2](https://github.com/Alwatr/flux/compare/v3.2.1...v3.2.2) (2024-11-02)
7
26
 
8
27
  ### Dependencies update
@@ -1 +1 @@
1
- {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,gBAAgB,EAAE,KAAK,sBAAsB,EAAC,MAAM,oBAAoB,CAAC;AAEjF,OAAO,KAAK,EAAa,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAC,MAAM,WAAW,CAAC;AAIvF,MAAM,WAAW,4BAA4B,CAAC,CAAC,SAAS,MAAM,CAAE,SAAQ,sBAAsB;IAC5F,YAAY,EAAE,CAAC,CAAC;CACjB;AAED;;GAEG;AACH,8BAAsB,0BAA0B,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,CAAE,SAAQ,gBAAgB,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAC,CAAC;IACvH;;OAEG;IACH,SAAS,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAM;IAE/C;;OAEG;IACH,SAAS,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,CAAM;IAEjD,SAAS,CAAC,aAAa,EAAE,CAAC,CAAC;IAE3B,UAAmB,QAAQ,EAAE;QAAC,KAAK,EAAE,CAAC,CAAA;KAAC,CAAC;gBAE5B,MAAM,EAAE,4BAA4B,CAAC,CAAC,CAAC;IAMnD;;OAEG;IACH,SAAS,CAAC,oBAAoB,IAAI,IAAI;IAKtC;;OAEG;IACH,SAAS,CAAC,iBAAiB,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,YAAY,CAAC,OAAO,CAAC;IAKxF;;OAEG;cACa,WAAW,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBpD;;OAEG;YACW,gBAAgB;IAqB9B;;OAEG;IACH,OAAO,CAAC,YAAY;CAOrB"}
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,gBAAgB,EAAE,KAAK,sBAAsB,EAAC,MAAM,oBAAoB,CAAC;AAEjF,OAAO,KAAK,EAAa,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAC,MAAM,WAAW,CAAC;AAIvF,MAAM,WAAW,4BAA4B,CAAC,CAAC,SAAS,MAAM,CAAE,SAAQ,sBAAsB;IAC5F,YAAY,EAAE,CAAC,CAAC;CACjB;AAED;;GAEG;AACH,8BAAsB,0BAA0B,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,CAAE,SAAQ,gBAAgB,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAC,CAAC;IACvH;;OAEG;IACH,SAAS,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAM;IAE/C;;OAEG;IACH,SAAS,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,CAAM;IAEjD,SAAS,CAAC,aAAa,EAAE,CAAC,CAAC;IAE3B,UAAmB,QAAQ,EAAE;QAAC,KAAK,EAAE,CAAC,CAAA;KAAC,CAAC;gBAE5B,MAAM,EAAE,4BAA4B,CAAC,CAAC,CAAC;IASnD;;OAEG;IACH,SAAS,CAAC,oBAAoB,IAAI,IAAI;IAWtC;;OAEG;IACH,SAAS,CAAC,iBAAiB,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,YAAY,CAAC,OAAO,CAAC;IAKxF;;OAEG;cACa,WAAW,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBpD;;OAEG;YACW,gBAAgB;IAe9B;;OAEG;IACH,OAAO,CAAC,YAAY;CAOrB"}
package/dist/main.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /* @alwatr/fsm v3.2.2 */
1
+ /* @alwatr/fsm v4.0.0 */
2
2
  "use strict";
3
3
  var __defProp = Object.defineProperty;
4
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -29,7 +29,7 @@ module.exports = __toCommonJS(main_exports);
29
29
  // src/base.ts
30
30
  var import_nanolib = require("@alwatr/nanolib");
31
31
  var import_observable = require("@alwatr/observable");
32
- __dev_mode__: import_nanolib.packageTracer.add("@alwatr/fsm", "3.2.2");
32
+ __dev_mode__: import_nanolib.packageTracer.add("@alwatr/fsm", "4.0.0");
33
33
  var AlwatrFluxStateMachineBase = class extends import_observable.AlwatrObservable {
34
34
  constructor(config) {
35
35
  config.loggerPrefix ?? (config.loggerPrefix = "flux-state-machine");
@@ -42,14 +42,22 @@ var AlwatrFluxStateMachineBase = class extends import_observable.AlwatrObservabl
42
42
  * Bind actions name to class methods
43
43
  */
44
44
  this.actionRecord_ = {};
45
- this.message_ = { state: this.initialState_ = config.initialState };
45
+ this.initialState_ = config.initialState;
46
+ this.message_ = { state: this.initialState_ };
47
+ this.resetToInitialState_();
46
48
  }
47
49
  /**
48
50
  * Reset machine to initial state without notify.
49
51
  */
50
52
  resetToInitialState_() {
51
53
  this.logger_.logMethod?.("resetToInitialState_");
54
+ const from = this.message_.state;
52
55
  this.message_ = { state: this.initialState_ };
56
+ this.postTransition__({
57
+ from,
58
+ event: "reset",
59
+ to: this.initialState_
60
+ });
53
61
  }
54
62
  /**
55
63
  * Transition condition.
@@ -63,7 +71,7 @@ var AlwatrFluxStateMachineBase = class extends import_observable.AlwatrObservabl
63
71
  */
64
72
  async transition_(event) {
65
73
  const fromState = this.message_.state;
66
- const toState = this.stateRecord_[fromState]?.[event] ?? this.stateRecord_._all?.[event];
74
+ const toState = this.stateRecord_[fromState]?.[event];
67
75
  this.logger_.logMethodArgs?.("transition_", { fromState, event, toState });
68
76
  if (toState == null) {
69
77
  this.logger_.incident?.("transition", "invalid_target_state", {
@@ -82,18 +90,14 @@ var AlwatrFluxStateMachineBase = class extends import_observable.AlwatrObservabl
82
90
  */
83
91
  async postTransition__(eventDetail) {
84
92
  this.logger_.logMethodArgs?.("_transitioned", eventDetail);
85
- await this.execAction__(`on_${eventDetail.event}`, eventDetail);
93
+ await this.execAction__(`on_event_${eventDetail.event}`, eventDetail);
86
94
  if (eventDetail.from !== eventDetail.to) {
87
- await this.execAction__(`on_state_exit`, eventDetail);
88
- await this.execAction__(`on_${eventDetail.from}_exit`, eventDetail);
89
- await this.execAction__(`on_state_enter`, eventDetail);
90
- await this.execAction__(`on_${eventDetail.to}_enter`, eventDetail);
91
- }
92
- if (Object.hasOwn(this, `on_${eventDetail.from}_${eventDetail.event}`)) {
93
- this.execAction__(`on_${eventDetail.from}_${eventDetail.event}`, eventDetail);
94
- } else {
95
- this.execAction__(`on_all_${eventDetail.event}`, eventDetail);
95
+ await this.execAction__(`on_any_state_exit`, eventDetail);
96
+ await this.execAction__(`on_state_${eventDetail.from}_exit`, eventDetail);
97
+ await this.execAction__(`on_any_state_enter`, eventDetail);
98
+ await this.execAction__(`on_state_${eventDetail.to}_enter`, eventDetail);
96
99
  }
100
+ this.execAction__(`on_state_${eventDetail.from}_event_${eventDetail.event}`, eventDetail);
97
101
  }
98
102
  /**
99
103
  * Execute action name if defined in _actionRecord.
package/dist/main.cjs.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/main.ts", "../src/base.ts", "../src/fsm.ts"],
4
- "sourcesContent": ["export * from './base.js';\nexport * from './fsm.js';\nexport * from './type.js';\n", "import {packageTracer} from '@alwatr/nanolib';\nimport {AlwatrObservable, type AlwatrObservableConfig} from '@alwatr/observable';\n\nimport type {ActionName, ActionRecord, StateEventDetail, StateRecord} from './type.js';\n\n__dev_mode__: packageTracer.add(__package_name__, __package_version__);\n\nexport interface AlwatrFluxStateMachineConfig<S extends string> extends AlwatrObservableConfig {\n initialState: S;\n}\n\n/**\n * Flux (Finite) State Machine Base Class\n */\nexport abstract class AlwatrFluxStateMachineBase<S extends string, E extends string> extends AlwatrObservable<{state: S}> {\n /**\n * States and transitions config.\n */\n protected stateRecord_: StateRecord<S, E> = {};\n\n /**\n * Bind actions name to class methods\n */\n protected actionRecord_: ActionRecord<S, E> = {};\n\n protected initialState_: S;\n\n protected override message_: {state: S};\n\n constructor(config: AlwatrFluxStateMachineConfig<S>) {\n config.loggerPrefix ??= 'flux-state-machine';\n super(config);\n this.message_ = {state: this.initialState_ = config.initialState};\n }\n\n /**\n * Reset machine to initial state without notify.\n */\n protected resetToInitialState_(): void {\n this.logger_.logMethod?.('resetToInitialState_');\n this.message_ = {state: this.initialState_};\n }\n\n /**\n * Transition condition.\n */\n protected shouldTransition_(_eventDetail: StateEventDetail<S, E>): MaybePromise<boolean> {\n this.logger_.logMethodFull?.('shouldTransition_', _eventDetail, true);\n return true;\n }\n\n /**\n * Transition flux state machine instance to new state.\n */\n protected async transition_(event: E): Promise<void> {\n const fromState = this.message_.state;\n const toState = this.stateRecord_[fromState]?.[event] ?? this.stateRecord_._all?.[event];\n\n this.logger_.logMethodArgs?.('transition_', {fromState, event, toState});\n\n if (toState == null) {\n this.logger_.incident?.('transition', 'invalid_target_state', {\n fromState,\n event,\n });\n return;\n }\n\n const eventDetail: StateEventDetail<S, E> = {from: fromState, event, to: toState};\n\n if ((await this.shouldTransition_(eventDetail)) !== true) return;\n\n this.notify_({state: toState});\n\n this.postTransition__(eventDetail);\n }\n\n /**\n * Execute all actions for current state.\n */\n private async postTransition__(eventDetail: StateEventDetail<S, E>): Promise<void> {\n this.logger_.logMethodArgs?.('_transitioned', eventDetail);\n\n await this.execAction__(`on_${eventDetail.event}`, eventDetail);\n\n if (eventDetail.from !== eventDetail.to) {\n await this.execAction__(`on_state_exit`, eventDetail);\n await this.execAction__(`on_${eventDetail.from}_exit`, eventDetail);\n await this.execAction__(`on_state_enter`, eventDetail);\n await this.execAction__(`on_${eventDetail.to}_enter`, eventDetail);\n }\n\n if (Object.hasOwn(this, `on_${eventDetail.from}_${eventDetail.event}`)) {\n this.execAction__(`on_${eventDetail.from}_${eventDetail.event}`, eventDetail);\n }\n else {\n // The action `all_eventName` is executed only if the action `fromState_eventName` is not defined.\n this.execAction__(`on_all_${eventDetail.event}`, eventDetail);\n }\n }\n\n /**\n * Execute action name if defined in _actionRecord.\n */\n private execAction__(name: ActionName<S, E>, eventDetail: StateEventDetail<S, E>): MaybePromise<void> {\n const actionFn = this.actionRecord_[name];\n if (typeof actionFn === 'function') {\n this.logger_.logMethodArgs?.('_$execAction', name);\n return actionFn.call(this, eventDetail);\n }\n }\n}\n", "import {AlwatrFluxStateMachineBase} from './base.js';\n\n/**\n * Flux (Finite) State Machine Base Class\n */\nexport abstract class AlwatrFluxStateMachine<S extends string, E extends string> extends AlwatrFluxStateMachineBase<S, E> {\n /**\n * Current state.\n */\n get state(): S {\n return this.message_.state;\n }\n\n /**\n * Transition flux state machine instance to new state.\n */\n transition(event: E): void {\n this.transition_(event);\n }\n\n /**\n * Reset machine to initial state without notify.\n */\n resetToInitialState(): void {\n this.resetToInitialState_();\n }\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,qBAA4B;AAC5B,wBAA4D;AAI5D,aAAc,8BAAc,IAAI,eAAkB,OAAmB;AAS9D,IAAe,6BAAf,cAAsF,mCAA6B;AAAA,EAexH,YAAY,QAAyC;AACnD,WAAO,iBAAP,OAAO,eAAiB;AACxB,UAAM,MAAM;AAbd;AAAA;AAAA;AAAA,SAAU,eAAkC,CAAC;AAK7C;AAAA;AAAA;AAAA,SAAU,gBAAoC,CAAC;AAS7C,SAAK,WAAW,EAAC,OAAO,KAAK,gBAAgB,OAAO,aAAY;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA,EAKU,uBAA6B;AACrC,SAAK,QAAQ,YAAY,sBAAsB;AAC/C,SAAK,WAAW,EAAC,OAAO,KAAK,cAAa;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA,EAKU,kBAAkB,cAA6D;AACvF,SAAK,QAAQ,gBAAgB,qBAAqB,cAAc,IAAI;AACpE,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAgB,YAAY,OAAyB;AACnD,UAAM,YAAY,KAAK,SAAS;AAChC,UAAM,UAAU,KAAK,aAAa,SAAS,IAAI,KAAK,KAAK,KAAK,aAAa,OAAO,KAAK;AAEvF,SAAK,QAAQ,gBAAgB,eAAe,EAAC,WAAW,OAAO,QAAO,CAAC;AAEvE,QAAI,WAAW,MAAM;AACnB,WAAK,QAAQ,WAAW,cAAc,wBAAwB;AAAA,QAC5D;AAAA,QACA;AAAA,MACF,CAAC;AACD;AAAA,IACF;AAEA,UAAM,cAAsC,EAAC,MAAM,WAAW,OAAO,IAAI,QAAO;AAEhF,QAAK,MAAM,KAAK,kBAAkB,WAAW,MAAO,KAAM;AAE1D,SAAK,QAAQ,EAAC,OAAO,QAAO,CAAC;AAE7B,SAAK,iBAAiB,WAAW;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,iBAAiB,aAAoD;AACjF,SAAK,QAAQ,gBAAgB,iBAAiB,WAAW;AAEzD,UAAM,KAAK,aAAa,MAAM,YAAY,KAAK,IAAI,WAAW;AAE9D,QAAI,YAAY,SAAS,YAAY,IAAI;AACvC,YAAM,KAAK,aAAa,iBAAiB,WAAW;AACpD,YAAM,KAAK,aAAa,MAAM,YAAY,IAAI,SAAS,WAAW;AAClE,YAAM,KAAK,aAAa,kBAAkB,WAAW;AACrD,YAAM,KAAK,aAAa,MAAM,YAAY,EAAE,UAAU,WAAW;AAAA,IACnE;AAEA,QAAI,OAAO,OAAO,MAAM,MAAM,YAAY,IAAI,IAAI,YAAY,KAAK,EAAE,GAAG;AACtE,WAAK,aAAa,MAAM,YAAY,IAAI,IAAI,YAAY,KAAK,IAAI,WAAW;AAAA,IAC9E,OACK;AAEH,WAAK,aAAa,UAAU,YAAY,KAAK,IAAI,WAAW;AAAA,IAC9D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAa,MAAwB,aAAyD;AACpG,UAAM,WAAW,KAAK,cAAc,IAAI;AACxC,QAAI,OAAO,aAAa,YAAY;AAClC,WAAK,QAAQ,gBAAgB,gBAAgB,IAAI;AACjD,aAAO,SAAS,KAAK,MAAM,WAAW;AAAA,IACxC;AAAA,EACF;AACF;;;AC1GO,IAAe,yBAAf,cAAkF,2BAAiC;AAAA;AAAA;AAAA;AAAA,EAIxH,IAAI,QAAW;AACb,WAAO,KAAK,SAAS;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,OAAgB;AACzB,SAAK,YAAY,KAAK;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,sBAA4B;AAC1B,SAAK,qBAAqB;AAAA,EAC5B;AACF;",
4
+ "sourcesContent": ["export * from './base.js';\nexport * from './fsm.js';\nexport * from './type.js';\n", "import {packageTracer} from '@alwatr/nanolib';\nimport {AlwatrObservable, type AlwatrObservableConfig} from '@alwatr/observable';\n\nimport type {ActionName, ActionRecord, StateEventDetail, StateRecord} from './type.js';\n\n__dev_mode__: packageTracer.add(__package_name__, __package_version__);\n\nexport interface AlwatrFluxStateMachineConfig<S extends string> extends AlwatrObservableConfig {\n initialState: S;\n}\n\n/**\n * Flux (Finite) State Machine Base Class\n */\nexport abstract class AlwatrFluxStateMachineBase<S extends string, E extends string> extends AlwatrObservable<{state: S}> {\n /**\n * States and transitions config.\n */\n protected stateRecord_: StateRecord<S, E> = {};\n\n /**\n * Bind actions name to class methods\n */\n protected actionRecord_: ActionRecord<S, E> = {};\n\n protected initialState_: S;\n\n protected override message_: {state: S};\n\n constructor(config: AlwatrFluxStateMachineConfig<S>) {\n config.loggerPrefix ??= 'flux-state-machine';\n super(config);\n\n this.initialState_ = config.initialState;\n this.message_ = {state: this.initialState_};\n this.resetToInitialState_();\n }\n\n /**\n * Reset machine to initial state without notify.\n */\n protected resetToInitialState_(): void {\n this.logger_.logMethod?.('resetToInitialState_');\n const from = this.message_.state;\n this.message_ = {state: this.initialState_};\n this.postTransition__({\n from,\n event: 'reset',\n to: this.initialState_,\n });\n }\n\n /**\n * Transition condition.\n */\n protected shouldTransition_(_eventDetail: StateEventDetail<S, E>): MaybePromise<boolean> {\n this.logger_.logMethodFull?.('shouldTransition_', _eventDetail, true);\n return true;\n }\n\n /**\n * Transition flux state machine instance to new state.\n */\n protected async transition_(event: E): Promise<void> {\n const fromState = this.message_.state;\n const toState = this.stateRecord_[fromState]?.[event];\n\n this.logger_.logMethodArgs?.('transition_', {fromState, event, toState});\n\n if (toState == null) {\n this.logger_.incident?.('transition', 'invalid_target_state', {\n fromState,\n event,\n });\n return;\n }\n\n const eventDetail: StateEventDetail<S, E> = {from: fromState, event, to: toState};\n\n if ((await this.shouldTransition_(eventDetail)) !== true) return;\n\n this.notify_({state: toState}); // message update but notify event delayed after execActions.\n\n this.postTransition__(eventDetail);\n }\n\n /**\n * Execute all actions for current state.\n */\n private async postTransition__(eventDetail: StateEventDetail<S, E>): Promise<void> {\n this.logger_.logMethodArgs?.('_transitioned', eventDetail);\n\n await this.execAction__(`on_event_${eventDetail.event}`, eventDetail);\n\n if (eventDetail.from !== eventDetail.to) {\n await this.execAction__(`on_any_state_exit`, eventDetail);\n await this.execAction__(`on_state_${eventDetail.from}_exit`, eventDetail);\n await this.execAction__(`on_any_state_enter`, eventDetail);\n await this.execAction__(`on_state_${eventDetail.to}_enter`, eventDetail);\n }\n\n this.execAction__(`on_state_${eventDetail.from}_event_${eventDetail.event}`, eventDetail);\n }\n\n /**\n * Execute action name if defined in _actionRecord.\n */\n private execAction__(name: ActionName<S, E | 'reset'>, eventDetail: StateEventDetail<S, E>): MaybePromise<void> {\n const actionFn = this.actionRecord_[name];\n if (typeof actionFn === 'function') {\n this.logger_.logMethodArgs?.('_$execAction', name);\n return actionFn.call(this, eventDetail);\n }\n }\n}\n", "import {AlwatrFluxStateMachineBase} from './base.js';\n\n/**\n * Flux (Finite) State Machine Base Class\n */\nexport abstract class AlwatrFluxStateMachine<S extends string, E extends string> extends AlwatrFluxStateMachineBase<S, E> {\n /**\n * Current state.\n */\n get state(): S {\n return this.message_.state;\n }\n\n /**\n * Transition flux state machine instance to new state.\n */\n transition(event: E): void {\n this.transition_(event);\n }\n\n /**\n * Reset machine to initial state without notify.\n */\n resetToInitialState(): void {\n this.resetToInitialState_();\n }\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,qBAA4B;AAC5B,wBAA4D;AAI5D,aAAc,8BAAc,IAAI,eAAkB,OAAmB;AAS9D,IAAe,6BAAf,cAAsF,mCAA6B;AAAA,EAexH,YAAY,QAAyC;AACnD,WAAO,iBAAP,OAAO,eAAiB;AACxB,UAAM,MAAM;AAbd;AAAA;AAAA;AAAA,SAAU,eAAkC,CAAC;AAK7C;AAAA;AAAA;AAAA,SAAU,gBAAoC,CAAC;AAU7C,SAAK,gBAAgB,OAAO;AAC5B,SAAK,WAAW,EAAC,OAAO,KAAK,cAAa;AAC1C,SAAK,qBAAqB;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA,EAKU,uBAA6B;AACrC,SAAK,QAAQ,YAAY,sBAAsB;AAC/C,UAAM,OAAO,KAAK,SAAS;AAC3B,SAAK,WAAW,EAAC,OAAO,KAAK,cAAa;AAC1C,SAAK,iBAAiB;AAAA,MACpB;AAAA,MACA,OAAO;AAAA,MACP,IAAI,KAAK;AAAA,IACX,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKU,kBAAkB,cAA6D;AACvF,SAAK,QAAQ,gBAAgB,qBAAqB,cAAc,IAAI;AACpE,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAgB,YAAY,OAAyB;AACnD,UAAM,YAAY,KAAK,SAAS;AAChC,UAAM,UAAU,KAAK,aAAa,SAAS,IAAI,KAAK;AAEpD,SAAK,QAAQ,gBAAgB,eAAe,EAAC,WAAW,OAAO,QAAO,CAAC;AAEvE,QAAI,WAAW,MAAM;AACnB,WAAK,QAAQ,WAAW,cAAc,wBAAwB;AAAA,QAC5D;AAAA,QACA;AAAA,MACF,CAAC;AACD;AAAA,IACF;AAEA,UAAM,cAAsC,EAAC,MAAM,WAAW,OAAO,IAAI,QAAO;AAEhF,QAAK,MAAM,KAAK,kBAAkB,WAAW,MAAO,KAAM;AAE1D,SAAK,QAAQ,EAAC,OAAO,QAAO,CAAC;AAE7B,SAAK,iBAAiB,WAAW;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,iBAAiB,aAAoD;AACjF,SAAK,QAAQ,gBAAgB,iBAAiB,WAAW;AAEzD,UAAM,KAAK,aAAa,YAAY,YAAY,KAAK,IAAI,WAAW;AAEpE,QAAI,YAAY,SAAS,YAAY,IAAI;AACvC,YAAM,KAAK,aAAa,qBAAqB,WAAW;AACxD,YAAM,KAAK,aAAa,YAAY,YAAY,IAAI,SAAS,WAAW;AACxE,YAAM,KAAK,aAAa,sBAAsB,WAAW;AACzD,YAAM,KAAK,aAAa,YAAY,YAAY,EAAE,UAAU,WAAW;AAAA,IACzE;AAEA,SAAK,aAAa,YAAY,YAAY,IAAI,UAAU,YAAY,KAAK,IAAI,WAAW;AAAA,EAC1F;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAa,MAAkC,aAAyD;AAC9G,UAAM,WAAW,KAAK,cAAc,IAAI;AACxC,QAAI,OAAO,aAAa,YAAY;AAClC,WAAK,QAAQ,gBAAgB,gBAAgB,IAAI;AACjD,aAAO,SAAS,KAAK,MAAM,WAAW;AAAA,IACxC;AAAA,EACF;AACF;;;AC7GO,IAAe,yBAAf,cAAkF,2BAAiC;AAAA;AAAA;AAAA;AAAA,EAIxH,IAAI,QAAW;AACb,WAAO,KAAK,SAAS;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,OAAgB;AACzB,SAAK,YAAY,KAAK;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,sBAA4B;AAC1B,SAAK,qBAAqB;AAAA,EAC5B;AACF;",
6
6
  "names": []
7
7
  }
package/dist/main.mjs CHANGED
@@ -1,9 +1,9 @@
1
- /* @alwatr/fsm v3.2.2 */
1
+ /* @alwatr/fsm v4.0.0 */
2
2
 
3
3
  // src/base.ts
4
4
  import { packageTracer } from "@alwatr/nanolib";
5
5
  import { AlwatrObservable } from "@alwatr/observable";
6
- __dev_mode__: packageTracer.add("@alwatr/fsm", "3.2.2");
6
+ __dev_mode__: packageTracer.add("@alwatr/fsm", "4.0.0");
7
7
  var AlwatrFluxStateMachineBase = class extends AlwatrObservable {
8
8
  constructor(config) {
9
9
  config.loggerPrefix ?? (config.loggerPrefix = "flux-state-machine");
@@ -16,14 +16,22 @@ var AlwatrFluxStateMachineBase = class extends AlwatrObservable {
16
16
  * Bind actions name to class methods
17
17
  */
18
18
  this.actionRecord_ = {};
19
- this.message_ = { state: this.initialState_ = config.initialState };
19
+ this.initialState_ = config.initialState;
20
+ this.message_ = { state: this.initialState_ };
21
+ this.resetToInitialState_();
20
22
  }
21
23
  /**
22
24
  * Reset machine to initial state without notify.
23
25
  */
24
26
  resetToInitialState_() {
25
27
  this.logger_.logMethod?.("resetToInitialState_");
28
+ const from = this.message_.state;
26
29
  this.message_ = { state: this.initialState_ };
30
+ this.postTransition__({
31
+ from,
32
+ event: "reset",
33
+ to: this.initialState_
34
+ });
27
35
  }
28
36
  /**
29
37
  * Transition condition.
@@ -37,7 +45,7 @@ var AlwatrFluxStateMachineBase = class extends AlwatrObservable {
37
45
  */
38
46
  async transition_(event) {
39
47
  const fromState = this.message_.state;
40
- const toState = this.stateRecord_[fromState]?.[event] ?? this.stateRecord_._all?.[event];
48
+ const toState = this.stateRecord_[fromState]?.[event];
41
49
  this.logger_.logMethodArgs?.("transition_", { fromState, event, toState });
42
50
  if (toState == null) {
43
51
  this.logger_.incident?.("transition", "invalid_target_state", {
@@ -56,18 +64,14 @@ var AlwatrFluxStateMachineBase = class extends AlwatrObservable {
56
64
  */
57
65
  async postTransition__(eventDetail) {
58
66
  this.logger_.logMethodArgs?.("_transitioned", eventDetail);
59
- await this.execAction__(`on_${eventDetail.event}`, eventDetail);
67
+ await this.execAction__(`on_event_${eventDetail.event}`, eventDetail);
60
68
  if (eventDetail.from !== eventDetail.to) {
61
- await this.execAction__(`on_state_exit`, eventDetail);
62
- await this.execAction__(`on_${eventDetail.from}_exit`, eventDetail);
63
- await this.execAction__(`on_state_enter`, eventDetail);
64
- await this.execAction__(`on_${eventDetail.to}_enter`, eventDetail);
65
- }
66
- if (Object.hasOwn(this, `on_${eventDetail.from}_${eventDetail.event}`)) {
67
- this.execAction__(`on_${eventDetail.from}_${eventDetail.event}`, eventDetail);
68
- } else {
69
- this.execAction__(`on_all_${eventDetail.event}`, eventDetail);
69
+ await this.execAction__(`on_any_state_exit`, eventDetail);
70
+ await this.execAction__(`on_state_${eventDetail.from}_exit`, eventDetail);
71
+ await this.execAction__(`on_any_state_enter`, eventDetail);
72
+ await this.execAction__(`on_state_${eventDetail.to}_enter`, eventDetail);
70
73
  }
74
+ this.execAction__(`on_state_${eventDetail.from}_event_${eventDetail.event}`, eventDetail);
71
75
  }
72
76
  /**
73
77
  * Execute action name if defined in _actionRecord.
package/dist/main.mjs.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/base.ts", "../src/fsm.ts"],
4
- "sourcesContent": ["import {packageTracer} from '@alwatr/nanolib';\nimport {AlwatrObservable, type AlwatrObservableConfig} from '@alwatr/observable';\n\nimport type {ActionName, ActionRecord, StateEventDetail, StateRecord} from './type.js';\n\n__dev_mode__: packageTracer.add(__package_name__, __package_version__);\n\nexport interface AlwatrFluxStateMachineConfig<S extends string> extends AlwatrObservableConfig {\n initialState: S;\n}\n\n/**\n * Flux (Finite) State Machine Base Class\n */\nexport abstract class AlwatrFluxStateMachineBase<S extends string, E extends string> extends AlwatrObservable<{state: S}> {\n /**\n * States and transitions config.\n */\n protected stateRecord_: StateRecord<S, E> = {};\n\n /**\n * Bind actions name to class methods\n */\n protected actionRecord_: ActionRecord<S, E> = {};\n\n protected initialState_: S;\n\n protected override message_: {state: S};\n\n constructor(config: AlwatrFluxStateMachineConfig<S>) {\n config.loggerPrefix ??= 'flux-state-machine';\n super(config);\n this.message_ = {state: this.initialState_ = config.initialState};\n }\n\n /**\n * Reset machine to initial state without notify.\n */\n protected resetToInitialState_(): void {\n this.logger_.logMethod?.('resetToInitialState_');\n this.message_ = {state: this.initialState_};\n }\n\n /**\n * Transition condition.\n */\n protected shouldTransition_(_eventDetail: StateEventDetail<S, E>): MaybePromise<boolean> {\n this.logger_.logMethodFull?.('shouldTransition_', _eventDetail, true);\n return true;\n }\n\n /**\n * Transition flux state machine instance to new state.\n */\n protected async transition_(event: E): Promise<void> {\n const fromState = this.message_.state;\n const toState = this.stateRecord_[fromState]?.[event] ?? this.stateRecord_._all?.[event];\n\n this.logger_.logMethodArgs?.('transition_', {fromState, event, toState});\n\n if (toState == null) {\n this.logger_.incident?.('transition', 'invalid_target_state', {\n fromState,\n event,\n });\n return;\n }\n\n const eventDetail: StateEventDetail<S, E> = {from: fromState, event, to: toState};\n\n if ((await this.shouldTransition_(eventDetail)) !== true) return;\n\n this.notify_({state: toState});\n\n this.postTransition__(eventDetail);\n }\n\n /**\n * Execute all actions for current state.\n */\n private async postTransition__(eventDetail: StateEventDetail<S, E>): Promise<void> {\n this.logger_.logMethodArgs?.('_transitioned', eventDetail);\n\n await this.execAction__(`on_${eventDetail.event}`, eventDetail);\n\n if (eventDetail.from !== eventDetail.to) {\n await this.execAction__(`on_state_exit`, eventDetail);\n await this.execAction__(`on_${eventDetail.from}_exit`, eventDetail);\n await this.execAction__(`on_state_enter`, eventDetail);\n await this.execAction__(`on_${eventDetail.to}_enter`, eventDetail);\n }\n\n if (Object.hasOwn(this, `on_${eventDetail.from}_${eventDetail.event}`)) {\n this.execAction__(`on_${eventDetail.from}_${eventDetail.event}`, eventDetail);\n }\n else {\n // The action `all_eventName` is executed only if the action `fromState_eventName` is not defined.\n this.execAction__(`on_all_${eventDetail.event}`, eventDetail);\n }\n }\n\n /**\n * Execute action name if defined in _actionRecord.\n */\n private execAction__(name: ActionName<S, E>, eventDetail: StateEventDetail<S, E>): MaybePromise<void> {\n const actionFn = this.actionRecord_[name];\n if (typeof actionFn === 'function') {\n this.logger_.logMethodArgs?.('_$execAction', name);\n return actionFn.call(this, eventDetail);\n }\n }\n}\n", "import {AlwatrFluxStateMachineBase} from './base.js';\n\n/**\n * Flux (Finite) State Machine Base Class\n */\nexport abstract class AlwatrFluxStateMachine<S extends string, E extends string> extends AlwatrFluxStateMachineBase<S, E> {\n /**\n * Current state.\n */\n get state(): S {\n return this.message_.state;\n }\n\n /**\n * Transition flux state machine instance to new state.\n */\n transition(event: E): void {\n this.transition_(event);\n }\n\n /**\n * Reset machine to initial state without notify.\n */\n resetToInitialState(): void {\n this.resetToInitialState_();\n }\n}\n"],
5
- "mappings": ";;;AAAA,SAAQ,qBAAoB;AAC5B,SAAQ,wBAAoD;AAI5D,aAAc,eAAc,IAAI,eAAkB,OAAmB;AAS9D,IAAe,6BAAf,cAAsF,iBAA6B;AAAA,EAexH,YAAY,QAAyC;AACnD,WAAO,iBAAP,OAAO,eAAiB;AACxB,UAAM,MAAM;AAbd;AAAA;AAAA;AAAA,SAAU,eAAkC,CAAC;AAK7C;AAAA;AAAA;AAAA,SAAU,gBAAoC,CAAC;AAS7C,SAAK,WAAW,EAAC,OAAO,KAAK,gBAAgB,OAAO,aAAY;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA,EAKU,uBAA6B;AACrC,SAAK,QAAQ,YAAY,sBAAsB;AAC/C,SAAK,WAAW,EAAC,OAAO,KAAK,cAAa;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA,EAKU,kBAAkB,cAA6D;AACvF,SAAK,QAAQ,gBAAgB,qBAAqB,cAAc,IAAI;AACpE,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAgB,YAAY,OAAyB;AACnD,UAAM,YAAY,KAAK,SAAS;AAChC,UAAM,UAAU,KAAK,aAAa,SAAS,IAAI,KAAK,KAAK,KAAK,aAAa,OAAO,KAAK;AAEvF,SAAK,QAAQ,gBAAgB,eAAe,EAAC,WAAW,OAAO,QAAO,CAAC;AAEvE,QAAI,WAAW,MAAM;AACnB,WAAK,QAAQ,WAAW,cAAc,wBAAwB;AAAA,QAC5D;AAAA,QACA;AAAA,MACF,CAAC;AACD;AAAA,IACF;AAEA,UAAM,cAAsC,EAAC,MAAM,WAAW,OAAO,IAAI,QAAO;AAEhF,QAAK,MAAM,KAAK,kBAAkB,WAAW,MAAO,KAAM;AAE1D,SAAK,QAAQ,EAAC,OAAO,QAAO,CAAC;AAE7B,SAAK,iBAAiB,WAAW;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,iBAAiB,aAAoD;AACjF,SAAK,QAAQ,gBAAgB,iBAAiB,WAAW;AAEzD,UAAM,KAAK,aAAa,MAAM,YAAY,KAAK,IAAI,WAAW;AAE9D,QAAI,YAAY,SAAS,YAAY,IAAI;AACvC,YAAM,KAAK,aAAa,iBAAiB,WAAW;AACpD,YAAM,KAAK,aAAa,MAAM,YAAY,IAAI,SAAS,WAAW;AAClE,YAAM,KAAK,aAAa,kBAAkB,WAAW;AACrD,YAAM,KAAK,aAAa,MAAM,YAAY,EAAE,UAAU,WAAW;AAAA,IACnE;AAEA,QAAI,OAAO,OAAO,MAAM,MAAM,YAAY,IAAI,IAAI,YAAY,KAAK,EAAE,GAAG;AACtE,WAAK,aAAa,MAAM,YAAY,IAAI,IAAI,YAAY,KAAK,IAAI,WAAW;AAAA,IAC9E,OACK;AAEH,WAAK,aAAa,UAAU,YAAY,KAAK,IAAI,WAAW;AAAA,IAC9D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAa,MAAwB,aAAyD;AACpG,UAAM,WAAW,KAAK,cAAc,IAAI;AACxC,QAAI,OAAO,aAAa,YAAY;AAClC,WAAK,QAAQ,gBAAgB,gBAAgB,IAAI;AACjD,aAAO,SAAS,KAAK,MAAM,WAAW;AAAA,IACxC;AAAA,EACF;AACF;;;AC1GO,IAAe,yBAAf,cAAkF,2BAAiC;AAAA;AAAA;AAAA;AAAA,EAIxH,IAAI,QAAW;AACb,WAAO,KAAK,SAAS;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,OAAgB;AACzB,SAAK,YAAY,KAAK;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,sBAA4B;AAC1B,SAAK,qBAAqB;AAAA,EAC5B;AACF;",
4
+ "sourcesContent": ["import {packageTracer} from '@alwatr/nanolib';\nimport {AlwatrObservable, type AlwatrObservableConfig} from '@alwatr/observable';\n\nimport type {ActionName, ActionRecord, StateEventDetail, StateRecord} from './type.js';\n\n__dev_mode__: packageTracer.add(__package_name__, __package_version__);\n\nexport interface AlwatrFluxStateMachineConfig<S extends string> extends AlwatrObservableConfig {\n initialState: S;\n}\n\n/**\n * Flux (Finite) State Machine Base Class\n */\nexport abstract class AlwatrFluxStateMachineBase<S extends string, E extends string> extends AlwatrObservable<{state: S}> {\n /**\n * States and transitions config.\n */\n protected stateRecord_: StateRecord<S, E> = {};\n\n /**\n * Bind actions name to class methods\n */\n protected actionRecord_: ActionRecord<S, E> = {};\n\n protected initialState_: S;\n\n protected override message_: {state: S};\n\n constructor(config: AlwatrFluxStateMachineConfig<S>) {\n config.loggerPrefix ??= 'flux-state-machine';\n super(config);\n\n this.initialState_ = config.initialState;\n this.message_ = {state: this.initialState_};\n this.resetToInitialState_();\n }\n\n /**\n * Reset machine to initial state without notify.\n */\n protected resetToInitialState_(): void {\n this.logger_.logMethod?.('resetToInitialState_');\n const from = this.message_.state;\n this.message_ = {state: this.initialState_};\n this.postTransition__({\n from,\n event: 'reset',\n to: this.initialState_,\n });\n }\n\n /**\n * Transition condition.\n */\n protected shouldTransition_(_eventDetail: StateEventDetail<S, E>): MaybePromise<boolean> {\n this.logger_.logMethodFull?.('shouldTransition_', _eventDetail, true);\n return true;\n }\n\n /**\n * Transition flux state machine instance to new state.\n */\n protected async transition_(event: E): Promise<void> {\n const fromState = this.message_.state;\n const toState = this.stateRecord_[fromState]?.[event];\n\n this.logger_.logMethodArgs?.('transition_', {fromState, event, toState});\n\n if (toState == null) {\n this.logger_.incident?.('transition', 'invalid_target_state', {\n fromState,\n event,\n });\n return;\n }\n\n const eventDetail: StateEventDetail<S, E> = {from: fromState, event, to: toState};\n\n if ((await this.shouldTransition_(eventDetail)) !== true) return;\n\n this.notify_({state: toState}); // message update but notify event delayed after execActions.\n\n this.postTransition__(eventDetail);\n }\n\n /**\n * Execute all actions for current state.\n */\n private async postTransition__(eventDetail: StateEventDetail<S, E>): Promise<void> {\n this.logger_.logMethodArgs?.('_transitioned', eventDetail);\n\n await this.execAction__(`on_event_${eventDetail.event}`, eventDetail);\n\n if (eventDetail.from !== eventDetail.to) {\n await this.execAction__(`on_any_state_exit`, eventDetail);\n await this.execAction__(`on_state_${eventDetail.from}_exit`, eventDetail);\n await this.execAction__(`on_any_state_enter`, eventDetail);\n await this.execAction__(`on_state_${eventDetail.to}_enter`, eventDetail);\n }\n\n this.execAction__(`on_state_${eventDetail.from}_event_${eventDetail.event}`, eventDetail);\n }\n\n /**\n * Execute action name if defined in _actionRecord.\n */\n private execAction__(name: ActionName<S, E | 'reset'>, eventDetail: StateEventDetail<S, E>): MaybePromise<void> {\n const actionFn = this.actionRecord_[name];\n if (typeof actionFn === 'function') {\n this.logger_.logMethodArgs?.('_$execAction', name);\n return actionFn.call(this, eventDetail);\n }\n }\n}\n", "import {AlwatrFluxStateMachineBase} from './base.js';\n\n/**\n * Flux (Finite) State Machine Base Class\n */\nexport abstract class AlwatrFluxStateMachine<S extends string, E extends string> extends AlwatrFluxStateMachineBase<S, E> {\n /**\n * Current state.\n */\n get state(): S {\n return this.message_.state;\n }\n\n /**\n * Transition flux state machine instance to new state.\n */\n transition(event: E): void {\n this.transition_(event);\n }\n\n /**\n * Reset machine to initial state without notify.\n */\n resetToInitialState(): void {\n this.resetToInitialState_();\n }\n}\n"],
5
+ "mappings": ";;;AAAA,SAAQ,qBAAoB;AAC5B,SAAQ,wBAAoD;AAI5D,aAAc,eAAc,IAAI,eAAkB,OAAmB;AAS9D,IAAe,6BAAf,cAAsF,iBAA6B;AAAA,EAexH,YAAY,QAAyC;AACnD,WAAO,iBAAP,OAAO,eAAiB;AACxB,UAAM,MAAM;AAbd;AAAA;AAAA;AAAA,SAAU,eAAkC,CAAC;AAK7C;AAAA;AAAA;AAAA,SAAU,gBAAoC,CAAC;AAU7C,SAAK,gBAAgB,OAAO;AAC5B,SAAK,WAAW,EAAC,OAAO,KAAK,cAAa;AAC1C,SAAK,qBAAqB;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA,EAKU,uBAA6B;AACrC,SAAK,QAAQ,YAAY,sBAAsB;AAC/C,UAAM,OAAO,KAAK,SAAS;AAC3B,SAAK,WAAW,EAAC,OAAO,KAAK,cAAa;AAC1C,SAAK,iBAAiB;AAAA,MACpB;AAAA,MACA,OAAO;AAAA,MACP,IAAI,KAAK;AAAA,IACX,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKU,kBAAkB,cAA6D;AACvF,SAAK,QAAQ,gBAAgB,qBAAqB,cAAc,IAAI;AACpE,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAgB,YAAY,OAAyB;AACnD,UAAM,YAAY,KAAK,SAAS;AAChC,UAAM,UAAU,KAAK,aAAa,SAAS,IAAI,KAAK;AAEpD,SAAK,QAAQ,gBAAgB,eAAe,EAAC,WAAW,OAAO,QAAO,CAAC;AAEvE,QAAI,WAAW,MAAM;AACnB,WAAK,QAAQ,WAAW,cAAc,wBAAwB;AAAA,QAC5D;AAAA,QACA;AAAA,MACF,CAAC;AACD;AAAA,IACF;AAEA,UAAM,cAAsC,EAAC,MAAM,WAAW,OAAO,IAAI,QAAO;AAEhF,QAAK,MAAM,KAAK,kBAAkB,WAAW,MAAO,KAAM;AAE1D,SAAK,QAAQ,EAAC,OAAO,QAAO,CAAC;AAE7B,SAAK,iBAAiB,WAAW;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,iBAAiB,aAAoD;AACjF,SAAK,QAAQ,gBAAgB,iBAAiB,WAAW;AAEzD,UAAM,KAAK,aAAa,YAAY,YAAY,KAAK,IAAI,WAAW;AAEpE,QAAI,YAAY,SAAS,YAAY,IAAI;AACvC,YAAM,KAAK,aAAa,qBAAqB,WAAW;AACxD,YAAM,KAAK,aAAa,YAAY,YAAY,IAAI,SAAS,WAAW;AACxE,YAAM,KAAK,aAAa,sBAAsB,WAAW;AACzD,YAAM,KAAK,aAAa,YAAY,YAAY,EAAE,UAAU,WAAW;AAAA,IACzE;AAEA,SAAK,aAAa,YAAY,YAAY,IAAI,UAAU,YAAY,KAAK,IAAI,WAAW;AAAA,EAC1F;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAa,MAAkC,aAAyD;AAC9G,UAAM,WAAW,KAAK,cAAc,IAAI;AACxC,QAAI,OAAO,aAAa,YAAY;AAClC,WAAK,QAAQ,gBAAgB,gBAAgB,IAAI;AACjD,aAAO,SAAS,KAAK,MAAM,WAAW;AAAA,IACxC;AAAA,EACF;AACF;;;AC7GO,IAAe,yBAAf,cAAkF,2BAAiC;AAAA;AAAA;AAAA;AAAA,EAIxH,IAAI,QAAW;AACb,WAAO,KAAK,SAAS;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,OAAgB;AACzB,SAAK,YAAY,KAAK;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,sBAA4B;AAC1B,SAAK,qBAAqB;AAAA,EAC5B;AACF;",
6
6
  "names": []
7
7
  }
package/dist/type.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- export interface StateEventDetail<S, E> {
1
+ export interface StateEventDetail<S extends string, E extends string> {
2
2
  from: S;
3
- event: E;
3
+ event: E | 'reset';
4
4
  to: S;
5
5
  }
6
- export type StateRecord<S extends string, E extends string> = Partial<Record<S | '_all', Partial<Record<E, S>>>>;
7
- export type Action<S extends string, E extends string> = (eventDetail?: StateEventDetail<S, E>) => MaybePromise<void>;
8
- export type ActionName<S extends string, E extends string> = `on_${E}` | `on_state_exit` | `on_state_enter` | `on_${S}_exit` | `on_${S}_enter` | `on_${S}_${E}` | `on_all_${E}`;
9
- export type ActionRecord<S extends string, E extends string> = Partial<Record<ActionName<S, E>, Action<S, E>>>;
6
+ export type StateRecord<S extends string, E extends string> = Partial<Record<S, Partial<Record<E | 'reset', S>>>>;
7
+ export type Action<S extends string, E extends string> = (eventDetail?: StateEventDetail<S, E | 'reset'>) => MaybePromise<void>;
8
+ export type ActionName<S extends string, E extends string> = `on_event_${E}` | `on_any_state_exit` | `on_any_state_enter` | `on_state_${S}_exit` | `on_state_${S}_enter` | `on_state_${S}_event_${E}`;
9
+ export type ActionRecord<S extends string, E extends string> = Partial<Record<ActionName<S, E | 'reset'>, Action<S, E | 'reset'>>>;
10
10
  //# sourceMappingURL=type.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../src/type.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB,CAAC,CAAC,EAAE,CAAC;IACpC,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,EAAE,CAAC,CAAC;IACT,EAAE,EAAE,CAAC,CAAC;CACP;AAED,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAEjH,MAAM,MAAM,MAAM,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,IAAI,CAAC,WAAW,CAAC,EAAE,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,YAAY,CAAC,IAAI,CAAC,CAAC;AAEtH,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,IACrD,MAAM,CAAC,EAAE,GACT,eAAe,GACf,gBAAgB,GAChB,MAAM,CAAC,OAAO,GACd,MAAM,CAAC,QAAQ,GACf,MAAM,CAAC,IAAI,CAAC,EAAE,GACd,UAAU,CAAC,EAAE,CAAC;AAElB,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../src/type.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM;IAClE,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC;IACnB,EAAE,EAAE,CAAC,CAAC;CACP;AAED,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAElH,MAAM,MAAM,MAAM,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,IAAI,CAAC,WAAW,CAAC,EAAE,gBAAgB,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,KAAK,YAAY,CAAC,IAAI,CAAC,CAAC;AAEhI,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,IACrD,YAAY,CAAC,EAAE,GACf,mBAAmB,GACnB,oBAAoB,GACpB,YAAY,CAAC,OAAO,GACpB,YAAY,CAAC,QAAQ,GACrB,YAAY,CAAC,UAAU,CAAC,EAAE,CAAC;AAE/B,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alwatr/fsm",
3
- "version": "3.2.2",
3
+ "version": "4.0.0",
4
4
  "description": "A robust TypeScript library for implementing Flux (Finite) State Machines, enabling clear and organized management of application state and transitions.",
5
5
  "author": "S. Ali Mihandoost <ali.mihandoost@gmail.com> (https://ali.mihandoost.com)",
6
6
  "keywords": [
@@ -58,17 +58,17 @@
58
58
  "clean": "rm -rfv dist *.tsbuildinfo"
59
59
  },
60
60
  "dependencies": {
61
- "@alwatr/nanolib": "^5.0.0",
62
- "@alwatr/observable": "^3.2.2"
61
+ "@alwatr/nanolib": "^5.1.0",
62
+ "@alwatr/observable": "^4.0.0"
63
63
  },
64
64
  "devDependencies": {
65
65
  "@alwatr/nano-build": "^5.0.0",
66
66
  "@alwatr/prettier-config": "^5.0.0",
67
67
  "@alwatr/tsconfig-base": "^5.0.0",
68
68
  "@alwatr/type-helper": "^5.0.0",
69
- "@types/node": "^22.8.6",
69
+ "@types/node": "^22.9.0",
70
70
  "jest": "^29.7.0",
71
71
  "typescript": "^5.6.3"
72
72
  },
73
- "gitHead": "4952c4c6c9758dfcd30e9bc584aec25f10169219"
73
+ "gitHead": "88875a7de14d10fd1e4c0288182dccf4f87cdc62"
74
74
  }