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';
|
// Unregister this service worker and clear all caches
|
||||||
const STATIC_CACHE = 'tomsjavajive-static-v1';
|
self.addEventListener('install', () => self.skipWaiting());
|
||||||
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
|
|
||||||
self.addEventListener('activate', (event) => {
|
self.addEventListener('activate', (event) => {
|
||||||
console.log('[Service Worker] Activating...');
|
event.waitUntil(
|
||||||
|
caches.keys()
|
||||||
event.waitUntil(
|
.then(keys => Promise.all(keys.map(key => caches.delete(key))))
|
||||||
caches.keys().then((cacheNames) => {
|
.then(() => self.registration.unregister())
|
||||||
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');
|
|
||||||
});
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
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