From b8c6ceddd54d2031f73eae34ac29cb592c44de0b Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Fri, 24 Mar 2023 08:20:18 +0100 Subject: [PATCH] stream: expose stream symbols This is required for streams interop with e.g. readable-stream. Currently readable-stream helpers will not work with normal node streams which is confusing and bad for the ecosystem. PR-URL: https://github.com/nodejs/node/pull/45671 Reviewed-By: Matteo Collina Reviewed-By: James M Snell Reviewed-By: Antoine du Hamel Reviewed-By: Benjamin Gruenbaum Reviewed-By: Debadree Chatterjee --- lib/internal/streams/destroy.js | 4 ++-- lib/internal/streams/utils.js | 22 ++++++++++++++-------- lib/stream.js | 4 ++++ 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/lib/internal/streams/destroy.js b/lib/internal/streams/destroy.js index 358422e12a33e0..cfb49f2c7c7273 100644 --- a/lib/internal/streams/destroy.js +++ b/lib/internal/streams/destroy.js @@ -11,7 +11,7 @@ const { Symbol, } = primordials; const { - kDestroyed, + kIsDestroyed, isDestroyed, isFinished, isServerRequest, @@ -327,7 +327,7 @@ function destroyer(stream, err) { } if (!stream.destroyed) { - stream[kDestroyed] = true; + stream[kIsDestroyed] = true; } } diff --git a/lib/internal/streams/utils.js b/lib/internal/streams/utils.js index c9e61ca8cdd8eb..1b2a6c0fbf6a05 100644 --- a/lib/internal/streams/utils.js +++ b/lib/internal/streams/utils.js @@ -1,16 +1,20 @@ 'use strict'; const { - Symbol, SymbolAsyncIterator, SymbolIterator, SymbolFor, } = primordials; -const kDestroyed = Symbol('kDestroyed'); -const kIsErrored = Symbol('kIsErrored'); -const kIsReadable = Symbol('kIsReadable'); -const kIsDisturbed = Symbol('kIsDisturbed'); +// We need to use SymbolFor to make these globally available +// for interopt with readable-stream, i.e. readable-stream +// and node core needs to be able to read/write private state +// from each other for proper interoperability. +const kIsDestroyed = SymbolFor('nodejs.stream.destroyed'); +const kIsErrored = SymbolFor('nodejs.stream.errored'); +const kIsReadable = SymbolFor('nodejs.stream.readable'); +const kIsWritable = SymbolFor('nodejs.stream.writable'); +const kIsDisturbed = SymbolFor('nodejs.stream.disturbed'); const kIsClosedPromise = SymbolFor('nodejs.webstream.isClosedPromise'); const kControllerErrorFunction = SymbolFor('nodejs.webstream.controllerErrorFunction'); @@ -104,7 +108,7 @@ function isDestroyed(stream) { const wState = stream._writableState; const rState = stream._readableState; const state = wState || rState; - return !!(stream.destroyed || stream[kDestroyed] || state?.destroyed); + return !!(stream.destroyed || stream[kIsDestroyed] || state?.destroyed); } // Have been end():d. @@ -162,6 +166,7 @@ function isReadable(stream) { } function isWritable(stream) { + if (stream && stream[kIsWritable] != null) return stream[kIsWritable]; if (typeof stream?.writable !== 'boolean') return null; if (isDestroyed(stream)) return false; return isWritableNodeStream(stream) && @@ -298,7 +303,8 @@ function isErrored(stream) { } module.exports = { - kDestroyed, + isDestroyed, + kIsDestroyed, isDisturbed, kIsDisturbed, isErrored, @@ -307,8 +313,8 @@ module.exports = { kIsReadable, kIsClosedPromise, kControllerErrorFunction, + kIsWritable, isClosed, - isDestroyed, isDuplexNodeStream, isFinished, isIterable, diff --git a/lib/stream.js b/lib/stream.js index 4c105067bae1ca..e8f205c056834f 100644 --- a/lib/stream.js +++ b/lib/stream.js @@ -51,9 +51,13 @@ const promises = require('stream/promises'); const utils = require('internal/streams/utils'); const Stream = module.exports = require('internal/streams/legacy').Stream; + +Stream.isDestroyed = utils.isDestroyed; Stream.isDisturbed = utils.isDisturbed; Stream.isErrored = utils.isErrored; Stream.isReadable = utils.isReadable; +Stream.isWritable = utils.isWritable; + Stream.Readable = require('internal/streams/readable'); for (const key of ObjectKeys(streamReturningOperators)) { const op = streamReturningOperators[key];