SCGR commited on
Commit
34b260a
·
1 Parent(s): 07aa61a
Files changed (1) hide show
  1. frontend/public/sw.js +58 -95
frontend/public/sw.js CHANGED
@@ -1,140 +1,103 @@
1
- const CACHE_NAME = 'promptaid-vision-v1';
2
- const STATIC_CACHE = 'static-v1';
3
- const DYNAMIC_CACHE = 'dynamic-v1';
4
 
5
- // Files to cache immediately - will be populated dynamically
6
- const STATIC_FILES = [
7
- '/',
8
- '/index.html',
9
- '/vite.svg'
10
- ];
 
 
 
 
 
 
11
 
12
- // Install event - cache static files
13
  self.addEventListener('install', (event) => {
14
  event.waitUntil(
15
- caches.open(STATIC_CACHE).then((cache) => {
16
- return cache.addAll(STATIC_FILES);
17
- })
18
  );
19
  self.skipWaiting();
20
  });
21
 
22
- // Activate event - clean up old caches
23
  self.addEventListener('activate', (event) => {
24
  event.waitUntil(
25
- caches.keys().then((cacheNames) => {
26
- return Promise.all(
27
- cacheNames.map((cacheName) => {
28
- if (cacheName !== STATIC_CACHE && cacheName !== DYNAMIC_CACHE) {
29
- return caches.delete(cacheName);
30
- }
31
  })
32
- );
33
- })
34
  );
35
  self.clients.claim();
36
  });
37
 
38
- // Fetch event - serve from cache, fallback to network
39
  self.addEventListener('fetch', (event) => {
40
  const { request } = event;
 
 
 
 
41
  const url = new URL(request.url);
42
 
43
- // Skip non-GET requests and non-HTTP(S) requests
44
- if (request.method !== 'GET' || (url.protocol !== 'http:' && url.protocol !== 'https:')) {
 
 
 
45
  return;
46
  }
47
 
48
- // Handle API requests - network first, cache fallback
49
  if (url.pathname.startsWith('/api/')) {
50
  event.respondWith(
51
  fetch(request)
52
- .then((response) => {
53
- // Cache successful API responses
54
- if (response.ok) {
55
- const responseClone = response.clone();
56
- caches.open(DYNAMIC_CACHE).then((cache) => {
57
- cache.put(request, responseClone);
58
- });
59
  }
60
- return response;
61
- })
62
- .catch(() => {
63
- // Fallback to cached response
64
- return caches.match(request);
65
  })
 
66
  );
67
  return;
68
  }
69
 
70
- // Handle static assets - cache first, network fallback
71
- if (url.pathname.startsWith('/assets/') || url.pathname.startsWith('/')) {
72
- event.respondWith(
73
- caches.match(request).then((cachedResponse) => {
74
- if (cachedResponse) {
75
- // Return cached version immediately
76
- return cachedResponse;
77
- }
78
 
79
- // Fetch from network and cache
80
- return fetch(request).then((response) => {
81
- if (response.ok) {
82
- const responseClone = response.clone();
83
- caches.open(STATIC_CACHE).then((cache) => {
84
- cache.put(request, responseClone);
85
- });
 
86
  }
87
- return response;
88
  });
89
  })
90
  );
91
  return;
92
  }
93
 
94
- // Default strategy - network first
95
  event.respondWith(
96
  fetch(request)
97
- .then((response) => {
98
- if (response.ok) {
99
- const responseClone = response.clone();
100
- caches.open(DYNAMIC_CACHE).then((cache) => {
101
- cache.put(request, responseClone);
102
- });
103
  }
104
- return response;
105
  })
106
- .catch(() => {
107
- return caches.match(request);
108
- })
109
- );
110
- });
111
-
112
- // Background sync for offline actions
113
- self.addEventListener('sync', (event) => {
114
- if (event.tag === 'background-sync') {
115
- event.waitUntil(doBackgroundSync());
116
- }
117
- });
118
-
119
- async function doBackgroundSync() {
120
- // Handle any pending offline actions
121
- console.log('Background sync triggered');
122
- }
123
-
124
- // Push notifications (if needed later)
125
- self.addEventListener('push', (event) => {
126
- const options = {
127
- body: event.data ? event.data.text() : 'New update available',
128
- icon: '/vite.svg',
129
- badge: '/vite.svg',
130
- vibrate: [100, 50, 100],
131
- data: {
132
- dateOfArrival: Date.now(),
133
- primaryKey: 1
134
- }
135
- };
136
-
137
- event.waitUntil(
138
- self.registration.showNotification('PromptAid Vision', options)
139
  );
140
  });
 
