Vitron-Front/public/sw.js
2026-04-29 01:44:16 +03:30

145 lines
3.7 KiB
JavaScript

const STATIC_CACHE_NAME = "vitrown-static-v2";
const DYNAMIC_CACHE_NAME = "vitrown-dynamic-v2";
const STATIC_ASSETS = [
"/",
"/resources/manifest.webmanifest",
"/favicon.ico",
"/icon-192x192.png",
"/icon-512x512.png",
"/apple-touch-icon.png",
];
// Install event - cache static assets
self.addEventListener("install", (event) => {
event.waitUntil(
caches.open(STATIC_CACHE_NAME).then((cache) => {
return cache.addAll(STATIC_ASSETS);
})
);
self.skipWaiting();
});
// Activate event - clean up old caches
self.addEventListener("activate", (event) => {
event.waitUntil(
caches.keys().then((cacheNames) => {
return Promise.all(
cacheNames
.filter((cacheName) => {
return (
cacheName.startsWith("vitrown-") &&
cacheName !== STATIC_CACHE_NAME &&
cacheName !== DYNAMIC_CACHE_NAME
);
})
.map((cacheName) => caches.delete(cacheName))
);
})
);
self.clients.claim();
});
// Fetch event - network first, cache fallback strategy
self.addEventListener("fetch", (event) => {
const { request } = event;
const url = new URL(request.url);
// Skip non-GET requests
if (request.method !== "GET") {
return;
}
// Skip non-HTTP(S) requests (chrome-extension://, etc.)
if (!url.protocol.startsWith("http")) {
return;
}
// Skip WebSocket, SSE, and API requests
if (
url.pathname.startsWith("/api/") ||
url.protocol === "ws:" ||
url.protocol === "wss:" ||
request.headers.get("accept")?.includes("text/event-stream")
) {
return;
}
// For navigation requests, try network first
if (request.mode === "navigate") {
event.respondWith(
fetch(request)
.then((response) => {
const responseToCache = response.clone();
caches.open(DYNAMIC_CACHE_NAME).then((cache) => {
cache.put(request, responseToCache);
});
return response;
})
.catch(() => {
return caches.match(request);
})
);
return;
}
// For static assets (CSS, JS, images), use cache first
if (
request.destination === "style" ||
request.destination === "script" ||
request.destination === "image" ||
request.destination === "font"
) {
event.respondWith(
caches.match(request).then((cachedResponse) => {
if (cachedResponse) {
// Update cache in background
fetch(request).then((response) => {
if (response.status === 200) {
const responseToCache = response.clone();
caches.open(STATIC_CACHE_NAME).then((cache) => {
cache.put(request, responseToCache);
});
}
});
return cachedResponse;
}
return fetch(request).then((response) => {
if (response.status === 200) {
const responseToCache = response.clone();
caches.open(STATIC_CACHE_NAME).then((cache) => {
cache.put(request, responseToCache);
});
}
return response;
});
})
);
return;
}
// For other requests, network first
event.respondWith(
fetch(request)
.then((response) => {
if (response.status === 200) {
const responseToCache = response.clone();
caches.open(DYNAMIC_CACHE_NAME).then((cache) => {
cache.put(request, responseToCache);
});
}
return response;
})
.catch(() => {
return caches.match(request);
})
);
});
// Listen for messages from the client
self.addEventListener("message", (event) => {
if (event.data && event.data.type === "SKIP_WAITING") {
self.skipWaiting();
}
});