From 48d43eaf091240ffb29ded4076ed051cd5c2683b Mon Sep 17 00:00:00 2001 From: Yoshua Wuyts Date: Wed, 11 May 2016 13:51:17 +0700 Subject: [PATCH] choo: add initial render --- README.md | 10 +++- examples/title.js | 30 ++++++++++++ index.js | 119 ++++++++++++++++++++++++++++++++++++++++++++-- package.json | 8 +++- 4 files changed, 161 insertions(+), 6 deletions(-) create mode 100644 examples/title.js diff --git a/README.md b/README.md index 6f55177..c9f7b95 100644 --- a/README.md +++ b/README.md @@ -24,10 +24,10 @@ const app = choo() app.model('title', { state: { title: 'my-demo-app' }, reducers: { - 'update': (action, state) => ({ title: action.payload }) + update: (action, state) => ({ title: action.payload }) }, effects: { - 'update': (action, state) => document.title = action.title + update: (action, state) => (document.title = action.title) } }) @@ -59,6 +59,12 @@ document.appendChild(node) ## API ### choo +## Packages used +- __views:__ [`yo-yo`](https://github.com/maxogden/yo-yo) +- __models:__ [`send-action`](https://github.com/sethvincent/send-action), + [`xtend`](https://github.com/raynos/xtend) +- __routes:__ [`sheet-router`](https://github.com/yoshuawuyts/sheet-router) + ## Installation ```sh $ npm install choo diff --git a/examples/title.js b/examples/title.js new file mode 100644 index 0000000..e415232 --- /dev/null +++ b/examples/title.js @@ -0,0 +1,30 @@ +const choo = require('../') + +const app = choo() +app.model('title', { + state: { title: 'my-demo-app' }, + reducers: { + 'update': (action, state) => ({ title: action.payload }) + }, + effects: { + 'update': (action, state, send) => (document.title = action.title) + } +}) + +const mainView = (params, state, send) => choo.view` +
+

${state.title}

+ + send('title:update', { payload: e.target.value })}> +
+` + +app.router((route) => [ + route('/', mainView) +]) + +const node = app.start() +document.body.appendChild(node) diff --git a/index.js b/index.js index e68f610..3b328e3 100644 --- a/index.js +++ b/index.js @@ -1,8 +1,121 @@ -const assert = require('assert') +// const history = require('sheet-router/history') +const sheetRouter = require('sheet-router') +const document = require('global/document') +// const href = require('sheet-router/href') +const sendAction = require('send-action') +const mutate = require('xtend/mutable') +const xtend = require('xtend') +const yo = require('yo-yo') +choo.view = yo module.exports = choo -// A framework for creating solid web applications -// null -> null +// A framework for creating sturdy web applications +// null -> fn function choo () { + var _router = null + var _models = [ appInit() ] + + start.router = router + start.model = model + start.start = start + + return start + + // start the application + // str|DOMNode -> DOMNode + function start (query) { + const events = bootstrap(_models) + const send = sendAction({ + onaction: events.middleware, + onchange: onchange, + state: events.state + }) + + const node = _router(send.state().location, send.state(), send) + console.log(node) + document.body.appendChild(node) + + // update on every change + function onchange (action, state) { + const el = document.querySelector('#main') + yo.update(el, router(state.location, send, state)) + } + } + + // register all routes + // [obj|fn] -> null + function router (cb) { + _router = sheetRouter(cb) + } + + // create a new model + // (str?, obj) -> null + function model (name, model) { + if (!model) model = name + if (typeof name === 'string') model.name = name + _models.push(model) + } +} + +function appInit () { + return { + state: { + location: document.location.href + }, + reducers: { + location: setLocation + } + } + + // handle href links + function setLocation (action, state) { + const location = action.location.replace(/#.*/, '') + return xtend(state, { location: location }) + } +} + +function bootstrap (events) { + const initialState = { } + const reducers = {} + const effects = {} + + events.forEach(function (event) { + const name = event.name + if (event.state) mutate(initialState, event.state) + if (event.reducers) { + Object.keys(event.reducers).forEach(function (key) { + if (name) { + reducers[name + ':' + key] = event.reducers[key] + } else { + reducers[key] = event.reducers[key] + } + }) + } + if (event.effects) { + Object.keys(event.effects).forEach(function (key) { + if (name) { + effects[name + ':' + key] = event.effects[key] + } else { + effects[key] = event.effects[key] + } + }) + } + }) + + return { + middleware: modifyState, + state: initialState + } + + function modifyState (action, state, send) { + if (reducers[action.type]) { + return reducers[action.type](action, state, send) + } else if (effects[action.type]) { + effects[action.type](action, state, send) + return state + } else { + throw new Error('Could not find action ' + action.type) + } + } } diff --git a/package.json b/package.json index 54f83d5..6875ff9 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,13 @@ "tiny" ], "license": "MIT", - "dependencies": {}, + "dependencies": { + "global": "^4.3.0", + "send-action": "^1.1.0", + "sheet-router": "^2.0.4", + "xtend": "^4.0.1", + "yo-yo": "^1.2.0" + }, "devDependencies": { "dependency-check": "^2.5.1", "istanbul": "^0.4.3",