forked from storeon/storeon
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
121 lines (109 loc) · 2.67 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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/**
* Initialize new store and apply all modules to the store.
*
* @param {moduleInitializer[]} modules Functions which will set initial state
* define reducer and subscribe
* to all system events.
*
* @return {Store} The new store.
*
* @example
* import createStore from 'storeon'
* let increment = store => {
* store.on('@init', () => ({ count: 0 }))
* store.on('inc', ({ count }) => ({ count: count + 1 }))
* }
* const store = createStore([increment])
* store.get().count //=> 0
* store.dispatch('inc')
* store.get().count //=> 1
*/
var createStore = function (modules) {
var events = { }
var state = { }
var on = function (event, cb) {
(events[event] || (events[event] = [])).push(cb)
return function () {
events[event] = events[event].filter(function (i) {
return i !== cb
})
}
}
var dispatch = function (event, data) {
if (event !== '@dispatch') {
dispatch('@dispatch', [event, data, events[event]])
}
if (events[event]) {
var changes = { }
var changed
events[event].forEach(function (i) {
var diff = i(state, data)
if (diff && typeof diff.then !== 'function') {
changed = state = Object.assign({ }, state, diff)
Object.assign(changes, diff)
}
})
if (changed) dispatch('@changed', changes)
}
}
var get = function () {
return state
}
var store = { dispatch: dispatch, get: get, on: on }
modules.forEach(function (i) {
if (i) i(store)
})
dispatch('@init')
return store
}
module.exports = createStore
/**
* Store with application state and event listeners.
*
* @name Store
* @class
*/
/**
* Return current state. You can use this method only to read state.
* Any state changes should be in event listeners.
*
* @return {object} The current state.
*
* @name get
* @function
* @memberof Store#
*/
/**
* Emit event.
*
* @param {string} event The event name.
* @param {*} [data] Any additional data for the event.
*
* @return {object} The current state.
*
* @name dispatch
* @function
* @memberof Store#
*/
/**
* Add event listener.
*
* @param {string} event The event name.
* @param {listener} listener The event listener.
*
* @return {function} The function to remove listener.
*
* @name on
* @function
* @memberof Store#
*/
/**
* @callback moduleInitializer
* @param {Store} store Store to define initial state and reducers.
*/
/**
* @callback listener
* @param {object} state The current state of the store.
* @param {*} [data] The event data if it was passed.
* @return {object|undefined} Changes for next state.
*/