updateAllItems method
Implementation
Future updateAllItems(Iterable<V> data) async {
final newDataAsMap = Map<MKey, V>.fromEntries(
data.map<V>(repository.initialize).mapNotNull((v) {
return v.mkey == null ? null : MapEntry<MKey, V>(v.mkey!, v);
}));
final keyDiffs = await (_data.keys.toSet().differencesAsync(
newDataAsMap.keys.toSet(),
equality: this.equality,
debugName: "${this.type.baseCode}[keys]",
));
await applyChanges((_changes) async {
runInAction(() {
/// Handle anything that changed first
for (final diff in keyDiffs) {
switch (diff.type) {
case SetDiffType.add:
for (final key in diff.items) {
final _record = _internalGet(key);
final newRecord = newDataAsMap[key];
if (_record.isNotLoaded) {
_changes.set(key, _record);
} else {
_changes.change(key, _record);
}
// Debate on whether this should be silent or not... A silent update won't publish changes
// which seems like it could cause issues
_record.update(newRecord);
}
break;
case SetDiffType.remove:
for (final key in diff.items) {
_data.remove(key);
_changes.unset(key);
}
break;
default:
/// There aren't any other options for sets
break;
}
}
/// Do an internal update for all shared keys
final shared = newDataAsMap.keys.toSet().union(_data.keys.toSet());
for (final recordId in shared) {
final _record = _internalGet(recordId);
final isNew = _record.isNotLoaded;
final incomingRecord = newDataAsMap[recordId];
/// If there isn't really any change, then don't bother with an update.
if (_record.isResolved &&
!identical(_record.valueOrNull, incomingRecord) &&
_record.valueOrNull == incomingRecord) {
log.finer(
"not propagating record [${recordId.mxid}] because it matches the existing");
continue;
}
_record.update(incomingRecord);
if (isNew) {
_changes.set(recordId, _record);
} else {
_changes.change(recordId, _record);
}
}
});
});
_reloadCompletions.add(_data.values.toList());
}