Files
spiceflow/client/src/sw.ts
2026-01-20 14:04:19 -05:00

93 lines
2.3 KiB
TypeScript

/// <reference lib="webworker" />
import { cleanupOutdatedCaches, precacheAndRoute } from 'workbox-precaching';
declare let self: ServiceWorkerGlobalScope;
// Clean up old caches
cleanupOutdatedCaches();
// Precache all assets generated by the build
precacheAndRoute(self.__WB_MANIFEST);
// Push notification payload type
interface PushPayload {
title: string;
body: string;
sessionId: string;
sessionTitle: string;
tools: string[];
}
// Handle push events
self.addEventListener('push', (event) => {
if (!event.data) {
console.log('[SW] Push event with no data');
return;
}
try {
const payload: PushPayload = event.data.json();
console.log('[SW] Push received:', payload);
const options = {
body: payload.body,
icon: '/pwa-192x192.png',
badge: '/pwa-192x192.png',
tag: `permission-${payload.sessionId}`,
renotify: true,
requireInteraction: true,
data: {
sessionId: payload.sessionId,
url: `/session/${payload.sessionId}`
},
actions: [
{
action: 'open',
title: 'Open Session'
}
]
} satisfies NotificationOptions & { renotify?: boolean; requireInteraction?: boolean; actions?: { action: string; title: string }[] };
event.waitUntil(self.registration.showNotification(payload.title, options));
} catch (err) {
console.error('[SW] Error processing push:', err);
}
});
// Handle notification click
self.addEventListener('notificationclick', (event) => {
console.log('[SW] Notification clicked:', event.action);
event.notification.close();
const url = event.notification.data?.url || '/';
// Focus existing window or open new one
event.waitUntil(
self.clients.matchAll({ type: 'window', includeUncontrolled: true }).then((clientList) => {
// Try to find an existing window with the app
for (const client of clientList) {
if (client.url.includes(self.location.origin) && 'focus' in client) {
client.focus();
// Navigate to the session
client.postMessage({
type: 'NAVIGATE',
url: url
});
return;
}
}
// No existing window, open a new one
if (self.clients.openWindow) {
return self.clients.openWindow(url);
}
})
);
});
// Handle messages from the main app
self.addEventListener('message', (event) => {
if (event.data?.type === 'SKIP_WAITING') {
self.skipWaiting();
}
});