Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
index.js1038 linesDownload Raw Back to commonjs
1"use strict";
2var __importDefault = (this && this.__importDefault) || function (mod) {
3    return (mod && mod.__esModule) ? mod : { "default": mod };
4};
5Object.defineProperty(exports, "__esModule", { value: true });
6exports.Minipass = exports.isWritable = exports.isReadable = exports.isStream = void 0;
7const proc = typeof process === 'object' && process
8    ? process
9    : {
10        stdout: null,
11        stderr: null,
12    };
13const node_events_1 = require("node:events");
14const node_stream_1 = __importDefault(require("node:stream"));
15const node_string_decoder_1 = require("node:string_decoder");
16/**
17 * Return true if the argument is a Minipass stream, Node stream, or something
18 * else that Minipass can interact with.
19 */
20const isStream = (s) => !!s &&
21    typeof s === 'object' &&
22    (s instanceof Minipass ||
23        s instanceof node_stream_1.default ||
24        (0, exports.isReadable)(s) ||
25        (0, exports.isWritable)(s))
26/**
27 * Return true if the argument is a valid {@link Minipass.Readable}
28 */
29;
30exports.isStream = isStream;
31/**
32 * Return true if the argument is a valid {@link Minipass.Readable}
33 */
34const isReadable = (s) => !!s &&
35    typeof s === 'object' &&
36    s instanceof node_events_1.EventEmitter &&
37    typeof s.pipe === 'function' &&
38    // node core Writable streams have a pipe() method, but it throws
39    s.pipe !== node_stream_1.default.Writable.prototype.pipe
40/**
41 * Return true if the argument is a valid {@link Minipass.Writable}
42 */
43;
44exports.isReadable = isReadable;
45/**
46 * Return true if the argument is a valid {@link Minipass.Writable}
47 */
48const isWritable = (s) => !!s &&
49    typeof s === 'object' &&
50    s instanceof node_events_1.EventEmitter &&
51    typeof s.write === 'function' &&
52    typeof s.end === 'function';
53exports.isWritable = isWritable;
54const EOF = Symbol('EOF');
55const MAYBE_EMIT_END = Symbol('maybeEmitEnd');
56const EMITTED_END = Symbol('emittedEnd');
57const EMITTING_END = Symbol('emittingEnd');
58const EMITTED_ERROR = Symbol('emittedError');
59const CLOSED = Symbol('closed');
60const READ = Symbol('read');
61const FLUSH = Symbol('flush');
62const FLUSHCHUNK = Symbol('flushChunk');
63const ENCODING = Symbol('encoding');
64const DECODER = Symbol('decoder');
65const FLOWING = Symbol('flowing');
66const PAUSED = Symbol('paused');
67const RESUME = Symbol('resume');
68const BUFFER = Symbol('buffer');
69const PIPES = Symbol('pipes');
70const BUFFERLENGTH = Symbol('bufferLength');
71const BUFFERPUSH = Symbol('bufferPush');
72const BUFFERSHIFT = Symbol('bufferShift');
73const OBJECTMODE = Symbol('objectMode');
74// internal event when stream is destroyed
75const DESTROYED = Symbol('destroyed');
76// internal event when stream has an error
77const ERROR = Symbol('error');
78const EMITDATA = Symbol('emitData');
79const EMITEND = Symbol('emitEnd');
80const EMITEND2 = Symbol('emitEnd2');
81const ASYNC = Symbol('async');
82const ABORT = Symbol('abort');
83const ABORTED = Symbol('aborted');
84const SIGNAL = Symbol('signal');
85const DATALISTENERS = Symbol('dataListeners');
86const DISCARDED = Symbol('discarded');
87const defer = (fn) => Promise.resolve().then(fn);
88const nodefer = (fn) => fn();
89const isEndish = (ev) => ev === 'end' || ev === 'finish' || ev === 'prefinish';
90const isArrayBufferLike = (b) => b instanceof ArrayBuffer ||
91    (!!b &&
92        typeof b === 'object' &&
93        b.constructor &&
94        b.constructor.name === 'ArrayBuffer' &&
95        b.byteLength >= 0);
96const isArrayBufferView = (b) => !Buffer.isBuffer(b) && ArrayBuffer.isView(b);
97/**
98 * Internal class representing a pipe to a destination stream.
99 *
100 * @internal
101 */
102class Pipe {
103    src;
104    dest;
105    opts;
106    ondrain;
107    constructor(src, dest, opts) {
108        this.src = src;
109        this.dest = dest;
110        this.opts = opts;
111        this.ondrain = () => src[RESUME]();
112        this.dest.on('drain', this.ondrain);
113    }
114    unpipe() {
115        this.dest.removeListener('drain', this.ondrain);
116    }
117    // only here for the prototype
118    /* c8 ignore start */
119    proxyErrors(_er) { }
120    /* c8 ignore stop */
121    end() {
122        this.unpipe();
123        if (this.opts.end)
124            this.dest.end();
125    }
126}
127/**
128 * Internal class representing a pipe to a destination stream where
129 * errors are proxied.
130 *
131 * @internal
132 */
133class PipeProxyErrors extends Pipe {
134    unpipe() {
135        this.src.removeListener('error', this.proxyErrors);
136        super.unpipe();
137    }
138    constructor(src, dest, opts) {
139        super(src, dest, opts);
140        this.proxyErrors = (er) => this.dest.emit('error', er);
141        src.on('error', this.proxyErrors);
142    }
143}
144const isObjectModeOptions = (o) => !!o.objectMode;
145const isEncodingOptions = (o) => !o.objectMode && !!o.encoding && o.encoding !== 'buffer';
146/**
147 * Main export, the Minipass class
148 *
149 * `RType` is the type of data emitted, defaults to Buffer
150 *
151 * `WType` is the type of data to be written, if RType is buffer or string,
152 * then any {@link Minipass.ContiguousData} is allowed.
153 *
154 * `Events` is the set of event handler signatures that this object
155 * will emit, see {@link Minipass.Events}
156 */
157class Minipass extends node_events_1.EventEmitter {
158    [FLOWING] = false;
159    [PAUSED] = false;
160    [PIPES] = [];
161    [BUFFER] = [];
162    [OBJECTMODE];
163    [ENCODING];
164    [ASYNC];
165    [DECODER];
166    [EOF] = false;
167    [EMITTED_END] = false;
168    [EMITTING_END] = false;
169    [CLOSED] = false;
170    [EMITTED_ERROR] = null;
171    [BUFFERLENGTH] = 0;
172    [DESTROYED] = false;
173    [SIGNAL];
174    [ABORTED] = false;
175    [DATALISTENERS] = 0;
176    [DISCARDED] = false;
177    /**
178     * true if the stream can be written
179     */
180    writable = true;
181    /**
182     * true if the stream can be read
183     */
184    readable = true;
185    /**
186     * If `RType` is Buffer, then options do not need to be provided.
187     * Otherwise, an options object must be provided to specify either
188     * {@link Minipass.SharedOptions.objectMode} or
189     * {@link Minipass.SharedOptions.encoding}, as appropriate.
190     */
191    constructor(...args) {
192        const options = (args[0] ||
193            {});
194        super();
195        if (options.objectMode && typeof options.encoding === 'string') {
196            throw new TypeError('Encoding and objectMode may not be used together');
197        }
198        if (isObjectModeOptions(options)) {
199            this[OBJECTMODE] = true;
200            this[ENCODING] = null;
201        }
202        else if (isEncodingOptions(options)) {
203            this[ENCODING] = options.encoding;
204            this[OBJECTMODE] = false;
205        }
206        else {
207            this[OBJECTMODE] = false;
208            this[ENCODING] = null;
209        }
210        this[ASYNC] = !!options.async;
211        this[DECODER] = this[ENCODING]
212            ? new node_string_decoder_1.StringDecoder(this[ENCODING])
213            : null;
214        //@ts-ignore - private option for debugging and testing
215        if (options && options.debugExposeBuffer === true) {
216            Object.defineProperty(this, 'buffer', { get: () => this[BUFFER] });
217        }
218        //@ts-ignore - private option for debugging and testing
219        if (options && options.debugExposePipes === true) {
220            Object.defineProperty(this, 'pipes', { get: () => this[PIPES] });
221        }
222        const { signal } = options;
223        if (signal) {
224            this[SIGNAL] = signal;
225            if (signal.aborted) {
226                this[ABORT]();
227            }
228            else {
229                signal.addEventListener('abort', () => this[ABORT]());
230            }
231        }
232    }
233    /**
234     * The amount of data stored in the buffer waiting to be read.
235     *
236     * For Buffer strings, this will be the total byte length.
237     * For string encoding streams, this will be the string character length,
238     * according to JavaScript's `string.length` logic.
239     * For objectMode streams, this is a count of the items waiting to be
240     * emitted.
241     */
242    get bufferLength() {
243        return this[BUFFERLENGTH];
244    }
245    /**
246     * The `BufferEncoding` currently in use, or `null`
247     */
248    get encoding() {
249        return this[ENCODING];
250    }
251    /**
252     * @deprecated - This is a read only property
253     */
254    set encoding(_enc) {
255        throw new Error('Encoding must be set at instantiation time');
256    }
257    /**
258     * @deprecated - Encoding may only be set at instantiation time
259     */
260    setEncoding(_enc) {
261        throw new Error('Encoding must be set at instantiation time');
262    }
263    /**
264     * True if this is an objectMode stream
265     */
266    get objectMode() {
267        return this[OBJECTMODE];
268    }
269    /**
270     * @deprecated - This is a read-only property
271     */
272    set objectMode(_om) {
273        throw new Error('objectMode must be set at instantiation time');
274    }
275    /**
276     * true if this is an async stream
277     */
278    get ['async']() {
279        return this[ASYNC];
280    }
281    /**
282     * Set to true to make this stream async.
283     *
284     * Once set, it cannot be unset, as this would potentially cause incorrect
285     * behavior.  Ie, a sync stream can be made async, but an async stream
286     * cannot be safely made sync.
287     */
288    set ['async'](a) {
289        this[ASYNC] = this[ASYNC] || !!a;
290    }
291    // drop everything and get out of the flow completely
292    [ABORT]() {
293        this[ABORTED] = true;
294        this.emit('abort', this[SIGNAL]?.reason);
295        this.destroy(this[SIGNAL]?.reason);
296    }
297    /**
298     * True if the stream has been aborted.
299     */
300    get aborted() {
301        return this[ABORTED];
302    }
303    /**
304     * No-op setter. Stream aborted status is set via the AbortSignal provided
305     * in the constructor options.
306     */
307    set aborted(_) { }
308    write(chunk, encoding, cb) {
309        if (this[ABORTED])
310            return false;
311        if (this[EOF])
312            throw new Error('write after end');
313        if (this[DESTROYED]) {
314            this.emit('error', Object.assign(new Error('Cannot call write after a stream was destroyed'), { code: 'ERR_STREAM_DESTROYED' }));
315            return true;
316        }
317        if (typeof encoding === 'function') {
318            cb = encoding;
319            encoding = 'utf8';
320        }
321        if (!encoding)
322            encoding = 'utf8';
323        const fn = this[ASYNC] ? defer : nodefer;
324        // convert array buffers and typed array views into buffers
325        // at some point in the future, we may want to do the opposite!
326        // leave strings and buffers as-is
327        // anything is only allowed if in object mode, so throw
328        if (!this[OBJECTMODE] && !Buffer.isBuffer(chunk)) {
329            if (isArrayBufferView(chunk)) {
330                //@ts-ignore - sinful unsafe type changing
331                chunk = Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength);
332            }
333            else if (isArrayBufferLike(chunk)) {
334                //@ts-ignore - sinful unsafe type changing
335                chunk = Buffer.from(chunk);
336            }
337            else if (typeof chunk !== 'string') {
338                throw new Error('Non-contiguous data written to non-objectMode stream');
339            }
340        }
341        // handle object mode up front, since it's simpler
342        // this yields better performance, fewer checks later.
343        if (this[OBJECTMODE]) {
344            // maybe impossible?
345            /* c8 ignore start */
346            if (this[FLOWING] && this[BUFFERLENGTH] !== 0)
347                this[FLUSH](true);
348            /* c8 ignore stop */
349            if (this[FLOWING])
350                this.emit('data', chunk);
351            else
352                this[BUFFERPUSH](chunk);
353            if (this[BUFFERLENGTH] !== 0)
354                this.emit('readable');
355            if (cb)
356                fn(cb);
357            return this[FLOWING];
358        }
359        // at this point the chunk is a buffer or string
360        // don't buffer it up or send it to the decoder
361        if (!chunk.length) {
362            if (this[BUFFERLENGTH] !== 0)
363                this.emit('readable');
364            if (cb)
365                fn(cb);
366            return this[FLOWING];
367        }
368        // fast-path writing strings of same encoding to a stream with
369        // an empty buffer, skipping the buffer/decoder dance
370        if (typeof chunk === 'string' &&
371            // unless it is a string already ready for us to use
372            !(encoding === this[ENCODING] && !this[DECODER]?.lastNeed)) {
373            //@ts-ignore - sinful unsafe type change
374            chunk = Buffer.from(chunk, encoding);
375        }
376        if (Buffer.isBuffer(chunk) && this[ENCODING]) {
377            //@ts-ignore - sinful unsafe type change
378            chunk = this[DECODER].write(chunk);
379        }
380        // Note: flushing CAN potentially switch us into not-flowing mode
381        if (this[FLOWING] && this[BUFFERLENGTH] !== 0)
382            this[FLUSH](true);
383        if (this[FLOWING])
384            this.emit('data', chunk);
385        else
386            this[BUFFERPUSH](chunk);
387        if (this[BUFFERLENGTH] !== 0)
388            this.emit('readable');
389        if (cb)
390            fn(cb);
391        return this[FLOWING];
392    }
393    /**
394     * Low-level explicit read method.
395     *
396     * In objectMode, the argument is ignored, and one item is returned if
397     * available.
398     *
399     * `n` is the number of bytes (or in the case of encoding streams,
400     * characters) to consume. If `n` is not provided, then the entire buffer
401     * is returned, or `null` is returned if no data is available.
402     *
403     * If `n` is greater that the amount of data in the internal buffer,
404     * then `null` is returned.
405     */
406    read(n) {
407        if (this[DESTROYED])
408            return null;
409        this[DISCARDED] = false;
410        if (this[BUFFERLENGTH] === 0 ||
411            n === 0 ||
412            (n && n > this[BUFFERLENGTH])) {
413            this[MAYBE_EMIT_END]();
414            return null;
415        }
416        if (this[OBJECTMODE])
417            n = null;
418        if (this[BUFFER].length > 1 && !this[OBJECTMODE]) {
419            // not object mode, so if we have an encoding, then RType is string
420            // otherwise, must be Buffer
421            this[BUFFER] = [
422                (this[ENCODING]
423                    ? this[BUFFER].join('')
424                    : Buffer.concat(this[BUFFER], this[BUFFERLENGTH])),
425            ];
426        }
427        const ret = this[READ](n || null, this[BUFFER][0]);
428        this[MAYBE_EMIT_END]();
429        return ret;
430    }
431    [READ](n, chunk) {
432        if (this[OBJECTMODE])
433            this[BUFFERSHIFT]();
434        else {
435            const c = chunk;
436            if (n === c.length || n === null)
437                this[BUFFERSHIFT]();
438            else if (typeof c === 'string') {
439                this[BUFFER][0] = c.slice(n);
440                chunk = c.slice(0, n);
441                this[BUFFERLENGTH] -= n;
442            }
443            else {
444                this[BUFFER][0] = c.subarray(n);
445                chunk = c.subarray(0, n);
446                this[BUFFERLENGTH] -= n;
447            }
448        }
449        this.emit('data', chunk);
450        if (!this[BUFFER].length && !this[EOF])
451            this.emit('drain');
452        return chunk;
453    }
454    end(chunk, encoding, cb) {
455        if (typeof chunk === 'function') {
456            cb = chunk;
457            chunk = undefined;
458        }
459        if (typeof encoding === 'function') {
460            cb = encoding;
461            encoding = 'utf8';
462        }
463        if (chunk !== undefined)
464            this.write(chunk, encoding);
465        if (cb)
466            this.once('end', cb);
467        this[EOF] = true;
468        this.writable = false;
469        // if we haven't written anything, then go ahead and emit,
470        // even if we're not reading.
471        // we'll re-emit if a new 'end' listener is added anyway.
472        // This makes MP more suitable to write-only use cases.
473        if (this[FLOWING] || !this[PAUSED])
474            this[MAYBE_EMIT_END]();
475        return this;
476    }
477    // don't let the internal resume be overwritten
478    [RESUME]() {
479        if (this[DESTROYED])
480            return;
481        if (!this[DATALISTENERS] && !this[PIPES].length) {
482            this[DISCARDED] = true;
483        }
484        this[PAUSED] = false;
485        this[FLOWING] = true;
486        this.emit('resume');
487        if (this[BUFFER].length)
488            this[FLUSH]();
489        else if (this[EOF])
490            this[MAYBE_EMIT_END]();
491        else
492            this.emit('drain');
493    }
494    /**
495     * Resume the stream if it is currently in a paused state
496     *
497     * If called when there are no pipe destinations or `data` event listeners,
498     * this will place the stream in a "discarded" state, where all data will
499     * be thrown away. The discarded state is removed if a pipe destination or
500     * data handler is added, if pause() is called, or if any synchronous or
501     * asynchronous iteration is started.
502     */
503    resume() {
504        return this[RESUME]();
505    }
506    /**
507     * Pause the stream
508     */
509    pause() {
510        this[FLOWING] = false;
511        this[PAUSED] = true;
512        this[DISCARDED] = false;
513    }
514    /**
515     * true if the stream has been forcibly destroyed
516     */
517    get destroyed() {
518        return this[DESTROYED];
519    }
520    /**
521     * true if the stream is currently in a flowing state, meaning that
522     * any writes will be immediately emitted.
523     */
524    get flowing() {
525        return this[FLOWING];
526    }
527    /**
528     * true if the stream is currently in a paused state
529     */
530    get paused() {
531        return this[PAUSED];
532    }
533    [BUFFERPUSH](chunk) {
534        if (this[OBJECTMODE])
535            this[BUFFERLENGTH] += 1;
536        else
537            this[BUFFERLENGTH] += chunk.length;
538        this[BUFFER].push(chunk);
539    }
540    [BUFFERSHIFT]() {
541        if (this[OBJECTMODE])
542            this[BUFFERLENGTH] -= 1;
543        else
544            this[BUFFERLENGTH] -= this[BUFFER][0].length;
545        return this[BUFFER].shift();
546    }
547    [FLUSH](noDrain = false) {
548        do { } while (this[FLUSHCHUNK](this[BUFFERSHIFT]()) &&
549            this[BUFFER].length);
550        if (!noDrain && !this[BUFFER].length && !this[EOF])
551            this.emit('drain');
552    }
553    [FLUSHCHUNK](chunk) {
554        this.emit('data', chunk);
555        return this[FLOWING];
556    }
557    /**
558     * Pipe all data emitted by this stream into the destination provided.
559     *
560     * Triggers the flow of data.
561     */
562    pipe(dest, opts) {
563        if (this[DESTROYED])
564            return dest;
565        this[DISCARDED] = false;
566        const ended = this[EMITTED_END];
567        opts = opts || {};
568        if (dest === proc.stdout || dest === proc.stderr)
569            opts.end = false;
570        else
571            opts.end = opts.end !== false;
572        opts.proxyErrors = !!opts.proxyErrors;
573        // piping an ended stream ends immediately
574        if (ended) {
575            if (opts.end)
576                dest.end();
577        }
578        else {
579            // "as" here just ignores the WType, which pipes don't care about,
580            // since they're only consuming from us, and writing to the dest
581            this[PIPES].push(!opts.proxyErrors
582                ? new Pipe(this, dest, opts)
583                : new PipeProxyErrors(this, dest, opts));
584            if (this[ASYNC])
585                defer(() => this[RESUME]());
586            else
587                this[RESUME]();
588        }
589        return dest;
590    }
591    /**
592     * Fully unhook a piped destination stream.
593     *
594     * If the destination stream was the only consumer of this stream (ie,
595     * there are no other piped destinations or `'data'` event listeners)
596     * then the flow of data will stop until there is another consumer or
597     * {@link Minipass#resume} is explicitly called.
598     */
599    unpipe(dest) {
600        const p = this[PIPES].find(p => p.dest === dest);
601        if (p) {
602            if (this[PIPES].length === 1) {
603                if (this[FLOWING] && this[DATALISTENERS] === 0) {
604                    this[FLOWING] = false;
605                }
606                this[PIPES] = [];
607            }
608            else
609                this[PIPES].splice(this[PIPES].indexOf(p), 1);
610            p.unpipe();
611        }
612    }
613    /**
614     * Alias for {@link Minipass#on}
615     */
616    addListener(ev, handler) {
617        return this.on(ev, handler);
618    }
619    /**
620     * Mostly identical to `EventEmitter.on`, with the following
621     * behavior differences to prevent data loss and unnecessary hangs:
622     *
623     * - Adding a 'data' event handler will trigger the flow of data
624     *
625     * - Adding a 'readable' event handler when there is data waiting to be read
626     *   will cause 'readable' to be emitted immediately.
627     *
628     * - Adding an 'endish' event handler ('end', 'finish', etc.) which has
629     *   already passed will cause the event to be emitted immediately and all
630     *   handlers removed.
631     *
632     * - Adding an 'error' event handler after an error has been emitted will
633     *   cause the event to be re-emitted immediately with the error previously
634     *   raised.
635     */
636    on(ev, handler) {
637        const ret = super.on(ev, handler);
638        if (ev === 'data') {
639            this[DISCARDED] = false;
640            this[DATALISTENERS]++;
641            if (!this[PIPES].length && !this[FLOWING]) {
642                this[RESUME]();
643            }
644        }
645        else if (ev === 'readable' && this[BUFFERLENGTH] !== 0) {
646            super.emit('readable');
647        }
648        else if (isEndish(ev) && this[EMITTED_END]) {
649            super.emit(ev);
650            this.removeAllListeners(ev);
651        }
652        else if (ev === 'error' && this[EMITTED_ERROR]) {
653            const h = handler;
654            if (this[ASYNC])
655                defer(() => h.call(this, this[EMITTED_ERROR]));
656            else
657                h.call(this, this[EMITTED_ERROR]);
658        }
659        return ret;
660    }
661    /**
662     * Alias for {@link Minipass#off}
663     */
664    removeListener(ev, handler) {
665        return this.off(ev, handler);
666    }
667    /**
668     * Mostly identical to `EventEmitter.off`
669     *
670     * If a 'data' event handler is removed, and it was the last consumer
671     * (ie, there are no pipe destinations or other 'data' event listeners),
672     * then the flow of data will stop until there is another consumer or
673     * {@link Minipass#resume} is explicitly called.
674     */
675    off(ev, handler) {
676        const ret = super.off(ev, handler);
677        // if we previously had listeners, and now we don't, and we don't
678        // have any pipes, then stop the flow, unless it's been explicitly
679        // put in a discarded flowing state via stream.resume().
680        if (ev === 'data') {
681            this[DATALISTENERS] = this.listeners('data').length;
682            if (this[DATALISTENERS] === 0 &&
683                !this[DISCARDED] &&
684                !this[PIPES].length) {
685                this[FLOWING] = false;
686            }
687        }
688        return ret;
689    }
690    /**
691     * Mostly identical to `EventEmitter.removeAllListeners`
692     *
693     * If all 'data' event handlers are removed, and they were the last consumer
694     * (ie, there are no pipe destinations), then the flow of data will stop
695     * until there is another consumer or {@link Minipass#resume} is explicitly
696     * called.
697     */
698    removeAllListeners(ev) {
699        const ret = super.removeAllListeners(ev);
700        if (ev === 'data' || ev === undefined) {
701            this[DATALISTENERS] = 0;
702            if (!this[DISCARDED] && !this[PIPES].length) {
703                this[FLOWING] = false;
704            }
705        }
706        return ret;
707    }
708    /**
709     * true if the 'end' event has been emitted
710     */
711    get emittedEnd() {
712        return this[EMITTED_END];
713    }
714    [MAYBE_EMIT_END]() {
715        if (!this[EMITTING_END] &&
716            !this[EMITTED_END] &&
717            !this[DESTROYED] &&
718            this[BUFFER].length === 0 &&
719            this[EOF]) {
720            this[EMITTING_END] = true;
721            this.emit('end');
722            this.emit('prefinish');
723            this.emit('finish');
724            if (this[CLOSED])
725                this.emit('close');
726            this[EMITTING_END] = false;
727        }
728    }
729    /**
730     * Mostly identical to `EventEmitter.emit`, with the following
731     * behavior differences to prevent data loss and unnecessary hangs:
732     *
733     * If the stream has been destroyed, and the event is something other
734     * than 'close' or 'error', then `false` is returned and no handlers
735     * are called.
736     *
737     * If the event is 'end', and has already been emitted, then the event
738     * is ignored. If the stream is in a paused or non-flowing state, then
739     * the event will be deferred until data flow resumes. If the stream is
740     * async, then handlers will be called on the next tick rather than
741     * immediately.
742     *
743     * If the event is 'close', and 'end' has not yet been emitted, then
744     * the event will be deferred until after 'end' is emitted.
745     *
746     * If the event is 'error', and an AbortSignal was provided for the stream,
747     * and there are no listeners, then the event is ignored, matching the
748     * behavior of node core streams in the presense of an AbortSignal.
749     *
750     * If the event is 'finish' or 'prefinish', then all listeners will be
751     * removed after emitting the event, to prevent double-firing.
752     */
753    emit(ev, ...args) {
754        const data = args[0];
755        // error and close are only events allowed after calling destroy()
756        if (ev !== 'error' &&
757            ev !== 'close' &&
758            ev !== DESTROYED &&
759            this[DESTROYED]) {
760            return false;
761        }
762        else if (ev === 'data') {
763            return !this[OBJECTMODE] && !data
764                ? false
765                : this[ASYNC]
766                    ? (defer(() => this[EMITDATA](data)), true)
767                    : this[EMITDATA](data);
768        }
769        else if (ev === 'end') {
770            return this[EMITEND]();
771        }
772        else if (ev === 'close') {
773            this[CLOSED] = true;
774            // don't emit close before 'end' and 'finish'
775            if (!this[EMITTED_END] && !this[DESTROYED])
776                return false;
777            const ret = super.emit('close');
778            this.removeAllListeners('close');
779            return ret;
780        }
781        else if (ev === 'error') {
782            this[EMITTED_ERROR] = data;
783            super.emit(ERROR, data);
784            const ret = !this[SIGNAL] || this.listeners('error').length
785                ? super.emit('error', data)
786                : false;
787            this[MAYBE_EMIT_END]();
788            return ret;
789        }
790        else if (ev === 'resume') {
791            const ret = super.emit('resume');
792            this[MAYBE_EMIT_END]();
793            return ret;
794        }
795        else if (ev === 'finish' || ev === 'prefinish') {
796            const ret = super.emit(ev);
797            this.removeAllListeners(ev);
798            return ret;
799        }
800        // Some other unknown event
801        const ret = super.emit(ev, ...args);
802        this[MAYBE_EMIT_END]();
803        return ret;
804    }
805    [EMITDATA](data) {
806        for (const p of this[PIPES]) {
807            if (p.dest.write(data) === false)
808                this.pause();
809        }
810        const ret = this[DISCARDED] ? false : super.emit('data', data);
811        this[MAYBE_EMIT_END]();
812        return ret;
813    }
814    [EMITEND]() {
815        if (this[EMITTED_END])
816            return false;
817        this[EMITTED_END] = true;
818        this.readable = false;
819        return this[ASYNC]
820            ? (defer(() => this[EMITEND2]()), true)
821            : this[EMITEND2]();
822    }
823    [EMITEND2]() {
824        if (this[DECODER]) {
825            const data = this[DECODER].end();
826            if (data) {
827                for (const p of this[PIPES]) {
828                    p.dest.write(data);
829                }
830                if (!this[DISCARDED])
831                    super.emit('data', data);
832            }
833        }
834        for (const p of this[PIPES]) {
835            p.end();
836        }
837        const ret = super.emit('end');
838        this.removeAllListeners('end');
839        return ret;
840    }
841    /**
842     * Return a Promise that resolves to an array of all emitted data once
843     * the stream ends.
844     */
845    async collect() {
846        const buf = Object.assign([], {
847            dataLength: 0,
848        });
849        if (!this[OBJECTMODE])
850            buf.dataLength = 0;
851        // set the promise first, in case an error is raised
852        // by triggering the flow here.
853        const p = this.promise();
854        this.on('data', c => {
855            buf.push(c);
856            if (!this[OBJECTMODE])
857                buf.dataLength += c.length;
858        });
859        await p;
860        return buf;
861    }
862    /**
863     * Return a Promise that resolves to the concatenation of all emitted data
864     * once the stream ends.
865     *
866     * Not allowed on objectMode streams.
867     */
868    async concat() {
869        if (this[OBJECTMODE]) {
870            throw new Error('cannot concat in objectMode');
871        }
872        const buf = await this.collect();
873        return (this[ENCODING]
874            ? buf.join('')
875            : Buffer.concat(buf, buf.dataLength));
876    }
877    /**
878     * Return a void Promise that resolves once the stream ends.
879     */
880    async promise() {
881        return new Promise((resolve, reject) => {
882            this.on(DESTROYED, () => reject(new Error('stream destroyed')));
883            this.on('error', er => reject(er));
884            this.on('end', () => resolve());
885        });
886    }
887    /**
888     * Asynchronous `for await of` iteration.
889     *
890     * This will continue emitting all chunks until the stream terminates.
891     */
892    [Symbol.asyncIterator]() {
893        // set this up front, in case the consumer doesn't call next()
894        // right away.
895        this[DISCARDED] = false;
896        let stopped = false;
897        const stop = async () => {
898            this.pause();
899            stopped = true;
900            return { value: undefined, done: true };
901        };
902        const next = () => {
903            if (stopped)
904                return stop();
905            const res = this.read();
906            if (res !== null)
907                return Promise.resolve({ done: false, value: res });
908            if (this[EOF])
909                return stop();
910            let resolve;
911            let reject;
912            const onerr = (er) => {
913                this.off('data', ondata);
914                this.off('end', onend);
915                this.off(DESTROYED, ondestroy);
916                stop();
917                reject(er);
918            };
919            const ondata = (value) => {
920                this.off('error', onerr);
921                this.off('end', onend);
922                this.off(DESTROYED, ondestroy);
923                this.pause();
924                resolve({ value, done: !!this[EOF] });
925            };
926            const onend = () => {
927                this.off('error', onerr);
928                this.off('data', ondata);
929                this.off(DESTROYED, ondestroy);
930                stop();
931                resolve({ done: true, value: undefined });
932            };
933            const ondestroy = () => onerr(new Error('stream destroyed'));
934            return new Promise((res, rej) => {
935                reject = rej;
936                resolve = res;
937                this.once(DESTROYED, ondestroy);
938                this.once('error', onerr);
939                this.once('end', onend);
940                this.once('data', ondata);
941            });
942        };
943        return {
944            next,
945            throw: stop,
946            return: stop,
947            [Symbol.asyncIterator]() {
948                return this;
949            },
950            [Symbol.asyncDispose]: async () => { },
951        };
952    }
953    /**
954     * Synchronous `for of` iteration.
955     *
956     * The iteration will terminate when the internal buffer runs out, even
957     * if the stream has not yet terminated.
958     */
959    [Symbol.iterator]() {
960        // set this up front, in case the consumer doesn't call next()
961        // right away.
962        this[DISCARDED] = false;
963        let stopped = false;
964        const stop = () => {
965            this.pause();
966            this.off(ERROR, stop);
967            this.off(DESTROYED, stop);
968            this.off('end', stop);
969            stopped = true;
970            return { done: true, value: undefined };
971        };
972        const next = () => {
973            if (stopped)
974                return stop();
975            const value = this.read();
976            return value === null ? stop() : { done: false, value };
977        };
978        this.once('end', stop);
979        this.once(ERROR, stop);
980        this.once(DESTROYED, stop);
981        return {
982            next,
983            throw: stop,
984            return: stop,
985            [Symbol.iterator]() {
986                return this;
987            },
988            [Symbol.dispose]: () => { },
989        };
990    }
991    /**
992     * Destroy a stream, preventing it from being used for any further purpose.
993     *
994     * If the stream has a `close()` method, then it will be called on
995     * destruction.
996     *
997     * After destruction, any attempt to write data, read data, or emit most
998     * events will be ignored.
999     *
1000     * If an error argument is provided, then it will be emitted in an
1001     * 'error' event.
1002     */
1003    destroy(er) {
1004        if (this[DESTROYED]) {
1005            if (er)
1006                this.emit('error', er);
1007            else
1008                this.emit(DESTROYED);
1009            return this;
1010        }
1011        this[DESTROYED] = true;
1012        this[DISCARDED] = true;
1013        // throw away all buffered data, it's never coming out
1014        this[BUFFER].length = 0;
1015        this[BUFFERLENGTH] = 0;
1016        const wc = this;
1017        if (typeof wc.close === 'function' && !this[CLOSED])
1018            wc.close();
1019        if (er)
1020            this.emit('error', er);
1021        // if no error to emit, still reject pending promises
1022        else
1023            this.emit(DESTROYED);
1024        return this;
1025    }
1026    /**
1027     * Alias for {@link isStream}
1028     *
1029     * Former export location, maintained for backwards compatibility.
1030     *
1031     * @deprecated
1032     */
1033    static get isStream() {
1034        return exports.isStream;
1035    }
1036}
1037exports.Minipass = Minipass;
1038//# sourceMappingURL=index.js.map
codekingpro/portable-devtools · Team Ai