LearnNewsExamplesServices
Frontmatter
id9406
titleCreate `Neo.data.TreeStore`
stateClosed
labels
enhancementaicore
assigneestobiu
createdAtMar 9, 2026, 11:44 AM
updatedAtMar 9, 2026, 2:38 PM
githubUrlhttps://github.com/neomjs/neo/issues/9406
authortobiu
commentsCount3
parentIssue9404
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtMar 9, 2026, 2:38 PM

Create Neo.data.TreeStore

Closed v12.1.0 enhancementaicore
tobiu
tobiu commented on Mar 9, 2026, 11:44 AM

Goal

Create a specialized store to manage hierarchical data and provide a flattened view for virtual scrolling.

Details

  • Location: src/data/TreeStore.mjs
  • Extends: Neo.data.Store
  • Internal State:
    • Implement a #childrenMap (Map) keyed by parentId to enable O(1) child lookups.
  • Flattened View:
    • The store must maintain the full data structure but expose a flattened 1D array of only the visible nodes (root nodes + children of expanded nodes) to the grid's virtual scroller.
  • Core Methods:
    • expand(nodeId): Updates node state, retrieves children, injects them into the flattened view, and fires a mutate event.
    • collapse(nodeId): Reverses the expansion, recursively removing visible descendants from the flattened array.
    • toggle(nodeId): Toggles the expanded state.
    • loadData(data): Overridden to populate the internal #childrenMap.
  • Config:
    • singleExpand (Boolean): Support for accordion-style expansion (expanding one node collapses siblings).
tobiu added the enhancement label on Mar 9, 2026, 11:44 AM
tobiu added the ai label on Mar 9, 2026, 11:44 AM
tobiu added the core label on Mar 9, 2026, 11:44 AM
tobiu added parent issue #9404 on Mar 9, 2026, 11:44 AM
tobiu
tobiu Mar 9, 2026, 12:09 PM

Input from Gemini 3.1 Pro:

Implementation Guidance for Agents:

The core architectural mandate for the TreeStore is to allow the Neo.grid.Body virtual scroller to function without modification.

  1. The Flattened View: The GridBody iterates over the store's items array. Therefore, the TreeStore MUST override or manage its internal _items array to only contain the currently visible nodes (root nodes + children of expanded nodes).
  2. O(1) Lookups: You must implement a private #childrenMap = new Map() keyed by parentId to ensure that when a node is expanded, retrieving its children to inject into the flattened view is an O(1) operation. Do not use store.filter() to find children during an expand operation.
  3. Mutations: Expanding or collapsing a node should update the flattened view and fire a mutate event so the grid automatically recalculates aria-rowcount and scrollbar height.

Important Files to Reference:

  • src/collection/Base.mjs (Understand splice and mutate events).
  • src/grid/Body.mjs -> createViewData() (Understand how the grid maps the 1D array to the DOM).
tobiu assigned to @tobiu on Mar 9, 2026, 12:10 PM
tobiu cross-referenced by #9413 on Mar 9, 2026, 12:33 PM
tobiu referenced in commit aec7125 - "feat: Add Neo.data.TreeStore (#9406) on Mar 9, 2026, 2:38 PM
tobiu
tobiu Mar 9, 2026, 2:38 PM

Input from Gemini 3.1 Pro:

✦ Implemented Neo.data.TreeStore with the "Splice Approach".

  • Introduces #childrenMap and #allRecordsMap for data integrity and fast lookup.
  • The internal _items array (used by GridBody) dynamically flattens only the visible nodes via Collection.splice().
  • Implemented expand(), collapse(), and toggle() functions for fast virtual scrolling recalculation without a full store filter.
  • Added singleExpand behavior.

Changes pushed to dev.

tobiu
tobiu Mar 9, 2026, 2:38 PM

Implemented Neo.data.TreeStore. Pushed to dev.

tobiu closed this issue on Mar 9, 2026, 2:38 PM