// مظنه — service worker (slice 11, پ۱۱-۲). served by App\Http\Controllers\AppShellController::serviceWorker. // it keeps ONLY the shell and NEVER a price or an order answer: a stale price is wrong money. // · a page (navigation) ⇒ always the network; only when the network is gone, the kept «اتصال نیست» page // · a file of the shell ⇒ the kept copy (the build's names are hashed, so a kept file never goes stale) // · everything else ⇒ not touched: JSON reads, every POST, other origins go straight to the network const VERSION = {!! $versionJson !!}; const CACHE = 'mz-shell-' + VERSION; const OFFLINE = '/offline'; const SHELL = {!! $shellJson !!}; self.addEventListener('install', (event) => { event.waitUntil( caches.open(CACHE) // credentials omitted: the kept copies are the same for every person on this device .then((cache) => cache.addAll(SHELL.map((url) => new Request(url, { credentials: 'omit', cache: 'reload' })))) .then(() => self.skipWaiting()), ); }); self.addEventListener('activate', (event) => { event.waitUntil( caches.keys() .then((keys) => Promise.all(keys.filter((key) => key.startsWith('mz-shell-') && key !== CACHE).map((key) => caches.delete(key)))) .then(() => self.clients.claim()), ); }); const shellPaths = new Set(SHELL.map((url) => new URL(url, self.location.origin).pathname + new URL(url, self.location.origin).search)); self.addEventListener('fetch', (event) => { const request = event.request; if (request.method !== 'GET') { return; } const url = new URL(request.url); if (url.origin !== self.location.origin) { return; } if (request.mode === 'navigate') { event.respondWith(fetch(request).catch(() => caches.match(OFFLINE, { cacheName: CACHE }))); return; } if (url.pathname !== OFFLINE && shellPaths.has(url.pathname + url.search)) { event.respondWith(caches.match(request, { cacheName: CACHE }).then((kept) => kept || fetch(request))); } });