You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add an opt-in lazy-child data path for large, remote, or expensive hierarchies without breaking the existing eager PreparedTree API.
The model should accept an asynchronous children provider, expose unloaded/loading/loaded/failed state to every renderer, and load a branch only when interaction requires it. Existing eager trees should continue to use the same public initializers and behavior, while both eager and lazy inputs converge on one internal tree-query/store seam so renderers no longer depend directly on PreparedTree storage.
This feature owns hierarchy state, request coordination, validation, and renderer updates. It does not enumerate the filesystem, watch directories, persist state, or choose a cache-eviction policy for callers.
Acceptance criteria
Existing PreparedTree, FileTreeModel(preparedTree), FileTree, and FileTreeView call sites remain source-compatible and do not become implicitly asynchronous.
TreeKit provides a Sendable lazy children provider with separate root loading, mightHaveChildren, and child-loading capabilities.
Renderers query hierarchy data through a model/store interface instead of reaching through the model to preparedTree internals.
Every expandable item has explicit unloaded, loading, loaded, or failed state; row context exposes enough state for custom loading, error, and retry presentation without fake nodes.
Expanding an unloaded branch starts one request, concurrent expansion requests coalesce, and collapsing a successfully loaded branch retains its children for the model lifetime.
Reset and cancellation invalidate in-flight generations, and stale results cannot overwrite newer model state even when the underlying task does not stop immediately.
Loaded nodes are validated for globally unique and stable IDs before one atomic model transaction publishes them; invalid results preserve the previous hierarchy and surface a typed error.
Failed loads can be retried explicitly and do not leave disclosure, selection, focus, or expansion in an inconsistent state.
Lazy reveal can traverse unloaded ancestors through an explicit ID path or provider resolver, coalescing existing requests before selecting and scrolling to the target.
SwiftUI, AppKit, and UIKit expose equivalent expansion, retry, selection, focus, accessibility, and reveal semantics.
The Demo includes deterministic slow, failed, retried, cancelled, and remote-style lazy branches alongside the existing eager tree.
Tests cover cancellation, stale completion, retry, duplicate IDs, hidden descendant expansion, reveal through unloaded ancestors, reset during load, sorting, selection retention, and concurrent expansion.
Performance evidence compares eager and lazy modes at 2,500, 100,000, and at least 500,000 potential nodes, reporting discovered/loaded node counts, physical and peak footprint, main-thread time, and visible-content update latency.
DocC and README document eager versus lazy input, provider ownership, failure behavior, caching guarantees, and the filesystem/persistence boundary.
What to build
Add an opt-in lazy-child data path for large, remote, or expensive hierarchies without breaking the existing eager
PreparedTreeAPI.The model should accept an asynchronous children provider, expose unloaded/loading/loaded/failed state to every renderer, and load a branch only when interaction requires it. Existing eager trees should continue to use the same public initializers and behavior, while both eager and lazy inputs converge on one internal tree-query/store seam so renderers no longer depend directly on
PreparedTreestorage.This feature owns hierarchy state, request coordination, validation, and renderer updates. It does not enumerate the filesystem, watch directories, persist state, or choose a cache-eviction policy for callers.
Acceptance criteria
PreparedTree,FileTreeModel(preparedTree),FileTree, andFileTreeViewcall sites remain source-compatible and do not become implicitly asynchronous.Sendablelazy children provider with separate root loading,mightHaveChildren, and child-loading capabilities.preparedTreeinternals.Related
Docs/LazyLoading.mddefine the initial compatibility and state-machine direction.Non-goals
Blocked by
None - can start immediately.