main.js (4158B)
1 /** 2 * @license Apache-2.0 3 * 4 * Copyright (c) 2018 The Stdlib Authors. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 'use strict'; 20 21 // MODULES // 22 23 var Readable = require( 'readable-stream' ).Readable; 24 var isError = require( '@stdlib/assert/is-error' ); 25 var copy = require( '@stdlib/utils/copy' ); 26 var inherit = require( '@stdlib/utils/inherit' ); 27 var setNonEnumerable = require( '@stdlib/utils/define-nonenumerable-property' ); 28 var setNonEnumerableReadOnly = require( '@stdlib/utils/define-nonenumerable-read-only-property' ); 29 var nextTick = require( '@stdlib/utils/next-tick' ); 30 var DEFAULTS = require( './defaults.json' ); 31 var validate = require( './validate.js' ); 32 var debug = require( './debug.js' ); 33 34 35 // FUNCTIONS // 36 37 /** 38 * Implements the `_read` method. 39 * 40 * @private 41 * @param {number} size - number (of bytes) to read 42 * @returns {void} 43 */ 44 function read() { 45 /* eslint-disable no-invalid-this */ 46 this.push( null ); 47 48 /* eslint-enable no-invalid-this */ 49 } 50 51 /** 52 * Gracefully destroys a stream, providing backward compatibility. 53 * 54 * @private 55 * @param {(string|Object|Error)} [error] - error 56 * @returns {EmptyStream} Stream instance 57 */ 58 function destroy( error ) { 59 /* eslint-disable no-invalid-this */ 60 var self; 61 if ( this._destroyed ) { 62 debug( 'Attempted to destroy an already destroyed stream.' ); 63 return this; 64 } 65 self = this; 66 this._destroyed = true; 67 68 nextTick( close ); 69 70 return this; 71 72 /** 73 * Closes a stream. 74 * 75 * @private 76 */ 77 function close() { 78 if ( error ) { 79 debug( 'Stream was destroyed due to an error. Error: %s.', ( isError( error ) ) ? error.message : JSON.stringify( error ) ); 80 self.emit( 'error', error ); 81 } 82 debug( 'Closing the stream...' ); 83 self.emit( 'close' ); 84 } 85 86 /* eslint-enable no-invalid-this */ 87 } 88 89 90 // MAIN // 91 92 /** 93 * Stream constructor for creating an "empty" stream. 94 * 95 * @constructor 96 * @param {Options} [options] - stream options 97 * @param {boolean} [options.objectMode=false] - specifies whether the stream should operate in object mode 98 * @throws {TypeError} options argument must be an object 99 * @throws {TypeError} must provide valid options 100 * @returns {EmptyStream} Stream instance 101 * 102 * @example 103 * var inspectStream = require( '@stdlib/streams/node/inspect-sink' ); 104 * 105 * function log( chunk ) { 106 * console.log( chunk.toString() ); 107 * } 108 * 109 * var stream = new EmptyStream(); 110 * 111 * stream.pipe( inspectStream( log ) ); 112 */ 113 function EmptyStream( options ) { 114 var opts; 115 var err; 116 if ( !( this instanceof EmptyStream ) ) { 117 if ( arguments.length > 0 ) { 118 return new EmptyStream( options ); 119 } 120 return new EmptyStream(); 121 } 122 opts = copy( DEFAULTS ); 123 if ( arguments.length > 0 ) { 124 err = validate( opts, options ); 125 if ( err ) { 126 throw err; 127 } 128 } 129 // Make the stream a readable stream: 130 debug( 'Creating a readable stream configured with the following options: %s.', JSON.stringify( opts ) ); 131 Readable.call( this, opts ); 132 133 // Destruction state: 134 setNonEnumerable( this, '_destroyed', false ); 135 136 return this; 137 } 138 139 /* 140 * Inherit from the `Readable` prototype. 141 */ 142 inherit( EmptyStream, Readable ); 143 144 /** 145 * Implements the `_read` method. 146 * 147 * @private 148 * @name _read 149 * @memberof EmptyStream.prototype 150 * @type {Function} 151 * @param {number} size - number (of bytes) to read 152 * @returns {void} 153 */ 154 setNonEnumerableReadOnly( EmptyStream.prototype, '_read', read ); 155 156 /** 157 * Gracefully destroys a stream, providing backward compatibility. 158 * 159 * @name destroy 160 * @memberof EmptyStream.prototype 161 * @type {Function} 162 * @param {(string|Object|Error)} [error] - error 163 * @returns {EmptyStream} Stream instance 164 */ 165 setNonEnumerableReadOnly( EmptyStream.prototype, 'destroy', destroy ); 166 167 168 // EXPORTS // 169 170 module.exports = EmptyStream;