You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					105 lines
				
				3.0 KiB
			
		
		
			
		
	
	
					105 lines
				
				3.0 KiB
			| 
											3 years ago
										 | 'use strict'; // undocumented cb() API, needed for core, not for public API
 | ||
|  | 
 | ||
|  | function destroy(err, cb) { | ||
|  |   var _this = this; | ||
|  | 
 | ||
|  |   var readableDestroyed = this._readableState && this._readableState.destroyed; | ||
|  |   var writableDestroyed = this._writableState && this._writableState.destroyed; | ||
|  | 
 | ||
|  |   if (readableDestroyed || writableDestroyed) { | ||
|  |     if (cb) { | ||
|  |       cb(err); | ||
|  |     } else if (err) { | ||
|  |       if (!this._writableState) { | ||
|  |         process.nextTick(emitErrorNT, this, err); | ||
|  |       } else if (!this._writableState.errorEmitted) { | ||
|  |         this._writableState.errorEmitted = true; | ||
|  |         process.nextTick(emitErrorNT, this, err); | ||
|  |       } | ||
|  |     } | ||
|  | 
 | ||
|  |     return this; | ||
|  |   } // we set destroyed to true before firing error callbacks in order
 | ||
|  |   // to make it re-entrance safe in case destroy() is called within callbacks
 | ||
|  | 
 | ||
|  | 
 | ||
|  |   if (this._readableState) { | ||
|  |     this._readableState.destroyed = true; | ||
|  |   } // if this is a duplex stream mark the writable part as destroyed as well
 | ||
|  | 
 | ||
|  | 
 | ||
|  |   if (this._writableState) { | ||
|  |     this._writableState.destroyed = true; | ||
|  |   } | ||
|  | 
 | ||
|  |   this._destroy(err || null, function (err) { | ||
|  |     if (!cb && err) { | ||
|  |       if (!_this._writableState) { | ||
|  |         process.nextTick(emitErrorAndCloseNT, _this, err); | ||
|  |       } else if (!_this._writableState.errorEmitted) { | ||
|  |         _this._writableState.errorEmitted = true; | ||
|  |         process.nextTick(emitErrorAndCloseNT, _this, err); | ||
|  |       } else { | ||
|  |         process.nextTick(emitCloseNT, _this); | ||
|  |       } | ||
|  |     } else if (cb) { | ||
|  |       process.nextTick(emitCloseNT, _this); | ||
|  |       cb(err); | ||
|  |     } else { | ||
|  |       process.nextTick(emitCloseNT, _this); | ||
|  |     } | ||
|  |   }); | ||
|  | 
 | ||
|  |   return this; | ||
|  | } | ||
|  | 
 | ||
|  | function emitErrorAndCloseNT(self, err) { | ||
|  |   emitErrorNT(self, err); | ||
|  |   emitCloseNT(self); | ||
|  | } | ||
|  | 
 | ||
|  | function emitCloseNT(self) { | ||
|  |   if (self._writableState && !self._writableState.emitClose) return; | ||
|  |   if (self._readableState && !self._readableState.emitClose) return; | ||
|  |   self.emit('close'); | ||
|  | } | ||
|  | 
 | ||
|  | function undestroy() { | ||
|  |   if (this._readableState) { | ||
|  |     this._readableState.destroyed = false; | ||
|  |     this._readableState.reading = false; | ||
|  |     this._readableState.ended = false; | ||
|  |     this._readableState.endEmitted = false; | ||
|  |   } | ||
|  | 
 | ||
|  |   if (this._writableState) { | ||
|  |     this._writableState.destroyed = false; | ||
|  |     this._writableState.ended = false; | ||
|  |     this._writableState.ending = false; | ||
|  |     this._writableState.finalCalled = false; | ||
|  |     this._writableState.prefinished = false; | ||
|  |     this._writableState.finished = false; | ||
|  |     this._writableState.errorEmitted = false; | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | function emitErrorNT(self, err) { | ||
|  |   self.emit('error', err); | ||
|  | } | ||
|  | 
 | ||
|  | function errorOrDestroy(stream, err) { | ||
|  |   // We have tests that rely on errors being emitted
 | ||
|  |   // in the same tick, so changing this is semver major.
 | ||
|  |   // For now when you opt-in to autoDestroy we allow
 | ||
|  |   // the error to be emitted nextTick. In a future
 | ||
|  |   // semver major update we should change the default to this.
 | ||
|  |   var rState = stream._readableState; | ||
|  |   var wState = stream._writableState; | ||
|  |   if (rState && rState.autoDestroy || wState && wState.autoDestroy) stream.destroy(err);else stream.emit('error', err); | ||
|  | } | ||
|  | 
 | ||
|  | module.exports = { | ||
|  |   destroy: destroy, | ||
|  |   undestroy: undestroy, | ||
|  |   errorOrDestroy: errorOrDestroy | ||
|  | }; |