// npm i web-streams-polyfill
const streams = require("web-streams-polyfill");
const {ReadableStream, WritableStream, TransformStream} = streams;

const {TextEncoder} = require("util");

//NOTE: TransformSTream is  not yet in standard spec

// transform stream
const ts1 = new TransformStream({
    async transform(chunk, controller) {
        console.log("[transform]", chunk);
        controller.enqueue(new TextEncoder().encode(chunk));
    },
    async flush(controller) {
        console.log("[flush]");
        controller.close();
    },
});

const rs1 = new ReadableStream({
    async start(controller) {
        // called by constructor
        console.log("[start]");
        controller.enqueue("a");
        controller.enqueue("b");
        controller.enqueue("c");
    },
    async pull(controller) {
        // called read when controller's queue is empty
        console.log("[pull]");
        controller.enqueue("d");
        controller.close(); // or controller.error();
    },
    async cancel(reason) {
        // called when rs.cancel(reason)
        console.log("[cancel]", reason);
    },
});

(async () => {
    // rs.pipeThrough(ts): rs send to ts.writable
    // - returns ts.readable
    const r = rs1.pipeThrough(ts1).getReader();
    for (let n = await r.read(); !n.done; n = await r.read()) {
        console.log("[value]", n.value);
    }
})().catch(console.error);