@0xbow/privacy-pools-core-sdk 1.0.4 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/esm/{fetchArtifacts.esm-C_DNv-_D.js → fetchArtifacts.esm-DbVRphob.js} +2 -2
  2. package/dist/esm/{fetchArtifacts.esm-C_DNv-_D.js.map → fetchArtifacts.esm-DbVRphob.js.map} +1 -1
  3. package/dist/esm/{fetchArtifacts.node-BBPNjgiT.js → fetchArtifacts.node-D-fJGtzV.js} +2 -2
  4. package/dist/esm/{fetchArtifacts.node-BBPNjgiT.js.map → fetchArtifacts.node-D-fJGtzV.js.map} +1 -1
  5. package/dist/esm/{index-BxzIe_IR.js → index-DkNRxKxP.js} +2889 -109
  6. package/dist/esm/index-DkNRxKxP.js.map +1 -0
  7. package/dist/esm/index.mjs +1 -1
  8. package/dist/index.d.mts +87 -14
  9. package/dist/node/{fetchArtifacts.esm-l-EDo53-.js → fetchArtifacts.esm-BIT-b_1_.js} +2 -2
  10. package/dist/node/{fetchArtifacts.esm-l-EDo53-.js.map → fetchArtifacts.esm-BIT-b_1_.js.map} +1 -1
  11. package/dist/node/{fetchArtifacts.node-DYwQHSF4.js → fetchArtifacts.node-CKwwU50E.js} +2 -2
  12. package/dist/node/{fetchArtifacts.node-DYwQHSF4.js.map → fetchArtifacts.node-CKwwU50E.js.map} +1 -1
  13. package/dist/node/{index-DGsIfUGw.js → index-C3RV9Cri.js} +2889 -109
  14. package/dist/node/index-C3RV9Cri.js.map +1 -0
  15. package/dist/node/index.mjs +1 -1
  16. package/dist/types/core/account.service.d.ts +8 -6
  17. package/dist/types/core/data.service.d.ts +28 -8
  18. package/dist/types/{fetchArtifacts.esm-IMTIZwq7.js → fetchArtifacts.esm-DT5RuODl.js} +1 -1
  19. package/dist/types/{fetchArtifacts.node-BcXsBNCT.js → fetchArtifacts.node-D_iVIPqW.js} +1 -1
  20. package/dist/types/{index-DbuAhDci.js → index-CHy3YamH.js} +2888 -108
  21. package/dist/types/index.js +1 -1
  22. package/dist/types/types/index.d.ts +1 -0
  23. package/dist/types/types/rateLimit.d.ts +51 -0
  24. package/package.json +4 -2
  25. package/src/core/account.service.ts +52 -39
  26. package/src/core/data.service.ts +325 -95
  27. package/src/types/index.ts +1 -0
  28. package/src/types/rateLimit.ts +66 -0
  29. package/dist/esm/index-BxzIe_IR.js.map +0 -1
  30. package/dist/node/index-DGsIfUGw.js.map +0 -1
  31. package/dist/types/utils/concurrency.d.ts +0 -15
  32. package/src/utils/concurrency.ts +0 -32
@@ -21,6 +21,18 @@ import { O_TRUNC, O_CREAT, O_RDWR, O_RDONLY } from 'constants';
21
21
  import 'readline';
22
22
  import require$$1$3 from 'path';
23
23
 
24
+ /**
25
+ * Default log fetch configuration
26
+ */
27
+ const DEFAULT_LOG_FETCH_CONFIG = {
28
+ blockChunkSize: 10000,
29
+ concurrency: 3,
30
+ chunkDelayMs: 0,
31
+ retryOnFailure: true,
32
+ maxRetries: 3,
33
+ retryBaseDelayMs: 1000,
34
+ };
35
+
24
36
  const version$1 = '2.22.14';
25
37
 
