88 lines
2.5 KiB
JavaScript
88 lines
2.5 KiB
JavaScript
/**
|
||
* Service Worker — КЛГ АСУ ТК v2.
|
||
* Стратегия: network-first для API, cache-first для статики.
|
||
* Offline fallback для всех страниц.
|
||
*/
|
||
const CACHE_NAME = 'klg-v2';
|
||
const STATIC_CACHE = 'klg-static-v2';
|
||
const API_CACHE = 'klg-api-v2';
|
||
|
||
const SHELL_URLS = [
|
||
'/', '/dashboard', '/login', '/offline',
|
||
'/aircraft', '/airworthiness', '/airworthiness-core',
|
||
'/maintenance', '/defects', '/personnel-plg',
|
||
'/calendar', '/risks', '/checklists', '/regulator',
|
||
];
|
||
|
||
// Install: cache app shell
|
||
self.addEventListener('install', (event) => {
|
||
event.waitUntil(
|
||
caches.open(CACHE_NAME).then((cache) => cache.addAll(SHELL_URLS))
|
||
);
|
||
self.skipWaiting();
|
||
});
|
||
|
||
// Activate: clean old caches
|
||
self.addEventListener('activate', (event) => {
|
||
event.waitUntil(
|
||
caches.keys().then((keys) =>
|
||
Promise.all(
|
||
keys
|
||
.filter((k) => k !== CACHE_NAME && k !== STATIC_CACHE && k !== API_CACHE)
|
||
.map((k) => caches.delete(k))
|
||
)
|
||
)
|
||
);
|
||
self.clients.claim();
|
||
});
|
||
|
||
// Fetch: network-first for API, cache-first for static
|
||
self.addEventListener('fetch', (event) => {
|
||
const { request } = event;
|
||
const url = new URL(request.url);
|
||
|
||
// API requests: network-first with cache fallback
|
||
if (url.pathname.startsWith('/api/')) {
|
||
event.respondWith(
|
||
fetch(request)
|
||
.then((response) => {
|
||
// Cache GET responses for offline
|
||
if (request.method === 'GET' && response.ok) {
|
||
const clone = response.clone();
|
||
caches.open(API_CACHE).then((cache) => cache.put(request, clone));
|
||
}
|
||
return response;
|
||
})
|
||
.catch(() => caches.match(request))
|
||
);
|
||
return;
|
||
}
|
||
|
||
// Static assets: cache-first
|
||
if (url.pathname.match(/\.(js|css|png|jpg|svg|woff2?)$/)) {
|
||
event.respondWith(
|
||
caches.match(request).then((cached) =>
|
||
cached || fetch(request).then((response) => {
|
||
const clone = response.clone();
|
||
caches.open(STATIC_CACHE).then((cache) => cache.put(request, clone));
|
||
return response;
|
||
})
|
||
)
|
||
);
|
||
return;
|
||
}
|
||
|
||
// Pages: network-first with offline fallback
|
||
event.respondWith(
|
||
fetch(request)
|
||
.then((response) => {
|
||
const clone = response.clone();
|
||
caches.open(CACHE_NAME).then((cache) => cache.put(request, clone));
|
||
return response;
|
||
})
|
||
.catch(() =>
|
||
caches.match(request).then((cached) => cached || caches.match('/offline'))
|
||
)
|
||
);
|
||
});
|