Architecture
Understanding SyncLayer's technical architecture and design patterns
Overview
SyncLayer is built on a three-layer architecture designed for offline-first applications:
Local Storage
- •Isar Database
- •Offline Queue
- •Version Tracking
Sync Engine
- •Event System
- •Conflict Resolution
- •Auto-Retry
Backend Layer
- •REST Adapter
- •Firebase
- •Supabase
Local Storage Layer
The foundation of SyncLayer is built on Isar, a high-performance NoSQL database for Flutter.
- ✓Zero-copy object access for maximum performance
- ✓ACID compliance for data integrity
- ✓Automatic indexing for fast queries
- ✓Version tracking for conflict detection
- ✓Offline queue for pending operations
@collection
class SyncEntity {
Id id = Isar.autoIncrement;
late String collectionName;
late String entityId;
late String data; // JSON string
late int version;
late DateTime lastModified;
late bool isSynced;
}Sync Engine
The sync engine is event-driven and handles all synchronization logic:
Event System
All operations emit events that you can listen to:
SyncLayer.events.listen((event) {
if (event is SyncStartedEvent) {
// Sync started
} else if (event is SyncCompletedEvent) {
// Sync completed successfully
} else if (event is SyncErrorEvent) {
// Handle sync error
} else if (event is ConflictDetectedEvent) {
// Conflict detected
}
});Conflict Resolution
Three built-in strategies for handling conflicts:
Last Write Wins
The most recent modification (by timestamp) takes precedence
Best for: Simple apps, single-user scenarios
Server Wins
Server data always overrides local changes
Best for: Read-heavy apps, authoritative server
Client Wins
Local changes always override server data
Best for: Offline-first apps, user autonomy
Retry Logic
Intelligent retry with exponential backoff:
SyncConfig(
maxRetries: 3,
retryDelay: Duration(seconds: 2),
// Retry delays: 2s, 4s, 8s
)Backend Adapters
SyncLayer uses the adapter pattern to support multiple backends:
abstract class BackendAdapter {
Future<Map<String, dynamic>> pull(
String collection,
DateTime? lastSync,
);
Future<void> push(
String collection,
List<Map<String, dynamic>> changes,
);
Future<void> delete(
String collection,
String id,
);
}Built-in adapters:
REST Adapter
Standard HTTP REST API with configurable endpoints
Firebase Adapter
Cloud Firestore integration with real-time updates
Supabase Adapter
PostgreSQL-backed with real-time subscriptions
Appwrite Adapter
Self-hosted backend with built-in auth
Data Flow
Understanding how data flows through SyncLayer:
Local Operation
User performs CRUD operation (save, update, delete)
Immediate Storage
Data saved to Isar database instantly
Queue Addition
Operation added to sync queue if online
Backend Sync
Queue processed and synced to backend
Conflict Check
Version comparison and conflict resolution
Update Local
Local database updated with resolved data
Performance Considerations
- ✓Batch operations for improved throughput
- ✓Lazy loading for large datasets
- ✓Indexed queries for fast lookups
- ✓Debounced sync to reduce network calls
- ✓Compression for network transfers