$ show rvagg/through2
Through2 is a lightweight, zero-configuration library for creating Node.js Transform streams and Web Streams (TransformStream) from simple functions. The core implementation in `through2.js` auto-dispatches between three function styles: classic callback, async function (resolved value pushed), and async generator (yields pushed, cross-chunk state as local variable). It handles backpressure, flush callbacks, and clean destruction including async generator `finally` blocks. The `web.js` entry provides a parallel API for the WHATWG Web Streams API using `{ readable, writable }` pairs that satisfy `pipeThrough`, with explicit cancellation hooks for async generators (a workaround for browser `TransformStream` missing `cancel` in some environments). The library is actively maintained, uses semantic-release with conventional commits, has CI for Node and browser (via polendina), TypeScript type declarations, and follows modern ESM packaging (also supports CJS via `require(esm)` on Node 22.12+). Its architecture is a thin facade over the `readable-stream` Transform class and native TransformStream, with careful attention to stream lifecycle, backpressure propagation, and resource cleanup.
The LLM identified 2 files worth highlighting for reuse:
Core module implementing Node.js Transform stream wrappers (`transform`, `objectTransform`, `transformer`). The `setupAsyncGen` function is a notable internal component: it drives an async generator over incoming chunks, queues them, and manages bidirectional backpressure by pausing writes when the queue exceeds writableHWM and pausing the generator when `t.push()` returns false (readable buffer full). It also ensures the generator's `finally` block runs on destroy/close. This pattern is transferable to any library that needs to bridge async generator pipelines with Node Transform streams.
Web Streams API entry point. The `asyncGenTransform` function builds a `{ readable, writable }` pair (not a `TransformStream` instance) to work around missing `Transformer.cancel` in browsers. It uses a `ReadableStream` with custom `pull` logic that drives the user's async generator on demand, and a `WritableStream` that queues writes and propagates backpressure via pending promises. Cancellation on either side finalizes the generator (runs `finally`) and errors the opposite side. This pattern is reusable for any scenario requiring a cross-runtime async generator transformation with proper cancellation semantics.