fsm-manager
v0.1.0
Published
Allows composing FSM's. Also provides a built-in 'timeout' transition
Downloads
6
Maintainers
Readme
FSM_Manager - Finite State Machine Manager for Vue.js
Rick Berger, Aphorica Inc. ([email protected])
Finite State Machine Composer/Manager with Timeout (For Vue.js applications)
Intro
This is implemented over (and is dependent on) the excellent JakesGordon/Javascript-Finite-State-Machine package.
This package allows composibility of Finite State Machine instances, which are maintained on a basic LIFO stack. The implementation is as a base class - the intent is for the application to derive an application-specific variant.
Install
Install via NPM or Yarn:
npm install fsm-manaager
...
yarn add fsm-manager
Usage
To use is fairly simple:
import StateMachine from 'javascript-state-machine';
import FSM_Manager from 'fsm-manager';
let LOGGING = true;
// enable or disble log output
import FSM_Manager from 'fsm-manager';
class APP_FSM_Manager extends FSM_Manager {
constructor(_router) {
// router is a VueRouter instance
super(_router, LOGGING);
let main_fsm = (create a state machine instance);
this.setupObserver(main_fsm);
// sets up the fsm_manager as an observer to the fsm
this.pushFSM(main_fsm);
// pushes this fsm onto the stack and makes it the currentFSM
this.currentFSM().init();
// starts the fsm
}
// at some point (transition, likely) you'll want to add an fsm:
//
setupNewFSM(info) {
// info is passed from the transition
let newFSM = (create another state machine instance);
this.setupObserver(newFSM);
// same as before
this.pushFSM(newFSM);
// and onto the stack it goes
// now, newFSM is the currentFSM
}
// in some other transition, (like an 'exit' transition from the newFSM) it's
// time to pop the newFSM and resume the main_fsm instance:
//
exitTransition(info) {
let self = this;
setTimeout(function() {
// do the pop and trigger of the main_fsm transition in a timeout
// to avoid the 'transition triggered within a transition' problem.
let currentFSM = self.popFSM();
self.currentFSM().newFSMPopped();
}, 0);
})
}
}
Vue Router Handling
The VueRouter instance is passed to the FSM. After that, for the most part, the FSM handles the route invocations. This is done by looking for a route of the same name as the 'to' state. Consider a router definition snippet:
...
{
path: '/action-selection',
name: 'action-selection',
component: 'ActionSelection'
},
...
When a transition occurs, the 'to' state of the transition is checked against the 'name' value of the route. If there is a match, the route is invoked. If not,
handleStateChange()
is called. Your derived class can then handle the state change
for which there is no corresponding UI component.
There are a couple of functions you can override:
Built-in Timeout Transition Handler
If your application needs to time out after a period of inactivity (or whatever), FSM_Manager has a built in timer facility to help you implement that functionality.
For each FSM, you need to provide two things:
To start the timer, just call the base class function with a duration value:
...
this.setTimer(60000);
// sets the timer for 60 seconds
...
When the timer triggers, the currentFSM is popped off the stack, the timed-out
data
item is set to true, and the timeout
transition is invoked. This proceeds until the
stack only contains the main_fsm instance.
You can override the handleTimeout()
override if you need to do anything else.
You can clear (stop) the timer with a call to clearTimer()
.
Other JS Frameworks
I'm focusing on Vue.js for my own work. I imagine this could be fairly easily refactored to provide variants for other frameworks such as Angular2 or React. If that is something that is desirable, I can work with you on it.
ES6 Implementation
I personally am only writing in ES6, anymore. The project is 'babel-ized', and the babel output is what you are importing/requiring. I have left the ES6 source in the package, so you can view it and see what it's doing.
It's a single file — you could just pull the file and include it in your project if you want to handle the 'babel-izing' differently.
Browser BackButton Behavior.
In the code, you'll see handleBrowserHashChange()
. This was a stab at handling
browser back-button behavior, but it doesn't work very well. I'll revisit this
at some point (when I need it.) I suspect it is a simpler problem than this approach.
If it's something you drastically need, ping me and we can discuss.
Working Example
You can see how this all works in the demo Aphorica/atmplus.
This is also serving as my test app, for now.
License
While fsm-manager is MIT-Licensed, note that the JakesGordon/Javascript-Finite-State-Machine package is under LGPL.
You need to follow that license requirements for your own efforts.