110 lines
3.6 KiB
JavaScript
110 lines
3.6 KiB
JavaScript
/**
|
|
* Warehouse Stocktake PWA - Service Worker
|
|
*
|
|
* Provides basic caching for the app shell (offline-first for static assets).
|
|
* API calls are always fetched from network.
|
|
*/
|
|
|
|
const CACHE_NAME = 'warehouse-stocktake-v1';
|
|
|
|
// Static assets to cache for offline use
|
|
const ASSETS_TO_CACHE = [
|
|
'/MobileApp/WarehouseStocktake',
|
|
'/mobile/warehouse-stocktake/app.js',
|
|
'/mobile/warehouse-stocktake/app.css',
|
|
'/mobile/warehouse-stocktake/components/LoginScreen.js',
|
|
'/mobile/warehouse-stocktake/components/StocktakeList.js',
|
|
'/mobile/warehouse-stocktake/components/Scanner.js',
|
|
'/mobile/shared/auth.js',
|
|
'/mobile/shared/base.css',
|
|
'/assets/images/xinon-full-transparent.png',
|
|
'/assets/images/xinon-full-transparent-white.png',
|
|
'/assets/images/xinon-sm.png',
|
|
'/assets/images/favicon.ico'
|
|
];
|
|
|
|
// Install event - cache static assets
|
|
self.addEventListener('install', (event) => {
|
|
event.waitUntil(
|
|
caches.open(CACHE_NAME)
|
|
.then(cache => {
|
|
console.log('[SW] Caching app shell');
|
|
return cache.addAll(ASSETS_TO_CACHE);
|
|
})
|
|
.then(() => self.skipWaiting())
|
|
);
|
|
});
|
|
|
|
// Activate event - clean up old caches
|
|
self.addEventListener('activate', (event) => {
|
|
event.waitUntil(
|
|
caches.keys()
|
|
.then(cacheNames => {
|
|
return Promise.all(
|
|
cacheNames
|
|
.filter(name => name !== CACHE_NAME)
|
|
.map(name => {
|
|
console.log('[SW] Deleting old cache:', name);
|
|
return caches.delete(name);
|
|
})
|
|
);
|
|
})
|
|
.then(() => self.clients.claim())
|
|
);
|
|
});
|
|
|
|
// Fetch event - network first for API, cache first for assets
|
|
self.addEventListener('fetch', (event) => {
|
|
const { request } = event;
|
|
const url = new URL(request.url);
|
|
|
|
// Skip non-GET requests
|
|
if (request.method !== 'GET') {
|
|
return;
|
|
}
|
|
|
|
// Skip CDN requests (Vue, Tailwind, etc.)
|
|
if (url.hostname !== self.location.hostname) {
|
|
return;
|
|
}
|
|
|
|
// API calls - always go to network (no caching)
|
|
if (url.pathname.startsWith('/MobileApp/') &&
|
|
!url.pathname.endsWith('/WarehouseStocktake') &&
|
|
url.pathname !== '/MobileApp/WarehouseStocktake') {
|
|
return;
|
|
}
|
|
|
|
// Static assets - cache first, fallback to network
|
|
event.respondWith(
|
|
caches.match(request)
|
|
.then(cachedResponse => {
|
|
if (cachedResponse) {
|
|
// Return cached version, but also update cache in background
|
|
event.waitUntil(
|
|
fetch(request)
|
|
.then(networkResponse => {
|
|
if (networkResponse.ok) {
|
|
caches.open(CACHE_NAME)
|
|
.then(cache => cache.put(request, networkResponse));
|
|
}
|
|
})
|
|
.catch(() => {})
|
|
);
|
|
return cachedResponse;
|
|
}
|
|
|
|
// Not in cache - fetch from network and cache
|
|
return fetch(request)
|
|
.then(networkResponse => {
|
|
if (networkResponse.ok) {
|
|
const responseToCache = networkResponse.clone();
|
|
caches.open(CACHE_NAME)
|
|
.then(cache => cache.put(request, responseToCache));
|
|
}
|
|
return networkResponse;
|
|
});
|
|
})
|
|
);
|
|
});
|