State machine and state transition management utility class
Find a file
2025-12-03 10:27:55 -05:00
src Per-state out functions 2025-12-03 10:27:55 -05:00
.gitignore Initial commit 2025-12-02 16:30:10 -05:00
biome.json Add license and run fmt 2025-12-02 17:51:38 -05:00
bun.lock Initial commit 2025-12-02 16:30:10 -05:00
LICENSE Add license and run fmt 2025-12-02 17:51:38 -05:00
Makefile Initial commit 2025-12-02 16:30:10 -05:00
package.json Per-state out functions 2025-12-03 10:27:55 -05:00
README.md Per-state out functions 2025-12-03 10:27:55 -05:00
tsconfig.json Initial commit 2025-12-02 16:30:10 -05:00

State Machine

State machine and state transition management utility class

Usage

The StateMachine class is generic and takes an enum defining the possible states:

enum States {
  Connecting,
  Connected,
  Disconnected,
}

const machine = new StateMachine<States>({
  // The starting state of the machine
  initial: States.Connecting,

  // All state transitions.
  // States must define an `in` transition for other states to be able to
  // change to it.
  transitions: {
    // An empty object means that no state can transition to this.
    // Useful especially for initial states that cannot be returned to.
    [States.Connecting]: {},

    // For each state, define `in` and optional `out` functions
    [States.Connected]: {
      in: {
        [States.Connecting]: () => {
          console.log("Connected!");
        },
      },

      // Specifying a function instead of a map for in/out is a global transition
      out: () => {
        console.log("Oh, if we're not connected anymore, thats bad!");
      },
    },
    [States.Disconnected]: {
      // `in: true` is shorthand for "anything can transition to this"
      // Specifying a global transition function for `in` also allows all
      in: true,
    },
  },
});

// Prints "Connected!"
fakeEvents.on("connected", () => machine.change(States.Connected));

// Prints "Oh, if we're not connected anymore, that's bad!"
fakeEvents.on("error", () => machine.change(States.Disconnected));