/
AltStore.js
100 lines (82 loc) · 2.17 KB
/
AltStore.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
88
89
90
91
92
93
94
95
96
97
98
99
100
import EventEmitter from 'eventemitter3'
import Symbol from 'es-symbol'
import * as Sym from '../symbols/symbols'
import * as fn from '../../utils/functions'
// event emitter instance
const EE = Symbol()
/*istanbul ignore next*/
function isPromise(obj) {
return obj && (typeof obj === 'object' || typeof obj === 'function') &&
typeof obj.then === 'function'
}
class AltStore {
constructor(alt, model, state, StoreModel) {
this[EE] = new EventEmitter()
this[Sym.LIFECYCLE] = model[Sym.LIFECYCLE]
this[Sym.STATE_CONTAINER] = state || model
this._storeName = model._storeName
this.boundListeners = model[Sym.ALL_LISTENERS]
this.StoreModel = StoreModel
fn.assign(this, model[Sym.PUBLIC_METHODS])
// Register dispatcher
this.dispatchToken = alt.dispatcher.register((payload) => {
this[Sym.LIFECYCLE].emit(
'beforeEach',
payload,
this[Sym.STATE_CONTAINER]
)
let result = false
if (model[Sym.LISTENERS][payload.action]) {
try {
result = model[Sym.LISTENERS][payload.action](payload.data)
} catch (e) {
if (model[Sym.HANDLING_ERRORS]) {
this[Sym.LIFECYCLE].emit(
'error',
e,
payload,
this[Sym.STATE_CONTAINER]
)
} else {
throw e
}
}
if (result !== false) {
if (isPromise(result)) {
result.then(this.emitChange.bind(this))
} else {
this.emitChange()
}
}
}
this[Sym.LIFECYCLE].emit(
'afterEach',
payload,
this[Sym.STATE_CONTAINER]
)
return result
})
this[Sym.LIFECYCLE].emit('init')
}
getEventEmitter() {
return this[EE]
}
emitChange() {
this[EE].emit('change', this[Sym.STATE_CONTAINER])
}
listen(cb) {
this[EE].on('change', cb)
return () => this.unlisten(cb)
}
unlisten(cb) {
this[Sym.LIFECYCLE].emit('unlisten')
this[EE].removeListener('change', cb)
}
getState() {
return this.StoreModel.config.getState.call(
this,
this[Sym.STATE_CONTAINER]
)
}
}
export default AltStore