npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

typestate

v1.0.6

Published

A small finite state machine implementation in TypeScript.

Downloads

13,082

Readme

Build Status npm version NuGet version Bower version

TypeState

TypeState is a strongly typed finite state machine for TypeScript or JavaScript. Finite state machines are useful for modeling complicated flows and keeping track of state.

Installation

Install-Package TypeState

npm install typestate

bower install typestate

Basic Example

// Let's model the states of an elevator

// Define an Enum with all possible valid states
enum Elevator {
   DoorsOpened,
   DoorsClosed,
   Moving
}

// Construct the FSM with the inital state, in this case the elevator starts with its doors opened
var fsm = new TypeState.FiniteStateMachine<Elevator>(Elevator.DoorsOpened);

// Declare the valid state transitions to model your system

// Doors can go from opened to closed, and vice versa
fsm.from(Elevator.DoorsOpened).to(Elevator.DoorsClosed);
fsm.from(Elevator.DoorsClosed).to(Elevator.DoorsOpened);

// Once the doors are closed the elevator may move
fsm.from(Elevator.DoorsClosed).to(Elevator.Moving);

// When the elevator reaches its destination, it may stop moving
fsm.from(Elevator.Moving).to(Elevator.DoorsClosed);

// Check that the current state is the initial state
if(fsm.is(Elevator.DoorsOpened)){
   console.log("The doors are open Dave");  
}


// Test validity of transitions from the current state, in this case 'Elevator.DoorsOpened'
fsm.canGo(Elevator.DoorsClosed); // returns true
fsm.canGo(Elevator.Moving); //returns false

// Go to a new state, closing the elevator doors. 
fsm.go(Elevator.DoorsClosed); // The fsm.currentState is now set to 'Elevator.DoorsClosed'

// The elevator can now move or open the doors again
fsm.canGo(Elevator.Moving); // returns true
fsm.canGo(Elevator.DoorsOpened); //returns true

Using JavaScript

JavaScript is easy with TypeState. The finite state machine relies on states that can be converted to strings with the .toString() method. So to use JavaScript simple replace the top few lines of the previous example with the following:

var Elevator = {
	DoorsOpened : "DoorsOpened",
	DoorsClosed : "DoorsClosed",
	Moving : "Moving"
}

var fsm = new FiniteStateMachine(Elevator.DoorsOpened)

Listening for state changes

TypeState allows you to listen to state changes. For example if the elevator starts moving, we would like to play some elevator music. Additionally we would like to stop the music when the elevator stops.


fsm.on(Elevator.Moving, (from: Elevator)=>{
	playGroovyElevatorMusic();
});

fsm.on(Elevator.DoorsClosed, (from: Elevator)=>{
	stopGroovyElevatorMusic();
});

Interrupting Transitions

Sometimes you need to interrupt transitions. You may interrupt transitions to a state with onEnter(STATE, CALLBACK) and interrupt transitions from a state with the onExit(STATE, CALLBACK). If the CALLBACK returns false the transition is canceled and the state will not change.


console.log("DoorsOpened", fsm.currentState === Elevator.DoorsOpened); // true
var handsInDoor = true;

// Listen for transitions to DoorsClosed, if the callback returns false the transition is canceled.
fsm.onEnter(Elevator.DoorsClosed, (from: Elevator)=>{
   if(handsInDoor){
      return false;
   }
   return true;
});

// Attempt to transition
fsm.go(Elevator.DoorsClosed);

// State does not change to DoorsClosed
console.log("DoorsOpened", fsm.currentState === Elevator.DoorsOpened); //true

Wildcard Transitions

If all transitions to or from a certain state are valid, there are a convience wildcard methods fromAny(STATE_ENUM) and toAny(STATE_ENUM) for such cases.


enum ValidStates {
	A,
	B,
	C,
	D
}

var newFsm = new TypeState.FiniteStateMachine<ValidStates>(ValidStates.A);
newFsm.from(ValidStates.A).toAny(ValidStates);
newFsm.fromAny(ValidStates).to(ValidStates.B);