Spaces:
Running
Running
| // Service Worker for CryptoSphere PWA | |
| const CACHE_NAME = 'cryptosphere-tracker-v1.0.0'; | |
| const urlsToCache = [ | |
| '/crypto-tracker.html', | |
| '/crypto-style.css', | |
| '/crypto-script.js', | |
| '/components/crypto-navbar.js', | |
| '/components/crypto-footer.js', | |
| '/components/crypto-card.js', | |
| '/crypto-manifest.json' | |
| ]; | |
| // Install event | |
| self.addEventListener('install', (event) => { | |
| event.waitUntil( | |
| caches.open(CACHE_NAME) | |
| .then((cache) => { | |
| return cache.addAll(urlsToCache); | |
| }) | |
| ); | |
| }); | |
| // Activate event | |
| self.addEventListener('activate', (event) => { | |
| event.waitUntil( | |
| caches.keys().then((cacheNames) => { | |
| return Promise.all( | |
| cacheNames.map((cacheName) => { | |
| if (cacheName !== CACHE_NAME) { | |
| return caches.delete(cacheName); | |
| } | |
| }) | |
| ); | |
| }); | |
| // Fetch event with network-first strategy for crypto data | |
| self.addEventListener('fetch', (event) => { | |
| if (event.request.url.includes('api.coingecko.com')) { | |
| // Network-first for real-time crypto data | |
| event.respondWith( | |
| fetch(event.request) | |
| .then((response) => { | |
| // Cache the response | |
| const responseClone = response.clone(); | |
| caches.open(CACHE_NAME) | |
| .then((cache) => { | |
| cache.put(event.request, responseClone); | |
| }) | |
| .catch(() => { | |
| return caches.match(event.request); | |
| }) | |
| ); | |
| } else { | |
| // Cache-first for static assets | |
| event.respondWith( | |
| caches.match(event.request) | |
| .then((response) => { | |
| return response || fetch(event.request); | |
| }) | |
| ); | |
| } | |
| }); | |
| // Background sync for portfolio updates | |
| self.addEventListener('sync', (event) => { | |
| if (event.tag === 'portfolio-sync') { | |
| event.waitUntil(syncPortfolioData()); | |
| } | |
| }); | |
| }); | |
| async function syncPortfolioData() { | |
| // Sync portfolio data when connection is restored | |
| const db = await openCryptoDB(); | |
| const pendingUpdates = await db.getAll('pendingUpdates'); | |
| for (const update of pendingUpdates) { | |
| try { | |
| await fetch('/api/portfolio/update', { | |
| method: 'POST', | |
| body: JSON.stringify(update.data) | |
| }); | |
| await db.delete('pendingUpdates', update.id); | |
| } catch (error) { | |
| console.error('Background portfolio sync failed:', error); | |
| } | |
| } | |
| } | |
| // IndexedDB for offline crypto data storage | |
| function openCryptoDB() { | |
| return new Promise((resolve, reject) => { | |
| const request = indexedDB.open('CryptoSphereData', 2); | |
| request.onerror = () => reject(request.error); | |
| request.onsuccess = () => resolve(request.result); | |
| request.onupgradeneeded = (event) => { | |
| const db = event.target.result; | |
| // Create object store for crypto data | |
| if (!db.objectStoreNames.contains('cryptoData')) { | |
| const store = db.createObjectStore('cryptoData', { keyPath: 'id' }); | |
| store.createIndex('symbol', 'symbol', { unique: false }); | |
| store.createIndex('market_cap', 'market_cap', { unique: false }); | |
| // Create object store for portfolio | |
| if (!db.objectStoreNames.contains('portfolio')) { | |
| const portfolioStore = db.createObjectStore('portfolio', { keyPath: 'id' }); | |
| }; | |
| }); | |
| } |