-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 2d6d358
Showing
11 changed files
with
362 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
node_modules | ||
|
||
npm-debug.log |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
const h = require('snabbdom/h').default; | ||
|
||
module.exports = function Li({ emitter, props }) { | ||
function store() { | ||
const state = { | ||
value: props.value | ||
}; | ||
|
||
emitter.on('item:change', () => { | ||
state.value = Date.now(); | ||
emitter.emit('self:update'); | ||
}); | ||
|
||
return state; | ||
} | ||
|
||
function change() { | ||
emitter.emit('item:change'); | ||
} | ||
|
||
function view({ state }) { | ||
return h('li', { on: { click: change } }, state.value); | ||
} | ||
|
||
return { | ||
store, | ||
view | ||
}; | ||
}; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
const Li = require('./li'); | ||
const h = require('snabbdom/h').default; | ||
|
||
module.exports = function List({ emitter, component, props }) { | ||
function store() { | ||
const state = { | ||
items: props.items | ||
}; | ||
|
||
emitter.on('item:add', (e) => { | ||
state.items.push(e.value); | ||
emitter.emit('self:update'); | ||
}); | ||
|
||
emitter.on('item:remove', () => { | ||
state.items.pop(); | ||
emitter.emit('self:update'); | ||
}); | ||
|
||
return state; | ||
} | ||
|
||
function add() { | ||
emitter.emit('item:add', { value: Date.now() }); | ||
} | ||
|
||
function remove() { | ||
emitter.emit('item:remove'); | ||
} | ||
|
||
const li = component(Li); | ||
|
||
function view({ state }) { | ||
return h('div#list', [ | ||
h('button', { on: { click: add } }, 'add'), | ||
h('button', { on: { click: remove } }, 'remove'), | ||
h('ul', state.items.map((value, key) => li({ value, key }))) | ||
]); | ||
} | ||
|
||
return { | ||
store, | ||
view | ||
}; | ||
}; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
const { start } = require('../index'); | ||
const List = require('./components/list'); | ||
const h = require('snabbdom/h').default; | ||
|
||
function App({ emitter, component }) { | ||
function store() { | ||
const state = { | ||
time: Date.now() | ||
}; | ||
|
||
emitter.on('change:time', (e) => { | ||
state.time = e.time; | ||
emitter.emit('self:update'); | ||
}); | ||
|
||
return state; | ||
} | ||
|
||
const change = () => { | ||
emitter.emit('change:time', { time: Date.now() }); | ||
}; | ||
|
||
function view({ state }) { | ||
return h('div#app', [ | ||
h('h1', { on: { click: change } }, state.time), | ||
component(List, { items: ['test 1', 'test 2'] }) | ||
]); | ||
} | ||
|
||
return { | ||
store, | ||
view | ||
}; | ||
} | ||
|
||
window.addEventListener('DOMContentLoaded', () => { | ||
const container = document.createElement('div'); | ||
container.id = 'app'; | ||
document.body.insertBefore(container, document.body.firstChild); | ||
|
||
start(container, App); | ||
}); |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
const mitt = require('mitt'); | ||
const createRenderer = require('./lib/create-renderer'); | ||
const { component } = require('./lib/component'); | ||
|
||
function start(container, createApp, props = {}) { | ||
const render = createRenderer(container); | ||
|
||
const emitter = mitt(); | ||
|
||
emitter.on('self:update', () => { | ||
render({ view, state, props }); | ||
}); | ||
|
||
const { view, store } = createApp({ emitter, component: component(emitter), props }); | ||
|
||
const state = store(); | ||
|
||
emitter.emit('self:update'); | ||
|
||
return emitter; | ||
} | ||
|
||
exports.start = start; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
const mitt = require('mitt'); | ||
const give = require('xet'); | ||
const curry = require('curry'); | ||
const DeepMap = require('./deepmap'); | ||
const createRenderer = require('./create-renderer'); | ||
const noop = () => {}; | ||
const instances = new DeepMap(); | ||
|
||
function defineHooks(emitter, vnode) { | ||
vnode.data.hook = vnode.data.hook || {}; | ||
|
||
const userInsert = vnode.data.hook.insert || noop; | ||
const userPostpatch = vnode.data.hook.postpatch || noop; | ||
|
||
vnode.data.hook.insert = vnode => { | ||
vnode.emitter = emitter; | ||
userInsert(vnode); | ||
}; | ||
|
||
vnode.data.hook.postpatch = (oldVnode, vnode) => { | ||
const children = vnode.elm.parentElement.vnode.children; | ||
children[children.indexOf(oldVnode)] = vnode; | ||
userPostpatch(oldVnode, vnode); | ||
}; | ||
|
||
return vnode; | ||
} | ||
|
||
function createComponent(factory, { props = {} }) { | ||
const render = createRenderer(); | ||
|
||
const emitter = mitt(); | ||
|
||
emitter.on('self:update', () => { | ||
render({ view, state, props }); | ||
}); | ||
|
||
const { view: userView, store } = factory({ emitter, component: component(emitter), props }); | ||
|
||
const view = ({ state, props }) => { | ||
return defineHooks(emitter, userView({ state, props })); | ||
}; | ||
|
||
const state = store(); | ||
|
||
render({ view, state, props }); | ||
|
||
return render; | ||
} | ||
|
||
const component = curry((emitter, factory, props) => { | ||
const keys = [emitter, component, props.key]; | ||
|
||
const instance = give.call(instances, keys, () => createComponent(factory, { props })); | ||
|
||
return instance.getVnode(); | ||
}); | ||
|
||
exports.defineHooks = defineHooks; | ||
exports.createComponent = createComponent; | ||
exports.component = component; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
const snabbdom = require('snabbdom'); | ||
const patch = snabbdom.init([ | ||
require('snabbdom/modules/eventlisteners').default, | ||
require('snabbdom/modules/style').default, | ||
require('./remember-vnode') | ||
], require('./htmldomapi')); | ||
|
||
module.exports = function createRenderer(container) { | ||
let vnode = container; | ||
|
||
function render({ view, state, props }) { | ||
if (vnode) { | ||
vnode = patch(vnode, view({ state, props })); | ||
} else { | ||
vnode = view({ state, props }); | ||
} | ||
|
||
return vnode; | ||
} | ||
|
||
render.getVnode = () => { | ||
return vnode; | ||
}; | ||
|
||
return render; | ||
}; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
const give = require('xet'); | ||
const root = new WeakMap(); | ||
const leaves = new Map(); | ||
|
||
const deepClear = deepMap => { | ||
if (leaves.has(deepMap)) { | ||
leaves.delete(deepMap); | ||
} | ||
|
||
for (let map of deepMap.values()) { | ||
deepClear(map); | ||
} | ||
|
||
return deepMap.clear(); | ||
}; | ||
|
||
module.exports = class DeepMap { | ||
constructor(entries = []) { | ||
for (let entry of entries) { | ||
this.set(...entry); | ||
} | ||
|
||
root.set(this, new Map()); | ||
} | ||
|
||
clear() { | ||
return deepClear(this); | ||
} | ||
|
||
delete(keys) { | ||
let branch = root.get(this); | ||
|
||
for (let key of keys) { | ||
if (branch.has(key)) { | ||
branch = branch.get(key); | ||
} else { | ||
return false; | ||
} | ||
} | ||
|
||
return leaves.delete(branch); | ||
} | ||
|
||
has(keys) { | ||
let branch = root.get(this); | ||
|
||
for (let key of keys) { | ||
if (branch.has(key)) { | ||
branch = branch.get(key); | ||
} else { | ||
return false; | ||
} | ||
} | ||
|
||
return leaves.has(branch); | ||
} | ||
|
||
get(keys) { | ||
let branch = root.get(this); | ||
|
||
for (let key of keys) { | ||
branch = branch.get(key); | ||
} | ||
|
||
return leaves.get(branch); | ||
} | ||
|
||
set(keys, value) { | ||
let branch = root.get(this); | ||
|
||
for (let key of keys) { | ||
branch = give.call(branch, key, () => new Map()); | ||
} | ||
|
||
leaves.set(branch, value); | ||
|
||
return this; | ||
} | ||
}; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
const htmldomapi = require('snabbdom/htmldomapi').default; | ||
const removeChild = htmldomapi.removeChild; | ||
|
||
htmldomapi.removeChild = (node, child) => { | ||
if (node && child) { | ||
removeChild(node, child); | ||
} | ||
}; | ||
|
||
module.exports = htmldomapi; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
module.exports = { | ||
create(oldVnode, vnode) { | ||
vnode.elm.vnode = vnode; | ||
}, | ||
update(oldVnode, vnode) { | ||
vnode.elm.vnode = vnode; | ||
} | ||
}; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
{ | ||
"name": "snabbmitt", | ||
"version": "0.0.1", | ||
"description": "", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "eslint .", | ||
"start": "budo example/index.js --live --open" | ||
}, | ||
"keywords": [], | ||
"author": "", | ||
"license": "ISC", | ||
"eslintConfig": { | ||
"extends": "postcss", | ||
"env": { | ||
"browser": true, | ||
"node": true | ||
}, | ||
"rules": { | ||
"max-len": 0, | ||
"no-use-before-define": 0, | ||
"no-shadow": 0 | ||
} | ||
}, | ||
"dependencies": { | ||
"curry": "^1.2.0", | ||
"mitt": "^1.1.0", | ||
"snabbdom": "^0.6.6", | ||
"xet": "^1.0.4" | ||
}, | ||
"devDependencies": { | ||
"budo": "^9.4.7", | ||
"eslint": "^3.17.1", | ||
"eslint-config-postcss": "^2.0.2" | ||
} | ||
} |