/** * Service worker (Workbox, injectManifest mode). * * - App shell + the PokéAPI snapshot are precached (offline launch, instant * list / search / game switching). * - Lazy detail JSON from pokeapi.co: stale-while-revalidate, 30-day TTL. * - Sprites from the PokeAPI sprites repo: cache-first, capped LRU. */ import { precacheAndRoute } from 'workbox-precaching'; import { registerRoute } from 'workbox-routing'; import { StaleWhileRevalidate, CacheFirst } from 'workbox-strategies'; import { ExpirationPlugin } from 'workbox-expiration'; import { CacheableResponsePlugin } from 'workbox-cacheable-response'; precacheAndRoute(self.__WB_MANIFEST || []); const MONTH = 30 * 24 * 60 * 60; registerRoute( ({ url }) => url.origin === 'https://pokeapi.co', new StaleWhileRevalidate({ cacheName: 'pokeapi-json', plugins: [ new CacheableResponsePlugin({ statuses: [0, 200] }), new ExpirationPlugin({ maxEntries: 1500, maxAgeSeconds: MONTH, purgeOnQuotaError: true, }), ], }), ); registerRoute( ({ url }) => url.origin === 'https://raw.githubusercontent.com' && (url.pathname.includes('/PokeAPI/sprites/') || url.pathname.includes('/PokeAPI/cries/')), new CacheFirst({ cacheName: 'pokeapi-img', plugins: [ new CacheableResponsePlugin({ statuses: [0, 200] }), new ExpirationPlugin({ maxEntries: 600, maxAgeSeconds: MONTH, purgeOnQuotaError: true, }), ], }), ); self.addEventListener('message', (event) => { if (event.data && event.data.type === 'SKIP_WAITING') self.skipWaiting(); });