summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/api/stream.md10
-rw-r--r--lib/_stream_duplex.js10
-rw-r--r--lib/_stream_writable.js10
-rw-r--r--test/parallel/test-stream-duplex-writable-finished.js30
-rw-r--r--test/parallel/test-stream-writable-finished.js30
5 files changed, 90 insertions, 0 deletions
diff --git a/doc/api/stream.md b/doc/api/stream.md
index a5c55f5ca1..155e39906b 100644
--- a/doc/api/stream.md
+++ b/doc/api/stream.md
@@ -503,6 +503,16 @@ This property contains the number of bytes (or objects) in the queue
ready to be written. The value provides introspection data regarding
the status of the `highWaterMark`.
+##### writable.writableFinished
+<!-- YAML
+added: v12.4.0
+-->
+
+* {boolean}
+
+Is `true` if all data has been flushed to the underlying system. After
+the [`'finish'`][] event has been emitted.
+
##### writable.writableObjectMode
<!-- YAML
added: v12.3.0
diff --git a/lib/_stream_duplex.js b/lib/_stream_duplex.js
index 49520c4074..d20877e921 100644
--- a/lib/_stream_duplex.js
+++ b/lib/_stream_duplex.js
@@ -98,6 +98,16 @@ Object.defineProperty(Duplex.prototype, 'writableLength', {
}
});
+Object.defineProperty(Duplex.prototype, 'writableFinished', {
+ // Making it explicit this property is not enumerable
+ // because otherwise some prototype manipulation in
+ // userland will fail
+ enumerable: false,
+ get() {
+ return this._writableState.finished;
+ }
+});
+
// The no-half-open enforcer
function onend() {
// If the writable side ended, then we're ok.
diff --git a/lib/_stream_writable.js b/lib/_stream_writable.js
index 267418e9d7..e85b4dead8 100644
--- a/lib/_stream_writable.js
+++ b/lib/_stream_writable.js
@@ -714,6 +714,16 @@ Object.defineProperty(Writable.prototype, 'writableObjectMode', {
}
});
+Object.defineProperty(Writable.prototype, 'writableFinished', {
+ // Making it explicit this property is not enumerable
+ // because otherwise some prototype manipulation in
+ // userland will fail
+ enumerable: false,
+ get() {
+ return this._writableState.finished;
+ }
+});
+
Writable.prototype.destroy = destroyImpl.destroy;
Writable.prototype._undestroy = destroyImpl.undestroy;
Writable.prototype._destroy = function(err, cb) {
diff --git a/test/parallel/test-stream-duplex-writable-finished.js b/test/parallel/test-stream-duplex-writable-finished.js
new file mode 100644
index 0000000000..6d9e860b61
--- /dev/null
+++ b/test/parallel/test-stream-duplex-writable-finished.js
@@ -0,0 +1,30 @@
+'use strict';
+
+const common = require('../common');
+const { Duplex } = require('stream');
+const assert = require('assert');
+
+// basic
+{
+ // Find it on Duplex.prototype
+ assert(Duplex.prototype.hasOwnProperty('writableFinished'));
+}
+
+// event
+{
+ const duplex = new Duplex();
+
+ duplex._write = (chunk, encoding, cb) => {
+ // The state finished should start in false.
+ assert.strictEqual(duplex.writableFinished, false);
+ cb();
+ };
+
+ duplex.on('finish', common.mustCall(() => {
+ assert.strictEqual(duplex.writableFinished, true);
+ }));
+
+ duplex.end('testing finished state', common.mustCall(() => {
+ assert.strictEqual(duplex.writableFinished, true);
+ }));
+}
diff --git a/test/parallel/test-stream-writable-finished.js b/test/parallel/test-stream-writable-finished.js
new file mode 100644
index 0000000000..a5dfc06025
--- /dev/null
+++ b/test/parallel/test-stream-writable-finished.js
@@ -0,0 +1,30 @@
+'use strict';
+
+const common = require('../common');
+const { Writable } = require('stream');
+const assert = require('assert');
+
+// basic
+{
+ // Find it on Writable.prototype
+ assert(Writable.prototype.hasOwnProperty('writableFinished'));
+}
+
+// event
+{
+ const writable = new Writable();
+
+ writable._write = (chunk, encoding, cb) => {
+ // The state finished should start in false.
+ assert.strictEqual(writable.writableFinished, false);
+ cb();
+ };
+
+ writable.on('finish', common.mustCall(() => {
+ assert.strictEqual(writable.writableFinished, true);
+ }));
+
+ writable.end('testing finished state', common.mustCall(() => {
+ assert.strictEqual(writable.writableFinished, true);
+ }));
+}