// CodePress CMS Service Worker for PWA functionality const CACHE_NAME = 'codepress-v1.5.0'; const STATIC_CACHE = 'codepress-static-v1.5.0'; const DYNAMIC_CACHE = 'codepress-dynamic-v1.5.0'; // Files to cache immediately const STATIC_FILES = [ '/', '/manifest.json', '/assets/css/bootstrap.min.css', '/assets/css/bootstrap-icons.css', '/assets/css/style.css', '/assets/css/mobile.css', '/assets/js/bootstrap.bundle.min.js', '/assets/js/app.js', '/assets/icon.svg' ]; // Install event - cache static files self.addEventListener('install', event => { console.log('[Service Worker] Installing'); event.waitUntil( caches.open(STATIC_CACHE) .then(cache => { console.log('[Service Worker] Caching static files'); return cache.addAll(STATIC_FILES); }) .then(() => self.skipWaiting()) ); }); // Activate event - clean old caches self.addEventListener('activate', event => { console.log('[Service Worker] Activating'); event.waitUntil( caches.keys().then(cacheNames => { return Promise.all( cacheNames.map(cacheName => { if (cacheName !== STATIC_CACHE && cacheName !== DYNAMIC_CACHE) { console.log('[Service Worker] Deleting old cache:', cacheName); return caches.delete(cacheName); } }) ); }).then(() => self.clients.claim()) ); }); // Fetch event - serve from cache or network self.addEventListener('fetch', event => { const { request } = event; const url = new URL(request.url); // Skip non-GET requests if (request.method !== 'GET') return; // Skip external requests if (!url.origin.includes(self.location.origin)) return; // Handle API requests differently if (url.pathname.startsWith('/api/')) { event.respondWith( fetch(request) .then(response => { // Cache successful API responses if (response.ok) { const responseClone = response.clone(); caches.open(DYNAMIC_CACHE) .then(cache => cache.put(request, responseClone)); } return response; }) .catch(() => { // Return cached API response if available return caches.match(request); }) ); return; } // Handle page requests if (request.destination === 'document' || url.pathname === '/') { event.respondWith( caches.match(request) .then(cachedResponse => { if (cachedResponse) { // Return cached version and update in background fetch(request).then(networkResponse => { if (networkResponse.ok) { caches.open(DYNAMIC_CACHE) .then(cache => cache.put(request, networkResponse)); } }).catch(() => { // Network failed, keep cached version }); return cachedResponse; } // Not in cache, fetch from network return fetch(request) .then(response => { if (response.ok) { const responseClone = response.clone(); caches.open(DYNAMIC_CACHE) .then(cache => cache.put(request, responseClone)); } return response; }); }) ); return; } // Handle static assets event.respondWith( caches.match(request) .then(cachedResponse => { if (cachedResponse) { return cachedResponse; } return fetch(request) .then(response => { // Cache static assets if (response.ok && ( request.destination === 'style' || request.destination === 'script' || request.destination === 'image' || request.destination === 'font' )) { const responseClone = response.clone(); caches.open(STATIC_CACHE) .then(cache => cache.put(request, responseClone)); } return response; }); }) ); }); // Background sync for offline actions self.addEventListener('sync', event => { if (event.tag === 'background-sync') { event.waitUntil(doBackgroundSync()); } }); async function doBackgroundSync() { // Implement background sync logic here console.log('[Service Worker] Background sync triggered'); }