const CACHE_NAME = 'dance-video-cache-v' + new Date().getTime(); // 毎回異なるキャッシュ名 const ASSETS_TO_CACHE = [ '/', '/index.html', '/videos/k-back-human.mp4', '/videos/k-back-stick-human.mp4', '/videos/k-back-stick.mp4', '/videos/k-human.mp4', '/videos/k-stick-human.mp4', '/videos/m-back-human.mp4', '/videos/m-back-stick-human.mp4', '/videos/m-back-stick.mp4', '/videos/m-human.mp4', '/videos/m-stick-human.mp4', '/videos/e-back-human.mp4', '/videos/e-back-stick-human.mp4', '/videos/e-back-stick.mp4', '/videos/e-human.mp4', '/videos/e-stick-human.mp4' ]; self.addEventListener('install', event => { self.skipWaiting(); // 新しいSWを即時アクティベート event.waitUntil( caches.open(CACHE_NAME) .then(cache => { console.log('Opened cache'); return cache.addAll(ASSETS_TO_CACHE.map(url => new Request(url, {cache: 'reload'}))); }) .catch(error => console.log('Cache addAll error:', error)) ); }); 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()) // すべてのクライアントを制御 ); }); self.addEventListener('fetch', event => { // 外部リソースはキャッシュしない if (event.request.url.startsWith('http') && !event.request.url.startsWith(self.location.origin)) { event.respondWith(fetch(event.request)); return; } event.respondWith( caches.match(event.request) .then(response => { // キャッシュがあれば返す、なければフェッチしてキャッシュ return response || fetch(event.request).then(response => { // クローンを作成(ストリームは一度しか読めないため) const responseToCache = response.clone(); caches.open(CACHE_NAME) .then(cache => cache.put(event.request, responseToCache)); return response; }); }) .catch(error => { console.log('Fetch failed; returning offline page:', error); return caches.match('/offline.html'); // オフラインページがあれば }) ); });