Spaces:
Running
Running
File size: 4,073 Bytes
3ca9355 9557c6b 3ca9355 bcd22af 9557c6b bcd22af 3ca9355 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
/**
* Service Worker for PWA
* Handles offline functionality and caching
*/
const CACHE_NAME = 'mipesca-v2';
const STATIC_CACHE = [
'./',
'index.html',
'css/styles.css',
'js/app.js',
'js/db.js',
'js/geolocation.js',
'js/api.js',
'js/sync.js',
'js/components/home.js',
'js/components/species-selector.js',
'js/components/capture-form.js',
'js/components/confirmation.js',
'js/components/history.js',
'js/components/info.js',
'manifest.json',
'https://unpkg.com/dexie@3.2.4/dist/dexie.min.js'
];
// Install event - cache static assets
self.addEventListener('install', (event) => {
console.log('Service Worker installing...');
event.waitUntil(
caches.open(CACHE_NAME)
.then((cache) => {
console.log('Caching static assets');
return cache.addAll(STATIC_CACHE);
})
.then(() => self.skipWaiting())
);
});
// Activate event - clean up 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 !== CACHE_NAME) {
console.log('Deleting old cache:', cacheName);
return caches.delete(cacheName);
}
})
);
}).then(() => self.clients.claim())
);
});
// Fetch event - serve from cache, fallback to network
self.addEventListener('fetch', (event) => {
const { request } = event;
const url = new URL(request.url);
// API requests - network first, then cache
if (url.pathname.startsWith('/api/')) {
event.respondWith(
fetch(request)
.then((response) => {
// Clone response to cache it
const responseClone = response.clone();
caches.open(CACHE_NAME).then((cache) => {
cache.put(request, responseClone);
});
return response;
})
.catch(() => {
// If network fails, try cache
return caches.match(request);
})
);
return;
}
// Static assets - cache first, then network
event.respondWith(
caches.match(request)
.then((cachedResponse) => {
if (cachedResponse) {
return cachedResponse;
}
return fetch(request)
.then((response) => {
// Don't cache non-successful responses
if (!response || response.status !== 200 || response.type === 'error') {
return response;
}
// Clone response to cache it
const responseClone = response.clone();
caches.open(CACHE_NAME).then((cache) => {
cache.put(request, responseClone);
});
return response;
});
})
.catch(() => {
// Return offline page if available
if (request.mode === 'navigate') {
return caches.match('/index.html');
}
})
);
});
// Background sync for captures
self.addEventListener('sync', (event) => {
if (event.tag === 'sync-captures') {
console.log('Background sync triggered');
event.waitUntil(
// Notify clients to sync
self.clients.matchAll().then((clients) => {
clients.forEach((client) => {
client.postMessage({
type: 'BACKGROUND_SYNC',
action: 'sync-captures'
});
});
})
);
}
});
|