|
2 | 2 |
|
3 | 3 | const pipeline = require('internal/streams/pipeline'); |
4 | 4 | const Duplex = require('internal/streams/duplex'); |
5 | | -const { createDeferredPromise } = require('internal/util'); |
6 | 5 | const { destroyer } = require('internal/streams/destroy'); |
7 | | -const from = require('internal/streams/from'); |
8 | 6 | const { |
9 | 7 | isNodeStream, |
10 | | - isIterable, |
11 | 8 | isReadable, |
12 | 9 | isWritable, |
13 | 10 | } = require('internal/streams/utils'); |
14 | | -const { |
15 | | - PromiseResolve, |
16 | | -} = primordials; |
17 | 11 | const { |
18 | 12 | AbortError, |
19 | 13 | codes: { |
20 | | - ERR_INVALID_ARG_TYPE, |
21 | 14 | ERR_INVALID_ARG_VALUE, |
22 | | - ERR_INVALID_RETURN_VALUE, |
23 | 15 | ERR_MISSING_ARGS, |
24 | 16 | }, |
25 | 17 | } = require('internal/errors'); |
26 | | -const assert = require('internal/assert'); |
27 | 18 |
|
28 | 19 | // This is needed for pre node 17. |
29 | 20 | class ComposeDuplex extends Duplex { |
@@ -53,18 +44,18 @@ module.exports = function compose(...streams) { |
53 | 44 | } |
54 | 45 |
|
55 | 46 | if (streams.length === 1) { |
56 | | - return makeDuplex(streams[0], 'streams[0]'); |
| 47 | + return Duplex.from(streams[0]); |
57 | 48 | } |
58 | 49 |
|
59 | 50 | const orgStreams = [...streams]; |
60 | 51 |
|
61 | 52 | if (typeof streams[0] === 'function') { |
62 | | - streams[0] = makeDuplex(streams[0], 'streams[0]'); |
| 53 | + streams[0] = Duplex.from(streams[0]); |
63 | 54 | } |
64 | 55 |
|
65 | 56 | if (typeof streams[streams.length - 1] === 'function') { |
66 | 57 | const idx = streams.length - 1; |
67 | | - streams[idx] = makeDuplex(streams[idx], `streams[${idx}]`); |
| 58 | + streams[idx] = Duplex.from(streams[idx]); |
68 | 59 | } |
69 | 60 |
|
70 | 61 | for (let n = 0; n < streams.length; ++n) { |
@@ -117,7 +108,7 @@ module.exports = function compose(...streams) { |
117 | 108 | // Implement Writable/Readable/Duplex traits. |
118 | 109 | // See, https://github.com/nodejs/node/pull/33515. |
119 | 110 | d = new ComposeDuplex({ |
120 | | - highWaterMark: 1, |
| 111 | + // TODO (ronag): highWaterMark? |
121 | 112 | writableObjectMode: !!head?.writableObjectMode, |
122 | 113 | readableObjectMode: !!tail?.writableObjectMode, |
123 | 114 | writable, |
@@ -203,82 +194,3 @@ module.exports = function compose(...streams) { |
203 | 194 |
|
204 | 195 | return d; |
205 | 196 | }; |
206 | | - |
207 | | -function makeDuplex(stream, name) { |
208 | | - let ret; |
209 | | - if (typeof stream === 'function') { |
210 | | - assert(stream.length > 0); |
211 | | - |
212 | | - const { value, write, final } = fromAsyncGen(stream); |
213 | | - |
214 | | - if (isIterable(value)) { |
215 | | - ret = from(ComposeDuplex, value, { |
216 | | - objectMode: true, |
217 | | - highWaterMark: 1, |
218 | | - write, |
219 | | - final |
220 | | - }); |
221 | | - } else if (typeof value?.then === 'function') { |
222 | | - const promise = PromiseResolve(value) |
223 | | - .then((val) => { |
224 | | - if (val != null) { |
225 | | - throw new ERR_INVALID_RETURN_VALUE('nully', name, val); |
226 | | - } |
227 | | - }) |
228 | | - .catch((err) => { |
229 | | - destroyer(ret, err); |
230 | | - }); |
231 | | - |
232 | | - ret = new ComposeDuplex({ |
233 | | - objectMode: true, |
234 | | - highWaterMark: 1, |
235 | | - readable: false, |
236 | | - write, |
237 | | - final(cb) { |
238 | | - final(() => promise.then(cb, cb)); |
239 | | - } |
240 | | - }); |
241 | | - } else { |
242 | | - throw new ERR_INVALID_RETURN_VALUE( |
243 | | - 'Iterable, AsyncIterable or AsyncFunction', name, value); |
244 | | - } |
245 | | - } else if (isNodeStream(stream)) { |
246 | | - ret = stream; |
247 | | - } else if (isIterable(stream)) { |
248 | | - ret = from(ComposeDuplex, stream, { |
249 | | - objectMode: true, |
250 | | - highWaterMark: 1, |
251 | | - writable: false |
252 | | - }); |
253 | | - } else { |
254 | | - throw new ERR_INVALID_ARG_TYPE( |
255 | | - name, |
256 | | - ['Stream', 'Iterable', 'AsyncIterable', 'Function'], |
257 | | - stream) |
258 | | - ; |
259 | | - } |
260 | | - return ret; |
261 | | -} |
262 | | - |
263 | | -function fromAsyncGen(fn) { |
264 | | - let { promise, resolve } = createDeferredPromise(); |
265 | | - const value = fn(async function*() { |
266 | | - while (true) { |
267 | | - const { chunk, done, cb } = await promise; |
268 | | - process.nextTick(cb); |
269 | | - if (done) return; |
270 | | - yield chunk; |
271 | | - ({ promise, resolve } = createDeferredPromise()); |
272 | | - } |
273 | | - }()); |
274 | | - |
275 | | - return { |
276 | | - value, |
277 | | - write(chunk, encoding, cb) { |
278 | | - resolve({ chunk, done: false, cb }); |
279 | | - }, |
280 | | - final(cb) { |
281 | | - resolve({ done: true, cb }); |
282 | | - } |
283 | | - }; |
284 | | -} |
0 commit comments