| 18 | } |
| 19 | |
| 20 | function buildFileTree(nodes: GraphNode[]): DirNode { |
| 21 | const root: DirNode = { name: "/", fullPath: "", children: new Map(), nodeIds: new Set(), directNodes: [] }; |
| 22 | for (const node of nodes) { |
| 23 | if (!node.file_path) continue; |
| 24 | const parts = node.file_path.split("/"); |
| 25 | let cur = root; |
| 26 | for (let i = 0; i < parts.length - 1; i++) { |
| 27 | if (!parts[i]) continue; |
| 28 | let child = cur.children.get(parts[i]); |
| 29 | if (!child) { |
| 30 | const prefix = parts.slice(0, i + 1).join("/"); |
| 31 | child = { name: parts[i], fullPath: prefix, children: new Map(), nodeIds: new Set(), directNodes: [] }; |
| 32 | cur.children.set(parts[i], child); |
| 33 | } |
| 34 | cur = child; |
| 35 | } |
| 36 | cur.directNodes.push(node); |
| 37 | } |
| 38 | function collect(d: DirNode): Set<number> { |
| 39 | const ids = new Set<number>(); |
| 40 | for (const n of d.directNodes) ids.add(n.id); |
| 41 | for (const c of d.children.values()) for (const id of collect(c)) ids.add(id); |
| 42 | d.nodeIds = ids; |
| 43 | return ids; |
| 44 | } |
| 45 | collect(root); |
| 46 | return root; |
| 47 | } |
| 48 | |
| 49 | function flattenSingleChild(dir: DirNode): DirNode { |
| 50 | const children = new Map<string, DirNode>(); |