pushBatch method
Push multiple records to the remote in optimized batches.
The default implementation falls back to individual push calls. Override in backend-specific subclasses (e.g. SupabaseRemoteStore) to use batch APIs for better performance.
Implementation
@override
Future<void> pushBatch(List<SyncEntry> entries) async {
if (entries.isEmpty) return;
// Group entries by table and operation
final groups = <String, Map<SyncOperation, List<SyncEntry>>>{};
for (final entry in entries) {
final tableGroups = groups.putIfAbsent(entry.table, () => {});
tableGroups.putIfAbsent(entry.operation, () => []).add(entry);
}
try {
for (final tableEntry in groups.entries) {
final tableName = tableEntry.key;
final opsMap = tableEntry.value;
// Batch Upserts
final upserts = opsMap[SyncOperation.upsert];
if (upserts != null && upserts.isNotEmpty) {
final payloads = upserts.map((e) => e.payload).toList();
await client.from(tableName).upsert(payloads);
}
// Batch Deletes
final deletes = opsMap[SyncOperation.delete];
if (deletes != null && deletes.isNotEmpty) {
final ids = deletes.map((e) => e.recordId).toList();
await client.from(tableName).delete().inFilter('id', ids);
}
// Batch Patches (individual updates — Supabase has no batch update)
final patches = opsMap[SyncOperation.patch];
if (patches != null && patches.isNotEmpty) {
for (final entry in patches) {
await client
.from(tableName)
.update(entry.payload)
.eq('id', entry.recordId);
}
}
}
} on AuthException catch (e) {
throw AuthExpiredException(e);
} catch (e) {
if (_isAuthError(e)) throw AuthExpiredException(e);
rethrow;
}
}