@@ -15,11 +15,7 @@ self.addEventListener('install', (event) => {
1515 event . waitUntil (
1616 caches . open ( STATIC_CACHE ) . then ( cache => {
1717 console . log ( 'Caching static assets' ) ;
18- const assets = [
19- '/' ,
20- '/index.html'
21- ] ;
22- return cache . addAll ( assets ) . catch ( err => {
18+ return cache . addAll ( STATIC_ASSETS ) . catch ( err => {
2319 console . warn ( 'Some static assets failed to cache:' , err ) ;
2420 } ) ;
2521 } )
@@ -49,52 +45,39 @@ self.addEventListener('activate', (event) => {
4945self . addEventListener ( 'fetch' , ( event ) => {
5046 const url = new URL ( event . request . url ) ;
5147
52- // Don't intercept non-GET requests to our own origin (they should go directly)
53- if ( url . origin === location . origin && event . request . method !== 'GET' ) {
48+ // Handle all GitHub API requests for any method
49+ if ( url . origin === GITHUB_API_BASE ) {
50+ event . respondWith ( handleGitHubRequest ( event . request ) ) ;
5451 return ;
5552 }
5653
57- // Handle all GitHub API requests
58- if ( url . origin === GITHUB_API_BASE ) {
59- event . respondWith ( handleGitHubRequest ( event . request ) ) ;
54+ if ( event . request . method !== 'GET' ) {
6055 return ;
6156 }
6257
63- // Allow external resources to pass through without caching scripts
64- // Only handle if method is GET
65- if ( event . request . method === 'GET' ) {
66- // For gravatar images - cache them, but let umnico and other scripts pass through
67- if ( ( url . hostname . includes ( 'gravatar.com' ) || url . hostname . includes ( 'www.gravatar.com' ) ) &&
68- event . request . destination === 'image' ) {
69- event . respondWith (
70- caches . open ( EXTERNAL_CACHE ) . then ( cache => {
71- return cache . match ( event . request ) . then ( cached => {
72- return fetch ( event . request )
73- . then ( response => {
74- if ( response && response . status === 200 ) {
75- cache . put ( event . request , response . clone ( ) ) ;
76- }
77- return response ;
78- } )
79- . catch ( ( ) => cached || new Response ( '' , { status : 204 } ) ) ;
80- } ) ;
81- } )
82- ) ;
83- return ;
84- }
58+ // Handle external gravatar images separately to support offline avatar caching
59+ if ( ( url . hostname === 'gravatar.com' || url . hostname === 'www.gravatar.com' ) &&
60+ event . request . destination === 'image' ) {
61+ event . respondWith ( handleGravatarRequest ( event . request ) ) ;
62+ return ;
63+ }
8564
86- // For umnico and other external resources - network only, don't cache scripts
87- if ( url . hostname . includes ( 'umnico.com' ) || url . hostname . includes ( 'www.umnico.com' ) ) {
88- event . respondWith (
89- fetch ( event . request )
90- . catch ( ( ) => new Response ( '' , { status : 204 } ) )
91- ) ;
92- return ;
93- }
65+ // Allow umnico scripts to load from network, but don't block the app
66+ if ( url . hostname === 'umnico.com' || url . hostname === 'www.umnico.com' ) {
67+ event . respondWith (
68+ fetch ( event . request ) . catch ( ( ) => new Response ( '' , { status : 204 } ) )
69+ ) ;
70+ return ;
71+ }
9472
95- // Handle static assets with network-first strategy
96- event . respondWith ( handleStaticRequest ( event . request ) ) ;
73+ // Handle page navigation and app shell requests
74+ if ( event . request . mode === 'navigate' || event . request . headers . get ( 'accept' ) ?. includes ( 'text/html' ) ) {
75+ event . respondWith ( handleNavigationRequest ( event . request ) ) ;
76+ return ;
9777 }
78+
79+ // Handle same-origin or other static GET requests
80+ event . respondWith ( handleStaticRequest ( event . request ) ) ;
9881} ) ;
9982
10083// Handle GitHub API requests - cache-first for offline support
@@ -105,12 +88,7 @@ async function handleGitHubRequest(request) {
10588 // For GET requests, check cache first
10689 if ( request . method === 'GET' ) {
10790 const cache = await caches . open ( GITHUB_API_CACHE ) ;
108- const cacheKey = new Request ( request . url , {
109- method : 'GET' ,
110- headers : new Headers ( { Accept : 'application/vnd.github+json' } )
111- } ) ;
112-
113- const cachedResponse = await cache . match ( cacheKey ) ;
91+ const cachedResponse = await cache . match ( request . url ) ;
11492 if ( cachedResponse ) {
11593 return cachedResponse . clone ( ) ;
11694 }
@@ -157,29 +135,28 @@ async function handleGitHubRequest(request) {
157135 }
158136}
159137
160- // Handle static requests - network -first, fallback to cache
138+ // Handle static requests - cache -first, fallback to network
161139async function handleStaticRequest ( request ) {
140+ const cache = await caches . open ( STATIC_CACHE ) ;
141+ const cachedResponse = await cache . match ( request ) ;
142+ if ( cachedResponse ) {
143+ return cachedResponse . clone ( ) ;
144+ }
145+
162146 try {
163147 const response = await fetch ( request ) ;
164148 if ( response . ok ) {
165- const cache = await caches . open ( STATIC_CACHE ) ;
166149 cache . put ( request , response . clone ( ) ) . catch ( err => {
167150 console . warn ( 'Failed to cache response:' , err ) ;
168151 } ) ;
169152 return response ;
170153 }
171154 throw new Error ( 'Network response not ok' ) ;
172155 } catch ( error ) {
173- const cached = await caches . match ( request ) ;
174- if ( cached ) {
175- return cached ;
176- }
177-
178- const navigationFallback = request . mode === 'navigate' || ( request . headers . get ( 'accept' ) ?. includes ( 'text/html' ) ) ;
179- if ( navigationFallback ) {
180- const shell = await caches . match ( '/index.html' ) ;
156+ if ( request . mode === 'navigate' || request . headers . get ( 'accept' ) ?. includes ( 'text/html' ) ) {
157+ const shell = await cache . match ( '/index.html' ) ;
181158 if ( shell ) {
182- return shell ;
159+ return shell . clone ( ) ;
183160 }
184161 }
185162
@@ -190,10 +167,61 @@ async function handleStaticRequest(request) {
190167 }
191168}
192169
170+ // Handle navigation requests with app shell fallback
171+ async function handleNavigationRequest ( request ) {
172+ const cache = await caches . open ( STATIC_CACHE ) ;
173+ const shell = await cache . match ( '/index.html' ) ;
174+ if ( shell ) {
175+ return shell . clone ( ) ;
176+ }
177+
178+ try {
179+ const response = await fetch ( request ) ;
180+ if ( response . ok ) {
181+ cache . put ( request , response . clone ( ) ) . catch ( err => {
182+ console . warn ( 'Failed to cache navigation response:' , err ) ;
183+ } ) ;
184+ return response ;
185+ }
186+ } catch ( error ) {
187+ console . warn ( 'Navigation fetch failed:' , error ) ;
188+ }
189+
190+ return new Response ( 'Offline - App shell unavailable' , {
191+ status : 503 ,
192+ statusText : 'Service Unavailable'
193+ } ) ;
194+ }
195+
196+ // Handle Gravatar image requests with cache-first strategy
197+ async function handleGravatarRequest ( request ) {
198+ const cache = await caches . open ( EXTERNAL_CACHE ) ;
199+ const cachedResponse = await cache . match ( request ) ;
200+ if ( cachedResponse ) {
201+ return cachedResponse . clone ( ) ;
202+ }
203+
204+ try {
205+ const response = await fetch ( request ) ;
206+ if ( response . ok ) {
207+ cache . put ( request , response . clone ( ) ) . catch ( err => {
208+ console . warn ( 'Failed to cache gravatar image:' , err ) ;
209+ } ) ;
210+ return response ;
211+ }
212+ throw new Error ( 'Network response not ok' ) ;
213+ } catch ( error ) {
214+ if ( cachedResponse ) {
215+ return cachedResponse . clone ( ) ;
216+ }
217+ return new Response ( '' , { status : 204 } ) ;
218+ }
219+ }
220+
193221// Try to return cached version when offline
194222async function tryOfflineFallback ( request ) {
195223 const cache = await caches . open ( GITHUB_API_CACHE ) ;
196- const cached = await cache . match ( request ) ;
224+ const cached = await cache . match ( request . url ) ;
197225 if ( cached ) {
198226 console . log ( 'Returning cached GitHub API response (offline)' ) ;
199227 return cached . clone ( ) ;
0 commit comments