jsonl-webstream
Version:
Lightweight library for JSON Lines web stream between browsers and Node.js environments
67 lines (66 loc) • 1.96 kB
JavaScript
class JsonLinesWriterImpl {
onWrite;
onComplete;
#onCancel;
write(data) {
if (this.onWrite) {
this.onWrite(data);
}
}
close(err) {
if (this.onComplete) {
this.onComplete(err);
}
}
onCancel(callback) {
this.#onCancel = callback;
}
cancel() {
if (this.#onCancel) {
this.#onCancel();
}
}
}
/**
* Creates a paired ReadableStream and writer for JSON Lines streaming.
*
* This function establishes a bidirectional pipeline for sending JSON data as newline-delimited JSON:
* 1. Creates a writer interface that accepts JSON values
* 2. Sets up a binary ReadableStream that encodes JSON objects to UTF-8 text
* 3. Connects the writer's events to the stream's controller
* 4. Handles proper stream termination (completion, errors, and cancellation)
*
* @returns An object containing:
* - stream: A binary ReadableStream that emits UTF-8 encoded JSON lines
* - writer: A JsonLinesWriter interface for sending JSON objects to the client
*
* @example
* // In an HTTP handler:
* const { stream, writer } = createJsonLinesSender();
* response.header("Content-Type", "application/jsonl");
* response.send(stream);
*
* // Send data at any time:
* writer.write({ message: "Hello" });
* writer.close(); // When finished
*/
export function createJsonLinesSender() {
const writer = new JsonLinesWriterImpl();
const encoder = new TextEncoder();
const stream = new ReadableStream({
type: "bytes",
start(controller) {
writer.onWrite = (data) => {
const bytes = encoder.encode(`${JSON.stringify(data)}\n`);
controller.enqueue(bytes);
};
writer.onComplete = () => {
controller.close();
};
},
cancel() {
writer.cancel();
},
});
return { stream, writer };
}