/** * Hook for managing offline sync with local SQLite cache. */ import { useEffect, useState, useCallback, useRef } from "react"; import { useConvex } from "convex/react"; import { createSyncService, type SyncService, type SyncStatus } from "../db/syncService"; import { useHashCache } from "../context"; /** * Hook to manage sync service lifecycle and status. * Initializes local database, syncs with Convex, and provides hashes for recognition. */ export function useSync() { const convex = useConvex(); const syncServiceRef = useRef(null); const [status, setStatus] = useState({ isInitialized: false, isSyncing: false, lastSync: 0, localCardCount: 0, }); const { setCardHashes } = useHashCache(); // Initialize sync service useEffect(() => { if (!convex || syncServiceRef.current) return; const service = createSyncService(convex); syncServiceRef.current = service; // Subscribe to status changes const unsubscribe = service.onStatusChange(setStatus); // Initialize and load cached hashes const init = async () => { await service.initialize(); // Load cached hashes into app store const hashes = await service.getHashes(); if (hashes.length > 0) { setCardHashes(hashes); console.log(`[useSync] Loaded ${hashes.length} cached hashes`); } // Start background sync service.sync().then(async () => { // Reload hashes after sync const updatedHashes = await service.getHashes(); setCardHashes(updatedHashes); }); }; init(); return () => { unsubscribe(); }; }, [convex, setCardHashes]); // Manual sync trigger const sync = useCallback(async () => { if (!syncServiceRef.current) return; await syncServiceRef.current.sync(); // Reload hashes after sync const hashes = await syncServiceRef.current.getHashes(); setCardHashes(hashes); }, [setCardHashes]); // Clear local cache const clearCache = useCallback(async () => { if (!syncServiceRef.current) return; await syncServiceRef.current.clearLocalCache(); setCardHashes([]); }, [setCardHashes]); // Get current hashes from cache const getHashes = useCallback(async () => { if (!syncServiceRef.current) return []; return syncServiceRef.current.getHashes(); }, []); return { ...status, sync, clearCache, getHashes, }; } /** * Context-free sync initialization for use in _layout.tsx * Returns a component that initializes sync when mounted. */ export function SyncInitializer() { useSync(); return null; }