@langchain/community
Version:
Third-party integrations for LangChain.js
78 lines (77 loc) • 2.79 kB
JavaScript
/**
* [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) with [Streams API](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API)
*
* @see https://web.dev/websocketstream/
*/
export class BaseWebSocketStream {
constructor(url, options = {}) {
Object.defineProperty(this, "url", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "connection", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "closed", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "close", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
if (options.signal?.aborted) {
throw new DOMException("This operation was aborted", "AbortError");
}
this.url = url;
const ws = this.openWebSocket(url, options);
const closeWithInfo = ({ code, reason } = {}) => ws.close(code, reason);
this.connection = new Promise((resolve, reject) => {
ws.onopen = () => {
resolve({
readable: new ReadableStream({
start(controller) {
ws.onmessage = ({ data }) => controller.enqueue(data);
ws.onerror = (e) => controller.error(e);
},
cancel: closeWithInfo,
}),
writable: new WritableStream({
write(chunk) {
ws.send(chunk);
},
abort() {
ws.close();
},
close: closeWithInfo,
}),
protocol: ws.protocol,
extensions: ws.extensions,
});
ws.removeEventListener("error", reject);
};
ws.addEventListener("error", reject);
});
this.closed = new Promise((resolve, reject) => {
ws.onclose = ({ code, reason }) => {
resolve({ code, reason });
ws.removeEventListener("error", reject);
};
ws.addEventListener("error", reject);
});
if (options.signal) {
// eslint-disable-next-line no-param-reassign
options.signal.onabort = () => ws.close();
}
this.close = closeWithInfo;
}
}