/** * Synchronization Service * Migrated from Angular sync.service.ts * Handles offline-online data synchronization */ const syncService = { isSyncing: false, syncInterval: null, /** * Initialize sync service */ async init() { console.log('Sync service initializing...'); // Listen for online/offline events window.addEventListener('online', () => { console.log('Connection restored, syncing...'); this.syncNow().catch(err => console.error('Auto-sync online failed:', err)); }); window.addEventListener('offline', () => { console.log('Connection lost, working offline'); }); // Auto-sync every 5 minutes when online this.syncInterval = setInterval(() => { if (navigator.onLine) { this.syncNow().catch(err => console.error('Periodic auto-sync failed:', err)); } }, 5 * 60 * 1000); // Initial sync if online - wrapped in try-catch for stability if (navigator.onLine) { try { await this.syncNow(); } catch (error) { console.warn('Initial sync failed (offline mode fallback):', error); } } }, /** * Sync unsynced captures to backend */ async syncNow() { if (this.isSyncing || !navigator.onLine) { return; } this.isSyncing = true; try { const unsyncedCaptures = await dbService.getUnsyncedCaptures(); if (unsyncedCaptures.length === 0) { console.log('No captures to sync'); this.isSyncing = false; return; } console.log(`Syncing ${unsyncedCaptures.length} captures...`); const result = await apiService.syncCaptures(unsyncedCaptures); // Update sync status for successfully synced captures for (const id of result.synced) { await dbService.updateSyncStatus(id, true); } console.log(`Successfully synced ${result.synced.length} captures`); // Dispatch event for UI updates window.dispatchEvent(new CustomEvent('syncComplete', { detail: { synced: result.synced.length, errors: result.errors ? result.errors.length : 0 } })); } catch (error) { console.error('Sync failed:', error); throw error; // Re-throw to allow init() to catch it } finally { this.isSyncing = false; } }, /** * Get sync status */ async getSyncStatus() { try { const unsyncedCount = (await dbService.getUnsyncedCaptures()).length; return { isOnline: navigator.onLine, isSyncing: this.isSyncing, unsyncedCount: unsyncedCount }; } catch (error) { console.warn('Could not get sync status from DB:', error); return { isOnline: navigator.onLine, isSyncing: this.isSyncing, unsyncedCount: 0 }; } }, /** * Stop sync service */ stop() { if (this.syncInterval) { clearInterval(this.syncInterval); } } };