1
+ const STATIC_CACHE = 'static-v2';
2
+ const DYNAMIC_CACHE = 'dynamic-v2';
 
3
 
4
+ // Precache minimal shell (optional you can skip if serving hashed assets)
5
+ const PRECACHE = ['/', '/index.html', '/vite.svg'];
6
+
7
+ const isHttpGet = (req) => {
8
+ try {
9
+ if (req.method !== 'GET') return false;
10
+ const u = new URL(req.url);
11
+ return u.protocol === 'http:' || u.protocol === 'https:';
12
+ } catch {
13
+ return false;
14
+ }
15
+ };
16
 
 
17
  self.addEventListener('install', (event) => {
18
  event.waitUntil(
19
+ caches.open(STATIC_CACHE).then((cache) => cache.addAll(PRECACHE))
 
 
20
  );
21
  self.skipWaiting();
22
  });
23
 
 
24
  self.addEventListener('activate', (event) => {
25
  event.waitUntil(
26
+ caches.keys().then((names) =>
27
+ Promise.all(
28
+ names.map((n) => {
29
+ if (n !== STATIC_CACHE && n !== DYNAMIC_CACHE) return caches.delete(n);
 
 
30
  })
31
+ )
32
+ )
33
  );
34
  self.clients.claim();
35
  });
36
 
37
+ // Core fetch strategy
38
  self.addEventListener('fetch', (event) => {
39
  const { request } = event;
40
+
41
+ // Ignore non-GET or non-http(s)
42
+ if (!isHttpGet(request)) return;
43
+
44
  const url = new URL(request.url);
45
 
46
+ // 1) SPA navigation fallback: serve index.html for client routes
47
+ if (request.mode === 'navigate') {
48
+ event.respondWith(
49
+ fetch(request).catch(() => caches.match('/index.html'))
50
+ );
51
  return;
52
  }
53
 
54
+ // 2) API: Network-first, cache successful responses
55
  if (url.pathname.startsWith('/api/')) {
56
  event.respondWith(
57
  fetch(request)
58
+ .then((resp) => {
59
+ if (resp && resp.ok && isHttpGet(request)) {
60
+ const copy = resp.clone();
61
+ caches.open(DYNAMIC_CACHE).then((c) => c.put(request, copy));
 
 
 
62
  }
63
+ return resp;
 
 
 
 
64
  })
65
+ .catch(() => caches.match(request))
66
  );
67
  return;
68
  }
69
 
70
+ // 3) Static assets: Cache-first for script/style/image/font
71
+ const dest = request.destination;
72
+ const isAsset =
73
+ dest === 'script' || dest === 'style' || dest === 'image' || dest === 'font';
 
 
 
 
74
 
75
+ if (isAsset) {
76
+ event.respondWith(
77
+ caches.match(request).then((hit) => {
78
+ if (hit) return hit;
79
+ return fetch(request).then((resp) => {
80
+ if (resp && resp.ok && isHttpGet(request)) {
81
+ const copy = resp.clone();
82
+ caches.open(STATIC_CACHE).then((c) => c.put(request, copy));
83
  }
84
+ return resp;
85
  });
86
  })
87
  );
88
  return;
89
  }
90
 
91
+ // 4) Everything else: network-first with safe cache
92
  event.respondWith(
93
  fetch(request)
94
+ .then((resp) => {
95
+ if (resp && resp.ok && isHttpGet(request)) {
96
+ const copy = resp.clone();
97
+ caches.open(DYNAMIC_CACHE).then((c) => c.put(request, copy));
 
 
98
  }
99
+ return resp;
100
  })
101
+ .catch(() => caches.match(request))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  );
103
  });