atagen

malice

public
Star0
Watch0

Commit 919753ab134c

tarball

atagen <boss@atagen.co>2026-10-26 03:48 UTC

3 files changed+10-2
web: keep the service worker current and prune old shell assets

updateViaCache none makes sw.js and its imports bypass the HTTP cache, so a stale cached copy importing a deleted chunk can no longer leave the device build without media. The shell cache had kept every past build's wasm, about 170MB.
Modified file: web/src/lib/transport-worker.ts+1 additions−1 deletions
@@ -14,7 +14,7 @@ const SW_RELOAD_GUARD = 'malice-sw-reload';
1414 function registerServiceWorker(): void {
1515 if (!('serviceWorker' in navigator)) return;
1616 void navigator.serviceWorker
17- .register('/sw.js', { type: 'module' })
17+ .register('/sw.js', { type: 'module', updateViaCache: 'none' })
1818 .then(() => navigator.serviceWorker.ready)
1919 .then(() => {
2020 if (navigator.serviceWorker.controller) {
Modified file: web/src/sw.ts+6 additions
@@ -25,6 +25,12 @@ sw.addEventListener('activate', (event) => {
2525 (async () => {
2626 const keys = await caches.keys();
2727 await Promise.all(keys.filter((key) => key !== CACHE_NAME && key !== AVATAR_CACHE).map((key) => caches.delete(key)));
28+ const shell = await caches.open(CACHE_NAME);
29+ const keep = new Set(['/', '/index.html', ...sw.__MALICE_PRECACHE__]);
30+ for (const request of await shell.keys()) {
31+ const path = new URL(request.url).pathname;
32+ if (path.startsWith('/assets/') && !keep.has(path)) await shell.delete(request);
33+ }
2834 await sw.clients.claim();
2935 })()
3036 );
Modified file: web/vite.config.ts+3 additions−1 deletions
@@ -4,6 +4,8 @@ import { fileURLToPath } from 'node:url';
44 import { defineConfig } from 'vite';
55 import { svelte } from '@sveltejs/vite-plugin-svelte';
66
7+const EMOJI_DATA_CHUNK = /^assets\/(compact|emojibase)-[^/]*\.js$/;
8+
79 /**
810 * The page isn't SW-controlled on first launch, so the worker chunk and the
911 * wasm can bypass fetch interception entirely and never get cached. Instead
@@ -16,7 +18,7 @@ function precacheManifestPlugin(): import('vite').Plugin {
1618 name: 'malice-sw-precache-manifest',
1719 generateBundle(_options, bundle) {
1820 const urls = Object.keys(bundle)
19- .filter((fileName) => fileName !== 'sw.js' && !fileName.startsWith('twemoji/'))
21+ .filter((fileName) => fileName !== 'sw.js' && !fileName.startsWith('twemoji/') && !EMOJI_DATA_CHUNK.test(fileName))
2022 .map((fileName) => `/${fileName}`);
2123 const swChunk = bundle['sw.js'];
2224 if (swChunk && swChunk.type === 'chunk') {