///
import { clientsClaim } from 'workbox-core';
import { CacheableResponsePlugin } from 'workbox-cacheable-response';
import { ExpirationPlugin } from 'workbox-expiration';
import { precacheAndRoute, cleanupOutdatedCaches } from 'workbox-precaching';
import { registerRoute } from 'workbox-routing';
import { CacheFirst, NetworkFirst, StaleWhileRevalidate } from 'workbox-strategies';
import { shouldCacheResponse } from './lib/cachePolicy';
declare const self: ServiceWorkerGlobalScope & {
__WB_MANIFEST: Array;
};
clientsClaim();
precacheAndRoute(self.__WB_MANIFEST);
cleanupOutdatedCaches();
const isGuestNavigation = (pathname: string) => {
if (pathname === '/event') {
return true;
}
if (pathname.startsWith('/e/')) {
return true;
}
if (pathname.startsWith('/g/')) {
return true;
}
if (pathname.startsWith('/share/')) {
return true;
}
if (pathname.startsWith('/help')) {
return true;
}
if (pathname.startsWith('/legal')) {
return true;
}
if (pathname.startsWith('/settings')) {
return true;
}
return false;
};
registerRoute(
({ request, url }) =>
request.mode === 'navigate' && url.origin === self.location.origin && isGuestNavigation(url.pathname),
new NetworkFirst({
cacheName: 'guest-pages',
networkTimeoutSeconds: 5,
plugins: [
new CacheableResponsePlugin({ statuses: [0, 200] }),
new ExpirationPlugin({ maxEntries: 40, maxAgeSeconds: 60 * 60 * 24 * 7 }),
],
})
);
registerRoute(
({ request, url }) =>
request.method === 'GET' &&
url.origin === self.location.origin &&
url.pathname.startsWith('/api/v1/'),
new NetworkFirst({
cacheName: 'guest-api',
networkTimeoutSeconds: 6,
plugins: [
{
cacheWillUpdate: async ({ response }) => (shouldCacheResponse(response) ? response : null),
},
new CacheableResponsePlugin({ statuses: [0, 200] }),
new ExpirationPlugin({ maxEntries: 80, maxAgeSeconds: 60 * 60 * 24 }),
],
})
);
registerRoute(
({ request, url }) => request.destination === 'image' && url.origin === self.location.origin,
new CacheFirst({
cacheName: 'guest-images',
plugins: [
new CacheableResponsePlugin({ statuses: [0, 200] }),
new ExpirationPlugin({ maxEntries: 200, maxAgeSeconds: 60 * 60 * 24 * 30 }),
],
})
);
registerRoute(
({ request, url }) => request.destination === 'font' && url.origin === self.location.origin,
new StaleWhileRevalidate({
cacheName: 'guest-fonts',
plugins: [
new CacheableResponsePlugin({ statuses: [0, 200] }),
new ExpirationPlugin({ maxEntries: 30, maxAgeSeconds: 60 * 60 * 24 * 365 }),
],
})
);
self.addEventListener('message', (event) => {
if (event.data?.type === 'SKIP_WAITING') {
self.skipWaiting();
}
});
self.addEventListener('sync', (event: any) => {
if (event.tag === 'upload-queue') {
event.waitUntil(
(async () => {
const clients = await self.clients.matchAll({ includeUncontrolled: true, type: 'window' });
clients.forEach((client) => client.postMessage({ type: 'sync-queue' }));
})()
);
}
});
self.addEventListener('push', (event) => {
const payload = event.data?.json?.() ?? {};
event.waitUntil(
(async () => {
const title = payload.title ?? 'Neue Nachricht';
const options = {
body: payload.body ?? '',
icon: '/apple-touch-icon.png',
badge: '/apple-touch-icon.png',
data: payload.data ?? {},
};
await self.registration.showNotification(title, options);
const clients = await self.clients.matchAll({ type: 'window', includeUncontrolled: true });
clients.forEach((client) => client.postMessage({ type: 'guest-notification-refresh' }));
})()
);
});
self.addEventListener('notificationclick', (event) => {
event.notification.close();
const targetUrl = event.notification.data?.url || '/';
event.waitUntil(
self.clients.matchAll({ type: 'window', includeUncontrolled: true }).then((clientList) => {
for (const client of clientList) {
if ('focus' in client) {
client.navigate(targetUrl);
return client.focus();
}
}
if (self.clients.openWindow) {
return self.clients.openWindow(targetUrl);
}
})
);
});
self.addEventListener('pushsubscriptionchange', (event) => {
event.waitUntil(
self.clients.matchAll({ type: 'window', includeUncontrolled: true }).then((clientList) => {
clientList.forEach((client) => client.postMessage({ type: 'push-subscription-change' }));
})
);
});