mata v0.0.1
Mata
This is an early work in progress, consider this an unsupported speculative draft
A small finite-state automata framework for JS, built with first-class TypeScript support.
For example, let's say we want to represent a login flow for a user in a web 
application. Our application state has a User object:
interface User {
    admin: boolean
    authed: boolean
}
let user: User = {
    admin: false,
    authed: false,
};Defining a state machine
We can define a state machine for our User type which will represent the
navigation flow for logging in.
const fsm = new mata.Machine<User>({The Machine constructor takes a single Initializer object which has two
required keys machine and config. The machine key is the definition
of the state machine. It is of the form: { from: { to: condition } }:
    machine: {
        signIn: {
            adminView: (u) => u.admin,
            userView: (u) => u.authed && !u.admin
        },
        adminView: {
            signOut: (u) => !u.authed
        },
        userView: {
            signOut: (u) => !u.authed        
        },
        signOut: {
            signIn: mata.Continue 
        }
    },So if the machine is in the state adminView, it will transition to the state
signOut if the user.authed property is false.
The other part of the Initialization argument is config. It requires an
init argument of the form (states: ValidStates) => State. The states
argument is a lookup table of every known state.
    config: {
        init: (states) => states.signIn
    }
});Running a state machine
At runtime, the state property represents the current state. The states
property is a lookup table for all valid states. 
fsm.state === fsm.states.signIn; // initial stateThe next(input) method causes the state machine to transition to the next
valid state with a condition that returns true for input.
user.authed = true;
fsm.next(user);
fsm.state === fsm.states.userView;next doesn't always cause a state change – if no condition is satisfied then
the state remains the same.
fsm.next(user);
fsm.state === fsm.states.userView;Observing a state machine
The subscribe method registers a listener function that is executed every 
time the state transitions. The Listener is of the type 
(e: TransitionEvent) => void. The TransitionEvent includes from, to and
input keys. NOTE: The input will be null if transition is invoked manually.
fsm.subscribe(({ from, to, input }) => {
    console.log(`Transition: ${from} --> ${to} for ${input}`);
});
user.authed = false;
fsm.next(user);
// Transition: userView --> signOut for { authed: false, admin: false }If you wish to detach your Listener, store the return value of
subscribe, it is a function which will unsubscribe your new listener when
executed:
const unsubscribe = fsm.subscribe(({ from, to, input }) => { });
// ... later
unsubscribe(); // listener will no longer executeVisualizing a state machine
mata/visualizers provides some functions for turning a state machine into
a graph description. Currently Mermaid and 
Dot are supported. The example
state machine from this readme looks like:
toMermaid:
toDot:
8 years ago