time-to-botec

Benchmark sampling in different programming languages
Log | Files | Refs | README

README.md (7645B)


      1 <!--
      2 
      3 @license Apache-2.0
      4 
      5 Copyright (c) 2018 The Stdlib Authors.
      6 
      7 Licensed under the Apache License, Version 2.0 (the "License");
      8 you may not use this file except in compliance with the License.
      9 You may obtain a copy of the License at
     10 
     11    http://www.apache.org/licenses/LICENSE-2.0
     12 
     13 Unless required by applicable law or agreed to in writing, software
     14 distributed under the License is distributed on an "AS IS" BASIS,
     15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16 See the License for the specific language governing permissions and
     17 limitations under the License.
     18 
     19 -->
     20 
     21 # Transform Stream
     22 
     23 > [Transform stream][transform-stream].
     24 
     25 <section class="usage">
     26 
     27 ## Usage
     28 
     29 ```javascript
     30 var transformStream = require( '@stdlib/streams/node/transform' );
     31 ```
     32 
     33 <a name="transform-stream"></a>
     34 
     35 #### transformStream( \[options] )
     36 
     37 Creates a [transform stream][transform-stream].
     38 
     39 ```javascript
     40 var stdout = require( '@stdlib/streams/node/stdout' );
     41 
     42 function transform( chunk, enc, clbk ) {
     43     clbk( null, chunk.toString()+'\n' );
     44 }
     45 
     46 var stream = transformStream({
     47     'transform': transform
     48 });
     49 
     50 stream.pipe( stdout );
     51 
     52 stream.write( '1' );
     53 stream.write( '2' );
     54 stream.write( '3' );
     55 
     56 stream.end();
     57 // e.g., => '1\n2\n3\n'
     58 ```
     59 
     60 The function accepts the following `options`:
     61 
     62 -   **transform**: callback to invoke upon receiving a new chunk.
     63 -   **flush**: callback to invoke after receiving all chunks and prior to a stream closing.
     64 -   **objectMode**: specifies whether a [stream][stream] should operate in [objectMode][object-mode]. Default: `false`.
     65 -   **encoding**: specifies how `Buffer` objects should be decoded to `strings`. Default: `null`.
     66 -   **highWaterMark**: specifies the `Buffer` level at which `write()` calls start returning `false`.
     67 -   **allowHalfOpen**: specifies whether a [stream][stream] should remain open even if one side ends. Default: `false`.
     68 -   **decodeStrings**: specifies whether to decode `strings` into `Buffer` objects when writing. Default: `true`.
     69 
     70 To set [stream][stream] `options`,
     71 
     72 ```javascript
     73 var opts = {
     74     'objectMode': true,
     75     'encoding': 'utf8',
     76     'highWaterMark': 64,
     77     'allowHalfOpen': true,
     78     'decodeStrings': false
     79 };
     80 
     81 var stream = transformStream( opts );
     82 ```
     83 
     84 The `transform` option should be a `function` having the following signature:
     85 
     86 ```javascript
     87 function transform( chunk, enc, clbk ) {
     88     var multipleData;
     89     var err;
     90 
     91     if ( multipleData ) {
     92         // Push as many chunks as required...
     93         this.push( chunk );
     94         this.push( chunk );
     95 
     96         // ...
     97 
     98         if ( err ) {
     99             return clbk( err );
    100         }
    101         return clbk();
    102     }
    103     if ( err ) {
    104         return clbk( err );
    105     }
    106     clbk( null, chunk );
    107 }
    108 ```
    109 
    110 The `flush` option should be a `function` which performs any remaining tasks before the stream closes, such as unfinished data processing.
    111 
    112 ```javascript
    113 function flush( clbk ) {
    114     var err;
    115 
    116     // Push any remaining chunks...
    117     this.push( '...' );
    118     this.push( '...' );
    119 
    120     // ...
    121 
    122     if ( err ) {
    123         return clbk( err );
    124     }
    125     clbk();
    126 }
    127 ```
    128 
    129 If no `transform` is provided, the returned `stream` will be a simple pass through stream.
    130 
    131 #### transformStream.factory( \[options] )
    132 
    133 Returns a `function` for creating [streams][transform-stream] which are identically configured according to provided `options`.
    134 
    135 ```javascript
    136 var opts = {
    137     'objectMode': true,
    138     'encoding': 'utf8',
    139     'highWaterMark': 64
    140 };
    141 
    142 var factory = transformStream.factory( opts );
    143 ```
    144 
    145 This method accepts the same `options` as [`transformStream()`](#transform-stream), **except** for the `transform` and `flush` options which must be provided **explicitly**, as shown below.
    146 
    147 ##### factory( transform\[, flush] )
    148 
    149 Creates a [transform stream][transform-stream].
    150 
    151 ```javascript
    152 function transform1( chunk, enc, clbk ) {
    153     clbk( null, chunk.toString()+'\n' );
    154 }
    155 
    156 function transform2( chunk, enc, clbk ) {
    157     clbk( null, chunk.toString()+'\t' );
    158 }
    159 
    160 function flush( clbk ) {
    161     clbk();
    162 }
    163 
    164 var factory = transformStream.factory();
    165 
    166 var s1 = factory( transform1 );
    167 var s2 = factory( transform2, flush );
    168 ```
    169 
    170 #### transformStream.objectMode( \[options] )
    171 
    172 This method is a convenience function to create [streams][stream] which always operate in [objectMode][object-mode].
    173 
    174 <!-- eslint-disable object-curly-newline -->
    175 
    176 ```javascript
    177 var stdout = require( '@stdlib/streams/node/stdout' );
    178 
    179 function stringify( chunk, enc, clbk ) {
    180     clbk( null, JSON.stringify( chunk ) );
    181 }
    182 
    183 function newline( chunk, enc, clbk ) {
    184     clbk( null, chunk+'\n' );
    185 }
    186 
    187 var s1 = transformStream.objectMode({
    188     'transform': stringify
    189 });
    190 
    191 var s2 = transformStream.objectMode({
    192     'transform': newline
    193 });
    194 
    195 s1.pipe( s2 ).pipe( stdout );
    196 
    197 s1.write( { 'value': 'a' } );
    198 s1.write( { 'value': 'b' } );
    199 s1.write( { 'value': 'c' } );
    200 
    201 s1.end();
    202 // e.g., => '{"value":"a"}\n{"value":"b"}\n{"value":"c"}\n'
    203 ```
    204 
    205 This method accepts the same `options` as [`transformStream()`](#transform-stream); however, the method will **always** override the [objectMode][object-mode] option in `options`.
    206 
    207 #### transformStream.ctor( \[options] )
    208 
    209 Instead of returning a [transform stream][transform-stream] instance, this method returns a custom [transform stream][transform-stream] constructor. If provided `transform` and `flush` options, these methods are bound to the constructor prototype. If not provided a `transform`, the returned constructor creates simple pass through streams.
    210 
    211 <!-- eslint-disable no-underscore-dangle -->
    212 
    213 ```javascript
    214 function transform( chunk, enc, clbk ) {
    215     clbk( null, chunk.toString()+'\n' );
    216 }
    217 
    218 function flush( clbk ) {
    219     this.push( 'beep' );
    220     clbk();
    221 }
    222 
    223 var opts = {
    224     'transform': transform,
    225     'flush': flush
    226 };
    227 
    228 var TransformStream = transformStream.ctor( opts );
    229 
    230 var bool = ( TransformStream.prototype._transform === transform );
    231 // returns true
    232 
    233 bool = ( TransformStream.prototype._flush === flush );
    234 // returns true
    235 ```
    236 
    237 The returned constructor accepts the same `options` as documented above, **except** for the `transform` and `flush` options, which are not supported. Any `options` provided to the constructor **override** `options` provided to the constructor factory.
    238 
    239 </section>
    240 
    241 <!-- /.usage -->
    242 
    243 <section class="examples">
    244 
    245 ## Examples
    246 
    247 <!-- eslint no-undef: "error" -->
    248 
    249 ```javascript
    250 var stdout = require( '@stdlib/streams/node/stdout' );
    251 var factory = require( '@stdlib/streams/node/transform' ).factory;
    252 
    253 function parse( chunk, enc, clbk ) {
    254     clbk( null, JSON.parse( chunk ) );
    255 }
    256 
    257 function pluck( chunk, enc, clbk ) {
    258     clbk( null, chunk.value );
    259 }
    260 
    261 function square( chunk, enc, clbk ) {
    262     var v = +chunk;
    263     clbk( null, v*v );
    264 }
    265 
    266 function toStr( chunk, enc, clbk ) {
    267     clbk( null, chunk.toString() );
    268 }
    269 
    270 function join( chunk, enc, clbk ) {
    271     clbk( null, chunk+'\n' );
    272 }
    273 
    274 // Create a factory which generates streams running in `objectMode`:
    275 var tStream = factory({
    276     'objectMode': true
    277 });
    278 
    279 // Create streams for each transform:
    280 var s1 = tStream( parse );
    281 var s2 = tStream( pluck );
    282 var s3 = tStream( square );
    283 var s4 = tStream( toStr );
    284 var s5 = tStream( join );
    285 
    286 // Create the pipeline:
    287 s1.pipe( s2 )
    288     .pipe( s3 )
    289     .pipe( s4 )
    290     .pipe( s5 )
    291     .pipe( stdout );
    292 
    293 // Write data to the pipeline...
    294 var v;
    295 var i;
    296 for ( i = 0; i < 100; i++ ) {
    297     v = '{"value":'+i+'}';
    298     s1.write( v, 'utf8' );
    299 }
    300 s1.end();
    301 ```
    302 
    303 </section>
    304 
    305 <!-- /.examples -->
    306 
    307 <section class="links">
    308 
    309 [stream]: https://nodejs.org/api/stream.html
    310 
    311 [object-mode]: https://nodejs.org/api/stream.html#stream_object_mode
    312 
    313 [transform-stream]: https://nodejs.org/api/stream.html
    314 
    315 </section>
    316 
    317 <!-- /.links -->