mirror of
https://github.com/myronblair/tomsjavajive
synced 2026-06-30 17:50:32 -05:00
Disable service worker and clear all caches
SW was caching shop pages and JS files, serving stale versions without the inline onclick handler. Replacing with self-unregistering SW. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,269 +1,9 @@
|
||||
const CACHE_NAME = 'tomsjavajive-v1';
|
||||
const STATIC_CACHE = 'tomsjavajive-static-v1';
|
||||
const DYNAMIC_CACHE = 'tomsjavajive-dynamic-v1';
|
||||
|
||||
// Static assets to cache immediately
|
||||
const STATIC_ASSETS = [
|
||||
'/',
|
||||
'/shop.php',
|
||||
'/cart.php',
|
||||
'/assets/css/style.css',
|
||||
'/assets/js/main.js',
|
||||
'/assets/images/logo.png',
|
||||
'/manifest.json',
|
||||
'/offline.html'
|
||||
];
|
||||
|
||||
// Install event - cache static assets
|
||||
self.addEventListener('install', (event) => {
|
||||
console.log('[Service Worker] Installing...');
|
||||
|
||||
event.waitUntil(
|
||||
caches.open(STATIC_CACHE)
|
||||
.then((cache) => {
|
||||
console.log('[Service Worker] Caching static assets');
|
||||
return cache.addAll(STATIC_ASSETS.map(url => {
|
||||
return new Request(url, { cache: 'no-cache' });
|
||||
})).catch(err => {
|
||||
console.log('[Service Worker] Some assets failed to cache:', err);
|
||||
return Promise.resolve();
|
||||
});
|
||||
})
|
||||
.then(() => self.skipWaiting())
|
||||
);
|
||||
});
|
||||
|
||||
// Activate event - clean up old caches
|
||||
// Unregister this service worker and clear all caches
|
||||
self.addEventListener('install', () => self.skipWaiting());
|
||||
self.addEventListener('activate', (event) => {
|
||||
console.log('[Service Worker] Activating...');
|
||||
|
||||
event.waitUntil(
|
||||
caches.keys().then((cacheNames) => {
|
||||
return Promise.all(
|
||||
cacheNames
|
||||
.filter((cacheName) => {
|
||||
return cacheName !== STATIC_CACHE &&
|
||||
cacheName !== DYNAMIC_CACHE &&
|
||||
cacheName.startsWith('tomsjavajive-');
|
||||
})
|
||||
.map((cacheName) => {
|
||||
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 admin panel
|
||||
if (url.pathname.startsWith('/admin')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip API requests (always network)
|
||||
if (url.pathname.startsWith('/api')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle navigation requests
|
||||
if (request.mode === 'navigate') {
|
||||
event.respondWith(
|
||||
fetch(request)
|
||||
.then((response) => {
|
||||
// Clone and cache the response
|
||||
const responseClone = response.clone();
|
||||
caches.open(DYNAMIC_CACHE).then((cache) => {
|
||||
cache.put(request, responseClone);
|
||||
});
|
||||
return response;
|
||||
})
|
||||
.catch(() => {
|
||||
// Try to serve from cache
|
||||
return caches.match(request)
|
||||
.then((cachedResponse) => {
|
||||
if (cachedResponse) {
|
||||
return cachedResponse;
|
||||
}
|
||||
// Serve offline page
|
||||
return caches.match('/offline.html');
|
||||
});
|
||||
})
|
||||
event.waitUntil(
|
||||
caches.keys()
|
||||
.then(keys => Promise.all(keys.map(key => caches.delete(key))))
|
||||
.then(() => self.registration.unregister())
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle static assets (cache-first strategy)
|
||||
if (isStaticAsset(url.pathname)) {
|
||||
event.respondWith(
|
||||
caches.match(request)
|
||||
.then((cachedResponse) => {
|
||||
if (cachedResponse) {
|
||||
// Fetch in background to update cache
|
||||
fetch(request).then((response) => {
|
||||
if (response.ok) {
|
||||
caches.open(STATIC_CACHE).then((cache) => {
|
||||
cache.put(request, response);
|
||||
});
|
||||
}
|
||||
}).catch(() => {});
|
||||
|
||||
return cachedResponse;
|
||||
}
|
||||
|
||||
return fetch(request).then((response) => {
|
||||
if (response.ok) {
|
||||
const responseClone = response.clone();
|
||||
caches.open(STATIC_CACHE).then((cache) => {
|
||||
cache.put(request, responseClone);
|
||||
});
|
||||
}
|
||||
return response;
|
||||
});
|
||||
})
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle images (cache-first with network fallback)
|
||||
if (isImageRequest(request)) {
|
||||
event.respondWith(
|
||||
caches.match(request)
|
||||
.then((cachedResponse) => {
|
||||
if (cachedResponse) {
|
||||
return cachedResponse;
|
||||
}
|
||||
|
||||
return fetch(request)
|
||||
.then((response) => {
|
||||
if (response.ok) {
|
||||
const responseClone = response.clone();
|
||||
caches.open(DYNAMIC_CACHE).then((cache) => {
|
||||
cache.put(request, responseClone);
|
||||
});
|
||||
}
|
||||
return response;
|
||||
})
|
||||
.catch(() => {
|
||||
// Return placeholder image
|
||||
return caches.match('/assets/images/placeholder-product.svg');
|
||||
});
|
||||
})
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Default: network-first with cache fallback
|
||||
event.respondWith(
|
||||
fetch(request)
|
||||
.then((response) => {
|
||||
if (response.ok) {
|
||||
const responseClone = response.clone();
|
||||
caches.open(DYNAMIC_CACHE).then((cache) => {
|
||||
cache.put(request, responseClone);
|
||||
});
|
||||
}
|
||||
return response;
|
||||
})
|
||||
.catch(() => {
|
||||
return caches.match(request);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
// Helper functions
|
||||
function isStaticAsset(pathname) {
|
||||
return pathname.match(/\.(css|js|woff|woff2|ttf|eot)$/i);
|
||||
}
|
||||
|
||||
function isImageRequest(request) {
|
||||
return request.destination === 'image' ||
|
||||
request.url.match(/\.(png|jpg|jpeg|gif|svg|webp|ico)$/i);
|
||||
}
|
||||
|
||||
// Push notification handling
|
||||
self.addEventListener('push', (event) => {
|
||||
console.log('[Service Worker] Push received');
|
||||
|
||||
let data = { title: "Tom's Java Jive", body: 'You have a new notification!' };
|
||||
|
||||
if (event.data) {
|
||||
try {
|
||||
data = event.data.json();
|
||||
} catch (e) {
|
||||
data.body = event.data.text();
|
||||
}
|
||||
}
|
||||
|
||||
const options = {
|
||||
body: data.body,
|
||||
icon: '/assets/icons/icon-192.png',
|
||||
badge: '/assets/icons/badge-72.png',
|
||||
vibrate: [100, 50, 100],
|
||||
data: {
|
||||
url: data.url || '/'
|
||||
},
|
||||
actions: [
|
||||
{ action: 'view', title: 'View' },
|
||||
{ action: 'close', title: 'Close' }
|
||||
]
|
||||
};
|
||||
|
||||
event.waitUntil(
|
||||
self.registration.showNotification(data.title, options)
|
||||
);
|
||||
});
|
||||
|
||||
// Notification click handling
|
||||
self.addEventListener('notificationclick', (event) => {
|
||||
console.log('[Service Worker] Notification clicked');
|
||||
|
||||
event.notification.close();
|
||||
|
||||
if (event.action === 'close') {
|
||||
return;
|
||||
}
|
||||
|
||||
const url = event.notification.data?.url || '/';
|
||||
|
||||
event.waitUntil(
|
||||
clients.matchAll({ type: 'window', includeUncontrolled: true })
|
||||
.then((clientList) => {
|
||||
// Focus existing window if available
|
||||
for (const client of clientList) {
|
||||
if (client.url === url && 'focus' in client) {
|
||||
return client.focus();
|
||||
}
|
||||
}
|
||||
// Open new window
|
||||
if (clients.openWindow) {
|
||||
return clients.openWindow(url);
|
||||
}
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
// Background sync for cart/orders
|
||||
self.addEventListener('sync', (event) => {
|
||||
console.log('[Service Worker] Background sync:', event.tag);
|
||||
|
||||
if (event.tag === 'sync-cart') {
|
||||
event.waitUntil(syncCart());
|
||||
}
|
||||
});
|
||||
|
||||
async function syncCart() {
|
||||
// Get pending cart actions from IndexedDB
|
||||
// and sync with server
|
||||
console.log('[Service Worker] Syncing cart...');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user