app: refonte JWE v2 - SvelteKit 2 + Svelte 5 + MapLibre, 4 modes de jeu, API anti-triche, ecran Cas B 'Pwen blinde', i18n FR/GCF, PWA

This commit is contained in:
sucupira
2026-07-16 21:05:22 -04:00
parent ee85a10e20
commit 923fa2869f
38 changed files with 8570 additions and 0 deletions
+64
View File
@@ -0,0 +1,64 @@
/// <reference types="@sveltejs/kit" />
/// <reference no-default-lib="true"/>
/// <reference lib="esnext" />
/// <reference lib="webworker" />
import { build, files, version } from '$service-worker';
const sw = self as unknown as ServiceWorkerGlobalScope;
const APP_SHELL = `jwe-shell-${version}`; // immuable, recréé à chaque build
const PHOTOS = 'jwe-photos'; // stale-while-revalidate
const ASSETS = [...build, ...files];
sw.addEventListener('install', (event) => {
event.waitUntil(caches.open(APP_SHELL).then((cache) => cache.addAll(ASSETS)));
});
sw.addEventListener('activate', (event) => {
event.waitUntil(
caches.keys().then((keys) =>
Promise.all(
keys
.filter((key) => key !== APP_SHELL && key !== PHOTOS)
.map((key) => caches.delete(key))
)
)
);
});
function isPhoto(url: URL): boolean {
return (
url.hostname === 'upload.wikimedia.org' ||
(url.hostname === 'commons.wikimedia.org' && url.pathname.startsWith('/wiki/Special:FilePath'))
);
}
sw.addEventListener('fetch', (event) => {
const url = new URL(event.request.url);
if (event.request.method !== 'GET') return;
// App shell : cache d'abord
if (ASSETS.includes(url.pathname)) {
event.respondWith(caches.match(event.request).then((r) => r ?? fetch(event.request)));
return;
}
// Photos Wikimedia : stale-while-revalidate
if (isPhoto(url)) {
event.respondWith(
caches.open(PHOTOS).then(async (cache) => {
const cached = await cache.match(event.request);
const frais = fetch(event.request)
.then((res) => {
if (res.ok) void cache.put(event.request, res.clone());
return res;
})
.catch(() => cached as Response);
return cached ?? frais;
})
);
return;
}
});