Skip to main content
Back to Documentation

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
Data Modeldart
@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:

dart
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:

dart
SyncConfig(
  maxRetries: 3,
  retryDelay: Duration(seconds: 2),
  // Retry delays: 2s, 4s, 8s
)

Backend Adapters

SyncLayer uses the adapter pattern to support multiple backends:

dart
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:

1

Local Operation

User performs CRUD operation (save, update, delete)

2

Immediate Storage

Data saved to Isar database instantly

3

Queue Addition

Operation added to sync queue if online

4

Backend Sync

Queue processed and synced to backend

5

Conflict Check

Version comparison and conflict resolution

6

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

Learn More

Dive deeper into specific topics: