import Deferred from '../util/Deferred'; declare const self: ServiceWorkerGlobalScope; type ShareData = { title?: string; text?: string; url?: string; files?: File[]; }; const READY_CLIENT_DEFERREDS = new Map>(); export async function respondForShare(e: FetchEvent) { if (e.request.method === 'POST') { try { const formData = await e.request.formData(); const data = parseFormData(formData); requestShare(data, e.resultingClientId); } catch (err) { // eslint-disable-next-line no-console console.warn('[SHARE] Failed to parse input data', err); } } return Response.redirect('.'); } export function handleClientMessage(e: ExtendableMessageEvent) { const { source, data } = e; if (!source) return; if (data.type === 'clientReady') { const { id } = source as Client; const deferred = READY_CLIENT_DEFERREDS.get(id); if (deferred) { deferred.resolve(); } else { READY_CLIENT_DEFERREDS.set(id, Deferred.resolved()); } } } async function requestShare(data: ShareData, clientId: string) { const client = await self.clients.get(clientId); if (!client) { return; } await getClientReadyDeferred(clientId); client.postMessage({ type: 'share', payload: data, }); } function getClientReadyDeferred(clientId: string) { const deferred = READY_CLIENT_DEFERREDS.get(clientId); if (deferred) { return deferred.promise; } const newDeferred = new Deferred(); READY_CLIENT_DEFERREDS.set(clientId, newDeferred); return newDeferred.promise; } function parseFormData(formData: FormData): ShareData { const files = formData.getAll('files') as File[]; const title = formData.get('title') as string; const text = formData.get('text') as string; const url = formData.get('url') as string; return { title, text, url, files, }; }