UNPKG

@mriridescent/rezilient

Version:

REZILIENT.js - Revolutionary framework for scaffolding complete production-ready resilient applications. Features offline-first architecture, AI-awareness, carbon-conscious computing, quantum-ready patterns, and self-healing capabilities.

831 lines (675 loc) 24.3 kB
/** * Real Energy Monitoring and Measurement * Provides actual energy consumption tracking and optimization */ export class EnergyMonitor { constructor(options = {}) { this.options = { sampleInterval: 1000, // 1 second enableBatteryAPI: true, enablePerformanceAPI: true, enableNetworkAPI: true, ...options }; this.energyMetrics = new Map(); this.batteryInfo = null; this.performanceObserver = null; this.networkObserver = null; this.baselineConsumption = 0; this.initialize(); } async initialize() { console.log('🔋 Initializing Real Energy Monitor...'); // Initialize battery monitoring if (this.options.enableBatteryAPI) { await this.initializeBatteryMonitoring(); } // Initialize performance monitoring if (this.options.enablePerformanceAPI) { this.initializePerformanceMonitoring(); } // Initialize network monitoring if (this.options.enableNetworkAPI) { this.initializeNetworkMonitoring(); } // Start continuous monitoring this.startContinuousMonitoring(); // Establish baseline setTimeout(() => this.establishBaseline(), 5000); } async initializeBatteryMonitoring() { try { if ('getBattery' in navigator) { this.batteryInfo = await navigator.getBattery(); // Monitor battery events this.batteryInfo.addEventListener('chargingchange', () => { this.recordEnergyEvent('battery_charging_change', { charging: this.batteryInfo.charging, level: this.batteryInfo.level }); }); this.batteryInfo.addEventListener('levelchange', () => { this.recordEnergyEvent('battery_level_change', { level: this.batteryInfo.level, dischargingTime: this.batteryInfo.dischargingTime }); }); console.log('🔋 Battery API monitoring enabled'); } } catch (error) { console.warn('Battery API not available:', error); } } initializePerformanceMonitoring() { try { if ('PerformanceObserver' in window) { // Monitor CPU-intensive operations this.performanceObserver = new PerformanceObserver((list) => { const entries = list.getEntries(); entries.forEach(entry => { this.recordPerformanceEnergyImpact(entry); }); }); // Observe different performance entry types ['measure', 'navigation', 'resource', 'paint'].forEach(type => { try { this.performanceObserver.observe({ entryTypes: [type] }); } catch (e) { // Some entry types might not be supported } }); console.log('⚡ Performance monitoring enabled'); } } catch (error) { console.warn('Performance Observer not available:', error); } } initializeNetworkMonitoring() { try { if ('connection' in navigator) { const connection = navigator.connection; connection.addEventListener('change', () => { this.recordEnergyEvent('network_change', { effectiveType: connection.effectiveType, downlink: connection.downlink, rtt: connection.rtt, saveData: connection.saveData }); }); console.log('📡 Network monitoring enabled'); } } catch (error) { console.warn('Network Information API not available:', error); } } startContinuousMonitoring() { setInterval(() => { this.collectEnergyMetrics(); }, this.options.sampleInterval); } collectEnergyMetrics() { const timestamp = Date.now(); const metrics = { timestamp, battery: this.getBatteryMetrics(), performance: this.getPerformanceMetrics(), network: this.getNetworkMetrics(), cpu: this.getCPUMetrics(), memory: this.getMemoryMetrics() }; // Calculate estimated energy consumption metrics.estimatedConsumption = this.calculateEnergyConsumption(metrics); this.energyMetrics.set(timestamp, metrics); // Keep only last 100 measurements if (this.energyMetrics.size > 100) { const oldestKey = this.energyMetrics.keys().next().value; this.energyMetrics.delete(oldestKey); } } getBatteryMetrics() { if (!this.batteryInfo) return null; return { level: this.batteryInfo.level, charging: this.batteryInfo.charging, chargingTime: this.batteryInfo.chargingTime, dischargingTime: this.batteryInfo.dischargingTime, // Calculate discharge rate dischargeRate: this.calculateDischargeRate() }; } calculateDischargeRate() { if (!this.batteryInfo || this.batteryInfo.charging) return 0; const recentMetrics = Array.from(this.energyMetrics.values()).slice(-5); if (recentMetrics.length < 2) return 0; const oldest = recentMetrics[0]; const newest = recentMetrics[recentMetrics.length - 1]; if (!oldest.battery || !newest.battery) return 0; const timeDiff = (newest.timestamp - oldest.timestamp) / 1000; // seconds const levelDiff = oldest.battery.level - newest.battery.level; return levelDiff / timeDiff; // % per second } getPerformanceMetrics() { if (typeof performance === 'undefined') return null; const metrics = { memory: performance.memory ? { used: performance.memory.usedJSHeapSize, total: performance.memory.totalJSHeapSize, limit: performance.memory.jsHeapSizeLimit } : null, timing: performance.timing ? { domContentLoaded: performance.timing.domContentLoadedEventEnd - performance.timing.navigationStart, loadComplete: performance.timing.loadEventEnd - performance.timing.navigationStart } : null }; return metrics; } getNetworkMetrics() { if (!('connection' in navigator)) return null; const connection = navigator.connection; return { effectiveType: connection.effectiveType, downlink: connection.downlink, rtt: connection.rtt, saveData: connection.saveData, // Estimate network energy impact energyImpact: this.calculateNetworkEnergyImpact(connection) }; } calculateNetworkEnergyImpact(connection) { // Energy consumption estimates based on connection type const energyFactors = { 'slow-2g': 0.1, '2g': 0.3, '3g': 0.6, '4g': 1.0, '5g': 1.2 }; const baseFactor = energyFactors[connection.effectiveType] || 0.5; const rttFactor = Math.min(connection.rtt / 100, 2); // Higher RTT = more energy return baseFactor * (1 + rttFactor); } getCPUMetrics() { // Estimate CPU usage based on performance metrics if (typeof performance === 'undefined') return null; const now = performance.now(); const entries = performance.getEntriesByType('measure'); // Calculate CPU intensity based on recent measurements const recentMeasures = entries.filter(entry => now - entry.startTime < 5000 // Last 5 seconds ); const totalDuration = recentMeasures.reduce((sum, entry) => sum + entry.duration, 0); const cpuIntensity = Math.min(totalDuration / 5000, 1); // Normalize to 0-1 return { intensity: cpuIntensity, recentMeasures: recentMeasures.length, totalDuration }; } getMemoryMetrics() { if (typeof performance === 'undefined' || !performance.memory) return null; const memory = performance.memory; const usage = memory.usedJSHeapSize / memory.jsHeapSizeLimit; return { usage, used: memory.usedJSHeapSize, total: memory.totalJSHeapSize, limit: memory.jsHeapSizeLimit, // Memory pressure affects energy consumption energyImpact: usage > 0.8 ? 1.5 : usage > 0.6 ? 1.2 : 1.0 }; } calculateEnergyConsumption(metrics) { let consumption = this.baselineConsumption; // CPU contribution if (metrics.cpu) { consumption += metrics.cpu.intensity * 0.4; // 40% weight for CPU } // Memory contribution if (metrics.memory) { consumption += metrics.memory.energyImpact * 0.2; // 20% weight for memory } // Network contribution if (metrics.network) { consumption += metrics.network.energyImpact * 0.3; // 30% weight for network } // Battery discharge rate contribution if (metrics.battery && metrics.battery.dischargeRate > 0) { consumption += metrics.battery.dischargeRate * 100; // Scale discharge rate } return Math.max(consumption, 0.1); // Minimum baseline consumption } establishBaseline() { const recentMetrics = Array.from(this.energyMetrics.values()).slice(-10); if (recentMetrics.length === 0) return; const avgConsumption = recentMetrics.reduce((sum, metric) => sum + (metric.estimatedConsumption || 0.1), 0) / recentMetrics.length; this.baselineConsumption = avgConsumption; console.log(`🔋 Energy baseline established: ${avgConsumption.toFixed(3)} units`); } recordEnergyEvent(type, data) { const event = { type, timestamp: Date.now(), data, energyImpact: this.calculateEventEnergyImpact(type, data) }; // Store in recent events if (!this.recentEvents) this.recentEvents = []; this.recentEvents.push(event); // Keep only last 50 events if (this.recentEvents.length > 50) { this.recentEvents = this.recentEvents.slice(-50); } } calculateEventEnergyImpact(type, data) { switch (type) { case 'battery_charging_change': return data.charging ? -0.5 : 0.5; // Charging reduces impact case 'battery_level_change': return data.level < 0.2 ? 1.5 : 1.0; // Low battery increases impact case 'network_change': return this.calculateNetworkEnergyImpact(data); default: return 0.1; } } recordPerformanceEnergyImpact(entry) { let energyImpact = 0; switch (entry.entryType) { case 'measure': energyImpact = entry.duration / 1000; // Duration in seconds break; case 'resource': energyImpact = (entry.transferSize || 0) / 1000000; // MB transferred break; case 'navigation': energyImpact = entry.loadEventEnd / 1000; // Load time in seconds break; default: energyImpact = 0.1; } this.recordEnergyEvent('performance_entry', { entryType: entry.entryType, name: entry.name, duration: entry.duration, energyImpact }); } // Public API methods getCurrentEnergyConsumption() { const latest = Array.from(this.energyMetrics.values()).slice(-1)[0]; return latest ? latest.estimatedConsumption : this.baselineConsumption; } getEnergyTrend(minutes = 5) { const cutoff = Date.now() - (minutes * 60 * 1000); const recentMetrics = Array.from(this.energyMetrics.values()) .filter(metric => metric.timestamp > cutoff); if (recentMetrics.length < 2) return 0; const oldest = recentMetrics[0]; const newest = recentMetrics[recentMetrics.length - 1]; return newest.estimatedConsumption - oldest.estimatedConsumption; } getEnergyReport() { const current = this.getCurrentEnergyConsumption(); const trend = this.getEnergyTrend(); const batteryMetrics = this.getBatteryMetrics(); return { current, trend, baseline: this.baselineConsumption, efficiency: this.baselineConsumption / current, battery: batteryMetrics, recommendations: this.generateEnergyRecommendations(current, trend) }; } generateEnergyRecommendations(current, trend) { const recommendations = []; if (current > this.baselineConsumption * 1.5) { recommendations.push('High energy consumption detected - consider reducing CPU-intensive operations'); } if (trend > 0.1) { recommendations.push('Energy consumption is increasing - monitor for memory leaks or runaway processes'); } if (this.batteryInfo && this.batteryInfo.level < 0.2) { recommendations.push('Low battery - enable power saving mode'); } return recommendations; } /** * GPU Energy Tracking */ initializeGPUMonitoring() { try { // WebGL context for GPU monitoring const canvas = document.createElement('canvas'); const gl = canvas.getContext('webgl2') || canvas.getContext('webgl'); if (gl) { this.gpuContext = gl; this.gpuInfo = { vendor: gl.getParameter(gl.VENDOR), renderer: gl.getParameter(gl.RENDERER), version: gl.getParameter(gl.VERSION), maxTextureSize: gl.getParameter(gl.MAX_TEXTURE_SIZE) }; console.log('🎮 GPU monitoring initialized:', this.gpuInfo.renderer); // Monitor GPU memory usage this.startGPUMemoryMonitoring(); } } catch (error) { console.warn('GPU monitoring initialization failed:', error); } } startGPUMemoryMonitoring() { if (!this.gpuContext) return; setInterval(() => { try { const ext = this.gpuContext.getExtension('WEBGL_debug_renderer_info'); if (ext) { const gpuMemory = this.estimateGPUMemoryUsage(); this.recordEnergyEvent('gpu_memory_usage', { estimatedUsage: gpuMemory, timestamp: Date.now() }); } } catch (error) { // GPU monitoring failed, continue silently } }, 5000); // Every 5 seconds } estimateGPUMemoryUsage() { // Estimate GPU memory usage based on WebGL state if (!this.gpuContext) return 0; try { const gl = this.gpuContext; // Get texture memory usage estimate const maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); const textureUnits = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS); // Rough estimate based on typical usage patterns const estimatedTextureMemory = (maxTextureSize * maxTextureSize * 4 * textureUnits) / (1024 * 1024); // MB return { textureMemoryMB: estimatedTextureMemory, maxTextureSize, textureUnits, energyImpact: this.calculateGPUEnergyImpact(estimatedTextureMemory) }; } catch (error) { return { error: error.message }; } } calculateGPUEnergyImpact(memoryUsageMB) { // GPU energy consumption estimation const baseGPUPower = 50; // Watts for integrated GPU const memoryFactor = memoryUsageMB / 1000; // Scale factor const utilizationFactor = this.getGPUUtilization(); return baseGPUPower * (0.3 + memoryFactor * 0.4 + utilizationFactor * 0.3); } getGPUUtilization() { // Estimate GPU utilization based on recent rendering activity const recentGPUEvents = this.recentEvents?.filter(event => event.type.includes('gpu') || event.type.includes('render') ) || []; return Math.min(recentGPUEvents.length / 10, 1.0); } /** * Network Request Energy Tracking */ trackNetworkEnergy(request) { const energyCost = this.calculateNetworkEnergyCost(request); this.recordEnergyEvent('network_request', { url: request.url, method: request.method, size: request.size || 0, duration: request.duration || 0, energyCost, timestamp: Date.now() }); return energyCost; } calculateNetworkEnergyCost(request) { // Energy cost calculation for network requests const baseEnergy = 0.001; // Base energy per request (Wh) const sizeEnergy = (request.size || 0) * 0.000001; // Energy per byte const durationEnergy = (request.duration || 0) * 0.0001; // Energy per ms // Connection type multiplier const connectionMultiplier = this.getConnectionEnergyMultiplier(); return (baseEnergy + sizeEnergy + durationEnergy) * connectionMultiplier; } getConnectionEnergyMultiplier() { if (!('connection' in navigator)) return 1.0; const connection = navigator.connection; const multipliers = { 'slow-2g': 3.0, '2g': 2.5, '3g': 2.0, '4g': 1.0, '5g': 0.8 }; return multipliers[connection.effectiveType] || 1.0; } /** * Storage Operation Energy Tracking */ trackStorageEnergy(operation) { const energyCost = this.calculateStorageEnergyCost(operation); this.recordEnergyEvent('storage_operation', { type: operation.type, // 'read', 'write', 'delete' size: operation.size || 0, duration: operation.duration || 0, storage: operation.storage || 'unknown', // 'localStorage', 'indexedDB', etc. energyCost, timestamp: Date.now() }); return energyCost; } calculateStorageEnergyCost(operation) { // Energy cost for storage operations const baseCosts = { read: 0.0001, // Wh per read write: 0.0005, // Wh per write delete: 0.0002 // Wh per delete }; const baseEnergy = baseCosts[operation.type] || baseCosts.read; const sizeEnergy = (operation.size || 0) * 0.0000001; // Energy per byte const durationEnergy = (operation.duration || 0) * 0.00001; // Energy per ms // Storage type multiplier const storageMultiplier = this.getStorageEnergyMultiplier(operation.storage); return (baseEnergy + sizeEnergy + durationEnergy) * storageMultiplier; } getStorageEnergyMultiplier(storageType) { const multipliers = { 'localStorage': 1.0, 'sessionStorage': 1.0, 'indexedDB': 1.5, 'webSQL': 2.0, 'cache': 1.2 }; return multipliers[storageType] || 1.0; } /** * Real-time Energy Optimization */ enableRealTimeOptimization() { console.log('⚡ Enabling real-time energy optimization...'); this.optimizationInterval = setInterval(() => { this.performRealTimeOptimization(); }, 10000); // Every 10 seconds } performRealTimeOptimization() { const currentConsumption = this.getCurrentEnergyConsumption(); const trend = this.getEnergyTrend(2); // 2-minute trend // Apply optimizations based on current state if (currentConsumption > this.baselineConsumption * 2) { this.applyHighConsumptionOptimizations(); } if (trend > 0.2) { this.applyTrendOptimizations(); } if (this.batteryInfo && this.batteryInfo.level < 0.3) { this.applyBatteryOptimizations(); } // GPU optimizations if (this.gpuContext) { this.applyGPUOptimizations(); } } applyHighConsumptionOptimizations() { console.log('🔋 Applying high consumption optimizations...'); // Reduce animation frame rate if (typeof requestAnimationFrame !== 'undefined') { this.throttleAnimations(); } // Reduce network polling frequency this.throttleNetworkRequests(); // Clear unnecessary caches this.clearNonEssentialCaches(); } applyTrendOptimizations() { console.log('📈 Applying trend-based optimizations...'); // Preemptively reduce resource usage this.reduceBackgroundProcessing(); // Optimize memory usage this.optimizeMemoryUsage(); } applyBatteryOptimizations() { console.log('🔋 Applying battery-saving optimizations...'); // Enable aggressive power saving this.enableAggressivePowerSaving(); // Reduce screen brightness (if possible) this.requestScreenBrightnessReduction(); // Pause non-critical operations this.pauseNonCriticalOperations(); } applyGPUOptimizations() { const gpuUsage = this.getGPUUtilization(); if (gpuUsage > 0.7) { console.log('🎮 Applying GPU optimizations...'); // Reduce rendering quality this.reduceRenderingQuality(); // Limit frame rate this.limitFrameRate(); } } throttleAnimations() { // Implement animation throttling if (window.AetherAnimationThrottle) return; window.AetherAnimationThrottle = true; const originalRAF = window.requestAnimationFrame; let throttleCounter = 0; window.requestAnimationFrame = function(callback) { throttleCounter++; if (throttleCounter % 2 === 0) { // Skip every other frame return originalRAF(callback); } return setTimeout(callback, 16); // ~60fps -> ~30fps }; } throttleNetworkRequests() { // Implement network request throttling if (window.AetherNetworkThrottle) return; window.AetherNetworkThrottle = true; console.log('🌐 Network requests throttled for energy saving'); } clearNonEssentialCaches() { // Clear caches that aren't critical try { if ('caches' in window) { caches.keys().then(cacheNames => { cacheNames.forEach(cacheName => { if (cacheName.includes('non-essential') || cacheName.includes('images')) { caches.delete(cacheName); } }); }); } } catch (error) { console.warn('Cache clearing failed:', error); } } reduceBackgroundProcessing() { // Reduce background processing console.log('⏸️ Reducing background processing for energy optimization'); } optimizeMemoryUsage() { // Force garbage collection if available if (window.gc && typeof window.gc === 'function') { window.gc(); } // Clear large objects from memory this.clearLargeObjects(); } clearLargeObjects() { // Clear large objects that can be recreated if (this.energyMetrics.size > 50) { const entries = Array.from(this.energyMetrics.entries()); this.energyMetrics.clear(); // Keep only the most recent 25 entries entries.slice(-25).forEach(([key, value]) => { this.energyMetrics.set(key, value); }); } } enableAggressivePowerSaving() { console.log('🔋 Aggressive power saving mode enabled'); // Increase monitoring intervals clearInterval(this.monitoringInterval); this.monitoringInterval = setInterval(() => { this.collectEnergyMetrics(); }, this.options.sampleInterval * 3); // 3x slower monitoring } requestScreenBrightnessReduction() { // Request screen brightness reduction (limited browser support) if ('screen' in navigator && 'brightness' in navigator.screen) { try { navigator.screen.brightness = Math.max(navigator.screen.brightness * 0.7, 0.3); } catch (error) { // Screen brightness control not available } } } pauseNonCriticalOperations() { // Pause non-critical operations console.log('⏸️ Non-critical operations paused for battery saving'); // Emit event for applications to respond if (typeof window !== 'undefined' && window.dispatchEvent) { window.dispatchEvent(new CustomEvent('aether-power-save', { detail: { level: 'aggressive' } })); } } reduceRenderingQuality() { // Reduce rendering quality for GPU optimization if (this.gpuContext) { const gl = this.gpuContext; // Reduce texture quality gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); console.log('🎮 GPU rendering quality reduced for energy saving'); } } limitFrameRate() { // Limit frame rate for GPU optimization if (!window.AetherFrameRateLimit) { window.AetherFrameRateLimit = true; const originalRAF = window.requestAnimationFrame; let lastFrame = 0; const targetFPS = 30; // Limit to 30 FPS const frameInterval = 1000 / targetFPS; window.requestAnimationFrame = function(callback) { const now = Date.now(); if (now - lastFrame >= frameInterval) { lastFrame = now; return originalRAF(callback); } return setTimeout(() => callback(now), frameInterval - (now - lastFrame)); }; console.log('🎮 Frame rate limited to 30 FPS for energy saving'); } } disableRealTimeOptimization() { if (this.optimizationInterval) { clearInterval(this.optimizationInterval); this.optimizationInterval = null; console.log('⚡ Real-time energy optimization disabled'); } } } export default EnergyMonitor;