Last active
December 29, 2016 06:31
-
-
Save mnichols/d221031de888e9d24ddc48defc6497ff 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
import objectPath from "object-path" | |
function assertValue(funcName, value) { | |
if(typeof value !== 'undefined') { | |
return | |
} | |
throw new Error(`You are returning 'undefined' from ${funcName}. This is a bug.`) | |
} | |
/** | |
* nestComponent | |
* | |
* @param path - the node/property where the component should mount onto the state tree | |
* @returns {Object} pathed component spec, write to and reading from `path` where appropriate | |
*/ | |
export default function nestComponent(path) { | |
return function inner(component) { | |
let topLevel = {} | |
function V(props = {}, actions) { | |
if(!component.view) { | |
topLevel = {} | |
return null | |
} | |
const namespaced = objectPath.get(topLevel, path, {}) | |
if(props.children) { | |
namespaced.children = props.children | |
} | |
const result = component.view({ ...namespaced, ...props }, actions) | |
//reset | |
topLevel = {} | |
return result | |
} | |
const result = { | |
initialModel: component.initialModel ? ({ model }) => { | |
let result = component.initialModel({}) | |
objectPath.set(model, path, Object.assign(objectPath.get(model, path, {}), result)); | |
return model; | |
} : null, | |
receive: component.receive ? ({ model, proposal }) => { | |
let result = component.receive({ model: objectPath.get(model, path, {}), proposal }) | |
assertValue('receive', result) | |
objectPath.set(model, path, result) | |
return topLevel = model | |
} : null, | |
view: V, | |
actions: component.actions, | |
postRender: component.postRender ? ({ model, state }) => component.postRender({ model: objectPath.get(model, path, {}), state: objectPath.get(state, path, {}) }) : null, | |
ready: component.ready, | |
nextAction: component.nextAction ? ({ model, proposal, actions, propose }) => component.nextAction({ model: objectPath.get(model, path, {}), proposal, actions, propose }) : null, | |
state: component.state ? ({ model, state }) => { | |
let result = component.state({ model: objectPath.get(model, path, {}), state: objectPath.get(state, path, {}) }) | |
assertValue('state', result) | |
//dont mutate app model | |
topLevel = { ...model } | |
objectPath.set(topLevel, path, result) | |
return topLevel | |
} : ({ model }) => topLevel = model, | |
} | |
return result | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment