BidirectionalSyncStrategy<T> class

Bidirectional synchronization strategy.

Extends PushOnlySyncStrategy with the ability to pull remote changes and merge them into local storage. Conflicts between local pending changes and incoming remote data are resolved via a configurable _conflictResolver callback (default: remote wins).

Conflict resolution

When pullRemote encounters a record that is SyncStatus.pending or SyncStatus.failed locally, the conflict resolver is invoked with the local and remote versions. The returned entity is saved to local storage.

  • If the resolver returns the remote entity (default behavior), the record is marked SyncStatus.synced — the local pending change is discarded in favor of the remote version.
  • If the resolver returns the local entity, the record remains pending — the local change still needs to push on the next sync cycle.

Example (generated wiring)

final strategy = BidirectionalSyncStrategy<Product>(
  fetchLocal: (keys) => localDataSource.getByIds(keys),
  fetchRemoteList: () => remoteDataSource.getAll(),
  createRemote: (product) => remoteDataSource.create(product),
  updateRemote: (product) => remoteDataSource.update(product),
  deleteRemote: (id) => remoteDataSource.delete(id),
  saveLocal: (product) => localDataSource.put(product),
  keyResolver: (product) => product.id,
  metadataStore: syncMetadataStore,
  conflictResolver: (local, remote) {
    // Last-write-wins by updatedAt
    if (local == null) return remote;
    return local.updatedAt.isAfter(remote.updatedAt) ? local : remote;
  },
);
Inheritance

Constructors

BidirectionalSyncStrategy({required Future<List<T>> fetchLocal(List<String> keys), required Future<T> createRemote(T entity), required Future<T> updateRemote(T entity), required Future<void> deleteRemote(String key), required String keyResolver(T entity), required SyncMetadataStore metadataStore, required Future<List<T>> fetchRemoteList(), required Future<void> saveLocal(T entity), T conflictResolver(T? local, T remote)?, SyncConfig config = const SyncConfig()})

Properties

fetchLocal → Future<List<T>> Function(List<String> keys)
Protected: fetch local entities by keys.
no setterinherited
hashCode → int
The hash code for this object.
no setterinherited
keyResolver → String Function(T entity)
Protected: resolve sync key from an entity.
no setterinherited
logger → Logger
Logger instance for this class.
no setterinherited
metadataStore → SyncMetadataStore
Protected: metadata store.
no setterinherited
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited

Methods

getPendingCount() → Future<int>
Get count of records pending sync.
inherited
getSyncStatus(String key) → Future<SyncStatus>
Get sync status for a specific record by key.
inherited
markDeleted(String key) → Future<void>
Mark a record as deleted (tombstone).
inherited
markPending(String key, {SyncOperation operation = SyncOperation.create}) → Future<void>
Mark a record as pending sync.
inherited
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
pullRemote({CancelToken? cancelToken}) → Future<void>
Pull remote data and merge into local storage.
override
syncFailed({CancelToken? cancelToken}) → Future<void>
Retry all previously failed records.
inherited
syncPending({CancelToken? cancelToken}) → Future<void>
Push all pending local changes to the remote data source.
inherited
toString() → String
A string representation of this object.
inherited

Operators

operator ==(Object other) → bool
The equality operator.
inherited