LearnNewsExamplesServices
Frontmatter
id9423
titleTreeStore Full CRUD Support & Structural Mutations
stateClosed
labels
enhancementarchitecturecore
assigneestobiu
createdAtMar 9, 2026, 7:41 PM
updatedAtMar 9, 2026, 7:54 PM
githubUrlhttps://github.com/neomjs/neo/issues/9423
authortobiu
commentsCount1
parentIssue9404
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtMar 9, 2026, 7:54 PM

TreeStore Full CRUD Support & Structural Mutations

Closed v12.1.0 enhancementarchitecturecore
tobiu
tobiu commented on Mar 9, 2026, 7:41 PM

Goal

To provide full CRUD operations (remove, splice, move) for the Neo.data.TreeStore, ensuring that the internal data maps (#childrenMap, #allRecordsMap) and the ARIA sibling stats remain perfectly synchronized with the visible flat array.

Context

Currently, the TreeStore supports data ingestion (add) and visibility toggling (expand/collapse). However, invoking standard Collection mutation methods like remove or splice will only affect the visible items array, causing memory leaks and structural corruption in the internal Tree maps.

This is a critical prerequisite for advanced TreeGrid features like Drag & Drop reordering and moving child nodes between parents.

Requirements

  1. Override splice: Implement a custom splice method in TreeStore that acts as the single source of truth for all mutations.
  2. Removal Logic: When a node is removed:
    • Recursively identify and remove all its descendants from #allRecordsMap.
    • Remove the node from its parent's array in #childrenMap.
    • If the node (or any descendants) was currently visible (expanded), calculate the flat delta and pass it to super.splice().
  3. Move Logic (Drag & Drop Prep): Handle cases where an existing node is "added" again but with a different parentId.
    • Remove from the old parent's #childrenMap.
    • Add to the new parent's #childrenMap.
  4. Recalculate ARIA Stats: After any structural change to a parent's children array, invoke updateSiblingStats(parentId) on all affected parents to ensure siblingCount and siblingIndex remain accurate for O(1) rendering reads.
tobiu assigned to @tobiu on Mar 9, 2026, 7:41 PM
tobiu added the enhancement label on Mar 9, 2026, 7:41 PM
tobiu added the architecture label on Mar 9, 2026, 7:41 PM
tobiu added the core label on Mar 9, 2026, 7:41 PM
tobiu added parent issue #9404 on Mar 9, 2026, 7:41 PM
tobiu referenced in commit c5c4e40 - "feat(data): Implement TreeStore.splice for full CRUD support (#9423)" on Mar 9, 2026, 7:53 PM
tobiu
tobiu Mar 9, 2026, 7:53 PM

Input from Gemini 3.1 Pro:

✦ I have implemented the custom TreeStore.splice() method to act as the single source of truth for all structural mutations.

Key achievements:

  • Removals: Recursively cleans up deep descendants from #allRecordsMap and #childrenMap, preventing memory leaks and calculating the correct flat delta for the visible array.
  • Additions/Moves: Properly ingests new nodes or reparents moved nodes into the structural maps.
  • ARIA Stats: Recalculates siblingCount and siblingIndex for all parents affected by the mutation.
  • Fallback Mutations: Fires a manual mutate event even if the target nodes are hidden, ensuring secondary systems like Store.count remain in sync.

The add() override was removed entirely, as Collection.add() inherently funnels through this new, robust splice() method.

Closing as complete.

tobiu closed this issue on Mar 9, 2026, 7:54 PM