Skip to content

TS-FSM is a strongly typed finite state machine for TypeScript that is using async operations. Library uses generics to take the user states and events. Zero dependencies!

License

Notifications You must be signed in to change notification settings

WebLegions/typescript-fsm

Repository files navigation

TypeScript State Machine (typescript-fsm)

Build Status npm package It's already here!

Finite state machines are useful for modeling complicated flows and keeping track of state. TS-FSM is a strongly typed finite state machine for TypeScript that is using promises for async operations. I'm using this state-machine as a simple replacement for Redux in some ReactJs based apps. Example here

Features

  • TypeScript native (compiles to ES6)
  • Only 1 KB (minified) and zero dependencies!!!
  • Hooks after state change - - async or sync callbacks
  • Promises are used for async transition completion
  • Generics for states and events types
  • Simple tabular state machine definition
  • Use with NodeJS or JS client

Get it

git clone https://github.com/eram/typescript-fsm.git cd typescript-fsm npm install npm test 

Use it

npm install typescript-fsm 

Basic Example

I'm modeling a "door" here. One can open the door, close it or break it. Each action is done async: when you open it goes into opening state and then resolved to opened state etc. Once broken, it reaches a final state.

Door state machine

Let's code it in Typescript! Note that the same code can be run in Javascript, just remove the generics.

import { t, StateMachine } from "typescript-fsm"; // these are the states and events for the door enum States { closing = 0, closed, opening, opened, broken }; enum Events { open = 100, openComplete, close, closeComplete, break }; // lets define the transitions that will govern the state-machine const transitions = [ /* fromState event toState callback */ t(States.closed, Events.open, States.opening, onOpen), t(States.opening, Events.openComplete, States.opened, justLog), t(States.opened, Events.close, States.closing, onClose), t(States.closing, Events.closeComplete, States.closed, justLog), t(States.closed, Events.break, States.broken, justLog), t(States.opened, Events.break, States.broken, justLog), t(States.opening, Events.break, States.broken, justLog), t(States.closing, Events.break, States.broken, justLog), ]; // initialize the state machine const door = new StateMachine<States, Events>( States.closed, // initial state transitions, // array of transitions  ); // transition callbacks - async functions async function onOpen() { console.log("onOpen..."); return door.dispatch(Events.openComplete); } async function onClose() { console.log("onClose..."); return door.dispatch(Events.closeComplete); } // synchronous callbacks are also ok function justLog() { console.log(`${States[door.getState()]}`); } // we are ready for action - run a few state-machine steps... new Promise(async (resolve) => { // open the door and wait for it to be opened await door.dispatch(Events.open); door.getState(); // => States.opened // check if the door can be closed door.can(Events.close); // => true // break the door async door.dispatch(Events.break).then(() => { // did we get to a finite state? door.isFinal(); // => true  }); // door is now broken. It cannot be closed... try { await door.dispatch(Events.close); assert("should not get here!"); } catch (e) { // we're good } // let the async complete setTimeout(resolve, 10); });

Another example

Check out the test code - a class that implements a state machine with method binding, method params and more transitions. 100% coverage here!

Beautiful :-)

Comments and suggestions are welcome.

About

TS-FSM is a strongly typed finite state machine for TypeScript that is using async operations. Library uses generics to take the user states and events. Zero dependencies!

Topics

Resources

License

Security policy

Stars

Watchers

Forks

Packages

No packages published

Contributors 9