expandNonPrimitives method

bool expandNonPrimitives(
  1. String nodeId, {
  2. bool includeEdges = true,
})

Expand all non-primitive (submodule) hidden children of a node.

A non-primitive child is one that has children or hidden children of its own (i.e. it is a submodule, not a leaf/primitive gate). This also reveals the hyperedges that connect to those children.

Returns true if new children/edges were revealed.

Implementation

bool expandNonPrimitives(String nodeId, {bool includeEdges = true}) {
  final node = nodeMap[nodeId];
  if (node == null) {
    return false;
  }

  // Node must have hidden children for this to make sense.
  if (node.hiddenChildren == null || node.hiddenChildren!.isEmpty) {
    return false;
  }

  // Find non-primitive hidden children (have children or hiddenChildren).
  final nonPrimitiveIds = <String>{};
  for (final child in node.hiddenChildren!) {
    if (child.children.isNotEmpty || child.isExpandable) {
      nonPrimitiveIds.add(child.id);
    }
  }

  if (nonPrimitiveIds.isEmpty) {
    return false;
  }

  // Find hyperedges that connect to these non-primitive children.
  final matchingHyperedgeIds = <String>{};
  if (includeEdges) {
    final hyperedges = node.hyperedges;
    if (hyperedges != null) {
      for (final h in hyperedges) {
        var involves = false;
        for (final (nId, _) in h.sources) {
          if (nonPrimitiveIds.contains(nId)) {
            involves = true;
            break;
          }
        }
        if (!involves) {
          for (final (nId, _) in h.targets) {
            if (nonPrimitiveIds.contains(nId)) {
              involves = true;
              break;
            }
          }
        }
        if (involves) {
          matchingHyperedgeIds.add(h.id);
        }
      }
    }
  }

  // Check if everything is already visible (idempotent)
  final existingChildren = node.partialChildIds ?? {};
  final existingEdges = node.partialHyperedgeIds ?? {};
  if (existingChildren.containsAll(nonPrimitiveIds) &&
      existingEdges.containsAll(matchingHyperedgeIds)) {
    return false; // Already visible
  }

  // Additive: merge into existing partial sets
  node
    ..partialChildIds = {...existingChildren, ...nonPrimitiveIds}
    ..partialHyperedgeIds = {...existingEdges, ...matchingHyperedgeIds};

  return true;
}