-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
82 lines (62 loc) · 1.77 KB
/
index.js
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
import Events from '@bleckert/events';
export class Machine extends Events {
constructor(states, initial = 'IDLE', data = {}, actions = {}) {
super();
this.states = states;
this.initial = initial;
this.state = initial;
this.actions = actions;
this._defaultData = { ...data };
this.set(this._defaultData);
}
can(action) {
return action in this.states[this.state].on;
}
isFinal() {
return this.states[this.state].final;
}
transition(prevState, input) {
if (prevState) {
this.emit(`${prevState}-OFF`);
}
this.emit(this.state, input);
this.emit('transition', this.state, prevState, input);
if (this.actions[this.state]) {
this.actions[this.state](this, input);
}
}
dispatch(actionName, input = null) {
if (!this.can(actionName)) {
return;
}
const currentState = this.state;
this.state = this.states[this.state].on[actionName];
this.transition(currentState, input);
}
start(input = null) {
this.transition(null, input);
}
reset(input = null) {
this.set({ ...this._defaultData });
this.state = this.initial;
this.start(input);
}
offState(state, cb) {
this.on(`${state}-OFF`, cb);
}
set(data) {
this.data = data;
Object.freeze(this.data);
}
setData(data) {
this.set({ ...this.data, ...data });
this.emit('data', data);
}
}
const store = {};
export function createMachine(config) {
if (!store[config.id]) {
store[config.id] = new Machine(config.states, config.initial, config.data, config.actions);
}
return store[config.id];
}