diff --git a/package-lock.json b/package-lock.json index 3cd23daf..717e9437 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8102,7 +8102,7 @@ } }, "sapper": { - "version": "github:nolanlawson/sapper#701bc3455a9387d76f8047e7152c8295c9516788", + "version": "github:nolanlawson/sapper#2b21a7cfefaa9305354ce0ce0a51a83e9fe645a6", "requires": { "chalk": "2.3.2", "chokidar": "1.7.0", @@ -8131,13 +8131,14 @@ } }, "ajv": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.3.0.tgz", - "integrity": "sha1-FlCkERTvAFdMrBC4Ay2PTBSBLac=", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.4.0.tgz", + "integrity": "sha1-06/3jpJ3VJdx2vAWTP9ISCt1T8Y=", "requires": { "fast-deep-equal": "1.0.0", "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" + "json-schema-traverse": "0.3.1", + "uri-js": "3.0.2" } }, "ansi-styles": { @@ -8336,7 +8337,7 @@ "requires": { "acorn": "5.3.0", "acorn-dynamic-import": "2.0.2", - "ajv": "6.3.0", + "ajv": "6.4.0", "ajv-keywords": "3.1.0", "async": "2.6.0", "enhanced-resolve": "3.4.1", @@ -10230,6 +10231,21 @@ "resolved": "https://registry.npmjs.org/upath/-/upath-1.0.4.tgz", "integrity": "sha512-d4SJySNBXDaQp+DPrziv3xGS6w3d2Xt69FijJr86zMPBy23JEloMCEOUBBzuN7xCtjLCnmB9tI/z7SBCahHBOw==" }, + "uri-js": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-3.0.2.tgz", + "integrity": "sha1-+QuFhQf4HepNz7s8TD2/orVX+qo=", + "requires": { + "punycode": "2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", + "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=" + } + } + }, "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", diff --git a/server.js b/server.js index 534ed12e..425759d9 100644 --- a/server.js +++ b/server.js @@ -17,7 +17,7 @@ app.use(compression({ threshold: 0 })) app.use(serveStatic('assets', { setHeaders: (res) => { - res.setHeader('Cache-Control', 'public,max-age=14400') + res.setHeader('Cache-Control', 'public,max-age=600') } })) diff --git a/templates/service-worker.js b/templates/service-worker.js index bbe0d6d4..f806331f 100644 --- a/templates/service-worker.js +++ b/templates/service-worker.js @@ -1,13 +1,19 @@ const timestamp = '__timestamp__' -const ASSETS = `cache${timestamp}` +const ASSETS = `assets_${timestamp}` +const ON_DEMAND = `ondemand_${timestamp}` -// `shell` is an array of all the files generated by webpack, // `assets` is an array of everything in the `assets` directory -const assets = __assets__.map(file => file.startsWith('/') ? file : `/${file}`) -const toCache = __shell__.concat(assets) - .filter(filename => !filename.endsWith('.map')) +const assets = __assets__ + .map(file => file.startsWith('/') ? file : `/${file}`) .filter(filename => !filename.startsWith('/apple-icon')) -const cached = new Set(toCache) + +// `shell` is an array of all the files generated by webpack +// also contains '/index.html' for some reason +const resources = __shell__ + .filter(filename => !filename.endsWith('.map')) + +const toCache = [].concat(assets).concat(resources) +const cacheSet = new Set(toCache) // `routes` is an array of `{ pattern: RegExp }` objects that // match the pages in your app @@ -24,17 +30,19 @@ self.addEventListener('install', event => { self.addEventListener('activate', event => { event.waitUntil((async () => { let keys = await caches.keys() - // delete old caches + + // delete old asset/ondemand caches for (let key of keys) { - if (key !== ASSETS) { + if (key !== ASSETS && key !== ON_DEMAND) { await caches.delete(key) } } + await self.clients.claim() })()) }) -const CACHE_FIRST = [ +const ON_DEMAND_PATHS = [ '/system/accounts/avatars' ] @@ -48,26 +56,24 @@ self.addEventListener('fetch', event => { } event.respondWith((async () => { - // always serve assets and webpack-generated files from cache - if (url.origin === self.origin && cached.has(url.pathname)) { - let cache = await caches.open(ASSETS) - return cache.match(req) + let sameOrigin = url.origin === self.origin + + // always serve webpack-generated resources and + // assets from the cache + if (sameOrigin && cacheSet.has(url.pathname)) { + return caches.match(req) } - // 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))) { - let cache = await caches.open(ASSETS) - return cache.match('/index.html') + // for routes, serve the /index.html file from the most recent + // assets cache + if (sameOrigin && routes.find(route => route.pattern.test(url.pathname))) { + return caches.match('/index.html') } // For these GET requests, go cache-first if (req.method === 'GET' && - CACHE_FIRST.some(pattern => url.pathname.startsWith(pattern))) { - let cache = await caches.open(`offline${timestamp}`) + ON_DEMAND_PATHS.some(pattern => url.pathname.startsWith(pattern))) { + let cache = await caches.open(ON_DEMAND) let response = await cache.match(req) if (response) { // update asynchronously