diff --git a/app/api/enhanced-screenshot/route.js b/app/api/enhanced-screenshot/route.js index 44a7e6a..1a8fcb0 100644 --- a/app/api/enhanced-screenshot/route.js +++ b/app/api/enhanced-screenshot/route.js @@ -6,13 +6,13 @@ import { progressTracker } from '../../../lib/progress-tracker' export async function POST(request) { try { const body = await request.json() - const { symbol, layouts, timeframe, timeframes, selectedLayouts, analyze = true } = body + const { symbol, layouts, timeframe, timeframes, selectedLayouts, analyze = true, sessionId: providedSessionId } = body - console.log('📊 Enhanced screenshot request:', { symbol, layouts, timeframe, timeframes, selectedLayouts }) + console.log('📊 Enhanced screenshot request:', { symbol, layouts, timeframe, timeframes, selectedLayouts, providedSessionId }) - // Generate unique session ID for progress tracking - const sessionId = `analysis_${Date.now()}_${Math.random().toString(36).substr(2, 9)}` - console.log('🔍 Created session ID:', sessionId) + // Use provided sessionId or generate one + const sessionId = providedSessionId || `analysis_${Date.now()}_${Math.random().toString(36).substr(2, 9)}` + console.log('🔍 Using session ID:', sessionId) // Create progress tracking session with initial steps const initialSteps = [ diff --git a/app/api/progress/[sessionId]/stream/route.ts b/app/api/progress/[sessionId]/stream/route.ts index 6d50e12..663b7bb 100644 --- a/app/api/progress/[sessionId]/stream/route.ts +++ b/app/api/progress/[sessionId]/stream/route.ts @@ -12,21 +12,30 @@ export async function GET( const stream = new ReadableStream({ start(controller) { + console.log(`🔍 Starting EventSource stream for session: ${sessionId}`) + // Send initial progress if session exists const initialProgress = progressTracker.getProgress(sessionId) if (initialProgress) { + console.log(`🔍 Sending initial progress for ${sessionId}:`, initialProgress.currentStep) const data = `data: ${JSON.stringify(initialProgress)}\n\n` controller.enqueue(encoder.encode(data)) + } else { + // Send a connection established message even if no progress yet + const connectMsg = `data: ${JSON.stringify({ type: 'connected', sessionId })}\n\n` + controller.enqueue(encoder.encode(connectMsg)) } // Listen for progress updates const progressHandler = (progress: any) => { + console.log(`🔍 Streaming progress update for ${sessionId}:`, progress.currentStep) const data = `data: ${JSON.stringify(progress)}\n\n` controller.enqueue(encoder.encode(data)) } // Listen for completion const completeHandler = () => { + console.log(`🔍 Streaming completion for ${sessionId}`) const data = `data: ${JSON.stringify({ type: 'complete' })}\n\n` controller.enqueue(encoder.encode(data)) controller.close() diff --git a/components/AIAnalysisPanel.tsx b/components/AIAnalysisPanel.tsx index 3600650..b4c3f46 100644 --- a/components/AIAnalysisPanel.tsx +++ b/components/AIAnalysisPanel.tsx @@ -40,6 +40,7 @@ interface ProgressStep { } interface AnalysisProgress { + sessionId: string currentStep: number totalSteps: number steps: ProgressStep[] @@ -82,6 +83,8 @@ export default function AIAnalysisPanel({ onAnalysisComplete }: AIAnalysisPanelP // Real-time progress tracking const startProgressTracking = (sessionId: string) => { + console.log(`🔍 Starting progress tracking for session: ${sessionId}`) + // Close existing connection if (eventSource) { eventSource.close() @@ -89,13 +92,23 @@ export default function AIAnalysisPanel({ onAnalysisComplete }: AIAnalysisPanelP const es = new EventSource(`/api/progress/${sessionId}/stream`) + es.onopen = () => { + console.log(`🔍 EventSource connection opened for ${sessionId}`) + } + es.onmessage = (event) => { try { const progressData = JSON.parse(event.data) + console.log(`🔍 Received progress update for ${sessionId}:`, progressData) + if (progressData.type === 'complete') { + console.log(`🔍 Analysis complete for ${sessionId}`) es.close() setEventSource(null) + } else if (progressData.type === 'connected') { + console.log(`🔍 EventSource connected for ${sessionId}`) } else { + // Update progress state immediately setProgress(progressData) } } catch (error) { @@ -203,6 +216,11 @@ export default function AIAnalysisPanel({ onAnalysisComplete }: AIAnalysisPanelP try { if (analysisTimeframes.length === 1) { // Single timeframe analysis with real-time progress + + // Pre-generate sessionId and start progress tracking BEFORE making the API call + const sessionId = `analysis_${Date.now()}_${Math.random().toString(36).substr(2, 9)}` + startProgressTracking(sessionId) + const response = await fetch('/api/enhanced-screenshot', { method: 'POST', headers: { 'Content-Type': 'application/json' }, @@ -210,7 +228,8 @@ export default function AIAnalysisPanel({ onAnalysisComplete }: AIAnalysisPanelP symbol: analysisSymbol, timeframe: analysisTimeframes[0], layouts: selectedLayouts, - analyze: true + analyze: true, + sessionId: sessionId // Pass pre-generated sessionId }) }) @@ -220,11 +239,6 @@ export default function AIAnalysisPanel({ onAnalysisComplete }: AIAnalysisPanelP throw new Error(data.error || 'Analysis failed') } - // Start real-time progress tracking if sessionId is provided - if (data.sessionId) { - startProgressTracking(data.sessionId) - } - setResult(data) // Call the callback with analysis result if provided diff --git a/lib/progress-tracker.ts b/lib/progress-tracker.ts index 1ae151a..beac288 100644 --- a/lib/progress-tracker.ts +++ b/lib/progress-tracker.ts @@ -36,7 +36,12 @@ class ProgressTracker extends EventEmitter { } this.sessions.set(sessionId, progress) - this.emit(`progress:${sessionId}`, progress) + + // Small delay to ensure EventSource connection is established before emitting + setTimeout(() => { + this.emit(`progress:${sessionId}`, progress) + }, 100) + return progress } @@ -77,7 +82,11 @@ class ProgressTracker extends EventEmitter { this.sessions.set(sessionId, updatedProgress) console.log(`🔍 Emitting progress event for ${sessionId}, currentStep: ${updatedProgress.currentStep}`) - this.emit(`progress:${sessionId}`, updatedProgress) + + // Small delay to ensure proper event ordering and prevent race conditions + setTimeout(() => { + this.emit(`progress:${sessionId}`, updatedProgress) + }, 50) } updateTimeframeProgress(sessionId: string, current: number, total: number, currentTimeframe?: string): void {