@@ -112,47 +112,112 @@ public function serviceWorker(): \Illuminate\Http\Response
112112 {
113113 $ serviceWorkerContent = "
114114// Service Worker for Catch-Em-All PWA
115- const CACHE_NAME = 'catch-em-all-v1';
116- const urlsToCache = [
117- '/',
118- '/auth/login',
119- '/leaderboard',
120- '/collection',
121- '/achievements'
115+ const CACHE_VERSION = 'v1';
116+ const CACHE_NAME = `catch-em-all- \${CACHE_VERSION}`;
117+ const STATIC_CACHE_NAME = `catch-em-all-static- \${CACHE_VERSION}`;
118+
119+ // Only cache static assets that don't change often
120+ const STATIC_ASSETS = [
121+ '/manifest.json',
122+ '/icons/icon-72x72.png',
123+ '/icons/icon-96x96.png',
124+ '/icons/icon-128x128.png',
125+ '/icons/icon-144x144.png',
126+ '/icons/icon-152x152.png',
127+ '/icons/icon-192x192.png',
128+ '/icons/icon-384x384.png',
129+ '/icons/icon-512x512.png'
122130];
123131
124132self.addEventListener('install', function(event) {
133+ // Pre-cache static assets only
125134 event.waitUntil(
126- caches.open(CACHE_NAME )
135+ caches.open(STATIC_CACHE_NAME )
127136 .then(function(cache) {
128- return cache.addAll(urlsToCache );
137+ return cache.addAll(STATIC_ASSETS );
129138 })
130139 );
131- });
132-
133- self.addEventListener('fetch', function(event) {
134- event.respondWith(
135- caches.match(event.request)
136- .then(function(response) {
137- // Return cached version or fetch from network
138- return response || fetch(event.request);
139- }
140- )
141- );
140+ // Force the new service worker to activate
141+ self.skipWaiting();
142142});
143143
144144self.addEventListener('activate', function(event) {
145145 event.waitUntil(
146146 caches.keys().then(function(cacheNames) {
147147 return Promise.all(
148148 cacheNames.map(function(cacheName) {
149- if (cacheName !== CACHE_NAME) {
149+ // Delete old cache versions
150+ if (cacheName.startsWith('catch-em-all-') &&
151+ cacheName !== CACHE_NAME &&
152+ cacheName !== STATIC_CACHE_NAME) {
150153 return caches.delete(cacheName);
151154 }
152155 })
153156 );
154157 })
155158 );
159+ // Take control of all pages immediately
160+ self.clients.claim();
161+ });
162+
163+ self.addEventListener('fetch', function(event) {
164+ const { request } = event;
165+ const url = new URL(request.url);
166+
167+ // Skip non-GET requests
168+ if (request.method !== 'GET') {
169+ return;
170+ }
171+
172+ // Skip cross-origin requests
173+ if (url.origin !== location.origin) {
174+ return;
175+ }
176+
177+ // Network-first strategy for API and dynamic content
178+ if (url.pathname.startsWith('/api/') ||
179+ url.pathname.startsWith('/catch') ||
180+ url.pathname.startsWith('/auth/') ||
181+ request.headers.get('accept')?.includes('application/json')) {
182+ event.respondWith(
183+ fetch(request)
184+ .catch(() => {
185+ // If network fails, try cache as fallback
186+ return caches.match(request);
187+ })
188+ );
189+ return;
190+ }
191+
192+ // Cache-first strategy for static assets
193+ if (url.pathname.startsWith('/icons/') ||
194+ url.pathname.startsWith('/build/') ||
195+ url.pathname === '/manifest.json') {
196+ event.respondWith(
197+ caches.match(request)
198+ .then(function(response) {
199+ return response || fetch(request).then(function(response) {
200+ // Cache successful responses
201+ if (response.status === 200) {
202+ const responseClone = response.clone();
203+ caches.open(STATIC_CACHE_NAME).then(function(cache) {
204+ cache.put(request, responseClone);
205+ });
206+ }
207+ return response;
208+ });
209+ })
210+ );
211+ return;
212+ }
213+
214+ // Default: network-first for everything else
215+ event.respondWith(
216+ fetch(request)
217+ .catch(() => {
218+ return caches.match(request);
219+ })
220+ );
156221});
157222 " ;
158223
0 commit comments