import { IDisposable } from 'notificar'; import { PathFx } from 'path-fx'; import { Directory } from './Directory'; import { FileEntry } from './FileEntry'; import { FileOrDir, IBasicFileSystemHost, IMetadataChange, IWatcherEvent, TopDownIteratorCallback } from './types'; export declare class Root extends Directory { readonly host: IBasicFileSystemHost; private readonly _pathfx; private rootPath; private events; private onceItemVisibleWatchers; private onceDirectoryExpandedWatchers; private onceDisposedWatchers; private onceParentChangedWatchers; private fswatchers; /** * When a big chain of generic "change" events come our way, we batch them up in a queue and dispatch them "efficently" after 't' milliseconds. * * This is usually in case of chokidar watcher when usePolling is enabled (https://www.npmjs.com/package/chokidar#performance) * * ONLY GENERIC CHANGE EVENTS GET QUEUED, OTHER SPECIFIC EVENTS ARE DISPATCHED AS THEY COME */ private changeEventDispatchQueue; /** * Timeout after which all queued change events will be auto fired and list will be flushed for next use */ private eventFlushTimeout; constructor(host: IBasicFileSystemHost, root: string); /** * Path utils like `join`, `basename`, `dirname` etc. * * Use utils from this object to ensure all operations are compliant with path style as specified by the host */ readonly pathfx: PathFx; readonly expanded: boolean; readonly path: string; onDidChangeDirExpansionState(cb: (directory: Directory, nowExpanded: boolean, visibleAtSurface: boolean) => void): IDisposable; onWillChangeDirExpansionState(cb: (directory: Directory, nowExpanded: boolean) => void): IDisposable; onWillProcessWatchEvent(cb: (directory: Directory, event: IWatcherEvent) => void): IDisposable; onDidProcessWatchEvent(cb: (directory: Directory, event: IWatcherEvent) => void): IDisposable; onDidUpdate(cb: () => void): IDisposable; onWillDispose(cb: (target: FileOrDir) => void): IDisposable; onDidDispose(cb: (target: FileOrDir) => void): IDisposable; onDidChangeParent(callback: (target: FileOrDir, prevParent: Directory, newParent: Directory) => void): IDisposable; onWillChangeParent(callback: (target: FileOrDir, prevParent: Directory, newParent: Directory) => void): IDisposable; onDidChangePath(callback: (target: FileOrDir) => void): IDisposable; onDidChangeMetadata(callback: (target: FileOrDir, change: IMetadataChange) => void): IDisposable; onOnceChangeParent(target: FileOrDir, callback: (target: FileOrDir, prevParent: Directory, newParent: Directory) => void): IDisposable; onOnceDisposed(target: FileOrDir, callback: (target: FileOrDir) => void): IDisposable; onOnceDirectoryExpanded(directory: Directory, callback: (directory: Directory) => void): IDisposable; onOnceItemVisible(item: FileOrDir, callback: (item: FileOrDir) => void): IDisposable; /** * Like `readdirp` but much more sicker * * Iterates top down starting from first child of `startingPoint` (default `Root`) until exited * * ⚠ *THIS IS A UTILITY FUNCTION, DO NOT USE IT FOR FLATTENING TREE STRUCTURES* ⚠ * * Flattened structure (for wiring with windowing libraries) is accessible through `Root.getFileEntryAtIndex`. Most windowing libraries will provide you * with the `index` they need data for. Flattened structure available through `Root` is managed internally and `Root#branchSize` is the number of items * visible at surface. * * Iterator will start at level `startingPoint#depth` (default `Root` thus `0`). To track `stepIns` and `stepOuts`, keep an eye on current item's `depth` (`FileEntry#depth`) */ iterateTopDown(callback: TopDownIteratorCallback, startingPoint?: Directory): Promise; expandDirectory(directory: Directory, ensureVisible?: boolean): Promise; collapseDirectory(directory: Directory): void; inotify(event: IWatcherEvent): void; getIndexAtFileEntryID(id: number): number; /** * Reverse of `Root#getFileEntryAtIndex` */ getIndexAtFileEntry(fileEntry: FileOrDir): number; /** * Lookup flattened tree structure by index * * `Root` manages the flattened structure, which is automatically adjusted whenever a child Directory is expanded or collapsed * * Total number of items that "can" be visible at surface can be accessed by `Root#branchSize` * * Most windowing libraries will require you to specify item count, and upon rendering they will require data for an arbitrary index number * * Use `Root#branchSize` and `Root#getFileEntryAtIndex` respectively. * */ getFileEntryAtIndex(index: number): FileEntry; /** * Looks up for given file or directory at path in the tree (pre-loaded tree only) * * This method, unlike `Root#forceLoadFileEntryAtPath`, WILL NOT, force load anything (synchronouse for that reason) */ findFileEntryInLoadedTree(path: string): FileOrDir; /** * Brute force variant of `Root#findFileEntryInLoadedTree`. * * This method will force load children of `Directory` if it comes in way of specified path. However, it will not affect visual state of tree. */ forceLoadFileEntryAtPath(path: string): Promise; /** * Checks if an item is visible at surface, as opposed to being buried in the tree. * * "Visible" here does not mean visible in the current view/scroll state of rendered content. Instead, it means the item "can" be visible if scolled to the right spot. * * "Buried" means that item may (or may not) be inside an expanded directory, but at least one of its parent directory is in collapsed state preventing it * from being "visible" at surface. */ isItemVisibleAtSurface(item: FileOrDir): boolean; setExpanded(ensureVisible?: boolean): Promise; setCollapsed(): void; flushEventQueue(): Promise; protected setFlattenedBranch(branch: Uint32Array): void; private walkPathTillRelative; /** * FileTreeView's watcher queues up FS events instead of dispatching them immediately for performance reasons * Event queue is flushed after 't' milliseconds after last FS event is dispatched by host. * Call it directly if some component requires FileTreeView to be up to date with any changes. * * ONLY GENERIC CHANGE EVENTS ARE QUEUED, OTHER SPECIFIC EVENTS ARE DISPATCHED AS THEY COME */ private queueChangeEvent; private dispatchWatchEvent; private terminateWatch; }