Created
September 22, 2017 03:42
-
-
Save mnichols/8b2c26c6e68a3eea7e8dff17be76a42a to your computer and use it in GitHub Desktop.
This file contains hidden or 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
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