mirror of https://github.com/langgenius/dify.git
84 lines
1.7 KiB
TypeScript
84 lines
1.7 KiB
TypeScript
import produce from 'immer'
|
|
import {
|
|
getConnectedEdges,
|
|
getOutgoers,
|
|
} from 'reactflow'
|
|
import type {
|
|
Edge,
|
|
Node,
|
|
} from './types'
|
|
|
|
export const nodesLevelOrderTraverse = (
|
|
firstNode: Node,
|
|
nodes: Node[],
|
|
edges: Edge[],
|
|
callback: (n: Node) => void,
|
|
) => {
|
|
const queue = [{
|
|
node: firstNode,
|
|
}]
|
|
|
|
while (queue.length) {
|
|
const { node } = queue.shift()!
|
|
callback(node)
|
|
|
|
const targetBranches = node.data.targetBranches
|
|
if (targetBranches?.length) {
|
|
const targetEdges = getConnectedEdges([node], edges)
|
|
|
|
if (targetEdges.length) {
|
|
const sortedTargetEdges = targetEdges
|
|
.filter(edge => edge.source === node.id)
|
|
.sort((a, b) => {
|
|
const aIndex = targetBranches.findIndex(branch => branch.id === a.sourceHandle)
|
|
const bIndex = targetBranches.findIndex(branch => branch.id === b.sourceHandle)
|
|
|
|
return aIndex - bIndex
|
|
})
|
|
|
|
const outgoers = getOutgoers(node, nodes, sortedTargetEdges)
|
|
queue.push(...outgoers.map((outgoer) => {
|
|
return {
|
|
node: outgoer,
|
|
}
|
|
}))
|
|
}
|
|
}
|
|
else {
|
|
const outgoers = getOutgoers(node, nodes, edges)
|
|
|
|
if (outgoers.length === 1) {
|
|
queue.push({
|
|
node: outgoers[0],
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
export const initialNodesAndEdges = (nodes: Node[], edges: Edge[]) => {
|
|
const newNodes = produce(nodes, (draft) => {
|
|
draft.forEach((node) => {
|
|
node.type = 'custom'
|
|
})
|
|
})
|
|
const newEdges = produce(edges, (draft) => {
|
|
draft.forEach((edge) => {
|
|
edge.type = 'custom'
|
|
})
|
|
})
|
|
|
|
return [newNodes, newEdges]
|
|
}
|
|
|
|
export type PositionMap = {
|
|
position: {
|
|
x: number
|
|
y: number
|
|
}
|
|
index: {
|
|
x: number
|
|
y: number
|
|
}
|
|
}
|