Skip to content

Instantly share code, notes, and snippets.

@ungoldman
Last active July 24, 2018 09:24
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ungoldman/9fedf1a44d12e4b6302b213184e71953 to your computer and use it in GitHub Desktop.
Save ungoldman/9fedf1a44d12e4b6302b213184e71953 to your computer and use it in GitHub Desktop.
sketch of a simple wrapper for predictable, namespaced choo stores
/*
Now a real module used in production!
https://github.com/ungoldman/choo-store
*/
class Store {
constructor (opts) {
opts = opts || {}
if (!opts.namespace) throw new Error('namespace required')
if (!opts.initialState) throw new Error('initialState required')
if (!opts.events) throw new Error('events required')
Object.assign(this, opts)
this.connect = this.connect.bind(this)
}
connect (state, emitter) {
const { namespace, initialState, events } = this
state[namespace] = initialState
Object.keys(events).forEach(event => {
emitter.on(`${namespace}:${event}`, action(opts => {
events[event](opts, state[namespace], emitter, state)
}))
})
emitter.on(`${namespace}:reset`, action(opts => {
state[namespace] = initialState
}))
function action (fn) {
return opts => {
opts = opts || {}
fn(opts)
if (opts.render) emitter.emit('render')
}
}
}
}
const clickStore = new Store({
namespace: 'clicks',
initialState: { counter: 0 },
events: {
increment: (opts, store, emitter, state) => {
store.counter++
}
}
})
app.use(clickStore.connect)
// later
emit('clicks:increment')
// state.clicks.counter === 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment