changesSince method
The entities changed or removed since version (an earlier value of
Cache.version), as JSON copies of those entities only (for the operation roots:
of the fields that changed, see CacheDelta.changedFields). Store it,
then ask again from CacheDelta.version.
Implementation
@override
CacheDelta changesSince(int version) {
if (version < _fullSince) {
return CacheDelta(
version: _version,
changed: {
for (final e in _entities.entries) e.key: _entityJson(e.value),
},
removed: {},
full: true,
);
}
final changed = <String, Map<String, Object?>>{};
Map<String, Map<String, Object?>>? changedFields;
Map<String, Set<String>>? removedFields;
for (final e in _changedAt.entries) {
if (e.value <= version) continue;
final key = e.key;
final entity = _entities[key]!;
final stamps = _fieldChangedAt[key];
if (!isRootKey(key) || version < (_fieldsSince[key] ?? 0)) {
changed[key] = _entityJson(entity);
continue;
}
// A root, field by field: the fields stamped since [version].
final fields = <String, Object?>{};
Set<String>? gone;
if (stamps != null) {
for (final s in stamps.entries) {
if (s.value <= version) continue;
if (entity.containsKey(s.key)) {
fields[s.key] = _toJson(entity[s.key]);
} else {
(gone ??= {}).add(s.key);
}
}
}
// An empty entry for a root created empty, so it exists in the copy.
if (fields.isNotEmpty || gone == null) {
(changedFields ??= {})[key] = fields;
}
if (gone != null) (removedFields ??= {})[key] = gone;
}
return CacheDelta(
version: _version,
changed: changed,
removed: {
for (final e in _removedAt.entries)
if (e.value > version) e.key,
},
changedFields: changedFields ?? const {},
removedFields: removedFields ?? const {},
);
}