-
Notifications
You must be signed in to change notification settings - Fork 3
/
service-worker-helper.js
92 lines (79 loc) · 3.17 KB
/
service-worker-helper.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
/**
* This namespace contains helpers for building a service worker. This namespace only exports *initializeQServiceWorker*.
*
* See [Setting up Push Notifications](https://developers.quintype.com/malibu/tutorial/setting-up-push-notifications) for an example of setting up push notifications.
*
* ```javascript
* import { initializeQServiceWorker } from "@quintype/framework/client/service-worker-helper";
* ```
*
* @category Service Worker
* @module service-worker-helper
* @returns {void}
*/
// istanbul ignore file: Needs to be run as a service worker
import { matchBestRoute } from "../isomorphic/match-best-route";
const workboxVersion = "6.2.0";
function qDebug() {
if (process.env.NODE_ENV !== "production") {
console.debug.apply(console, arguments);
}
}
const getAssetsWithRevision = (assets) =>
assets.map((asset) =>
typeof asset === "string"
? {
url: asset,
revision: null,
}
: asset
);
/**
* Start the Service Worker.
* @param {ServiceWorkerScope} self
* @param {Object} params
* @param {function} params.excludeNavigation A function to exclude the PWA from serving the shell on that route, even if the route matches as per *routes*.
* @param {Array<Route>} params.routes An array of routes for the PWA to match
* @param {Array<string>} params.assets A list of assets to be cached before the ServiceWorker is installed
* @param {string|undefined} params.mountAt Mount point for the routes to be mounted
* @param {string} params.shell Path for the shell. Default '/shell.html'
*/
export function initializeQServiceWorker(params = {}) {
importScripts(`https://storage.googleapis.com/workbox-cdn/releases/${workboxVersion}/workbox-sw.js`);
const routeMatcher = function routeMatcher({ event, url }) {
if (event.request.mode !== "navigate") {
return false;
}
// Can this somehow be changed to using a combination of qtLoadedFromShell and some other stuff?
// Other random libraries may change this fragment
if (url.searchParams.has("bypass-sw") || url.hash === "#bypass-sw") {
qDebug(`Bypassing the shell due to bypass-sw being present`);
return false;
}
if (params.excludeNavigation && params.excludeNavigation(url)) {
return false;
}
let { pathname } = url;
if (params.mountAt && !pathname.startsWith(params.mountAt)) {
return false;
}
// Remove the mountAt before matching any routes
if (params.mountAt && pathname.startsWith(params.mountAt)) {
pathname = pathname.slice(params.mountAt.length);
}
if (matchBestRoute(pathname, params.routes)) {
qDebug(`Rendering the shell for navigation to ${pathname}`);
return true;
}
qDebug(`Not rendering the shell for navigation to ${pathname}`);
return false;
};
const shell = params.shell || "/shell.html";
const shellHandler = ({ event }) => caches.match(shell).then((r) => r || fetch(event.request));
const assetsToPrecache = getAssetsWithRevision(params.assets);
self.skipWaiting();
workbox.core.clientsClaim();
workbox.precaching.cleanupOutdatedCaches();
workbox.precaching.precache(assetsToPrecache);
workbox.routing.registerRoute(routeMatcher, shellHandler);
}