work in progress

This commit is contained in:
Rich Harris
2018-02-16 12:01:55 -05:00
parent 9a760c570f
commit f9828f9fd2
36 changed files with 667 additions and 7791 deletions

6
test/app/app/client.js Normal file
View File

@@ -0,0 +1,6 @@
import { init } from '../../../runtime.js';
import { routes } from './manifest/client.js';
window.init = () => {
return init(document.querySelector('#sapper'), routes);
};

View File

@@ -0,0 +1,12 @@
// This file is generated by Sapper — do not edit it!
export const routes = [
{ pattern: /^\/?$/, params: () => ({}), load: () => import(/* webpackChunkName: "_" */ '../../routes/index.html') },
{ pattern: /^\/4xx\/?$/, params: () => ({}), load: () => import(/* webpackChunkName: "_4xx" */ '../../routes/4xx.html') },
{ pattern: /^\/about\/?$/, params: () => ({}), load: () => import(/* webpackChunkName: "about" */ '../../routes/about.html') },
{ pattern: /^\/show-url\/?$/, params: () => ({}), load: () => import(/* webpackChunkName: "show_url" */ '../../routes/show-url.html') },
{ pattern: /^\/slow-preload\/?$/, params: () => ({}), load: () => import(/* webpackChunkName: "slow_preload" */ '../../routes/slow-preload.html') },
{ pattern: /^\/delete-test\/?$/, params: () => ({}), load: () => import(/* webpackChunkName: "delete_test" */ '../../routes/delete-test.html') },
{ pattern: /^\/5xx\/?$/, params: () => ({}), load: () => import(/* webpackChunkName: "_5xx" */ '../../routes/5xx.html') },
{ pattern: /^\/blog\/?$/, params: () => ({}), load: () => import(/* webpackChunkName: "blog" */ '../../routes/blog/index.html') },
{ pattern: /^\/blog(?:\/([^\/]+))?\/?$/, params: match => ({ slug: match[1] }), load: () => import(/* webpackChunkName: "blog_$slug$" */ '../../routes/blog/[slug].html') }
];

View File

@@ -0,0 +1,28 @@
// This file is generated by Sapper — do not edit it!
import _ from '../../routes/index.html';
import _4xx from '../../routes/4xx.html';
import about from '../../routes/about.html';
import show_url from '../../routes/show-url.html';
import slow_preload from '../../routes/slow-preload.html';
import delete_test from '../../routes/delete-test.html';
import _5xx from '../../routes/5xx.html';
import blog from '../../routes/blog/index.html';
import * as api_blog_contents from '../../routes/api/blog/contents.js';
import * as api_delete_$id$ from '../../routes/api/delete/[id].js';
import * as api_blog_$slug$ from '../../routes/api/blog/[slug].js';
import blog_$slug$ from '../../routes/blog/[slug].html';
export const routes = [
{ id: '_', type: 'page', pattern: /^\/?$/, params: () => ({}), module: _ },
{ id: '_4xx', type: 'page', pattern: /^\/4xx\/?$/, params: () => ({}), module: _4xx },
{ id: 'about', type: 'page', pattern: /^\/about\/?$/, params: () => ({}), module: about },
{ id: 'show_url', type: 'page', pattern: /^\/show-url\/?$/, params: () => ({}), module: show_url },
{ id: 'slow_preload', type: 'page', pattern: /^\/slow-preload\/?$/, params: () => ({}), module: slow_preload },
{ id: 'delete_test', type: 'page', pattern: /^\/delete-test\/?$/, params: () => ({}), module: delete_test },
{ id: '_5xx', type: 'page', pattern: /^\/5xx\/?$/, params: () => ({}), module: _5xx },
{ id: 'blog', type: 'page', pattern: /^\/blog\/?$/, params: () => ({}), module: blog },
{ id: 'api_blog_contents', type: 'route', pattern: /^\/api\/blog\/contents\/?$/, params: () => ({}), module: api_blog_contents },
{ id: 'api_delete_$id$', type: 'route', pattern: /^\/api\/delete(?:\/([^\/]+))?\/?$/, params: match => ({ id: match[1] }), module: api_delete_$id$ },
{ id: 'api_blog_$slug$', type: 'route', pattern: /^\/api\/blog(?:\/([^\/]+))?\/?$/, params: match => ({ slug: match[1] }), module: api_blog_$slug$ },
{ id: 'blog_$slug$', type: 'page', pattern: /^\/blog(?:\/([^\/]+))?\/?$/, params: match => ({ slug: match[1] }), module: blog_$slug$ }
];

View File

