push method
Future<T>
push({
- required T item,
- required String userId,
- DataSource source = DataSource.local,
- bool forceRemoteSync = false,
Implementation
Future<T> push({
required T item,
required String userId,
DataSource source = DataSource.local,
bool forceRemoteSync = false,
}) async {
_ensureInitialized();
_relationLoader.registerRelationSchema(item);
// Check for user switch before proceeding.
await _syncEngineInstance.checkForUserSwitch(userId);
var transformed = await _applyPreSaveTransforms(item);
// Automatically increment vector clock if deviceId is available — but
// only for locally-originated writes. A remote-sourced save is another
// device's edit being applied here; claiming a local causal step for it
// makes every subsequent legitimate remote update look concurrent.
if (deviceId != null && source == DataSource.local) {
transformed = transformed.incrementClock(deviceId!) as T;
}
final existing = await localAdapter.read(item.id, userId: userId);
if (existing != null) {
// This is an update. Calculate the diff.
final delta = transformed.diff(existing);
if (delta == null) {
_logger.debug(
'No changes detected for entity ${item.id}, skipping save.',
);
return transformed;
}
// If we are here, it's a valid update with changes.
final result = await _performUpdate(transformed, delta, source, forceRemoteSync);
// Invalidate caches that might be affected by this update
_cacheCoordinator.invalidateCachesForEntity(result);
return result;
} else {
// This is a new creation.
final result = await _performCreate(transformed, source, forceRemoteSync);
// Invalidate caches that might be affected by this creation
_cacheCoordinator.invalidateCachesForEntity(result);
return result;
}
}