diff --git a/lib/index.js b/lib/index.js index f93a691..c9fca5d 100644 --- a/lib/index.js +++ b/lib/index.js @@ -140,19 +140,31 @@ function get_route_handler(fn) { res.set('Link', `<${client.main_file}>;rel="preload";as="script", <${client.routes[route.id]}>;rel="preload";as="script"`); let data = { params: req.params, query: req.query }; - if (mod.preload) data = Object.assign(data, await mod.preload(data)); - const { html, head, css } = mod.render(data); + if (mod.preload) { + const promise = Promise.resolve(mod.preload(data)).then(preloaded => { + Object.assign(data, preloaded); + return mod.render(data); + }); - const page = templates.render(200, { - main: client.main_file, - html, - head: `${head}`, - styles: (css && css.code ? `` : '') - }); + templates.stream(res, 200, { + main: client.main_file, + html: promise.then(rendered => rendered.html), + head: promise.then(({ head }) => `${head}`), + styles: promise.then(({ css }) => (css && css.code ? `` : '')) + }); + } else { + const { html, head, css } = mod.render(data); - res.status(200); - res.end(page); + const page = templates.render(200, { + main: client.main_file, + html, + head: `${head}`, + styles: (css && css.code ? `` : '') + }); + + res.end(page); + } } else { diff --git a/lib/templates.js b/lib/templates.js index 137e478..93274d1 100644 --- a/lib/templates.js +++ b/lib/templates.js @@ -26,10 +26,36 @@ function create_templates() { return { test: status => pattern.test(status), specificity, - render(data) { + render: data => { return template.replace(/%sapper\.(\w+)%/g, (match, key) => { return key in data ? data[key] : ''; }); + }, + stream: async (res, data) => { + let i = 0; + + do { + const start = template.indexOf('%sapper', i); + + if (start === -1) { + res.end(template.slice(start)); + return; + } + + res.write(template.slice(i, start)); + + const end = template.indexOf('%', start + 1); + if (end === -1) { + throw new Error(`Bad template`); // TODO validate ahead of time + } + + const tag = template.slice(start + 1, end); + const match = /sapper\.(\w+)/.exec(tag); + if (!match || !(match[1] in data)) throw new Error(`Bad template`); // TODO ditto + + res.write(await data[match[1]]); + i = end + 1; + } while (i < template.length); } } }) @@ -52,5 +78,12 @@ exports.render = (status, data) => { const template = templates.find(template => template.test(status)); if (template) return template.render(data); + return `Missing template for status code ${status}`; +}; + +exports.stream = (res, status, data) => { + const template = templates.find(template => template.test(status)); + if (template) return template.stream(res, data); + return `Missing template for status code ${status}`; }; \ No newline at end of file