Security News
ESLint is Now Language-Agnostic: Linting JSON, Markdown, and Beyond
ESLint has added JSON and Markdown linting support with new officially-supported plugins, expanding its versatility beyond JavaScript.
The xstate npm package is a library for creating, interpreting, and executing finite state machines and statecharts, as well as managing invocations of those machines as actors. It provides a robust framework for modeling and analyzing application logic in a composable and declarative way, which can help manage complex state logic in UIs, robotics, and other systems.
Finite State Machines
This feature allows you to create simple finite state machines. The code sample demonstrates a toggle machine with two states: 'active' and 'inactive'.
{"import { Machine } from 'xstate';\n\nconst toggleMachine = Machine({\n id: 'toggle',\n initial: 'inactive',\n states: {\n inactive: { on: { TOGGLE: 'active' } },\n active: { on: { TOGGLE: 'inactive' } }\n }\n});"}
Statecharts
This feature allows you to create statecharts, which are an extension of state machines that can have hierarchical and parallel states. The code sample shows a traffic light machine with three states: 'green', 'yellow', and 'red'.
{"import { Machine } from 'xstate';\n\nconst lightMachine = Machine({\n id: 'light',\n initial: 'green',\n states: {\n green: { on: { TIMER: 'yellow' } },\n yellow: { on: { TIMER: 'red' } },\n red: { on: { TIMER: 'green' } }\n }\n});"}
Interpreters
This feature allows you to interpret and execute the state machines and statecharts. The code sample demonstrates how to start a service that interprets the toggleMachine and logs state transitions.
{"import { interpret } from 'xstate';\n\nconst service = interpret(toggleMachine).onTransition((state) => console.log(state.value));\n\nservice.start();\nservice.send('TOGGLE');\nservice.send('TOGGLE');"}
Actors
This feature allows you to manage machine invocations as actors, which can send and receive events from other machines. The code sample shows how to spawn a child machine within a parent machine's context.
{"import { spawn, Machine } from 'xstate';\n\nconst parentMachine = Machine({\n context: {\n child: null\n },\n entry: ['spawnChild']\n}, {\n actions: {\n spawnChild: assign({\n child: () => spawn(someMachine)\n })\n }\n});"}
robot3 is a functional, immutable finite state machine library with a similar API to xstate. It is smaller in size but does not offer the full range of features such as hierarchical and parallel states.
state-machine-cat allows you to visualize state machines and statecharts. While it does not execute state machines like xstate, it is useful for documentation and analysis purposes.
redux-saga is a library that handles side effects in Redux applications using sagas, which are similar to state machines. It is more focused on managing side effects than modeling state, unlike xstate which is more general-purpose.
Simple, stateless JavaScript finite-state machines.
What is it? Estado is a tiny, framework-agnostic JS library for representing finite-state machines and hierarchical state machines, or Harel statecharts. Its main use is as a pure (extended) transition function of the form (state, action) -> state
.
Why? (Article coming soon!) TL;DR: Finite state machines are extremely useful for representing the various states your application can be in, and how each state transitions to another state when an action is performed. Also, declaring your state machine as data (Estado language parses to pure JSON, and is SCXML-compatible) means you can use your state machine, well, anywhere. Any language.
Example? See a non-trivial example here to get an idea of how it works with React and Redux.
npm install estado --save
import { machine } from 'estado';
let lightMachine = machine(`
green -> yellow (TIMER)
yellow -> red (TIMER)
red -> green (TIMER)
`);
// Pure, stateless transition functions
let currentState = lightMachine.transition('green', 'TIMER');
// => 'yellow'
let newState = lightMachine.transition(currentState, 'TIMER');
// => 'red'
// Initial state
let initialState = lightMachine.transition();
// => 'green'
Estado allows you to parse an easy-to-learn DSL for declaratively writing finite state machines.
A state is just an alphanumeric string (underscores are allowed) without quotes or spaces: some_valid_state
. Final states are appended with an exclamation point: someFinalState!
.
By default, the first state declared in a state group is an initial state.
A transition (edge) between states is denoted with an arrow: ->
. A state can transition to itself with a reverse arrow: <-
. In the example below, state1
transitions to state2
on the FOO
event. state2
transitions to itself on the BAR
event.
state1 -> state2 (FOO)
state2 <- (BAR)
An action is also an alphanumeric string (underscores allowed), just like states. They are contained in parentheses after a transition: state1 -> state2 (SOME_EVENT)
, or after a self-transition: state3 <- (AN_EVENT)
. Actions are optional (but encouraged for proper state machine design).
States can be hierarchical (nested) by including them inside brackets after a state declaration. They can be deeply nested an infinite amount of levels. This is useful for implementing statecharts.
state1 {
nestedState1 -> nestedState2 (FOO)
nestedState2!
} -> state2 (BAR)
-> state3 (BAZ)
state2!
state3!
Here's a more pragmatic example:
green -> yellow (TIMER)
yellow -> red (TIMER)
red {
walk -> countdown (COUNTDOWN_START)
countdown -> stop (COUNTDOWN_STOP)
stop!
} -> green (TIMER)
When you enter the red
state from yellow
, you immediately go into red.walk
(which allows pedestrians to walk). Upon reaching red.stop
(which disallows pedestrians from walking), actions are handled from the parent red
state, so the TIMER
going off would transition it back to the green
state.
Read here if you're curious to the AST and State Machine Schema that this language produces.
Creates a new Machine()
instance with the specified data (see the schema above) and options (optional).
data
: (object | string) The definition of the state machine.options
: (object) Machine-specific options:
deterministic
: (boolean) Specifies whether the machine is deterministic or nondeterministic (default: true
)Returns the next state, given a current state and an action. If no state nor action is provided, the initial state is returned.
Note: This is a pure function, and does not maintain internal state.
state
: (string) The current state ID.action
: (string | Action) The action that triggers the transition from the state
to the next state.Example:
lightMachine.transition();
// => 'green'
lightMachine.transition('green', 'TIMER');
// => 'yellow'
lightMachine.transition('yellow', { type: 'TIMER' });
// => 'red'
lightMachine.transition('yellow');
// => 'yellow'
FAQs
Finite State Machines and Statecharts for the Modern Web.
The npm package xstate receives a total of 1,285,676 weekly downloads. As such, xstate popularity was classified as popular.
We found that xstate demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
ESLint has added JSON and Markdown linting support with new officially-supported plugins, expanding its versatility beyond JavaScript.
Security News
Members Hub is conducting large-scale campaigns to artificially boost Discord server metrics, undermining community trust and platform integrity.
Security News
NIST has failed to meet its self-imposed deadline of clearing the NVD's backlog by the end of the fiscal year. Meanwhile, CVE's awaiting analysis have increased by 33% since June.