(request: NodeGraphExecutionRequest)
| 316 | return extractConnectionData(targetIncomingConnections[targetIncomingConnections.length - 1], executionResults, nodeMap); |
| 317 | }; |
| 318 | export const executeNodeGraph = async (request: NodeGraphExecutionRequest): Promise<NodeGraphExecutionResult> => { |
| 319 | const { nodes, connections, nodeConfigs, executionContext, resetCounters = true } = request; |
| 320 | const startTime = performance.now(); |
| 321 | console.log(`Starting node graph execution: ${nodes.length} nodes, ${connections.length} connections`); |
| 322 | if (resetCounters) { |
| 323 | resetCounterTracking(); |
| 324 | } |
| 325 | try { |
| 326 | const nodeMap = new Map(nodes.map((node) => [node.id, node])); |
| 327 | const outgoingConnectionsBySource = new Map<string, SerializedConnection[]>(); |
| 328 | const incomingConnectionsByTarget = new Map<string, SerializedConnection[]>(); |
| 329 | const incomingEdges = new Set<string>(); |
| 330 | for (const connection of connections) { |
| 331 | const outgoingConnections = outgoingConnectionsBySource.get(connection.sourceId); |
| 332 | if (outgoingConnections) { |
| 333 | outgoingConnections.push(connection); |
| 334 | } else { |
| 335 | outgoingConnectionsBySource.set(connection.sourceId, [connection]); |
| 336 | } |
| 337 | const incomingConnections = incomingConnectionsByTarget.get(connection.targetId); |
| 338 | if (incomingConnections) { |
| 339 | incomingConnections.push(connection); |
| 340 | } else { |
| 341 | incomingConnectionsByTarget.set(connection.targetId, [connection]); |
| 342 | } |
| 343 | incomingEdges.add(connection.targetId); |
| 344 | } |
| 345 | const startingNodes = nodes.filter((node) => !incomingEdges.has(node.id)); |
| 346 | if (startingNodes.length === 0) { |
| 347 | return { |
| 348 | success: false, |
| 349 | executionResults: new Map(), |
| 350 | totalExecuted: 0, |
| 351 | successCount: 0, |
| 352 | failureCount: 0, |
| 353 | error: "No starting nodes found in the graph", |
| 354 | }; |
| 355 | } |
| 356 | flowExecutionDebugLog( |
| 357 | executionContext, |
| 358 | `Graph starting nodes: ${startingNodes.map((node) => `${node.id}(${node.type})`).join(", ")}`, |
| 359 | ); |
| 360 | const executionResults = new Map<string, NodeExecutionResult>(); |
| 361 | const executed = new Set<string>(); |
| 362 | const executionQueue = startingNodes.map((node) => ({ node, inputData: null as any })); |
| 363 | let queueIndex = 0; |
| 364 | while (queueIndex < executionQueue.length) { |
| 365 | const { node, inputData } = executionQueue[queueIndex++]; |
| 366 | if (executed.has(node.id)) { |
| 367 | continue; |
| 368 | } |
| 369 | try { |
| 370 | flowExecutionDebugLog(executionContext, `Executing node ${node.id} (${node.type})`); |
| 371 | const config = nodeConfigs?.[node.id]; |
| 372 | const textValue = |
| 373 | config === undefined ? serializeNodeConfigForExecution(node) : typeof config === "string" ? config : ""; |
| 374 | const result = await executeNodeAction({ |
| 375 | nodeId: node.id, |
no test coverage detected