Files
Ustagammon/web/sw.js
Pierre MARTINandClaude Opus 5.5 a8636b3f83 Plateau jouable en PWA : interface, Web Worker, stockage, service worker
L'application est à la racine du site : plateau en SVG, saisie au toucher
(pion puis case d'arrivée, proposées à partir du moteur), boutons du jet,
du videau et de nouvelle partie, coup de l'ordinateur affiché avec son
temps, fin de partie, reprise depuis localStorage, aide lue dans les
copies de docs/. Le moteur tourne dans le Web Worker existant ; main.ts
est le seul assembleur (nouvelles règles dependency-cruiser). Le service
worker met tout le site en cache, avec une empreinte du contenu comme
version. Les pages de test du moteur passent sous /moteur/. Politique de
sécurité du contenu dans le Caddyfile ; make test-browser joue une partie
dans Chromium et Firefox sans écran (Playwright, hors de make test).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 21:47:12 +01:00

62 lines
2.1 KiB
JavaScript

// sw.js -- service worker d'Ustagammon : l'application hors ligne.
//
// Copyright (C) 2026 les auteurs d'Ustagammon.
// Licence : GPLv3 ou ultérieure (voir LICENSE).
//
// À l'installation, tous les fichiers du site (dont les 8,7 Mo de données du
// moteur) sont mis en cache ; ensuite, chaque fichier est servi depuis ce
// cache, sans réseau. VERSION et FILES sont écrits en tête de ce fichier par
// scripts/service-worker.sh au moment de make site.
//
// Mise à jour : à chaque publication, VERSION change, donc ce fichier. Le
// navigateur installe alors la nouvelle version, qui télécharge tout dans un
// nouveau cache, prend la main tout de suite et efface l'ancien cache. La
// page déjà ouverte a chargé tous ses fichiers au démarrage : elle continue
// sans rien remarquer, et le prochain lancement utilise la nouvelle version.
/* global VERSION, FILES */
const CACHE = `ustagammon-${VERSION}`;
self.addEventListener("install", (event) => {
event.waitUntil(
(async () => {
const cache = await caches.open(CACHE);
// no-cache : revalider auprès du serveur, jamais une copie
// périmée du cache HTTP du navigateur.
await cache.addAll(FILES.map((file) => new Request(file, { cache: "no-cache" })));
await self.skipWaiting();
})(),
);
});
self.addEventListener("activate", (event) => {
event.waitUntil(
(async () => {
for (const name of await caches.keys()) {
if (name !== CACHE) {
await caches.delete(name);
}
}
await self.clients.claim();
})(),
);
});
self.addEventListener("fetch", (event) => {
const request = event.request;
if (request.method !== "GET" || new URL(request.url).origin !== self.location.origin) {
return;
}
event.respondWith(
(async () => {
const cached = await caches.match(request, {
cacheName: CACHE,
ignoreSearch: true,
ignoreVary: true,
});
return cached ?? fetch(request);
})(),
);
});