Package Exports
- unlimited-machine-works
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (unlimited-machine-works) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
⚔ Unlimited Blade Machine Works ⚔
The unlimited working 1KB state machine library for the web!
Work in Progress - Use at your own risk! LOL
Table of Contents
Rationale
When you think about it, web applications can be modeled as state machines. You should only jump from one state to another and not magically end up in another in an unpredictable manner. You should only make transitions that are possible for your current state. Modeling your web application as a state machine makes managing the flow of your application much easier as it makes your application more predictable. This is the main driving force of building this library.
How to import
Import on the browser
<script src="https://cdn.jsdelivr.net/npm/unlimited-machine-works@1.1.5/umw.min.js" async></script>
Import on Node
const UMW = require('unlimited-machine-works')
Quickstart
Creating a machine
You can use the summon
or make
methods to create a machine.
const machine = UMW.summon({name: 'Attack Helicopter', speed: 0}, {
'INITIAL': {
'MOVE': {
to: 'MOVING',
action: (data, args) => {
return Object.assign({}, data, {speed: 1})
}
}
},
'MOVING': {
'ACCELERATE': {
to: 'MOVING',
action: (data, args) => {
return Object.assign({}, data, {speed: data.speed + 1})
}
},
'ACCELERATE_BY': {
to: 'MOVING',
action: (data, args) => {
return Object.assign({}, data, {speed: data.speed + args.speed})
}
},
'STOP': {
to: 'INITIAL',
action: (data, args) => {
return Object.assign({}, data, {speed: 0})
}
}
}
})
Creating a Machine Explained
The first argument of creating a machine is an object that contains the initial data that you want to manage alongside your state and transitions. The second argument is optional if you don't want to add states upon machine creation. The second argument allows you to add states and transitions upon creating the machine.
Take a look at this snippet from the above code:
'INITIAL': {
'MOVE': {
to: 'MOVING',
action: (data, args) => {
return Object.assign({}, state, {speed: 1})
}
}
}
The INITIAL
key is a state. Each state should have at least transition or else you won't be able to state. In this case, MOVE
is the transition of the INITIAL
state. The to
key of a transition specifies to which state to go to after the transition. The action
key of a transition should be a function that accepts the current data and the arguments given when the transition is called. The return value will replace the data
that was originally given.
Checking what transitions you can do
You can use the actions
method of your machine to check. This will return the transition names as an array of strings.
console.log(machine.actions); // [ 'MOVE' ]
Doing a transition
You can use the do
method of your machine to execute a transition.
machine.do('MOVE')
If the transition defined requires additional arguments, you can add an object with the arguments as the second argument.
machine.do('ACCELERATE_BY', {speed: 4})
speed
can be accessed from the args
object. Check the snippet above.
Reacting to transitions
You can react to transitions by adding a subscriber to the machine using the addSubscriber
method. The method takes a function which receives the new state and data after the transition. You can then do things like rendering elements in this function.
This piece of code will log the current speed data everytime a transition occurs.
machine.addSubscriber((state, data) => {
console.log(`Speed: ${data.speed}`)
})
Graphics Credits
Logo by my sister Jade Ada (@blondiewiththebadhair).
Other Icons
Roadmap
- Create react-umw
- Using asynchronous functions for subscribers and other things
- Using Proxy objects to detect change
- Data diffing
- Adding
summon()
flag for verbose errors - Adding subscribers as a part of the spec
- Move
addSubscribers()
in to an Adding Subscribers Dynamically section - Add tests
- Add status badges
- Add Flow
- Add visualization
Inspired By
- Stent
- Hyperapp
License
MIT