This commit is contained in:
DIGIDEV\corer committed 2026-10-20 13:16:38 +09:00
commit 3e4a056b14
67 files changed
+13926

No files matched your search

+75
View File
@@ -0,0 +1,75 @@
/*
* Offline copy of the public calculator (field staff often have weak signal).
* - The calculator page: network first (fresh parameters), stored copy when
* offline or slow. Responses marked no-store (admin views) are never kept.
* - Versioned assets (assets/...?v=): stored copy first.
* - calc.php, admin/ and everything else: network only, never stored.
*/
'use strict';
var CACHE = 'serubi-v1';
var PAGE_TIMEOUT_MS = 4000;
var SCOPE = self.registration.scope; // e.g. https://host/ or http://localhost/calcserubi-prod/
var PAGE_KEY = SCOPE; // one stored copy of the calculator, whatever the query string
self.addEventListener('install', function () { self.skipWaiting(); });
self.addEventListener('activate', function (event) {
event.waitUntil(caches.keys().then(function (keys) {
return Promise.all(keys.filter(function (k) { return k !== CACHE; }).map(function (k) { return caches.delete(k); }));
}).then(function () { return self.clients.claim(); }));
});
function isCalculatorPage(url) {
var rel = url.href.slice(SCOPE.length).split('?')[0];
return rel === '' || rel === 'index.php';
}
function storable(res) {
return res && res.ok && res.type === 'basic' && !/no-store/i.test(res.headers.get('Cache-Control') || '');
}
function pageNetworkFirst(request) {
return caches.open(CACHE).then(function (cache) {
var network = fetch(request).then(function (res) {
if (storable(res)) cache.put(PAGE_KEY, res.clone());
return res;
});
network.catch(function () { /* handled below */ });
var timeout = new Promise(function (resolve) { setTimeout(resolve, PAGE_TIMEOUT_MS); });
// slow network: answer from the stored copy after the timeout, if there is one
return Promise.race([network, timeout.then(function () { return cache.match(PAGE_KEY).then(function (c) { return c || network; }); })])
.catch(function () { return cache.match(PAGE_KEY).then(function (c) { if (c) return c; throw new Error('offline'); }); });
});
}
function assetCacheFirst(request) {
return caches.open(CACHE).then(function (cache) {
return cache.match(request).then(function (hit) {
if (hit) return hit;
return fetch(request).then(function (res) {
if (storable(res)) {
// keep only the newest version (?v=) of each asset
var path = new URL(request.url).pathname;
cache.keys().then(function (keys) {
keys.forEach(function (k) { if (new URL(k.url).pathname === path && k.url !== request.url) cache.delete(k); });
});
cache.put(request, res.clone());
}
return res;
});
});
});
}
self.addEventListener('fetch', function (event) {
var req = event.request;
if (req.method !== 'GET') return;
var url = new URL(req.url);
if (url.origin !== self.location.origin || req.url.indexOf(SCOPE) !== 0) return;
if (req.mode === 'navigate' && isCalculatorPage(url)) {
event.respondWith(pageNetworkFirst(req));
} else if (url.pathname.indexOf('/assets/') !== -1) {
event.respondWith(assetCacheFirst(req));
}
// anything else (calc.php, admin/, ...) goes straight to the network
});