Skip to content

Instantly share code, notes, and snippets.

@Raynos
Created September 27, 2012 02:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Raynos/3791742 to your computer and use it in GitHub Desktop.
Save Raynos/3791742 to your computer and use it in GitHub Desktop.
Stream Spec 0.9

Readable

read(bytes)

When called must either return a chunk of data or null. If applicable return a chunk of data that matches the number of bytes asked for. If no bytes are asked for it's recommended you return as large a chunk as you can.

If you return null, it's expected you will emit 'readable' in the future to signal that more data is available. After emitting 'readable' it's expected that read's will return a non null value.

pipe(dest, [options])

Pipe allows you to pipe a readable stream into a writable stream. Pipe does the following:

  • it emits 'pipe' on the writable stream with the readable stream as the value.
  • it reads from the readable stream and write's each chunk returned from read to the writable stream
  • if the readable stream returns null from a read it waits until the readable stream emits 'readable' before it continues reading
  • if the writable stream's write call returns false it stops reading until the writable stream emits 'drain'
  • if options.end is not false pipe will call end on the writable stream when the readable stream emits 'end'

Note: This need not be implemented. Inherit from Stream and get pipe for free.

Event 'readable'

A readable stream emit's readable to signal that there is data to be read. i.e. future read calls will return a chunk of data.

Event 'end'

A readable stream emits 'end' when there is no more data to be read. The underlying source of data is depleted. 'end' implies that the source of data has ended cleanly.

Event 'error' (err)

A readable stream emits 'error' when some error has occurred. This generally means that the stream is in state beyond repair and should be aborted.

Writable Stream

write(chunk, encoding)

Writes a chunk of data to the underlying source of data. If applicable ensure you apply the encoding to the chunk. If this returns false then the writable stream is saying that you are writing too fast and should slow down. When false is returned, the writable stream will emit 'drain' in the future to signal that it's ok to write again.

end([chunk, encoding])

Ending the streams means your saying there is no more data to be written and it's fine to clean up any underlying data sources. It's optional to write a single chunk when ending the stream (with encoding if applicable).

Event 'drain'

Emitted by a writable stream when it's ok to write again.

Event 'finish'

Emitted by a writable stream when it's finished writing everything. This happens after .end() has been called.

Event 'pipe' (src)

Emitted by a writable stream when someone calls pipe on a readable stream with the writable as the destination. src is the readable stream which is piping into the writable stream.

Note: This need not be implemented. A correct pipe implementation should emit "pipe" on the target for you.

Event 'error' (err)

Emitted by the writable stream when an error occurs. Assume that the stream is in a corrupted state after it emits error.

Types of streams

Streams over buffers

Streams over buffers are a lower level type of stream that generally deals with raw data coming from an IO call.

When writing streams like this it makes sense to use the build in Readable, Writable, Duplex or Transform classes.

When dealing with streams over buffers calling read(bytes) or write(chunk, encoding) makes sense because you can split a buffer into a bytes and return a subset of it and you can encode string value chunk into a valid Buffer using the supplied encoding.

Synthetic streams

If your stream operates on anything that is not Buffers (strings are buffers with an encoding) then it's a synthetic stream. Commonly it's a stream over objects.

When doing synthetic streams it does not make sense to use the build in base classes as they only work when the chunks are buffers (or strings that can be converted to buffers). It's necessary to use other base classes instead.

@Raynos
Copy link
Author

Raynos commented Oct 15, 2012

@isaacs

Would appreciate feedback on what else a stream author needs to implement other then the listed above.

It should be taken for granted that a stream author need not implement pipe nor emit "pipe"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment