Last active
November 22, 2015 03:58
-
-
Save rohozhnikoff/4c32922841cd7849fa61 to your computer and use it in GitHub Desktop.
memux = redux + memoize for stream-like flow
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* {key: reducerFunc}, {key: initialReducerValue} | |
* */ | |
function createStore(reducers, initial) { | |
var _handle = function () { | |
}; | |
var _STATE = initial || {}, | |
_reducersNames = Object.keys(reducers); | |
return { | |
subscribe: function (handle) { | |
_handle = handle | |
}, | |
getState: function () { | |
return _STATE | |
}, | |
dispatch: function (action) { | |
console.log('[ACTION:FIRED]:', action) | |
var reducersNames = cloneArray(_reducersNames); | |
// create wrappers | |
var reducersWithMemo = reduceTree(reducers, function (hash, func, key) { | |
hash[key] = function () { | |
if (contain(reducersNames, key)) { | |
console.log('try to call reducer ' + key + '(prevState, action)...') | |
_STATE[key] = func(_STATE[key], action, reducersWithMemo); | |
reducersNames = withoutFirst(reducersNames, key) | |
} | |
return _STATE[key] | |
}; | |
return hash; | |
}, {}); | |
while (reducersNames.length > 0) { | |
reducersWithMemo[reducersNames[0]](_STATE[reducersNames[0]], action, reducersWithMemo) | |
} | |
_handle(_STATE); | |
} | |
} | |
} | |
/** | |
* REDUCERS (Memucers) | |
* | |
* you can use store[reducer name] like getter, | |
* even if this reducer not resolved yet | |
* | |
* */ | |
function filter(state, action, store) { | |
var params = store.params(); | |
return store.list().filter(function (item) { | |
return params === 'odd' | |
? (item % 2 === 0) | |
: (item % 2 !== 0) | |
}) | |
} | |
function list(state, action, list) { | |
if (action.type === 'add numbers') { | |
return state.concat(action.numbers) | |
} | |
return state | |
} | |
function params(state, action, list) { | |
return (action.type === 'change param' && action.param) || state | |
} | |
/** | |
* INITIALIZE | |
* */ | |
var store = createStore({ | |
filter: filter, | |
list: list, | |
params: params, | |
}, { | |
list: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], | |
params: 'odd' | |
}); | |
store.subscribe(console.log.bind(console, '[STATE:REFRESH]:\n')); | |
/** | |
* SOMEWHERE IN BUSINESS-LOGIC | |
* */ | |
store.dispatch({ | |
type: 'change param', | |
param: 'even' | |
}); | |
store.dispatch({ | |
type: 'add numbers', | |
numbers: [10, 11, 12, 13, 14] | |
}); | |
store.dispatch({ | |
type: 'change param', | |
param: 'odd' | |
}); | |
store.dispatch({ | |
type: 'unknown action type' | |
}); | |
store.dispatch({ | |
type: 'add numbers', | |
numbers: [15, 16, 17, 18, 19, 20] | |
}); | |
store.dispatch({ | |
type: 'change param', | |
param: 'even' | |
}); | |
/** --------- UTILS --------- */ | |
function reduceTree(hash, iterator, memo) { | |
for (var key in hash) { | |
memo = iterator(memo, hash[key], key, hash) | |
} | |
return memo | |
} | |
function cloneArray(list) { | |
return list.concat([]) | |
} | |
function contain(list, el) { | |
return list.indexOf(el) !== -1 | |
} | |
function withoutFirst(list, el) { | |
var firstIndex = list.indexOf(el); | |
return list.slice(0, firstIndex).concat(list.slice(firstIndex + 1)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment