-
Notifications
You must be signed in to change notification settings - Fork 0
/
slots.js
73 lines (73 loc) · 2.5 KB
/
slots.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
class Slots { //nickname for a vending machine
// TODO: make reactive?, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
constructor({actions, mutators, subscribers, initState, notify, namespace, debug = false, quiet = false}) {
this.actions = {}
this.mutators = {}
this.subscribers = subscribers || []
this.state = {}
this.debug = debug
this.quiet = quiet
this.import({actions, mutators, initState, notify, namespace})
}
dispatch(action, payload) {
if (this.debug) {console.log(`dispatch ${action}`, payload)}
if (action.includes(':')) {
const parts = action.split(':')
this.actions[parts[0]][parts[1]]({mutate: this.mutate.bind(this), state: this.state, dispatch: this.dispatch.bind(this)}, payload)
} else {
this.actions[action]({mutate: this.mutate.bind(this), state: this.state, dispatch: this.dispatch.bind(this)}, payload)
}
}
mutate(action, payload) {
if (this.debug) {console.log(`mutate ${action}`, payload)}
let parts = []
if (action.includes(':')) {
parts = action.split(':')
this.state = this.mutators[parts[0]][parts[1]](this.state, payload)
} else {
this.state = this.mutators[action](this.state, payload)
}
!this.quiet && this.notify(parts[0])
}
subscribe(listener) {
// TODO: subscribe to only a namespace
this.subscribers.push(listener)
return () => {
this.subscribers = this.subscribers.filter(subscriber => subscriber !== listener)
}
}
notify(namespace) {
if (this.debug) {console.log(`notify ${namespace || ''} ${this.quiet}`)}
!this.quiet && this.subscribers.forEach(subscriber => subscriber(this.state, namespace))
}
import({namespace, actions, initState, mutators, notify}) {
if (namespace && !this.state.hasOwnProperty(namespace)) {
this.state[namespace] = {}
this.actions[namespace] = {}
this.mutators[namespace] = {}
}
let _state, _actions, _mutators
if (namespace) {
_state = this.state[namespace]
_actions = this.actions[namespace]
_mutators = this.mutators[namespace]
} else {
_state = this.state
_actions = this.actions
_mutators = this.mutators
}
if (actions) {
_actions = Object.assign(_actions, actions)
}
if (mutators) {
_mutators = Object.assign(_mutators, mutators)
}
if (initState) {
_state = Object.assign(_state, initState)
}
if (notify) {
this.notify(namespace)
}
return this
}
}