logo hsb.horse
← Zur Snippets-Übersicht

Snippets

Text mit TransformStream aufteilen

Ein TypeScript-Beispiel zur Verwendung von ReadableStream und TransformStream, um langen Text in Chunks einer bestimmten Größe aufzuteilen.

Veröffentlicht: Aktualisiert:

Ich wollte den Umgang mit der Stream API besser beherrschen und habe daher mit String-Manipulation als Beispiel experimentiert. Dies implementiert einen TransformStream, der langen Text in Arrays einer bestimmten Größe aufteilt.

Implementierung

type Ctrl = TransformStreamDefaultController<string[]>;
class TextArrayTransformStream extends TransformStream<string, string[]> {
#chunk: string[] = [];
#chunkSize: number;
#splitReg: RegExp;
constructor(chunkSize: number, maxTextLength: number) {
super({
transform: (chunk, controller) => this.#handle(chunk, controller),
flush: (controller) => this.#flush(controller),
});
this.#chunkSize = chunkSize;
this.#splitReg = new RegExp(`.{1,${maxTextLength}}`, "g");
}
#handle(chunk: string, controller: Ctrl): void {
for (const str of chunk.match(this.#splitReg) || []) {
if (this.#chunk.length >= this.#chunkSize) {
controller.enqueue(this.#chunk);
this.#chunk = [];
} else {
this.#chunk.push(str);
}
}
}
#flush(controller: Ctrl): void {
if (this.#chunk.length > 0) {
controller.enqueue(this.#chunk);
}
}
}

Hilfsfunktion

function toReadableStream(text: string): ReadableStream<string> {
return new ReadableStream({
start(controller) {
controller.enqueue(text);
controller.close();
}
});
}

Verwendungsbeispiel

async function main() {
const text = "Langer Text...";
const arrayLength = 5; // In Gruppen zu je 5 Elementen
const textLength = 10; // Jedes Element hat 10 Zeichen
const stream = toReadableStream(text)
.pipeThrough(new TextArrayTransformStream(arrayLength, textLength));
const reader = stream.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
console.log(value); // string[] wird sequentiell ausgegeben
}
}

Anwendungsfälle

Dieses Muster ist in folgenden Szenarien effektiv:

  • Beim Batch-Verarbeiten von LLM-API-Antworten
  • Beim paginierten Anzeigen großer Textmengen
  • Vorverarbeitung vor dem Senden an APIs mit Zeichenbegrenzung

Beachten Sie, dass AsyncIterator nicht implementiert ist, daher kann die for await…of-Syntax nicht verwendet werden.