remove method
Removes the value at path (a map field or a list element) so it reads
as missing again. Returns the dependency keys touched.
Implementation
@override
Set<String> remove(String operation, List<Object> path) {
final touched = <String>{};
if (path.isEmpty) return touched;
var start = 0;
String entityKey;
if (path.first is Ref) {
entityKey = (path.first as Ref).key;
start = 1;
} else {
entityKey = rootKey(operation);
}
if (start >= path.length) return touched;
Object? container = _entities[entityKey];
String? topField;
// As in [write]: the list [topField] holds and the index walked through.
List<Object?>? topList;
int? topIndex;
for (var i = start; i < path.length - 1; i++) {
final key = path[i];
if (container is Ref) {
entityKey = container.key;
container = _entities[entityKey];
topField = null;
topList = null;
topIndex = null;
}
if (key is String) {
if (container is! Map) return touched;
final held = container[key];
if (topField == null) {
topField = key;
if (held is List<Object?>) topList = held;
}
container = held;
} else {
final index = key as int;
if (container is! List || index >= container.length) return touched;
if (identical(container, topList)) topIndex = index;
container = container[index];
}
}
if (container is Ref) {
entityKey = container.key;
container = _entities[entityKey];
topField = null;
topList = null;
topIndex = null;
}
final last = path.last;
if (last is String) {
if (container is! Map || !container.containsKey(last)) return touched;
final previous = container.remove(last);
if (topField == null) {
topField = last;
if (previous is List<Object?>) {
_touchList(entityKey, last, previous, 0, touched);
}
}
} else {
final index = last as int;
if (container is! List<Object?> || index >= container.length) {
return touched;
}
if (identical(container, topList)) {
// The elements from [index] on shift: all of them changed.
_touchList(entityKey, topField!, container, index, touched);
}
container.removeAt(index);
}
if (topField != null) touched.add(depKey(entityKey, topField));
if (topIndex != null) {
touched.add(_listDeps(entityKey, topField!).element(topIndex));
}
_markChanged(entityKey, topField);
_emit(touched);
return touched;
}