| 190 | } |
| 191 | |
| 192 | function updateTree( |
| 193 | items: TreeNode<T>[], |
| 194 | key: Key | null, |
| 195 | update: (node: TreeNode<T>) => TreeNode<T> | null, |
| 196 | originalMap: Map<Key, TreeNode<T>> |
| 197 | ) { |
| 198 | let node = key == null ? null : originalMap.get(key); |
| 199 | if (node == null) { |
| 200 | return {items, nodeMap: originalMap}; |
| 201 | } |
| 202 | let map = new Map<Key, TreeNode<T>>(originalMap); |
| 203 | |
| 204 | // Create a new node. If null, then delete the node, otherwise replace. |
| 205 | let newNode = update(node); |
| 206 | if (newNode == null) { |
| 207 | deleteNode(node, map); |
| 208 | } else { |
| 209 | addNode(newNode, map); |
| 210 | } |
| 211 | |
| 212 | // Walk up the tree and update each parent to refer to the new children. |
| 213 | while (node && node.parentKey) { |
| 214 | let nextParent = map.get(node.parentKey)!; |
| 215 | let copy: TreeNode<T> = { |
| 216 | key: nextParent.key, |
| 217 | parentKey: nextParent.parentKey, |
| 218 | value: nextParent.value, |
| 219 | children: null |
| 220 | }; |
| 221 | |
| 222 | let children = nextParent.children; |
| 223 | if (newNode == null && children) { |
| 224 | children = children.filter(c => c !== node); |
| 225 | } |
| 226 | |
| 227 | copy.children = |
| 228 | children?.map(child => { |
| 229 | if (child === node) { |
| 230 | // newNode cannot be null here due to the above filter. |
| 231 | return newNode!; |
| 232 | } |
| 233 | |
| 234 | return child; |
| 235 | }) ?? null; |
| 236 | |
| 237 | map.set(copy.key, copy); |
| 238 | |
| 239 | newNode = copy; |
| 240 | node = nextParent; |
| 241 | } |
| 242 | |
| 243 | if (newNode == null) { |
| 244 | items = items.filter(c => c !== node); |
| 245 | } |
| 246 | |
| 247 | return { |
| 248 | items: items.map(item => { |
| 249 | if (item === node) { |