* Find root nodes (nodes with no incoming edges). * Returns nodes sorted by their order in the DAG. * If no roots exist (cycle-only graph), returns all nodes to ensure rendering.
(dag: BlockDependencyDag)
| 236 | * If no roots exist (cycle-only graph), returns all nodes to ensure rendering. |
| 237 | */ |
| 238 | function findRootNodes(dag: BlockDependencyDag): string[] { |
| 239 | const hasIncoming = new Set<string>() |
| 240 | for (const edge of dag.edges) { |
| 241 | hasIncoming.add(edge.to) |
| 242 | } |
| 243 | |
| 244 | let roots = dag.nodes.filter(node => !hasIncoming.has(node.id)).map(node => node.id) |
| 245 | |
| 246 | // If no roots found (cycle-only graph), use all nodes as roots |
| 247 | if (roots.length === 0) { |
| 248 | roots = dag.nodes.map(node => node.id) |
| 249 | } |
| 250 | |
| 251 | // Sort by order |
| 252 | const nodeMap = buildNodeMap(dag) |
| 253 | roots.sort((a, b) => (nodeMap.get(a)?.order ?? 0) - (nodeMap.get(b)?.order ?? 0)) |
| 254 | |
| 255 | return roots |
| 256 | } |
| 257 | |
| 258 | /** |
| 259 | * Build sorted children for a node, deduplicating edges to the same child. |
no test coverage detected