import { extractTriggersFromPoint } from "./extractTriggersFromPoint"; export async function determineExecutionMachineSequences(products: productsSchema): Promise { const pointToEventMap = new Map(); const allPoints: PointsScheme[] = []; // First pass: map points to their corresponding events products.forEach(product => { product.eventDatas.forEach(event => { if (event.type === 'transfer') { event.points.forEach(point => { pointToEventMap.set(point.uuid, event); allPoints.push(point); }); } else if ( event.type === 'vehicle' || event.type === 'machine' || event.type === 'storageUnit' || event.type === 'roboticArm' ) { pointToEventMap.set(event.point.uuid, event); allPoints.push(event.point); } }); }); // Build 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 && pointToEventMap.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); }); // Find root points (points that trigger others but are not triggered themselves) const rootPoints = allPoints.filter(point => { const hasOutgoingTriggers = extractTriggersFromPoint(point).some( t => t.triggeredAsset?.triggeredPoint?.pointUuid ); return hasOutgoingTriggers && !triggeredPoints.has(point.uuid); }); const executionSequences: EventsSchema[][] = []; function buildSequence(startUuid: string): EventsSchema[] { const sequence: EventsSchema[] = []; const visited = new Set(); function traverse(uuid: string) { if (visited.has(uuid)) return; visited.add(uuid); const event = pointToEventMap.get(uuid); if (event && !sequence.includes(event)) { sequence.push(event); } const nextPoints = dependencyGraph.get(uuid) || []; nextPoints.forEach(nextUuid => traverse(nextUuid)); } traverse(startUuid); return sequence; } // Build sequences from root points rootPoints.forEach(root => { executionSequences.push(buildSequence(root.uuid)); }); // Handle any isolated triggered points const processedEvents = new Set( executionSequences.flat().map(event => event) ); allPoints.forEach(point => { const event = pointToEventMap.get(point.uuid); if (triggeredPoints.has(point.uuid) && event && !processedEvents.has(event)) { executionSequences.push(buildSequence(point.uuid)); } }); return executionSequences; }