Skip to content

Commit 4ca062d

Browse files
committed
ft: cache sw with console
1 parent 4c05e41 commit 4ca062d

3 files changed

Lines changed: 76 additions & 3 deletions

File tree

public/sw.js

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ self.addEventListener('activate', (event) => {
3333
self.addEventListener('fetch', (event) => {
3434
const url = new URL(event.request.url);
3535

36-
// Only intercept GitHub API requests
37-
if (url.origin === GITHUB_API_BASE) {
36+
// Only intercept GitHub API GET requests to GitHub API
37+
if (url.origin === GITHUB_API_BASE && event.request.method === 'GET') {
3838
event.respondWith(handleGitHubRequest(event.request));
3939
}
4040
});
@@ -50,6 +50,19 @@ async function handleGitHubRequest(request) {
5050
return fetch(request);
5151
}
5252

53+
const cache = await caches.open(CACHE_NAME);
54+
const cacheKey = new Request(request.url, {
55+
method: request.method,
56+
headers: new Headers({
57+
Accept: 'application/vnd.github+json'
58+
})
59+
});
60+
61+
const cachedResponse = await cache.match(cacheKey);
62+
if (cachedResponse) {
63+
return cachedResponse.clone();
64+
}
65+
5366
// Create new request with authorization header
5467
const authHeaders = new Headers(request.headers);
5568
authHeaders.set('Authorization', `Bearer ${token}`);
@@ -61,8 +74,11 @@ async function handleGitHubRequest(request) {
6174

6275
// Make the request
6376
const response = await fetch(authRequest);
77+
if (response.ok) {
78+
const responseClone = response.clone();
79+
await cache.put(cacheKey, responseClone);
80+
}
6481

65-
// Return response (headers are sanitized by browser automatically)
6682
return response;
6783

6884
} catch (error) {
@@ -144,5 +160,14 @@ self.addEventListener('message', (event) => {
144160
const store = transaction.objectStore(TOKEN_STORE);
145161
store.delete('github-token');
146162
});
163+
} else if (event.data && event.data.type === 'CLEAR_CACHE') {
164+
caches.delete(CACHE_NAME).then(() => {
165+
console.log('Service Worker cache cleared:', CACHE_NAME);
166+
self.clients.matchAll().then(clients => {
167+
clients.forEach(client => {
168+
client.postMessage({ type: 'CACHE_CLEARED' });
169+
});
170+
});
171+
});
147172
}
148173
});

src/lib/github.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { config } from '../config/app';
2+
import { swManager } from './serviceWorker';
23
import { handleApiError } from './apiErrorHandler';
34

45
const { owner, repo, branch } = config.github;
@@ -129,6 +130,7 @@ sha?: string)
129130
}
130131
const data = await res.json();
131132
fileCache.set(path, { content, sha: data.content?.sha });
133+
await swManager.clearCache();
132134
return data;
133135
} catch (error: any) {
134136
handleApiError(error, 'putFile');
@@ -165,6 +167,7 @@ export async function deleteFile(path: string, message: string, sha: string) {
165167
throw await createGitHubError(res);
166168
}
167169
fileCache.delete(path);
170+
await swManager.clearCache();
168171
} catch (error: any) {
169172
handleApiError(error, 'deleteFile');
170173
}

src/lib/serviceWorker.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
// Service Worker Manager
22
// Handles registration and secure token storage in IndexedDB
33

4+
declare global {
5+
interface Window {
6+
clearGitHubApiCache?: () => Promise<void>;
7+
}
8+
}
9+
410
class ServiceWorkerManager {
511
private registration: ServiceWorkerRegistration | null = null;
612
private pendingToken: string | null = null;
13+
private pendingCacheClear = false;
714

815
async register(): Promise<void> {
916
if (!('serviceWorker' in navigator)) {
@@ -30,9 +37,19 @@ class ServiceWorkerManager {
3037
this.pendingToken = null;
3138
}
3239

40+
// Send any queued cache clear request once the worker is active
41+
if (this.pendingCacheClear && this.registration?.active) {
42+
this.sendCacheClear();
43+
this.pendingCacheClear = false;
44+
}
45+
3346
// Set up message handling
3447
navigator.serviceWorker.addEventListener('message', this.handleMessage.bind(this));
3548

49+
window.clearGitHubApiCache = async () => {
50+
await this.clearCache();
51+
};
52+
3653
} catch (error) {
3754
console.error('Service Worker registration failed:', error);
3855
}
@@ -80,6 +97,34 @@ class ServiceWorkerManager {
8097
}
8198
}
8299

100+
async clearCache(): Promise<void> {
101+
if (!this.registration?.active) {
102+
this.pendingCacheClear = true;
103+
return;
104+
}
105+
106+
try {
107+
this.sendCacheClear();
108+
} catch (error) {
109+
console.error('Failed to clear service worker cache:', error);
110+
}
111+
}
112+
113+
private sendCacheClear(): void {
114+
if (!this.registration?.active) {
115+
console.warn('Service worker not active, cannot clear cache');
116+
return;
117+
}
118+
119+
try {
120+
this.registration.active.postMessage({
121+
type: 'CLEAR_CACHE'
122+
});
123+
} catch (error) {
124+
console.error('Failed to send cache clear command to service worker:', error);
125+
}
126+
}
127+
83128
private handleMessage(event: MessageEvent): void {
84129
// Handle messages from service worker if needed
85130
if (event.data?.type === 'TOKEN_STORED') {

0 commit comments

Comments
 (0)