Files
edge-tts/web/sw.js
2025-12-02 12:22:06 +08:00

143 lines
4.1 KiB
JavaScript

// Service Worker for Edge TTS PWA
const CACHE_NAME = 'edge-tts-v1';
const urlsToCache = [
'/',
'/index.html',
'/styles.css',
'/app.js',
'/manifest.json',
'/icon-192.png',
'/icon-512.png'
];
// Install event - cache resources
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME)
.then((cache) => {
console.log('Opened cache');
return cache.addAll(urlsToCache.map(url => {
// Try to add each URL, but don't fail if some are missing
return cache.add(url).catch(err => {
console.log('Failed to cache:', url, err);
});
}));
})
.then(() => self.skipWaiting())
);
});
// Activate event - clean up old caches
self.addEventListener('activate', (event) => {
event.waitUntil(
caches.keys().then((cacheNames) => {
return Promise.all(
cacheNames.map((cacheName) => {
if (cacheName !== CACHE_NAME) {
console.log('Deleting old cache:', cacheName);
return caches.delete(cacheName);
}
})
);
}).then(() => self.clients.claim())
);
});
// Fetch event - serve from cache, fallback to network
self.addEventListener('fetch', (event) => {
const { request } = event;
// Skip API requests - always go to network
if (request.url.includes('/api/')) {
event.respondWith(
fetch(request)
.catch(() => {
return new Response(
JSON.stringify({ error: 'Network unavailable' }),
{
status: 503,
headers: { 'Content-Type': 'application/json' }
}
);
})
);
return;
}
// Cache-first strategy for static assets
event.respondWith(
caches.match(request)
.then((response) => {
// Cache hit - return response
if (response) {
return response;
}
// Clone the request
const fetchRequest = request.clone();
return fetch(fetchRequest).then((response) => {
// Check if valid response
if (!response || response.status !== 200 || response.type !== 'basic') {
return response;
}
// Clone the response
const responseToCache = response.clone();
// Cache the new resource
caches.open(CACHE_NAME)
.then((cache) => {
cache.put(request, responseToCache);
});
return response;
});
})
.catch(() => {
// Return offline page or error
return new Response('Offline', {
status: 503,
statusText: 'Service Unavailable'
});
})
);
});
// Background sync for offline TTS generation (future enhancement)
self.addEventListener('sync', (event) => {
if (event.tag === 'sync-tts') {
event.waitUntil(syncTTS());
}
});
async function syncTTS() {
// Placeholder for future offline TTS queue functionality
console.log('Syncing pending TTS requests...');
}
// Push notifications (future enhancement)
self.addEventListener('push', (event) => {
const data = event.data.json();
const options = {
body: data.body,
icon: '/icon-192.png',
badge: '/icon-192.png',
vibrate: [200, 100, 200]
};
event.waitUntil(
self.registration.showNotification(data.title, options)
);
});
// Notification click handler
self.addEventListener('notificationclick', (event) => {
event.notification.close();
event.waitUntil(
clients.openWindow('/')
);
});