69 lines
2.1 KiB
JavaScript
69 lines
2.1 KiB
JavaScript
/* eslint-env serviceworker */
|
|
/**
|
|
* Service worker for the web build.
|
|
*
|
|
* Its only job is the Web Share Target: the manifest's share_target POSTs a
|
|
* photo to /share-target, which no static server can accept. This worker
|
|
* stashes the photo in Cache Storage and redirects to /shared-photo, where
|
|
* src/libs/webShareTarget.ts picks it up. Every other request goes straight to
|
|
* the network (no fetch handler response, no precaching).
|
|
*
|
|
* It also replaces the Workbox worker that older builds registered at this
|
|
* same URL, and deletes that worker's precaches, which otherwise keep serving
|
|
* a stale index.html that points at JavaScript files no longer deployed.
|
|
*/
|
|
|
|
const SHARE_TARGET_CACHE = "share-target";
|
|
// Keep in sync with src/libs/webShareTarget.ts
|
|
const SHARED_PHOTO_KEY = "/share-target/photo";
|
|
const FILE_NAME_HEADER = "X-File-Name";
|
|
|
|
self.addEventListener("install", () => {
|
|
self.skipWaiting();
|
|
});
|
|
|
|
self.addEventListener("activate", (event) => {
|
|
event.waitUntil(
|
|
(async () => {
|
|
const names = await caches.keys();
|
|
await Promise.all(
|
|
names
|
|
.filter((name) => name !== SHARE_TARGET_CACHE)
|
|
.map((name) => caches.delete(name)),
|
|
);
|
|
await self.clients.claim();
|
|
})(),
|
|
);
|
|
});
|
|
|
|
self.addEventListener("fetch", (event) => {
|
|
const url = new URL(event.request.url);
|
|
if (
|
|
event.request.method !== "POST" ||
|
|
url.origin !== self.location.origin ||
|
|
url.pathname !== "/share-target"
|
|
) {
|
|
return;
|
|
}
|
|
|
|
event.respondWith(
|
|
(async () => {
|
|
const formData = await event.request.formData();
|
|
const photo = formData.get("photo");
|
|
if (photo instanceof File) {
|
|
const cache = await caches.open(SHARE_TARGET_CACHE);
|
|
await cache.put(
|
|
SHARED_PHOTO_KEY,
|
|
new Response(photo, {
|
|
headers: {
|
|
"Content-Type": photo.type || "application/octet-stream",
|
|
[FILE_NAME_HEADER]: encodeURIComponent(photo.name || ""),
|
|
},
|
|
}),
|
|
);
|
|
}
|
|
return Response.redirect("/shared-photo?source=share-target", 303);
|
|
})(),
|
|
);
|
|
});
|