UNPKG

3.12 kBJavaScriptView Raw
1'use strict'; // undocumented cb() API, needed for core, not for public API
2
3function destroy(err, cb) {
4 var _this = this;
5
6 var readableDestroyed = this._readableState && this._readableState.destroyed;
7 var writableDestroyed = this._writableState && this._writableState.destroyed;
8
9 if (readableDestroyed || writableDestroyed) {
10 if (cb) {
11 cb(err);
12 } else if (err) {
13 if (!this._writableState) {
14 process.nextTick(emitErrorNT, this, err);
15 } else if (!this._writableState.errorEmitted) {
16 this._writableState.errorEmitted = true;
17 process.nextTick(emitErrorNT, this, err);
18 }
19 }
20
21 return this;
22 } // we set destroyed to true before firing error callbacks in order
23 // to make it re-entrance safe in case destroy() is called within callbacks
24
25
26 if (this._readableState) {
27 this._readableState.destroyed = true;
28 } // if this is a duplex stream mark the writable part as destroyed as well
29
30
31 if (this._writableState) {
32 this._writableState.destroyed = true;
33 }
34
35 this._destroy(err || null, function (err) {
36 if (!cb && err) {
37 if (!_this._writableState) {
38 process.nextTick(emitErrorAndCloseNT, _this, err);
39 } else if (!_this._writableState.errorEmitted) {
40 _this._writableState.errorEmitted = true;
41 process.nextTick(emitErrorAndCloseNT, _this, err);
42 } else {
43 process.nextTick(emitCloseNT, _this);
44 }
45 } else if (cb) {
46 process.nextTick(emitCloseNT, _this);
47 cb(err);
48 } else {
49 process.nextTick(emitCloseNT, _this);
50 }
51 });
52
53 return this;
54}
55
56function emitErrorAndCloseNT(self, err) {
57 emitErrorNT(self, err);
58 emitCloseNT(self);
59}
60
61function emitCloseNT(self) {
62 if (self._writableState && !self._writableState.emitClose) return;
63 if (self._readableState && !self._readableState.emitClose) return;
64 self.emit('close');
65}
66
67function undestroy() {
68 if (this._readableState) {
69 this._readableState.destroyed = false;
70 this._readableState.reading = false;
71 this._readableState.ended = false;
72 this._readableState.endEmitted = false;
73 }
74
75 if (this._writableState) {
76 this._writableState.destroyed = false;
77 this._writableState.ended = false;
78 this._writableState.ending = false;
79 this._writableState.finalCalled = false;
80 this._writableState.prefinished = false;
81 this._writableState.finished = false;
82 this._writableState.errorEmitted = false;
83 }
84}
85
86function emitErrorNT(self, err) {
87 self.emit('error', err);
88}
89
90function errorOrDestroy(stream, err) {
91 // We have tests that rely on errors being emitted
92 // in the same tick, so changing this is semver major.
93 // For now when you opt-in to autoDestroy we allow
94 // the error to be emitted nextTick. In a future
95 // semver major update we should change the default to this.
96 var rState = stream._readableState;
97 var wState = stream._writableState;
98 if (rState && rState.autoDestroy || wState && wState.autoDestroy) stream.destroy(err);else stream.emit('error', err);
99}
100
101module.exports = {
102 destroy: destroy,
103 undestroy: undestroy,
104 errorOrDestroy: errorOrDestroy
105};
\No newline at end of file