File Explorer

/var/lang/lib/node_modules/npm/node_modules/minipass/dist/esm

This explorer reads the filesystem of the server it runs on, so /workspace/user isn't present here. Browsing and the terminal still work against this server's own disk from /.

index.js32.5 KB · 1020 lines
const proc = typeof process === 'object' && process    ? process    : {        stdout: null,        stderr: null,    };import { EventEmitter } from 'node:events';import Stream from 'node:stream';import { StringDecoder } from 'node:string_decoder';/** * Return true if the argument is a Minipass stream, Node stream, or something * else that Minipass can interact with. */export const isStream = (s) => !!s &&    typeof s === 'object' &&    (s instanceof Minipass ||        s instanceof Stream ||        isReadable(s) ||        isWritable(s));/** * Return true if the argument is a valid {@link Minipass.Readable} */export const isReadable = (s) => !!s &&    typeof s === 'object' &&    s instanceof EventEmitter &&    typeof s.pipe === 'function' &&    // node core Writable streams have a pipe() method, but it throws    s.pipe !== Stream.Writable.prototype.pipe;/** * Return true if the argument is a valid {@link Minipass.Writable} */export const isWritable = (s) => !!s &&    typeof s === 'object' &&    s instanceof EventEmitter &&    typeof s.write === 'function' &&    typeof s.end === 'function';const EOF = Symbol('EOF');const MAYBE_EMIT_END = Symbol('maybeEmitEnd');const EMITTED_END = Symbol('emittedEnd');const EMITTING_END = Symbol('emittingEnd');const EMITTED_ERROR = Symbol('emittedError');const CLOSED = Symbol('closed');const READ = Symbol('read');const FLUSH = Symbol('flush');const FLUSHCHUNK = Symbol('flushChunk');const ENCODING = Symbol('encoding');const DECODER = Symbol('decoder');const FLOWING = Symbol('flowing');const PAUSED = Symbol('paused');const RESUME = Symbol('resume');const BUFFER = Symbol('buffer');const PIPES = Symbol('pipes');const BUFFERLENGTH = Symbol('bufferLength');const BUFFERPUSH = Symbol('bufferPush');const BUFFERSHIFT = Symbol('bufferShift');const OBJECTMODE = Symbol('objectMode');// internal event when stream is destroyedconst DESTROYED = Symbol('destroyed');// internal event when stream has an errorconst ERROR = Symbol('error');const EMITDATA = Symbol('emitData');const EMITEND = Symbol('emitEnd');const EMITEND2 = Symbol('emitEnd2');const ASYNC = Symbol('async');const ABORT = Symbol('abort');const ABORTED = Symbol('aborted');const SIGNAL = Symbol('signal');const DATALISTENERS = Symbol('dataListeners');const DISCARDED = Symbol('discarded');const defer = (fn) => Promise.resolve().then(fn);const nodefer = (fn) => fn();const isEndish = (ev) => ev === 'end' || ev === 'finish' || ev === 'prefinish';const isArrayBufferLike = (b) => b instanceof ArrayBuffer ||    (!!b &&        typeof b === 'object' &&        b.constructor &&        b.constructor.name === 'ArrayBuffer' &&        b.byteLength >= 0);const isArrayBufferView = (b) => !Buffer.isBuffer(b) && ArrayBuffer.isView(b);/** * Internal class representing a pipe to a destination stream. * * @internal */class Pipe {    src;    dest;    opts;    ondrain;    constructor(src, dest, opts) {        this.src = src;        this.dest = dest;        this.opts = opts;        this.ondrain = () => src[RESUME]();        this.dest.on('drain', this.ondrain);    }    unpipe() {        this.dest.removeListener('drain', this.ondrain);    }    // only here for the prototype    /* c8 ignore start */    proxyErrors(_er) { }    /* c8 ignore stop */    end() {        this.unpipe();        if (this.opts.end)            this.dest.end();    }}/** * Internal class representing a pipe to a destination stream where * errors are proxied. * * @internal */class PipeProxyErrors extends Pipe {    unpipe() {        this.src.removeListener('error', this.proxyErrors);        super.unpipe();    }    constructor(src, dest, opts) {        super(src, dest, opts);        this.proxyErrors = (er) => this.dest.emit('error', er);        src.on('error', this.proxyErrors);    }}const isObjectModeOptions = (o) => !!o.objectMode;const isEncodingOptions = (o) => !o.objectMode && !!o.encoding && o.encoding !== 'buffer';/** * Main export, the Minipass class * * `RType` is the type of data emitted, defaults to Buffer * * `WType` is the type of data to be written, if RType is buffer or string, * then any {@link Minipass.ContiguousData} is allowed. * * `Events` is the set of event handler signatures that this object * will emit, see {@link Minipass.Events} */export class Minipass extends EventEmitter {    [FLOWING] = false;    [PAUSED] = false;    [PIPES] = [];    [BUFFER] = [];    [OBJECTMODE];    [ENCODING];    [ASYNC];    [DECODER];    [EOF] = false;    [EMITTED_END] = false;    [EMITTING_END] = false;    [CLOSED] = false;    [EMITTED_ERROR] = null;    [BUFFERLENGTH] = 0;    [DESTROYED] = false;    [SIGNAL];    [ABORTED] = false;    [DATALISTENERS] = 0;    [DISCARDED] = false;    /**     * true if the stream can be written     */    writable = true;    /**     * true if the stream can be read     */    readable = true;    /**     * If `RType` is Buffer, then options do not need to be provided.     * Otherwise, an options object must be provided to specify either     * {@link Minipass.SharedOptions.objectMode} or     * {@link Minipass.SharedOptions.encoding}, as appropriate.     */    constructor(...args) {        const options = (args[0] ||            {});        super();        if (options.objectMode && typeof options.encoding === 'string') {            throw new TypeError('Encoding and objectMode may not be used together');        }        if (isObjectModeOptions(options)) {            this[OBJECTMODE] = true;            this[ENCODING] = null;        }        else if (isEncodingOptions(options)) {            this[ENCODING] = options.encoding;            this[OBJECTMODE] = false;        }        else {            this[OBJECTMODE] = false;            this[ENCODING] = null;        }        this[ASYNC] = !!options.async;        this[DECODER] = this[ENCODING]            ? new StringDecoder(this[ENCODING])            : null;        //@ts-ignore - private option for debugging and testing        if (options && options.debugExposeBuffer === true) {            Object.defineProperty(this, 'buffer', { get: () => this[BUFFER] });        }        //@ts-ignore - private option for debugging and testing        if (options && options.debugExposePipes === true) {            Object.defineProperty(this, 'pipes', { get: () => this[PIPES] });        }        const { signal } = options;        if (signal) {            this[SIGNAL] = signal;            if (signal.aborted) {                this[ABORT]();            }            else {                signal.addEventListener('abort', () => this[ABORT]());            }        }    }    /**     * The amount of data stored in the buffer waiting to be read.     *     * For Buffer strings, this will be the total byte length.     * For string encoding streams, this will be the string character length,     * according to JavaScript's `string.length` logic.     * For objectMode streams, this is a count of the items waiting to be     * emitted.     */    get bufferLength() {        return this[BUFFERLENGTH];    }    /**     * The `BufferEncoding` currently in use, or `null`     */    get encoding() {        return this[ENCODING];    }    /**     * @deprecated - This is a read only property     */    set encoding(_enc) {        throw new Error('Encoding must be set at instantiation time');    }    /**     * @deprecated - Encoding may only be set at instantiation time     */    setEncoding(_enc) {        throw new Error('Encoding must be set at instantiation time');    }    /**     * True if this is an objectMode stream     */    get objectMode() {        return this[OBJECTMODE];    }    /**     * @deprecated - This is a read-only property     */    set objectMode(_om) {        throw new Error('objectMode must be set at instantiation time');    }    /**     * true if this is an async stream     */    get ['async']() {        return this[ASYNC];    }    /**     * Set to true to make this stream async.     *     * Once set, it cannot be unset, as this would potentially cause incorrect     * behavior.  Ie, a sync stream can be made async, but an async stream     * cannot be safely made sync.     */    set ['async'](a) {        this[ASYNC] = this[ASYNC] || !!a;    }    // drop everything and get out of the flow completely    [ABORT]() {        this[ABORTED] = true;        this.emit('abort', this[SIGNAL]?.reason);        this.destroy(this[SIGNAL]?.reason);    }    /**     * True if the stream has been aborted.     */    get aborted() {        return this[ABORTED];    }    /**     * No-op setter. Stream aborted status is set via the AbortSignal provided     * in the constructor options.     */    set aborted(_) { }    write(chunk, encoding, cb) {        if (this[ABORTED])            return false;        if (this[EOF])            throw new Error('write after end');        if (this[DESTROYED]) {            this.emit('error', Object.assign(new Error('Cannot call write after a stream was destroyed'), { code: 'ERR_STREAM_DESTROYED' }));            return true;        }        if (typeof encoding === 'function') {            cb = encoding;            encoding = 'utf8';        }        if (!encoding)            encoding = 'utf8';        const fn = this[ASYNC] ? defer : nodefer;        // convert array buffers and typed array views into buffers        // at some point in the future, we may want to do the opposite!        // leave strings and buffers as-is        // anything is only allowed if in object mode, so throw        if (!this[OBJECTMODE] && !Buffer.isBuffer(chunk)) {            if (isArrayBufferView(chunk)) {                //@ts-ignore - sinful unsafe type changing                chunk = Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength);            }            else if (isArrayBufferLike(chunk)) {                //@ts-ignore - sinful unsafe type changing                chunk = Buffer.from(chunk);            }            else if (typeof chunk !== 'string') {                throw new Error('Non-contiguous data written to non-objectMode stream');            }        }        // handle object mode up front, since it's simpler        // this yields better performance, fewer checks later.        if (this[OBJECTMODE]) {            // maybe impossible?            /* c8 ignore start */            if (this[FLOWING] && this[BUFFERLENGTH] !== 0)                this[FLUSH](true);            /* c8 ignore stop */            if (this[FLOWING])                this.emit('data', chunk);            else                this[BUFFERPUSH](chunk);            if (this[BUFFERLENGTH] !== 0)                this.emit('readable');            if (cb)                fn(cb);            return this[FLOWING];        }        // at this point the chunk is a buffer or string        // don't buffer it up or send it to the decoder        if (!chunk.length) {            if (this[BUFFERLENGTH] !== 0)                this.emit('readable');            if (cb)                fn(cb);            return this[FLOWING];        }        // fast-path writing strings of same encoding to a stream with        // an empty buffer, skipping the buffer/decoder dance        if (typeof chunk === 'string' &&            // unless it is a string already ready for us to use            !(encoding === this[ENCODING] && !this[DECODER]?.lastNeed)) {            //@ts-ignore - sinful unsafe type change            chunk = Buffer.from(chunk, encoding);        }        if (Buffer.isBuffer(chunk) && this[ENCODING]) {            //@ts-ignore - sinful unsafe type change            chunk = this[DECODER].write(chunk);        }        // Note: flushing CAN potentially switch us into not-flowing mode        if (this[FLOWING] && this[BUFFERLENGTH] !== 0)            this[FLUSH](true);        if (this[FLOWING])            this.emit('data', chunk);        else            this[BUFFERPUSH](chunk);        if (this[BUFFERLENGTH] !== 0)            this.emit('readable');        if (cb)            fn(cb);        return this[FLOWING];    }    /**     * Low-level explicit read method.     *     * In objectMode, the argument is ignored, and one item is returned if     * available.     *     * `n` is the number of bytes (or in the case of encoding streams,     * characters) to consume. If `n` is not provided, then the entire buffer     * is returned, or `null` is returned if no data is available.     *     * If `n` is greater that the amount of data in the internal buffer,     * then `null` is returned.     */    read(n) {        if (this[DESTROYED])            return null;        this[DISCARDED] = false;        if (this[BUFFERLENGTH] === 0 ||            n === 0 ||            (n && n > this[BUFFERLENGTH])) {            this[MAYBE_EMIT_END]();            return null;        }        if (this[OBJECTMODE])            n = null;        if (this[BUFFER].length > 1 && !this[OBJECTMODE]) {            // not object mode, so if we have an encoding, then RType is string            // otherwise, must be Buffer            this[BUFFER] = [                (this[ENCODING]                    ? this[BUFFER].join('')                    : Buffer.concat(this[BUFFER], this[BUFFERLENGTH])),            ];        }        const ret = this[READ](n || null, this[BUFFER][0]);        this[MAYBE_EMIT_END]();        return ret;    }    [READ](n, chunk) {        if (this[OBJECTMODE])            this[BUFFERSHIFT]();        else {            const c = chunk;            if (n === c.length || n === null)                this[BUFFERSHIFT]();            else if (typeof c === 'string') {                this[BUFFER][0] = c.slice(n);                chunk = c.slice(0, n);                this[BUFFERLENGTH] -= n;            }            else {                this[BUFFER][0] = c.subarray(n);                chunk = c.subarray(0, n);                this[BUFFERLENGTH] -= n;            }        }        this.emit('data', chunk);        if (!this[BUFFER].length && !this[EOF])            this.emit('drain');        return chunk;    }    end(chunk, encoding, cb) {        if (typeof chunk === 'function') {            cb = chunk;            chunk = undefined;        }        if (typeof encoding === 'function') {            cb = encoding;            encoding = 'utf8';        }        if (chunk !== undefined)            this.write(chunk, encoding);        if (cb)            this.once('end', cb);        this[EOF] = true;        this.writable = false;        // if we haven't written anything, then go ahead and emit,        // even if we're not reading.        // we'll re-emit if a new 'end' listener is added anyway.        // This makes MP more suitable to write-only use cases.        if (this[FLOWING] || !this[PAUSED])            this[MAYBE_EMIT_END]();        return this;    }    // don't let the internal resume be overwritten    [RESUME]() {        if (this[DESTROYED])            return;        if (!this[DATALISTENERS] && !this[PIPES].length) {            this[DISCARDED] = true;        }        this[PAUSED] = false;        this[FLOWING] = true;        this.emit('resume');        if (this[BUFFER].length)            this[FLUSH]();        else if (this[EOF])            this[MAYBE_EMIT_END]();        else            this.emit('drain');    }    /**     * Resume the stream if it is currently in a paused state     *     * If called when there are no pipe destinations or `data` event listeners,     * this will place the stream in a "discarded" state, where all data will     * be thrown away. The discarded state is removed if a pipe destination or     * data handler is added, if pause() is called, or if any synchronous or     * asynchronous iteration is started.     */    resume() {        return this[RESUME]();    }    /**     * Pause the stream     */    pause() {        this[FLOWING] = false;        this[PAUSED] = true;        this[DISCARDED] = false;    }    /**     * true if the stream has been forcibly destroyed     */    get destroyed() {        return this[DESTROYED];    }    /**     * true if the stream is currently in a flowing state, meaning that     * any writes will be immediately emitted.     */    get flowing() {        return this[FLOWING];    }    /**     * true if the stream is currently in a paused state     */    get paused() {        return this[PAUSED];    }    [BUFFERPUSH](chunk) {        if (this[OBJECTMODE])            this[BUFFERLENGTH] += 1;        else            this[BUFFERLENGTH] += chunk.length;        this[BUFFER].push(chunk);    }    [BUFFERSHIFT]() {        if (this[OBJECTMODE])            this[BUFFERLENGTH] -= 1;        else            this[BUFFERLENGTH] -= this[BUFFER][0].length;        return this[BUFFER].shift();    }    [FLUSH](noDrain = false) {        do { } while (this[FLUSHCHUNK](this[BUFFERSHIFT]()) &&            this[BUFFER].length);        if (!noDrain && !this[BUFFER].length && !this[EOF])            this.emit('drain');    }    [FLUSHCHUNK](chunk) {        this.emit('data', chunk);        return this[FLOWING];    }    /**     * Pipe all data emitted by this stream into the destination provided.     *     * Triggers the flow of data.     */    pipe(dest, opts) {        if (this[DESTROYED])            return dest;        this[DISCARDED] = false;        const ended = this[EMITTED_END];        opts = opts || {};        if (dest === proc.stdout || dest === proc.stderr)            opts.end = false;        else            opts.end = opts.end !== false;        opts.proxyErrors = !!opts.proxyErrors;        // piping an ended stream ends immediately        if (ended) {            if (opts.end)                dest.end();        }        else {            // "as" here just ignores the WType, which pipes don't care about,            // since they're only consuming from us, and writing to the dest            this[PIPES].push(!opts.proxyErrors                ? new Pipe(this, dest, opts)                : new PipeProxyErrors(this, dest, opts));            if (this[ASYNC])                defer(() => this[RESUME]());            else                this[RESUME]();        }        return dest;    }    /**     * Fully unhook a piped destination stream.     *     * If the destination stream was the only consumer of this stream (ie,     * there are no other piped destinations or `'data'` event listeners)     * then the flow of data will stop until there is another consumer or     * {@link Minipass#resume} is explicitly called.     */    unpipe(dest) {        const p = this[PIPES].find(p => p.dest === dest);        if (p) {            if (this[PIPES].length === 1) {                if (this[FLOWING] && this[DATALISTENERS] === 0) {                    this[FLOWING] = false;                }                this[PIPES] = [];            }            else                this[PIPES].splice(this[PIPES].indexOf(p), 1);            p.unpipe();        }    }    /**     * Alias for {@link Minipass#on}     */    addListener(ev, handler) {        return this.on(ev, handler);    }    /**     * Mostly identical to `EventEmitter.on`, with the following     * behavior differences to prevent data loss and unnecessary hangs:     *     * - Adding a 'data' event handler will trigger the flow of data     *     * - Adding a 'readable' event handler when there is data waiting to be read     *   will cause 'readable' to be emitted immediately.     *     * - Adding an 'endish' event handler ('end', 'finish', etc.) which has     *   already passed will cause the event to be emitted immediately and all     *   handlers removed.     *     * - Adding an 'error' event handler after an error has been emitted will     *   cause the event to be re-emitted immediately with the error previously     *   raised.     */    on(ev, handler) {        const ret = super.on(ev, handler);        if (ev === 'data') {            this[DISCARDED] = false;            this[DATALISTENERS]++;            if (!this[PIPES].length && !this[FLOWING]) {                this[RESUME]();            }        }        else if (ev === 'readable' && this[BUFFERLENGTH] !== 0) {            super.emit('readable');        }        else if (isEndish(ev) && this[EMITTED_END]) {            super.emit(ev);            this.removeAllListeners(ev);        }        else if (ev === 'error' && this[EMITTED_ERROR]) {            const h = handler;            if (this[ASYNC])                defer(() => h.call(this, this[EMITTED_ERROR]));            else                h.call(this, this[EMITTED_ERROR]);        }        return ret;    }    /**     * Alias for {@link Minipass#off}     */    removeListener(ev, handler) {        return this.off(ev, handler);    }    /**     * Mostly identical to `EventEmitter.off`     *     * If a 'data' event handler is removed, and it was the last consumer     * (ie, there are no pipe destinations or other 'data' event listeners),     * then the flow of data will stop until there is another consumer or     * {@link Minipass#resume} is explicitly called.     */    off(ev, handler) {        const ret = super.off(ev, handler);        // if we previously had listeners, and now we don't, and we don't        // have any pipes, then stop the flow, unless it's been explicitly        // put in a discarded flowing state via stream.resume().        if (ev === 'data') {            this[DATALISTENERS] = this.listeners('data').length;            if (this[DATALISTENERS] === 0 &&                !this[DISCARDED] &&                !this[PIPES].length) {                this[FLOWING] = false;            }        }        return ret;    }    /**     * Mostly identical to `EventEmitter.removeAllListeners`     *     * If all 'data' event handlers are removed, and they were the last consumer     * (ie, there are no pipe destinations), then the flow of data will stop     * until there is another consumer or {@link Minipass#resume} is explicitly     * called.     */    removeAllListeners(ev) {        const ret = super.removeAllListeners(ev);        if (ev === 'data' || ev === undefined) {            this[DATALISTENERS] = 0;            if (!this[DISCARDED] && !this[PIPES].length) {                this[FLOWING] = false;            }        }        return ret;    }    /**     * true if the 'end' event has been emitted     */    get emittedEnd() {        return this[EMITTED_END];    }    [MAYBE_EMIT_END]() {        if (!this[EMITTING_END] &&            !this[EMITTED_END] &&            !this[DESTROYED] &&            this[BUFFER].length === 0 &&            this[EOF]) {            this[EMITTING_END] = true;            this.emit('end');            this.emit('prefinish');            this.emit('finish');            if (this[CLOSED])                this.emit('close');            this[EMITTING_END] = false;        }    }    /**     * Mostly identical to `EventEmitter.emit`, with the following     * behavior differences to prevent data loss and unnecessary hangs:     *     * If the stream has been destroyed, and the event is something other     * than 'close' or 'error', then `false` is returned and no handlers     * are called.     *     * If the event is 'end', and has already been emitted, then the event     * is ignored. If the stream is in a paused or non-flowing state, then     * the event will be deferred until data flow resumes. If the stream is     * async, then handlers will be called on the next tick rather than     * immediately.     *     * If the event is 'close', and 'end' has not yet been emitted, then     * the event will be deferred until after 'end' is emitted.     *     * If the event is 'error', and an AbortSignal was provided for the stream,     * and there are no listeners, then the event is ignored, matching the     * behavior of node core streams in the presense of an AbortSignal.     *     * If the event is 'finish' or 'prefinish', then all listeners will be     * removed after emitting the event, to prevent double-firing.     */    emit(ev, ...args) {        const data = args[0];        // error and close are only events allowed after calling destroy()        if (ev !== 'error' &&            ev !== 'close' &&            ev !== DESTROYED &&            this[DESTROYED]) {            return false;        }        else if (ev === 'data') {            return !this[OBJECTMODE] && !data                ? false                : this[ASYNC]                    ? (defer(() => this[EMITDATA](data)), true)                    : this[EMITDATA](data);        }        else if (ev === 'end') {            return this[EMITEND]();        }        else if (ev === 'close') {            this[CLOSED] = true;            // don't emit close before 'end' and 'finish'            if (!this[EMITTED_END] && !this[DESTROYED])                return false;            const ret = super.emit('close');            this.removeAllListeners('close');            return ret;        }        else if (ev === 'error') {            this[EMITTED_ERROR] = data;            super.emit(ERROR, data);            const ret = !this[SIGNAL] || this.listeners('error').length                ? super.emit('error', data)                : false;            this[MAYBE_EMIT_END]();            return ret;        }        else if (ev === 'resume') {            const ret = super.emit('resume');            this[MAYBE_EMIT_END]();            return ret;        }        else if (ev === 'finish' || ev === 'prefinish') {            const ret = super.emit(ev);            this.removeAllListeners(ev);            return ret;        }        // Some other unknown event        const ret = super.emit(ev, ...args);        this[MAYBE_EMIT_END]();        return ret;    }    [EMITDATA](data) {        for (const p of this[PIPES]) {            if (p.dest.write(data) === false)                this.pause();        }        const ret = this[DISCARDED] ? false : super.emit('data', data);        this[MAYBE_EMIT_END]();        return ret;    }    [EMITEND]() {        if (this[EMITTED_END])            return false;        this[EMITTED_END] = true;        this.readable = false;        return this[ASYNC]            ? (defer(() => this[EMITEND2]()), true)            : this[EMITEND2]();    }    [EMITEND2]() {        if (this[DECODER]) {            const data = this[DECODER].end();            if (data) {                for (const p of this[PIPES]) {                    p.dest.write(data);                }                if (!this[DISCARDED])                    super.emit('data', data);            }        }        for (const p of this[PIPES]) {            p.end();        }        const ret = super.emit('end');        this.removeAllListeners('end');        return ret;    }    /**     * Return a Promise that resolves to an array of all emitted data once     * the stream ends.     */    async collect() {        const buf = Object.assign([], {            dataLength: 0,        });        if (!this[OBJECTMODE])            buf.dataLength = 0;        // set the promise first, in case an error is raised        // by triggering the flow here.        const p = this.promise();        this.on('data', c => {            buf.push(c);            if (!this[OBJECTMODE])                buf.dataLength += c.length;        });        await p;        return buf;    }    /**     * Return a Promise that resolves to the concatenation of all emitted data     * once the stream ends.     *     * Not allowed on objectMode streams.     */    async concat() {        if (this[OBJECTMODE]) {            throw new Error('cannot concat in objectMode');        }        const buf = await this.collect();        return (this[ENCODING]            ? buf.join('')            : Buffer.concat(buf, buf.dataLength));    }    /**     * Return a void Promise that resolves once the stream ends.     */    async promise() {        return new Promise((resolve, reject) => {            this.on(DESTROYED, () => reject(new Error('stream destroyed')));            this.on('error', er => reject(er));            this.on('end', () => resolve());        });    }    /**     * Asynchronous `for await of` iteration.     *     * This will continue emitting all chunks until the stream terminates.     */    [Symbol.asyncIterator]() {        // set this up front, in case the consumer doesn't call next()        // right away.        this[DISCARDED] = false;        let stopped = false;        const stop = async () => {            this.pause();            stopped = true;            return { value: undefined, done: true };        };        const next = () => {            if (stopped)                return stop();            const res = this.read();            if (res !== null)                return Promise.resolve({ done: false, value: res });            if (this[EOF])                return stop();            let resolve;            let reject;            const onerr = (er) => {                this.off('data', ondata);                this.off('end', onend);                this.off(DESTROYED, ondestroy);                stop();                reject(er);            };            const ondata = (value) => {                this.off('error', onerr);                this.off('end', onend);                this.off(DESTROYED, ondestroy);                this.pause();                resolve({ value, done: !!this[EOF] });            };            const onend = () => {                this.off('error', onerr);                this.off('data', ondata);                this.off(DESTROYED, ondestroy);                stop();                resolve({ done: true, value: undefined });            };            const ondestroy = () => onerr(new Error('stream destroyed'));            return new Promise((res, rej) => {                reject = rej;                resolve = res;                this.once(DESTROYED, ondestroy);                this.once('error', onerr);                this.once('end', onend);                this.once('data', ondata);            });        };        return {            next,            throw: stop,            return: stop,            [Symbol.asyncIterator]() {                return this;            },            [Symbol.asyncDispose]: async () => { },        };    }    /**     * Synchronous `for of` iteration.     *     * The iteration will terminate when the internal buffer runs out, even     * if the stream has not yet terminated.     */    [Symbol.iterator]() {        // set this up front, in case the consumer doesn't call next()        // right away.        this[DISCARDED] = false;        let stopped = false;        const stop = () => {            this.pause();            this.off(ERROR, stop);            this.off(DESTROYED, stop);            this.off('end', stop);            stopped = true;            return { done: true, value: undefined };        };        const next = () => {            if (stopped)                return stop();            const value = this.read();            return value === null ? stop() : { done: false, value };        };        this.once('end', stop);        this.once(ERROR, stop);        this.once(DESTROYED, stop);        return {            next,            throw: stop,            return: stop,            [Symbol.iterator]() {                return this;            },            [Symbol.dispose]: () => { },        };    }    /**     * Destroy a stream, preventing it from being used for any further purpose.     *     * If the stream has a `close()` method, then it will be called on     * destruction.     *     * After destruction, any attempt to write data, read data, or emit most     * events will be ignored.     *     * If an error argument is provided, then it will be emitted in an     * 'error' event.     */    destroy(er) {        if (this[DESTROYED]) {            if (er)                this.emit('error', er);            else                this.emit(DESTROYED);            return this;        }        this[DESTROYED] = true;        this[DISCARDED] = true;        // throw away all buffered data, it's never coming out        this[BUFFER].length = 0;        this[BUFFERLENGTH] = 0;        const wc = this;        if (typeof wc.close === 'function' && !this[CLOSED])            wc.close();        if (er)            this.emit('error', er);        // if no error to emit, still reject pending promises        else            this.emit(DESTROYED);        return this;    }    /**     * Alias for {@link isStream}     *     * Former export location, maintained for backwards compatibility.     *     * @deprecated     */    static get isStream() {        return isStream;    }}//# sourceMappingURL=index.js.map