import { Video } from '@/lib/types'; import { getSourceName } from '@/lib/utils/source-names'; import { calculateRelevanceScore, hasMinimumMatch } from '@/lib/utils/search'; interface StreamHandlerParams { reader: ReadableStreamDefaultReader; onStart: (totalSources: number) => void; onVideos: (videos: Video[], source: string) => void; onProgress: (completedSources: number, totalVideosFound: number) => void; onComplete: () => void; onError: (message: string) => void; currentQuery: string; } export async function processSearchStream({ reader, onStart, onVideos, onProgress, onComplete, onError, currentQuery, }: StreamHandlerParams) { const decoder = new TextDecoder(); let buffer = ''; let timeoutId: NodeJS.Timeout | null = null; let isCompleted = false; // Auto-complete if no progress for 3 seconds const resetTimeout = () => { if (timeoutId) clearTimeout(timeoutId); timeoutId = setTimeout(() => { if (!isCompleted) { isCompleted = true; onComplete(); } }, 3000); }; try { resetTimeout(); // Start initial timeout while (true) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value, { stream: true }); const lines = buffer.split('\n'); buffer = lines.pop() || ''; for (const line of lines) { if (!line.startsWith('data: ')) continue; try { const data = JSON.parse(line.slice(6)); if (data.type === 'start') { onStart(data.totalSources); resetTimeout(); } else if (data.type === 'videos') { const newVideos: Video[] = data.videos .filter((video: any) => hasMinimumMatch(video.vod_name, currentQuery)) .map((video: any) => ({ ...video, sourceName: video.sourceDisplayName || getSourceName(video.source), isNew: true, relevanceScore: calculateRelevanceScore(video, currentQuery), })); onVideos(newVideos, data.source); resetTimeout(); } else if (data.type === 'progress') { onProgress(data.completedSources, data.totalVideosFound); resetTimeout(); } else if (data.type === 'complete') { if (timeoutId) clearTimeout(timeoutId); isCompleted = true; onComplete(); } else if (data.type === 'error') { onError(data.message); } } catch (error) { console.error('Error parsing stream data:', error); } } } } catch (error) { if (timeoutId) clearTimeout(timeoutId); throw error; } finally { if (timeoutId) clearTimeout(timeoutId); } }