feat: Add comprehensive documentation suite and reorganize project structure
- Created complete documentation in docs/ directory - Added PROJECT_OVERVIEW.md with feature highlights and getting started guide - Added ARCHITECTURE.md with system design and technical details - Added SECURITY.md with comprehensive security implementation guide - Added DEVELOPMENT.md with development workflows and best practices - Added DEPLOYMENT.md with production deployment instructions - Added API.md with complete REST API documentation - Added CONTRIBUTING.md with contribution guidelines - Added CHANGELOG.md with version history and migration notes - Reorganized all documentation files into docs/ directory for better organization - Updated README.md with proper documentation links and quick navigation - Enhanced project structure with professional documentation standards
This commit is contained in:
59
sw.js
Normal file
59
sw.js
Normal file
@@ -0,0 +1,59 @@
|
||||
// EasyStream Service Worker (lightweight, safe defaults)
|
||||
const CACHE_VERSION = 'es-v1';
|
||||
const STATIC_CACHE = `${CACHE_VERSION}-static`;
|
||||
const PRECACHE = [
|
||||
'/index.js',
|
||||
'/manifest.json'
|
||||
];
|
||||
|
||||
self.addEventListener('install', (event) => {
|
||||
event.waitUntil((async () => {
|
||||
const cache = await caches.open(STATIC_CACHE);
|
||||
await cache.addAll(PRECACHE);
|
||||
self.skipWaiting();
|
||||
})());
|
||||
});
|
||||
|
||||
self.addEventListener('activate', (event) => {
|
||||
event.waitUntil((async () => {
|
||||
const keys = await caches.keys();
|
||||
await Promise.all(keys.filter(k => !k.startsWith(CACHE_VERSION)).map(k => caches.delete(k)));
|
||||
self.clients.claim();
|
||||
})());
|
||||
});
|
||||
|
||||
self.addEventListener('fetch', (event) => {
|
||||
const url = event.request.url;
|
||||
// never cache uploads or HLS segments/manifests
|
||||
if (url.includes('upload') || url.includes('uploader') || url.includes('index.m3u8') || url.includes('.ts')) {
|
||||
return; // bypass SW
|
||||
}
|
||||
|
||||
// Navigation requests: network-first with cache fallback for basic offline shell
|
||||
if (event.request.mode === 'navigate') {
|
||||
event.respondWith((async () => {
|
||||
try {
|
||||
const fresh = await fetch(event.request);
|
||||
return fresh;
|
||||
} catch (e) {
|
||||
const cache = await caches.open(STATIC_CACHE);
|
||||
const shell = await cache.match('/index.js');
|
||||
return shell || Response.error();
|
||||
}
|
||||
})());
|
||||
return;
|
||||
}
|
||||
|
||||
// Others: stale-while-revalidate
|
||||
event.respondWith((async () => {
|
||||
const cached = await caches.match(event.request);
|
||||
const fetchPromise = fetch(event.request).then((networkResponse) => {
|
||||
if (networkResponse && networkResponse.ok && event.request.method === 'GET') {
|
||||
const copy = networkResponse.clone();
|
||||
caches.open(STATIC_CACHE).then((cache) => cache.put(event.request, copy)).catch(() => {});
|
||||
}
|
||||
return networkResponse;
|
||||
}).catch(() => cached);
|
||||
return cached || fetchPromise;
|
||||
})());
|
||||
});
|
||||
Reference in New Issue
Block a user