// // Generic TreeDataProvider over the node model. Subclasses only implement // roots(); everything else — lazy children, TreeItem mapping — happens here. // const log = require("../util/log.js"); const { message } = require("./nodes.js"); class NodeProvider { constructor(store) { this.store = store; this._roots = null; } /** Subclasses return an array of nodes (or a Promise of one). */ roots() { return []; } /** Drops memoised roots so the next getChildren rebuilds from the store. */ invalidate() { this._roots = null; } async getChildren(element) { try { if (!element) { if (!this._roots) { this._roots = await this.roots(); // A section may hoist a repository's children to the top // level; those nodes must not keep a parent Nova cannot see. for (const root of this._roots) root.parent = null; } return this._roots; } if (element.children) return element.children; if (element.load) { const children = await element.load(); element.children = children || []; for (const child of element.children) child.parent = element; return element.children; } return []; } catch (error) { log.error("tree build failed", String(error && error.stack ? error.stack : error)); return [message(`⚠ ${error.message || error}`)]; } } getParent(element) { return element ? element.parent : null; } getTreeItem(element) { const collapsible = element.children || element.load ? element.expanded ? TreeItemCollapsibleState.Expanded : TreeItemCollapsibleState.Collapsed : TreeItemCollapsibleState.None; const item = new TreeItem(element.name, collapsible); item.identifier = element.identifier; item.contextValue = element.contextValue; if (element.descriptiveText) item.descriptiveText = element.descriptiveText; if (element.tooltip) item.tooltip = element.tooltip; if (element.image) item.image = element.image; if (element.path) item.path = element.path; if (element.command) item.command = element.command; return item; } } exports.NodeProvider = NodeProvider;