mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-02 07:43:42 +08:00
Readable, Writable, Duplex, Transform and PassThrough take the objectMode option, and a Duplex, Transform or PassThrough the readableObjectMode and writableObjectMode options, as true or false literals in an options object literal or in an options value. An object-mode side holds any value that converts to a checked-dynamic value: push, unshift, write, end, pipe, pipeline, for await, 'data' listeners, Readable.from and the transform callback carry values in TypeScript and JavaScript, and constructor-function streams and options held in variables do the same. The object-mode high-water mark counts values and defaults to 16. A readable buffer that mixes strings, Buffers and other values holds them all, and push(undefined) and other values on a byte-mode stream report ERR_INVALID_ARG_TYPE through 'error', as in Node. In typed code a write or transform callback, or a _write or _transform method, may declare its chunk with any such type, which converts when the callback runs. Writes pass the encoding argument to _write and _transform as Node does: undefined when absent, null when a callback took its place, otherwise the value unchanged. A parameter declared string | null | undefined receives that value and one declared string receives "" for undefined and null. write(chunk, encoding) on a byte-mode stream encodes a string chunk with any known encoding and throws ERR_UNKNOWN_ENCODING for an unknown one. Readable.from takes typed Maps and Sets of any such value, and arrays that mix strings and Buffers. for await over a readable-only stream that will emit 'close' now ends after 'close', as Node's eos does. Buffered writes that complete inside clearBuffer run their callbacks in order, and 'finish' waits for a deferred afterWrite that carries a callback, as Node's pendingcb does, unless a _final callback schedules it. The 'data' listener adapters take three slots and write and transform callbacks read their chunk and encoding through runtime accessors, so RUNTIME_ABI_VERSION is now 26.
80 lines
2.1 KiB
TypeScript
80 lines
2.1 KiB
TypeScript
// Typed object-mode stream subclasses: Transform, Writable and Readable
|
|
// classes that pass objectMode to super(), _transform/_write/_read with
|
|
// record chunks, encoding parameters typed string | null | undefined, and
|
|
// push() of records and other values.
|
|
import { Readable, Transform, Writable } from "node:stream";
|
|
import { pipeline } from "node:stream/promises";
|
|
|
|
interface Order {
|
|
id: number;
|
|
items: string[];
|
|
}
|
|
|
|
interface Summary {
|
|
id: number;
|
|
count: number;
|
|
}
|
|
|
|
class Orders extends Readable {
|
|
private next = 1;
|
|
constructor() {
|
|
super({ objectMode: true });
|
|
}
|
|
_read(): void {
|
|
if (this.next > 3) {
|
|
this.push(null);
|
|
return;
|
|
}
|
|
const id = this.next++;
|
|
this.push({ id, items: Array.from({ length: id }, (_, i) => `item${i}`) });
|
|
}
|
|
}
|
|
|
|
class Summarize extends Transform {
|
|
constructor() {
|
|
super({ objectMode: true });
|
|
}
|
|
_transform(
|
|
order: Order,
|
|
encoding: string | null | undefined,
|
|
cb: (err: Error | null, data?: Summary) => void,
|
|
): void {
|
|
console.log("summarize", order.id, encoding);
|
|
cb(null, { id: order.id, count: order.items.length });
|
|
}
|
|
}
|
|
|
|
class Report extends Writable {
|
|
lines: string[] = [];
|
|
constructor() {
|
|
super({ objectMode: true, highWaterMark: 1 });
|
|
}
|
|
_write(s: Summary, _encoding: string, cb: (err?: Error | null) => void): void {
|
|
this.lines.push(`#${s.id}=${s.count}`);
|
|
cb();
|
|
}
|
|
}
|
|
|
|
async function main(): Promise<void> {
|
|
const report = new Report();
|
|
console.log("report", report.writableObjectMode, report.writableHighWaterMark);
|
|
await pipeline(new Orders(), new Summarize(), report);
|
|
console.log("lines", report.lines.join(" "));
|
|
|
|
const direct = new Summarize();
|
|
direct.on("data", (s: Summary) => console.log("direct", s.id, s.count));
|
|
direct.write({ id: 9, items: ["a"] }, "utf8");
|
|
direct.write({ id: 10, items: [] }, () => console.log("written"));
|
|
direct.end();
|
|
|
|
const values = new Readable({ objectMode: true, read() {} });
|
|
values.push(1.5);
|
|
values.push("text");
|
|
values.push([1, 2]);
|
|
values.push(null);
|
|
const seen: string[] = [];
|
|
for await (const v of values) seen.push(JSON.stringify(v));
|
|
console.log("values", seen.join(" "));
|
|
}
|
|
main();
|