# stronger-typed-streams

> NodeJS Streams, but with stronger types

Latest version **0.2.0** (published 2020-10-31) · MIT license · 0 weekly downloads

## Install

```sh
npm install stronger-typed-streams
pnpm add stronger-typed-streams
yarn add stronger-typed-streams
bun add stronger-typed-streams
```

## Health

**Score 25/100 (F)** — status: abandoned.

Positive: has types; no vulnerabilities; high quality score.

Warnings: low downloads; no esm support; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.2.0 |
| Published | 2020-10-31 |
| First published | 2017-05-30 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 0 |
| Unpacked size | 31.7 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 10 |
| Author | Matthew Forrester |
| Maintainers | forbesmyster |

## Links

- npm: https://www.npmjs.com/package/stronger-typed-streams
- Repository: https://github.com/forbesmyester/stronger-typed-streams
- Homepage: https://github.com/forbesmyester/stronger-typed-streams#readme
- Issues: https://github.com/forbesmyester/stronger-typed-streams/issues
- npm.io page: https://npm.io/package/stronger-typed-streams

## Recent versions

- 0.2.0 (latest) — 2020-10-31
- 0.1.2 — 2017-06-24
- 0.1.1 — 2017-06-07
- 0.1.0 — 2017-05-30

## README

# stronger-typed-streams

While I am a fan of [RxJS](https://github.com/Reactive-Extensions/RxJS) there are still advantages to using just plain [NodeJS Streams](https://nodejs.org/api/stream.html), the main one for me being that back-pressure just works.

The TypeScript bindings for NodeJS Streams are perfectly adequate themselves but I felt that the typings could also ensure that the [Readable](https://nodejs.org/api/stream.html#stream_class_stream_readable) is outputting to a compatible [Writable](https://nodejs.org/api/stream.html#stream_class_stream_writable) or [Transform](https://nodejs.org/api/stream.html#stream_class_stream_transform).

This mini project, which really is pretty much just subclasses of the NodeJS Streams classes aims to address that deficiency. This means that if you have a model of the following:

    `Farm` -> `Bakery` -> `Shop`

Where `Flour` is the input to the Bakery, which converts it into `Bread` for selling in the shop. Going from `Farm` to `Shop` directly is not allowed as customers of the shop wish to buy bread not flour.

In code the only valid way to join these should be:

    let farm = new Farm({highWaterMark: 1});
    let bakery = new Bakery({highWaterMark: 1});
    let shop = new Shop({highWaterMark: 1}, stock);
    
    let supplyChain = farm.pipe(bakery).pipe(shop);

But the core NodeJS TypeScript bindings would allow going directly from `farm` to `shop`.

## Installation

    npm install --save stronger-typed-streams

## Usage

Create a subclass of to plant and sow grain:

    class Farm extends Readable<Flour> {

        private i: number = 0;

        constructor(opts = {}) {
            super(Object.assign({objectMode: true}, opts));
        }

        _read() {
            let v = this.i++ < 8 ? new Flour(1) : null;
            process.nextTick(() => {
                this.push(v);
            });
        }
    }

And a class that converts Flour to Bread:

    class Bakery extends Transform<Flour, Bread> {

        private flour: Flour[] = [];

        constructor(opts = {}) {
            super(Object.assign({objectMode: true}, opts));
        }

        _flush(cb) {
            process.nextTick(() => {
                if (this.flour.length) {
                    this.push(new Bread(this.flour));
                }
                this.flour = [];
                cb();
            });
        }

        _transform(flour: Flour, encoding, cb) {
            process.nextTick(() => {
                this.flour.push(flour);
                if (this.flour.length >= 3) {
                    this._flush(cb);
                    return;
                }
                cb();
            });
        }

    }

And something to sell the finished product to the consumers:

    class Shop extends Writable<Bread> {

        constructor(opts = {}, out) {
            super(Object.assign({objectMode: true}, opts));
        }

        _write(bread: Bread, encoding, cb) {
            process.nextTick(() => {
                console.log("Bread for sale!);
                cb();
            });
        }
    }

Now create a supply chain by joining instances of all the classes together:

    let farm = new Farm({highWaterMark: 1});
    let bakery = new Bakery({highWaterMark: 1});
    let shop = new Shop({highWaterMark: 1}, stock);
    
    let supplyChain = farm.pipe(bakery).pipe(shop);

If you tried to attach a Farm directly to a Shop the TypeScript compiler would tell you:

    TS2345: Argument of type 'Shop' is not assignable to parameter of type 'Writable<Flour>'.

Which is absolutely correct and allows you to catch errors at compile time instead of runtime, perhaps in the wild.

There is also a Duplex implementation, but this is only tested in Node versions >= 8 because in the tests I an API method that is only available in Node 8+.

---
_Source: https://npm.io/package/stronger-typed-streams · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
