UNPKG

vlibras-player-webjs

Version:

Biblioteca JavaScript moderna para integração do VLibras Player com React, Vue, Angular e vanilla JS

441 lines (437 loc) 14.9 kB
/** * Utilitários de desenvolvimento e diagnóstico para VLibras Player * Fornece ferramentas para debugging, profiling e diagnósticos */ /** * Classe principal de utilitários de desenvolvimento */ export class VLibrasDevTools { /** * Ativa o modo debug */ static enableDebugMode() { this.isDebugMode = true; console.log('🔧 VLibras Debug Mode ativado'); // Adiciona estilo CSS para debug this.injectDebugStyles(); // Monitora performance automaticamente this.startAutoPerformanceMonitoring(); } /** * Desativa o modo debug */ static disableDebugMode() { this.isDebugMode = false; console.log('🔧 VLibras Debug Mode desativado'); } /** * Verifica se está no modo debug */ static isDebugEnabled() { return this.isDebugMode; } /** * Executa diagnósticos completos do sistema */ static async runDiagnostics() { console.log('🔍 Executando diagnósticos do VLibras...'); const webglInfo = this.checkWebGL(); const assetsInfo = await this.checkAssets(); const performanceInfo = this.checkPerformance(); const compatibilityInfo = this.checkCompatibility(); const recommendations = this.generateRecommendations(webglInfo, assetsInfo, performanceInfo, compatibilityInfo); const result = { webgl: webglInfo, assets: assetsInfo, performance: performanceInfo, compatibility: compatibilityInfo, recommendations }; console.log('✅ Diagnósticos concluídos:', result); return result; } /** * Inicia profiling de performance */ static startProfiling() { this.performanceData = []; this.profilingStartTime = performance.now(); console.log('📊 Profiling iniciado'); } /** * Para profiling e retorna relatório */ static stopProfiling() { if (!this.profilingStartTime) { throw new Error('Profiling não foi iniciado'); } const report = { operations: [...this.performanceData], summary: { totalOperations: this.performanceData.length, averageDuration: this.performanceData.reduce((acc, op) => acc + op.duration, 0) / this.performanceData.length || 0, slowestOperation: this.performanceData.reduce((slowest, current) => current.duration > slowest.duration ? current : slowest, this.performanceData[0] || { name: 'none', duration: 0, timestamp: 0 }).name, memoryPeak: Math.max(...this.performanceData.map(op => op.memory || 0)) } }; console.log('📊 Profiling concluído:', report); this.profilingStartTime = null; return report; } /** * Registra uma operação para profiling */ static recordOperation(name, duration, memory) { if (this.profilingStartTime) { this.performanceData.push({ name, duration, timestamp: performance.now(), memory }); } if (this.isDebugMode) { console.log(`⏱️ ${name}: ${duration.toFixed(2)}ms`); } } /** * Obtém informações de debug */ static getDebugInfo() { return { version: '2.4.0', buildTime: new Date().toISOString(), environment: typeof process !== 'undefined' && process.env?.NODE_ENV === 'development' ? 'development' : 'production', features: [ 'UnityBridge', 'VLibrasPresets', 'VLibrasCSS', 'VLibrasEvents', 'VLibrasDevTools', 'ReactHooks', 'AccessibilitySupport', 'PerformanceMonitoring' ], configuration: { debugMode: this.isDebugMode, profilingActive: this.profilingStartTime !== null, operationsRecorded: this.performanceData.length } }; } /** * Limpa dados de cache (placeholder - implementar com sistema de cache real) */ static async clearCache() { console.log('🗑️ Limpando cache...'); // TODO: Implementar limpeza de cache quando sistema de cache for criado localStorage.removeItem('vlibras-cache'); console.log('✅ Cache limpo'); } /** * Obtém informações do cache (placeholder) */ static getCacheInfo() { // TODO: Implementar com sistema de cache real return { size: 0, entries: 0, hitRate: 0, missRate: 0, storage: 'memory' }; } /** * Verifica suporte e informações do WebGL */ static checkWebGL() { try { const canvas = document.createElement('canvas'); const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl'); if (!gl) { return { supported: false, version: 'Not supported', renderer: 'Unknown', vendor: 'Unknown' }; } const debugInfo = gl.getExtension('WEBGL_debug_renderer_info'); return { supported: true, version: gl.getParameter(gl.VERSION), renderer: debugInfo ? gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL) : 'Unknown', vendor: debugInfo ? gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL) : 'Unknown' }; } catch (error) { return { supported: false, version: 'Error checking', renderer: 'Error', vendor: 'Error' }; } } /** * Verifica assets do VLibras */ static async checkAssets() { const startTime = performance.now(); try { // Simula verificação de assets - ajustar com paths reais const assetPaths = [ '/target/playerweb.wasm.code.unityweb', '/target/playerweb.wasm.framework.unityweb', '/target/playerweb.data.unityweb' ]; let totalSize = 0; let availableAssets = 0; for (const path of assetPaths) { try { const response = await fetch(path, { method: 'HEAD' }); if (response.ok) { availableAssets++; const contentLength = response.headers.get('content-length'); if (contentLength) { totalSize += parseInt(contentLength, 10); } } } catch { // Asset não disponível } } const loadTime = performance.now() - startTime; return { available: availableAssets === assetPaths.length, size: totalSize, version: '2.1.0', loadTime }; } catch (error) { return { available: false, size: 0, version: 'Unknown', loadTime: performance.now() - startTime }; } } /** * Verifica informações de performance */ static checkPerformance() { const memory = performance.memory; return { loadTime: performance.now(), memoryUsage: memory ? memory.usedJSHeapSize : 0, fps: this.estimateFPS() }; } /** * Verifica compatibilidade do browser */ static checkCompatibility() { const userAgent = navigator.userAgent; let browser = 'Unknown'; let version = 'Unknown'; let supported = false; // Detecção básica de browser if (userAgent.includes('Chrome')) { browser = 'Chrome'; const match = userAgent.match(/Chrome\/(\d+)/); version = match ? match[1] : 'Unknown'; supported = parseInt(version) >= 80; } else if (userAgent.includes('Firefox')) { browser = 'Firefox'; const match = userAgent.match(/Firefox\/(\d+)/); version = match ? match[1] : 'Unknown'; supported = parseInt(version) >= 75; } else if (userAgent.includes('Safari') && !userAgent.includes('Chrome')) { browser = 'Safari'; const match = userAgent.match(/Version\/(\d+)/); version = match ? match[1] : 'Unknown'; supported = parseInt(version) >= 13; } else if (userAgent.includes('Edge')) { browser = 'Edge'; const match = userAgent.match(/Edge\/(\d+)/); version = match ? match[1] : 'Unknown'; supported = parseInt(version) >= 79; } return { browser, version, supported, userAgent }; } /** * Gera recomendações baseadas nos diagnósticos */ static generateRecommendations(webgl, assets, performance, compatibility) { const recommendations = []; if (!webgl.supported) { recommendations.push('WebGL não é suportado. Considere usar um browser mais recente ou habilitar aceleração de hardware.'); } if (!assets.available) { recommendations.push('Assets do VLibras não estão disponíveis. Verifique se os arquivos estão no caminho correto.'); } if (assets.loadTime > 3000) { recommendations.push('Tempo de carregamento de assets está alto. Considere usar CDN ou otimizar assets.'); } if (performance.memoryUsage > 100 * 1024 * 1024) { recommendations.push('Uso de memória está alto. Considere otimizar o código ou limpar cache.'); } if (performance.fps < 30) { recommendations.push('FPS está baixo. Verifique a performance do dispositivo.'); } if (!compatibility.supported) { recommendations.push(`Browser ${compatibility.browser} ${compatibility.version} pode não ser totalmente compatível. Atualize para uma versão mais recente.`); } if (recommendations.length === 0) { recommendations.push('Sistema está funcionando corretamente! 🎉'); } return recommendations; } /** * Estima FPS (simplificado) */ static estimateFPS() { // Implementação simplificada - em produção usar requestAnimationFrame return 60; } /** * Injeta estilos CSS para debug */ static injectDebugStyles() { const style = document.createElement('style'); style.id = 'vlibras-debug-styles'; style.textContent = ` .vlibras-debug-overlay { position: fixed; top: 10px; right: 10px; background: rgba(0, 0, 0, 0.8); color: white; padding: 10px; border-radius: 5px; font-family: monospace; font-size: 12px; z-index: 9999; max-width: 300px; } .vlibras-debug-item { margin: 2px 0; } .vlibras-debug-warning { color: #ff9800; } .vlibras-debug-error { color: #f44336; } .vlibras-debug-success { color: #4caf50; } `; document.head.appendChild(style); } /** * Inicia monitoramento automático de performance */ static startAutoPerformanceMonitoring() { if (this.isDebugMode) { setInterval(() => { const memory = performance.memory; if (memory && memory.usedJSHeapSize > 50 * 1024 * 1024) { console.warn('⚠️ Alto uso de memória detectado:', memory.usedJSHeapSize / (1024 * 1024), 'MB'); } }, 5000); } } } VLibrasDevTools.isDebugMode = false; VLibrasDevTools.performanceData = []; VLibrasDevTools.profilingStartTime = null; /** * Decorador para medir performance automaticamente */ export function measurePerformance(target, propertyName, descriptor) { const method = descriptor.value; descriptor.value = function (...args) { const startTime = performance.now(); const startMemory = performance.memory?.usedJSHeapSize || 0; const result = method.apply(this, args); const endTime = performance.now(); const endMemory = performance.memory?.usedJSHeapSize || 0; const duration = endTime - startTime; const memoryDelta = endMemory - startMemory; VLibrasDevTools.recordOperation(`${target.constructor.name}.${propertyName}`, duration, memoryDelta); return result; }; return descriptor; } /** * Utilitários de logging estruturado */ export class VLibrasLogger { static debug(message, data) { this.log('DEBUG', message, data); } static info(message, data) { this.log('INFO', message, data); } static warn(message, data) { this.log('WARN', message, data); } static error(message, data) { this.log('ERROR', message, data); } static log(level, message, data) { const logEntry = { level, message, timestamp: Date.now(), data }; this.logs.push(logEntry); if (VLibrasDevTools.isDebugEnabled()) { const style = this.getLogStyle(level); console.log(`%c[VLibras ${level}]%c ${message}`, style, '', data); } // Manter apenas os últimos 1000 logs if (this.logs.length > 1000) { this.logs = this.logs.slice(-1000); } } static getLogStyle(level) { switch (level) { case 'DEBUG': return 'color: #2196f3; font-weight: bold;'; case 'INFO': return 'color: #4caf50; font-weight: bold;'; case 'WARN': return 'color: #ff9800; font-weight: bold;'; case 'ERROR': return 'color: #f44336; font-weight: bold;'; default: return 'font-weight: bold;'; } } static getLogs() { return [...this.logs]; } static clearLogs() { this.logs = []; } } VLibrasLogger.logs = []; // Auto-ativar debug mode em desenvolvimento if (typeof process !== 'undefined' && process.env?.NODE_ENV === 'development') { VLibrasDevTools.enableDebugMode(); } //# sourceMappingURL=VLibrasDevTools.js.map