26
38
  let errorConfig = {
@@ -51070,10 +51082,10 @@ const circuitToAsset = {
51070
51082
 
51071
51083
  async function importFetchVersionedArtifact(isBrowser) {
51072
51084
  if (isBrowser) {
51073
- return import('./fetchArtifacts.esm-IMTIZwq7.js');
51085
+ return import('./fetchArtifacts.esm-DT5RuODl.js');
51074
51086
  }
51075
51087
  else {
51076
- return import('./fetchArtifacts.node-BcXsBNCT.js');
51088
+ return import('./fetchArtifacts.node-D_iVIPqW.js');
51077
51089
  }
51078
51090
  }
51079
51091
 
@@ -76344,6 +76356,2675 @@ class AccountError extends SDKError {
76344
76356
  }
76345
76357
  }
76346
76358
 
76359
+ /**
76360
+ * Creates a continuation function with some arguments already applied.
76361
+ *
76362
+ * Useful as a shorthand when combined with other control flow functions. Any
76363
+ * arguments passed to the returned function are added to the arguments
76364
+ * originally passed to apply.
76365
+ *
76366
+ * @name apply
76367
+ * @static
76368
+ * @memberOf module:Utils
76369
+ * @method
76370
+ * @category Util
76371
+ * @param {Function} fn - The function you want to eventually apply all
76372
+ * arguments to. Invokes with (arguments...).
76373
+ * @param {...*} arguments... - Any number of arguments to automatically apply
76374
+ * when the continuation is called.
76375
+ * @returns {Function} the partially-applied function
76376
+ * @example
76377
+ *
76378
+ * // using apply
76379
+ * async.parallel([
76380
+ * async.apply(fs.writeFile, 'testfile1', 'test1'),
76381
+ * async.apply(fs.writeFile, 'testfile2', 'test2')
76382
+ * ]);
76383
+ *
76384
+ *
76385
+ * // the same process without using apply
76386
+ * async.parallel([
76387
+ * function(callback) {
76388
+ * fs.writeFile('testfile1', 'test1', callback);
76389
+ * },
76390
+ * function(callback) {
76391
+ * fs.writeFile('testfile2', 'test2', callback);
76392
+ * }
76393
+ * ]);
76394
+ *
76395
+ * // It's possible to pass any number of additional arguments when calling the
76396
+ * // continuation:
76397
+ *
76398
+ * node> var fn = async.apply(sys.puts, 'one');
76399
+ * node> fn('two', 'three');
76400
+ * one
76401
+ * two
76402
+ * three
76403
+ */
76404
+
76405
+ function initialParams (fn) {
76406
+ return function (...args/*, callback*/) {
76407
+ var callback = args.pop();
76408
+ return fn.call(this, args, callback);
76409
+ };
76410
+ }
76411
+
76412
+ /* istanbul ignore file */
76413
+
76414
+ var hasQueueMicrotask = typeof queueMicrotask === 'function' && queueMicrotask;
76415
+ var hasSetImmediate = typeof setImmediate === 'function' && setImmediate;
76416
+ var hasNextTick = typeof process === 'object' && typeof process.nextTick === 'function';
76417
+
76418
+ function fallback(fn) {
76419
+ setTimeout(fn, 0);
76420
+ }
76421
+
76422
+ function wrap(defer) {
76423
+ return (fn, ...args) => defer(() => fn(...args));
76424
+ }
76425
+
76426
+ var _defer$1;
76427
+
76428
+ if (hasQueueMicrotask) {
76429
+ _defer$1 = queueMicrotask;
76430
+ } else if (hasSetImmediate) {
76431
+ _defer$1 = setImmediate;
76432
+ } else if (hasNextTick) {
76433
+ _defer$1 = process.nextTick;
76434
+ } else {
76435
+ _defer$1 = fallback;
76436
+ }
76437
+
76438
+ var setImmediate$1 = wrap(_defer$1);
76439
+
76440
+ /**
76441
+ * Take a sync function and make it async, passing its return value to a
76442
+ * callback. This is useful for plugging sync functions into a waterfall,
76443
+ * series, or other async functions. Any arguments passed to the generated
76444
+ * function will be passed to the wrapped function (except for the final
76445
+ * callback argument). Errors thrown will be passed to the callback.
76446
+ *
76447
+ * If the function passed to `asyncify` returns a Promise, that promises's
76448
+ * resolved/rejected state will be used to call the callback, rather than simply
76449
+ * the synchronous return value.
76450
+ *
76451
+ * This also means you can asyncify ES2017 `async` functions.
76452
+ *
76453
+ * @name asyncify
76454
+ * @static
76455
+ * @memberOf module:Utils
76456
+ * @method
76457
+ * @alias wrapSync
76458
+ * @category Util
76459
+ * @param {Function} func - The synchronous function, or Promise-returning
76460
+ * function to convert to an {@link AsyncFunction}.
76461
+ * @returns {AsyncFunction} An asynchronous wrapper of the `func`. To be
76462
+ * invoked with `(args..., callback)`.
76463
+ * @example
76464
+ *
76465
+ * // passing a regular synchronous function
76466
+ * async.waterfall([
76467
+ * async.apply(fs.readFile, filename, "utf8"),
76468
+ * async.asyncify(JSON.parse),
76469
+ * function (data, next) {
76470
+ * // data is the result of parsing the text.
76471
+ * // If there was a parsing error, it would have been caught.
76472
+ * }
76473
+ * ], callback);
76474
+ *
76475
+ * // passing a function returning a promise
76476
+ * async.waterfall([
76477
+ * async.apply(fs.readFile, filename, "utf8"),
76478
+ * async.asyncify(function (contents) {
76479
+ * return db.model.create(contents);
76480
+ * }),
76481
+ * function (model, next) {
76482
+ * // `model` is the instantiated model object.
76483
+ * // If there was an error, this function would be skipped.
76484
+ * }
76485
+ * ], callback);
76486
+ *
76487
+ * // es2017 example, though `asyncify` is not needed if your JS environment
76488
+ * // supports async functions out of the box
76489
+ * var q = async.queue(async.asyncify(async function(file) {
76490
+ * var intermediateStep = await processFile(file);
76491
+ * return await somePromise(intermediateStep)
76492
+ * }));
76493
+ *
76494
+ * q.push(files);
76495
+ */
76496
+ function asyncify(func) {
76497
+ if (isAsync(func)) {
76498
+ return function (...args/*, callback*/) {
76499
+ const callback = args.pop();
76500
+ const promise = func.apply(this, args);
76501
+ return handlePromise(promise, callback)
76502
+ }
76503
+ }
76504
+
76505
+ return initialParams(function (args, callback) {
76506
+ var result;
76507
+ try {
76508
+ result = func.apply(this, args);
76509
+ } catch (e) {
76510
+ return callback(e);
76511
+ }
76512
+ // if result is Promise object
76513
+ if (result && typeof result.then === 'function') {
76514
+ return handlePromise(result, callback)
76515
+ } else {
76516
+ callback(null, result);
76517
+ }
76518
+ });
76519
+ }
76520
+
76521
+ function handlePromise(promise, callback) {
76522
+ return promise.then(value => {
76523
+ invokeCallback(callback, null, value);
76524
+ }, err => {
76525
+ invokeCallback(callback, err && (err instanceof Error || err.message) ? err : new Error(err));
76526
+ });
76527
+ }
76528
+
76529
+ function invokeCallback(callback, error, value) {
76530
+ try {
76531
+ callback(error, value);
76532
+ } catch (err) {
76533
+ setImmediate$1(e => { throw e }, err);
76534
+ }
76535
+ }
76536
+
76537
+ function isAsync(fn) {
76538
+ return fn[Symbol.toStringTag] === 'AsyncFunction';
76539
+ }
76540
+
76541
+ function isAsyncGenerator(fn) {
76542
+ return fn[Symbol.toStringTag] === 'AsyncGenerator';
76543
+ }
76544
+
76545
+ function isAsyncIterable(obj) {
76546
+ return typeof obj[Symbol.asyncIterator] === 'function';
76547
+ }
76548
+
76549
+ function wrapAsync(asyncFn) {
76550
+ if (typeof asyncFn !== 'function') throw new Error('expected a function')
76551
+ return isAsync(asyncFn) ? asyncify(asyncFn) : asyncFn;
76552
+ }
76553
+
76554
+ // conditionally promisify a function.
76555
+ // only return a promise if a callback is omitted
76556
+ function awaitify (asyncFn, arity) {
76557
+ if (!arity) arity = asyncFn.length;
76558
+ if (!arity) throw new Error('arity is undefined')
76559
+ function awaitable (...args) {
76560
+ if (typeof args[arity - 1] === 'function') {
76561
+ return asyncFn.apply(this, args)
76562
+ }
76563
+
76564
+ return new Promise((resolve, reject) => {
76565
+ args[arity - 1] = (err, ...cbArgs) => {
76566
+ if (err) return reject(err)
76567
+ resolve(cbArgs.length > 1 ? cbArgs : cbArgs[0]);
76568
+ };
76569
+ asyncFn.apply(this, args);
76570
+ })
76571
+ }
76572
+
76573
+ return awaitable
76574
+ }
76575
+
76576
+ function _asyncMap(eachfn, arr, iteratee, callback) {
76577
+ arr = arr || [];
76578
+ var results = [];
76579
+ var counter = 0;
76580
+ var _iteratee = wrapAsync(iteratee);
76581
+
76582
+ return eachfn(arr, (value, _, iterCb) => {
76583
+ var index = counter++;
76584
+ _iteratee(value, (err, v) => {
76585
+ results[index] = v;
76586
+ iterCb(err);
76587
+ });
76588
+ }, err => {
76589
+ callback(err, results);
76590
+ });
76591
+ }
76592
+
76593
+ function isArrayLike(value) {
76594
+ return value &&
76595
+ typeof value.length === 'number' &&
76596
+ value.length >= 0 &&
76597
+ value.length % 1 === 0;
76598
+ }
76599
+
76600
+ // A temporary value used to identify if the loop should be broken.
76601
+ // See #1064, #1293
76602
+ const breakLoop = {};
76603
+
76604
+ function once(fn) {
76605
+ function wrapper (...args) {
76606
+ if (fn === null) return;
76607
+ var callFn = fn;
76608
+ fn = null;
76609
+ callFn.apply(this, args);
76610
+ }
76611
+ Object.assign(wrapper, fn);
76612
+ return wrapper
76613
+ }
76614
+
76615
+ function getIterator (coll) {
76616
+ return coll[Symbol.iterator] && coll[Symbol.iterator]();
76617
+ }
76618
+
76619
+ function createArrayIterator(coll) {
76620
+ var i = -1;
76621
+ var len = coll.length;
76622
+ return function next() {
76623
+ return ++i < len ? {value: coll[i], key: i} : null;
76624
+ }
76625
+ }
76626
+
76627
+ function createES2015Iterator(iterator) {
76628
+ var i = -1;
76629
+ return function next() {
76630
+ var item = iterator.next();
76631
+ if (item.done)
76632
+ return null;
76633
+ i++;
76634
+ return {value: item.value, key: i};
76635
+ }
76636
+ }
76637
+
76638
+ function createObjectIterator(obj) {
76639
+ var okeys = obj ? Object.keys(obj) : [];
76640
+ var i = -1;
76641
+ var len = okeys.length;
76642
+ return function next() {
76643
+ var key = okeys[++i];
76644
+ if (key === '__proto__') {
76645
+ return next();
76646
+ }
76647
+ return i < len ? {value: obj[key], key} : null;
76648
+ };
76649
+ }
76650
+
76651
+ function createIterator(coll) {
76652
+ if (isArrayLike(coll)) {
76653
+ return createArrayIterator(coll);
76654
+ }
76655
+
76656
+ var iterator = getIterator(coll);
76657
+ return iterator ? createES2015Iterator(iterator) : createObjectIterator(coll);
76658
+ }
76659
+
76660
+ function onlyOnce(fn) {
76661
+ return function (...args) {
76662
+ if (fn === null) throw new Error("Callback was already called.");
76663
+ var callFn = fn;
76664
+ fn = null;
76665
+ callFn.apply(this, args);
76666
+ };
76667
+ }
76668
+
76669
+ // for async generators
76670
+ function asyncEachOfLimit(generator, limit, iteratee, callback) {
76671
+ let done = false;
76672
+ let canceled = false;
76673
+ let awaiting = false;
76674
+ let running = 0;
76675
+ let idx = 0;
76676
+
76677
+ function replenish() {
76678
+ //console.log('replenish')
76679
+ if (running >= limit || awaiting || done) return
76680
+ //console.log('replenish awaiting')
76681
+ awaiting = true;
76682
+ generator.next().then(({value, done: iterDone}) => {
76683
+ //console.log('got value', value)
76684
+ if (canceled || done) return
76685
+ awaiting = false;
76686
+ if (iterDone) {
76687
+ done = true;
76688
+ if (running <= 0) {
76689
+ //console.log('done nextCb')
76690
+ callback(null);
76691
+ }
76692
+ return;
76693
+ }
76694
+ running++;
76695
+ iteratee(value, idx, iterateeCallback);
76696
+ idx++;
76697
+ replenish();
76698
+ }).catch(handleError);
76699
+ }
76700
+
76701
+ function iterateeCallback(err, result) {
76702
+ //console.log('iterateeCallback')
76703
+ running -= 1;
76704
+ if (canceled) return
76705
+ if (err) return handleError(err)
76706
+
76707
+ if (err === false) {
76708
+ done = true;
76709
+ canceled = true;
76710
+ return
76711
+ }
76712
+
76713
+ if (result === breakLoop || (done && running <= 0)) {
76714
+ done = true;
76715
+ //console.log('done iterCb')
76716
+ return callback(null);
76717
+ }
76718
+ replenish();
76719
+ }
76720
+
76721
+ function handleError(err) {
76722
+ if (canceled) return
76723
+ awaiting = false;
76724
+ done = true;
76725
+ callback(err);
76726
+ }
76727
+
76728
+ replenish();
76729
+ }
76730
+
76731
+ var eachOfLimit$2 = (limit) => {
76732
+ return (obj, iteratee, callback) => {
76733
+ callback = once(callback);
76734
+ if (limit <= 0) {
76735
+ throw new RangeError('concurrency limit cannot be less than 1')
76736
+ }
76737
+ if (!obj) {
76738
+ return callback(null);
76739
+ }
76740
+ if (isAsyncGenerator(obj)) {
76741
+ return asyncEachOfLimit(obj, limit, iteratee, callback)
76742
+ }
76743
+ if (isAsyncIterable(obj)) {
76744
+ return asyncEachOfLimit(obj[Symbol.asyncIterator](), limit, iteratee, callback)
76745
+ }
76746
+ var nextElem = createIterator(obj);
76747
+ var done = false;
76748
+ var canceled = false;
76749
+ var running = 0;
76750
+ var looping = false;
76751
+
76752
+ function iterateeCallback(err, value) {
76753
+ if (canceled) return
76754
+ running -= 1;
76755
+ if (err) {
76756
+ done = true;
76757
+ callback(err);
76758
+ }
76759
+ else if (err === false) {
76760
+ done = true;
76761
+ canceled = true;
76762
+ }
76763
+ else if (value === breakLoop || (done && running <= 0)) {
76764
+ done = true;
76765
+ return callback(null);
76766
+ }
76767
+ else if (!looping) {
76768
+ replenish();
76769
+ }
76770
+ }
76771
+
76772
+ function replenish () {
76773
+ looping = true;
76774
+ while (running < limit && !done) {
76775
+ var elem = nextElem();
76776
+ if (elem === null) {
76777
+ done = true;
76778
+ if (running <= 0) {
76779
+ callback(null);
76780
+ }
76781
+ return;
76782
+ }
76783
+ running += 1;
76784
+ iteratee(elem.value, elem.key, onlyOnce(iterateeCallback));
76785
+ }
76786
+ looping = false;
76787
+ }
76788
+
76789
+ replenish();
76790
+ };
76791
+ };
76792
+
76793
+ /**
76794
+ * The same as [`eachOf`]{@link module:Collections.eachOf} but runs a maximum of `limit` async operations at a
76795
+ * time.
76796
+ *
76797
+ * @name eachOfLimit
76798
+ * @static
76799
+ * @memberOf module:Collections
76800
+ * @method
76801
+ * @see [async.eachOf]{@link module:Collections.eachOf}
76802
+ * @alias forEachOfLimit
76803
+ * @category Collection
76804
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
76805
+ * @param {number} limit - The maximum number of async operations at a time.
76806
+ * @param {AsyncFunction} iteratee - An async function to apply to each
76807
+ * item in `coll`. The `key` is the item's key, or index in the case of an
76808
+ * array.
76809
+ * Invoked with (item, key, callback).
76810
+ * @param {Function} [callback] - A callback which is called when all
76811
+ * `iteratee` functions have finished, or an error occurs. Invoked with (err).
76812
+ * @returns {Promise} a promise, if a callback is omitted
76813
+ */
76814
+ function eachOfLimit(coll, limit, iteratee, callback) {
76815
+ return eachOfLimit$2(limit)(coll, wrapAsync(iteratee), callback);
76816
+ }
76817
+
76818
+ var eachOfLimit$1 = awaitify(eachOfLimit, 4);
76819
+
76820
+ // eachOf implementation optimized for array-likes
76821
+ function eachOfArrayLike(coll, iteratee, callback) {
76822
+ callback = once(callback);
76823
+ var index = 0,
76824
+ completed = 0,
76825
+ {length} = coll,
76826
+ canceled = false;
76827
+ if (length === 0) {
76828
+ callback(null);
76829
+ }
76830
+
76831
+ function iteratorCallback(err, value) {
76832
+ if (err === false) {
76833
+ canceled = true;
76834
+ }
76835
+ if (canceled === true) return
76836
+ if (err) {
76837
+ callback(err);
76838
+ } else if ((++completed === length) || value === breakLoop) {
76839
+ callback(null);
76840
+ }
76841
+ }
76842
+
76843
+ for (; index < length; index++) {
76844
+ iteratee(coll[index], index, onlyOnce(iteratorCallback));
76845
+ }
76846
+ }
76847
+
76848
+ // a generic version of eachOf which can handle array, object, and iterator cases.
76849
+ function eachOfGeneric (coll, iteratee, callback) {
76850
+ return eachOfLimit$1(coll, Infinity, iteratee, callback);
76851
+ }
76852
+
76853
+ /**
76854
+ * Like [`each`]{@link module:Collections.each}, except that it passes the key (or index) as the second argument
76855
+ * to the iteratee.
76856
+ *
76857
+ * @name eachOf
76858
+ * @static
76859
+ * @memberOf module:Collections
76860
+ * @method
76861
+ * @alias forEachOf
76862
+ * @category Collection
76863
+ * @see [async.each]{@link module:Collections.each}
76864
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
76865
+ * @param {AsyncFunction} iteratee - A function to apply to each
76866
+ * item in `coll`.
76867
+ * The `key` is the item's key, or index in the case of an array.
76868
+ * Invoked with (item, key, callback).
76869
+ * @param {Function} [callback] - A callback which is called when all
76870
+ * `iteratee` functions have finished, or an error occurs. Invoked with (err).
76871
+ * @returns {Promise} a promise, if a callback is omitted
76872
+ * @example
76873
+ *
76874
+ * // dev.json is a file containing a valid json object config for dev environment
76875
+ * // dev.json is a file containing a valid json object config for test environment
76876
+ * // prod.json is a file containing a valid json object config for prod environment
76877
+ * // invalid.json is a file with a malformed json object
76878
+ *
76879
+ * let configs = {}; //global variable
76880
+ * let validConfigFileMap = {dev: 'dev.json', test: 'test.json', prod: 'prod.json'};
76881
+ * let invalidConfigFileMap = {dev: 'dev.json', test: 'test.json', invalid: 'invalid.json'};
76882
+ *
76883
+ * // asynchronous function that reads a json file and parses the contents as json object
76884
+ * function parseFile(file, key, callback) {
76885
+ * fs.readFile(file, "utf8", function(err, data) {
76886
+ * if (err) return calback(err);
76887
+ * try {
76888
+ * configs[key] = JSON.parse(data);
76889
+ * } catch (e) {
76890
+ * return callback(e);
76891
+ * }
76892
+ * callback();
76893
+ * });
76894
+ * }
76895
+ *
76896
+ * // Using callbacks
76897
+ * async.forEachOf(validConfigFileMap, parseFile, function (err) {
76898
+ * if (err) {
76899
+ * console.error(err);
76900
+ * } else {
76901
+ * console.log(configs);
76902
+ * // configs is now a map of JSON data, e.g.
76903
+ * // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json}
76904
+ * }
76905
+ * });
76906
+ *
76907
+ * //Error handing
76908
+ * async.forEachOf(invalidConfigFileMap, parseFile, function (err) {
76909
+ * if (err) {
76910
+ * console.error(err);
76911
+ * // JSON parse error exception
76912
+ * } else {
76913
+ * console.log(configs);
76914
+ * }
76915
+ * });
76916
+ *
76917
+ * // Using Promises
76918
+ * async.forEachOf(validConfigFileMap, parseFile)
76919
+ * .then( () => {
76920
+ * console.log(configs);
76921
+ * // configs is now a map of JSON data, e.g.
76922
+ * // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json}
76923
+ * }).catch( err => {
76924
+ * console.error(err);
76925
+ * });
76926
+ *
76927
+ * //Error handing
76928
+ * async.forEachOf(invalidConfigFileMap, parseFile)
76929
+ * .then( () => {
76930
+ * console.log(configs);
76931
+ * }).catch( err => {
76932
+ * console.error(err);
76933
+ * // JSON parse error exception
76934
+ * });
76935
+ *
76936
+ * // Using async/await
76937
+ * async () => {
76938
+ * try {
76939
+ * let result = await async.forEachOf(validConfigFileMap, parseFile);
76940
+ * console.log(configs);
76941
+ * // configs is now a map of JSON data, e.g.
76942
+ * // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json}
76943
+ * }
76944
+ * catch (err) {
76945
+ * console.log(err);
76946
+ * }
76947
+ * }
76948
+ *
76949
+ * //Error handing
76950
+ * async () => {
76951
+ * try {
76952
+ * let result = await async.forEachOf(invalidConfigFileMap, parseFile);
76953
+ * console.log(configs);
76954
+ * }
76955
+ * catch (err) {
76956
+ * console.log(err);
76957
+ * // JSON parse error exception
76958
+ * }
76959
+ * }
76960
+ *
76961
+ */
76962
+ function eachOf(coll, iteratee, callback) {
76963
+ var eachOfImplementation = isArrayLike(coll) ? eachOfArrayLike : eachOfGeneric;
76964
+ return eachOfImplementation(coll, wrapAsync(iteratee), callback);
76965
+ }
76966
+
76967
+ var eachOf$1 = awaitify(eachOf, 3);
76968
+
76969
+ /**
76970
+ * Produces a new collection of values by mapping each value in `coll` through
76971
+ * the `iteratee` function. The `iteratee` is called with an item from `coll`
76972
+ * and a callback for when it has finished processing. Each of these callbacks
76973
+ * takes 2 arguments: an `error`, and the transformed item from `coll`. If
76974
+ * `iteratee` passes an error to its callback, the main `callback` (for the
76975
+ * `map` function) is immediately called with the error.
76976
+ *
76977
+ * Note, that since this function applies the `iteratee` to each item in
76978
+ * parallel, there is no guarantee that the `iteratee` functions will complete
76979
+ * in order. However, the results array will be in the same order as the
76980
+ * original `coll`.
76981
+ *
76982
+ * If `map` is passed an Object, the results will be an Array. The results
76983
+ * will roughly be in the order of the original Objects' keys (but this can
76984
+ * vary across JavaScript engines).
76985
+ *
76986
+ * @name map
76987
+ * @static
76988
+ * @memberOf module:Collections
76989
+ * @method
76990
+ * @category Collection
76991
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
76992
+ * @param {AsyncFunction} iteratee - An async function to apply to each item in
76993
+ * `coll`.
76994
+ * The iteratee should complete with the transformed item.
76995
+ * Invoked with (item, callback).
76996
+ * @param {Function} [callback] - A callback which is called when all `iteratee`
76997
+ * functions have finished, or an error occurs. Results is an Array of the
76998
+ * transformed items from the `coll`. Invoked with (err, results).
76999
+ * @returns {Promise} a promise, if no callback is passed
77000
+ * @example
77001
+ *
77002
+ * // file1.txt is a file that is 1000 bytes in size
77003
+ * // file2.txt is a file that is 2000 bytes in size
77004
+ * // file3.txt is a file that is 3000 bytes in size
77005
+ * // file4.txt does not exist
77006
+ *
77007
+ * const fileList = ['file1.txt','file2.txt','file3.txt'];
77008
+ * const withMissingFileList = ['file1.txt','file2.txt','file4.txt'];
77009
+ *
77010
+ * // asynchronous function that returns the file size in bytes
77011
+ * function getFileSizeInBytes(file, callback) {
77012
+ * fs.stat(file, function(err, stat) {
77013
+ * if (err) {
77014
+ * return callback(err);
77015
+ * }
77016
+ * callback(null, stat.size);
77017
+ * });
77018
+ * }
77019
+ *
77020
+ * // Using callbacks
77021
+ * async.map(fileList, getFileSizeInBytes, function(err, results) {
77022
+ * if (err) {
77023
+ * console.log(err);
77024
+ * } else {
77025
+ * console.log(results);
77026
+ * // results is now an array of the file size in bytes for each file, e.g.
77027
+ * // [ 1000, 2000, 3000]
77028
+ * }
77029
+ * });
77030
+ *
77031
+ * // Error Handling
77032
+ * async.map(withMissingFileList, getFileSizeInBytes, function(err, results) {
77033
+ * if (err) {
77034
+ * console.log(err);
77035
+ * // [ Error: ENOENT: no such file or directory ]
77036
+ * } else {
77037
+ * console.log(results);
77038
+ * }
77039
+ * });
77040
+ *
77041
+ * // Using Promises
77042
+ * async.map(fileList, getFileSizeInBytes)
77043
+ * .then( results => {
77044
+ * console.log(results);
77045
+ * // results is now an array of the file size in bytes for each file, e.g.
77046
+ * // [ 1000, 2000, 3000]
77047
+ * }).catch( err => {
77048
+ * console.log(err);
77049
+ * });
77050
+ *
77051
+ * // Error Handling
77052
+ * async.map(withMissingFileList, getFileSizeInBytes)
77053
+ * .then( results => {
77054
+ * console.log(results);
77055
+ * }).catch( err => {
77056
+ * console.log(err);
77057
+ * // [ Error: ENOENT: no such file or directory ]
77058
+ * });
77059
+ *
77060
+ * // Using async/await
77061
+ * async () => {
77062
+ * try {
77063
+ * let results = await async.map(fileList, getFileSizeInBytes);
77064
+ * console.log(results);
77065
+ * // results is now an array of the file size in bytes for each file, e.g.
77066
+ * // [ 1000, 2000, 3000]
77067
+ * }
77068
+ * catch (err) {
77069
+ * console.log(err);
77070
+ * }
77071
+ * }
77072
+ *
77073
+ * // Error Handling
77074
+ * async () => {
77075
+ * try {
77076
+ * let results = await async.map(withMissingFileList, getFileSizeInBytes);
77077
+ * console.log(results);
77078
+ * }
77079
+ * catch (err) {
77080
+ * console.log(err);
77081
+ * // [ Error: ENOENT: no such file or directory ]
77082
+ * }
77083
+ * }
77084
+ *
77085
+ */
77086
+ function map (coll, iteratee, callback) {
77087
+ return _asyncMap(eachOf$1, coll, iteratee, callback)
77088
+ }
77089
+ var map$1 = awaitify(map, 3);
77090
+
77091
+ /**
77092
+ * The same as [`eachOf`]{@link module:Collections.eachOf} but runs only a single async operation at a time.
77093
+ *
77094
+ * @name eachOfSeries
77095
+ * @static
77096
+ * @memberOf module:Collections
77097
+ * @method
77098
+ * @see [async.eachOf]{@link module:Collections.eachOf}
77099
+ * @alias forEachOfSeries
77100
+ * @category Collection
77101
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
77102
+ * @param {AsyncFunction} iteratee - An async function to apply to each item in
77103
+ * `coll`.
77104
+ * Invoked with (item, key, callback).
77105
+ * @param {Function} [callback] - A callback which is called when all `iteratee`
77106
+ * functions have finished, or an error occurs. Invoked with (err).
77107
+ * @returns {Promise} a promise, if a callback is omitted
77108
+ */
77109
+ function eachOfSeries(coll, iteratee, callback) {
77110
+ return eachOfLimit$1(coll, 1, iteratee, callback)
77111
+ }
77112
+ var eachOfSeries$1 = awaitify(eachOfSeries, 3);
77113
+
77114
+ /**
77115
+ * The same as [`map`]{@link module:Collections.map} but runs only a single async operation at a time.
77116
+ *
77117
+ * @name mapSeries
77118
+ * @static
77119
+ * @memberOf module:Collections
77120
+ * @method
77121
+ * @see [async.map]{@link module:Collections.map}
77122
+ * @category Collection
77123
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
77124
+ * @param {AsyncFunction} iteratee - An async function to apply to each item in
77125
+ * `coll`.
77126
+ * The iteratee should complete with the transformed item.
77127
+ * Invoked with (item, callback).
77128
+ * @param {Function} [callback] - A callback which is called when all `iteratee`
77129
+ * functions have finished, or an error occurs. Results is an array of the
77130
+ * transformed items from the `coll`. Invoked with (err, results).
77131
+ * @returns {Promise} a promise, if no callback is passed
77132
+ */
77133
+ function mapSeries (coll, iteratee, callback) {
77134
+ return _asyncMap(eachOfSeries$1, coll, iteratee, callback)
77135
+ }
77136
+ awaitify(mapSeries, 3);
77137
+
77138
+ /**
77139
+ * Reduces `coll` into a single value using an async `iteratee` to return each
77140
+ * successive step. `memo` is the initial state of the reduction. This function
77141
+ * only operates in series.
77142
+ *
77143
+ * For performance reasons, it may make sense to split a call to this function
77144
+ * into a parallel map, and then use the normal `Array.prototype.reduce` on the
77145
+ * results. This function is for situations where each step in the reduction
77146
+ * needs to be async; if you can get the data before reducing it, then it's
77147
+ * probably a good idea to do so.
77148
+ *
77149
+ * @name reduce
77150
+ * @static
77151
+ * @memberOf module:Collections
77152
+ * @method
77153
+ * @alias inject
77154
+ * @alias foldl
77155
+ * @category Collection
77156
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
77157
+ * @param {*} memo - The initial state of the reduction.
77158
+ * @param {AsyncFunction} iteratee - A function applied to each item in the
77159
+ * array to produce the next step in the reduction.
77160
+ * The `iteratee` should complete with the next state of the reduction.
77161
+ * If the iteratee completes with an error, the reduction is stopped and the
77162
+ * main `callback` is immediately called with the error.
77163
+ * Invoked with (memo, item, callback).
77164
+ * @param {Function} [callback] - A callback which is called after all the
77165
+ * `iteratee` functions have finished. Result is the reduced value. Invoked with
77166
+ * (err, result).
77167
+ * @returns {Promise} a promise, if no callback is passed
77168
+ * @example
77169
+ *
77170
+ * // file1.txt is a file that is 1000 bytes in size
77171
+ * // file2.txt is a file that is 2000 bytes in size
77172
+ * // file3.txt is a file that is 3000 bytes in size
77173
+ * // file4.txt does not exist
77174
+ *
77175
+ * const fileList = ['file1.txt','file2.txt','file3.txt'];
77176
+ * const withMissingFileList = ['file1.txt','file2.txt','file3.txt', 'file4.txt'];
77177
+ *
77178
+ * // asynchronous function that computes the file size in bytes
77179
+ * // file size is added to the memoized value, then returned
77180
+ * function getFileSizeInBytes(memo, file, callback) {
77181
+ * fs.stat(file, function(err, stat) {
77182
+ * if (err) {
77183
+ * return callback(err);
77184
+ * }
77185
+ * callback(null, memo + stat.size);
77186
+ * });
77187
+ * }
77188
+ *
77189
+ * // Using callbacks
77190
+ * async.reduce(fileList, 0, getFileSizeInBytes, function(err, result) {
77191
+ * if (err) {
77192
+ * console.log(err);
77193
+ * } else {
77194
+ * console.log(result);
77195
+ * // 6000
77196
+ * // which is the sum of the file sizes of the three files
77197
+ * }
77198
+ * });
77199
+ *
77200
+ * // Error Handling
77201
+ * async.reduce(withMissingFileList, 0, getFileSizeInBytes, function(err, result) {
77202
+ * if (err) {
77203
+ * console.log(err);
77204
+ * // [ Error: ENOENT: no such file or directory ]
77205
+ * } else {
77206
+ * console.log(result);
77207
+ * }
77208
+ * });
77209
+ *
77210
+ * // Using Promises
77211
+ * async.reduce(fileList, 0, getFileSizeInBytes)
77212
+ * .then( result => {
77213
+ * console.log(result);
77214
+ * // 6000
77215
+ * // which is the sum of the file sizes of the three files
77216
+ * }).catch( err => {
77217
+ * console.log(err);
77218
+ * });
77219
+ *
77220
+ * // Error Handling
77221
+ * async.reduce(withMissingFileList, 0, getFileSizeInBytes)
77222
+ * .then( result => {
77223
+ * console.log(result);
77224
+ * }).catch( err => {
77225
+ * console.log(err);
77226
+ * // [ Error: ENOENT: no such file or directory ]
77227
+ * });
77228
+ *
77229
+ * // Using async/await
77230
+ * async () => {
77231
+ * try {
77232
+ * let result = await async.reduce(fileList, 0, getFileSizeInBytes);
77233
+ * console.log(result);
77234
+ * // 6000
77235
+ * // which is the sum of the file sizes of the three files
77236
+ * }
77237
+ * catch (err) {
77238
+ * console.log(err);
77239
+ * }
77240
+ * }
77241
+ *
77242
+ * // Error Handling
77243
+ * async () => {
77244
+ * try {
77245
+ * let result = await async.reduce(withMissingFileList, 0, getFileSizeInBytes);
77246
+ * console.log(result);
77247
+ * }
77248
+ * catch (err) {
77249
+ * console.log(err);
77250
+ * // [ Error: ENOENT: no such file or directory ]
77251
+ * }
77252
+ * }
77253
+ *
77254
+ */
77255
+ function reduce(coll, memo, iteratee, callback) {
77256
+ callback = once(callback);
77257
+ var _iteratee = wrapAsync(iteratee);
77258
+ return eachOfSeries$1(coll, (x, i, iterCb) => {
77259
+ _iteratee(memo, x, (err, v) => {
77260
+ memo = v;
77261
+ iterCb(err);
77262
+ });
77263
+ }, err => callback(err, memo));
77264
+ }
77265
+ awaitify(reduce, 4);
77266
+
77267
+ /**
77268
+ * The same as [`map`]{@link module:Collections.map} but runs a maximum of `limit` async operations at a time.
77269
+ *
77270
+ * @name mapLimit
77271
+ * @static
77272
+ * @memberOf module:Collections
77273
+ * @method
77274
+ * @see [async.map]{@link module:Collections.map}
77275
+ * @category Collection
77276
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
77277
+ * @param {number} limit - The maximum number of async operations at a time.
77278
+ * @param {AsyncFunction} iteratee - An async function to apply to each item in
77279
+ * `coll`.
77280
+ * The iteratee should complete with the transformed item.
77281
+ * Invoked with (item, callback).
77282
+ * @param {Function} [callback] - A callback which is called when all `iteratee`
77283
+ * functions have finished, or an error occurs. Results is an array of the
77284
+ * transformed items from the `coll`. Invoked with (err, results).
77285
+ * @returns {Promise} a promise, if no callback is passed
77286
+ */
77287
+ function mapLimit (coll, limit, iteratee, callback) {
77288
+ return _asyncMap(eachOfLimit$2(limit), coll, iteratee, callback)
77289
+ }
77290
+ var mapLimit$1 = awaitify(mapLimit, 4);
77291
+
77292
+ /**
77293
+ * The same as [`concat`]{@link module:Collections.concat} but runs a maximum of `limit` async operations at a time.
77294
+ *
77295
+ * @name concatLimit
77296
+ * @static
77297
+ * @memberOf module:Collections
77298
+ * @method
77299
+ * @see [async.concat]{@link module:Collections.concat}
77300
+ * @category Collection
77301
+ * @alias flatMapLimit
77302
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
77303
+ * @param {number} limit - The maximum number of async operations at a time.
77304
+ * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`,
77305
+ * which should use an array as its result. Invoked with (item, callback).
77306
+ * @param {Function} [callback] - A callback which is called after all the
77307
+ * `iteratee` functions have finished, or an error occurs. Results is an array
77308
+ * containing the concatenated results of the `iteratee` function. Invoked with
77309
+ * (err, results).
77310
+ * @returns A Promise, if no callback is passed
77311
+ */
77312
+ function concatLimit(coll, limit, iteratee, callback) {
77313
+ var _iteratee = wrapAsync(iteratee);
77314
+ return mapLimit$1(coll, limit, (val, iterCb) => {
77315
+ _iteratee(val, (err, ...args) => {
77316
+ if (err) return iterCb(err);
77317
+ return iterCb(err, args);
77318
+ });
77319
+ }, (err, mapResults) => {
77320
+ var result = [];
77321
+ for (var i = 0; i < mapResults.length; i++) {
77322
+ if (mapResults[i]) {
77323
+ result = result.concat(...mapResults[i]);
77324
+ }
77325
+ }
77326
+
77327
+ return callback(err, result);
77328
+ });
77329
+ }
77330
+ var concatLimit$1 = awaitify(concatLimit, 4);
77331
+
77332
+ /**
77333
+ * Applies `iteratee` to each item in `coll`, concatenating the results. Returns
77334
+ * the concatenated list. The `iteratee`s are called in parallel, and the
77335
+ * results are concatenated as they return. The results array will be returned in
77336
+ * the original order of `coll` passed to the `iteratee` function.
77337
+ *
77338
+ * @name concat
77339
+ * @static
77340
+ * @memberOf module:Collections
77341
+ * @method
77342
+ * @category Collection
77343
+ * @alias flatMap
77344
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
77345
+ * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`,
77346
+ * which should use an array as its result. Invoked with (item, callback).
77347
+ * @param {Function} [callback] - A callback which is called after all the
77348
+ * `iteratee` functions have finished, or an error occurs. Results is an array
77349
+ * containing the concatenated results of the `iteratee` function. Invoked with
77350
+ * (err, results).
77351
+ * @returns A Promise, if no callback is passed
77352
+ * @example
77353
+ *
77354
+ * // dir1 is a directory that contains file1.txt, file2.txt
77355
+ * // dir2 is a directory that contains file3.txt, file4.txt
77356
+ * // dir3 is a directory that contains file5.txt
77357
+ * // dir4 does not exist
77358
+ *
77359
+ * let directoryList = ['dir1','dir2','dir3'];
77360
+ * let withMissingDirectoryList = ['dir1','dir2','dir3', 'dir4'];
77361
+ *
77362
+ * // Using callbacks
77363
+ * async.concat(directoryList, fs.readdir, function(err, results) {
77364
+ * if (err) {
77365
+ * console.log(err);
77366
+ * } else {
77367
+ * console.log(results);
77368
+ * // [ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', file5.txt ]
77369
+ * }
77370
+ * });
77371
+ *
77372
+ * // Error Handling
77373
+ * async.concat(withMissingDirectoryList, fs.readdir, function(err, results) {
77374
+ * if (err) {
77375
+ * console.log(err);
77376
+ * // [ Error: ENOENT: no such file or directory ]
77377
+ * // since dir4 does not exist
77378
+ * } else {
77379
+ * console.log(results);
77380
+ * }
77381
+ * });
77382
+ *
77383
+ * // Using Promises
77384
+ * async.concat(directoryList, fs.readdir)
77385
+ * .then(results => {
77386
+ * console.log(results);
77387
+ * // [ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', file5.txt ]
77388
+ * }).catch(err => {
77389
+ * console.log(err);
77390
+ * });
77391
+ *
77392
+ * // Error Handling
77393
+ * async.concat(withMissingDirectoryList, fs.readdir)
77394
+ * .then(results => {
77395
+ * console.log(results);
77396
+ * }).catch(err => {
77397
+ * console.log(err);
77398
+ * // [ Error: ENOENT: no such file or directory ]
77399
+ * // since dir4 does not exist
77400
+ * });
77401
+ *
77402
+ * // Using async/await
77403
+ * async () => {
77404
+ * try {
77405
+ * let results = await async.concat(directoryList, fs.readdir);
77406
+ * console.log(results);
77407
+ * // [ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', file5.txt ]
77408
+ * } catch (err) {
77409
+ * console.log(err);
77410
+ * }
77411
+ * }
77412
+ *
77413
+ * // Error Handling
77414
+ * async () => {
77415
+ * try {
77416
+ * let results = await async.concat(withMissingDirectoryList, fs.readdir);
77417
+ * console.log(results);
77418
+ * } catch (err) {
77419
+ * console.log(err);
77420
+ * // [ Error: ENOENT: no such file or directory ]
77421
+ * // since dir4 does not exist
77422
+ * }
77423
+ * }
77424
+ *
77425
+ */
77426
+ function concat(coll, iteratee, callback) {
77427
+ return concatLimit$1(coll, Infinity, iteratee, callback)
77428
+ }
77429
+ awaitify(concat, 3);
77430
+
77431
+ /**
77432
+ * The same as [`concat`]{@link module:Collections.concat} but runs only a single async operation at a time.
77433
+ *
77434
+ * @name concatSeries
77435
+ * @static
77436
+ * @memberOf module:Collections
77437
+ * @method
77438
+ * @see [async.concat]{@link module:Collections.concat}
77439
+ * @category Collection
77440
+ * @alias flatMapSeries
77441
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
77442
+ * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`.
77443
+ * The iteratee should complete with an array an array of results.
77444
+ * Invoked with (item, callback).
77445
+ * @param {Function} [callback] - A callback which is called after all the
77446
+ * `iteratee` functions have finished, or an error occurs. Results is an array
77447
+ * containing the concatenated results of the `iteratee` function. Invoked with
77448
+ * (err, results).
77449
+ * @returns A Promise, if no callback is passed
77450
+ */
77451
+ function concatSeries(coll, iteratee, callback) {
77452
+ return concatLimit$1(coll, 1, iteratee, callback)
77453
+ }
77454
+ awaitify(concatSeries, 3);
77455
+
77456
+ function _createTester(check, getResult) {
77457
+ return (eachfn, arr, _iteratee, cb) => {
77458
+ var testPassed = false;
77459
+ var testResult;
77460
+ const iteratee = wrapAsync(_iteratee);
77461
+ eachfn(arr, (value, _, callback) => {
77462
+ iteratee(value, (err, result) => {
77463
+ if (err || err === false) return callback(err);
77464
+
77465
+ if (check(result) && !testResult) {
77466
+ testPassed = true;
77467
+ testResult = getResult(true, value);
77468
+ return callback(null, breakLoop);
77469
+ }
77470
+ callback();
77471
+ });
77472
+ }, err => {
77473
+ if (err) return cb(err);
77474
+ cb(null, testPassed ? testResult : getResult(false));
77475
+ });
77476
+ };
77477
+ }
77478
+
77479
+ /**
77480
+ * Returns the first value in `coll` that passes an async truth test. The
77481
+ * `iteratee` is applied in parallel, meaning the first iteratee to return
77482
+ * `true` will fire the detect `callback` with that result. That means the
77483
+ * result might not be the first item in the original `coll` (in terms of order)
77484
+ * that passes the test.
77485
+
77486
+ * If order within the original `coll` is important, then look at
77487
+ * [`detectSeries`]{@link module:Collections.detectSeries}.
77488
+ *
77489
+ * @name detect
77490
+ * @static
77491
+ * @memberOf module:Collections
77492
+ * @method
77493
+ * @alias find
77494
+ * @category Collections
77495
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
77496
+ * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.
77497
+ * The iteratee must complete with a boolean value as its result.
77498
+ * Invoked with (item, callback).
77499
+ * @param {Function} [callback] - A callback which is called as soon as any
77500
+ * iteratee returns `true`, or after all the `iteratee` functions have finished.
77501
+ * Result will be the first item in the array that passes the truth test
77502
+ * (iteratee) or the value `undefined` if none passed. Invoked with
77503
+ * (err, result).
77504
+ * @returns {Promise} a promise, if a callback is omitted
77505
+ * @example
77506
+ *
77507
+ * // dir1 is a directory that contains file1.txt, file2.txt
77508
+ * // dir2 is a directory that contains file3.txt, file4.txt
77509
+ * // dir3 is a directory that contains file5.txt
77510
+ *
77511
+ * // asynchronous function that checks if a file exists
77512
+ * function fileExists(file, callback) {
77513
+ * fs.access(file, fs.constants.F_OK, (err) => {
77514
+ * callback(null, !err);
77515
+ * });
77516
+ * }
77517
+ *
77518
+ * async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists,
77519
+ * function(err, result) {
77520
+ * console.log(result);
77521
+ * // dir1/file1.txt
77522
+ * // result now equals the first file in the list that exists
77523
+ * }
77524
+ *);
77525
+ *
77526
+ * // Using Promises
77527
+ * async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists)
77528
+ * .then(result => {
77529
+ * console.log(result);
77530
+ * // dir1/file1.txt
77531
+ * // result now equals the first file in the list that exists
77532
+ * }).catch(err => {
77533
+ * console.log(err);
77534
+ * });
77535
+ *
77536
+ * // Using async/await
77537
+ * async () => {
77538
+ * try {
77539
+ * let result = await async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists);
77540
+ * console.log(result);
77541
+ * // dir1/file1.txt
77542
+ * // result now equals the file in the list that exists
77543
+ * }
77544
+ * catch (err) {
77545
+ * console.log(err);
77546
+ * }
77547
+ * }
77548
+ *
77549
+ */
77550
+ function detect(coll, iteratee, callback) {
77551
+ return _createTester(bool => bool, (res, item) => item)(eachOf$1, coll, iteratee, callback)
77552
+ }
77553
+ awaitify(detect, 3);
77554
+
77555
+ /**
77556
+ * The same as [`detect`]{@link module:Collections.detect} but runs a maximum of `limit` async operations at a
77557
+ * time.
77558
+ *
77559
+ * @name detectLimit
77560
+ * @static
77561
+ * @memberOf module:Collections
77562
+ * @method
77563
+ * @see [async.detect]{@link module:Collections.detect}
77564
+ * @alias findLimit
77565
+ * @category Collections
77566
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
77567
+ * @param {number} limit - The maximum number of async operations at a time.
77568
+ * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.
77569
+ * The iteratee must complete with a boolean value as its result.
77570
+ * Invoked with (item, callback).
77571
+ * @param {Function} [callback] - A callback which is called as soon as any
77572
+ * iteratee returns `true`, or after all the `iteratee` functions have finished.
77573
+ * Result will be the first item in the array that passes the truth test
77574
+ * (iteratee) or the value `undefined` if none passed. Invoked with
77575
+ * (err, result).
77576
+ * @returns {Promise} a promise, if a callback is omitted
77577
+ */
77578
+ function detectLimit(coll, limit, iteratee, callback) {
77579
+ return _createTester(bool => bool, (res, item) => item)(eachOfLimit$2(limit), coll, iteratee, callback)
77580
+ }
77581
+ awaitify(detectLimit, 4);
77582
+
77583
+ /**
77584
+ * The same as [`detect`]{@link module:Collections.detect} but runs only a single async operation at a time.
77585
+ *
77586
+ * @name detectSeries
77587
+ * @static
77588
+ * @memberOf module:Collections
77589
+ * @method
77590
+ * @see [async.detect]{@link module:Collections.detect}
77591
+ * @alias findSeries
77592
+ * @category Collections
77593
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
77594
+ * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.
77595
+ * The iteratee must complete with a boolean value as its result.
77596
+ * Invoked with (item, callback).
77597
+ * @param {Function} [callback] - A callback which is called as soon as any
77598
+ * iteratee returns `true`, or after all the `iteratee` functions have finished.
77599
+ * Result will be the first item in the array that passes the truth test
77600
+ * (iteratee) or the value `undefined` if none passed. Invoked with
77601
+ * (err, result).
77602
+ * @returns {Promise} a promise, if a callback is omitted
77603
+ */
77604
+ function detectSeries(coll, iteratee, callback) {
77605
+ return _createTester(bool => bool, (res, item) => item)(eachOfLimit$2(1), coll, iteratee, callback)
77606
+ }
77607
+
77608
+ awaitify(detectSeries, 3);
77609
+
77610
+ /**
77611
+ * The post-check version of [`whilst`]{@link module:ControlFlow.whilst}. To reflect the difference in
77612
+ * the order of operations, the arguments `test` and `iteratee` are switched.
77613
+ *
77614
+ * `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript.
77615
+ *
77616
+ * @name doWhilst
77617
+ * @static
77618
+ * @memberOf module:ControlFlow
77619
+ * @method
77620
+ * @see [async.whilst]{@link module:ControlFlow.whilst}
77621
+ * @category Control Flow
77622
+ * @param {AsyncFunction} iteratee - A function which is called each time `test`
77623
+ * passes. Invoked with (callback).
77624
+ * @param {AsyncFunction} test - asynchronous truth test to perform after each
77625
+ * execution of `iteratee`. Invoked with (...args, callback), where `...args` are the
77626
+ * non-error args from the previous callback of `iteratee`.
77627
+ * @param {Function} [callback] - A callback which is called after the test
77628
+ * function has failed and repeated execution of `iteratee` has stopped.
77629
+ * `callback` will be passed an error and any arguments passed to the final
77630
+ * `iteratee`'s callback. Invoked with (err, [results]);
77631
+ * @returns {Promise} a promise, if no callback is passed
77632
+ */
77633
+ function doWhilst(iteratee, test, callback) {
77634
+ callback = onlyOnce(callback);
77635
+ var _fn = wrapAsync(iteratee);
77636
+ var _test = wrapAsync(test);
77637
+ var results;
77638
+
77639
+ function next(err, ...args) {
77640
+ if (err) return callback(err);
77641
+ if (err === false) return;
77642
+ results = args;
77643
+ _test(...args, check);
77644
+ }
77645
+
77646
+ function check(err, truth) {
77647
+ if (err) return callback(err);
77648
+ if (err === false) return;
77649
+ if (!truth) return callback(null, ...results);
77650
+ _fn(next);
77651
+ }
77652
+
77653
+ return check(null, true);
77654
+ }
77655
+
77656
+ awaitify(doWhilst, 3);
77657
+
77658
+ function _withoutIndex(iteratee) {
77659
+ return (value, index, callback) => iteratee(value, callback);
77660
+ }
77661
+
77662
+ /**
77663
+ * Applies the function `iteratee` to each item in `coll`, in parallel.
77664
+ * The `iteratee` is called with an item from the list, and a callback for when
77665
+ * it has finished. If the `iteratee` passes an error to its `callback`, the
77666
+ * main `callback` (for the `each` function) is immediately called with the
77667
+ * error.
77668
+ *
77669
+ * Note, that since this function applies `iteratee` to each item in parallel,
77670
+ * there is no guarantee that the iteratee functions will complete in order.
77671
+ *
77672
+ * @name each
77673
+ * @static
77674
+ * @memberOf module:Collections
77675
+ * @method
77676
+ * @alias forEach
77677
+ * @category Collection
77678
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
77679
+ * @param {AsyncFunction} iteratee - An async function to apply to
77680
+ * each item in `coll`. Invoked with (item, callback).
77681
+ * The array index is not passed to the iteratee.
77682
+ * If you need the index, use `eachOf`.
77683
+ * @param {Function} [callback] - A callback which is called when all
77684
+ * `iteratee` functions have finished, or an error occurs. Invoked with (err).
77685
+ * @returns {Promise} a promise, if a callback is omitted
77686
+ * @example
77687
+ *
77688
+ * // dir1 is a directory that contains file1.txt, file2.txt
77689
+ * // dir2 is a directory that contains file3.txt, file4.txt
77690
+ * // dir3 is a directory that contains file5.txt
77691
+ * // dir4 does not exist
77692
+ *
77693
+ * const fileList = [ 'dir1/file2.txt', 'dir2/file3.txt', 'dir/file5.txt'];
77694
+ * const withMissingFileList = ['dir1/file1.txt', 'dir4/file2.txt'];
77695
+ *
77696
+ * // asynchronous function that deletes a file
77697
+ * const deleteFile = function(file, callback) {
77698
+ * fs.unlink(file, callback);
77699
+ * };
77700
+ *
77701
+ * // Using callbacks
77702
+ * async.each(fileList, deleteFile, function(err) {
77703
+ * if( err ) {
77704
+ * console.log(err);
77705
+ * } else {
77706
+ * console.log('All files have been deleted successfully');
77707
+ * }
77708
+ * });
77709
+ *
77710
+ * // Error Handling
77711
+ * async.each(withMissingFileList, deleteFile, function(err){
77712
+ * console.log(err);
77713
+ * // [ Error: ENOENT: no such file or directory ]
77714
+ * // since dir4/file2.txt does not exist
77715
+ * // dir1/file1.txt could have been deleted
77716
+ * });
77717
+ *
77718
+ * // Using Promises
77719
+ * async.each(fileList, deleteFile)
77720
+ * .then( () => {
77721
+ * console.log('All files have been deleted successfully');
77722
+ * }).catch( err => {
77723
+ * console.log(err);
77724
+ * });
77725
+ *
77726
+ * // Error Handling
77727
+ * async.each(fileList, deleteFile)
77728
+ * .then( () => {
77729
+ * console.log('All files have been deleted successfully');
77730
+ * }).catch( err => {
77731
+ * console.log(err);
77732
+ * // [ Error: ENOENT: no such file or directory ]
77733
+ * // since dir4/file2.txt does not exist
77734
+ * // dir1/file1.txt could have been deleted
77735
+ * });
77736
+ *
77737
+ * // Using async/await
77738
+ * async () => {
77739
+ * try {
77740
+ * await async.each(files, deleteFile);
77741
+ * }
77742
+ * catch (err) {
77743
+ * console.log(err);
77744
+ * }
77745
+ * }
77746
+ *
77747
+ * // Error Handling
77748
+ * async () => {
77749
+ * try {
77750
+ * await async.each(withMissingFileList, deleteFile);
77751
+ * }
77752
+ * catch (err) {
77753
+ * console.log(err);
77754
+ * // [ Error: ENOENT: no such file or directory ]
77755
+ * // since dir4/file2.txt does not exist
77756
+ * // dir1/file1.txt could have been deleted
77757
+ * }
77758
+ * }
77759
+ *
77760
+ */
77761
+ function eachLimit$2(coll, iteratee, callback) {
77762
+ return eachOf$1(coll, _withoutIndex(wrapAsync(iteratee)), callback);
77763
+ }
77764
+
77765
+ awaitify(eachLimit$2, 3);
77766
+
77767
+ /**
77768
+ * The same as [`each`]{@link module:Collections.each} but runs a maximum of `limit` async operations at a time.
77769
+ *
77770
+ * @name eachLimit
77771
+ * @static
77772
+ * @memberOf module:Collections
77773
+ * @method
77774
+ * @see [async.each]{@link module:Collections.each}
77775
+ * @alias forEachLimit
77776
+ * @category Collection
77777
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
77778
+ * @param {number} limit - The maximum number of async operations at a time.
77779
+ * @param {AsyncFunction} iteratee - An async function to apply to each item in
77780
+ * `coll`.
77781
+ * The array index is not passed to the iteratee.
77782
+ * If you need the index, use `eachOfLimit`.
77783
+ * Invoked with (item, callback).
77784
+ * @param {Function} [callback] - A callback which is called when all
77785
+ * `iteratee` functions have finished, or an error occurs. Invoked with (err).
77786
+ * @returns {Promise} a promise, if a callback is omitted
77787
+ */
77788
+ function eachLimit(coll, limit, iteratee, callback) {
77789
+ return eachOfLimit$2(limit)(coll, _withoutIndex(wrapAsync(iteratee)), callback);
77790
+ }
77791
+ var eachLimit$1 = awaitify(eachLimit, 4);
77792
+
77793
+ /**
77794
+ * The same as [`each`]{@link module:Collections.each} but runs only a single async operation at a time.
77795
+ *
77796
+ * Note, that unlike [`each`]{@link module:Collections.each}, this function applies iteratee to each item
77797
+ * in series and therefore the iteratee functions will complete in order.
77798
+
77799
+ * @name eachSeries
77800
+ * @static
77801
+ * @memberOf module:Collections
77802
+ * @method
77803
+ * @see [async.each]{@link module:Collections.each}
77804
+ * @alias forEachSeries
77805
+ * @category Collection
77806
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
77807
+ * @param {AsyncFunction} iteratee - An async function to apply to each
77808
+ * item in `coll`.
77809
+ * The array index is not passed to the iteratee.
77810
+ * If you need the index, use `eachOfSeries`.
77811
+ * Invoked with (item, callback).
77812
+ * @param {Function} [callback] - A callback which is called when all
77813
+ * `iteratee` functions have finished, or an error occurs. Invoked with (err).
77814
+ * @returns {Promise} a promise, if a callback is omitted
77815
+ */
77816
+ function eachSeries(coll, iteratee, callback) {
77817
+ return eachLimit$1(coll, 1, iteratee, callback)
77818
+ }
77819
+ var eachSeries$1 = awaitify(eachSeries, 3);
77820
+
77821
+ /**
77822
+ * Wrap an async function and ensure it calls its callback on a later tick of
77823
+ * the event loop. If the function already calls its callback on a next tick,
77824
+ * no extra deferral is added. This is useful for preventing stack overflows
77825
+ * (`RangeError: Maximum call stack size exceeded`) and generally keeping
77826
+ * [Zalgo](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony)
77827
+ * contained. ES2017 `async` functions are returned as-is -- they are immune
77828
+ * to Zalgo's corrupting influences, as they always resolve on a later tick.
77829
+ *
77830
+ * @name ensureAsync
77831
+ * @static
77832
+ * @memberOf module:Utils
77833
+ * @method
77834
+ * @category Util
77835
+ * @param {AsyncFunction} fn - an async function, one that expects a node-style
77836
+ * callback as its last argument.
77837
+ * @returns {AsyncFunction} Returns a wrapped function with the exact same call
77838
+ * signature as the function passed in.
77839
+ * @example
77840
+ *
77841
+ * function sometimesAsync(arg, callback) {
77842
+ * if (cache[arg]) {
77843
+ * return callback(null, cache[arg]); // this would be synchronous!!
77844
+ * } else {
77845
+ * doSomeIO(arg, callback); // this IO would be asynchronous
77846
+ * }
77847
+ * }
77848
+ *
77849
+ * // this has a risk of stack overflows if many results are cached in a row
77850
+ * async.mapSeries(args, sometimesAsync, done);
77851
+ *
77852
+ * // this will defer sometimesAsync's callback if necessary,
77853
+ * // preventing stack overflows
77854
+ * async.mapSeries(args, async.ensureAsync(sometimesAsync), done);
77855
+ */
77856
+ function ensureAsync(fn) {
77857
+ if (isAsync(fn)) return fn;
77858
+ return function (...args/*, callback*/) {
77859
+ var callback = args.pop();
77860
+ var sync = true;
77861
+ args.push((...innerArgs) => {
77862
+ if (sync) {
77863
+ setImmediate$1(() => callback(...innerArgs));
77864
+ } else {
77865
+ callback(...innerArgs);
77866
+ }
77867
+ });
77868
+ fn.apply(this, args);
77869
+ sync = false;
77870
+ };
77871
+ }
77872
+
77873
+ /**
77874
+ * Returns `true` if every element in `coll` satisfies an async test. If any
77875
+ * iteratee call returns `false`, the main `callback` is immediately called.
77876
+ *
77877
+ * @name every
77878
+ * @static
77879
+ * @memberOf module:Collections
77880
+ * @method
77881
+ * @alias all
77882
+ * @category Collection
77883
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
77884
+ * @param {AsyncFunction} iteratee - An async truth test to apply to each item
77885
+ * in the collection in parallel.
77886
+ * The iteratee must complete with a boolean result value.
77887
+ * Invoked with (item, callback).
77888
+ * @param {Function} [callback] - A callback which is called after all the
77889
+ * `iteratee` functions have finished. Result will be either `true` or `false`
77890
+ * depending on the values of the async tests. Invoked with (err, result).
77891
+ * @returns {Promise} a promise, if no callback provided
77892
+ * @example
77893
+ *
77894
+ * // dir1 is a directory that contains file1.txt, file2.txt
77895
+ * // dir2 is a directory that contains file3.txt, file4.txt
77896
+ * // dir3 is a directory that contains file5.txt
77897
+ * // dir4 does not exist
77898
+ *
77899
+ * const fileList = ['dir1/file1.txt','dir2/file3.txt','dir3/file5.txt'];
77900
+ * const withMissingFileList = ['file1.txt','file2.txt','file4.txt'];
77901
+ *
77902
+ * // asynchronous function that checks if a file exists
77903
+ * function fileExists(file, callback) {
77904
+ * fs.access(file, fs.constants.F_OK, (err) => {
77905
+ * callback(null, !err);
77906
+ * });
77907
+ * }
77908
+ *
77909
+ * // Using callbacks
77910
+ * async.every(fileList, fileExists, function(err, result) {
77911
+ * console.log(result);
77912
+ * // true
77913
+ * // result is true since every file exists
77914
+ * });
77915
+ *
77916
+ * async.every(withMissingFileList, fileExists, function(err, result) {
77917
+ * console.log(result);
77918
+ * // false
77919
+ * // result is false since NOT every file exists
77920
+ * });
77921
+ *
77922
+ * // Using Promises
77923
+ * async.every(fileList, fileExists)
77924
+ * .then( result => {
77925
+ * console.log(result);
77926
+ * // true
77927
+ * // result is true since every file exists
77928
+ * }).catch( err => {
77929
+ * console.log(err);
77930
+ * });
77931
+ *
77932
+ * async.every(withMissingFileList, fileExists)
77933
+ * .then( result => {
77934
+ * console.log(result);
77935
+ * // false
77936
+ * // result is false since NOT every file exists
77937
+ * }).catch( err => {
77938
+ * console.log(err);
77939
+ * });
77940
+ *
77941
+ * // Using async/await
77942
+ * async () => {
77943
+ * try {
77944
+ * let result = await async.every(fileList, fileExists);
77945
+ * console.log(result);
77946
+ * // true
77947
+ * // result is true since every file exists
77948
+ * }
77949
+ * catch (err) {
77950
+ * console.log(err);
77951
+ * }
77952
+ * }
77953
+ *
77954
+ * async () => {
77955
+ * try {
77956
+ * let result = await async.every(withMissingFileList, fileExists);
77957
+ * console.log(result);
77958
+ * // false
77959
+ * // result is false since NOT every file exists
77960
+ * }
77961
+ * catch (err) {
77962
+ * console.log(err);
77963
+ * }
77964
+ * }
77965
+ *
77966
+ */
77967
+ function every(coll, iteratee, callback) {
77968
+ return _createTester(bool => !bool, res => !res)(eachOf$1, coll, iteratee, callback)
77969
+ }
77970
+ awaitify(every, 3);
77971
+
77972
+ /**
77973
+ * The same as [`every`]{@link module:Collections.every} but runs a maximum of `limit` async operations at a time.
77974
+ *
77975
+ * @name everyLimit
77976
+ * @static
77977
+ * @memberOf module:Collections
77978
+ * @method
77979
+ * @see [async.every]{@link module:Collections.every}
77980
+ * @alias allLimit
77981
+ * @category Collection
77982
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
77983
+ * @param {number} limit - The maximum number of async operations at a time.
77984
+ * @param {AsyncFunction} iteratee - An async truth test to apply to each item
77985
+ * in the collection in parallel.
77986
+ * The iteratee must complete with a boolean result value.
77987
+ * Invoked with (item, callback).
77988
+ * @param {Function} [callback] - A callback which is called after all the
77989
+ * `iteratee` functions have finished. Result will be either `true` or `false`
77990
+ * depending on the values of the async tests. Invoked with (err, result).
77991
+ * @returns {Promise} a promise, if no callback provided
77992
+ */
77993
+ function everyLimit(coll, limit, iteratee, callback) {
77994
+ return _createTester(bool => !bool, res => !res)(eachOfLimit$2(limit), coll, iteratee, callback)
77995
+ }
77996
+ awaitify(everyLimit, 4);
77997
+
77998
+ /**
77999
+ * The same as [`every`]{@link module:Collections.every} but runs only a single async operation at a time.
78000
+ *
78001
+ * @name everySeries
78002
+ * @static
78003
+ * @memberOf module:Collections
78004
+ * @method
78005
+ * @see [async.every]{@link module:Collections.every}
78006
+ * @alias allSeries
78007
+ * @category Collection
78008
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
78009
+ * @param {AsyncFunction} iteratee - An async truth test to apply to each item
78010
+ * in the collection in series.
78011
+ * The iteratee must complete with a boolean result value.
78012
+ * Invoked with (item, callback).
78013
+ * @param {Function} [callback] - A callback which is called after all the
78014
+ * `iteratee` functions have finished. Result will be either `true` or `false`
78015
+ * depending on the values of the async tests. Invoked with (err, result).
78016
+ * @returns {Promise} a promise, if no callback provided
78017
+ */
78018
+ function everySeries(coll, iteratee, callback) {
78019
+ return _createTester(bool => !bool, res => !res)(eachOfSeries$1, coll, iteratee, callback)
78020
+ }
78021
+ awaitify(everySeries, 3);
78022
+
78023
+ function filterArray(eachfn, arr, iteratee, callback) {
78024
+ var truthValues = new Array(arr.length);
78025
+ eachfn(arr, (x, index, iterCb) => {
78026
+ iteratee(x, (err, v) => {
78027
+ truthValues[index] = !!v;
78028
+ iterCb(err);
78029
+ });
78030
+ }, err => {
78031
+ if (err) return callback(err);
78032
+ var results = [];
78033
+ for (var i = 0; i < arr.length; i++) {
78034
+ if (truthValues[i]) results.push(arr[i]);
78035
+ }
78036
+ callback(null, results);
78037
+ });
78038
+ }
78039
+
78040
+ function filterGeneric(eachfn, coll, iteratee, callback) {
78041
+ var results = [];
78042
+ eachfn(coll, (x, index, iterCb) => {
78043
+ iteratee(x, (err, v) => {
78044
+ if (err) return iterCb(err);
78045
+ if (v) {
78046
+ results.push({index, value: x});
78047
+ }
78048
+ iterCb(err);
78049
+ });
78050
+ }, err => {
78051
+ if (err) return callback(err);
78052
+ callback(null, results
78053
+ .sort((a, b) => a.index - b.index)
78054
+ .map(v => v.value));
78055
+ });
78056
+ }
78057
+
78058
+ function _filter(eachfn, coll, iteratee, callback) {
78059
+ var filter = isArrayLike(coll) ? filterArray : filterGeneric;
78060
+ return filter(eachfn, coll, wrapAsync(iteratee), callback);
78061
+ }
78062
+
78063
+ /**
78064
+ * Returns a new array of all the values in `coll` which pass an async truth
78065
+ * test. This operation is performed in parallel, but the results array will be
78066
+ * in the same order as the original.
78067
+ *
78068
+ * @name filter
78069
+ * @static
78070
+ * @memberOf module:Collections
78071
+ * @method
78072
+ * @alias select
78073
+ * @category Collection
78074
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
78075
+ * @param {Function} iteratee - A truth test to apply to each item in `coll`.
78076
+ * The `iteratee` is passed a `callback(err, truthValue)`, which must be called
78077
+ * with a boolean argument once it has completed. Invoked with (item, callback).
78078
+ * @param {Function} [callback] - A callback which is called after all the
78079
+ * `iteratee` functions have finished. Invoked with (err, results).
78080
+ * @returns {Promise} a promise, if no callback provided
78081
+ * @example
78082
+ *
78083
+ * // dir1 is a directory that contains file1.txt, file2.txt
78084
+ * // dir2 is a directory that contains file3.txt, file4.txt
78085
+ * // dir3 is a directory that contains file5.txt
78086
+ *
78087
+ * const files = ['dir1/file1.txt','dir2/file3.txt','dir3/file6.txt'];
78088
+ *
78089
+ * // asynchronous function that checks if a file exists
78090
+ * function fileExists(file, callback) {
78091
+ * fs.access(file, fs.constants.F_OK, (err) => {
78092
+ * callback(null, !err);
78093
+ * });
78094
+ * }
78095
+ *
78096
+ * // Using callbacks
78097
+ * async.filter(files, fileExists, function(err, results) {
78098
+ * if(err) {
78099
+ * console.log(err);
78100
+ * } else {
78101
+ * console.log(results);
78102
+ * // [ 'dir1/file1.txt', 'dir2/file3.txt' ]
78103
+ * // results is now an array of the existing files
78104
+ * }
78105
+ * });
78106
+ *
78107
+ * // Using Promises
78108
+ * async.filter(files, fileExists)
78109
+ * .then(results => {
78110
+ * console.log(results);
78111
+ * // [ 'dir1/file1.txt', 'dir2/file3.txt' ]
78112
+ * // results is now an array of the existing files
78113
+ * }).catch(err => {
78114
+ * console.log(err);
78115
+ * });
78116
+ *
78117
+ * // Using async/await
78118
+ * async () => {
78119
+ * try {
78120
+ * let results = await async.filter(files, fileExists);
78121
+ * console.log(results);
78122
+ * // [ 'dir1/file1.txt', 'dir2/file3.txt' ]
78123
+ * // results is now an array of the existing files
78124
+ * }
78125
+ * catch (err) {
78126
+ * console.log(err);
78127
+ * }
78128
+ * }
78129
+ *
78130
+ */
78131
+ function filter (coll, iteratee, callback) {
78132
+ return _filter(eachOf$1, coll, iteratee, callback)
78133
+ }
78134
+ awaitify(filter, 3);
78135
+
78136
+ /**
78137
+ * The same as [`filter`]{@link module:Collections.filter} but runs a maximum of `limit` async operations at a
78138
+ * time.
78139
+ *
78140
+ * @name filterLimit
78141
+ * @static
78142
+ * @memberOf module:Collections
78143
+ * @method
78144
+ * @see [async.filter]{@link module:Collections.filter}
78145
+ * @alias selectLimit
78146
+ * @category Collection
78147
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
78148
+ * @param {number} limit - The maximum number of async operations at a time.
78149
+ * @param {Function} iteratee - A truth test to apply to each item in `coll`.
78150
+ * The `iteratee` is passed a `callback(err, truthValue)`, which must be called
78151
+ * with a boolean argument once it has completed. Invoked with (item, callback).
78152
+ * @param {Function} [callback] - A callback which is called after all the
78153
+ * `iteratee` functions have finished. Invoked with (err, results).
78154
+ * @returns {Promise} a promise, if no callback provided
78155
+ */
78156
+ function filterLimit (coll, limit, iteratee, callback) {
78157
+ return _filter(eachOfLimit$2(limit), coll, iteratee, callback)
78158
+ }
78159
+ awaitify(filterLimit, 4);
78160
+
78161
+ /**
78162
+ * The same as [`filter`]{@link module:Collections.filter} but runs only a single async operation at a time.
78163
+ *
78164
+ * @name filterSeries
78165
+ * @static
78166
+ * @memberOf module:Collections
78167
+ * @method
78168
+ * @see [async.filter]{@link module:Collections.filter}
78169
+ * @alias selectSeries
78170
+ * @category Collection
78171
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
78172
+ * @param {Function} iteratee - A truth test to apply to each item in `coll`.
78173
+ * The `iteratee` is passed a `callback(err, truthValue)`, which must be called
78174
+ * with a boolean argument once it has completed. Invoked with (item, callback).
78175
+ * @param {Function} [callback] - A callback which is called after all the
78176
+ * `iteratee` functions have finished. Invoked with (err, results)
78177
+ * @returns {Promise} a promise, if no callback provided
78178
+ */
78179
+ function filterSeries (coll, iteratee, callback) {
78180
+ return _filter(eachOfSeries$1, coll, iteratee, callback)
78181
+ }
78182
+ awaitify(filterSeries, 3);
78183
+
78184
+ /**
78185
+ * Calls the asynchronous function `fn` with a callback parameter that allows it
78186
+ * to call itself again, in series, indefinitely.
78187
+
78188
+ * If an error is passed to the callback then `errback` is called with the
78189
+ * error, and execution stops, otherwise it will never be called.
78190
+ *
78191
+ * @name forever
78192
+ * @static
78193
+ * @memberOf module:ControlFlow
78194
+ * @method
78195
+ * @category Control Flow
78196
+ * @param {AsyncFunction} fn - an async function to call repeatedly.
78197
+ * Invoked with (next).
78198
+ * @param {Function} [errback] - when `fn` passes an error to it's callback,
78199
+ * this function will be called, and execution stops. Invoked with (err).
78200
+ * @returns {Promise} a promise that rejects if an error occurs and an errback
78201
+ * is not passed
78202
+ * @example
78203
+ *
78204
+ * async.forever(
78205
+ * function(next) {
78206
+ * // next is suitable for passing to things that need a callback(err [, whatever]);
78207
+ * // it will result in this function being called again.
78208
+ * },
78209
+ * function(err) {
78210
+ * // if next is called with a value in its first parameter, it will appear
78211
+ * // in here as 'err', and execution will stop.
78212
+ * }
78213
+ * );
78214
+ */
78215
+ function forever(fn, errback) {
78216
+ var done = onlyOnce(errback);
78217
+ var task = wrapAsync(ensureAsync(fn));
78218
+
78219
+ function next(err) {
78220
+ if (err) return done(err);
78221
+ if (err === false) return;
78222
+ task(next);
78223
+ }
78224
+ return next();
78225
+ }
78226
+ awaitify(forever, 2);
78227
+
78228
+ /**
78229
+ * The same as [`groupBy`]{@link module:Collections.groupBy} but runs a maximum of `limit` async operations at a time.
78230
+ *
78231
+ * @name groupByLimit
78232
+ * @static
78233
+ * @memberOf module:Collections
78234
+ * @method
78235
+ * @see [async.groupBy]{@link module:Collections.groupBy}
78236
+ * @category Collection
78237
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
78238
+ * @param {number} limit - The maximum number of async operations at a time.
78239
+ * @param {AsyncFunction} iteratee - An async function to apply to each item in
78240
+ * `coll`.
78241
+ * The iteratee should complete with a `key` to group the value under.
78242
+ * Invoked with (value, callback).
78243
+ * @param {Function} [callback] - A callback which is called when all `iteratee`
78244
+ * functions have finished, or an error occurs. Result is an `Object` whoses
78245
+ * properties are arrays of values which returned the corresponding key.
78246
+ * @returns {Promise} a promise, if no callback is passed
78247
+ */
78248
+ function groupByLimit(coll, limit, iteratee, callback) {
78249
+ var _iteratee = wrapAsync(iteratee);
78250
+ return mapLimit$1(coll, limit, (val, iterCb) => {
78251
+ _iteratee(val, (err, key) => {
78252
+ if (err) return iterCb(err);
78253
+ return iterCb(err, {key, val});
78254
+ });
78255
+ }, (err, mapResults) => {
78256
+ var result = {};
78257
+ // from MDN, handle object having an `hasOwnProperty` prop
78258
+ var {hasOwnProperty} = Object.prototype;
78259
+
78260
+ for (var i = 0; i < mapResults.length; i++) {
78261
+ if (mapResults[i]) {
78262
+ var {key} = mapResults[i];
78263
+ var {val} = mapResults[i];
78264
+
78265
+ if (hasOwnProperty.call(result, key)) {
78266
+ result[key].push(val);
78267
+ } else {
78268
+ result[key] = [val];
78269
+ }
78270
+ }
78271
+ }
78272
+
78273
+ return callback(err, result);
78274
+ });
78275
+ }
78276
+
78277
+ awaitify(groupByLimit, 4);
78278
+
78279
+ /**
78280
+ * The same as [`mapValues`]{@link module:Collections.mapValues} but runs a maximum of `limit` async operations at a
78281
+ * time.
78282
+ *
78283
+ * @name mapValuesLimit
78284
+ * @static
78285
+ * @memberOf module:Collections
78286
+ * @method
78287
+ * @see [async.mapValues]{@link module:Collections.mapValues}
78288
+ * @category Collection
78289
+ * @param {Object} obj - A collection to iterate over.
78290
+ * @param {number} limit - The maximum number of async operations at a time.
78291
+ * @param {AsyncFunction} iteratee - A function to apply to each value and key
78292
+ * in `coll`.
78293
+ * The iteratee should complete with the transformed value as its result.
78294
+ * Invoked with (value, key, callback).
78295
+ * @param {Function} [callback] - A callback which is called when all `iteratee`
78296
+ * functions have finished, or an error occurs. `result` is a new object consisting
78297
+ * of each key from `obj`, with each transformed value on the right-hand side.
78298
+ * Invoked with (err, result).
78299
+ * @returns {Promise} a promise, if no callback is passed
78300
+ */
78301
+ function mapValuesLimit(obj, limit, iteratee, callback) {
78302
+ callback = once(callback);
78303
+ var newObj = {};
78304
+ var _iteratee = wrapAsync(iteratee);
78305
+ return eachOfLimit$2(limit)(obj, (val, key, next) => {
78306
+ _iteratee(val, key, (err, result) => {
78307
+ if (err) return next(err);
78308
+ newObj[key] = result;
78309
+ next(err);
78310
+ });
78311
+ }, err => callback(err, newObj));
78312
+ }
78313
+
78314
+ awaitify(mapValuesLimit, 4);
78315
+
78316
+ if (hasNextTick) {
78317
+ process.nextTick;
78318
+ } else if (hasSetImmediate) {
78319
+ setImmediate;
78320
+ } else ;
78321
+
78322
+ awaitify((eachfn, tasks, callback) => {
78323
+ var results = isArrayLike(tasks) ? [] : {};
78324
+
78325
+ eachfn(tasks, (task, key, taskCb) => {
78326
+ wrapAsync(task)((err, ...result) => {
78327
+ if (result.length < 2) {
78328
+ [result] = result;
78329
+ }
78330
+ results[key] = result;
78331
+ taskCb(err);
78332
+ });
78333
+ }, err => callback(err, results));
78334
+ }, 3);
78335
+
78336
+ /**
78337
+ * Runs the `tasks` array of functions in parallel, without waiting until the
78338
+ * previous function has completed. Once any of the `tasks` complete or pass an
78339
+ * error to its callback, the main `callback` is immediately called. It's
78340
+ * equivalent to `Promise.race()`.
78341
+ *
78342
+ * @name race
78343
+ * @static
78344
+ * @memberOf module:ControlFlow
78345
+ * @method
78346
+ * @category Control Flow
78347
+ * @param {Array} tasks - An array containing [async functions]{@link AsyncFunction}
78348
+ * to run. Each function can complete with an optional `result` value.
78349
+ * @param {Function} callback - A callback to run once any of the functions have
78350
+ * completed. This function gets an error or result from the first function that
78351
+ * completed. Invoked with (err, result).
78352
+ * @returns {Promise} a promise, if a callback is omitted
78353
+ * @example
78354
+ *
78355
+ * async.race([
78356
+ * function(callback) {
78357
+ * setTimeout(function() {
78358
+ * callback(null, 'one');
78359
+ * }, 200);
78360
+ * },
78361
+ * function(callback) {
78362
+ * setTimeout(function() {
78363
+ * callback(null, 'two');
78364
+ * }, 100);
78365
+ * }
78366
+ * ],
78367
+ * // main callback
78368
+ * function(err, result) {
78369
+ * // the result will be equal to 'two' as it finishes earlier
78370
+ * });
78371
+ */
78372
+ function race(tasks, callback) {
78373
+ callback = once(callback);
78374
+ if (!Array.isArray(tasks)) return callback(new TypeError('First argument to race must be an array of functions'));
78375
+ if (!tasks.length) return callback();
78376
+ for (var i = 0, l = tasks.length; i < l; i++) {
78377
+ wrapAsync(tasks[i])(callback);
78378
+ }
78379
+ }
78380
+
78381
+ awaitify(race, 2);
78382
+
78383
+ function reject$2(eachfn, arr, _iteratee, callback) {
78384
+ const iteratee = wrapAsync(_iteratee);
78385
+ return _filter(eachfn, arr, (value, cb) => {
78386
+ iteratee(value, (err, v) => {
78387
+ cb(err, !v);
78388
+ });
78389
+ }, callback);
78390
+ }
78391
+
78392
+ /**
78393
+ * The opposite of [`filter`]{@link module:Collections.filter}. Removes values that pass an `async` truth test.
78394
+ *
78395
+ * @name reject
78396
+ * @static
78397
+ * @memberOf module:Collections
78398
+ * @method
78399
+ * @see [async.filter]{@link module:Collections.filter}
78400
+ * @category Collection
78401
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
78402
+ * @param {Function} iteratee - An async truth test to apply to each item in
78403
+ * `coll`.
78404
+ * The should complete with a boolean value as its `result`.
78405
+ * Invoked with (item, callback).
78406
+ * @param {Function} [callback] - A callback which is called after all the
78407
+ * `iteratee` functions have finished. Invoked with (err, results).
78408
+ * @returns {Promise} a promise, if no callback is passed
78409
+ * @example
78410
+ *
78411
+ * // dir1 is a directory that contains file1.txt, file2.txt
78412
+ * // dir2 is a directory that contains file3.txt, file4.txt
78413
+ * // dir3 is a directory that contains file5.txt
78414
+ *
78415
+ * const fileList = ['dir1/file1.txt','dir2/file3.txt','dir3/file6.txt'];
78416
+ *
78417
+ * // asynchronous function that checks if a file exists
78418
+ * function fileExists(file, callback) {
78419
+ * fs.access(file, fs.constants.F_OK, (err) => {
78420
+ * callback(null, !err);
78421
+ * });
78422
+ * }
78423
+ *
78424
+ * // Using callbacks
78425
+ * async.reject(fileList, fileExists, function(err, results) {
78426
+ * // [ 'dir3/file6.txt' ]
78427
+ * // results now equals an array of the non-existing files
78428
+ * });
78429
+ *
78430
+ * // Using Promises
78431
+ * async.reject(fileList, fileExists)
78432
+ * .then( results => {
78433
+ * console.log(results);
78434
+ * // [ 'dir3/file6.txt' ]
78435
+ * // results now equals an array of the non-existing files
78436
+ * }).catch( err => {
78437
+ * console.log(err);
78438
+ * });
78439
+ *
78440
+ * // Using async/await
78441
+ * async () => {
78442
+ * try {
78443
+ * let results = await async.reject(fileList, fileExists);
78444
+ * console.log(results);
78445
+ * // [ 'dir3/file6.txt' ]
78446
+ * // results now equals an array of the non-existing files
78447
+ * }
78448
+ * catch (err) {
78449
+ * console.log(err);
78450
+ * }
78451
+ * }
78452
+ *
78453
+ */
78454
+ function reject (coll, iteratee, callback) {
78455
+ return reject$2(eachOf$1, coll, iteratee, callback)
78456
+ }
78457
+ awaitify(reject, 3);
78458
+
78459
+ /**
78460
+ * The same as [`reject`]{@link module:Collections.reject} but runs a maximum of `limit` async operations at a
78461
+ * time.
78462
+ *
78463
+ * @name rejectLimit
78464
+ * @static
78465
+ * @memberOf module:Collections
78466
+ * @method
78467
+ * @see [async.reject]{@link module:Collections.reject}
78468
+ * @category Collection
78469
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
78470
+ * @param {number} limit - The maximum number of async operations at a time.
78471
+ * @param {Function} iteratee - An async truth test to apply to each item in
78472
+ * `coll`.
78473
+ * The should complete with a boolean value as its `result`.
78474
+ * Invoked with (item, callback).
78475
+ * @param {Function} [callback] - A callback which is called after all the
78476
+ * `iteratee` functions have finished. Invoked with (err, results).
78477
+ * @returns {Promise} a promise, if no callback is passed
78478
+ */
78479
+ function rejectLimit (coll, limit, iteratee, callback) {
78480
+ return reject$2(eachOfLimit$2(limit), coll, iteratee, callback)
78481
+ }
78482
+ awaitify(rejectLimit, 4);
78483
+
78484
+ /**
78485
+ * The same as [`reject`]{@link module:Collections.reject} but runs only a single async operation at a time.
78486
+ *
78487
+ * @name rejectSeries
78488
+ * @static
78489
+ * @memberOf module:Collections
78490
+ * @method
78491
+ * @see [async.reject]{@link module:Collections.reject}
78492
+ * @category Collection
78493
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
78494
+ * @param {Function} iteratee - An async truth test to apply to each item in
78495
+ * `coll`.
78496
+ * The should complete with a boolean value as its `result`.
78497
+ * Invoked with (item, callback).
78498
+ * @param {Function} [callback] - A callback which is called after all the
78499
+ * `iteratee` functions have finished. Invoked with (err, results).
78500
+ * @returns {Promise} a promise, if no callback is passed
78501
+ */
78502
+ function rejectSeries (coll, iteratee, callback) {
78503
+ return reject$2(eachOfSeries$1, coll, iteratee, callback)
78504
+ }
78505
+ awaitify(rejectSeries, 3);
78506
+
78507
+ /**
78508
+ * Returns `true` if at least one element in the `coll` satisfies an async test.
78509
+ * If any iteratee call returns `true`, the main `callback` is immediately
78510
+ * called.
78511
+ *
78512
+ * @name some
78513
+ * @static
78514
+ * @memberOf module:Collections
78515
+ * @method
78516
+ * @alias any
78517
+ * @category Collection
78518
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
78519
+ * @param {AsyncFunction} iteratee - An async truth test to apply to each item
78520
+ * in the collections in parallel.
78521
+ * The iteratee should complete with a boolean `result` value.
78522
+ * Invoked with (item, callback).
78523
+ * @param {Function} [callback] - A callback which is called as soon as any
78524
+ * iteratee returns `true`, or after all the iteratee functions have finished.
78525
+ * Result will be either `true` or `false` depending on the values of the async
78526
+ * tests. Invoked with (err, result).
78527
+ * @returns {Promise} a promise, if no callback provided
78528
+ * @example
78529
+ *
78530
+ * // dir1 is a directory that contains file1.txt, file2.txt
78531
+ * // dir2 is a directory that contains file3.txt, file4.txt
78532
+ * // dir3 is a directory that contains file5.txt
78533
+ * // dir4 does not exist
78534
+ *
78535
+ * // asynchronous function that checks if a file exists
78536
+ * function fileExists(file, callback) {
78537
+ * fs.access(file, fs.constants.F_OK, (err) => {
78538
+ * callback(null, !err);
78539
+ * });
78540
+ * }
78541
+ *
78542
+ * // Using callbacks
78543
+ * async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists,
78544
+ * function(err, result) {
78545
+ * console.log(result);
78546
+ * // true
78547
+ * // result is true since some file in the list exists
78548
+ * }
78549
+ *);
78550
+ *
78551
+ * async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists,
78552
+ * function(err, result) {
78553
+ * console.log(result);
78554
+ * // false
78555
+ * // result is false since none of the files exists
78556
+ * }
78557
+ *);
78558
+ *
78559
+ * // Using Promises
78560
+ * async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists)
78561
+ * .then( result => {
78562
+ * console.log(result);
78563
+ * // true
78564
+ * // result is true since some file in the list exists
78565
+ * }).catch( err => {
78566
+ * console.log(err);
78567
+ * });
78568
+ *
78569
+ * async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists)
78570
+ * .then( result => {
78571
+ * console.log(result);
78572
+ * // false
78573
+ * // result is false since none of the files exists
78574
+ * }).catch( err => {
78575
+ * console.log(err);
78576
+ * });
78577
+ *
78578
+ * // Using async/await
78579
+ * async () => {
78580
+ * try {
78581
+ * let result = await async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists);
78582
+ * console.log(result);
78583
+ * // true
78584
+ * // result is true since some file in the list exists
78585
+ * }
78586
+ * catch (err) {
78587
+ * console.log(err);
78588
+ * }
78589
+ * }
78590
+ *
78591
+ * async () => {
78592
+ * try {
78593
+ * let result = await async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists);
78594
+ * console.log(result);
78595
+ * // false
78596
+ * // result is false since none of the files exists
78597
+ * }
78598
+ * catch (err) {
78599
+ * console.log(err);
78600
+ * }
78601
+ * }
78602
+ *
78603
+ */
78604
+ function some(coll, iteratee, callback) {
78605
+ return _createTester(Boolean, res => res)(eachOf$1, coll, iteratee, callback)
78606
+ }
78607
+ awaitify(some, 3);
78608
+
78609
+ /**
78610
+ * The same as [`some`]{@link module:Collections.some} but runs a maximum of `limit` async operations at a time.
78611
+ *
78612
+ * @name someLimit
78613
+ * @static
78614
+ * @memberOf module:Collections
78615
+ * @method
78616
+ * @see [async.some]{@link module:Collections.some}
78617
+ * @alias anyLimit
78618
+ * @category Collection
78619
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
78620
+ * @param {number} limit - The maximum number of async operations at a time.
78621
+ * @param {AsyncFunction} iteratee - An async truth test to apply to each item
78622
+ * in the collections in parallel.
78623
+ * The iteratee should complete with a boolean `result` value.
78624
+ * Invoked with (item, callback).
78625
+ * @param {Function} [callback] - A callback which is called as soon as any
78626
+ * iteratee returns `true`, or after all the iteratee functions have finished.
78627
+ * Result will be either `true` or `false` depending on the values of the async
78628
+ * tests. Invoked with (err, result).
78629
+ * @returns {Promise} a promise, if no callback provided
78630
+ */
78631
+ function someLimit(coll, limit, iteratee, callback) {
78632
+ return _createTester(Boolean, res => res)(eachOfLimit$2(limit), coll, iteratee, callback)
78633
+ }
78634
+ awaitify(someLimit, 4);
78635
+
78636
+ /**
78637
+ * The same as [`some`]{@link module:Collections.some} but runs only a single async operation at a time.
78638
+ *
78639
+ * @name someSeries
78640
+ * @static
78641
+ * @memberOf module:Collections
78642
+ * @method
78643
+ * @see [async.some]{@link module:Collections.some}
78644
+ * @alias anySeries
78645
+ * @category Collection
78646
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
78647
+ * @param {AsyncFunction} iteratee - An async truth test to apply to each item
78648
+ * in the collections in series.
78649
+ * The iteratee should complete with a boolean `result` value.
78650
+ * Invoked with (item, callback).
78651
+ * @param {Function} [callback] - A callback which is called as soon as any
78652
+ * iteratee returns `true`, or after all the iteratee functions have finished.
78653
+ * Result will be either `true` or `false` depending on the values of the async
78654
+ * tests. Invoked with (err, result).
78655
+ * @returns {Promise} a promise, if no callback provided
78656
+ */
78657
+ function someSeries(coll, iteratee, callback) {
78658
+ return _createTester(Boolean, res => res)(eachOfSeries$1, coll, iteratee, callback)
78659
+ }
78660
+ awaitify(someSeries, 3);
78661
+
78662
+ /**
78663
+ * Sorts a list by the results of running each `coll` value through an async
78664
+ * `iteratee`.
78665
+ *
78666
+ * @name sortBy
78667
+ * @static
78668
+ * @memberOf module:Collections
78669
+ * @method
78670
+ * @category Collection
78671
+ * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
78672
+ * @param {AsyncFunction} iteratee - An async function to apply to each item in
78673
+ * `coll`.
78674
+ * The iteratee should complete with a value to use as the sort criteria as
78675
+ * its `result`.
78676
+ * Invoked with (item, callback).
78677
+ * @param {Function} callback - A callback which is called after all the
78678
+ * `iteratee` functions have finished, or an error occurs. Results is the items
78679
+ * from the original `coll` sorted by the values returned by the `iteratee`
78680
+ * calls. Invoked with (err, results).
78681
+ * @returns {Promise} a promise, if no callback passed
78682
+ * @example
78683
+ *
78684
+ * // bigfile.txt is a file that is 251100 bytes in size
78685
+ * // mediumfile.txt is a file that is 11000 bytes in size
78686
+ * // smallfile.txt is a file that is 121 bytes in size
78687
+ *
78688
+ * // asynchronous function that returns the file size in bytes
78689
+ * function getFileSizeInBytes(file, callback) {
78690
+ * fs.stat(file, function(err, stat) {
78691
+ * if (err) {
78692
+ * return callback(err);
78693
+ * }
78694
+ * callback(null, stat.size);
78695
+ * });
78696
+ * }
78697
+ *
78698
+ * // Using callbacks
78699
+ * async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], getFileSizeInBytes,
78700
+ * function(err, results) {
78701
+ * if (err) {
78702
+ * console.log(err);
78703
+ * } else {
78704
+ * console.log(results);
78705
+ * // results is now the original array of files sorted by
78706
+ * // file size (ascending by default), e.g.
78707
+ * // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt']
78708
+ * }
78709
+ * }
78710
+ * );
78711
+ *
78712
+ * // By modifying the callback parameter the
78713
+ * // sorting order can be influenced:
78714
+ *
78715
+ * // ascending order
78716
+ * async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], function(file, callback) {
78717
+ * getFileSizeInBytes(file, function(getFileSizeErr, fileSize) {
78718
+ * if (getFileSizeErr) return callback(getFileSizeErr);
78719
+ * callback(null, fileSize);
78720
+ * });
78721
+ * }, function(err, results) {
78722
+ * if (err) {
78723
+ * console.log(err);
78724
+ * } else {
78725
+ * console.log(results);
78726
+ * // results is now the original array of files sorted by
78727
+ * // file size (ascending by default), e.g.
78728
+ * // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt']
78729
+ * }
78730
+ * }
78731
+ * );
78732
+ *
78733
+ * // descending order
78734
+ * async.sortBy(['bigfile.txt','mediumfile.txt','smallfile.txt'], function(file, callback) {
78735
+ * getFileSizeInBytes(file, function(getFileSizeErr, fileSize) {
78736
+ * if (getFileSizeErr) {
78737
+ * return callback(getFileSizeErr);
78738
+ * }
78739
+ * callback(null, fileSize * -1);
78740
+ * });
78741
+ * }, function(err, results) {
78742
+ * if (err) {
78743
+ * console.log(err);
78744
+ * } else {
78745
+ * console.log(results);
78746
+ * // results is now the original array of files sorted by
78747
+ * // file size (ascending by default), e.g.
78748
+ * // [ 'bigfile.txt', 'mediumfile.txt', 'smallfile.txt']
78749
+ * }
78750
+ * }
78751
+ * );
78752
+ *
78753
+ * // Error handling
78754
+ * async.sortBy(['mediumfile.txt','smallfile.txt','missingfile.txt'], getFileSizeInBytes,
78755
+ * function(err, results) {
78756
+ * if (err) {
78757
+ * console.log(err);
78758
+ * // [ Error: ENOENT: no such file or directory ]
78759
+ * } else {
78760
+ * console.log(results);
78761
+ * }
78762
+ * }
78763
+ * );
78764
+ *
78765
+ * // Using Promises
78766
+ * async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], getFileSizeInBytes)
78767
+ * .then( results => {
78768
+ * console.log(results);
78769
+ * // results is now the original array of files sorted by
78770
+ * // file size (ascending by default), e.g.
78771
+ * // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt']
78772
+ * }).catch( err => {
78773
+ * console.log(err);
78774
+ * });
78775
+ *
78776
+ * // Error handling
78777
+ * async.sortBy(['mediumfile.txt','smallfile.txt','missingfile.txt'], getFileSizeInBytes)
78778
+ * .then( results => {
78779
+ * console.log(results);
78780
+ * }).catch( err => {
78781
+ * console.log(err);
78782
+ * // [ Error: ENOENT: no such file or directory ]
78783
+ * });
78784
+ *
78785
+ * // Using async/await
78786
+ * (async () => {
78787
+ * try {
78788
+ * let results = await async.sortBy(['bigfile.txt','mediumfile.txt','smallfile.txt'], getFileSizeInBytes);
78789
+ * console.log(results);
78790
+ * // results is now the original array of files sorted by
78791
+ * // file size (ascending by default), e.g.
78792
+ * // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt']
78793
+ * }
78794
+ * catch (err) {
78795
+ * console.log(err);
78796
+ * }
78797
+ * })();
78798
+ *
78799
+ * // Error handling
78800
+ * async () => {
78801
+ * try {
78802
+ * let results = await async.sortBy(['missingfile.txt','mediumfile.txt','smallfile.txt'], getFileSizeInBytes);
78803
+ * console.log(results);
78804
+ * }
78805
+ * catch (err) {
78806
+ * console.log(err);
78807
+ * // [ Error: ENOENT: no such file or directory ]
78808
+ * }
78809
+ * }
78810
+ *
78811
+ */
78812
+ function sortBy (coll, iteratee, callback) {
78813
+ var _iteratee = wrapAsync(iteratee);
78814
+ return map$1(coll, (x, iterCb) => {
78815
+ _iteratee(x, (err, criteria) => {
78816
+ if (err) return iterCb(err);
78817
+ iterCb(err, {value: x, criteria});
78818
+ });
78819
+ }, (err, results) => {
78820
+ if (err) return callback(err);
78821
+ callback(null, results.sort(comparator).map(v => v.value));
78822
+ });
78823
+
78824
+ function comparator(left, right) {
78825
+ var a = left.criteria, b = right.criteria;
78826
+ return a < b ? -1 : a > b ? 1 : 0;
78827
+ }
78828
+ }
78829
+ awaitify(sortBy, 3);
78830
+
78831
+ /**
78832
+ * It runs each task in series but stops whenever any of the functions were
78833
+ * successful. If one of the tasks were successful, the `callback` will be
78834
+ * passed the result of the successful task. If all tasks fail, the callback
78835
+ * will be passed the error and result (if any) of the final attempt.
78836
+ *
78837
+ * @name tryEach
78838
+ * @static
78839
+ * @memberOf module:ControlFlow
78840
+ * @method
78841
+ * @category Control Flow
78842
+ * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection containing functions to
78843
+ * run, each function is passed a `callback(err, result)` it must call on
78844
+ * completion with an error `err` (which can be `null`) and an optional `result`
78845
+ * value.
78846
+ * @param {Function} [callback] - An optional callback which is called when one
78847
+ * of the tasks has succeeded, or all have failed. It receives the `err` and
78848
+ * `result` arguments of the last attempt at completing the `task`. Invoked with
78849
+ * (err, results).
78850
+ * @returns {Promise} a promise, if no callback is passed
78851
+ * @example
78852
+ * async.tryEach([
78853
+ * function getDataFromFirstWebsite(callback) {
78854
+ * // Try getting the data from the first website
78855
+ * callback(err, data);
78856
+ * },
78857
+ * function getDataFromSecondWebsite(callback) {
78858
+ * // First website failed,
78859
+ * // Try getting the data from the backup website
78860
+ * callback(err, data);
78861
+ * }
78862
+ * ],
78863
+ * // optional callback
78864
+ * function(err, results) {
78865
+ * Now do something with the data.
78866
+ * });
78867
+ *
78868
+ */
78869
+ function tryEach(tasks, callback) {
78870
+ var error = null;
78871
+ var result;
78872
+ return eachSeries$1(tasks, (task, taskCb) => {
78873
+ wrapAsync(task)((err, ...args) => {
78874
+ if (err === false) return taskCb(err);
78875
+
78876
+ if (args.length < 2) {
78877
+ [result] = args;
78878
+ } else {
78879
+ result = args;
78880
+ }
78881
+ error = err;
78882
+ taskCb(err ? null : {});
78883
+ });
78884
+ }, () => callback(error, result));
78885
+ }
78886
+
78887
+ awaitify(tryEach);
78888
+
78889
+ /**
78890
+ * Repeatedly call `iteratee`, while `test` returns `true`. Calls `callback` when
78891
+ * stopped, or an error occurs.
78892
+ *
78893
+ * @name whilst
78894
+ * @static
78895
+ * @memberOf module:ControlFlow
78896
+ * @method
78897
+ * @category Control Flow
78898
+ * @param {AsyncFunction} test - asynchronous truth test to perform before each
78899
+ * execution of `iteratee`. Invoked with (callback).
78900
+ * @param {AsyncFunction} iteratee - An async function which is called each time
78901
+ * `test` passes. Invoked with (callback).
78902
+ * @param {Function} [callback] - A callback which is called after the test
78903
+ * function has failed and repeated execution of `iteratee` has stopped. `callback`
78904
+ * will be passed an error and any arguments passed to the final `iteratee`'s
78905
+ * callback. Invoked with (err, [results]);
78906
+ * @returns {Promise} a promise, if no callback is passed
78907
+ * @example
78908
+ *
78909
+ * var count = 0;
78910
+ * async.whilst(
78911
+ * function test(cb) { cb(null, count < 5); },
78912
+ * function iter(callback) {
78913
+ * count++;
78914
+ * setTimeout(function() {
78915
+ * callback(null, count);
78916
+ * }, 1000);
78917
+ * },
78918
+ * function (err, n) {
78919
+ * // 5 seconds have passed, n = 5
78920
+ * }
78921
+ * );
78922
+ */
78923
+ function whilst(test, iteratee, callback) {
78924
+ callback = onlyOnce(callback);
78925
+ var _fn = wrapAsync(iteratee);
78926
+ var _test = wrapAsync(test);
78927
+ var results = [];
78928
+
78929
+ function next(err, ...rest) {
78930
+ if (err) return callback(err);
78931
+ results = rest;
78932
+ if (err === false) return;
78933
+ _test(check);
78934
+ }
78935
+
78936
+ function check(err, truth) {
78937
+ if (err) return callback(err);
78938
+ if (err === false) return;
78939
+ if (!truth) return callback(null, ...results);
78940
+ _fn(next);
78941
+ }
78942
+
78943
+ return _test(check);
78944
+ }
78945
+ awaitify(whilst, 3);
78946
+
78947
+ /**
78948
+ * Runs the `tasks` array of functions in series, each passing their results to
78949
+ * the next in the array. However, if any of the `tasks` pass an error to their
78950
+ * own callback, the next function is not executed, and the main `callback` is
78951
+ * immediately called with the error.
78952
+ *
78953
+ * @name waterfall
78954
+ * @static
78955
+ * @memberOf module:ControlFlow
78956
+ * @method
78957
+ * @category Control Flow
78958
+ * @param {Array} tasks - An array of [async functions]{@link AsyncFunction}
78959
+ * to run.
78960
+ * Each function should complete with any number of `result` values.
78961
+ * The `result` values will be passed as arguments, in order, to the next task.
78962
+ * @param {Function} [callback] - An optional callback to run once all the
78963
+ * functions have completed. This will be passed the results of the last task's
78964
+ * callback. Invoked with (err, [results]).
78965
+ * @returns {Promise} a promise, if a callback is omitted
78966
+ * @example
78967
+ *
78968
+ * async.waterfall([
78969
+ * function(callback) {
78970
+ * callback(null, 'one', 'two');
78971
+ * },
78972
+ * function(arg1, arg2, callback) {
78973
+ * // arg1 now equals 'one' and arg2 now equals 'two'
78974
+ * callback(null, 'three');
78975
+ * },
78976
+ * function(arg1, callback) {
78977
+ * // arg1 now equals 'three'
78978
+ * callback(null, 'done');
78979
+ * }
78980
+ * ], function (err, result) {
78981
+ * // result now equals 'done'
78982
+ * });
78983
+ *
78984
+ * // Or, with named functions:
78985
+ * async.waterfall([
78986
+ * myFirstFunction,
78987
+ * mySecondFunction,
78988
+ * myLastFunction,
78989
+ * ], function (err, result) {
78990
+ * // result now equals 'done'
78991
+ * });
78992
+ * function myFirstFunction(callback) {
78993
+ * callback(null, 'one', 'two');
78994
+ * }
78995
+ * function mySecondFunction(arg1, arg2, callback) {
78996
+ * // arg1 now equals 'one' and arg2 now equals 'two'
78997
+ * callback(null, 'three');
78998
+ * }
78999
+ * function myLastFunction(arg1, callback) {
79000
+ * // arg1 now equals 'three'
79001
+ * callback(null, 'done');
79002
+ * }
79003
+ */
79004
+ function waterfall (tasks, callback) {
79005
+ callback = once(callback);
79006
+ if (!Array.isArray(tasks)) return callback(new Error('First argument to waterfall must be an array of functions'));
79007
+ if (!tasks.length) return callback();
79008
+ var taskIndex = 0;
79009
+
79010
+ function nextTask(args) {
79011
+ var task = wrapAsync(tasks[taskIndex++]);
79012
+ task(...args, onlyOnce(next));
79013
+ }
79014
+
79015
+ function next(err, ...args) {
79016
+ if (err === false) return
79017
+ if (err || taskIndex === tasks.length) {
79018
+ return callback(err, ...args);
79019
+ }
79020
+ nextTask(args);
79021
+ }
79022
+
79023
+ nextTask([]);
79024
+ }
79025
+
79026
+ awaitify(waterfall);
79027
+
76347
79028
  var LogLevel;
76348
79029
  (function (LogLevel) {
76349
79030
  LogLevel[LogLevel["DEBUG"] = 0] = "DEBUG";
@@ -76385,31 +79066,6 @@ class Logger {
76385
79066
  }
76386
79067
  }
76387
79068
 
76388
- /**
76389
- * Executes an array of promise-returning functions with a maximum concurrency limit.
76390
- * This prevents overwhelming RPC endpoints with too many concurrent requests.
76391
- *
76392
- * @param tasks - Array of functions that return promises
76393
- * @param maxConcurrency - Maximum number of concurrent executions (default: 5)
76394
- * @returns Promise that resolves to an array of settled results
76395
- *
76396
- * @example
76397
- * ```typescript
76398
- * const tasks = pools.map(pool => () => fetchPoolData(pool));
76399
- * const results = await batchWithConcurrency(tasks, 5);
76400
- * ```
76401
- */
76402
- async function batchWithConcurrency(tasks, maxConcurrency = 5) {
76403
- const results = [];
76404
- // Process tasks in batches
76405
- for (let i = 0; i < tasks.length; i += maxConcurrency) {
76406
- const batch = tasks.slice(i, i + maxConcurrency);
76407
- const batchResults = await Promise.allSettled(batch.map(task => task()));
76408
- results.push(...batchResults);
76409
- }
76410
- return results;
76411
- }
76412
-
76413
79069
  class DataError extends SDKError {
76414
79070
  constructor(message, code = ErrorCode.NETWORK_ERROR, details) {
76415
79071
  super(message, code, details);
@@ -76454,6 +79110,7 @@ class AccountService {
76454
79110
  dataService;
76455
79111
  account;
76456
79112
  logger;
79113
+ poolConcurrency;
76457
79114
  /**
76458
79115
  * Creates a new AccountService instance.
76459
79116
  *
@@ -76461,12 +79118,14 @@ class AccountService {
76461
79118
  * @param config - Configuration for the account service (either mnemonic or existing account)
76462
79119
  * @param config.mnemonic - Optional mnemonic for deterministic key generation
76463
79120
  * @param config.account - Optional existing account to initialize with
79121
+ * @param config.poolConcurrency - Optional maximum number of pools to fetch events for concurrently (default: 2)
76464
79122
  *
76465
79123
  * @throws {AccountError} If account initialization fails
76466
79124
  */
76467
79125
  constructor(dataService, config) {
76468
79126
  this.dataService = dataService;
76469
79127
  this.logger = new Logger({ prefix: "Account" });
79128
+ this.poolConcurrency = config.poolConcurrency ?? 2;
76470
79129
  if ("mnemonic" in config) {
76471
79130
  this.account = this._initializeAccount(config.mnemonic);
76472
79131
  }
@@ -76853,36 +79512,44 @@ class AccountService {
76853
79512
  }
76854
79513
  }
76855
79514
  /**
76856
- * Fetches events for a given set of pools with concurrency control
79515
+ * Fetches events for a given set of pools
76857
79516
  *
76858
79517
  * @param pools - The pools to fetch events for
76859
- * @param maxConcurrency - Maximum number of concurrent pool fetches (default: 5)
76860
79518
  *
76861
79519
  * @returns A map of pool scopes to their events
76862
79520
  */
76863
- async getEvents(pools, maxConcurrency = 5) {
79521
+ async getEvents(pools) {
76864
79522
  const events = new Map();
76865
- // Create tasks for batched execution
76866
- const tasks = pools.map((pool) => async () => {
76867
- this.logger.info(`Fetching events for pool`, {
76868
- poolAddress: pool.address,
76869
- poolChainId: pool.chainId,
76870
- poolDeploymentBlock: pool.deploymentBlock,
76871
- });
76872
- const [depositEvents, withdrawalEvents, ragequitEvents] = await Promise.all([
76873
- this.getDepositEvents(pool),
76874
- this.getWithdrawalEvents(pool),
76875
- this.getRagequitEvents(pool),
76876
- ]);
76877
- return {
76878
- scope: pool.scope,
76879
- depositEvents,
76880
- withdrawalEvents,
76881
- ragequitEvents,
76882
- };
79523
+ // Use mapLimit to control concurrency at pool level
79524
+ const poolEventResults = await mapLimit$1(pools, this.poolConcurrency, async (pool) => {
79525
+ try {
79526
+ this.logger.info(`Fetching events for pool`, {
79527
+ poolAddress: pool.address,
79528
+ poolChainId: pool.chainId,
79529
+ poolDeploymentBlock: pool.deploymentBlock,
79530
+ });
79531
+ const [depositEvents, withdrawalEvents, ragequitEvents] = await Promise.all([
79532
+ this.getDepositEvents(pool),
79533
+ this.getWithdrawalEvents(pool),
79534
+ this.getRagequitEvents(pool),
79535
+ ]);
79536
+ return {
79537
+ status: "fulfilled",
79538
+ value: {
79539
+ scope: pool.scope,
79540
+ depositEvents,
79541
+ withdrawalEvents,
79542
+ ragequitEvents,
79543
+ },
79544
+ };
79545
+ }
79546
+ catch (error) {
79547
+ return {
79548
+ status: "rejected",
79549
+ reason: error,
79550
+ };
79551
+ }
76883
79552
  });
76884
- // Execute with concurrency control
76885
- const poolEventResults = await batchWithConcurrency(tasks, maxConcurrency);
76886
79553
  for (const result of poolEventResults) {
76887
79554
  if (result.status === "fulfilled") {
76888
79555
  const { scope, depositEvents, withdrawalEvents, ragequitEvents } = result.value;
@@ -76893,9 +79560,11 @@ class AccountService {
76893
79560
  });
76894
79561
  }
76895
79562
  else {
76896
- events.set(result.reason.details?.scope, {
79563
+ const errorWithDetails = result.reason;
79564
+ const scope = errorWithDetails.details?.scope;
79565
+ events.set(scope, {
76897
79566
  reason: result.reason.message,
76898
- scope: result.reason.details?.scope,
79567
+ scope: scope,
76899
79568
  });
76900
79569
  }
76901
79570
  }
@@ -77021,11 +79690,10 @@ class AccountService {
77021
79690
  * @param dataService - The data service to use for fetching events
77022
79691
  * @param source - The source to use for initializing the account. Either a mnemonic or an existing account service instance
77023
79692
  * @param pools - The pools to fetch events for
77024
- * @param maxConcurrency - Maximum number of concurrent pool fetches (default: 5)
77025
79693
  *
77026
79694
  * @remarks
77027
79695
  * This method performs the following steps for each pool:
77028
- * 1. Fetches deposit, withdrawal, and ragequit events for each pool (with concurrency control)
79696
+ * 1. Fetches deposit, withdrawal, and ragequit events for each pool
77029
79697
  * 2. Processes deposit events and creates pool accounts
77030
79698
  * 3. Processes withdrawal events and adds commitments to pool accounts
77031
79699
  * 4. Processes ragequit events and adds ragequit to pool accounts
@@ -77037,7 +79705,7 @@ class AccountService {
77037
79705
  *
77038
79706
  * @throws {AccountError} If account state reconstruction fails or if duplicate pools are found
77039
79707
  */
77040
- static async initializeWithEvents(dataService, source, pools, maxConcurrency = 5) {
79708
+ static async initializeWithEvents(dataService, source, pools) {
77041
79709
  // Log the start of the history retrieval process
77042
79710
  const logger = new Logger({ prefix: "Account" });
77043
79711
  logger.info(`Fetching events for pools`, { poolLength: pools.length });
@@ -77053,7 +79721,7 @@ class AccountService {
77053
79721
  const account = new AccountService(dataService, "mnemonic" in source
77054
79722
  ? { mnemonic: source.mnemonic }
77055
79723
  : { account: source.service.account });
77056
- const events = await account.getEvents(pools, maxConcurrency);
79724
+ const events = await account.getEvents(pools);
77057
79725
  for (const [scope, result] of events.entries()) {
77058
79726
  if ("reason" in result) {
77059
79727
  errors.push(result);
@@ -77249,24 +79917,31 @@ class DataService {
77249
79917
  chainConfigs;
77250
79918
  clients = new Map();
77251
79919
  logger;
79920
+ logFetchConfigs;
77252
79921
  /**
77253
79922
  * Initialize the data service with chain configurations
77254
79923
  *
77255
79924
  * @param chainConfigs - Array of chain configurations containing chainId, RPC URL, and API key
79925
+ * @param logFetchConfig - Per-chain configuration for rate-limited log fetching as a Map<chainId, config>.
79926
+ * Each chain can have its own specific settings (e.g., different block chunk sizes).
77256
79927
  * @throws {DataError} If client initialization fails for any chain
77257
79928
  */
77258
- constructor(chainConfigs) {
79929
+ constructor(chainConfigs, logFetchConfig = new Map()) {
77259
79930
  this.chainConfigs = chainConfigs;
77260
- this.logger = new Logger({ prefix: "Data" });
79931
+ this.logger = new Logger({ prefix: "Data", level: LogLevel.DEBUG });
79932
+ // Initialize per-chain configs with defaults merged with chain-specific overrides
79933
+ this.logFetchConfigs = new Map();
79934
+ for (const config of chainConfigs) {
79935
+ const chainSpecificConfig = logFetchConfig.get(config.chainId);
79936
+ this.logFetchConfigs.set(config.chainId, { ...DEFAULT_LOG_FETCH_CONFIG, ...chainSpecificConfig });
79937
+ }
77261
79938
  try {
77262
79939
  for (const config of chainConfigs) {
77263
79940
  if (!config.rpcUrl) {
77264
79941
  throw new Error(`Missing RPC URL for chain ${config.chainId}`);
77265
79942
  }
77266
79943
  const client = createPublicClient({
77267
- transport: http(config.rpcUrl, {
77268
- timeout: 20_000,
77269
- }),
79944
+ transport: http(config.rpcUrl),
77270
79945
  });
77271
79946
  this.clients.set(config.chainId, client);
77272
79947
  }
@@ -77278,29 +79953,41 @@ class DataService {
77278
79953
  /**
77279
79954
  * Get deposit events for a specific chain
77280
79955
  *
77281
- * @param chainId - Chain ID to fetch events from
77282
- * @param options - Event filter options including fromBlock, toBlock, and other filters
79956
+ * @param pool - Pool info containing chainId, address, and deployment block
77283
79957
  * @returns Array of deposit events with properly typed fields (bigint for numbers, Hash for commitments)
77284
79958
  * @throws {DataError} If client is not configured, network error occurs, or event data is invalid
77285
79959
  */
77286
79960
  async getDeposits(pool) {
77287
79961
  try {
77288
79962
  const client = this.getClientForChain(pool.chainId);
77289
- const config = this.getConfigForChain(pool.chainId);
77290
- const logs = await client.getLogs({
77291
- address: pool.address,
77292
- event: DEPOSIT_EVENT,
77293
- fromBlock: pool.deploymentBlock ?? config.startBlock
77294
- }).catch(error => {
77295
- throw new DataError("Failed to fetch deposit logs", ErrorCode.NETWORK_ERROR, { error: error instanceof Error ? error.message : "Unknown error" });
79963
+ const chainConfig = this.getConfigForChain(pool.chainId);
79964
+ const logConfig = this.getLogFetchConfigForChain(pool.chainId);
79965
+ const fromBlock = pool.deploymentBlock ?? chainConfig.startBlock;
79966
+ const toBlock = await this.getCurrentBlock(pool.chainId);
79967
+ const ranges = this.generateBlockRanges(fromBlock, toBlock, logConfig.blockChunkSize);
79968
+ this.logger.info(`Fetching deposits in ${ranges.length} chunks for pool ${pool.address}, chunk size is: ${logConfig.blockChunkSize}`);
79969
+ // Use async.mapLimit for controlled concurrency
79970
+ const allLogs = await mapLimit$1(ranges, logConfig.concurrency, async (range) => {
79971
+ if (logConfig.chunkDelayMs > 0) {
79972
+ await this.sleep(logConfig.chunkDelayMs);
79973
+ }
79974
+ return this.fetchLogsWithRetry(client, pool.address, DEPOSIT_EVENT, range, logConfig);
77296
79975
  });
77297
- return logs.map((log) => {
79976
+ // Flatten and parse results
79977
+ const flatLogs = allLogs.flat();
79978
+ return flatLogs.map((log) => {
77298
79979
  try {
77299
- if (!log.args) {
79980
+ const typedLog = log;
79981
+ if (!typedLog.args) {
77300
79982
  throw DataError.invalidLog("deposit", "missing args");
77301
79983
  }
77302
- const { _depositor: depositor, _commitment: commitment, _label: label, _value: value, _merkleRoot: precommitment, } = log.args;
77303
- if (!depositor || !commitment || !label || !precommitment || !log.blockNumber || !log.transactionHash) {
79984
+ const { _depositor: depositor, _commitment: commitment, _label: label, _value: value, _merkleRoot: precommitment, } = typedLog.args;
79985
+ if (!depositor ||
79986
+ !commitment ||
79987
+ !label ||
79988
+ !precommitment ||
79989
+ !typedLog.blockNumber ||
79990
+ !typedLog.transactionHash) {
77304
79991
  throw DataError.invalidLog("deposit", "missing required fields");
77305
79992
  }
77306
79993
  return {
@@ -77309,8 +79996,8 @@ class DataService {
77309
79996
  label: label,
77310
79997
  value: value || BigInt(0),
77311
79998
  precommitment: precommitment,
77312
- blockNumber: BigInt(log.blockNumber),
77313
- transactionHash: log.transactionHash,
79999
+ blockNumber: BigInt(typedLog.blockNumber),
80000
+ transactionHash: typedLog.transactionHash,
77314
80001
  };
77315
80002
  }
77316
80003
  catch (error) {
@@ -77329,37 +80016,50 @@ class DataService {
77329
80016
  /**
77330
80017
  * Get withdrawal events for a specific chain
77331
80018
  *
77332
- * @param chainId - Chain ID to fetch events from
77333
- * @param options - Event filter options including fromBlock, toBlock, and other filters
80019
+ * @param pool - Pool info containing chainId, address, and deployment block
80020
+ * @param fromBlock - Optional starting block (defaults to pool deployment block)
77334
80021
  * @returns Array of withdrawal events with properly typed fields (bigint for numbers, Hash for commitments)
77335
80022
  * @throws {DataError} If client is not configured, network error occurs, or event data is invalid
77336
80023
  */
77337
80024
  async getWithdrawals(pool, fromBlock = pool.deploymentBlock) {
77338
80025
  try {
77339
80026
  const client = this.getClientForChain(pool.chainId);
77340
- const config = this.getConfigForChain(pool.chainId);
77341
- const logs = await client.getLogs({
77342
- address: pool.address,
77343
- event: WITHDRAWAL_EVENT,
77344
- fromBlock: fromBlock ?? config.startBlock,
77345
- }).catch(error => {
77346
- throw new DataError("Failed to fetch withdrawal logs", ErrorCode.NETWORK_ERROR, { error: error instanceof Error ? error.message : "Unknown error" });
80027
+ const chainConfig = this.getConfigForChain(pool.chainId);
80028
+ const logConfig = this.getLogFetchConfigForChain(pool.chainId);
80029
+ const startBlock = fromBlock ?? chainConfig.startBlock;
80030
+ const toBlock = await this.getCurrentBlock(pool.chainId);
80031
+ const ranges = this.generateBlockRanges(startBlock, toBlock, logConfig.blockChunkSize);
80032
+ this.logger.debug(`Fetching withdrawals in ${ranges.length} chunks for pool ${pool.address}`);
80033
+ // Use async.mapLimit for controlled concurrency
80034
+ const allLogs = await mapLimit$1(ranges, logConfig.concurrency, async (range) => {
80035
+ if (logConfig.chunkDelayMs > 0) {
80036
+ await this.sleep(logConfig.chunkDelayMs);
80037
+ }
80038
+ return this.fetchLogsWithRetry(client, pool.address, WITHDRAWAL_EVENT, range, logConfig);
77347
80039
  });
77348
- return logs.map((log) => {
80040
+ // Flatten and parse results
80041
+ const flatLogs = allLogs.flat();
80042
+ return flatLogs.map((log) => {
77349
80043
  try {
77350
- if (!log.args) {
80044
+ const typedLog = log;
80045
+ if (!typedLog.args) {
77351
80046
  throw DataError.invalidLog("withdrawal", "missing args");
77352
80047
  }
77353
- const { _value: value, _spentNullifier: spentNullifier, _newCommitment: newCommitment, } = log.args;
77354
- if (!value || !spentNullifier || !newCommitment || !log.blockNumber || !log.transactionHash) {
80048
+ const { _value: value, _spentNullifier: spentNullifier, _newCommitment: newCommitment, } = typedLog.args;
80049
+ if (value === undefined ||
80050
+ value === null ||
80051
+ !spentNullifier ||
80052
+ !newCommitment ||
80053
+ !typedLog.blockNumber ||
80054
+ !typedLog.transactionHash) {
77355
80055
  throw DataError.invalidLog("withdrawal", "missing required fields");
77356
80056
  }
77357
80057
  return {
77358
80058
  withdrawn: value,
77359
80059
  spentNullifier: spentNullifier,
77360
80060
  newCommitment: newCommitment,
77361
- blockNumber: BigInt(log.blockNumber),
77362
- transactionHash: log.transactionHash,
80061
+ blockNumber: BigInt(typedLog.blockNumber),
80062
+ transactionHash: typedLog.transactionHash,
77363
80063
  };
77364
80064
  }
77365
80065
  catch (error) {
@@ -77378,29 +80078,41 @@ class DataService {
77378
80078
  /**
77379
80079
  * Get ragequit events for a specific chain
77380
80080
  *
77381
- * @param chainId - Chain ID to fetch events from
77382
- * @param options - Event filter options including fromBlock, toBlock, and other filters
80081
+ * @param pool - Pool info containing chainId, address, and deployment block
80082
+ * @param fromBlock - Optional starting block (defaults to pool deployment block)
77383
80083
  * @returns Array of ragequit events with properly typed fields (bigint for numbers, Hash for commitments)
77384
80084
  * @throws {DataError} If client is not configured, network error occurs, or event data is invalid
77385
80085
  */
77386
80086
  async getRagequits(pool, fromBlock = pool.deploymentBlock) {
77387
80087
  try {
77388
80088
  const client = this.getClientForChain(pool.chainId);
77389
- const config = this.getConfigForChain(pool.chainId);
77390
- const logs = await client.getLogs({
77391
- address: pool.address,
77392
- event: RAGEQUIT_EVENT,
77393
- fromBlock: fromBlock ?? config.startBlock,
77394
- }).catch(error => {
77395
- throw new DataError("Failed to fetch ragequit logs", ErrorCode.NETWORK_ERROR, { error: error instanceof Error ? error.message : "Unknown error" });
80089
+ const chainConfig = this.getConfigForChain(pool.chainId);
80090
+ const logConfig = this.getLogFetchConfigForChain(pool.chainId);
80091
+ const startBlock = fromBlock ?? chainConfig.startBlock;
80092
+ const toBlock = await this.getCurrentBlock(pool.chainId);
80093
+ const ranges = this.generateBlockRanges(startBlock, toBlock, logConfig.blockChunkSize);
80094
+ this.logger.debug(`Fetching ragequits in ${ranges.length} chunks for pool ${pool.address}`);
80095
+ // Use async.mapLimit for controlled concurrency
80096
+ const allLogs = await mapLimit$1(ranges, logConfig.concurrency, async (range) => {
80097
+ if (logConfig.chunkDelayMs > 0) {
80098
+ await this.sleep(logConfig.chunkDelayMs);
80099
+ }
80100
+ return this.fetchLogsWithRetry(client, pool.address, RAGEQUIT_EVENT, range, logConfig);
77396
80101
  });
77397
- return logs.map((log) => {
80102
+ // Flatten and parse results
80103
+ const flatLogs = allLogs.flat();
80104
+ return flatLogs.map((log) => {
77398
80105
  try {
77399
- if (!log.args) {
80106
+ const typedLog = log;
80107
+ if (!typedLog.args) {
77400
80108
  throw DataError.invalidLog("ragequit", "missing args");
77401
80109
  }
77402
- const { _ragequitter: ragequitter, _commitment: commitment, _label: label, _value: value, } = log.args;
77403
- if (!ragequitter || !commitment || !label || !log.blockNumber || !log.transactionHash) {
80110
+ const { _ragequitter: ragequitter, _commitment: commitment, _label: label, _value: value, } = typedLog.args;
80111
+ if (!ragequitter ||
80112
+ !commitment ||
80113
+ !label ||
80114
+ !typedLog.blockNumber ||
80115
+ !typedLog.transactionHash) {
77404
80116
  throw DataError.invalidLog("ragequit", "missing required fields");
77405
80117
  }
77406
80118
  return {
@@ -77408,8 +80120,8 @@ class DataService {
77408
80120
  commitment: commitment,
77409
80121
  label: label,
77410
80122
  value: value || BigInt(0),
77411
- blockNumber: BigInt(log.blockNumber),
77412
- transactionHash: log.transactionHash,
80123
+ blockNumber: BigInt(typedLog.blockNumber),
80124
+ transactionHash: typedLog.transactionHash,
77413
80125
  };
77414
80126
  }
77415
80127
  catch (error) {
@@ -77425,6 +80137,66 @@ class DataService {
77425
80137
  throw DataError.networkError(pool.chainId, error instanceof Error ? error : new Error(String(error)));
77426
80138
  }
77427
80139
  }
80140
+ /**
80141
+ * Gets the current block number for a chain
80142
+ */
80143
+ async getCurrentBlock(chainId) {
80144
+ const client = this.getClientForChain(chainId);
80145
+ return client.getBlockNumber();
80146
+ }
80147
+ /**
80148
+ * Generates block ranges for chunked fetching
80149
+ */
80150
+ generateBlockRanges(fromBlock, toBlock, chunkSize) {
80151
+ const ranges = [];
80152
+ let current = fromBlock;
80153
+ while (current <= toBlock) {
80154
+ const end = current + BigInt(chunkSize) - 1n;
80155
+ ranges.push({
80156
+ fromBlock: current,
80157
+ toBlock: end > toBlock ? toBlock : end,
80158
+ });
80159
+ current = end + 1n;
80160
+ }
80161
+ return ranges;
80162
+ }
80163
+ /**
80164
+ * Fetches logs for a single block range with retry logic
80165
+ */
80166
+ async fetchLogsWithRetry(client, address,
80167
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
80168
+ event, range, logConfig) {
80169
+ const maxRetries = logConfig.retryOnFailure
80170
+ ? logConfig.maxRetries
80171
+ : 0;
80172
+ let lastError;
80173
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
80174
+ try {
80175
+ const logs = await client.getLogs({
80176
+ address: address,
80177
+ event,
80178
+ fromBlock: range.fromBlock,
80179
+ toBlock: range.toBlock,
80180
+ });
80181
+ return logs;
80182
+ }
80183
+ catch (error) {
80184
+ lastError = error instanceof Error ? error : new Error(String(error));
80185
+ if (attempt < maxRetries) {
80186
+ const delay = logConfig.retryBaseDelayMs * Math.pow(2, attempt);
80187
+ this.logger.warn(`Log fetch failed, retrying in ${delay}ms (attempt ${attempt + 1}/${maxRetries})`, { error: lastError.message, range });
80188
+ await this.sleep(delay);
80189
+ }
80190
+ }
80191
+ }
80192
+ throw lastError;
80193
+ }
80194
+ /**
80195
+ * Helper to add delay between requests
80196
+ */
80197
+ sleep(ms) {
80198
+ return new Promise((resolve) => setTimeout(resolve, ms));
80199
+ }
77428
80200
  getClientForChain(chainId) {
77429
80201
  const client = this.clients.get(chainId);
77430
80202
  if (!client) {
@@ -77433,12 +80205,20 @@ class DataService {
77433
80205
  return client;
77434
80206
  }
77435
80207
  getConfigForChain(chainId) {
77436
- const config = this.chainConfigs.find(c => c.chainId === chainId);
80208
+ const config = this.chainConfigs.find((c) => c.chainId === chainId);
77437
80209
  if (!config) {
77438
80210
  throw DataError.chainNotConfigured(chainId);
77439
80211
  }
77440
80212
  return config;
77441
80213
  }
80214
+ getLogFetchConfigForChain(chainId) {
80215
+ const config = this.logFetchConfigs.get(chainId);
80216
+ if (!config) {
80217
+ // Fallback to default if not found (shouldn't happen if constructor is correct)
80218
+ return DEFAULT_LOG_FETCH_CONFIG;
80219
+ }
80220
+ return config;
80221
+ }
77442
80222
  }
77443
80223
 
77444
- export { AccountService as A, BlockchainProvider as B, CommitmentService as C, DataService as D, ErrorCode as E, FetchArtifact as F, InvalidRpcUrl as I, PrivacyPoolSDK as P, SDKError as S, WithdrawalService as W, generateDepositSecrets as a, generateWithdrawalSecrets as b, getCommitment as c, generateMerkleProof as d, bigintToHash as e, bigintToHex as f, generateMasterKeys as g, hashPrecommitment as h, calculateContext as i, Circuits as j, ContractInteractionsService as k, ProofError as l, ContractError as m, AccountError as n, CircuitName as o };
80224
+ export { AccountService as A, BlockchainProvider as B, CommitmentService as C, DataService as D, ErrorCode as E, FetchArtifact as F, InvalidRpcUrl as I, PrivacyPoolSDK as P, SDKError as S, WithdrawalService as W, DEFAULT_LOG_FETCH_CONFIG as a, generateDepositSecrets as b, generateWithdrawalSecrets as c, getCommitment as d, generateMerkleProof as e, bigintToHash as f, generateMasterKeys as g, hashPrecommitment as h, bigintToHex as i, calculateContext as j, Circuits as k, ContractInteractionsService as l, ProofError as m, ContractError as n, AccountError as o, CircuitName as p };