update method
Recomputes the visible flat list for the given inputs, reusing the cache and applying an incremental update when exactly one node's expansion changed.
Implementation
FlattenResult<T> update({
required List<Node<T>> data,
required ViewMode mode,
required Set<String>? expandedIds,
}) {
// Cache hit: nothing changed.
if (identical(_cachedData, data) &&
_cachedMode == mode &&
_expandedIdsEqual(_cachedExpandedIds, expandedIds) &&
_cachedList.isNotEmpty) {
return FlattenResult(list: _cachedList, change: null);
}
// Incremental: same data/mode, exactly one node expanded or collapsed.
if (identical(_cachedData, data) &&
_cachedMode == mode &&
_cachedList.isNotEmpty &&
_cachedExpandedIds != null &&
expandedIds != null) {
final changedId = _singleDiff(_cachedExpandedIds!, expandedIds);
if (changedId != null) {
final isExpand = expandedIds.contains(changedId);
final previousLength = _cachedList.length;
final result = isExpand
? FlattenService.expandNode<T>(
currentList: _cachedList,
nodeId: changedId,
expandedNodeIds: expandedIds,
)
: FlattenService.collapseNode<T>(
currentList: _cachedList,
nodeId: changedId,
);
if (result != null) {
_cachedList = result.list;
_cachedExpandedIds = Set<String>.of(expandedIds);
return FlattenResult(
list: _cachedList,
change: FlattenChange(
index: result.index,
deltaItems: result.list.length - previousLength,
),
);
}
}
}
// Full rebuild.
final displayNodes = ViewModeProjection.project<T>(nodes: data, mode: mode);
_cachedList = FlattenService.flatten<T>(
nodes: displayNodes,
expandedNodeIds: expandedIds,
);
_cachedData = data;
_cachedMode = mode;
_cachedExpandedIds =
expandedIds != null ? Set<String>.of(expandedIds) : null;
return FlattenResult(list: _cachedList, change: null);
}