UNPKG

@typed/content-hash

Version:

Content hash a directory of HTML/JS/CSS files and other static assets

63 lines (48 loc) 1.72 kB
import { NonEmptyArray } from 'fp-ts/NonEmptyArray' import { ReadonlyNonEmptyArray } from 'fp-ts/ReadonlyNonEmptyArray' import { DiGraph } from './DiGraph' import { toDependencyMap } from './toDependencyMap' export function getStronglyConnectedComponents<A>(graph: DiGraph<A>): ReadonlyArray<ReadonlyNonEmptyArray<A>> { const indices = new Map<A, number>() const lowlinks = new Map<A, number>() const onStack = new Set<A>() const stack: A[] = [] const stronglyConnectedComponents: Array<NonEmptyArray<A>> = [] const dependencyMap = toDependencyMap(graph) let index = 0 for (const v of dependencyMap.keys()) { if (!indices.has(v)) { strongConnect(v) } } return stronglyConnectedComponents function strongConnect(v: A) { indices.set(v, index) lowlinks.set(v, index++) stack.push(v) onStack.add(v) const dependencies = dependencyMap.get(v) if (dependencies) { for (const dependency of dependencies) { const hasNotBeenSeenBefore = !indices.has(dependency) if (hasNotBeenSeenBefore) { strongConnect(dependency) } if (hasNotBeenSeenBefore || onStack.has(dependency)) { const depIndex = hasNotBeenSeenBefore ? lowlinks.get(dependency)! : indices.get(dependency)! lowlinks.set(v, Math.min(lowlinks.get(v)!, depIndex)) } } } if (lowlinks.get(v)! === indices.get(v)) { const vertices = new Set<A>() let current: A | null = null while (v !== current) { current = stack.pop()! onStack.delete(current) vertices.add(current) } stronglyConnectedComponents.push(Array.from(vertices) as NonEmptyArray<A>) } } }