const CACHE_NAME = 'media-player-cache-v1'; let cachedFiles = [ '/index.html', '/index.html?mode=t', '/v.mp4', '/t/v.mp4', '/p.mp3', '/s.mp3', '/a.mp3', '/t.mp3', '/k.mp3', '/t/p.mp3', '/t/s.mp3', '/t/a.mp3', '/t/t.mp3', '/t/k.mp3' ]; // install: ファイルを個別にキャッシュ self.addEventListener('install', (event) => { event.waitUntil( caches.open(CACHE_NAME).then(async cache => { console.log('キャッシュを追加中:', cachedFiles); await Promise.allSettled( cachedFiles.map(file => cache.add(file).catch(err => console.warn(`キャッシュ失敗: ${file}`, err)) ) ); }) ); }); // fetch: キャッシュ優先 self.addEventListener('fetch', (event) => { event.respondWith( caches.match(event.request).then(response => { return response || fetch(event.request); }) ); }); // message: 動的にファイルを更新する場合の処理 self.addEventListener('message', (event) => { if (event.data?.type === 'CACHE_FILES') { const files = event.data.files || []; cachedFiles = ['/index.html', ...files]; event.waitUntil( caches.open(CACHE_NAME).then(async cache => { await Promise.allSettled( cachedFiles.map(file => cache.add(file).catch(err => console.warn(`キャッシュ失敗: ${file}`, err)) ) ); const keys = await cache.keys(); const validPaths = new Set(cachedFiles); for (const request of keys) { const path = new URL(request.url).pathname; if (!validPaths.has(path)) { await cache.delete(request); } } }) ); } });