mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
* 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
55 lines
1.4 KiB
TypeScript
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,
|
|
}
|
|
}
|