Created
September 12, 2016 14:46
-
-
Save myobie/27b029aa6510db8deaef499f5bd092b9 to your computer and use it in GitHub Desktop.
This file contains 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
export function namespacedModel (app, obj = {}) { | |
const namespace = obj.namespace | |
// TODO: assert that namespace was provided | |
const initialState = obj.state || {} | |
const reducers = obj.reducers || {} | |
const effects = obj.effects || {} | |
const subscriptions = obj.subscriptions || [] | |
const processedEffects = Object.keys(effects).reduce((o, effectName) => { | |
const eff = effects[effectName] | |
o[effectName] = (data, state, send) => eff(data, state, wrapSend(namespace, send)) | |
return o | |
}, {}) | |
const processedSubscriptions = Object.keys(subscriptions).reduce((o, subName) => { | |
const sub = subscriptions[subName] | |
o[subName] = (send, done) => sub(wrapSend(namespace, send), done) | |
return o | |
}, {}) | |
app.model({ | |
namespace, | |
state: initialState, | |
reducers, | |
effects: processedEffects, | |
subscriptions: processedSubscriptions | |
}) | |
} | |
function wrapSend (namespace, send) { | |
return function (actionName, ...args) { | |
if (actionName.startsWith('::')) { | |
// if it begins with two colons, then it's a top level single word action name | |
actionName = actionName.substr(2) | |
return send(actionName, ...args) | |
} else if (actionName.match(/:/)) { | |
// if it has a colon, then let it pass through as a global send | |
return send(actionName, ...args) | |
} else { | |
// else namespace it | |
return send(`${namespace}:${actionName}`, ...args) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment