Finite state machines using JSX and chainable methods
MIT License
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 }
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 | ❌ |
Feature | flux-machine |
---|---|
JSX | ✅ |
SCXML | ❌ |
JSON | ❌ |
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
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>
</>
);
machine
.when({
event: "end",
})
.action(() => {
console.log("transitioning to end"); // 'end' event was fired from any state
});
< 5kb
)
>= 95%
)
This library uses @xstate/fsm for its finite state machine.