forked from jakesgordon/javascript-state-machine
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.js
More file actions
102 lines (87 loc) · 3.51 KB
/
app.js
File metadata and controls
102 lines (87 loc) · 3.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
'use strict'
//-----------------------------------------------------------------------------------------------
var mixin = require('./util/mixin'),
camelize = require('./util/camelize'),
plugin = require('./plugin'),
Config = require('./config'),
JSM = require('./jsm');
//-----------------------------------------------------------------------------------------------
var PublicMethods = {
is: function(state) { return this._fsm.is(state) },
can: function(transition) { return this._fsm.can(transition) },
cannot: function(transition) { return this._fsm.cannot(transition) },
observe: function() { return this._fsm.observe(arguments) },
transitions: function() { return this._fsm.transitions() },
allTransitions: function() { return this._fsm.allTransitions() },
allStates: function() { return this._fsm.allStates() },
onInvalidTransition: function(t, from, to) { return this._fsm.onInvalidTransition(t, from, to) },
onPendingTransition: function(t, from, to) { return this._fsm.onPendingTransition(t, from, to) },
}
var PublicProperties = {
state: {
configurable: false,
enumerable: true,
get: function() {
return this._fsm.state;
},
set: function(state) {
throw Error('use transitions to change state')
}
}
}
//-----------------------------------------------------------------------------------------------
function StateMachine(options) {
return apply(this || {}, options);
}
function factory() {
var cstor, options;
if (typeof arguments[0] === 'function') {
cstor = arguments[0];
options = arguments[1] || {};
}
else {
cstor = function() { this._fsm.apply(this, arguments) };
options = arguments[0] || {};
}
var config = new Config(options, StateMachine);
build(cstor.prototype, config);
cstor.prototype._fsm.config = config; // convenience access to shared config without needing an instance
return cstor;
}
//-------------------------------------------------------------------------------------------------
function apply(instance, options) {
var config = new Config(options, StateMachine);
build(instance, config);
instance._fsm();
return instance;
}
function build(target, config) {
if ((typeof target !== 'object') || Array.isArray(target))
throw Error('StateMachine can only be applied to objects');
plugin.build(target, config);
Object.defineProperties(target, PublicProperties);
mixin(target, PublicMethods);
mixin(target, config.methods);
config.allTransitions().forEach(function(transition) {
target[camelize(transition)] = function() {
return this._fsm.fire(transition, [].slice.call(arguments))
}
});
target._fsm = function() {
this._fsm = new JSM(this, config);
this._fsm.init(arguments);
}
}
//-----------------------------------------------------------------------------------------------
StateMachine.version = '3.0.1';
StateMachine.factory = factory;
StateMachine.apply = apply;
StateMachine.defaults = {
wildcard: '*',
init: {
name: 'init',
from: 'none'
}
}
//===============================================================================================
module.exports = StateMachine;