@@ -0,0 +1,37 @@
export const timestamp = 1518800295364;
export const assets = [
"favicon.png",
"global.css",
"great-success.png",
"manifest.json",
"svelte-logo-192.png",
"svelte-logo-512.png"
];
export const shell = [
"/client/_.0.3a37f8afa58c59f4bdf9.js",
"/client/blog.1.3a37f8afa58c59f4bdf9.js",
"/client/blog_$slug$.2.3a37f8afa58c59f4bdf9.js",
"/client/about.3.3a37f8afa58c59f4bdf9.js",
"/client/_5xx.4.3a37f8afa58c59f4bdf9.js",
"/client/_4xx.5.3a37f8afa58c59f4bdf9.js",
"/client/slow_preload.6.3a37f8afa58c59f4bdf9.js",
"/client/show_url.7.3a37f8afa58c59f4bdf9.js",
"/client/delete_test.8.3a37f8afa58c59f4bdf9.js",
"/client/main.3a37f8afa58c59f4bdf9.js"
];
export const routes = [
{ pattern: /^\/?$/ },
{ pattern: /^\/4xx\/?$/ },
{ pattern: /^\/about\/?$/ },
{ pattern: /^\/show-url\/?$/ },
{ pattern: /^\/slow-preload\/?$/ },
{ pattern: /^\/delete-test\/?$/ },
{ pattern: /^\/5xx\/?$/ },
{ pattern: /^\/blog\/?$/ },
{ pattern: /^\/blog(?:\/([^\/]+))?\/?$/ }
];

78
test/app/app/server.js Normal file
View File

@@ -0,0 +1,78 @@
import fs from 'fs';
import express from 'express';
import compression from 'compression';
import serve from 'serve-static';
import sapper from '../../../middleware';
import { routes } from './manifest/server.js';
let count;
let ended;
process.on('message', message => {
if (message.action === 'start') {
count = 0;
ended = false;
process.send({ type: 'ready' });
}
if (message.action === 'end') {
ended = true;
if (count === 0) process.send({ type: 'done' });
}
});
const app = express();
app.use((req, res, next) => {
count += 1;
const { write, end } = res;
const chunks = [];
res.write = function(chunk) {
chunks.push(new Buffer(chunk));
write.apply(res, arguments);
};
res.end = function(chunk) {
if (chunk) chunks.push(new Buffer(chunk));
end.apply(res, arguments);
count -= 1;
process.send({
method: req.method,
url: req.url,
status: res.statusCode,
headers: res._headers,
body: Buffer.concat(chunks).toString()
});
if (count === 0 && ended) {
process.send({ type: 'done' });
}
};
next();
});
const { PORT = 3000 } = process.env;
// this allows us to do e.g. `fetch('/api/blog')` on the server
const fetch = require('node-fetch');
global.fetch = (url, opts) => {
if (url[0] === '/') url = `http://localhost:${PORT}${url}`;
return fetch(url, opts);
};
app.use(compression({ threshold: 0 }));
app.use(serve('assets'));
app.use(sapper({
routes
}));
app.listen(PORT, () => {
console.log(`listening on port ${PORT}`);
});

View File

@@ -0,0 +1,75 @@
import { assets, shell, timestamp, routes } from './manifest/service-worker.js';
const ASSETS = `cachetimestamp`;
// `shell` is an array of all the files generated by webpack,
// `assets` is an array of everything in the `assets` directory
const to_cache = shell.concat(assets);
const cached = new Set(to_cache);
self.addEventListener('install', event => {
event.waitUntil(
caches
.open(ASSETS)
.then(cache => cache.addAll(to_cache))
.then(() => {
self.skipWaiting();
})
);
});
self.addEventListener('activate', event => {
event.waitUntil(
caches.keys().then(async keys => {
// delete old caches
for (const key of keys) {
if (key !== ASSETS) await caches.delete(key);
}
await self.clients.claim();
})
);
});
self.addEventListener('fetch', event => {
const url = new URL(event.request.url);
// don't try to handle e.g. data: URIs
if (!url.protocol.startsWith('http')) return;
// always serve assets and webpack-generated files from cache
if (cached.has(url.pathname)) {
event.respondWith(caches.match(event.request));
return;
}
// for pages, you might want to serve a shell `index.html` file,
// which Sapper has generated for you. It's not right for every
// app, but if it's right for yours then uncomment this section
/*
if (url.origin === self.origin && routes.find(route => route.pattern.test(url.pathname))) {
event.respondWith(caches.match('/index.html'));
return;
}
*/
// for everything else, try the network first, falling back to
// cache if the user is offline. (If the pages never change, you
// might prefer a cache-first approach to a network-first one.)
event.respondWith(
caches
.open('offline')
.then(async cache => {
try {
const response = await fetch(event.request);
cache.put(event.request, response.clone());
return response;
} catch(err) {
const response = await cache.match(event.request);
if (response) return response;
throw err;
}
})
);
});

View File

@@ -0,0 +1,37 @@
<!doctype>
<html lang='en'>
<head>
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width'>
<meta name='theme-color' content='#aa1e1e'>
<link rel='stylesheet' href='/global.css'>
<link rel='manifest' href='/manifest.json'>
<link rel='icon' type='image/png' href='/favicon.png'>
<script>
// if ('serviceWorker' in navigator) {
// navigator.serviceWorker.register('/service-worker.js');
// }
</script>
<!-- Sapper generates a <style> tag containing critical CSS
for the current page. CSS for the rest of the app is
lazily loaded when it precaches secondary pages -->
%sapper.styles%
<!-- This contains the contents of the <:Head> component, if
the current page has one -->
%sapper.head%
</head>
<body>
<!-- The application will be rendered inside this element,
because `templates/main.js` references it -->
<div id='sapper'>%sapper.html%</div>
<!-- Sapper creates a <script> tag containing `templates/main.js`
and anything else it needs to hydrate the app and
initialise the router -->
%sapper.scripts%
</body>
</html>