0.1.24 • Published 2 years ago

flux-machine v0.1.24

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

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 specificationflux-machineSupported via
scxml<SCXML>
state<State>
parallel
transition<Transition>
initial<State initial>
final<Final>
onentry.onEntry()
onexit.onExit()
history
raise
if
elseif
else
foreach
log
datamodelfsm(..., data)
datafsm(..., data)
assign.assign()
donedata
content
param
script.action()
send.send()
cancel
invoke
finalize

Additional features

Featureflux-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.

0.1.24

2 years ago

0.1.23

2 years ago

0.1.22

2 years ago

0.1.21

2 years ago

0.1.20

2 years ago

0.1.19

2 years ago

0.1.18

2 years ago

0.1.17

2 years ago

0.1.16

2 years ago

0.1.15

2 years ago

0.1.14

2 years ago

0.1.12

2 years ago