1 | const cuid = require('cuid')
|
2 |
|
3 |
|
4 | const STATE_UPDATE = 'uppy/STATE_UPDATE'
|
5 |
|
6 |
|
7 | const defaultSelector = (id) => (state) => state.uppy[id]
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 | class ReduxStore {
|
19 | constructor (opts) {
|
20 | this._store = opts.store
|
21 | this._id = opts.id || cuid()
|
22 | this._selector = opts.selector || defaultSelector(this._id)
|
23 |
|
24 |
|
25 | this.setState({})
|
26 | }
|
27 |
|
28 | setState (patch) {
|
29 | this._store.dispatch({
|
30 | type: STATE_UPDATE,
|
31 | id: this._id,
|
32 | payload: patch
|
33 | })
|
34 | }
|
35 |
|
36 | getState () {
|
37 | return this._selector(this._store.getState())
|
38 | }
|
39 |
|
40 | subscribe (cb) {
|
41 | let prevState = this.getState()
|
42 | return this._store.subscribe(() => {
|
43 | const nextState = this.getState()
|
44 | if (prevState !== nextState) {
|
45 | const patch = getPatch(prevState, nextState)
|
46 | cb(prevState, nextState, patch)
|
47 | prevState = nextState
|
48 | }
|
49 | })
|
50 | }
|
51 | }
|
52 |
|
53 | function getPatch (prev, next) {
|
54 | const nextKeys = Object.keys(next)
|
55 | const patch = {}
|
56 | nextKeys.forEach((k) => {
|
57 | if (prev[k] !== next[k]) patch[k] = next[k]
|
58 | })
|
59 | return patch
|
60 | }
|
61 |
|
62 | function reducer (state = {}, action) {
|
63 | if (action.type === STATE_UPDATE) {
|
64 | const newState = Object.assign({}, state[action.id], action.payload)
|
65 | return Object.assign({}, state, {
|
66 | [action.id]: newState
|
67 | })
|
68 | }
|
69 | return state
|
70 | }
|
71 |
|
72 | function middleware () {
|
73 |
|
74 | return () => (next) => (action) => {
|
75 | next(action)
|
76 | }
|
77 | }
|
78 |
|
79 | module.exports = function createReduxStore (opts) {
|
80 | return new ReduxStore(opts)
|
81 | }
|
82 |
|
83 | module.exports.STATE_UPDATE = STATE_UPDATE
|
84 | module.exports.reducer = reducer
|
85 | module.exports.middleware = middleware
|