// cockpit/fester-module/targets.js /** * Fester Targets Module * Handles nodes, edges, metrics, heatmaps, and live updates for cockpit UI. */ (function(global) { const targetsModule = { nodes: {}, edges: [], metrics: {}, heatmaps: {}, callbacks: [], /** * Register a callback to receive updated DAG data */ onUpdate(callback) { if (typeof callback === 'function') { this.callbacks.push(callback); } }, /** * Update the internal state from WS or iframe message */ update(data) { if (!data) return; if (data.nodes) { data.nodes.forEach(node => this.nodes[node.id] = node); } if (data.edges) { this.edges = data.edges; } if (data.metrics) { Object.assign(this.metrics, data.metrics); } if (data.heatmaps) { Object.assign(this.heatmaps, data.heatmaps); } this.dispatch(); }, /** * Notify all registered callbacks with the updated data */ dispatch() { const snapshot = { nodes: Object.values(this.nodes), edges: this.edges, metrics: this.metrics, heatmaps: this.heatmaps }; this.callbacks.forEach(cb => cb(snapshot)); }, /** * Clear all stored DAG state */ clear() { this.nodes = {}; this.edges = []; this.metrics = {}; this.heatmaps = {}; this.dispatch(); } }; // Listen for iframe messages from cockpit.html window.addEventListener('message', (event) => { const data = event.data; if (data && typeof data === 'object') { targetsModule.update(data); } }); // Expose module globally global.FesterTargets = targetsModule; })(window);