Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

glarify some stuff

  • Loading branch information...
commit 7e45f0f443e7a076b6fa6cf8da1bc7e260f448af 1 parent 5a9e116
@dominictarr authored
Showing with 40 additions and 15 deletions.
  1. +40 −15 stream_spec.md
View
55 stream_spec.md
@@ -1,12 +1,20 @@
# a `Stream` spec
-This document defines the behaviour that a `Stream` must implement in order to be compatible with `Stream#pipe`. This is not an official document, but is intended as a guide to produce correct behaviour in user-land streams.
+This document defines the behaviour that a `Stream` must implement in order to be compatible with `Stream#pipe`.
+This is not an official document, but is intended as a guide to produce correct behaviour in user-land streams.
## Stream
-All streams *must* emit `'error'` if writing to or reading from becomes physically impossible. `'error'` implys that the stream has ended.
+All streams *must* emit `'error'` if writing to or reading from becomes physically impossible.
+`'error'` implys that the stream has ended, do not emit `'end'` after error, `'close'` may be emitted.
@Raynos
Raynos added a note

implies

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
-All streams *may* emit `'close'`. `'close'` means that any underlying resources have been disposed of. If a `ReadableStream` has ended normally, it *must not* emit `'close'` before `'end'`.
+All streams *should* emit `'close'`.
+`'close'` means that any underlying resources have been disposed of.
+`'close'` must be emitted either after end, or instead of `'end'`.
+
+Emitting `'close'` without `'end'` indicates a broken pipe - `Stream#pipe` will call `dest.destroy()`
+
+If a `ReadableStream` has ended normally, it *must not* emit `'close'` before `'end'`.
A `Stream` *must not* emit `'error'` if the error is recoverable.
(that is not in the stream spec)
@@ -15,7 +23,8 @@ All streams *should* implement `destroy` but a `WritableStream` *must* implement
### emit('error')
-All streams *must* emit `'error'` when an error that is not recoverable has occurred. If it has become physically impossible to write to or read from the `Stream`, then emit `'error'`.
+All streams *must* emit `'error'` when an error that is not recoverable has occurred.
+If it has become physically impossible to write to or read from the `Stream`, then emit `'error'`.
A `WriteableStream` *may* throw an error if `write` has been called after `end`.
(which should never happen, in correct usage)
@@ -24,7 +33,8 @@ otherwise, a stream *must never* throw an error. (always emit)
## WritableStream
-A `WritableStream` *must* implement methods `write`, `end`, and `destroy`, and `writable` *must* be set to `true`, and *must* inherit `Stream#pipe`
+A `WritableStream` *must* implement methods `write`, `end`, and `destroy`,
+and `writable` *must* be set to `true`, and *must* inherit `Stream#pipe`
### write(data)
@@ -32,7 +42,11 @@ A `WritableStream` *must* implement methods `write`, `end`, and `destroy`, and `
(if `false` then the writer *should* pause)
If `write` is called after end, an error *may* be thrown.
-If `write` returns `false`,it *must* eventually emit `'drain'`. `write` returning `false` means the stream is paused. paused means (or downstream) is at capacity, and the writer/upstream *should attempt* to slow down or stop. It does not mean buffer, although that is something a stream may reasonably do.
+If `write` returns `false`,it *must* eventually emit `'drain'`.
+`write` returning `false` means the stream is paused.
+paused means (or downstream) is at capacity,
+and the writer/upstream *should attempt* to slow down or stop.
+It does not mean all data must be buffered, although that is something a stream may reasonably do.
### end()
@@ -51,13 +65,19 @@ once any underlying resources are disposed of.
### emit ('drain')
-After pausing, a `Stream` must eventually emit `'drain'`. For example, when if a call to `write` returns `false` `Stream#pipe` will call `pause` on the source and register a one-time listener on `drain`, that will call `resume` on the source.
+After pausing, a `Stream` must eventually emit `'drain'`.
+For example, when if a call to `write() === false`,
+`Stream#pipe` will call `pause` on the source and
+then call `source.resume()`, when the dest emits `'drain'`.
-If drain is not emitted correctly, it's possible for `'data'` events to stop coming (depending on the source's behaviour when paused).
+If drain is not emitted correctly, it's possible for `'data'` events to stop coming
+(depending on the source's behaviour when paused).
## ReadableStream
-A `ReadableStream` *must* inherit `pipe` from `Stream`, and set `readable` to `true`, and *must* emit zero or more 'data' events, followed by a single `end` event. A `ReadableStream` *may* implement `pause` and `resume` methods.
+A `ReadableStream` *must* inherit `pipe` from `Stream`,
+and set `readable` to `true`, and *must* emit zero or more 'data' events,
+followed by a single `end` event. A `ReadableStream` *may* implement `pause` and `resume` methods.
* I will not bother to specify the behaviour of `pipe` because I am attempting to document what must be done in order for your `Stream` to be compatible with `pipe`.
@@ -68,7 +88,11 @@ A `ReadableStream` *must not* emit emit a `'data'` event after it has emitted `'
### emit('end')
-A `ReadableStream` *should* emit an `'end'` event when it is not going to emit any more `'data'` events. `'end'` *must not* be emitted more than once. A `ReadableStream` may set `readable` to `false` after it has emitted the `'end'` event.
+A `ReadableStream` *should* emit an `'end'` event when it is not going to emit any more `'data'` events.
+`'end'` *must not* be emitted more than once.
+A `ReadableStream` may set `readable` to `false` after it has emitted the `'end'` event.
+
+Also, a `Stream` should internally call `destroy` after it has emitted `'end'`.
### emit ('close')
@@ -78,11 +102,15 @@ Emitting close will cause `pipe` to call `destroy` on the down stream pipe, if i
### pause()
-A readable `Stream` *may* implement the `pause` method. When `pause` is called, the stream should attempt to emit `'data'` less often. (possibly stopping altogether until `resume` is called)
+A readable `Stream` *may* implement the `pause` method.
+When `pause` is called, the stream should attempt to emit `'data'` less often.
+(possibly stopping altogether until `resume` is called)
### resume()
-A `ReadableStream` *may* implement the `resume` method. If the `Stream` has been paused, it may now emit `'data'` more often, or commence emitting `data` if it has stopped all together.
+A `ReadableStream` *may* implement the `resume` method.
+If the `Stream` has been paused, it may now emit `'data'` more often,
+or commence emitting `data` if it has stopped all together.
If a stream is also writable, and has returned `false` on `write` it *must* now eventually emit `drain`
@@ -94,6 +122,3 @@ Calling `destroy` *must* dispose of any underlying resources.
Calling `destroy` *must* emit `'close'` eventually,
once any underlying resources are disposed of.
-## request for comment
-
-thank you in advance!
Please sign in to comment.
Something went wrong with that request. Please try again.