/** * Performance Profiler Module * * Provides performance profiling with flamegraph and timeline visualization * for LiveComponents and general application performance analysis. * * @module performance-profiler */ import { PerformanceProfiler, LiveComponentsProfiler } from './profiler.js'; import { FlamegraphVisualizer, TimelineVisualizer } from './visualizer.js'; export const definition = { name: 'performance-profiler', version: '1.0.0', dependencies: [], provides: ['performance-profiling', 'flamegraph', 'timeline'], priority: 0 }; let globalProfiler = null; let flamegraphViz = null; let timelineViz = null; /** * Initialize performance profiler module * @param {Object} config - Module configuration * @param {Object} state - Module state manager */ export async function init(config = {}, state) { console.log('[PerformanceProfiler] Initializing performance profiler module'); const enabled = config.enabled ?? false; // Create global profiler instance globalProfiler = new PerformanceProfiler({ enabled, maxSamples: config.maxSamples ?? 1000, samplingInterval: config.samplingInterval ?? 10, autoStart: config.autoStart ?? false }); // Initialize visualizers if containers exist if (config.flamegraphContainer) { const container = document.querySelector(config.flamegraphContainer); if (container) { flamegraphViz = new FlamegraphVisualizer(container, config.flamegraph ?? {}); console.log('[PerformanceProfiler] Flamegraph visualizer initialized'); } } if (config.timelineContainer) { const container = document.querySelector(config.timelineContainer); if (container) { timelineViz = new TimelineVisualizer(container, config.timeline ?? {}); console.log('[PerformanceProfiler] Timeline visualizer initialized'); } } // Expose global API if (typeof window !== 'undefined') { window.PerformanceProfiler = { profiler: globalProfiler, flamegraph: flamegraphViz, timeline: timelineViz, // Convenience methods start: () => globalProfiler.start(), stop: () => { const results = globalProfiler.stop(); if (results) { console.log('[PerformanceProfiler] Profiling results:', results); // Auto-render visualizations if available if (flamegraphViz) { const flamegraphData = globalProfiler.generateFlamegraph(); flamegraphViz.render(flamegraphData); } if (timelineViz) { const timelineData = globalProfiler.generateTimeline(); timelineViz.render(timelineData); } } return results; }, mark: (name, metadata) => globalProfiler.mark(name, metadata), measure: (name, start, end) => globalProfiler.measure(name, start, end), exportChromeTrace: () => globalProfiler.exportToChromeTrace(), createComponentProfiler: (component, options) => { return new LiveComponentsProfiler(component, { ...options, enabled: enabled || options?.enabled }); } }; console.log('[PerformanceProfiler] Global API available at window.PerformanceProfiler'); } // Auto-instrument LiveComponents if available if (typeof window !== 'undefined' && window.LiveComponents && config.autoInstrument !== false) { instrumentLiveComponents(); } console.log('[PerformanceProfiler] Module initialized'); } /** * Auto-instrument all LiveComponents * @private */ function instrumentLiveComponents() { const liveComponents = window.LiveComponents; if (!liveComponents || !liveComponents.registry) { console.warn('[PerformanceProfiler] LiveComponents not available for instrumentation'); return; } // Instrument existing components for (const [id, component] of liveComponents.registry.entries()) { const profiler = new LiveComponentsProfiler(component, { enabled: true }); // Store profiler reference component._profiler = profiler; console.log(`[PerformanceProfiler] Instrumented component: ${id}`); } // Instrument future components const originalRegister = liveComponents.register.bind(liveComponents); liveComponents.register = (id, component) => { const result = originalRegister(id, component); const profiler = new LiveComponentsProfiler(component, { enabled: true }); component._profiler = profiler; console.log(`[PerformanceProfiler] Instrumented component: ${id}`); return result; }; console.log('[PerformanceProfiler] LiveComponents instrumentation enabled'); } /** * Destroy performance profiler module */ export function destroy() { if (globalProfiler) { globalProfiler.clear(); } if (flamegraphViz) { flamegraphViz.clear(); } if (timelineViz) { timelineViz.clear(); } if (typeof window !== 'undefined') { delete window.PerformanceProfiler; } console.log('[PerformanceProfiler] Module destroyed'); } // Export classes for advanced usage export { PerformanceProfiler, LiveComponentsProfiler, FlamegraphVisualizer, TimelineVisualizer }; export default { init, destroy, definition };