diff --git a/example/index.js b/example/index.js
index 08fdba8..d33aad6 100644
--- a/example/index.js
+++ b/example/index.js
@@ -1,385 +1,19 @@
-var Microbounce = require('microbounce')
-var Microframe = require('microframe')
-var mutate = require('xtend/mutable')
-var expose = require('choo-expose')
var css = require('sheetify')
-var html = require('bel')
var choo = require('../')
css('todomvc-common/base.css')
css('todomvc-app-css/index.css')
-// we export this so tests can run
-if (module.parent) {
- exports.todoStore = todoStore
-} else {
- var app = choo()
-
- if (process.env.NODE_ENV !== 'production') {
- app.use(require('choo-persist')())
- app.use(require('choo-log')())
- }
- app.use(expose())
- app.use(todoStore)
-
- app.route('/', mainView)
- app.route('#active', mainView)
- app.route('#completed', mainView)
- app.route('*', mainView)
- app.mount('body')
+var app = choo()
+if (process.env.NODE_ENV !== 'production') {
+ app.use(require('choo-devtools')())
}
+app.use(require('./store'))
-function mainView (state, emit) {
- emit('log:debug', 'Rendering main view')
- return html`
-
-
- ${Header(state, emit)}
- ${TodoList(state, emit)}
- ${Footer(state, emit)}
-
-
-
- `
-}
+app.route('/', require('./view'))
+app.route('#active', require('./view'))
+app.route('#completed', require('./view'))
+app.route('*', require('./view'))
-function todoStore (state, emitter) {
- // Default values
- if (!state.todos) {
- state.todos = {}
-
- state.todos.active = []
- state.todos.done = []
- state.todos.all = []
-
- state.todos.idCounter = 0
- }
-
- // Always reset when application boots
- state.todos.input = ''
-
- // Register emitters after DOM is loaded to speed up DOM loading
- emitter.on('DOMContentLoaded', function () {
- // CRUD
- emitter.on('todos:create', create)
- emitter.on('todos:update', update)
- emitter.on('todos:delete', del)
-
- // Special
- emitter.on('todos:input', oninput)
-
- // Shorthand
- emitter.on('todos:edit', edit)
- emitter.on('todos:unedit', unedit)
- emitter.on('todos:toggle', toggle)
- emitter.on('todos:toggleAll', toggleAll)
- emitter.on('todos:deleteCompleted', deleteCompleted)
- })
-
- function oninput (text) {
- state.todos.input = text
- }
-
- function create (name) {
- var item = {
- id: state.todos.idCounter,
- editing: false,
- done: false,
- name: name
- }
-
- state.todos.idCounter += 1
- state.todos.active.push(item)
- state.todos.all.push(item)
- emitter.emit('render')
- }
-
- function edit (id) {
- state.todos.all.forEach(function (todo) {
- if (todo.id === id) todo.editing = true
- })
- emitter.emit('render')
- }
-
- function unedit (id) {
- state.todos.all.forEach(function (todo) {
- if (todo.id === id) todo.editing = false
- })
- emitter.emit('render')
- }
-
- function update (newTodo) {
- var todo = state.todos.all.filter(function (todo) {
- return todo.id === newTodo.id
- })[0]
-
- if (newTodo.done && todo.done === false) {
- state.todos.active.splice(state.todos.active.indexOf(todo), 1)
- state.todos.done.push(todo)
- } else if (newTodo.done === false && todo.done) {
- state.todos.done.splice(state.todos.done.indexOf(todo), 1)
- state.todos.active.push(todo)
- }
-
- mutate(todo, newTodo)
- emitter.emit('render')
- }
-
- function del (id) {
- var i = null
- var todo = null
- state.todos.all.forEach(function (_todo, j) {
- if (_todo.id === id) {
- i = j
- todo = _todo
- }
- })
- state.todos.all.splice(i, 1)
-
- if (todo.done) {
- var done = state.todos.done
- var doneIndex
- done.forEach(function (_todo, j) {
- if (_todo.id === id) {
- doneIndex = j
- }
- })
- done.splice(doneIndex, 1)
- } else {
- var active = state.todos.active
- var activeIndex
- active.forEach(function (_todo, j) {
- if (_todo.id === id) {
- activeIndex = j
- }
- })
- active.splice(activeIndex, 1)
- }
- emitter.emit('render')
- }
-
- function deleteCompleted (data) {
- var done = state.todos.done
- done.forEach(function (todo) {
- var index = state.todos.all.indexOf(todo)
- state.todos.all.splice(index, 1)
- })
- state.todos.done = []
- emitter.emit('render')
- }
-
- function toggle (id) {
- var todo = state.todos.all.filter(function (todo) {
- return todo.id === id
- })[0]
- var done = todo.done
- todo.done = !done
- var arr = done ? state.todos.done : state.todos.active
- var target = done ? state.todos.active : state.todos.done
- var index = arr.indexOf(todo)
- arr.splice(index, 1)
- target.push(todo)
- emitter.emit('render')
- }
-
- function toggleAll (data) {
- var todos = state.todos.all
- var allDone = state.todos.all.length &&
- state.todos.done.length === state.todos.all.length
-
- todos.forEach(function (todo) {
- todo.done = !allDone
- })
-
- if (allDone) {
- state.todos.done = []
- state.todos.active = state.todos.all
- } else {
- state.todos.done = state.todos.all
- state.todos.active = []
- }
-
- emitter.emit('render')
- }
-}
-
-function Footer (state, emit) {
- var filter = window.location.hash.replace(/^#/, '')
- var activeCount = state.todos.active.length
- var hasDone = state.todos.done.length
-
- return html`
-
- `
-
- function filterButton (name, filter, currentFilter, emit) {
- var filterClass = filter === currentFilter
- ? 'selected'
- : ''
-
- var uri = '#' + name.toLowerCase()
- if (uri === '#all') uri = '/'
- return html`
-
-
- ${name}
-
-
- `
- }
-
- function deleteCompleted (emit) {
- return html`
-
- `
-
- function deleteAllCompleted () {
- emit('todos:deleteCompleted')
- }
- }
-}
-
-var debounce = Microbounce(256)
-var nextFrame = Microframe()
-function Header (state, emit) {
- return html`
-
- `
-
- function createTodo (e) {
- var value = e.target.value
- if (!value) return
- if (e.keyCode === 13) {
- nextFrame(function () {
- emit('todos:input', '')
- emit('todos:create', value)
- })
- } else {
- debounce(function () {
- nextFrame(function () {
- emit('todos:input', value)
- })
- })
- }
- }
-}
-
-function TodoItem (todo, emit) {
- var clx = classList({ completed: todo.done, editing: todo.editing })
- return html`
-
-
-
-
-
-
-
-
- `
-
- function toggle (e) {
- emit('todos:toggle', todo.id)
- }
-
- function edit (e) {
- emit('todos:edit', todo.id)
- }
-
- function destroy (e) {
- emit('todos:delete', todo.id)
- }
-
- function update (e) {
- emit('todos:update', {
- id: todo.id,
- editing: false,
- name: e.target.value
- })
- }
-
- function handleEditKeydown (e) {
- if (e.keyCode === 13) update(e) // Enter
- else if (e.code === 27) emit('todos:unedit') // Escape
- }
-
- function classList (classes) {
- var str = ''
- var keys = Object.keys(classes)
- for (var i = 0, len = keys.length; i < len; i++) {
- var key = keys[i]
- var val = classes[key]
- if (val) str += (key + ' ')
- }
- return str
- }
-}
-
-function TodoList (state, emit) {
- var filter = window.location.hash.replace(/^#/, '')
- var items = filter === 'completed'
- ? state.todos.done
- : filter === 'active'
- ? state.todos.active
- : state.todos.all
-
- var allDone = state.todos.done.length === state.todos.all.length
-
- var nodes = items.map(function (todo) {
- return TodoItem(todo, emit)
- })
-
- return html`
-
- `
-
- function toggleAll () {
- emit('todos:toggleAll')
- }
-}
+if (module.parent) module.exports = app
+else app.mount('body')
diff --git a/example/package.json b/example/package.json
index 111ca0b..5a4bbcb 100644
--- a/example/package.json
+++ b/example/package.json
@@ -3,26 +3,19 @@
"version": "1.0.0",
"private": true,
"scripts": {
- "deps": "dependency-check . && dependency-check . --extra --no-dev",
- "start": "bankai start --open",
- "build": "bankai build --optimize",
- "test": "standard && npm run deps && node test.js"
+ "start": "bankai start",
+ "build": "bankai build",
+ "inspect": "bankai inspect",
+ "test": "standard && node test.js"
},
"dependencies": {
- "bel": "^4.5.1",
- "choo-expose": "^1.0.0",
- "choo-log": "^7.0.0-0",
- "choo-persist": "^3.0.0",
- "microbounce": "^1.0.0",
- "microframe": "^1.0.0",
+ "choo-devtools": "1.7.0",
"sheetify": "^6.0.1",
"todomvc-app-css": "^2.0.6",
- "todomvc-common": "^1.0.3",
- "xtend": "^4.0.1"
+ "todomvc-common": "^1.0.3"
},
"devDependencies": {
- "bankai": "^5.4.0",
- "dependency-check": "^2.8.0",
+ "bankai": "^9.0.0-rc6",
"standard": "^9.0.1"
}
}
diff --git a/example/store.js b/example/store.js
new file mode 100644
index 0000000..63f206d
--- /dev/null
+++ b/example/store.js
@@ -0,0 +1,160 @@
+module.exports = todoStore
+
+function todoStore (state, emitter) {
+ if (!state.todos) {
+ state.todos = {}
+
+ state.todos.active = []
+ state.todos.done = []
+ state.todos.all = []
+
+ state.todos.idCounter = 0
+ }
+
+ // Always reset when application boots
+ state.todos.input = ''
+
+ // Register emitters after DOM is loaded to speed up DOM loading
+ emitter.on('DOMContentLoaded', function () {
+ // CRUD
+ emitter.on('todos:create', create)
+ emitter.on('todos:update', update)
+ emitter.on('todos:delete', del)
+
+ // Special
+ emitter.on('todos:input', oninput)
+
+ // Shorthand
+ emitter.on('todos:edit', edit)
+ emitter.on('todos:unedit', unedit)
+ emitter.on('todos:toggle', toggle)
+ emitter.on('todos:toggleAll', toggleAll)
+ emitter.on('todos:deleteCompleted', deleteCompleted)
+ })
+
+ function oninput (text) {
+ state.todos.input = text
+ }
+
+ function create (name) {
+ var item = {
+ id: state.todos.idCounter,
+ editing: false,
+ done: false,
+ name: name
+ }
+
+ state.todos.idCounter += 1
+ state.todos.active.push(item)
+ state.todos.all.push(item)
+ emitter.emit('render')
+ }
+
+ function edit (id) {
+ state.todos.all.forEach(function (todo) {
+ if (todo.id === id) todo.editing = true
+ })
+ emitter.emit('render')
+ }
+
+ function unedit (id) {
+ state.todos.all.forEach(function (todo) {
+ if (todo.id === id) todo.editing = false
+ })
+ emitter.emit('render')
+ }
+
+ function update (newTodo) {
+ var todo = state.todos.all.filter(function (todo) {
+ return todo.id === newTodo.id
+ })[0]
+
+ if (newTodo.done && todo.done === false) {
+ state.todos.active.splice(state.todos.active.indexOf(todo), 1)
+ state.todos.done.push(todo)
+ } else if (newTodo.done === false && todo.done) {
+ state.todos.done.splice(state.todos.done.indexOf(todo), 1)
+ state.todos.active.push(todo)
+ }
+
+ Object.assign(todo, newTodo)
+ emitter.emit('render')
+ }
+
+ function del (id) {
+ var i = null
+ var todo = null
+ state.todos.all.forEach(function (_todo, j) {
+ if (_todo.id === id) {
+ i = j
+ todo = _todo
+ }
+ })
+ state.todos.all.splice(i, 1)
+
+ if (todo.done) {
+ var done = state.todos.done
+ var doneIndex
+ done.forEach(function (_todo, j) {
+ if (_todo.id === id) {
+ doneIndex = j
+ }
+ })
+ done.splice(doneIndex, 1)
+ } else {
+ var active = state.todos.active
+ var activeIndex
+ active.forEach(function (_todo, j) {
+ if (_todo.id === id) {
+ activeIndex = j
+ }
+ })
+ active.splice(activeIndex, 1)
+ }
+ emitter.emit('render')
+ }
+
+ function deleteCompleted (data) {
+ var done = state.todos.done
+ done.forEach(function (todo) {
+ var index = state.todos.all.indexOf(todo)
+ state.todos.all.splice(index, 1)
+ })
+ state.todos.done = []
+ emitter.emit('render')
+ }
+
+ function toggle (id) {
+ var todo = state.todos.all.filter(function (todo) {
+ return todo.id === id
+ })[0]
+ var done = todo.done
+ todo.done = !done
+ var arr = done ? state.todos.done : state.todos.active
+ var target = done ? state.todos.active : state.todos.done
+ var index = arr.indexOf(todo)
+ arr.splice(index, 1)
+ target.push(todo)
+ emitter.emit('render')
+ }
+
+ function toggleAll (data) {
+ var todos = state.todos.all
+ var allDone = state.todos.all.length &&
+ state.todos.done.length === state.todos.all.length
+
+ todos.forEach(function (todo) {
+ todo.done = !allDone
+ })
+
+ if (allDone) {
+ state.todos.done = []
+ state.todos.active = state.todos.all
+ } else {
+ state.todos.done = state.todos.all
+ state.todos.active = []
+ }
+
+ emitter.emit('render')
+ }
+}
diff --git a/example/test.js b/example/test.js
index dd2049a..116e220 100644
--- a/example/test.js
+++ b/example/test.js
@@ -2,8 +2,7 @@ var EventEmitter = require('events').EventEmitter
var spok = require('spok')
var tape = require('tape')
-var example = require('./')
-var todoStore = example.todoStore
+var todoStore = require('./store')
tape('should initialize empty state', function (t) {
var emitter = new EventEmitter()
diff --git a/example/view.js b/example/view.js
new file mode 100644
index 0000000..9f120b5
--- /dev/null
+++ b/example/view.js
@@ -0,0 +1,190 @@
+var html = require('bel') // cannot require choo/html because it's a nested repo
+
+module.exports = mainView
+
+function mainView (state, emit) {
+ emit('log:debug', 'Rendering main view')
+ return html`
+
+
+ ${Header(state, emit)}
+ ${TodoList(state, emit)}
+ ${Footer(state, emit)}
+
+
+
+ `
+}
+
+function Header (state, emit) {
+ return html`
+
+ `
+
+ function createTodo (e) {
+ var value = e.target.value
+ if (!value) return
+ if (e.keyCode === 13) {
+ emit('todos:input', '')
+ emit('todos:create', value)
+ } else {
+ emit('todos:input', value)
+ }
+ }
+}
+
+function Footer (state, emit) {
+ var filter = state.href.replace(/^\//, '') || ''
+ var activeCount = state.todos.active.length
+ var hasDone = state.todos.done.length
+
+ return html`
+
+ `
+
+ function filterButton (name, filter, currentFilter, emit) {
+ var filterClass = filter === currentFilter
+ ? 'selected'
+ : ''
+
+ var uri = '#' + name.toLowerCase()
+ if (uri === '#all') uri = '/'
+ return html`
+
+
+ ${name}
+
+
+ `
+ }
+
+ function deleteCompleted (emit) {
+ return html`
+
+ `
+
+ function deleteAllCompleted () {
+ emit('todos:deleteCompleted')
+ }
+ }
+}
+
+function TodoItem (todo, emit) {
+ var clx = classList({ completed: todo.done, editing: todo.editing })
+ return html`
+
+
+
+
+
+
+
+
+ `
+
+ function toggle (e) {
+ emit('todos:toggle', todo.id)
+ }
+
+ function edit (e) {
+ emit('todos:edit', todo.id)
+ }
+
+ function destroy (e) {
+ emit('todos:delete', todo.id)
+ }
+
+ function update (e) {
+ emit('todos:update', {
+ id: todo.id,
+ editing: false,
+ name: e.target.value
+ })
+ }
+
+ function handleEditKeydown (e) {
+ if (e.keyCode === 13) update(e) // Enter
+ else if (e.code === 27) emit('todos:unedit') // Escape
+ }
+
+ function classList (classes) {
+ var str = ''
+ var keys = Object.keys(classes)
+ for (var i = 0, len = keys.length; i < len; i++) {
+ var key = keys[i]
+ var val = classes[key]
+ if (val) str += (key + ' ')
+ }
+ return str
+ }
+}
+
+function TodoList (state, emit) {
+ var filter = state.href.replace(/^\//, '') || ''
+ var items = filter === 'completed'
+ ? state.todos.done
+ : filter === 'active'
+ ? state.todos.active
+ : state.todos.all
+
+ var allDone = state.todos.done.length === state.todos.all.length
+
+ var nodes = items.map(function (todo) {
+ return TodoItem(todo, emit)
+ })
+
+ return html`
+
+ `
+
+ function toggleAll () {
+ emit('todos:toggleAll')
+ }
+}