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 🙏

© 2026 – Pkg Stats / Ryan Hefner

unlimited-machine-works

v1.1.5

Published

The unlimited working 1KB state machine library for the web!

Readme

Table of Contents

Rationale

When you think about it, web applications can be modeled as state machines. You should only jump from one state to another and not magically end up in another in an unpredictable manner. You should only make transitions that are possible for your current state. Modeling your web application as a state machine makes managing the flow of your application much easier as it makes your application more predictable. This is the main driving force of building this library.

How to import

Import on the browser

<script src="https://cdn.jsdelivr.net/npm/[email protected]/umw.min.js" async></script>

Import on Node

const UMW = require('unlimited-machine-works')

Quickstart

Creating a machine

You can use the summon or make methods to create a machine.

const machine = UMW.summon({name: 'Attack Helicopter', speed: 0}, {
  'INITIAL': {
    'MOVE': {
      to: 'MOVING',
      action: (data, args) => {
        return Object.assign({}, data, {speed: 1})
      }
    }
  },
  'MOVING': {
    'ACCELERATE': {
      to: 'MOVING',
      action: (data, args) => {
        return Object.assign({}, data, {speed: data.speed + 1})
      }
    },
    'ACCELERATE_BY': {
      to: 'MOVING',
      action: (data, args) => {
        return Object.assign({}, data, {speed: data.speed + args.speed})
      }
    },
    'STOP': {
      to: 'INITIAL',
      action: (data, args) => {
        return Object.assign({}, data, {speed: 0})
      }
    }
  }
})

Creating a Machine Explained

The first argument of creating a machine is an object that contains the initial data that you want to manage alongside your state and transitions. The second argument is optional if you don't want to add states upon machine creation. The second argument allows you to add states and transitions upon creating the machine.

Take a look at this snippet from the above code:

'INITIAL': {
  'MOVE': {
    to: 'MOVING',
    action: (data, args) => {
      return Object.assign({}, state, {speed: 1})
    }
  }
}

The INITIAL key is a state. Each state should have at least transition or else you won't be able to state. In this case, MOVE is the transition of the INITIAL state. The to key of a transition specifies to which state to go to after the transition. The action key of a transition should be a function that accepts the current data and the arguments given when the transition is called. The return value will replace the data that was originally given.

Checking what transitions you can do

You can use the actions method of your machine to check. This will return the transition names as an array of strings.

console.log(machine.actions); // [ 'MOVE' ]

Doing a transition

You can use the do method of your machine to execute a transition.

machine.do('MOVE')

If the transition defined requires additional arguments, you can add an object with the arguments as the second argument.

machine.do('ACCELERATE_BY', {speed: 4})

speed can be accessed from the args object. Check the snippet above.

Reacting to transitions

You can react to transitions by adding a subscriber to the machine using the addSubscriber method. The method takes a function which receives the new state and data after the transition. You can then do things like rendering elements in this function.

This piece of code will log the current speed data everytime a transition occurs.

machine.addSubscriber((state, data) => {
  console.log(`Speed: ${data.speed}`)
})

Graphics Credits

Logo by my sister Jade Ada (@blondiewiththebadhair).

Other Icons

Roadmap

  • [x] Create react-umw
  • [x] Using asynchronous functions for subscribers and other things
  • [ ] Using Proxy objects to detect change
  • [ ] Data diffing
  • [ ] Adding summon() flag for verbose errors
  • [ ] Adding subscribers as a part of the spec
  • [ ] Move addSubscribers() in to an Adding Subscribers Dynamically section
  • [ ] Add tests
  • [ ] Add status badges
  • [ ] Add Flow
  • [ ] Add visualization

Inspired By

  • Stent
  • Hyperapp

License

MIT