Offline & Sync - Quick Reference
Phase 17 Quick Reference | Version 0.9.0
1. Basic Offline Message Queue
import { offlineDB } from '@/lib/offline/indexeddb'
// Queue a message
await offlineDB . addToMessageQueue ( {
id : 'temp-123' ,
channelId : 'channel-1' ,
content : 'Hello offline!' ,
contentType : 'text' ,
createdAt : Date . now ( ) ,
attempts : 0 ,
status : 'pending' ,
} )
// Get queue
const queue = await offlineDB . getMessageQueue ( 'pending' )
import { useOptimisticMessages } from '@/hooks/use-optimistic-messages'
const { sendMessage, optimisticMessages } = useOptimisticMessages ( 'channel-1' )
await sendMessage ( {
channelId : 'channel-1' ,
content : 'Instant UI update!' ,
} )
import { useSettingsSync } from '@/hooks/use-settings-sync'
const { settings, updateSettings } = useSettingsSync ( )
await updateSettings ( {
theme : { preset : 'dark' } ,
} )
// Register background sync
if ( 'serviceWorker' in navigator ) {
const reg = await navigator . serviceWorker . ready
await reg . sync . register ( 'sync-messages' )
}
Send Message with Attachments
const { sendMessage } = useOptimisticMessages ( )
const files = [ new File ( [ 'content' ] , 'doc.pdf' ) ]
await sendMessage ( {
channelId : 'channel-1' ,
content : 'Check this out!' ,
attachments : files ,
} )
import { syncService } from '@/lib/offline/sync-service'
// Get failed messages
const stats = await syncService . getQueueStats ( )
console . log ( 'Failed:' , stats . messages . failed )
// Retry all
await syncService . retryFailed ( )
import { ConflictResolver } from '@/lib/offline/conflict-resolver'
const resolver = new ConflictResolver ( )
// Auto-resolve
const resolution = await resolver . autoResolve ( conflict )
// Manual resolve
const resolution = await resolver . resolve ( conflict , 'local_wins' )
const estimate = await offlineDB . getStorageEstimate ( )
console . log ( `Using ${ estimate . percent . toFixed ( 2 ) } % of quota` )
import { OfflineIndicator } from '@/components/ui/offline-indicator'
; < OfflineIndicator position = "top" detailed />
import { OfflineQueueViewer } from '@/components/offline/offline-queue-viewer'
; < OfflineQueueViewer asDialog open = { show } onClose = { ( ) => setShow ( false ) } />
Hook
Purpose
useOptimisticMessages
Optimistic message updates
useSettingsSync
Settings synchronization
useOfflineStatus
Connection status
Endpoint
Method
Purpose
/api/messages
POST
Send message
/api/upload
POST
Upload file
/api/users/:id/settings
GET/PUT
Sync settings
pending - Queued, waiting to send
syncing - Currently sending
sent - Successfully delivered
failed - Failed to send
pending - Queued for upload
uploading - Currently uploading
uploaded - Upload complete
failed - Upload failed
idle - No sync in progress
syncing - Sync in progress
paused - Sync paused
error - Sync failed
concurrent_edit - Same item edited on multiple devices
delete_edit - Deleted on one device, edited on another
duplicate - Duplicate creation
version_mismatch - Version conflict
last_write_wins - Use most recent
server_wins - Use server version
client_wins - Use local version
merge - Merge changes
user_prompt - Ask user
syncService . addListener ( ( status , progress ) => {
console . log ( 'Status:' , status )
if ( progress ) {
console . log ( `${ progress . completed } /${ progress . total } ` )
}
} )
navigator . serviceWorker . addEventListener ( 'message' , ( event ) => {
switch ( event . data . type ) {
case 'SYNC_STARTED' :
case 'SYNC_COMPLETED' :
case 'SYNC_FAILED' :
// Handle event
}
} )
syncService . configure ( {
maxRetries : 3 , // Max retry attempts
retryDelay : 1000 , // Initial delay (ms)
maxRetryDelay : 30000 , // Max delay (ms)
batchSize : 10 , // Items per batch
} )
// Start (every 30s)
syncService . startAutoSync ( 30000 )
// Stop
syncService . stopAutoSync ( )
const queue = await offlineDB . getMessageQueue ( )
console . table ( queue )
const conflicts = await offlineDB . getConflicts ( )
console . log ( 'Conflicts:' , conflicts . length )
await syncService . clearQueues ( )
await offlineDB . clearAll ( )
Batch Operations - Process multiple items together
Debounce Updates - Don't sync on every change
Limit Cache - Keep cache size < 50MB
Clean Up - Remove old data periodically
Monitor Storage - Check getStorageEstimate()
Feature
Support
IndexedDB
All modern browsers
Service Workers
All modern browsers
Background Sync
Chrome, Edge only
Periodic Sync
Chrome, Edge only
try {
await sendMessage ( { channelId, content } )
} catch ( error ) {
if ( ! navigator . onLine ) {
// Will auto-retry when online
} else {
// Show error to user
toast . error ( 'Failed to send message' )
}
}
# Run tests
npm test offline
# Chrome DevTools
# Network tab -> Throttling -> Offline
# Application tab -> Service Workers -> Sync
// Initialize
await offlineDB . init ( )
// Queue message
await offlineDB . addToMessageQueue ( msg )
// Sync
await syncService . sync ( )
// Stats
await syncService . getQueueStats ( )
// Retry
await syncService . retryFailed ( )
// Cleanup
syncService . destroy ( )
offlineDB . close ( )