export class GraphNode < T > { public constructor ( value , edges = [ ] ) { this . value = value ; this . edges = new Set ( edges ) ; } /** The value of this node */ public readonly value : T ; /** Which nodes this node depends on */ public readonly edges : Set < GraphNode < T > > ; } /**
 * Performs a topological sort of the given graph so that nodes without dependencies come first.
 * Warning: This method will change the input dataset!
 */ export function topologicalSort < T > ( graph ) { const ret = [ ] ; while ( graph . length ) { const nodesWithoutDependencies = graph . filter ( ( node ) => node . edges . size === 0 ) ; if ( ! nodesWithoutDependencies . length ) { throw new Error ( "Circular dependency detected!" ) ; } const newNodes = nodesWithoutDependencies . map ( ( node ) => node . value ) ; ret . push ( ... newNodes ) ; graph = graph . filter ( ( node ) => node . edges . size > 0 ) ; for ( const node of graph ) { for ( const visited of nodesWithoutDependencies ) { node . edges . delete ( visited ) ; } } } return ret ; }