pirandello

![](http://images4.wikia.nocookie.net/__cb20100628073138/mirrorsedge/images/2/2c/PKlogo.jpg)

npm install pirandello
9 downloads in the last week
33 downloads in the last month

Pirandello

A better Stream abstraction for node.js. npm install pirandello

Use

Creating

There's a bunch of ways to create a Stream.

Stream.of

Creates a stream that sends a single value and ends.

Stream.of("hello world")
//> hello world

Stream.empty

Just ends immediately.

Stream.fromArray

Sends each item in the array, then ends.

Stream.fromArray(["hello ","world"])
//> hello world

Stream.fromReadable

Takes a node Readable stream and sends it one data chunk at a time.

Stream.fromReadable(fs.createReadStream('data.txt'))

new Stream

To construct your own Streams, call the constructor (new is optional) with a function that takes two arguments. Each argument is a function: call the first one with an object to send it over the stream, call the second one to end the stream. From the implementation of fromArray:

Stream.fromArray = function(arr) {
    return Stream(function(next,end) {
        arr.forEach(next)
        end()
    })
}

Modifying

Pirandello Streams are immutable; the methods below return a new stream. Streams are a fantasy-land MonadPlus.

Stream::concat

Returns a new stream that sends the contents of the current stream followed by the contents of the other stream.

Stream.of("hello ").concat(Stream.of("world"))
//> hello world

Stream::chain

Takes a function that operates on each chunk and should return a new Stream. Useful for concatenating lists.

function read(f) {
    return Stream.fromReadable(fs.createReadStream(f));
}

Stream.fromArray(process.argv).chain(read).pipe(process.stdout)

Stream::map

Maps over the chunk.

Stream.fromArray(["hello ","world"]).map(function(s) {return s.toUpperCase()})
//> HELLO WORLD

Stream::ap

Applies a stream of functions to a stream of inputs, returns a stream of outputs.

Stream.fromArray([
    function(s) { return s.toUpperCase(); },
    function(s) { return s.toLowerCase(); },
    function(s) { return s.substr(0,5); }
]).ap(Stream.of("Hello World "))
//> HELLO WORLD hello world Hello

Stream::toCharstream

Converts a Stream of strings into a Stream of individual characters.

Stream::take

Given a number, returns a stream of the first n chunks. Useful with toCharstream.

Stream.of("hello world").toCharstream().take(5)
//> hello

Stream::drop

Given a number, returns a stream without the first n chunks. Useful with toCharstream.

Stream.of("hello world").toCharstream().drop(6)
//> world

Consuming

Stream::pipe

Mostly compatible with Readable::pipe, sends every chunk to the destination Writable.

Stream::generator

When you really need low-level chunk functionality (maybe you're extending Pirandello? Good for you!), generator is what you want. It is, in fact, the function passed in when the Stream is instantiated; call it with two arguments, one function to deal with each chunk, and one which is called at the end. FUrom the implementation of pipe:

Stream.prototype.pipe = function(dest) {
    this.generator(
        function(chunk) { dest.write(chunk) }
        function() { dest.end() }
    )
}

Why?

I tried to make Readables look nice, I really did. The API is ugly, and the abstraction is leaky. Here's to a fresh start.

Licence

MIT

npm loves you