Skip to content

Instantly share code, notes, and snippets.

@0x6a68
Forked from twfarland/vdom-stream.js
Created March 24, 2016 18:35
Show Gist options
  • Save 0x6a68/080229eae12ba611eed1 to your computer and use it in GitHub Desktop.
Save 0x6a68/080229eae12ba611eed1 to your computer and use it in GitHub Desktop.
redux style reducer with vdom, baconjs and immutablejs
import Immutable from 'immutable'
import Bacon from 'baconjs'
import h from 'virtual-dom/h'
import diff from 'virtual-dom/diff'
import patch from 'virtual-dom/patch'
import createElement from 'virtual-dom/create-element'
const INCREMENT = 'INCREMENT'
const DECREMENT = 'DECREMENT'
// State, Action -> State
function reducer (state = initialState, action) {
switch (action.type) {
case INCREMENT:
return state.set('count', state.get('count') + 1)
case DECREMENT:
return state.set('count', state.get('count') - 1)
default:
return state
}
}
// State -> VDom
function view (state) {
return h('div', {},
[ h('b', { onclick: () => actions.push({ type: DECREMENT }) }, ['[-]'])
, String(state.get('count'))
, h('b', { onclick: () => actions.push({ type: INCREMENT }) }, ['[+]'])
])
}
// State
const initialState = Immutable.fromJS({
count: 0
})
// VDom
const initialVDom = view(initialState)
// Bus Action
const actions = new Bacon.Bus() // like elm mailbox
// Stream State
const model = actions.scan(initialState, reducer) // scan is like elm foldp
// Stream VDom
const vDoms = model.map(view)
// Stream Patch
const patches = vDoms.scan(initialVDom, diff)
// DomNode, VDom, Stream Patch -> _
function mount (parent, vDom, patchesStream) {
var dom = createElement(vDom)
patchesStream.onValue(patches => {
dom = patch(dom, patches)
})
parent.appendChild(dom)
}
mount(document.body, initialVDom, patches)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment