choo: fix subs
This commit is contained in:
@@ -15,7 +15,7 @@ function choo (opts) {
|
|||||||
opts = opts || {}
|
opts = opts || {}
|
||||||
const name = opts.name || 'choo'
|
const name = opts.name || 'choo'
|
||||||
var _router = null
|
var _router = null
|
||||||
var _models = [ appInit() ]
|
var _models = [ appInit(opts) ]
|
||||||
|
|
||||||
start.router = router
|
start.router = router
|
||||||
start.model = model
|
start.model = model
|
||||||
@@ -26,30 +26,58 @@ function choo (opts) {
|
|||||||
// start the application
|
// start the application
|
||||||
// null -> DOMNode
|
// null -> DOMNode
|
||||||
function start () {
|
function start () {
|
||||||
const events = bootstrap(_models)
|
const initialState = {}
|
||||||
const send = sendAction({
|
const reducers = {}
|
||||||
onaction: events.handleAction,
|
const effects = {}
|
||||||
onchange: onchange,
|
|
||||||
state: events.state
|
_models.forEach(function (model) {
|
||||||
|
if (model.state) apply(model.name, model.state, initialState)
|
||||||
|
if (model.reducers) apply(model.name, model.reducers, reducers)
|
||||||
|
if (model.effects) apply(model.name, model.effects, effects)
|
||||||
})
|
})
|
||||||
|
|
||||||
if (opts.href !== false) {
|
const send = sendAction({
|
||||||
href(function (href) {
|
onaction: handleAction,
|
||||||
send('location', { location: href })
|
onchange: onchange,
|
||||||
})
|
state: initialState
|
||||||
}
|
})
|
||||||
|
|
||||||
if (opts.history !== false) {
|
_models.forEach(function (model) {
|
||||||
history(function (href) {
|
if (model.subscriptions) {
|
||||||
send('location', { location: href })
|
model.subscriptions.forEach(function (sub) {
|
||||||
})
|
sub(send)
|
||||||
}
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const rootId = name + '-root'
|
const rootId = name + '-root'
|
||||||
const tree = _router(send.state().location, send.state(), send)
|
const tree = _router(send.state().location, send.state(), send)
|
||||||
tree.setAttribute('id', rootId)
|
tree.setAttribute('id', rootId)
|
||||||
return tree
|
return tree
|
||||||
|
|
||||||
|
function handleAction (action, state, send) {
|
||||||
|
var _reducers = false
|
||||||
|
var _effects = false
|
||||||
|
var newState = null
|
||||||
|
|
||||||
|
if (reducers[action.type]) {
|
||||||
|
newState = xtend(state, reducers[action.type](action, state))
|
||||||
|
_reducers = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (effects[action.type]) {
|
||||||
|
effects[action.type](action, newState || state, send)
|
||||||
|
newState = newState || state
|
||||||
|
_effects = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_reducers && !_effects) {
|
||||||
|
throw new Error('Could not find action ' + action.type)
|
||||||
|
}
|
||||||
|
|
||||||
|
return newState
|
||||||
|
}
|
||||||
|
|
||||||
// update on every change
|
// update on every change
|
||||||
function onchange (action, state) {
|
function onchange (action, state) {
|
||||||
const oldTree = document.querySelector('#' + rootId)
|
const oldTree = document.querySelector('#' + rootId)
|
||||||
@@ -76,17 +104,36 @@ function choo (opts) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// initial application state model
|
// initial application state model
|
||||||
// null -> obj
|
// obj -> obj
|
||||||
function appInit () {
|
function appInit (opts) {
|
||||||
return {
|
const model = {
|
||||||
state: {
|
state: {
|
||||||
location: document.location.href
|
location: document.location.href
|
||||||
},
|
},
|
||||||
reducers: {
|
reducers: {
|
||||||
location: setLocation
|
location: setLocation
|
||||||
}
|
},
|
||||||
|
subscriptions: []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opts.href !== false) {
|
||||||
|
model.subscriptions.push(function (send) {
|
||||||
|
href(function (href) {
|
||||||
|
send('location', { location: href })
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opts.history !== false) {
|
||||||
|
model.subscriptions.push(function (send) {
|
||||||
|
history(function (href) {
|
||||||
|
send('location', { location: href })
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return model
|
||||||
|
|
||||||
// handle href links
|
// handle href links
|
||||||
function setLocation (action, state) {
|
function setLocation (action, state) {
|
||||||
const location = action.location.replace(/#.*/, '')
|
const location = action.location.replace(/#.*/, '')
|
||||||
@@ -94,49 +141,6 @@ function appInit () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function bootstrap (events) {
|
|
||||||
const initialState = {}
|
|
||||||
const reducers = {}
|
|
||||||
const effects = {}
|
|
||||||
|
|
||||||
events.forEach(function (model) {
|
|
||||||
if (model.state) apply(model.name, model.state, initialState)
|
|
||||||
if (model.reducers) apply(model.name, model.reducers, reducers)
|
|
||||||
if (model.effects) apply(model.name, model.effects, effects)
|
|
||||||
if (model.subscriptions) {
|
|
||||||
apply(model.name, model.subscriptions, initialState)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
|
||||||
handleAction: handleAction,
|
|
||||||
state: initialState
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleAction (action, state, send) {
|
|
||||||
var _reducers = false
|
|
||||||
var _effects = false
|
|
||||||
var newState = null
|
|
||||||
|
|
||||||
if (reducers[action.type]) {
|
|
||||||
newState = xtend(state, reducers[action.type](action, state))
|
|
||||||
_reducers = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (effects[action.type]) {
|
|
||||||
effects[action.type](action, newState || state, send)
|
|
||||||
newState = newState || state
|
|
||||||
_effects = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_reducers && !_effects) {
|
|
||||||
throw new Error('Could not find action ' + action.type)
|
|
||||||
}
|
|
||||||
|
|
||||||
return newState
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// compose an object conditionally
|
// compose an object conditionally
|
||||||
// (str, obj, obj) -> null
|
// (str, obj, obj) -> null
|
||||||
function apply (name, source, target) {
|
function apply (name, source, target) {
|
||||||
|
|||||||
Reference in New Issue
Block a user