Open tunnckoCore opened 6 years ago
as seen in Hyperapp, which pretty great idea.
old code, but just for backup here
/** * * @param {*} options */ /* eslint-disable max-statements, no-param-reassign, no-consistent-return, no-return-assign */ const update = partialState => state => Object.assign({}, state, partialState) function elmaz(options) { const opts = Object.assign({}, options) let STATE = Object.assign({}, opts.state) const globalActions = {} const hasOwn = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key) const prev = [] function initActions(state, actions, raw) { Object.keys(raw).forEach(name => { if (typeof raw[name] === 'object' && hasOwn(state, name)) { prev.push(name) initActions(state[name], actions[name] || (actions[name] = {}), raw[name]) } else if (typeof raw[name] === 'function') { actions[name] = (...args) => { if (hasOwn(state, name)) { const result = raw[name]({ state: state[name], actions, update }, ...args) // so, reducer (returned REPLACES STATE directly) // so, use the `update` helper like `({ update }) => update({ hi: 123 }) if (typeof result === 'function') { state[name] = result(state[name]) STATE = Object.assign({}, STATE, state[name]) return state[name] } return result } const upper = prev.shift() if (hasOwn(STATE, upper)) { const result = raw[name]({ state: STATE[upper], actions, update }, ...args) // so, reducer (returned REPLACES STATE directly) // so, use the `update` helper like `({ update }) => update({ hi: 123 }) if (typeof result === 'function') { STATE[upper] = result(STATE[upper]) return STATE[name] } return result } const result = raw[name]({ state: STATE, actions, update }, ...args) // so, reducer (returned REPLACES STATE directly) // so, use the `update` helper like `({ update }) => update({ hi: 123 }) if (typeof result === 'function') { STATE = result(STATE) return STATE } return result } } }) } initActions(STATE, globalActions, opts.actions) return globalActions } const res = elmaz({ state: { hello: 'world', buddy: { hi: 'zazzy', todo: { list: [], count: 0, done: 0, }, }, }, actions: { foo: ({ state, actions }, ...args) => { console.log('foo action', state) console.log('========================') }, bar: ({ state }) => { console.log('bar action', state) console.log('========================') }, buddy: { some: ({ state }) => { console.log('buddy.some action', state) console.log('========================') // should replace the whole `state.buddy` state, // not the state of the app return (/* state */) => ({ hi: 'hello' }) }, xxx: ({ state }) => { console.log('buddy.xxx action', state) console.log('========================') }, todo: ({ state, actions }) => { console.log('====') console.log('buddy.todo state:', state) console.log('todo acts:', actions) console.log('======================== todo end') return update({ damn: true }) }, }, }, }) // res.buddy.some() // res.buddy.xxx() res.buddy.todo() res.foo() // console.log(res)
as seen in Hyperapp, which pretty great idea.
old code, but just for backup here