feat: enhance offline support with improved network management and sync handling

This commit is contained in:
Mo Tarbin
2026-06-06 00:58:18 -04:00
parent 24118e0dc3
commit 4e0b5d79df
9 changed files with 219 additions and 29 deletions

View File

@@ -10,6 +10,7 @@ import { networkManager } from './NetworkManager'
const PENDING_POLL_MS = 30_000 // retry pending commands every 30s
const CACHE_REFRESH_MS = 5 * 60_000 // refresh IDB cache every 5 min while online
const SERVER_PROBE_MS = 15_000 // probe server when marked unreachable but device has network
export function useSyncOnReconnect() {
const queryClient = useQueryClient()
@@ -18,6 +19,7 @@ export function useSyncOnReconnect() {
useEffect(() => {
let pendingPollInterval
let cacheRefreshInterval
let serverProbeInterval
let resumeListener
let networkListener
const handleVisibilityChange = () => {
@@ -77,13 +79,27 @@ export function useSyncOnReconnect() {
cacheRefreshInterval = setInterval(() => {
runSync()
}, CACHE_REFRESH_MS)
// 6. Probe server every 15s when server is unreachable but device has network
serverProbeInterval = setInterval(async () => {
if (!networkManager.isOnline && networkManager.deviceOnline) {
await runSync()
}
}, SERVER_PROBE_MS)
}
const runSync = async () => {
if (!isOfflineFeatureEnabled()) return
const wasOffline = !networkManager.isOnline
const didSync = await syncEngine.sync()
if (didSync) {
queryClient.invalidateQueries()
// After recovery from server-unreachable, run a second pass to flush
// any commands that were skipped while offline
if (wasOffline && networkManager.isOnline) {
const didSync2 = await syncEngine.sync()
if (didSync2) queryClient.invalidateQueries()
}
}
}
@@ -98,6 +114,10 @@ export function useSyncOnReconnect() {
clearInterval(cacheRefreshInterval)
}
if (serverProbeInterval) {
clearInterval(serverProbeInterval)
}
if (networkListener) {
networkManager.unregisterNetworkListener(networkListener)
}