Skip to content

Commit b5cf8b2

Browse files
authored
Merge pull request #19 from clue-labs/docs
Improve API documentation
2 parents bcbab44 + f6bc9f8 commit b5cf8b2

File tree

2 files changed

+232
-33
lines changed

2 files changed

+232
-33
lines changed

README.md

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ for [ReactPHP](https://reactphp.org/).
1414
* [unwrapReadable()](#unwrapreadable)
1515
* [unwrapWritable()](#unwrapwritable)
1616
* [Install](#install)
17+
* [Tests](#tests)
1718
* [License](#license)
1819

1920
## Usage
@@ -37,11 +38,8 @@ Alternatively, you can also refer to them with their fully-qualified name:
3738

3839
### buffer()
3940

40-
The `buffer(ReadableStreamInterface $stream, int $maxLength = null)` function can be used to create
41-
a `Promise` which resolves with the stream data buffer. With an optional maximum length argument
42-
which defaults to no limit. In case the maximum length is reached before the end the promise will
43-
be rejected with a `\OverflowException`.
44-
41+
The `buffer(ReadableStreamInterface<string> $stream, ?int $maxLength = null): PromiseInterface<string,Exception>` function can be used to
42+
create a `Promise` which resolves with the stream data buffer.
4543

4644
```php
4745
$stream = accessSomeJsonStream();
@@ -57,7 +55,11 @@ The promise will resolve with an empty string if the stream is already closed.
5755

5856
The promise will reject if the stream emits an error.
5957

60-
The promise will reject if it is canceled.
58+
The promise will reject if it is cancelled.
59+
60+
The optional `$maxLength` argument defaults to no limit. In case the maximum
61+
length is given and the stream emits more data before the end, the promise
62+
will be rejected with an `\OverflowException`.
6163

6264
```php
6365
$stream = accessSomeToLargeStream();
@@ -67,14 +69,14 @@ Stream\buffer($stream, 1024)->then(function ($contents) {
6769
}, function ($error) {
6870
// Reaching here when the stream buffer goes above the max size,
6971
// in this example that is 1024 bytes,
70-
// or when the stream emits an error.
72+
// or when the stream emits an error.
7173
});
7274
```
7375

7476
### first()
7577

76-
The `first(ReadableStreamInterface|WritableStreamInterface $stream, $event = 'data')`
77-
function can be used to create a `Promise` which resolves once the given event triggers for the first time.
78+
The `first(ReadableStreamInterface|WritableStreamInterface $stream, string $event = 'data'): PromiseInterface<mixed,Exception>` function can be used to
79+
create a `Promise` which resolves once the given event triggers for the first time.
7880

7981
```php
8082
$stream = accessSomeJsonStream();
@@ -97,12 +99,12 @@ The promise will reject once the stream closes – unless you're waiting for the
9799

98100
The promise will reject if the stream is already closed.
99101

100-
The promise will reject if it is canceled.
102+
The promise will reject if it is cancelled.
101103

102104
### all()
103105

104-
The `all(ReadableStreamInterface|WritableStreamInterface $stream, $event = 'data')`
105-
function can be used to create a `Promise` which resolves with an array of all the event data.
106+
The `all(ReadableStreamInterface|WritableStreamInterface $stream, string $event = 'data'): PromiseInterface<array,Exception>` function can be used to
107+
create a `Promise` which resolves with an array of all the event data.
106108

107109
```php
108110
$stream = accessSomeJsonStream();
@@ -123,12 +125,12 @@ The promise will resolve with an empty array if the stream is already closed.
123125

124126
The promise will reject if the stream emits an error.
125127

126-
The promise will reject if it is canceled.
128+
The promise will reject if it is cancelled.
127129

128130
### unwrapReadable()
129131

130-
The `unwrapReadable(PromiseInterface $promise)` function can be used to unwrap
131-
a `Promise` which resolves with a `ReadableStreamInterface`.
132+
The `unwrapReadable(PromiseInterface<ReadableStreamInterface,Exception> $promise): ReadableStreamInterface` function can be used to
133+
unwrap a `Promise` which resolves with a `ReadableStreamInterface`.
132134

133135
This function returns a readable stream instance (implementing `ReadableStreamInterface`)
134136
right away which acts as a proxy for the future promise resolution.
@@ -142,11 +144,11 @@ $promise = startDownloadStream($uri);
142144
$stream = Stream\unwrapReadable($promise);
143145

144146
$stream->on('data', function ($data) {
145-
echo $data;
147+
echo $data;
146148
});
147149

148150
$stream->on('end', function () {
149-
echo 'DONE';
151+
echo 'DONE';
150152
});
151153
```
152154

@@ -185,8 +187,8 @@ $loop->addTimer(2.0, function () use ($stream) {
185187

186188
### unwrapWritable()
187189

188-
The `unwrapWritable(PromiseInterface $promise)` function can be used to unwrap
189-
a `Promise` which resolves with a `WritableStreamInterface`.
190+
The `unwrapWritable(PromiseInterface<WritableStreamInterface,Exception> $promise): WritableStreamInterface` function can be used to
191+
unwrap a `Promise` which resolves with a `WritableStreamInterface`.
190192

191193
This function returns a writable stream instance (implementing `WritableStreamInterface`)
192194
right away which acts as a proxy for the future promise resolution.
@@ -204,7 +206,7 @@ $stream->write('hello');
204206
$stream->end('world');
205207

206208
$stream->on('close', function () {
207-
echo 'DONE';
209+
echo 'DONE';
208210
});
209211
```
210212

@@ -246,7 +248,7 @@ $loop->addTimer(2.0, function () use ($stream) {
246248
The recommended way to install this library is [through Composer](https://getcomposer.org).
247249
[New to Composer?](https://getcomposer.org/doc/00-intro.md)
248250

249-
This project follows [SemVer](http://semver.org/).
251+
This project follows [SemVer](https://semver.org/).
250252
This will install the latest supported version:
251253

252254
```bash
@@ -260,6 +262,21 @@ extensions and supports running on legacy PHP 5.3 through current PHP 7+ and
260262
HHVM.
261263
It's *highly recommended to use PHP 7+* for this project.
262264

265+
## Tests
266+
267+
To run the test suite, you first need to clone this repo and then install all
268+
dependencies [through Composer](https://getcomposer.org):
269+
270+
```bash
271+
$ composer install
272+
```
273+
274+
To run the test suite, go to the project root and run:
275+
276+
```bash
277+
$ php vendor/bin/phpunit
278+
```
279+
263280
## License
264281

265282
MIT, see [LICENSE file](LICENSE).

src/functions.php

Lines changed: 194 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,43 @@
99
use React\Stream\WritableStreamInterface;
1010

1111
/**
12-
* Creates a `Promise` which resolves with the stream data buffer
12+
* Creates a `Promise` which resolves with the stream data buffer.
1313
*
14-
* @param ReadableStreamInterface $stream
15-
* @param int|null $maxLength Maximum number of bytes to buffer or null for unlimited.
16-
* @return Promise\CancellablePromiseInterface Promise<string, Exception>
14+
* ```php
15+
* $stream = accessSomeJsonStream();
16+
*
17+
* Stream\buffer($stream)->then(function ($contents) {
18+
* var_dump(json_decode($contents));
19+
* });
20+
* ```
21+
*
22+
* The promise will resolve with all data chunks concatenated once the stream closes.
23+
*
24+
* The promise will resolve with an empty string if the stream is already closed.
25+
*
26+
* The promise will reject if the stream emits an error.
27+
*
28+
* The promise will reject if it is cancelled.
29+
*
30+
* The optional `$maxLength` argument defaults to no limit. In case the maximum
31+
* length is given and the stream emits more data before the end, the promise
32+
* will be rejected with an `\OverflowException`.
33+
*
34+
* ```php
35+
* $stream = accessSomeToLargeStream();
36+
*
37+
* Stream\buffer($stream, 1024)->then(function ($contents) {
38+
* var_dump(json_decode($contents));
39+
* }, function ($error) {
40+
* // Reaching here when the stream buffer goes above the max size,
41+
* // in this example that is 1024 bytes,
42+
* // or when the stream emits an error.
43+
* });
44+
* ```
45+
*
46+
* @param ReadableStreamInterface<string> $stream
47+
* @param ?int $maxLength Maximum number of bytes to buffer or null for unlimited.
48+
* @return PromiseInterface<string,Exception>
1749
*/
1850
function buffer(ReadableStreamInterface $stream, $maxLength = null)
1951
{
@@ -56,11 +88,34 @@ function buffer(ReadableStreamInterface $stream, $maxLength = null)
5688
}
5789

5890
/**
59-
* Creates a `Promise` which resolves with the first event data
91+
* Creates a `Promise` which resolves once the given event triggers for the first time.
92+
*
93+
* ```php
94+
* $stream = accessSomeJsonStream();
95+
*
96+
* Stream\first($stream)->then(function ($chunk) {
97+
* echo 'The first chunk arrived: ' . $chunk;
98+
* });
99+
* ```
100+
*
101+
* The promise will resolve with whatever the first event emitted or `null` if the
102+
* event does not pass any data.
103+
* If you do not pass a custom event name, then it will wait for the first "data"
104+
* event and resolve with a string containing the first data chunk.
105+
*
106+
* The promise will reject if the stream emits an error – unless you're waiting for
107+
* the "error" event, in which case it will resolve.
108+
*
109+
* The promise will reject once the stream closes – unless you're waiting for the
110+
* "close" event, in which case it will resolve.
111+
*
112+
* The promise will reject if the stream is already closed.
113+
*
114+
* The promise will reject if it is cancelled.
60115
*
61116
* @param ReadableStreamInterface|WritableStreamInterface $stream
62117
* @param string $event
63-
* @return Promise\CancellablePromiseInterface Promise<mixed, Exception>
118+
* @return PromiseInterface<mixed,Exception>
64119
*/
65120
function first(EventEmitterInterface $stream, $event = 'data')
66121
{
@@ -102,11 +157,32 @@ function first(EventEmitterInterface $stream, $event = 'data')
102157
}
103158

104159
/**
105-
* Creates a `Promise` which resolves with an array of all the event data
160+
* Creates a `Promise` which resolves with an array of all the event data.
161+
*
162+
* ```php
163+
* $stream = accessSomeJsonStream();
164+
*
165+
* Stream\all($stream)->then(function ($chunks) {
166+
* echo 'The stream consists of ' . count($chunks) . ' chunk(s)';
167+
* });
168+
* ```
169+
*
170+
* The promise will resolve with an array of whatever all events emitted or `null` if the
171+
* events do not pass any data.
172+
* If you do not pass a custom event name, then it will wait for all the "data"
173+
* events and resolve with an array containing all the data chunks.
174+
*
175+
* The promise will resolve with an array once the stream closes.
176+
*
177+
* The promise will resolve with an empty array if the stream is already closed.
178+
*
179+
* The promise will reject if the stream emits an error.
180+
*
181+
* The promise will reject if it is cancelled.
106182
*
107183
* @param ReadableStreamInterface|WritableStreamInterface $stream
108184
* @param string $event
109-
* @return Promise\CancellablePromiseInterface Promise<string, Exception>
185+
* @return PromiseInterface<array,Exception>
110186
*/
111187
function all(EventEmitterInterface $stream, $event = 'data')
112188
{
@@ -152,9 +228,62 @@ function all(EventEmitterInterface $stream, $event = 'data')
152228
}
153229

154230
/**
155-
* unwrap a `Promise` which resolves with a `ReadableStreamInterface`.
231+
* Unwraps a `Promise` which resolves with a `ReadableStreamInterface`.
232+
*
233+
* This function returns a readable stream instance (implementing `ReadableStreamInterface`)
234+
* right away which acts as a proxy for the future promise resolution.
235+
* Once the given Promise resolves with a `ReadableStreamInterface`, its data will
236+
* be piped to the output stream.
237+
*
238+
* ```php
239+
* //$promise = someFunctionWhichResolvesWithAStream();
240+
* $promise = startDownloadStream($uri);
241+
*
242+
* $stream = Stream\unwrapReadable($promise);
156243
*
157-
* @param PromiseInterface $promise Promise<ReadableStreamInterface, Exception>
244+
* $stream->on('data', function ($data) {
245+
* echo $data;
246+
* });
247+
*
248+
* $stream->on('end', function () {
249+
* echo 'DONE';
250+
* });
251+
* ```
252+
*
253+
* If the given promise is either rejected or fulfilled with anything but an
254+
* instance of `ReadableStreamInterface`, then the output stream will emit
255+
* an `error` event and close:
256+
*
257+
* ```php
258+
* $promise = startDownloadStream($invalidUri);
259+
*
260+
* $stream = Stream\unwrapReadable($promise);
261+
*
262+
* $stream->on('error', function (Exception $error) {
263+
* echo 'Error: ' . $error->getMessage();
264+
* });
265+
* ```
266+
*
267+
* The given `$promise` SHOULD be pending, i.e. it SHOULD NOT be fulfilled or rejected
268+
* at the time of invoking this function.
269+
* If the given promise is already settled and does not resolve with an
270+
* instance of `ReadableStreamInterface`, then you will not be able to receive
271+
* the `error` event.
272+
*
273+
* You can `close()` the resulting stream at any time, which will either try to
274+
* `cancel()` the pending promise or try to `close()` the underlying stream.
275+
*
276+
* ```php
277+
* $promise = startDownloadStream($uri);
278+
*
279+
* $stream = Stream\unwrapReadable($promise);
280+
*
281+
* $loop->addTimer(2.0, function () use ($stream) {
282+
* $stream->close();
283+
* });
284+
* ```
285+
*
286+
* @param PromiseInterface<ReadableStreamInterface,Exception> $promise
158287
* @return ReadableStreamInterface
159288
*/
160289
function unwrapReadable(PromiseInterface $promise)
@@ -163,9 +292,62 @@ function unwrapReadable(PromiseInterface $promise)
163292
}
164293

165294
/**
166-
* unwrap a `Promise` which resolves with a `WritableStreamInterface`.
295+
* Unwraps a `Promise` which resolves with a `WritableStreamInterface`.
296+
*
297+
* This function returns a writable stream instance (implementing `WritableStreamInterface`)
298+
* right away which acts as a proxy for the future promise resolution.
299+
* Any writes to this instance will be buffered in memory for when the promise resolves.
300+
* Once the given Promise resolves with a `WritableStreamInterface`, any data you
301+
* have written to the proxy will be forwarded transparently to the inner stream.
302+
*
303+
* ```php
304+
* //$promise = someFunctionWhichResolvesWithAStream();
305+
* $promise = startUploadStream($uri);
306+
*
307+
* $stream = Stream\unwrapWritable($promise);
308+
*
309+
* $stream->write('hello');
310+
* $stream->end('world');
311+
*
312+
* $stream->on('close', function () {
313+
* echo 'DONE';
314+
* });
315+
* ```
316+
*
317+
* If the given promise is either rejected or fulfilled with anything but an
318+
* instance of `WritableStreamInterface`, then the output stream will emit
319+
* an `error` event and close:
320+
*
321+
* ```php
322+
* $promise = startUploadStream($invalidUri);
323+
*
324+
* $stream = Stream\unwrapWritable($promise);
325+
*
326+
* $stream->on('error', function (Exception $error) {
327+
* echo 'Error: ' . $error->getMessage();
328+
* });
329+
* ```
330+
*
331+
* The given `$promise` SHOULD be pending, i.e. it SHOULD NOT be fulfilled or rejected
332+
* at the time of invoking this function.
333+
* If the given promise is already settled and does not resolve with an
334+
* instance of `WritableStreamInterface`, then you will not be able to receive
335+
* the `error` event.
336+
*
337+
* You can `close()` the resulting stream at any time, which will either try to
338+
* `cancel()` the pending promise or try to `close()` the underlying stream.
339+
*
340+
* ```php
341+
* $promise = startUploadStream($uri);
342+
*
343+
* $stream = Stream\unwrapWritable($promise);
344+
*
345+
* $loop->addTimer(2.0, function () use ($stream) {
346+
* $stream->close();
347+
* });
348+
* ```
167349
*
168-
* @param PromiseInterface $promise Promise<WritableStreamInterface, Exception>
350+
* @param PromiseInterface<WritableStreamInterface,Exception> $promise
169351
* @return WritableStreamInterface
170352
*/
171353
function unwrapWritable(PromiseInterface $promise)

0 commit comments

Comments
 (0)