diff --git a/package.json b/package.json
index 03c5567..09f3211 100644
--- a/package.json
+++ b/package.json
@@ -10,6 +10,7 @@
"ssg": "node ./ssg.js",
"ssg:serve": "node ./ssg.js && http-server ./dist",
"ssr": "nodemon --watch lib --watch www ./ssr.js",
+ "streaming": "nodemon --watch lib --watch www ./ssr-streaming.js",
"start": "yarn ssr"
},
"dependencies": {
diff --git a/ssg.js b/ssg.js
index c954a14..ebe9011 100644
--- a/ssg.js
+++ b/ssg.js
@@ -37,7 +37,7 @@ for (const entry of entries.filter(entry => entry.endsWith('.js'))) {
- WCC
+ WCC - SSG
${
eagerJs.map(script => {
diff --git a/ssr-streaming.js b/ssr-streaming.js
new file mode 100644
index 0000000..ee64925
--- /dev/null
+++ b/ssr-streaming.js
@@ -0,0 +1,595 @@
+import fastify from 'fastify';
+import fastifyStatic from 'fastify-static';
+import path from 'path';
+import stream, { Readable } from 'stream';
+import { renderToString } from './lib/wcc.js';
+
+const app = fastify({ logger: true });
+const port = 3001;
+
+app.register(fastifyStatic, {
+ root: new URL('./www', import.meta.url).pathname,
+ prefix: '/www'
+})
+app.register(fastifyStatic, {
+ root: new URL('./lib', import.meta.url).pathname,
+ prefix: '/lib',
+ decorateReply: false
+})
+
+function* renderPageStreaming(html, assets) {
+ const lazyJs = [];
+ const eagerJs = [];
+
+ for(const asset in assets) {
+ const a = assets[asset];
+
+ a.tagName = asset;
+
+ if(a.moduleURL.href.endsWith('.js')) {
+ if(a.hydrate === 'lazy') {
+ lazyJs.push(a)
+ } else {
+ eagerJs.push(a)
+ }
+ }
+ }
+
+ yield `
+
+
+
+ WCC - Streaming (SSR)
+ `;
+ yield `
+ ${
+ eagerJs.map(script => {
+ return `
+
+
+ `
+ }).join('\n')
+ }
+ `;
+ yield `
+ ${
+ lazyJs.map(script => {
+ return `
+
+ `
+ }).join('\n')
+ }
+ `;
+
+ yield `
+
+
+ +++++++++++++Start of Stream++++++++++++++
+ ${html}
+ +++++++++++++Start of Stream++++++++++++++
+ `
+
+ yield `
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ `
+
+ yield `
+ +++++++++++++End of Stream++++++++++++++
+ `
+
+ yield `
+
+
+ `;
+}
+
+app.get('/*', async (request, reply) => {
+ const { url } = request;
+
+ if(path.extname(url) === '') {
+ const pageRoute = url === '/' ? '/index' : url;
+ const entryPoint = `./www/pages${pageRoute}.js`
+
+ console.debug({ url });
+ console.debug({ pageRoute })
+ console.debug({ entryPoint })
+
+ const { html, assets } = await renderToString(new URL(entryPoint, import.meta.url), false);
+
+ // https://github.com/fastify/fastify/issues/805#issuecomment-369172154
+ const buffer = new stream.Readable();
+ buffer._read = ()=>{};
+
+ for(const data of renderPageStreaming(html, assets)) {
+ buffer.push(data);
+ }
+
+ buffer.push(null)
+
+ reply.type('text/html').send(buffer)
+
+ // TODO - related to favicon?
+ // Promise may not be fulfilled with 'undefined' when statusCode is not 204",
+ // "stack":"FastifyError: Promise may not be fulfilled with 'undefined' when statusCode is not 204
+ // reply
+ // .header('Content-Type', 'text/html; charset=utf-8')
+ // .header('Transfer-Encoding', 'chunked')
+ // .send(Readable.from(await renderPage(html, assets)));
+ }
+});
+
+const start = async () => {
+ try {
+ await app.listen(port)
+ } catch (err) {
+ app.log.error(err)
+ process.exit(1)
+ }
+}
+
+start()
\ No newline at end of file
diff --git a/ssr.js b/ssr.js
index 7d72e56..4ed166c 100644
--- a/ssr.js
+++ b/ssr.js
@@ -3,6 +3,7 @@ import fastifyStatic from 'fastify-static';
import { renderToString } from './lib/wcc.js';
const app = fastify({ logger: true });
+const port = 3000;
app.register(fastifyStatic, {
root: new URL('./www', import.meta.url).pathname,
@@ -47,7 +48,7 @@ app.get('/*', async (request, reply) => {
- WCC
+ WCC - SSR
${
eagerJs.map(script => {
return ``
@@ -90,7 +91,622 @@ app.get('/*', async (request, reply) => {
- ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}
+ ${html}