Files
flit/pwa/public/sw.js
Fredrik Johansson 5050ad5e79 Scaffold flit: PWA + Go CLI for ephemeral E2E file transfer
Ports the yaw/2.1 identity/signaling/WebRTC transport from waste-go to
both a browser PWA (with QR pairing and Web Share Target) and a headless
Go CLI, trimmed to 1:1 ephemeral file transfer only.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 19:23:04 +02:00

45 lines
1.6 KiB
JavaScript

// Minimal service worker: only exists to catch the POST /share-target
// request from Android's share sheet (required for Web Share Target to
// work — the browser needs an installed SW controlling the scope). Stores
// the shared files in a temporary Cache entry, then redirects to a page
// that reads them and feeds them into the send flow.
const SHARE_CACHE = 'flit-share-v1'
self.addEventListener('install', (event) => {
self.skipWaiting()
})
self.addEventListener('activate', (event) => {
event.waitUntil(self.clients.claim())
})
self.addEventListener('fetch', (event) => {
const url = new URL(event.request.url)
if (event.request.method === 'POST' && url.pathname === '/share-target') {
event.respondWith(handleShareTarget(event))
}
})
async function handleShareTarget(event) {
const formData = await event.request.formData()
const files = formData.getAll('files')
const cache = await caches.open(SHARE_CACHE)
await cache.put('/shared-files', new Response(await packFiles(files)))
return Response.redirect('/?shared=1', 303)
}
async function packFiles(files) {
// Pack as a multipart-ish JSON manifest + blobs isn't trivial inside a SW;
// simplest robust approach: store each file as its own cache entry keyed
// by index, plus a manifest of names/types.
const cache = await caches.open(SHARE_CACHE)
const manifest = []
for (let i = 0; i < files.length; i++) {
const f = files[i]
manifest.push({ name: f.name, type: f.type, size: f.size, key: `/shared-file-${i}` })
await cache.put(`/shared-file-${i}`, new Response(f))
}
return JSON.stringify(manifest)
}