MCPcopy Index your code
hub / github.com/simstudioai/sim / findGroupCycle

Function findGroupCycle

apps/sim/lib/table/workflow-columns.ts:929–971  ·  view source on GitHub ↗

* Returns the cycle as an ordered list of group ids, or null if acyclic. Edges * are induced by columns: an edge A → B exists iff B depends on a column that * A produces.

(groups: WorkflowGroup[])

Source from the content-addressed store, hash-verified

927 * A produces.
928 */
929function findGroupCycle(groups: WorkflowGroup[]): string[] | null {
930 // Map each output column → the group that produces it.
931 const producerByColumn = new Map<string, string>()
932 for (const g of groups) {
933 for (const o of g.outputs) producerByColumn.set(o.columnName, g.id)
934 }
935 const adjacency = new Map<string, string[]>()
936 for (const g of groups) {
937 const upstream = new Set<string>()
938 for (const depCol of g.dependencies?.columns ?? []) {
939 const producer = producerByColumn.get(depCol)
940 if (producer && producer !== g.id) upstream.add(producer)
941 }
942 adjacency.set(g.id, [...upstream])
943 }
944 const VISITING = 1
945 const VISITED = 2
946 const state = new Map<string, number>()
947 const stack: string[] = []
948
949 const dfs = (id: string): string[] | null => {
950 if (state.get(id) === VISITED) return null
951 if (state.get(id) === VISITING) {
952 const cycleStart = stack.indexOf(id)
953 return cycleStart >= 0 ? [...stack.slice(cycleStart), id] : [id]
954 }
955 state.set(id, VISITING)
956 stack.push(id)
957 for (const next of adjacency.get(id) ?? []) {
958 const found = dfs(next)
959 if (found) return found
960 }
961 stack.pop()
962 state.set(id, VISITED)
963 return null
964 }
965
966 for (const g of groups) {
967 const cycle = dfs(g.id)
968 if (cycle) return cycle
969 }
970 return null
971}
972
973interface SplitGroupReport {
974 groupId: string

Callers 1

validateSchemaFunction · 0.85

Calls 4

dfsFunction · 0.85
setMethod · 0.65
getMethod · 0.65
addMethod · 0.45

Tested by

no test coverage detected