From a85702fd7b480218f3529b12270182dda558e6c2 Mon Sep 17 00:00:00 2001 From: Dmitriy Pleshevskiy Date: Thu, 17 Oct 2019 13:54:15 +0300 Subject: [PATCH] fix: fix int enum bugs --- README.md | 32 ++++++++++++++++++++++++++++ package-lock.json | 2 +- package.json | 2 +- src/index.ts | 53 +++++++++++++++++++++++++++++++++-------------- 4 files changed, 72 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index b8d8479..78805c7 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,35 @@ # IT FSM Simple finite state machine + + +### Installation + +`npm install --save it-fsm` + + + +### Usage + +```javascript +import { StateMachine } from 'it-fsm'; + +const fsm = new StateMachine('TODO', { + TODO: { + complete: 'COMPLETE' + } +}) + + +if (fsm.can('complete')) { + fsm.complete().then(() => { + + }) +} +// or +if (fsm.canToState('COMPLETE')) { + fsm.complete().then(() => { + + }); +} +``` diff --git a/package-lock.json b/package-lock.json index aa00489..4db12e0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "rusn", + "name": "it-fsm", "version": "1.0.3", "lockfileVersion": 1, "requires": true, diff --git a/package.json b/package.json index 1f63bd4..dc381bb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "it-fsm", - "version": "1.0.2", + "version": "1.0.3", "description": "Simple finite state machine for nodejs", "main": "./src/index.js", "types": "./src/index.d.ts", diff --git a/src/index.ts b/src/index.ts index 951fb9a..a128275 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,56 +1,77 @@ export type Payload = Record -export type SystemEvent = (event: string, fromState: string, toState: string, +export type StateType = string | number +export type ActionConfigMap = Record +export type ActionEvent = (event: string, fromState: string, toState: string, payload: Payload) => Promise -export interface StateEvents { - [key: string]: string +export interface IConfig { + [key: string]: ActionEvent | ActionConfigMap + onEnter: ActionEvent + onLeave: ActionEvent } +export interface IActionConfig { + state: StateType + onBeforeChange?: ActionEvent + onChange?: ActionEvent +} export class StateMachine { [key: string]: any; private _currentState: string; - private _onEnter: SystemEvent; + private _onEnter: ActionEvent; + private _onLeave: ActionEvent; private _eventsByState: Record any>> = {}; private _statesByState: Record = {}; - constructor(initial: string, config: Record) { - this._currentState = initial; + constructor(initial: StateType, config: IConfig) { + this._currentState = initial.toString(); for (let fromState in config) { - if (fromState === 'onEnter') { - this._onEnter = config.onEnter as SystemEvent; + if (['onEnter', 'onLeave'].includes(fromState)) { + this._onEnter = config.onEnter; continue } this._statesByState[fromState] = []; - let events = config[fromState] as StateEvents; - for (let eventName in events) { - let toState: string = events[eventName]; - this._statesByState[fromState].push(toState); - this._initChangeState(eventName, fromState, toState) + let actions = config[fromState] as ActionConfigMap; + for (let actionName in actions) { + let action = actions[actionName]; + let actionConfig: IActionConfig = action.constructor === Object ? + action as IActionConfig + : { state: action as StateType }; + + this._statesByState[fromState].push(actionConfig.state.toString()); + this._initChangeState(actionName, fromState, actionConfig.state.toString(), actionConfig); } } } - private _initChangeState(eventName: string, fromState: string, toState: string): void { + private _initChangeState(eventName: string, fromState: string, toState: string, actionConfig: IActionConfig): void { if (!this._eventsByState[fromState]) { this._eventsByState[fromState] = {}; } + const { onBeforeChange, onChange } = actionConfig; + this._eventsByState[fromState][eventName] = async (payload: Payload = {}) => { + console.log(this._currentState, typeof this._currentState, fromState, typeof fromState); if (this._currentState !== fromState) { return; } - await this._onEnter(eventName, fromState, toState, payload); + this._onEnter && await this._onEnter(eventName, fromState, toState, payload); + onBeforeChange && await onBeforeChange(eventName, fromState, toState, payload); this._currentState = toState; + onChange && await onChange(eventName, fromState, toState, payload); + this._onLeave && await this._onLeave(eventName, fromState, toState, payload) + return this; }; @@ -60,6 +81,8 @@ export class StateMachine { && this._eventsByState[this._currentState][eventName]) { return this._eventsByState[this._currentState][eventName](payload); } + + console.log(this._eventsByState, this._currentState, eventName) } } }