LearnNewsExamplesServices
Frontmatter
id9435
titleTreeStore: Fix visible projection for dynamic child additions to expanded parents
stateClosed
labels
bugai
assigneestobiu
createdAtMar 10, 2026, 10:17 PM
updatedAtMar 10, 2026, 11:14 PM
githubUrlhttps://github.com/neomjs/neo/issues/9435
authortobiu
commentsCount1
parentIssue9404
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtMar 10, 2026, 11:14 PM

TreeStore: Fix visible projection for dynamic child additions to expanded parents

Closed v12.1.0 bugai
tobiu
tobiu commented on Mar 10, 2026, 10:17 PM

When a new child node is dynamically added to a TreeStore and its parent is already expanded, the splice() method fails to correctly project this new child into the flat _items array at the correct hierarchical index.

Currently, the logic either misses the child entirely (if the parent is already in #allRecordsMap) or relies on Collection.splice without an index, which appends the node to the very end of the array, destroying the visual tree structure.

We need to calculate the precise insertion index for visibleToAdd nodes, or restructure the insertion logic to ensure they appear sequentially after their parent and preceding siblings in the flat view.

tobiu assigned to @tobiu on Mar 10, 2026, 10:17 PM
tobiu added the bug label on Mar 10, 2026, 10:17 PM
tobiu added the ai label on Mar 10, 2026, 10:17 PM
tobiu added parent issue #9404 on Mar 10, 2026, 10:17 PM
tobiu referenced in commit 4d16914 - "fix(data.TreeStore): Fix visible projection for dynamic child additions to expanded, sorted, and filtered trees (#9435) on Mar 10, 2026, 11:13 PM
tobiu
tobiu Mar 10, 2026, 11:13 PM

Input from Gemini 3.1 Pro:

✦ The code has been successfully committed and pushed!

The underlying issue wasn't just the logic for calculating the insertion index, but also a major symbol mismatch between Collection.Base and TreeStore that caused TreeStore.splice() to fail to detect when filters were active.

Summary of Fixes:

  1. Unfiltered/Unsorted Additions: Implemented getInsertIndexForNode to accurately calculate the flat projection index based on the preceding sibling's deep visible descendants, ensuring nodes are inserted perfectly after their parent in the _items array.
  2. Filtered Additions: Standardized all state symbols (isFiltered, isSorted, updatingIndex) to use Symbol.for() globally across Collection.Base and TreeStore.mjs. TreeStore.splice() now correctly intercepts dynamic additions during filtered states and triggers a clean me.filter() projection rebuild without corrupting the O(1) maps.
  3. Sorted Additions: Confirmed via new unit tests that the existing autoSort mechanic cleanly relies on TreeStore.doSort() to handle positional insertion for sorted tree stores.

I will close this ticket now.

tobiu closed this issue on Mar 10, 2026, 11:14 PM
tobiu referenced in commit 3f315d6 - "docs(data.TreeStore): Enhance JSDoc for getInsertIndexForNode (#9435)" on Mar 10, 2026, 11:20 PM