| 1 | export const createStore = (initialState, queries = [], actions = []) => { |
| 2 | // internal state |
| 3 | const state = { |
| 4 | ...initialState |
| 5 | }; |
| 6 | |
| 7 | // contains all actions for next frame, is clear when actions are requested |
| 8 | const actionQueue = []; |
| 9 | const dispatchQueue = []; |
| 10 | |
| 11 | // returns a duplicate of the current state |
| 12 | const getState = () => ({ ...state }); |
| 13 | |
| 14 | // returns a duplicate of the actions array and clears the actions array |
| 15 | const processActionQueue = () => { |
| 16 | // create copy of actions queue |
| 17 | const queue = [...actionQueue]; |
| 18 | |
| 19 | // clear actions queue (we don't want no double actions) |
| 20 | actionQueue.length = 0; |
| 21 | |
| 22 | return queue; |
| 23 | }; |
| 24 | |
| 25 | // processes actions that might block the main UI thread |
| 26 | const processDispatchQueue = () => { |
| 27 | // create copy of actions queue |
| 28 | const queue = [...dispatchQueue]; |
| 29 | |
| 30 | // clear actions queue (we don't want no double actions) |
| 31 | dispatchQueue.length = 0; |
| 32 | |
| 33 | // now dispatch these actions |
| 34 | queue.forEach(({ type, data }) => { |
| 35 | dispatch(type, data); |
| 36 | }); |
| 37 | }; |
| 38 | |
| 39 | // adds a new action, calls its handler and |
| 40 | const dispatch = (type, data, isBlocking) => { |
| 41 | |
| 42 | // is blocking action (should never block if document is hidden) |
| 43 | if (isBlocking && !document.hidden) { |
| 44 | dispatchQueue.push({ type, data }); |
| 45 | return; |
| 46 | } |
| 47 | |
| 48 | // if this action has a handler, handle the action |
| 49 | if (actionHandlers[type]) { |
| 50 | actionHandlers[type](data); |
| 51 | } |
| 52 | |
| 53 | // now add action |
| 54 | actionQueue.push({ |
| 55 | type, |
| 56 | data |
| 57 | }); |
| 58 | }; |
| 59 | |
| 60 | const query = (str, ...args) => |