From 0e6ec21e81b5cdec8e7b567ad815452e6190ad26 Mon Sep 17 00:00:00 2001 From: mariosemes Date: Thu, 26 Mar 2026 22:28:35 +0100 Subject: [PATCH] Add event loop yields so SSE events flush during search Without yields, the async operations block the event loop and SSE events pile up unsent until the entire search completes. Adding setTimeout(0) yields after start and store_complete events lets Node.js flush the write buffer to the client. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/server/scraper/engine.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/server/scraper/engine.ts b/src/server/scraper/engine.ts index 0eb3d31..9775e17 100644 --- a/src/server/scraper/engine.ts +++ b/src/server/scraper/engine.ts @@ -161,6 +161,9 @@ export async function searchStreaming( stores: stores.map((s) => ({ id: s.id, name: s.name, renderJs: !!s.render_js })), }); + // Yield to event loop so the SSE start event flushes to client + await new Promise((r) => setTimeout(r, 0)); + const limit = pLimit(MAX_CONCURRENCY); const errors: SearchResult['meta']['errors'] = []; let totalResults = 0; @@ -193,6 +196,9 @@ export async function searchStreaming( resultCount: products.length, duration, }); + + // Yield so SSE event flushes to client + await new Promise((r) => setTimeout(r, 0)); } catch (err) { const duration = Date.now() - storeStart; const errorMessage = err instanceof Error ? err.message : String(err);