remove method

  1. @override
Set<String> remove(
  1. String operation,
  2. List<Object> path
)

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);
  _emit(touched);
  return touched;
}