Skip to content

Instantly share code, notes, and snippets.

@ishiduca
Last active February 6, 2018 00:04
Show Gist options
  • Save ishiduca/d491b2a4fe9c1e726b989df62f3079ae to your computer and use it in GitHub Desktop.
Save ishiduca/d491b2a4fe9c1e726b989df62f3079ae to your computer and use it in GitHub Desktop.
yo-yo + mississippi => shibainu
module.exports = {
init: init,
update: update,
view: view,
run: run
}
function init () { return {model: null} }
function update (model) { return {model: model} }
function view () { return null }
function run () { return null }
const missi = require('mississippi')
const {start, html} = require('./index')
const {views} = start({
init () {
return {
model: 0,
effect: 'SCHEDULE_TICK'
}
},
update (model, action) {
if (action === 'TICK') {
return {
model: (model + 1) % 60,
effect: 'SCHEDULE_TICK'
}
} else {
return {model}
}
},
view (model, dispatch) {
return html`
<div>
<h1>${model}</h1>
</div>
`
},
run (effect, sources) {
if (effect === 'SCHEDULE_TICK') {
const s = missi.through.obj()
setTimeout(() => s.end('TICK'), 1000)
return s
}
}
})
const main = html`<div></div>`
document.body.appendChild(main)
missi.pipe(
views(),
missi.through.obj((view, _, done) => {
html.update(main, view)
done()
}),
err => console.error(err)
)
module.exports = require('yo-yo')
module.exports = {
defaults: require('./defaults'),
start: require('./start'),
html: require('./html')
}
var xtend = require('xtend')
var defined = require('defined')
var missi = require('mississippi')
var defaults = require('./defaults')
module.exports = start
function start (app) {
app = xtend(app)
var init = defined(app.init, defaults.init)
var update = defined(app.update, defaults.update)
var view = defined(app.view, defaults.view)
var run = defined(app.run, defaults.run)
var actions = missi.through.obj()
var states = missi.through.obj()
var models = missi.through.obj()
var views = missi.through.obj()
var effects = missi.through.obj()
var effectActionsSources = missi.through.obj()
function dispatch (nextAction) {
actions.write(nextAction)
}
var initialState = init.call(app)
missi.pipe(
actions,
scan(function (state, action) {
return update.call(app, state.model, action)
}, initialState),
states,
map(function (state) {
return state.model
}),
difference(),
models,
map(function (model) {
return view.call(app, model, dispatch)
}),
filter(function (x) { return x != null }),
views,
onEnd
)
var notifys = {
actions: actions,
states: states,
models: models,
views: views,
effects: effects,
effectActionsSources: effectActionsSources
}
var sources = {}
Object.keys(notifys).forEach(function (name) {
sources[name] = (
['states', 'models', 'effects', 'views'].indexOf(name) !== -1
) ? replayLastValue(notifys[name]) : notifys[name]
})
missi.pipe(
states,
map(function (state) {
return state.effect
}),
filter(function (x) { return x != null }),
effects,
map(function (effect) {
return run.call(app, effect, sources)
}),
filter(function (x) { return x != null }),
effectActionsSources,
missi.through.obj(function (stream, _, done) {
stream.pipe(missi.through.obj(function (action, _, d) {
done(null, action)
d()
}))
}),
actions,
onEnd
)
process.nextTick(function () {
states.write(initialState)
})
return xtend(sources, {stop: stop})
function stop () {
Object.keys(notifys).forEach(function (name) {
notifys[name].end()
})
}
function onEnd (err) {
if (err) console.error(err)
}
}
function replayLastValue (s) {
var lastValue
s.pipe(missi.through.obj(function (x, _, done) {
lastValue = x
done()
}))
return function () {
return missi.through.obj(function (x, _, done) {
done(null, lastValue)
}).pipe(s)
}
}
function difference () {
var lastValue
return filter(function (x) {
var flg = x !== lastValue
lastValue = x
return flg
})
}
function filter (f) {
return missi.through.obj(function (x, _, done) {
var flg = !!f(x)
if (flg) done(null, x)
else done()
})
}
function map (f) {
return missi.through.obj(function (x, _, done) {
done(null, f(x))
})
}
function scan (f, a) {
var data = xtend(a)
return missi.through.obj(function (x, _, done) {
data = f(data, x)
done(null, data)
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment