Giter VIP home page Giter VIP logo

fsm-async's Introduction

fsm-async

Build Status GitHub license Semver GitHub Releases GitHub Issues

A state machine implementation featuring:

  1. on<state> life-cycle events, allowing the triggering of further (internal) events during the callback.

  2. async event functions that can be awaited. Depending on the implemented logic, multiple state changes can be awaited.

  3. Generic and awaitable waitUntilStateEnters(<state>) and waitUntilStateLeaves(<state>) functions providing full flexibility to state machine clients business logic.

Example

Define the transition table as a json object,

const transitionTable = {
  initial: 'disconnected',
  transitions: [
    { ev: 'connect', from: 'disconnected', to: 'connecting' },
    { ev: '_connectDone', from: 'connecting', to: 'connected' },
    { ev: 'disconnect', from: 'connected', to: 'disconnecting' },
    { ev: '_disconnectDone', from: 'disconnecting', to: 'disconnected' }
  ]
}

then apply this logic to your object:

const StateMachine = require('fsm-async')

class MyClient extends StateMachine {

  constructor () {
    const transitionTable = {
      initial: 'disconnected',
      transitions: [
        { ev: 'connect', from: 'disconnected', to: 'connecting' },
        { ev: '_connectDone', from: 'connecting', to: 'connected' },
        { ev: 'disconnect', from: 'connected', to: 'disconnecting' },
        { ev: '_disconnectDone', from: 'disconnecting', to: 'disconnected' }
      ]
    }
    super(transitionTable)
  }
}

This injects the events as proper callable functions to your instance, hence you can write:

myClient = new MyClient()
myClient.connect()

In the body of your class you can define life-cycle functions on<event> and on<state>, which are automatically called and can be used to trigger further events:

const StateMachine = require('fsm-async')

class MyClient extends StateMachine {

  constructor () {
    const transitionTable = {
      initial: 'disconnected',
      transitions: [
        { ev: 'connect', from: 'disconnected', to: 'connecting' },
        { ev: '_connectDone', from: 'connecting', to: 'connected' },
        { ev: 'disconnect', from: 'connected', to: 'disconnecting' },
        { ev: '_disconnectDone', from: 'disconnecting', to: 'disconnected' }
      ]
    }
    super(transitionTable)
  }

  // Use async here to be able to await internally
  async onConnecting () {
    // Simulate connection establishment
    await new Promise(resolve => setTimeout(resolve, 1000))
    // Internally trigger an event bringing the machine to connected state
    this._connectDone()
  }

  async onDisconnecting () {
    // Simulate disconnection
    await new Promise(resolve => setTimeout(resolve, 1000))
    // Internally trigger an event bringing the machine to disconnected state
    this._disconnectDone()
  }
}

Now, outer code can await the connect() of your client and/or use other utility functions injected by the StateMachine. The utility functions are:

  1. getState() returns current state
  2. waitUntilStateEnters(<state>) waits until a given state is entered
  3. waitUntilStateLeaves(<state>) waits until a given state is left
  4. onStateChange(<callback(state)>) notifies about state changes
  5. onInvalidTransition(<callback(event, state)>) notifies about invalid transitions

The StateMachine class at the same time is an event emitter. Hence,

stateMachine.on('state', <callback(state)>)
stateMachine.on('invalidTransition', <callback(event, state)>)

is also possible.

Please see the provided example code (examples folder) for more details and usage patterns.

You can run the example code via:

npm run example

fsm-async's People

Contributors

bheisen avatar cstim avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.