flux-machine
v0.1.24
Published
Spec compliant state machines using JSX, XML or JSON and chainable methods
Downloads
5
Maintainers
Readme
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 | 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
Code coverage
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.