UNPKG

@tsailab/xai

Version:

The loto-xai is an openai nodejs sdk compatible extension library.

72 lines 2.27 kB
import { createParser } from 'eventsource-parser'; import { XSseProxyError } from './xnode.sse.error'; import { fetch as globalFetch, } from './xnode.sse.types'; import { asyncStreamIterable } from './xnode.sse.util'; export async function xnodeSseFetchProxy(url, options, fetch = globalFetch) { const { eventType = 'message', onconnected, onend, onerror, onmessage, logwarn, ...fetchOptions } = options; if (!url?.length) { throw XSseProxyError.createError(`Illegal parameter of url.`); } const res = await fetch(url, fetchOptions); // error catched if (!res.ok) { let reason = ''; try { reason = await res.text(); } catch (err) { reason = err?.message ?? res.statusText; logwarn?.(err, reason); } const e = XSseProxyError.createError(reason, res); if (onerror) { onerror(e); } else { throw XSseProxyError.createError(reason, res); } } const parser = createParser({ onEvent: (em) => { if (em.event === eventType && em.data) { onmessage(em.data); } else { // ignore logwarn?.(em); } }, onError: (err) => { logwarn?.(err); onerror?.(err); }, onComment: (comment) => { logwarn?.(comment); onend?.(comment); }, }); const feed = (chunk) => { parser.feed(chunk); }; if (!res.body?.getReader) { // Vercel polyfills `fetch` with `node-fetch`, which doesn't conform to // web standards, so this is a workaround... const body = res.body; if (!body.on || !body.read) { throw new XSseProxyError(`Unsupport 'fetch' implemention`); } body.on('readable', () => { let chunk; while (null !== (chunk = body.read())) { feed(chunk.toString()); } }); } else { for await (const chunk of asyncStreamIterable(res.body)) { const str = new TextDecoder().decode(chunk); feed(str); } } } //# sourceMappingURL=xnode.sse.fetch.js.map