@rmdes/indiekit-frontend 1.0.0-beta.34 → 1.0.0-beta.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/serviceworker.js +36 -34
- package/package.json +1 -1
package/lib/serviceworker.js
CHANGED
|
@@ -76,24 +76,14 @@ async function clearOldCaches() {
|
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
/**
|
|
80
|
-
* Clear the pages cache so stale HTML (with old asset references) is not served
|
|
81
|
-
*/
|
|
82
|
-
async function clearPagesCache() {
|
|
83
|
-
try {
|
|
84
|
-
await caches.delete(pagesCacheName);
|
|
85
|
-
} catch (error) {
|
|
86
|
-
console.error("Error clearing pages cache", error);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
79
|
/**
|
|
91
80
|
* Notify all clients that the service worker has been updated
|
|
92
81
|
*/
|
|
93
82
|
async function notifyClients() {
|
|
83
|
+
const version = assetCacheName.replace("assets-", "");
|
|
94
84
|
const allClients = await clients.matchAll({ includeUncontrolled: true });
|
|
95
85
|
for (const client of allClients) {
|
|
96
|
-
client.postMessage({ command: "SW_UPDATED", version
|
|
86
|
+
client.postMessage({ command: "SW_UPDATED", version });
|
|
97
87
|
}
|
|
98
88
|
}
|
|
99
89
|
|
|
@@ -130,7 +120,10 @@ self.addEventListener("activate", async (event) => {
|
|
|
130
120
|
event.waitUntil(
|
|
131
121
|
(async () => {
|
|
132
122
|
await clearOldCaches();
|
|
133
|
-
|
|
123
|
+
// Don't clear pages cache on activate — stale cached pages provide a
|
|
124
|
+
// valuable fallback when the network is slow (e.g. right after a deploy).
|
|
125
|
+
// The network-first fetch strategy naturally updates cached pages on
|
|
126
|
+
// every successful navigation, so stale entries are short-lived.
|
|
134
127
|
await clients.claim();
|
|
135
128
|
await notifyClients();
|
|
136
129
|
})(),
|
|
@@ -158,44 +151,53 @@ self.addEventListener("fetch", (event) => {
|
|
|
158
151
|
return;
|
|
159
152
|
}
|
|
160
153
|
|
|
161
|
-
// For HTML requests
|
|
154
|
+
// For HTML requests: network-first with conditional timeout
|
|
155
|
+
// - If a cached version exists: race network against timeout, serve cache on timeout
|
|
156
|
+
// - If no cached version: wait for network without timeout (avoid premature "Offline")
|
|
162
157
|
if (
|
|
163
158
|
request.mode === "navigate" ||
|
|
164
|
-
request.headers.get("Accept").includes("text/html")
|
|
159
|
+
(request.headers.get("Accept") || "").includes("text/html")
|
|
165
160
|
) {
|
|
166
161
|
event.respondWith(
|
|
167
162
|
(async () => {
|
|
163
|
+
// Check cache and start network fetch in parallel
|
|
164
|
+
const cachedResponse = await caches.match(request);
|
|
165
|
+
const networkFetch = (async () => {
|
|
166
|
+
const preloadResponse = await Promise.resolve(event.preloadResponse);
|
|
167
|
+
return preloadResponse || (await fetch(request));
|
|
168
|
+
})();
|
|
169
|
+
|
|
168
170
|
try {
|
|
169
|
-
//
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
171
|
+
// Only apply timeout when we have a cached fallback.
|
|
172
|
+
// Without a cache, it's better to wait for the network (loading spinner)
|
|
173
|
+
// than to show "Offline" after 5 seconds on a slow backend.
|
|
174
|
+
const responseFromNetwork = cachedResponse
|
|
175
|
+
? await Promise.race([
|
|
176
|
+
networkFetch,
|
|
177
|
+
new Promise((_, reject) =>
|
|
178
|
+
setTimeout(
|
|
179
|
+
() => reject(new Error("Network timeout")),
|
|
180
|
+
timeout,
|
|
181
|
+
),
|
|
182
|
+
),
|
|
183
|
+
])
|
|
184
|
+
: await networkFetch;
|
|
181
185
|
|
|
182
186
|
// NETWORK succeeded — cache and serve
|
|
183
187
|
try {
|
|
184
|
-
const copy =
|
|
188
|
+
const copy = responseFromNetwork.clone();
|
|
185
189
|
const pagesCache = await caches.open(pagesCacheName);
|
|
186
190
|
await pagesCache.put(request, copy);
|
|
187
191
|
} catch (cacheError) {
|
|
188
192
|
console.error("Failed to cache page:", cacheError);
|
|
189
193
|
}
|
|
190
194
|
|
|
191
|
-
return
|
|
195
|
+
return responseFromNetwork;
|
|
192
196
|
} catch {
|
|
193
|
-
// NETWORK failed or timed out — fall back to cache
|
|
194
|
-
const responseFromCache = await caches.match(request);
|
|
195
|
-
const offlineResponse = await caches.match("/offline");
|
|
197
|
+
// NETWORK failed or timed out — fall back to cache or offline
|
|
196
198
|
return (
|
|
197
|
-
|
|
198
|
-
|
|
199
|
+
cachedResponse ||
|
|
200
|
+
(await caches.match("/offline")) ||
|
|
199
201
|
new Response("Offline", {
|
|
200
202
|
status: 503,
|
|
201
203
|
statusText: "Service Unavailable",
|