cloud_sync 0.4.0-rc.2 copy "cloud_sync: ^0.4.0-rc.2" to clipboard
cloud_sync: ^0.4.0-rc.2 copied to clipboard

A Dart library for synchronizing files between local and cloud storage using customizable metadata and file handlers, with progress callbacks and error handling.

CloudSync #

A robust, type-safe synchronization solution for Dart applications

Pub Version License: MIT style: very good analysis

๐Ÿ” Overview #

CloudSync is a flexible, bidirectional sync engine for Dart that helps keep your local and cloud data perfectly in sync. It supports adapter-based or functional APIs, progress tracking, concurrent operations, and robust cancellation.


๐Ÿš€ Features #

  • ๐Ÿ”„ Bidirectional Sync โ€” Sync in both directions (local โ†” cloud)
  • โฑ Conflict Resolution โ€” Timestamp-based "latest wins" strategy
  • ๐Ÿ“Š Detailed State Tracking โ€” 12 sync states for full visibility
  • ๐Ÿ›  Adapter or Functional API โ€” Choose what suits your architecture
  • โšก Concurrent Processing โ€” Parallel operations for better performance
  • โณ Auto-Sync Support โ€” Periodic background syncing
  • โœ‹ Cancelable Syncs โ€” Graceful cancellation at any stage
  • ๐Ÿงน Lifecycle Management โ€” dispose() cleanup support
  • ๐Ÿ›ก Error Handling โ€” Built-in reporting and recovery

๐Ÿ“ฆ Installation #

In your pubspec.yaml:

dependencies:
  cloud_sync: ^<latest_version>

Then run:

flutter pub get

๐Ÿงญ Quick Start #

Using Adapters #

final cloudSync = CloudSync<FileMetadata, FileData>.fromAdapters(
  localAdapter,
  cloudAdapter,
);

await cloudSync.sync(
  progressCallback: (state) {
    if (state is SyncCompleted) {
      print('โœ… Sync completed!');
    } else if (state is SyncError) {
      print('โŒ Sync failed: ${state.error}');
    }
  },
);

Enable Auto-Sync #

cloudSync.autoSync(
  interval: Duration(minutes: 5),
  progressCallback: handleSyncProgress,
);

Clean Up #

await cloudSync.dispose();

โš™๏ธ Core Architecture #

SyncMetadata Model #

abstract class SyncMetadata {
  final String id;
  final DateTime modifiedAt;
  final bool isDeleted;
}

Sync Flow #

  1. Metadata Fetching โ€” Get metadata from both sources
  2. Diff Detection โ€” Timestamp-based comparison
  3. Conflict Resolution โ€” Apply "latest wins" logic
  4. Sync Execution โ€” Upload/download data accordingly
  5. State Updates โ€” Progress tracked via SyncState

๐Ÿงฑ Implementation Options #

class LocalHiveAdapter implements SyncAdapter<NoteMetadata, Note> {
  @override
  Future<List<NoteMetadata>> fetchMetadataList() => metadataBox.values.toList();

  @override
  Future<Note> fetchDetail(NoteMetadata meta) async => notesBox.get(meta.id)!;

  @override
  Future<void> save(NoteMetadata meta, Note note) async {
    await notesBox.put(meta.id, note);
    await metadataBox.put(meta.id, meta);
  }
}

2. Functional Injection #

final cloudSync = CloudSync<PhotoMetadata, Photo>(
  fetchLocalMetadataList: localDb.getPhotoMetadata,
  fetchCloudMetadataList: cloudApi.getPhotoMetadata,
  fetchLocalDetail: (m) => localDb.getPhoto(m.id),
  fetchCloudDetail: (m) => cloudApi.downloadPhoto(m.id),
  saveToLocal: localDb.savePhoto,
  saveToCloud: cloudApi.uploadPhoto,
);

๐Ÿ“ถ Sync States #

State Description
InProgress Sync already running
FetchingLocalMetadata Fetching local metadata
FetchingCloudMetadata Fetching cloud metadata
ScanningLocal Scanning local for changes
ScanningCloud Scanning cloud for changes
SavingToLocal Downloading to local
SavedToLocal Local save complete
SavingToCloud Uploading to cloud
SavedToCloud Cloud save complete
SyncCompleted All sync steps finished
SyncError An error occurred
SyncCancelled Sync was cancelled

๐Ÿง  Advanced Usage #

Progress Tracking #

void handleSyncState(SyncState state) {
  switch (state) {
    case SavingToCloud(metadata: final meta):
      showUploading(meta.filename);
    case SyncError(error: final err):
      logError(err.toString());
    case SyncCompleted():
      showSuccess('Sync complete!');
    // handle other states...
  }
}

Concurrent Sync #

await cloudSync.sync(
  useConcurrentSync: true,
  progressCallback: handleSyncState,
);

Auto-Sync Control #

cloudSync.autoSync(
  interval: Duration(minutes: 15),
  progressCallback: handleSyncState,
);

await cloudSync.stopAutoSync(); // Stop it

Cancel Ongoing Sync #

await cloudSync.cancelSync(); // Triggers SyncCancelled

๐Ÿงช Best Practices #

  • Always call dispose() when done
  • Handle all SyncStates in your UI for clear feedback
  • Enable useConcurrentSync for large datasets
  • Wrap sync in a try/catch for reliability
try {
  await cloudSync.sync();
} on SyncDisposedError {
  // Already disposed
} catch (e) {
  handleUnexpectedError(e);
}

๐Ÿงพ Example: Metadata Class #

class DocumentMetadata extends SyncMetadata {
  final String title;
  final int version;

  DocumentMetadata({
    required super.id,
    required super.modifiedAt,
    required this.title,
    this.version = 1,
    super.isDeleted = false,
  });

  @override
  DocumentMetadata copyWith({
    String? id,
    DateTime? modifiedAt,
    String? title,
    int? version,
    bool? isDeleted,
  }) {
    return DocumentMetadata(
      id: id ?? this.id,
      modifiedAt: modifiedAt ?? this.modifiedAt,
      title: title ?? this.title,
      version: version ?? this.version,
      isDeleted: isDeleted ?? this.isDeleted,
    );
  }
}

๐Ÿ“„ License #

MIT License โ€” See LICENSE for full details.


๐Ÿค Contributing #

Issues and PRs are welcome! Open a discussion or submit a fix anytime.

5
likes
0
points
27
downloads

Publisher

verified publisherlamnhan.dev

Weekly Downloads

A Dart library for synchronizing files between local and cloud storage using customizable metadata and file handlers, with progress callbacks and error handling.

Repository (GitHub)
View/report issues

License

unknown (license)

More

Packages that depend on cloud_sync