compact method

void compact({
  1. required List<String> removeTypes,
})

This will remove all non-referenced key/ID entries in the graph for certain types. Typically used after clear()ing one or more types in local storage. USE WITH CAUTION!

Implementation

void compact({required List<String> removeTypes}) {
  // find all keys in the box that are not internal
  final allKeys = box!.keys
      .map((e) => e.toString())
      .where((e) => !e.startsWith('_'))
      .toImmutableList();

  // find all keys that reference `removeTypes` keys
  final referencedKeys =
      box!.values.toList().fold<Set<String>>({}, (acc, metadataMap) {
    final relEntries =
        metadataMap.entries.where((e) => !e.key.toString().startsWith('_'));
    return {
      ...acc,
      ...relEntries.fold<Set<String>>({}, (acc2, e2) {
        return {
          ...acc2,
          for (final key in e2.value)
            if (key.toString().hasTypeOf(removeTypes)) key.toString()
        };
      })
    };
  });

  final typeKeys = allKeys.where((key) => key.hasTypeOf(removeTypes));

  // find all nodes that are orphan
  for (final key in typeKeys) {
    final node = _getNode(key);
    if (node == null) return;

    // If node is empty, it's orphan so remove
    // If node only has an _id and it's not referenced, it's orphan so remove
    //
    // Example: books#8cb3c7a0: {_id: [_id_int:books#1]} -- if 8cb3c7a0 is not
    // referenced in any metadata anywhere, and the model itself is deleted,
    // then it's safe to remove
    if (node.isEmpty ||
        (node.keys.length == 1 &&
            node.keys.first == '_id' &&
            !referencedKeys.contains(key))) {
      _removeNode(key);
      final idKey = node['_id']!.first;
      _removeNode(idKey);
    }
  }
}