import { extractTriggersFromPoint } from "./extractTriggersFromPoint"; export function determineExecutionSequences(products: productsSchema): PointsScheme[][] { // Create maps for all points const pointMap = new Map(); const allPoints: PointsScheme[] = []; // First pass: collect all points products.forEach(product => { product.eventDatas.forEach(event => { if (event.type === 'transfer') { event.points.forEach(point => { pointMap.set(point.uuid, point); allPoints.push(point); }); } else if (event.type === 'vehicle' || event.type === 'machine' || event.type === 'storageUnit' || event.type === 'roboticArm') { pointMap.set(event.point.uuid, event.point); allPoints.push(event.point); } }); }); // Build complete dependency graph const dependencyGraph = new Map(); const reverseDependencyGraph = new Map(); const triggeredPoints = new Set(); allPoints.forEach(point => { const triggers = extractTriggersFromPoint(point); const dependencies: string[] = []; triggers.forEach(trigger => { const targetUuid = trigger.triggeredAsset?.triggeredPoint?.pointUuid; if (targetUuid && pointMap.has(targetUuid)) { dependencies.push(targetUuid); triggeredPoints.add(targetUuid); if (!reverseDependencyGraph.has(targetUuid)) { reverseDependencyGraph.set(targetUuid, []); } reverseDependencyGraph.get(targetUuid)!.push(point.uuid); } }); dependencyGraph.set(point.uuid, dependencies); }); // Identify independent root points (points that trigger others but aren't triggered themselves) const rootPoints = allPoints.filter(point => { const hasOutgoingTriggers = extractTriggersFromPoint(point).some( t => t.triggeredAsset?.triggeredPoint?.pointUuid ); return hasOutgoingTriggers && !triggeredPoints.has(point.uuid); }); // For each root point, build its complete trigger chain const executionSequences: PointsScheme[][] = []; function buildSequence(startUuid: string): PointsScheme[] { const sequence: PointsScheme[] = []; const visited = new Set(); function traverse(uuid: string) { if (visited.has(uuid)) return; visited.add(uuid); const point = pointMap.get(uuid); if (point) { sequence.push(point); } // Follow forward dependencies const nextPoints = dependencyGraph.get(uuid) || []; nextPoints.forEach(nextUuid => traverse(nextUuid)); } traverse(startUuid); return sequence; } // Build sequences for all root points rootPoints.forEach(root => { executionSequences.push(buildSequence(root.uuid)); }); // Handle any triggered points not reachable from roots (isolated chains) const processedPoints = new Set( executionSequences.flat().map(p => p.uuid) ); allPoints.forEach(point => { if (triggeredPoints.has(point.uuid) && !processedPoints.has(point.uuid)) { executionSequences.push(buildSequence(point.uuid)); } }); return executionSequences; }