weaviate-agents
Version:
JS/TS client for Weaviate Agents
86 lines (85 loc) • 4.16 kB
JavaScript
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var g = generator.apply(thisArg, _arguments || []), i, q = [];
return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;
function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }
function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
function fulfill(value) { resume("next", value); }
function reject(value) { resume("throw", value); }
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
};
/**
* Fetch Server-Sent Events (SSE) from a URL.
*
* All fields other than "event" and "data" are ignored
*
* @param input - The URL to fetch the SSE from.
* @param init - The request init options.
* @returns An async generator of ServerSentEvent objects.
*/
export function fetchServerSentEvents(input, init) {
return __asyncGenerator(this, arguments, function* fetchServerSentEvents_1() {
const response = yield __await(fetch(input, Object.assign(Object.assign({}, init), { headers: Object.assign(Object.assign({}, init === null || init === void 0 ? void 0 : init.headers), { Accept: "text/event-stream" }) })));
if (!response.ok || !response.body) {
throw Error(`Query agent streaming failed. ${yield __await(response.text())}`);
}
const reader = response.body.getReader();
const textDecoder = new TextDecoder("utf-8");
let buffer = "";
while (true) {
const { done, value } = yield __await(reader.read());
if (done) {
break;
}
// Use a buffer to accumulate text until we have a complete SSE (delimited by blank lines)
buffer += textDecoder.decode(value, { stream: true });
const { events, remainingBuffer } = parseServerSentEvents(buffer);
for (const event of events) {
yield yield __await(event);
}
buffer = remainingBuffer;
}
// Flush the remaining buffer
const { events } = parseServerSentEvents(buffer, true);
for (const event of events) {
yield yield __await(event);
}
});
}
function parseServerSentEvents(buffer, flush) {
var _a;
// Server sent events are delimited by blank lines,
// and may be spread across multiple chunks from the API
const sseChunks = buffer.split(/\r?\n\r?\n/);
let remainingBuffer = "";
if (flush !== true) {
// Put the (possibly incomplete) final event back into the buffer
remainingBuffer = (_a = sseChunks.pop()) !== null && _a !== void 0 ? _a : "";
}
const events = [];
for (const chunk of sseChunks) {
const lines = chunk.split(/\r?\n/);
let event = "message";
let data = "";
for (const line of lines) {
if (line.startsWith("event:")) {
// Replace event name if we get one
event = line.slice("event:".length).trim();
}
else if (line.startsWith("data:")) {
if (data) {
// Data was spread across multiple lines
data += "\n";
}
data += line.slice("data:".length).trim();
}
}
if (data) {
events.push({ event, data });
}
}
return { events, remainingBuffer };
}