flux-machine
TypeScript icon, indicating that this package has built-in type declarations

0.1.24 • Public • Published

Flux machine

Spec compliant finite state machines using JSX and chainable methods.

Installation:

npm install flux-machine

Example:

import fsm, { State, Transition } from "flux-machine";

// Define state chart using JSX (finite state)
const humanStateChart = (
  <>
    <State initial id="sleeping">
      <Transition event="walk" target="walking" />
    </State>
    <State id="walking">
      <Transition event="sleep" target="sleeping" />
      <Transition event="run" target="running" />
    </State>
    <State id="running">
      <Transition event="walk" target="walking" />
    </State>
  </>
);

// Define data (infinite state)
const data = {
  energy: 10,
  speed: 0,
};

// Create a machine
const humanMachine = fsm(humanStateChart, data);

// Add conditions, assignments or invoke side effects with chained syntax
humanMachine
  .when({
    state: "sleeping",
    event: "walk",
  })
  .assign(() => ({
    speed: 1,
  }));

humanMachine
  .when({
    state: "walking",
    event: "run",
  })
  .cond((data) => {
    return data.energy > 5;
  })
  .assign((context) => ({
    energy: data.energy--,
    speed: 10,
  }));

humanMachine
  .when({
    state: "sleeping",
  })
  .assign((data) => ({
    energy: data.energy++,
    speed: 0,
  }));

// Start machine
export const service = humanMachine.start();

// Interact with machine
service.send("walk");
console.log(service.state.value); // walking
console.log(service.state.context); // { speed: 1 }

Features

SCXML specification

SCXML specification flux-machine Supported via
scxml <SCXML>
state <State>
parallel
transition <Transition>
initial <State initial>
final <Final>
onentry .onEntry()
onexit .onExit()
history
raise
if
elseif
else
foreach
log
datamodel fsm(..., data)
data fsm(..., data)
assign .assign()
donedata
content
param
script .action()
send .send()
cancel
invoke
finalize

Additional features

Feature flux-machine
JSX
SCXML
JSON

Additional examples

Set an initial state that is not the first state

By default the first state is the initial state

const sc = (
  <>
    <State id="sleeping"></State>
    <State initial id="awake"></State>
  </>
);
const service = fsm(sc).start();
console.log(machine.state.value); // awake

Re-use transitions

const goToStart = <Transition event="start" target="1" />;
const goToEnd = <Transition event="end" target="3" />;
const sc = (
  <>
    <State id="1">{goToEnd}</State>
    <State id="2">{goToEnd}</State>
    <State id="3">{goToStart}</State>
  </>
);

Listen to transitions from any state

machine
  .when({
    event: "end",
  })
  .action(() => {
    console.log("transitioning to end"); // 'end' event was fired from any state
  });

Project goals

  • Match the SCXML specification as closely as possible
    • Allows developers to reference the spec directly
    • Allows developers learning efforts to be transferable
    • Avoids us having to write extensive documentation
  • Improved developer experience
    • Separate finite and extended state
    • Fluent API should provide intellisense to avoid guessing method or property names
  • Small bundle size (< 5kb)
    • Allows developers to import it into existing projects to address specific problems
  • High code coverage (>= 95%)
    • Allows developers to be confident the library works as expected

Bundle size

npm bundle size

Code coverage

codecov

FAQ

Can I use this in production?

  • I do not recommend it until it reaches V1.0.0

Why the name flux?

Credit

This library uses @xstate/fsm for its finite state machine.

Package Sidebar

Install

npm i flux-machine

Weekly Downloads

4

Version

0.1.24

License

MIT

Unpacked Size

145 kB

Total Files

49

Last publish

Collaborators

  • gkiely