Add a serviceworker (#234)

* Add a serviceworker

* rename + fix random extra character

* Fixing worker typings

* Fixing types properly this time.

* Once of those rare cases where this matters.

* Naming the things.

* Move registration to the app (so we can use snackbar later)

* Moving SW plugin later so it picks up things like HTML

* MVP service worker

* Two stage-service worker

* Fix prerendering by conditionally awaiting Custom Elements polyfill.

* Fix icon 404's

* add doc comment to autoswplugin

* Fix type
This commit is contained in:
Jason Miller
2018-11-08 07:02:05 -05:00
committed by Jake Archibald
parent e4e130c5d6
commit 7d42d4f973
28 changed files with 450 additions and 36 deletions

63
src/sw/index.ts Normal file
View File

@@ -0,0 +1,63 @@
import {
cacheOrNetworkAndCache, cleanupCache, cacheOrNetwork, cacheBasics, cacheAdditionalProcessors,
} from './util';
import { get } from 'idb-keyval';
// Give TypeScript the correct global.
declare var self: ServiceWorkerGlobalScope;
// This is populated by webpack.
declare var BUILD_ASSETS: string[];
const version = '1.0.0';
const versionedCache = 'static-' + version;
const dynamicCache = 'dynamic';
const expectedCaches = [versionedCache, dynamicCache];
self.addEventListener('install', (event) => {
event.waitUntil(async function () {
const promises = [];
promises.push(cacheBasics(versionedCache, BUILD_ASSETS));
// If the user has already interacted with the app, update the codecs too.
if (await get('user-interacted')) {
promises.push(cacheAdditionalProcessors(versionedCache, BUILD_ASSETS));
}
await Promise.all(promises);
}());
});
self.addEventListener('activate', (event) => {
event.waitUntil(async function () {
// Remove old caches.
const promises = (await caches.keys()).map((cacheName) => {
if (!expectedCaches.includes(cacheName)) return caches.delete(cacheName);
});
await Promise.all<any>(promises);
}());
});
self.addEventListener('fetch', (event) => {
// We only care about GET.
if (event.request.method !== 'GET') return;
const url = new URL(event.request.url);
// Don't care about other-origin URLs
if (url.origin !== location.origin) return;
if (url.pathname.startsWith('/demo-') || url.pathname.startsWith('/wc-polyfill')) {
cacheOrNetworkAndCache(event, dynamicCache);
cleanupCache(event, dynamicCache, BUILD_ASSETS);
return;
}
cacheOrNetwork(event);
});
self.addEventListener('message', (event) => {
if (event.data === 'cache-all') {
event.waitUntil(cacheAdditionalProcessors(versionedCache, BUILD_ASSETS));
}
});