atagen

malice

public
Star0
Watch0
81d6bf15e59bfcfc57f792500008a796939cdbd5
2
ssh://brewery@pls.lobotomise.me:33/atagen/malice.git

Blame: web/src/sw.ts

d8772d4eb408atagen2026-10-26 04:43 UTC1
import { AVATAR_CACHE, handleMediaFetch } from './sw-media';
235ce394f90datagen2026-10-26 06:54 UTC2
import { onPush, onSubscriptionChange } from './sw-push';
235ce394f90datagen2026-10-26 06:54 UTC3
import { roomFromTag, roomTarget } from './lib/push-model';
d8772d4eb408atagen2026-10-26 04:43 UTC4
d8772d4eb408atagen2026-10-26 04:43 UTC5
declare const __MALICE_DEVICE__: boolean;
973f8fbdaf80atagen2026-09-28 09:10 UTC6
973f8fbdaf80atagen2026-09-28 09:10 UTC7
// Prepended by vite.config.ts's precacheManifestPlugin: every emitted chunk,
973f8fbdaf80atagen2026-09-28 09:10 UTC8
// asset, and the wasm, as root-relative URLs.
973f8fbdaf80atagen2026-09-28 09:10 UTC9
const sw = self as unknown as ServiceWorkerGlobalScope & { __MALICE_PRECACHE__: string[] };
973f8fbdaf80atagen2026-09-28 09:10 UTC10
973f8fbdaf80atagen2026-09-28 09:10 UTC11
const CACHE_NAME = 'malice-shell-v1';
973f8fbdaf80atagen2026-09-28 09:10 UTC12
973f8fbdaf80atagen2026-09-28 09:10 UTC13
sw.addEventListener('install', (event) => {
973f8fbdaf80atagen2026-09-28 09:10 UTC14
  event.waitUntil(
973f8fbdaf80atagen2026-09-28 09:10 UTC15
    (async () => {
973f8fbdaf80atagen2026-09-28 09:10 UTC16
      const cache = await caches.open(CACHE_NAME);
973f8fbdaf80atagen2026-09-28 09:10 UTC17
      await cache.addAll(['/', '/index.html', ...sw.__MALICE_PRECACHE__]);
973f8fbdaf80atagen2026-09-28 09:10 UTC18
    })()
973f8fbdaf80atagen2026-09-28 09:10 UTC19
  );
d8772d4eb408atagen2026-10-26 04:43 UTC20
});
d8772d4eb408atagen2026-10-26 04:43 UTC21
d8772d4eb408atagen2026-10-26 04:43 UTC22
sw.addEventListener('message', (event) => {
d8772d4eb408atagen2026-10-26 04:43 UTC23
  if (event.data?.type === 'SKIP_WAITING') void sw.skipWaiting();
973f8fbdaf80atagen2026-09-28 09:10 UTC24
});
973f8fbdaf80atagen2026-09-28 09:10 UTC25
973f8fbdaf80atagen2026-09-28 09:10 UTC26
sw.addEventListener('activate', (event) => {
973f8fbdaf80atagen2026-09-28 09:10 UTC27
  event.waitUntil(
973f8fbdaf80atagen2026-09-28 09:10 UTC28
    (async () => {
973f8fbdaf80atagen2026-09-28 09:10 UTC29
      const keys = await caches.keys();
cf23dbf4e77catagen2026-10-23 06:36 UTC30
      await Promise.all(keys.filter((key) => key !== CACHE_NAME && key !== AVATAR_CACHE).map((key) => caches.delete(key)));
919753ab134catagen2026-10-26 03:48 UTC31
      const shell = await caches.open(CACHE_NAME);
919753ab134catagen2026-10-26 03:48 UTC32
      const keep = new Set(['/', '/index.html', ...sw.__MALICE_PRECACHE__]);
919753ab134catagen2026-10-26 03:48 UTC33
      for (const request of await shell.keys()) {
919753ab134catagen2026-10-26 03:48 UTC34
        const path = new URL(request.url).pathname;
919753ab134catagen2026-10-26 03:48 UTC35
        if (path.startsWith('/assets/') && !keep.has(path)) await shell.delete(request);
919753ab134catagen2026-10-26 03:48 UTC36
      }
973f8fbdaf80atagen2026-09-28 09:10 UTC37
      await sw.clients.claim();
973f8fbdaf80atagen2026-09-28 09:10 UTC38
    })()
973f8fbdaf80atagen2026-09-28 09:10 UTC39
  );
973f8fbdaf80atagen2026-09-28 09:10 UTC40
});
973f8fbdaf80atagen2026-09-28 09:10 UTC41
973f8fbdaf80atagen2026-09-28 09:10 UTC42
async function cacheFirst(request: Request): Promise<Response> {
973f8fbdaf80atagen2026-09-28 09:10 UTC43
  const cached = await caches.match(request);
973f8fbdaf80atagen2026-09-28 09:10 UTC44
  if (cached) return cached;
973f8fbdaf80atagen2026-09-28 09:10 UTC45
  const response = await fetch(request);
973f8fbdaf80atagen2026-09-28 09:10 UTC46
  if (response.ok) {
973f8fbdaf80atagen2026-09-28 09:10 UTC47
    const cache = await caches.open(CACHE_NAME);
973f8fbdaf80atagen2026-09-28 09:10 UTC48
    void cache.put(request, response.clone());
973f8fbdaf80atagen2026-09-28 09:10 UTC49
  }
973f8fbdaf80atagen2026-09-28 09:10 UTC50
  return response;
973f8fbdaf80atagen2026-09-28 09:10 UTC51
}
973f8fbdaf80atagen2026-09-28 09:10 UTC52
973f8fbdaf80atagen2026-09-28 09:10 UTC53
async function networkFirstNavigation(request: Request): Promise<Response> {
973f8fbdaf80atagen2026-09-28 09:10 UTC54
  try {
973f8fbdaf80atagen2026-09-28 09:10 UTC55
    return await fetch(request);
973f8fbdaf80atagen2026-09-28 09:10 UTC56
  } catch {
973f8fbdaf80atagen2026-09-28 09:10 UTC57
    const cached = await caches.match('/index.html');
973f8fbdaf80atagen2026-09-28 09:10 UTC58
    if (cached) return cached;
973f8fbdaf80atagen2026-09-28 09:10 UTC59
    throw new Error('offline and no cached shell');
973f8fbdaf80atagen2026-09-28 09:10 UTC60
  }
973f8fbdaf80atagen2026-09-28 09:10 UTC61
}
973f8fbdaf80atagen2026-09-28 09:10 UTC62
973f8fbdaf80atagen2026-09-28 09:10 UTC63
sw.addEventListener('fetch', (event) => {
973f8fbdaf80atagen2026-09-28 09:10 UTC64
  const url = new URL(event.request.url);
973f8fbdaf80atagen2026-09-28 09:10 UTC65
d8772d4eb408atagen2026-10-26 04:43 UTC66
  if (__MALICE_DEVICE__ && handleMediaFetch(event)) return;
d8772d4eb408atagen2026-10-26 04:43 UTC67
  if (url.pathname.startsWith('/api/')) return;
544a170ead2catagen2026-10-20 11:47 UTC68
  if (url.pathname.startsWith('/assets/') || url.pathname.startsWith('/twemoji/')) {
973f8fbdaf80atagen2026-09-28 09:10 UTC69
    event.respondWith(cacheFirst(event.request));
973f8fbdaf80atagen2026-09-28 09:10 UTC70
    return;
973f8fbdaf80atagen2026-09-28 09:10 UTC71
  }
973f8fbdaf80atagen2026-09-28 09:10 UTC72
  if (event.request.mode === 'navigate') {
973f8fbdaf80atagen2026-09-28 09:10 UTC73
    event.respondWith(networkFirstNavigation(event.request));
973f8fbdaf80atagen2026-09-28 09:10 UTC74
  }
973f8fbdaf80atagen2026-09-28 09:10 UTC75
});
d8772d4eb408atagen2026-10-26 04:43 UTC76
235ce394f90datagen2026-10-26 06:54 UTC77
sw.addEventListener('push', (event) => onPush(sw, event));
235ce394f90datagen2026-10-26 06:54 UTC78
sw.addEventListener('pushsubscriptionchange', (event) => onSubscriptionChange(sw, event));
235ce394f90datagen2026-10-26 06:54 UTC79
d8772d4eb408atagen2026-10-26 04:43 UTC80
sw.addEventListener('notificationclick', (event) => {
d8772d4eb408atagen2026-10-26 04:43 UTC81
  event.notification.close();
235ce394f90datagen2026-10-26 06:54 UTC82
  const data = event.notification.data as { roomId?: unknown; navigate?: unknown } | null;
235ce394f90datagen2026-10-26 06:54 UTC83
  const roomId = typeof data?.roomId === 'string' ? data.roomId : roomFromTag(event.notification.tag);
235ce394f90datagen2026-10-26 06:54 UTC84
  const navigate = typeof data?.navigate === 'string' ? data.navigate : null;
d8772d4eb408atagen2026-10-26 04:43 UTC85
  event.waitUntil(
d8772d4eb408atagen2026-10-26 04:43 UTC86
    (async () => {
d8772d4eb408atagen2026-10-26 04:43 UTC87
      const windows = await sw.clients.matchAll({ type: 'window', includeUncontrolled: true });
d8772d4eb408atagen2026-10-26 04:43 UTC88
      const existing = windows.find((client) => client.visibilityState === 'visible') ?? windows[0];
d8772d4eb408atagen2026-10-26 04:43 UTC89
      if (!existing) {
235ce394f90datagen2026-10-26 06:54 UTC90
        await sw.clients.openWindow(roomTarget(roomId, navigate));
d8772d4eb408atagen2026-10-26 04:43 UTC91
        return;
d8772d4eb408atagen2026-10-26 04:43 UTC92
      }
235ce394f90datagen2026-10-26 06:54 UTC93
      if (roomId) existing.postMessage({ type: 'malice-open-room', roomId });
d8772d4eb408atagen2026-10-26 04:43 UTC94
      await existing.focus();
d8772d4eb408atagen2026-10-26 04:43 UTC95
    })()
d8772d4eb408atagen2026-10-26 04:43 UTC96
  );
d8772d4eb408atagen2026-10-26 04:43 UTC97
});