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

@crux/fsm

v0.0.26-alpha

Published

`fsm` is an asynchronous Finite State Machine with a simple API.

Downloads

18

Readme

@crux/fsm

fsm is an asynchronous Finite State Machine with a simple API.

Installation

npm install --save @crux/fsm

Usage

The following example shows a very simple state machine. It has two states: idle and running, and two actions: go and stop.

import { createFSM } from '@crux/fsm';

const machine = createFSM({
  idle: {
    go: () => 'running',
  },
  running: {
    stop: () => 'idle'
  }
}, { initialState: 'idle' });

Notice that the idle state has no stop action, and the running state has no go action, because these actions are meaningless for those states - you can't make a machine stop if it's idle, etc.

We've defined idle as the initial state, so let's transition the machine to running by providing the go action:

await machine.transition('go');

machine.getState() // `running`

We had to await the transition because it's asynchronous. The main reason for this is that you can listen to state transitions and if your handlers are asynchronous too, you can make the machine wait until you're done before it transitions. This gives you control over when it transitions and what you can do before and after it does.

Adding listeners to the machine

machine.onEnter(({ action, current, last )) => {
  console.log(`Transition from "${last}" to "${current}" with the "${action}" action`);
});

machine.transition('go');

// Console output:
// Transition from "idle" to "running" with the "go" action

Let's see how we can delay the transition of the machine to allow us to do some clean up work before the next state. Note that this time we're using the OnExit event:

machine.onExit({ action, current )) => new Promise(resolve => {
  // do some clean up work, then...
  resolve();
}));

machine.transition('go');

This will ensure that we stay in the idle state until the Promise resolves. Only then will it transition to running.

Unsubscribing from events

The listener methods return a function to allow you to unsubscribe:

const unsubscribe = machine.onExit(() => {});

unsubscribe(); // listener destroyed

Shorthand methods

machine.transition(...) is a little ugly. Luckily fsm builds shorthand methods for each of your actions. So, transitioning our example is as simple as:

machine.go(); // new state is 'running'

machine.stop(); // new state is 'idle'

fsm doesn't just build shorthand methods for transitions, but also for state changes:

machine.onIdle((data) => {});

// You can also unsubscribe as with the onEnter and onExit handlers.
const unsubscribe = machine.onRunning((data) => {});

unsubscribe();

TypeScript support

fsm knows which are your states and which are your actions, and will throw TS errors when you try to transition with an action that doesn't exist. This applies to both transition and the shorthand methods:

machine.goForth(); // Property 'goForth' does not exist on type...

machine.transition('goForth'); // Argument of type '"goForth"' is not assignable to parameter of type...

fsm also types the data of emitted events

machine.onEnter(data => console.log(data)); // data type is { action: keyof Actions, current: keyof State, last: keyof State )