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