39c8b14f |
1 | # delayed-stream |
2 | |
3 | Buffers events from a stream until you are ready to handle them. |
4 | |
5 | ## Installation |
6 | |
7 | ``` bash |
8 | npm install delayed-stream |
9 | ``` |
10 | |
11 | ## Usage |
12 | |
13 | The following example shows how to write a http echo server that delays its |
14 | response by 1000 ms. |
15 | |
16 | ``` javascript |
17 | var DelayedStream = require('delayed-stream'); |
18 | var http = require('http'); |
19 | |
20 | http.createServer(function(req, res) { |
21 | var delayed = DelayedStream.create(req); |
22 | |
23 | setTimeout(function() { |
24 | res.writeHead(200); |
25 | delayed.pipe(res); |
26 | }, 1000); |
27 | }); |
28 | ``` |
29 | |
30 | If you are not using `Stream#pipe`, you can also manually release the buffered |
31 | events by calling `delayedStream.resume()`: |
32 | |
33 | ``` javascript |
34 | var delayed = DelayedStream.create(req); |
35 | |
36 | setTimeout(function() { |
37 | // Emit all buffered events and resume underlaying source |
38 | delayed.resume(); |
39 | }, 1000); |
40 | ``` |
41 | |
42 | ## Implementation |
43 | |
44 | In order to use this meta stream properly, here are a few things you should |
45 | know about the implementation. |
46 | |
47 | ### Event Buffering / Proxying |
48 | |
49 | All events of the `source` stream are hijacked by overwriting the `source.emit` |
50 | method. Until node implements a catch-all event listener, this is the only way. |
51 | |
52 | However, delayed-stream still continues to emit all events it captures on the |
53 | `source`, regardless of whether you have released the delayed stream yet or |
54 | not. |
55 | |
56 | Upon creation, delayed-stream captures all `source` events and stores them in |
57 | an internal event buffer. Once `delayedStream.release()` is called, all |
58 | buffered events are emitted on the `delayedStream`, and the event buffer is |
59 | cleared. After that, delayed-stream merely acts as a proxy for the underlaying |
60 | source. |
61 | |
62 | ### Error handling |
63 | |
64 | Error events on `source` are buffered / proxied just like any other events. |
65 | However, `delayedStream.create` attaches a no-op `'error'` listener to the |
66 | `source`. This way you only have to handle errors on the `delayedStream` |
67 | object, rather than in two places. |
68 | |
69 | ### Buffer limits |
70 | |
71 | delayed-stream provides a `maxDataSize` property that can be used to limit |
72 | the amount of data being buffered. In order to protect you from bad `source` |
73 | streams that don't react to `source.pause()`, this feature is enabled by |
74 | default. |
75 | |
76 | ## API |
77 | |
78 | ### DelayedStream.create(source, [options]) |
79 | |
80 | Returns a new `delayedStream`. Available options are: |
81 | |
82 | * `pauseStream` |
83 | * `maxDataSize` |
84 | |
85 | The description for those properties can be found below. |
86 | |
87 | ### delayedStream.source |
88 | |
89 | The `source` stream managed by this object. This is useful if you are |
90 | passing your `delayedStream` around, and you still want to access properties |
91 | on the `source` object. |
92 | |
93 | ### delayedStream.pauseStream = true |
94 | |
95 | Whether to pause the underlaying `source` when calling |
96 | `DelayedStream.create()`. Modifying this property afterwards has no effect. |
97 | |
98 | ### delayedStream.maxDataSize = 1024 * 1024 |
99 | |
100 | The amount of data to buffer before emitting an `error`. |
101 | |
102 | If the underlaying source is emitting `Buffer` objects, the `maxDataSize` |
103 | refers to bytes. |
104 | |
105 | If the underlaying source is emitting JavaScript strings, the size refers to |
106 | characters. |
107 | |
108 | If you know what you are doing, you can set this property to `Infinity` to |
109 | disable this feature. You can also modify this property during runtime. |
110 | |
111 | ### delayedStream.maxDataSize = 1024 * 1024 |
112 | |
113 | The amount of data to buffer before emitting an `error`. |
114 | |
115 | If the underlaying source is emitting `Buffer` objects, the `maxDataSize` |
116 | refers to bytes. |
117 | |
118 | If the underlaying source is emitting JavaScript strings, the size refers to |
119 | characters. |
120 | |
121 | If you know what you are doing, you can set this property to `Infinity` to |
122 | disable this feature. |
123 | |
124 | ### delayedStream.dataSize = 0 |
125 | |
126 | The amount of data buffered so far. |
127 | |
128 | ### delayedStream.readable |
129 | |
130 | An ECMA5 getter that returns the value of `source.readable`. |
131 | |
132 | ### delayedStream.resume() |
133 | |
134 | If the `delayedStream` has not been released so far, `delayedStream.release()` |
135 | is called. |
136 | |
137 | In either case, `source.resume()` is called. |
138 | |
139 | ### delayedStream.pause() |
140 | |
141 | Calls `source.pause()`. |
142 | |
143 | ### delayedStream.pipe(dest) |
144 | |
145 | Calls `delayedStream.resume()` and then proxies the arguments to `source.pipe`. |
146 | |
147 | ### delayedStream.release() |
148 | |
149 | Emits and clears all events that have been buffered up so far. This does not |
150 | resume the underlaying source, use `delayedStream.resume()` instead. |
151 | |
152 | ## License |
153 | |
154 | delayed-stream is licensed under the MIT license. |