index.js 33 KB

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