Skip to content

Commit b742f47

Browse files
committed
Enhance service worker precaching progress reporting
1 parent 6c87219 commit b742f47

1 file changed

Lines changed: 58 additions & 19 deletions

File tree

  • packages/extension-pwa/src

packages/extension-pwa/src/sw.ts

Lines changed: 58 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ type SwUpdateProgressMessage = {
2121
const PRECACHE_MANIFEST = self.__WB_MANIFEST;
2222
const PRECACHE_TOTAL = PRECACHE_MANIFEST.length;
2323
let updateProgressStarted = false;
24-
const updateProgressSeen = new Set<string>();
25-
const updateProgressFetched = new Set<string>();
24+
/** URLs finished during this waiting-SW install (cache hit or network fetch). */
25+
const precacheInstallDoneUrls = new Set<string>();
2626

2727
async function broadcastUpdateProgress(
2828
completed: number,
@@ -38,6 +38,38 @@ async function broadcastUpdateProgress(
3838
clients.forEach((client) => client.postMessage(message));
3939
}
4040

41+
function pathnameForProgress(url: string): string {
42+
try {
43+
return new URL(url).pathname;
44+
} catch {
45+
return url;
46+
}
47+
}
48+
49+
function shouldReportPrecacheInstallProgress(event: ExtendableEvent | undefined): boolean {
50+
return Boolean(event?.type === 'install' && self.registration.active && PRECACHE_TOTAL > 0);
51+
}
52+
53+
function ensureUpdateProgressStarted(): void {
54+
if (updateProgressStarted || !self.registration.active || PRECACHE_TOTAL <= 0) {
55+
return;
56+
}
57+
updateProgressStarted = true;
58+
void broadcastUpdateProgress(0, PRECACHE_TOTAL);
59+
}
60+
61+
function markPrecacheUrlDone(requestUrl: string): void {
62+
if (precacheInstallDoneUrls.has(requestUrl)) {
63+
return;
64+
}
65+
precacheInstallDoneUrls.add(requestUrl);
66+
void broadcastUpdateProgress(
67+
precacheInstallDoneUrls.size,
68+
PRECACHE_TOTAL,
69+
pathnameForProgress(requestUrl),
70+
);
71+
}
72+
4173
function withCoopCoep(response: Response): Response {
4274
if (response.status === 0 || response.type === 'opaque' || response.type === 'opaqueredirect') {
4375
return response;
@@ -56,25 +88,32 @@ cleanupOutdatedCaches();
5688

5789
addPlugins([
5890
{
59-
cachedResponseWillBeUsed: async ({ cachedResponse }) =>
60-
cachedResponse ? withCoopCoep(cachedResponse) : cachedResponse,
61-
requestWillFetch: async ({ request }) => {
62-
if (!updateProgressStarted && self.registration.active && PRECACHE_TOTAL > 0) {
63-
updateProgressStarted = true;
64-
void broadcastUpdateProgress(0, PRECACHE_TOTAL);
91+
handlerWillStart: async ({ event, request }) => {
92+
if (!shouldReportPrecacheInstallProgress(event)) {
93+
return;
94+
}
95+
ensureUpdateProgressStarted();
96+
void broadcastUpdateProgress(
97+
precacheInstallDoneUrls.size,
98+
PRECACHE_TOTAL,
99+
pathnameForProgress(request.url),
100+
);
101+
},
102+
cachedResponseWillBeUsed: async ({ cachedResponse, request, event }) => {
103+
if (cachedResponse) {
104+
const response = withCoopCoep(cachedResponse);
105+
if (shouldReportPrecacheInstallProgress(event)) {
106+
ensureUpdateProgressStarted();
107+
markPrecacheUrlDone(request.url);
108+
}
109+
return response;
65110
}
66-
updateProgressSeen.add(request.url);
67-
return request;
111+
return cachedResponse;
68112
},
69-
fetchDidSucceed: async ({ request, response }) => {
70-
if (
71-
updateProgressStarted &&
72-
updateProgressSeen.has(request.url) &&
73-
!updateProgressFetched.has(request.url)
74-
) {
75-
updateProgressFetched.add(request.url);
76-
const currentFile = new URL(request.url).pathname;
77-
void broadcastUpdateProgress(updateProgressFetched.size, PRECACHE_TOTAL, currentFile);
113+
fetchDidSucceed: async ({ request, response, event }) => {
114+
if (shouldReportPrecacheInstallProgress(event)) {
115+
ensureUpdateProgressStarted();
116+
markPrecacheUrlDone(request.url);
78117
}
79118
return withCoopCoep(response);
80119
},

0 commit comments

Comments
 (0)