export class Graph { nodes: Map<string, string[]> = new Map(); errors: string[] = [];
addNode(node: string, adjacents: string[]): void { this.nodes.set(node, adjacents); }
searchForCycles() { this.errors = []; const discovered: Set<string> = new Set(); const finished: Set<string> = new Set(); for (const node of this.nodes.keys()) { if (!discovered.has(node) && !finished.has(node)) { this.dfsVisit(node, discovered, finished); } } }
private dfsVisit( node: string, discovered: Set<string>, finished: Set<string>, ) { discovered.add(node); for (const adjacent of this.nodes.get(node)!) { if (discovered.has(adjacent)) { this.errors.push( `cyclic dependency between '${node}' and '${adjacent}'`, ); } if (!discovered.has(adjacent) && !finished.has(adjacent)) { this.dfsVisit(adjacent, discovered, finished); } } discovered.delete(node); finished.add(node); }}