t.test('history', function (t) { t.plan(3) const history = Event() const choo = proxyquire('../..', { 'sheet-router/history': history.listen }) const app = choo() app.model({ state: { user: null }, reducers: { set: (action, state) => ({user: action.id}) }, effects: { open: function (action, state, send, done) { t.deepEqual(action, {id: 1}) send('set', {id: 1}, function (err) { if (err) return done(err) history.broadcast('https://foo.com/users/1') }) } } }) app.router('/users', (route) => [ route('/users', parentView, [ route('/:user', childView) ]) ]) const tree = app.start() t.on('end', append(tree)) t.equal(tree.innerHTML.trim(), 'Open') tree.onclick() function parentView (state, prev, send) { return view` <button onclick=${() => send('open', {id: 1})}> Open </button> ` } function childView (state, prev, send) { t.equal(state.user, 1) return view`<button>${state.user}</button>` } })
t.test('hash', function (t) { t.plan(1) const hash = Event() const choo = proxyquire('../..', { 'sheet-router/hash': hash.listen }) const app = choo() app.model({ state: { user: null }, reducers: { set: (action, state) => ({user: action.id}) }, effects: { open: function (action, state, send, done) { send('set', {id: 1}, function (err) { if (err) return done(err) hash.broadcast('#users/1') }) } } }) app.router('/users', (route) => [ route('/users', parentView, [ route('/:user', childView) ]) ]) const tree = app.start({hash: true}) t.on('end', append(tree)) tree.onclick() function parentView (state, prev, send) { return view` <button onclick=${() => send('open', {id: 1})}> Open </button> ` } function childView (state, prev, send) { t.equal(state.user, 1) return view`<button>${state.user}</button>` } })
function AppRouter (apps) { var _default = null const router = HashRouter() const log = Event() validate(apps) apps.forEach(createRoutes) return Object.assign(appRouter, { onLog: log.listen }) function appRouter (req, res, callback) { // Handle ourselves b/c http-hash-router will return 404 with a default // route route regardless of the method if (req.method !== 'GET' && req.method !== 'HEAD') { return callback(MethodNotAllowed({ method: req.method, url: req.url })) } router(req, res, {}, function (err) { if (err && err.type === 'http-hash-router.not-found' && _default) { log.broadcast({ level: 'debug', message: `${req.url} -> default` }) return _default(req, res, callback) } callback(err) }) } function createRoutes (app) { if (app.routes === '*') { log.broadcast({ level: 'debug', message: `Registering "${app.name}" as default app` }) _default = partial(sendApp, app) return } app.routes.forEach((route) => router.set(route, partial(sendApp, app))) } function sendApp (app, req, res, options, callback) { if (!callback) callback = options log.broadcast({ level: 'debug', message: `${req.url} -> ${app.name}` }) fetch(app, pick(req, ['headers', 'url', 'method']), function (err, html) { if (err) return callback(err) log.broadcast({ level: 'info', message: `${app.name}: ${html.statusCode}` }) res.statusCode = html.statusCode const cookies = cookie.outbound(app.cookies, html.headers['set-cookie']) if (cookies) res.setHeader('Set-Cookie', cookies) pump(html, Transform(app), res, callback) }) } }