11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst { 41cb0ef41Sopenharmony_ci PromisePrototypeThen, 51cb0ef41Sopenharmony_ci SymbolAsyncIterator, 61cb0ef41Sopenharmony_ci SymbolIterator, 71cb0ef41Sopenharmony_ci} = primordials; 81cb0ef41Sopenharmony_ciconst { Buffer } = require('buffer'); 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ciconst { 111cb0ef41Sopenharmony_ci ERR_INVALID_ARG_TYPE, 121cb0ef41Sopenharmony_ci ERR_STREAM_NULL_VALUES, 131cb0ef41Sopenharmony_ci} = require('internal/errors').codes; 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_cifunction from(Readable, iterable, opts) { 161cb0ef41Sopenharmony_ci let iterator; 171cb0ef41Sopenharmony_ci if (typeof iterable === 'string' || iterable instanceof Buffer) { 181cb0ef41Sopenharmony_ci return new Readable({ 191cb0ef41Sopenharmony_ci objectMode: true, 201cb0ef41Sopenharmony_ci ...opts, 211cb0ef41Sopenharmony_ci read() { 221cb0ef41Sopenharmony_ci this.push(iterable); 231cb0ef41Sopenharmony_ci this.push(null); 241cb0ef41Sopenharmony_ci }, 251cb0ef41Sopenharmony_ci }); 261cb0ef41Sopenharmony_ci } 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ci let isAsync; 291cb0ef41Sopenharmony_ci if (iterable && iterable[SymbolAsyncIterator]) { 301cb0ef41Sopenharmony_ci isAsync = true; 311cb0ef41Sopenharmony_ci iterator = iterable[SymbolAsyncIterator](); 321cb0ef41Sopenharmony_ci } else if (iterable && iterable[SymbolIterator]) { 331cb0ef41Sopenharmony_ci isAsync = false; 341cb0ef41Sopenharmony_ci iterator = iterable[SymbolIterator](); 351cb0ef41Sopenharmony_ci } else { 361cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_TYPE('iterable', ['Iterable'], iterable); 371cb0ef41Sopenharmony_ci } 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ci const readable = new Readable({ 401cb0ef41Sopenharmony_ci objectMode: true, 411cb0ef41Sopenharmony_ci highWaterMark: 1, 421cb0ef41Sopenharmony_ci // TODO(ronag): What options should be allowed? 431cb0ef41Sopenharmony_ci ...opts, 441cb0ef41Sopenharmony_ci }); 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_ci // Flag to protect against _read 471cb0ef41Sopenharmony_ci // being called before last iteration completion. 481cb0ef41Sopenharmony_ci let reading = false; 491cb0ef41Sopenharmony_ci 501cb0ef41Sopenharmony_ci readable._read = function() { 511cb0ef41Sopenharmony_ci if (!reading) { 521cb0ef41Sopenharmony_ci reading = true; 531cb0ef41Sopenharmony_ci next(); 541cb0ef41Sopenharmony_ci } 551cb0ef41Sopenharmony_ci }; 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_ci readable._destroy = function(error, cb) { 581cb0ef41Sopenharmony_ci PromisePrototypeThen( 591cb0ef41Sopenharmony_ci close(error), 601cb0ef41Sopenharmony_ci () => process.nextTick(cb, error), // nextTick is here in case cb throws 611cb0ef41Sopenharmony_ci (e) => process.nextTick(cb, e || error), 621cb0ef41Sopenharmony_ci ); 631cb0ef41Sopenharmony_ci }; 641cb0ef41Sopenharmony_ci 651cb0ef41Sopenharmony_ci async function close(error) { 661cb0ef41Sopenharmony_ci const hadError = (error !== undefined) && (error !== null); 671cb0ef41Sopenharmony_ci const hasThrow = typeof iterator.throw === 'function'; 681cb0ef41Sopenharmony_ci if (hadError && hasThrow) { 691cb0ef41Sopenharmony_ci const { value, done } = await iterator.throw(error); 701cb0ef41Sopenharmony_ci await value; 711cb0ef41Sopenharmony_ci if (done) { 721cb0ef41Sopenharmony_ci return; 731cb0ef41Sopenharmony_ci } 741cb0ef41Sopenharmony_ci } 751cb0ef41Sopenharmony_ci if (typeof iterator.return === 'function') { 761cb0ef41Sopenharmony_ci const { value } = await iterator.return(); 771cb0ef41Sopenharmony_ci await value; 781cb0ef41Sopenharmony_ci } 791cb0ef41Sopenharmony_ci } 801cb0ef41Sopenharmony_ci 811cb0ef41Sopenharmony_ci async function next() { 821cb0ef41Sopenharmony_ci for (;;) { 831cb0ef41Sopenharmony_ci try { 841cb0ef41Sopenharmony_ci const { value, done } = isAsync ? 851cb0ef41Sopenharmony_ci await iterator.next() : 861cb0ef41Sopenharmony_ci iterator.next(); 871cb0ef41Sopenharmony_ci 881cb0ef41Sopenharmony_ci if (done) { 891cb0ef41Sopenharmony_ci readable.push(null); 901cb0ef41Sopenharmony_ci } else { 911cb0ef41Sopenharmony_ci const res = (value && 921cb0ef41Sopenharmony_ci typeof value.then === 'function') ? 931cb0ef41Sopenharmony_ci await value : 941cb0ef41Sopenharmony_ci value; 951cb0ef41Sopenharmony_ci if (res === null) { 961cb0ef41Sopenharmony_ci reading = false; 971cb0ef41Sopenharmony_ci throw new ERR_STREAM_NULL_VALUES(); 981cb0ef41Sopenharmony_ci } else if (readable.push(res)) { 991cb0ef41Sopenharmony_ci continue; 1001cb0ef41Sopenharmony_ci } else { 1011cb0ef41Sopenharmony_ci reading = false; 1021cb0ef41Sopenharmony_ci } 1031cb0ef41Sopenharmony_ci } 1041cb0ef41Sopenharmony_ci } catch (err) { 1051cb0ef41Sopenharmony_ci readable.destroy(err); 1061cb0ef41Sopenharmony_ci } 1071cb0ef41Sopenharmony_ci break; 1081cb0ef41Sopenharmony_ci } 1091cb0ef41Sopenharmony_ci } 1101cb0ef41Sopenharmony_ci return readable; 1111cb0ef41Sopenharmony_ci} 1121cb0ef41Sopenharmony_ci 1131cb0ef41Sopenharmony_cimodule.exports = from; 114