Files
sim/stores/workflows/workflow/utils.ts
T
Emir Karabeg 76dbc4a52f Feat/db sync (#94)
* feat(db-sync): added general sync file and implemented environment sync

* improvement(workflows-store): structured workflows store system better and added getter for values across stores

* fix(stores): deleted workflows/types since unused

* improvement(db-sync): added workflow event syncs and debounce

* improvement(db-sync): clean and upgraded db-sync system; environment sync implemented

* improvement(db-sync): added batch sync with registry; init bug needs fixing

* improvement(db-sync): finalized sync system and implemented for workflow

* fix(db-sync): fixed client-side rendering

* improvement(db-sync): created backwards sync system; environment implemented

* improvement(db-sync): added colors to db

* fix(db-sync): color sync with db

* improvement(db-sync): added workflow backwards sync; fixing color bug and race condition

* fix(db-stores): color sync

* feature(db-sync): db-sync complete; need to sync history

* improvement(db-sync): added scheduling

* fix(db-sync): environment sync to db
2025-03-03 19:43:39 -08:00

55 lines
1.4 KiB
TypeScript

import { Edge } from 'reactflow'
/**
* Performs a depth-first search to detect all cycles in the graph
* @param edges - List of all edges in the graph
* @param startNode - Starting node for cycle detection
* @returns Array of all unique cycles found in the graph
*/
export function detectCycle(
edges: Edge[],
startNode: string
): { hasCycle: boolean; paths: string[][] } {
const visited = new Set<string>()
const recursionStack = new Set<string>()
const allCycles: string[][] = []
const currentPath: string[] = []
function dfs(node: string) {
visited.add(node)
recursionStack.add(node)
currentPath.push(node)
// Get all neighbors of current node
const neighbors = edges.filter((edge) => edge.source === node).map((edge) => edge.target)
for (const neighbor of neighbors) {
if (!recursionStack.has(neighbor)) {
if (!visited.has(neighbor)) {
dfs(neighbor)
}
} else {
// Found a cycle
const cycleStartIndex = currentPath.indexOf(neighbor)
if (cycleStartIndex !== -1) {
const cycle = currentPath.slice(cycleStartIndex)
// Only add cycles with length > 1
if (cycle.length > 1) {
allCycles.push([...cycle])
}
}
}
}
currentPath.pop()
recursionStack.delete(node)
}
dfs(startNode)
return {
hasCycle: allCycles.length > 0,
paths: allCycles,
}
}