-
Notifications
You must be signed in to change notification settings - Fork 0
/
reduxSpirit.js
87 lines (71 loc) · 2.29 KB
/
reduxSpirit.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
83
84
85
86
87
import {Statechart} from 'scion-core'
const actionPrefix = 'a:'
export const reduxSpirit = (states, opts) => {
let sc
const options = opts || {}
function isObject(val) {
if (val === null) { return false;}
return ( (typeof val === 'function') || (typeof val === 'object') );
}
function initStatechart(store) {
setTimeout(function() {
if(Array.isArray(states)) {
sc = new Statechart({states})
}
else if(isObject) {
sc = new Statechart(states)
}
else {
throw new Error('Invalid statechart schema')
}
let lastEvent
if(options.log && options.verbose) {
sc.on('onBigStepBegin', () => console.log('big step begin'))
sc.on('onBigStepEnd', () => console.log('big step end'))
sc.on('onSmallStepBegin', e => console.log('small step begin', e))
sc.on('onSmallStepEnd', () => console.log('small step end'))
}
sc.on('onSmallStepBegin', e => lastEvent = e ? e.data : undefined)
sc.on('onEntry', state => {
const action = {...lastEvent}
action.type = `${actionPrefix}entry:${state}`
options.log && console.log('entry', state, action)
store.dispatch(action)
})
sc.on('onExit', state => {
const action = {...lastEvent}
action.type = `${actionPrefix}exit:${state}`
options.log && console.log('exit', state, action)
store.dispatch(action)
})
sc.on('onTransition', () => {
if(lastEvent && lastEvent.type) {
const action = {...lastEvent}
action.type = `${actionPrefix}transition:${lastEvent.type}`
options.log && console.log('transition', action)
store.dispatch(action)
}
})
sc.start()
}, 0)
}
return store => {
!sc && initStatechart(store)
return next => action => {
if(!action.type.startsWith(actionPrefix)) {
if(options.log) console.log('event', action)
sc.gen({
name: action.type,
data: action,
})
}
else {
if(options.log) console.log('action', action)
next(action)
}
}
}
}
export const onEntry = state => `${actionPrefix}entry:` + state
export const onExit = state => `${actionPrefix}exit:` + state
export const onTransition = event => `${actionPrefix}transition:` + event