// searchWorker.js — runs inside a worker_thread, fully isolated from the // main WS server. Receives a query via workerData, performs the Gradio // search, posts the result back via parentPort, then exits. // // Because this runs in its own V8 context / event loop, the Gradio client's // internal SSE fetch stream cannot interfere with the main thread's ws server. import { workerData, parentPort } from 'worker_threads'; import { Client } from '@gradio/client'; async function run() { const { query } = workerData; let client = null; try { client = await Client.connect('incognitolm/Web-Search'); const result = await client.predict('/perform_search', { query }); const raw = Array.isArray(result.data) ? result.data[0] : result.data; if (!raw) throw new Error('Empty response from search endpoint'); const text = typeof raw === 'string' ? raw : JSON.stringify(raw); parentPort.postMessage({ ok: true, result: text }); } catch (err) { parentPort.postMessage({ ok: false, error: String(err) }); } finally { try { client?.close?.(); } catch (_) {} // Force-exit so the worker doesn't hang on lingering async handles // (the SSE response body reader, heartbeat timer, etc.) setTimeout(() => process.exit(0), 0); } } run();