Spaces:
Building
Building
| /** | |
| * 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); | |
| } | |
| } | |
| }; | |