2026-04-17 15:41:20 +02:00
|
|
|
/// <reference types="@sveltejs/kit" />
|
|
|
|
|
/// <reference no-default-lib="true"/>
|
|
|
|
|
/// <reference lib="esnext" />
|
|
|
|
|
/// <reference lib="webworker" />
|
|
|
|
|
import { build, files, version } from '$service-worker';
|
2026-04-18 16:38:09 +02:00
|
|
|
import { resolveStrategy } from '$lib/sw/cache-strategy';
|
|
|
|
|
|
|
|
|
|
declare const self: ServiceWorkerGlobalScope;
|
2026-04-17 15:41:20 +02:00
|
|
|
|
2026-04-18 16:38:09 +02:00
|
|
|
const SHELL_CACHE = `kochwas-shell-${version}`;
|
|
|
|
|
const DATA_CACHE = 'kochwas-data-v1';
|
|
|
|
|
const IMAGES_CACHE = 'kochwas-images-v1';
|
2026-04-17 15:41:20 +02:00
|
|
|
|
2026-04-18 16:38:09 +02:00
|
|
|
// App-Shell-Assets (Build-Output + statische Dateien, die SvelteKit kennt)
|
|
|
|
|
const SHELL_ASSETS = [...build, ...files];
|
2026-04-17 15:41:20 +02:00
|
|
|
|
2026-04-18 16:38:09 +02:00
|
|
|
self.addEventListener('install', (event) => {
|
2026-04-17 15:41:20 +02:00
|
|
|
event.waitUntil(
|
2026-04-18 16:38:09 +02:00
|
|
|
(async () => {
|
|
|
|
|
const cache = await caches.open(SHELL_CACHE);
|
|
|
|
|
await cache.addAll(SHELL_ASSETS);
|
|
|
|
|
await self.skipWaiting();
|
|
|
|
|
})()
|
2026-04-17 15:41:20 +02:00
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
2026-04-18 16:38:09 +02:00
|
|
|
self.addEventListener('activate', (event) => {
|
2026-04-17 15:41:20 +02:00
|
|
|
event.waitUntil(
|
|
|
|
|
(async () => {
|
2026-04-18 16:38:09 +02:00
|
|
|
// Alte Shell-Caches (vorherige Versionen) räumen
|
2026-04-17 15:41:20 +02:00
|
|
|
const keys = await caches.keys();
|
|
|
|
|
await Promise.all(
|
|
|
|
|
keys
|
2026-04-18 16:38:09 +02:00
|
|
|
.filter((k) => k.startsWith('kochwas-shell-') && k !== SHELL_CACHE)
|
2026-04-17 15:41:20 +02:00
|
|
|
.map((k) => caches.delete(k))
|
|
|
|
|
);
|
2026-04-18 16:38:09 +02:00
|
|
|
await self.clients.claim();
|
2026-04-17 15:41:20 +02:00
|
|
|
})()
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
2026-04-18 16:38:09 +02:00
|
|
|
self.addEventListener('fetch', (event) => {
|
2026-04-17 15:41:20 +02:00
|
|
|
const req = event.request;
|
2026-04-18 16:38:09 +02:00
|
|
|
if (new URL(req.url).origin !== self.location.origin) return; // Cross-Origin unangetastet
|
2026-04-17 15:41:20 +02:00
|
|
|
|
2026-04-18 16:38:09 +02:00
|
|
|
const strategy = resolveStrategy({ url: req.url, method: req.method });
|
|
|
|
|
if (strategy === 'network-only') return;
|
2026-04-17 15:41:20 +02:00
|
|
|
|
2026-04-18 16:38:09 +02:00
|
|
|
if (strategy === 'shell') {
|
|
|
|
|
event.respondWith(cacheFirst(req, SHELL_CACHE));
|
|
|
|
|
} else if (strategy === 'images') {
|
|
|
|
|
event.respondWith(cacheFirst(req, IMAGES_CACHE));
|
|
|
|
|
} else if (strategy === 'swr') {
|
|
|
|
|
event.respondWith(staleWhileRevalidate(req, DATA_CACHE));
|
2026-04-17 15:41:20 +02:00
|
|
|
}
|
2026-04-18 16:38:09 +02:00
|
|
|
});
|
2026-04-17 15:41:20 +02:00
|
|
|
|
2026-04-18 16:38:09 +02:00
|
|
|
async function cacheFirst(req: Request, cacheName: string): Promise<Response> {
|
|
|
|
|
const cache = await caches.open(cacheName);
|
|
|
|
|
const hit = await cache.match(req);
|
|
|
|
|
if (hit) return hit;
|
|
|
|
|
const fresh = await fetch(req);
|
|
|
|
|
if (fresh.ok) cache.put(req, fresh.clone()).catch(() => {});
|
|
|
|
|
return fresh;
|
|
|
|
|
}
|
2026-04-17 15:41:20 +02:00
|
|
|
|
2026-04-18 16:38:09 +02:00
|
|
|
async function staleWhileRevalidate(req: Request, cacheName: string): Promise<Response> {
|
|
|
|
|
const cache = await caches.open(cacheName);
|
|
|
|
|
const hit = await cache.match(req);
|
|
|
|
|
const fetchPromise = fetch(req)
|
|
|
|
|
.then((res) => {
|
|
|
|
|
if (res.ok) cache.put(req, res.clone()).catch(() => {});
|
|
|
|
|
return res;
|
|
|
|
|
})
|
|
|
|
|
.catch(() => hit ?? Response.error());
|
|
|
|
|
return hit ?? fetchPromise;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export {};
|