forked from sugarlabs/musicblocks
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsw.js
More file actions
202 lines (172 loc) · 6.74 KB
/
sw.js
File metadata and controls
202 lines (172 loc) · 6.74 KB
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
/*
global
offlineFallbackPage
*/
// This is the "Offline page" service worker
const CACHE = "pwabuilder-precache";
const precacheFiles = [
/* Add an array of files to precache for your app */
"./index.html"
];
self.addEventListener("install", function (event) {
// eslint-disable-next-line no-console
console.log("[PWA Builder] Install Event processing");
// eslint-disable-next-line no-console
console.log("[PWA Builder] Skip waiting on install");
self.skipWaiting();
event.waitUntil(
caches.open(CACHE).then(function (cache) {
// eslint-disable-next-line no-console
console.log("[PWA Builder] Caching pages during install");
return cache.addAll(precacheFiles);
})
);
});
// Allow sw to control of current page
self.addEventListener("activate", function (event) {
// eslint-disable-next-line no-console
console.log("[PWA Builder] Claiming clients for current page");
event.waitUntil(self.clients.claim());
});
/*
function isPrecachedRequest(request) {
try {
const url = new URL(request.url);
const precached = new Set(precacheFiles.map(path => new URL(path, self.location).href));
return precached.has(url.href);
} catch {
return false;
}
}
function isStaticAssetRequest(request) {
// Only allow safe, same-origin, static subresources.
if (request.method !== "GET") return false;
const url = new URL(request.url);
if (url.origin !== self.location.origin) return false;
// Never runtime-cache URLs with query params (precache exact URLs instead).
if (url.search) return false;
// Avoid caching programmatic fetch() calls (often API/data requests).
if (!request.destination) return false;
// Avoid caching requests that explicitly include credentials.
if (request.credentials === "include") return false;
// Avoid range requests.
if (request.headers.has("range")) return false;
switch (request.destination) {
case "style":
case "script":
case "image":
case "font":
case "manifest":
return true;
default:
return false;
}
}
function isAppShellNavigation(request) {
if (request.method !== "GET") return false;
if (request.mode !== "navigate") return false;
const url = new URL(request.url);
if (url.origin !== self.location.origin) return false;
// Only treat the root and index.html as app-shell.
// Do not cache arbitrary documents.
if (url.search) return false;
return url.pathname === "/" || url.pathname.toLowerCase().endsWith("/index.html");
}
function shouldCacheResponse(request, response) {
if (!response) return false;
if (!response.ok) return false;
if (response.status === 206) return false;
// Only cache same-origin "basic" responses to avoid opaque caching.
if (response.type !== "basic") return false;
const cacheControl = (response.headers.get("Cache-Control") || "").toLowerCase();
if (cacheControl.includes("no-store") || cacheControl.includes("private")) return false;
// Only cache responses for allowlisted requests (static assets + explicit precache URLs).
return isStaticAssetRequest(request) || isPrecachedRequest(request);
}
*/
function updateCache(request, response) {
if (response.status === 206) {
console.log("Partial response is unsupported for caching.");
return Promise.resolve();
}
return caches.open(CACHE).then(function (cache) {
return cache.put(request, response);
});
}
function fromCache(request) {
// Check to see if you have it in the cache
// Return response
// If not in the cache, then return
return caches.open(CACHE).then(function (cache) {
return cache.match(request).then(function (matching) {
if (!matching || matching.status === 404) {
return Promise.reject("no-match");
}
return matching;
});
});
}
// If any fetch fails, it will look for the request in the cache and
// serve it from there first
self.addEventListener("fetch", function (event) {
if (event.request.method !== "GET") return;
event.respondWith(
fromCache(event.request).then(
function (response) {
// The response was found in the cache so we responde
// with it and update the entry
// This is where we call the server to get the newest
// version of the file to use the next time we show view
event.waitUntil(
fetch(event.request).then(function (response) {
if (response.ok) {
return updateCache(event.request, response);
}
})
);
return response;
},
async function () {
// The response was not found in the cache so we look
// for it on the server
try {
const response = await fetch(event.request);
if (response.ok) {
event.waitUntil(updateCache(event.request, response.clone()));
}
return response;
} catch (error) {
// eslint-disable-next-line no-console
console.log("[PWA Builder] Network request failed and no cache." + error);
if (typeof offlineFallbackPage !== "undefined") {
const fallbackResponse = await caches.match(offlineFallbackPage);
if (fallbackResponse) return fallbackResponse;
}
return new Response("Service Unavailable", {
status: 503,
statusText: "offline"
});
}
}
)
);
});
// This is an event that can be fired from your page to tell the SW to
// update the offline page
self.addEventListener("refreshOffline", function () {
if (typeof offlineFallbackPage !== "string" || offlineFallbackPage.trim().length === 0) {
// eslint-disable-next-line no-console
console.log("[PWA Builder] refreshOffline ignored: offlineFallbackPage is not set");
return Promise.resolve();
}
const offlinePageRequest = new Request(offlineFallbackPage);
return fetch(offlineFallbackPage).then(function (response) {
return caches.open(CACHE).then(function (cache) {
// eslint-disable-next-line no-console
console.log(
"[PWA Builder] Offline page updated from refreshOffline event: " + response.url
);
return cache.put(offlinePageRequest, response);
});
});
});