UNPKG

@thingsinc/treejs

Version:

Simple Model for manipulating tree structure.

121 lines (120 loc) 2.89 kB
Object.defineProperty(exports, "__esModule", { value: true }); exports.Tree = void 0; const uuid_1 = require("uuid"); const node_1 = require("./node"); class Tree { treeId; root; constructor({ nodes, key, childKey }) { this.treeId = (0, uuid_1.v4)(); const nodeParam = this.#buildParams({ nodes, key, childKey, }); this.root = this.#parse({ key, childKey, nodeParam, }); } find(fn) { let targetNode = undefined; this.root.move((node) => { if (fn(node)) { targetNode = node; return false; } return true; }); return targetNode; } findOrThrow(fn) { const targetNode = this.find(fn); if (!targetNode) { throw new Error("Target node not found"); } return targetNode; } findMany(fn) { const targetNodes = []; this.root.move((node) => { if (fn(node)) { targetNodes.push(node); } return true; }); return targetNodes; } flat() { const nodes = []; this.root.move((node) => { nodes.push(node); return true; }); return nodes; } #buildParams({ nodes, key, childKey }) { const nodeParams = nodes.map((node) => ({ ...node, children: [], })); const nodeMap = new Map(); const rootNode = nodeParams.find((node) => node.level === 0); if (!rootNode) { throw new Error("Level 0 root node not found"); } for (const node of nodeParams) { nodeMap.set(node.data[key], { ...node, children: [], parentKey: null, }); } for (const node of nodeParams) { if (node.data[childKey]) { const parent = nodeMap.get(node.data[key]); if (!parent) { throw new Error("Parent node not found"); } const child = nodeMap.get(node.data[childKey]); if (!child) { throw new Error("Child node not found"); } parent?.children.push({ ...child, parentKey: parent.data[key], }); } } const root = nodeMap.get(rootNode?.data[key]); for (const node of nodeParams) { delete node.data[childKey]; } return root; } #parse({ key, childKey, nodeParam, ancestorPath }) { const path = ancestorPath === undefined ? nodeParam.data[key] : ancestorPath; const node = new node_1.Node({ treeId: this.treeId, ancestorPath: path, key, childKey, level: nodeParam.level, parentKey: nodeParam.parentKey, children: nodeParam.children.map((childNodeModel) => this.#parse({ key, childKey, nodeParam: childNodeModel, ancestorPath: `${path}/${childNodeModel.data[key]}`, }), ), data: nodeParam.data, }); return node; } } exports.Tree = Tree; //# sourceMappingURL=tree.js.map