Files
GreenHomeUI/public/sw.js
alireza 618960bb5c
Some checks failed
Deploy MyApp on Same Server / build-and-deploy (push) Failing after 1s
optimization
2025-12-19 23:17:30 +03:30

194 lines
5.2 KiB
JavaScript

const CACHE_NAME = 'greenhome-1766173610406';
const STATIC_CACHE_NAME = 'greenhome-static-1766173610406';
// Static assets to cache on install
const STATIC_FILES_TO_CACHE = [
'/',
'/manifest.json',
'/icon-192.png',
'/icon-512.png',
];
// Check if request is for static assets
function isStaticAsset(url) {
return (
url.includes('/_next/static/') ||
url.includes('/_next/image') ||
url.match(/\.(js|css|woff|woff2|ttf|eot|svg|png|jpg|jpeg|gif|webp|ico)$/i)
);
}
// Check if request is for external API (skip caching)
function isExternalApiRequest(url) {
return url.startsWith('http') && !url.startsWith(self.location.origin);
}
self.addEventListener('install', (event) => {
event.waitUntil(
(async () => {
const cache = await caches.open(STATIC_CACHE_NAME);
try {
await cache.addAll(STATIC_FILES_TO_CACHE);
} catch (error) {
console.log('Some static files failed to cache:', error);
}
// Don't skip waiting automatically - let user decide when to update
// await self.skipWaiting();
})()
);
});
self.addEventListener('activate', (event) => {
event.waitUntil(
(async () => {
await self.clients.claim();
// Remove old caches
const keys = await caches.keys();
await Promise.all(
keys
.filter((key) => key !== CACHE_NAME && key !== STATIC_CACHE_NAME)
.map((key) => caches.delete(key))
);
})()
);
});
// Listen for messages from clients (e.g., when user clicks update button)
self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'SKIP_WAITING') {
self.skipWaiting().then(() => {
// Notify all clients about update
return self.clients.matchAll();
}).then((clients) => {
clients.forEach((client) => {
client.postMessage({ type: 'SW_UPDATED' });
});
});
}
});
self.addEventListener('fetch', (event) => {
const { request } = event;
const url = new URL(request.url);
// Skip non-GET requests and external API requests
if (request.method !== 'GET' || isExternalApiRequest(url.href)) {
return;
}
// Handle navigation requests (pages)
if (request.mode === 'navigate') {
event.respondWith(
(async () => {
try {
// Try network first
const preloadResponse = await event.preloadResponse;
if (preloadResponse) {
const cache = await caches.open(CACHE_NAME);
cache.put(request, preloadResponse.clone());
return preloadResponse;
}
const networkResponse = await fetch(request);
// Cache successful responses
if (networkResponse.ok) {
const cache = await caches.open(CACHE_NAME);
cache.put(request, networkResponse.clone());
}
return networkResponse;
} catch (error) {
// Network failed, try cache
const cache = await caches.open(CACHE_NAME);
const cachedResponse = await cache.match(request);
if (cachedResponse) {
return cachedResponse;
}
// Fallback to home page if available
const homePage = await cache.match('/');
if (homePage) {
return homePage;
}
// Last resort: return offline page
return new Response('Offline - No internet connection', {
status: 503,
statusText: 'Service Unavailable',
headers: { 'Content-Type': 'text/html' },
});
}
})()
);
return;
}
// Handle static assets (Cache First strategy)
if (isStaticAsset(url.href)) {
event.respondWith(
(async () => {
const cache = await caches.open(STATIC_CACHE_NAME);
const cachedResponse = await cache.match(request);
if (cachedResponse) {
return cachedResponse;
}
try {
const networkResponse = await fetch(request);
// Cache successful responses
if (networkResponse.ok) {
cache.put(request, networkResponse.clone());
}
return networkResponse;
} catch (error) {
// If network fails and no cache, return error
return new Response('Resource not available offline', {
status: 503,
statusText: 'Service Unavailable',
});
}
})()
);
return;
}
// Handle other requests (Network First strategy)
event.respondWith(
(async () => {
const cache = await caches.open(CACHE_NAME);
try {
// Try network first
const networkResponse = await fetch(request);
// Cache successful responses
if (networkResponse.ok) {
cache.put(request, networkResponse.clone());
}
return networkResponse;
} catch (error) {
// Network failed, try cache
const cachedResponse = await cache.match(request);
if (cachedResponse) {
return cachedResponse;
}
// Return error if no cache available
return new Response('Resource not available offline', {
status: 503,
statusText: 'Service Unavailable',
});
}
})()
);
});