Skip to content

Instantly share code, notes, and snippets.

@mnichols
Created September 22, 2017 03:42
Show Gist options
  • Save mnichols/8b2c26c6e68a3eea7e8dff17be76a42a to your computer and use it in GitHub Desktop.
Save mnichols/8b2c26c6e68a3eea7e8dff17be76a42a to your computer and use it in GitHub Desktop.
import m from 'mithril'
import stream from 'mithril/stream'
import {
curry,
compose,
merge,
over,
lensPath,
lift,
pick,
omit
} from 'ramda'
const scopeUpdate = (modelPath, update) => compose(update, over(lensPath(modelPath)))
// scope produces curried invocation of `update` calls at a certain model path
// `update` is required in final argument; others will be passed through
// example:
// function api ({ update }) { return { ... } }
// var deepNested = scope(['deep', 'nested'])
// var createActions = deepNested(api)
// var actions = createActions({ update })
export const scope = curry((modelPath, func, objOrUpdate) => {
// accept either `({update})` or `(update)`
let update = objOrUpdate.update
if (update) {
update = scopeUpdate(modelPath, update)
return func(merge(objOrUpdate, { update }))
}
return func(scopeUpdate(modelPath, objOrUpdate))
})
// combine simply merges the results of _n_ functions into one object
export const combine = (...funcs) => {
if (funcs.length === 1) {
return funcs[0]
}
// aka converge(merge, funcs)
return lift(merge)(...funcs)
}
export const connect = (update, model) => {
const applyUpdate = (model, updateModel) => {
updateModel(model)
return model
}
return stream.scan(applyUpdate, model, update)
}
/* mithril centric */
const lifecycle = ['oninit', 'oncreate', 'onupdate', 'onbeforeremove', 'onremove', 'onbeforeupdate']
// computes view model
export const compute = curry((computer, spec) => {
const rest = omit(lifecycle, spec)
return {
...rest,
view (vnode) {
return m(spec, merge(vnode.attrs, { model: computer(vnode.attrs.model) }))
}
}
})
// exports the component with lifecycle concerns hidden inside
export const component = (spec) => {
const view = pick(lifecycle, spec)
const rest = omit(lifecycle, spec)
return {
...rest,
view (vnode) {
return m(viewObj, vnode.attrs)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment