UNPKG

2.47 kBJavaScriptView Raw
1var getAllRoutes = require('wayfarer/get-all-routes')
2
3module.exports.is = function (app) {
4 return Boolean(app &&
5 app.router &&
6 app.router.router &&
7 app.router.router._trie)
8}
9
10module.exports.listRoutes = function (app) {
11 var keys = getAllRoutes(app.router.router)
12 return Object.keys(keys).filter(function (key) {
13 return !/\/:/.test(key) // Server rendering partials is tricky.
14 })
15}
16
17// Do a double render pass - the first time around we wait for promises to be
18// pushed into `state._experimental_prefetch`. Once all promises resolve, we
19// take the state, and do a second render pass with the new state.
20//
21// In Nanocomponent, people should do a conditional call to render this.
22//
23// ## Example
24//
25// ```js
26// class Button extends Nanocomponent {
27// constructor (name, state, emit) {
28// super(name)
29// this.state = state
30// this.emit = emit
31// this.local = this.state.components[name] = {
32// loaded: false // This is set on the global "state" object.
33// }
34// }
35//
36// render () {
37// if (!this.local.loaded) {
38// this.state._experimental_prefetch.push(this.fetch())
39// }
40//
41// html`<button>
42// ${this.local.loaded ? 'loaded' : 'not loaded'
43// </button>`
44// }
45//
46// update () {
47// return true
48// }
49//
50// async fetch () {
51// this.local.loaded = true // async functions return promises
52// }
53// }
54// ```
55//
56// NOTE: state is never passed in it seems. Funky fn signature, this should be
57// fixed.
58//
59// NOTE: Choo currently doesn't use the passed-in state as the base. It probably
60// should, so we can treat the state as the only stateful bits, and the rest is
61// just context.
62
63module.exports.render = function (app, route, cb) {
64 var state = {}
65 state._experimental_prefetch = []
66
67 return new Promise(function (resolve, reject) {
68 // First pass to populate prefetch
69 try {
70 app.toString(route, state)
71 } catch (err) {
72 return reject(err)
73 }
74 resolve(state._experimental_prefetch)
75 }).then(function (prefetches) {
76 return Promise.all(prefetches)
77 }).then(render).catch(cb)
78
79 function render () {
80 var res = { state: state }
81 res.body = app.toString(route, state)
82 delete res.state._experimental_prefetch // State needs to be serializable.
83 if (app.state.title) res.title = app.state.title
84 if (app.state.language) res.language = app.state.language
85 if (app.selector) res.selector = app.selector
86 cb(null, res)
87 }
88}