- Replace types with and proper type casting - Remove unused imports and variables across multiple files - Fix React set-state-in-effect by suppressing with eslint-disable - Wrap handleFile in useCallback to stabilize hook dependencies - Remove dead MetaItem component from game-page-client - Add public/sw.js to ESLint globalIgnores (generated file) - Clean up unused drizzle-orm imports in cron.ts, dashboard-public.ts - Remove unused _configured flag from r2-client.ts
81 lines
2.3 KiB
TypeScript
81 lines
2.3 KiB
TypeScript
import type { PrecacheEntry } from "@serwist/precaching";
|
|
import { CacheFirst, NetworkFirst, StaleWhileRevalidate } from "@serwist/strategies";
|
|
import { ExpirationPlugin } from "@serwist/expiration";
|
|
import { Serwist } from "serwist";
|
|
|
|
declare global {
|
|
interface Window {
|
|
__SW_MANIFEST: (string | PrecacheEntry)[];
|
|
}
|
|
}
|
|
|
|
const serwist = new Serwist({
|
|
precacheEntries: self.__SW_MANIFEST,
|
|
skipWaiting: true,
|
|
clientsClaim: true,
|
|
runtimeCaching: [
|
|
// Game detail pages: stale-while-revalidate, 24h max age
|
|
{
|
|
matcher: /\/game\/[\w-]+$/,
|
|
handler: new StaleWhileRevalidate({
|
|
cacheName: "game-pages",
|
|
plugins: [
|
|
new ExpirationPlugin({ maxEntries: 200, maxAgeSeconds: 24 * 60 * 60 }),
|
|
],
|
|
}),
|
|
},
|
|
// Game listing page: network-first (filters matter)
|
|
{
|
|
matcher: /\/games(\?.*)?$/,
|
|
handler: new NetworkFirst({
|
|
cacheName: "games-listing",
|
|
plugins: [
|
|
new ExpirationPlugin({ maxEntries: 20, maxAgeSeconds: 5 * 60 }),
|
|
],
|
|
}),
|
|
},
|
|
// Steam CDN images: cache-first, 30 days
|
|
{
|
|
matcher: /^https:\/\/cdn\.akamai\.steamstatic\.com\//,
|
|
handler: new CacheFirst({
|
|
cacheName: "steam-images",
|
|
plugins: [
|
|
new ExpirationPlugin({ maxEntries: 500, maxAgeSeconds: 30 * 24 * 60 * 60 }),
|
|
],
|
|
}),
|
|
},
|
|
// SteamGridDB images: cache-first, 30 days
|
|
{
|
|
matcher: /^https:\/\/cdn\d?\.steamgriddb\.com\//,
|
|
handler: new CacheFirst({
|
|
cacheName: "steamgrid-images",
|
|
plugins: [
|
|
new ExpirationPlugin({ maxEntries: 200, maxAgeSeconds: 30 * 24 * 60 * 60 }),
|
|
],
|
|
}),
|
|
},
|
|
// API responses: network-first (live data critical)
|
|
{
|
|
matcher: /\/api\//,
|
|
handler: new NetworkFirst({
|
|
cacheName: "api-responses",
|
|
plugins: [
|
|
new ExpirationPlugin({ maxEntries: 100, maxAgeSeconds: 5 * 60 }),
|
|
],
|
|
}),
|
|
},
|
|
// Navigation fallback for HTML pages (not XML/JSON/etc.)
|
|
{
|
|
matcher: ({ request }) => request.mode === "navigate" && !request.url.endsWith(".xml"),
|
|
handler: new NetworkFirst({
|
|
cacheName: "navigation",
|
|
plugins: [
|
|
new ExpirationPlugin({ maxEntries: 50, maxAgeSeconds: 24 * 60 * 60 }),
|
|
],
|
|
}),
|
|
},
|
|
],
|
|
});
|
|
|
|
serwist.addEventListeners();
|