Skip to content
This repository was archived by the owner on Jan 11, 2023. It is now read-only.

Commit 8925e54

Browse files
authored
Merge pull request #36 from sveltejs/gh-19
stream responses
2 parents 45e845e + a48afb7 commit 8925e54

File tree

2 files changed

+58
-13
lines changed

2 files changed

+58
-13
lines changed

lib/index.js

+24-12
Original file line numberDiff line numberDiff line change
@@ -140,19 +140,31 @@ function get_route_handler(fn) {
140140
res.set('Link', `<${client.main_file}>;rel="preload";as="script", <${client.routes[route.id]}>;rel="preload";as="script"`);
141141

142142
let data = { params: req.params, query: req.query };
143-
if (mod.preload) data = Object.assign(data, await mod.preload(data));
144143

145-
const { html, head, css } = mod.render(data);
146-
147-
const page = templates.render(200, {
148-
main: client.main_file,
149-
html,
150-
head: `<noscript id='sapper-head-start'></noscript>${head}<noscript id='sapper-head-end'></noscript>`,
151-
styles: (css && css.code ? `<style>${css.code}</style>` : '')
152-
});
153-
154-
res.status(200);
155-
res.end(page);
144+
if (mod.preload) {
145+
const promise = Promise.resolve(mod.preload(data)).then(preloaded => {
146+
Object.assign(data, preloaded);
147+
return mod.render(data);
148+
});
149+
150+
templates.stream(res, 200, {
151+
main: client.main_file,
152+
html: promise.then(rendered => rendered.html),
153+
head: promise.then(({ head }) => `<noscript id='sapper-head-start'></noscript>${head}<noscript id='sapper-head-end'></noscript>`),
154+
styles: promise.then(({ css }) => (css && css.code ? `<style>${css.code}</style>` : ''))
155+
});
156+
} else {
157+
const { html, head, css } = mod.render(data);
158+
159+
const page = templates.render(200, {
160+
main: client.main_file,
161+
html,
162+
head: `<noscript id='sapper-head-start'></noscript>${head}<noscript id='sapper-head-end'></noscript>`,
163+
styles: (css && css.code ? `<style>${css.code}</style>` : '')
164+
});
165+
166+
res.end(page);
167+
}
156168
}
157169

158170
else {

lib/templates.js

+34-1
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,36 @@ function create_templates() {
2626
return {
2727
test: status => pattern.test(status),
2828
specificity,
29-
render(data) {
29+
render: data => {
3030
return template.replace(/%sapper\.(\w+)%/g, (match, key) => {
3131
return key in data ? data[key] : '';
3232
});
33+
},
34+
stream: async (res, data) => {
35+
let i = 0;
36+
37+
do {
38+
const start = template.indexOf('%sapper', i);
39+
40+
if (start === -1) {
41+
res.end(template.slice(start));
42+
return;
43+
}
44+
45+
res.write(template.slice(i, start));
46+
47+
const end = template.indexOf('%', start + 1);
48+
if (end === -1) {
49+
throw new Error(`Bad template`); // TODO validate ahead of time
50+
}
51+
52+
const tag = template.slice(start + 1, end);
53+
const match = /sapper\.(\w+)/.exec(tag);
54+
if (!match || !(match[1] in data)) throw new Error(`Bad template`); // TODO ditto
55+
56+
res.write(await data[match[1]]);
57+
i = end + 1;
58+
} while (i < template.length);
3359
}
3460
}
3561
})
@@ -52,5 +78,12 @@ exports.render = (status, data) => {
5278
const template = templates.find(template => template.test(status));
5379
if (template) return template.render(data);
5480

81+
return `Missing template for status code ${status}`;
82+
};
83+
84+
exports.stream = (res, status, data) => {
85+
const template = templates.find(template => template.test(status));
86+
if (template) return template.stream(res, data);
87+
5588
return `Missing template for status code ${status}`;
5689
};

0 commit comments

Comments
 (0)