Skip to content

Instantly share code, notes, and snippets.

@myobie
Created September 12, 2016 14:46
Show Gist options
  • Save myobie/27b029aa6510db8deaef499f5bd092b9 to your computer and use it in GitHub Desktop.
Save myobie/27b029aa6510db8deaef499f5bd092b9 to your computer and use it in GitHub Desktop.
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