import type { LaneSource } from "./lane.js"; import { detectSchema, type SchemaRegistry } from "./treefold.js"; import { type TreeProvider } from "./treeprovider.js"; /** host-supplied file/folder node. Folders have `children`; files have `size`. */ export interface FileNode { name: string; /** bytes; folders derive their total from children */ size?: number; children?: FileNode[]; /** file text; when present, zooming into the file reveals it line by line */ content?: string; /** repo-relative path — lets a host lazily fetch content on zoom */ path?: string; } /** optional hooks for lazy content loading (e.g. from a GitHub repo) */ /** a decoded image a host's loadImage hook hands the tree to draw */ export interface TreeImage { width: number; height: number; /** the frame to draw at `nowMs` — static images ignore the argument */ frame(nowMs: number): CanvasImageSource; /** animated (GIF): the tree schedules repaints while it is visible */ animated?: boolean; /** release decoder/bitmap resources when LRU-evicted */ close?(): void; } export interface TreeOptions { /** fetch a file's text by its `path`; null/throw → leave it unloaded */ fetchContent?: (path: string) => Promise; /** * load an image file's pixels by `path` — host-supplied like fetchContent * (the lib never fetches). Requested lazily once the file's band is tall * enough to show a thumbnail; results are LRU-cached and drawn letterboxed. * Animated sources (GIFs) return `animated: true` and a time-indexed * `frame(nowMs)` — the tree repaints while one is visible. */ loadImage?: (path: string) => Promise; /** called after lazily-loaded content arrives (host wires it to invalidate) */ onUpdate?: () => void; /** * directory layout weight policy. "flat" (default) weighs every dir 1 — * navigation-first: siblings stay near-equal and overview stays a list. * "child-count" weighs a dir 1 + its immediate child count — density- * first: big dirs dominate and heterogeneous overviews fold into the * child×kind heat table. Only valid on complete listings (a lazy * provider must keep unlisted dirs at 1 or pagination churns shares). */ dirWeight?: "flat" | "child-count"; } /** options for {@link createLazyTreeSource} */ export interface LazyTreeOptions extends TreeOptions { /** display name of the root directory (default "/") */ rootName?: string; /** provider key of the root listing (default "") — providers whose paths * aren't display-name joins (ids, absolute paths) anchor here */ rootPath?: string; /** entries requested per list page (default 64) */ pageLimit?: number; } /** cached schema-fold state for one directory (see nextSchemaState) */ export interface SchemaState { key: string; version: unknown; registry: SchemaRegistry | null; /** render schema columns? false = kind fallback while registry persists */ active: boolean; } /** * schema-state transition — the single choke point for the three coupled * rules (pure, exported for tests): * - a NEW listing version starts a fresh epoch (prev registry dropped, * ghosts retired); within one version the registry is append-only. * - a transient detection failure (members dipped below quorum, listings * went partial) KEEPS the same-version registry but deactivates — column * order and ghost history must survive the wobble. * - the registry is active only while ALL its columns (ghosts included) * plus the '·' rest fit the column budget; over budget → kind fallback * with the registry intact, so re-widening restores the same order. */ export declare function nextSchemaState(prev: SchemaState | null, detected: ReturnType, version: unknown, maxColumns: number, key: string): SchemaState; /** tree source with an optional lazy content loader (host wires setOnUpdate) */ export interface TreeSource extends LaneSource { setOnUpdate(fn: () => void): void; /** * fs-watch-style mutation: upsert (`node`) or delete (`null`) the entry at * `path` (slash-separated, root name excluded). Re-deals shares within the * parent only (with a glide) — nothing outside its interval moves. */ applyFsEvent(path: string, node: FileNode | null): boolean; /** * lazy sources: request one listing page for a PROVIDER list key * (default: the root's key) outside the viewport-driven scheduler — * hosts/tests use it to prime a subtree. Resolves after the page * settles; no-op on eager sources. */ ensureListed(path?: string): Promise; } export declare function createTreeSource(root: FileNode, opts?: TreeOptions): TreeSource; /** * lazy tree source: nothing is known up front; listings materialize from a * {@link TreeProvider} driven by the viewport (a dir lists only once its * band affords an expansion, pages continue only while it stays on screen). * The provider is a host-supplied hook like fetchContent — the lib itself * still performs no transport. */ export declare function createLazyTreeSource(provider: TreeProvider, opts?: LazyTreeOptions): TreeSource; //# sourceMappingURL=tree.d.ts.map