Spaces:
Paused
Paused
| const AnalysisService = require('../../backend/services/analysisService'); | |
| const ScreenshotService = require('../../backend/services/screenshotService'); | |
| const AICritiqueService = require('../../backend/services/aiCritiqueService'); | |
| const VisualDesignAnalyzer = require('../../backend/services/visualDesignAnalyzer'); | |
| const CodeGenerationService = require('../../backend/services/codeGenerationService'); | |
| const { initializeDatabase } = require('../../backend/database/init'); | |
| class UXAnalyzer { | |
| constructor(config) { | |
| this.config = config; | |
| this.services = null; | |
| } | |
| async initialize() { | |
| if (this.services) return; | |
| // Initialize database | |
| await initializeDatabase(); | |
| // Initialize services | |
| const screenshotService = new ScreenshotService(this.config); | |
| const aiCritiqueService = new AICritiqueService(this.config); | |
| const visualDesignAnalyzer = new VisualDesignAnalyzer(); | |
| const codeGenerationService = new CodeGenerationService({ | |
| geminiApiKey: this.config.ai.geminiApiKey, | |
| logger: console | |
| }); | |
| const analysisService = new AnalysisService({ | |
| screenshotService, | |
| aiCritiqueService, | |
| visualDesignAnalyzer, | |
| codeGenerationService, | |
| config: this.config | |
| }); | |
| this.services = { | |
| analysisService, | |
| screenshotService, | |
| aiCritiqueService, | |
| visualDesignAnalyzer, | |
| codeGenerationService | |
| }; | |
| } | |
| async analyze(url, options = {}, progressCallback = null) { | |
| await this.initialize(); | |
| const defaultOptions = { | |
| viewports: ['desktop', 'tablet', 'mobile'], | |
| analysisType: 'comprehensive', | |
| includeAccessibility: false, | |
| includeCodeGeneration: true | |
| }; | |
| const finalOptions = { ...defaultOptions, ...options }; | |
| // Start analysis | |
| const analysisResult = await this.services.analysisService.analyzeWebsite(url, finalOptions); | |
| const analysisId = analysisResult.analysisId; | |
| // Poll for progress if callback provided | |
| if (progressCallback) { | |
| await this.monitorProgress(analysisId, progressCallback); | |
| } | |
| // Wait for completion and get results | |
| const result = await this.waitForCompletion(analysisId); | |
| return this.formatResult(result); | |
| } | |
| async monitorProgress(analysisId, callback) { | |
| const checkProgress = async () => { | |
| try { | |
| const result = await this.services.analysisService.getAnalysisResult(analysisId); | |
| if (result) { | |
| callback({ | |
| percent: result.progress || 0, | |
| stage: result.stage || 'Processing', | |
| status: result.status | |
| }); | |
| if (result.status === 'completed' || result.status === 'failed') { | |
| return; | |
| } | |
| } | |
| // Continue monitoring | |
| setTimeout(checkProgress, 2000); | |
| } catch (error) { | |
| // Continue monitoring on error | |
| setTimeout(checkProgress, 2000); | |
| } | |
| }; | |
| await checkProgress(); | |
| } | |
| async waitForCompletion(analysisId, maxWaitTime = 300000) { // 5 minutes max | |
| const startTime = Date.now(); | |
| return new Promise((resolve, reject) => { | |
| const checkCompletion = async () => { | |
| try { | |
| const result = await this.services.analysisService.getAnalysisResult(analysisId); | |
| if (result && result.status === 'completed') { | |
| resolve(result); | |
| return; | |
| } | |
| if (result && result.status === 'failed') { | |
| reject(new Error(result.errorMessage || 'Analysis failed')); | |
| return; | |
| } | |
| // Check timeout | |
| if (Date.now() - startTime > maxWaitTime) { | |
| reject(new Error('Analysis timeout')); | |
| return; | |
| } | |
| // Continue waiting | |
| setTimeout(checkCompletion, 2000); | |
| } catch (error) { | |
| reject(error); | |
| } | |
| }; | |
| checkCompletion(); | |
| }); | |
| } | |
| formatResult(rawResult) { | |
| const formatted = { | |
| id: rawResult.id, | |
| url: rawResult.url, | |
| status: rawResult.status, | |
| createdAt: rawResult.createdAt, | |
| completedAt: rawResult.completedAt, | |
| screenshots: rawResult.screenshots || [], | |
| results: rawResult.results || {} | |
| }; | |
| // Extract key results for easier CLI access | |
| if (rawResult.results) { | |
| formatted.accessibility = rawResult.results.accessibility; | |
| formatted.uxCritique = rawResult.results.ux_critique; | |
| formatted.report = rawResult.results.final_report; | |
| formatted.implementationCode = rawResult.results.implementation_code; | |
| } | |
| return formatted; | |
| } | |
| async cleanup() { | |
| if (this.services?.screenshotService) { | |
| // Close any open browsers | |
| await this.services.screenshotService.cleanup?.(); | |
| } | |
| } | |
| } | |
| module.exports = UXAnalyzer; |