Files
archy/packages/app/src/composables/useOffline.ts
T
DorianandClaude Opus 4.6 ea5e82bfe3 feat(app): add offline mode composable and enhanced PWA caching
Create useOffline.ts with online/offline detection, sync queue for
pending actions, and auto-process on reconnect. Enhance vite PWA config
with CacheFirst for TMDB and Wikipedia images, StaleWhileRevalidate for
TMDB API responses, with size and TTL limits.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 21:08:50 +00:00

76 lines
1.7 KiB
TypeScript

import { ref, onMounted, onUnmounted } from 'vue'
export interface SyncAction {
type: string
payload: unknown
timestamp: number
}
const isOnline = ref(navigator.onLine)
const pendingSync = ref(0)
const syncQueue: SyncAction[] = []
function handleOnline() {
isOnline.value = true
processSyncQueue()
}
function handleOffline() {
isOnline.value = false
}
/** Queue an action to be synced when back online */
function queueForSync(action: SyncAction) {
syncQueue.push(action)
pendingSync.value = syncQueue.length
}
/** Process all pending sync actions */
async function processSyncQueue(): Promise<void> {
if (!isOnline.value || syncQueue.length === 0) return
while (syncQueue.length > 0) {
const action = syncQueue.shift()
if (!action) break
try {
// Route sync actions based on type
if (action.type === 'conversation') {
// Conversation sync handled by idb-storage auto-save
continue
}
if (action.type === 'favorite') {
// Favorites are local-only, no sync needed
continue
}
// Add more sync handlers as needed
} catch {
// Re-queue failed actions
syncQueue.unshift(action)
break
}
}
pendingSync.value = syncQueue.length
}
export function useOffline() {
onMounted(() => {
window.addEventListener('online', handleOnline)
window.addEventListener('offline', handleOffline)
isOnline.value = navigator.onLine
})
onUnmounted(() => {
window.removeEventListener('online', handleOnline)
window.removeEventListener('offline', handleOffline)
})
return {
isOnline,
pendingSync,
queueForSync,
processSyncQueue,
}
}