@naturalcycles/js-lib 14.68.0 → 14.69.0

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.
package/dist/index.d.ts CHANGED
@@ -56,5 +56,6 @@ import { _gb, _hb, _kb, _mb } from './unit/size.util';
56
56
  import { is } from './vendor/is';
57
57
  import { CommonLogLevel, CommonLogFunction, CommonLogger, commonLoggerMinLevel, commonLoggerNoop, commonLogLevelNumber, commonLoggerPipe, commonLoggerPrefix } from './log/commonLogger';
58
58
  import { _safeJsonStringify } from './string/safeJsonStringify';
59
- export type { MemoCache, PromiseDecoratorCfg, PromiseDecoratorResp, ErrorData, ErrorObject, HttpErrorData, HttpErrorResponse, Admin401ErrorData, Admin403ErrorData, StringMap, PromiseMap, AnyObject, AnyFunction, ValuesOf, ValueOf, KeyValueTuple, ObjectMapper, ObjectPredicate, InstanceId, IsoDate, IsoDateTime, Reviver, PMapOptions, Mapper, AsyncMapper, Predicate, AsyncPredicate, BatchResult, DeferredPromise, PRetryOptions, PTimeoutOptions, TryCatchOptions, StringifyAnyOptions, JsonStringifyFunction, Merge, ReadonlyDeep, Promisable, PromiseValue, Simplify, ConditionalPick, ConditionalExcept, Class, UnixTimestamp, BaseDBEntity, SavedDBEntity, Saved, Unsaved, CreatedUpdated, CreatedUpdatedId, ObjectWithId, AnyObjectWithId, JsonSchema, JsonSchemaAny, JsonSchemaOneOf, JsonSchemaAllOf, JsonSchemaAnyOf, JsonSchemaNot, JsonSchemaRef, JsonSchemaConst, JsonSchemaEnum, JsonSchemaString, JsonSchemaNumber, JsonSchemaBoolean, JsonSchemaNull, JsonSchemaRootObject, JsonSchemaObject, JsonSchemaArray, JsonSchemaTuple, JsonSchemaBuilder, CommonLogLevel, CommonLogFunction, CommonLogger, };
60
- export { is, _Memo, _memoFn, _LogMethod, _getArgsSignature, _createPromiseDecorator, AppError, HttpError, AssertionError, _isErrorObject, _isHttpErrorObject, _isHttpErrorResponse, _assert, _assertEquals, _assertDeepEquals, _assertIsError, _assertIsString, _assertIsNumber, _assertTypeOf, _randomInt, _randomArrayItem, _createDeterministicRandom, _inRange, _stringMapValues, _stringMapEntries, _objectKeys, _capitalize, _upperFirst, _lowerFirst, _split, _removeWhitespace, _substringBefore, _substringBeforeLast, _substringAfter, _substringAfterLast, _substringBetweenLast, _replaceAll, _nl2br, _truncate, _truncateMiddle, _pick, _omit, _filterFalsyValues, _filterUndefinedValues, _filterNullishValues, _filterEmptyArrays, _filterEmptyValues, _filterObject, _undefinedIfEmpty, _isObject, _isPrimitive, _mapKeys, _mapValues, _mapObject, _objectNullValuesToUndefined, _deepEquals, _deepCopy, _isEmptyObject, _isEmpty, _merge, _deepTrim, _sortObjectDeep, _sortObject, _get, _set, _has, _unset, _mask, _invert, _invertMap, _by, _groupBy, _sortBy, _sortNumbers, _toFixed, _toPrecision, _round, _findLast, _takeWhile, _takeRightWhile, _dropWhile, _dropRightWhile, _countBy, _intersection, _difference, _shuffle, _mapToObject, _findKeyByValue, _anyToError, _anyToErrorObject, _errorToErrorObject, _errorObjectToAppError, _range, _uniq, _uniqBy, _flatten, _flattenDeep, _chunk, SimpleMovingAverage, _average, _averageWeighted, _percentile, _median, _debounce, _throttle, _Debounce, _Throttle, pMap, _passthroughMapper, _passUndefinedMapper, _passthroughPredicate, _passNothingPredicate, _noop, pBatch, ErrorMode, pFilter, pProps, pDelay, pDefer, pHang, pState, AggregatedError, pRetry, pTimeout, pTuple, _Retry, _Timeout, _tryCatch, _TryCatch, _try, pTry, _jsonParseIfPossible, _stringifyAny, _ms, _since, _hb, _gb, _mb, _kb, _snakeCase, _camelCase, _kebabCase, _sum, _sumBy, _clamp, _last, mergeJsonSchemaObjects, jsonSchema, JsonSchemaAnyBuilder, JSON_SCHEMA_ORDER, generateJsonSchemaFromData, _parseQueryString, _defineLazyProperty, _defineLazyProps, _lazyValue, commonLoggerMinLevel, commonLoggerNoop, commonLogLevelNumber, commonLoggerPipe, commonLoggerPrefix, _safeJsonStringify, };
59
+ import { PQueue, PQueueCfg } from './promise/pQueue';
60
+ export type { PQueueCfg, MemoCache, PromiseDecoratorCfg, PromiseDecoratorResp, ErrorData, ErrorObject, HttpErrorData, HttpErrorResponse, Admin401ErrorData, Admin403ErrorData, StringMap, PromiseMap, AnyObject, AnyFunction, ValuesOf, ValueOf, KeyValueTuple, ObjectMapper, ObjectPredicate, InstanceId, IsoDate, IsoDateTime, Reviver, PMapOptions, Mapper, AsyncMapper, Predicate, AsyncPredicate, BatchResult, DeferredPromise, PRetryOptions, PTimeoutOptions, TryCatchOptions, StringifyAnyOptions, JsonStringifyFunction, Merge, ReadonlyDeep, Promisable, PromiseValue, Simplify, ConditionalPick, ConditionalExcept, Class, UnixTimestamp, BaseDBEntity, SavedDBEntity, Saved, Unsaved, CreatedUpdated, CreatedUpdatedId, ObjectWithId, AnyObjectWithId, JsonSchema, JsonSchemaAny, JsonSchemaOneOf, JsonSchemaAllOf, JsonSchemaAnyOf, JsonSchemaNot, JsonSchemaRef, JsonSchemaConst, JsonSchemaEnum, JsonSchemaString, JsonSchemaNumber, JsonSchemaBoolean, JsonSchemaNull, JsonSchemaRootObject, JsonSchemaObject, JsonSchemaArray, JsonSchemaTuple, JsonSchemaBuilder, CommonLogLevel, CommonLogFunction, CommonLogger, };
61
+ export { is, _Memo, _memoFn, _LogMethod, _getArgsSignature, _createPromiseDecorator, AppError, HttpError, AssertionError, _isErrorObject, _isHttpErrorObject, _isHttpErrorResponse, _assert, _assertEquals, _assertDeepEquals, _assertIsError, _assertIsString, _assertIsNumber, _assertTypeOf, _randomInt, _randomArrayItem, _createDeterministicRandom, _inRange, _stringMapValues, _stringMapEntries, _objectKeys, _capitalize, _upperFirst, _lowerFirst, _split, _removeWhitespace, _substringBefore, _substringBeforeLast, _substringAfter, _substringAfterLast, _substringBetweenLast, _replaceAll, _nl2br, _truncate, _truncateMiddle, _pick, _omit, _filterFalsyValues, _filterUndefinedValues, _filterNullishValues, _filterEmptyArrays, _filterEmptyValues, _filterObject, _undefinedIfEmpty, _isObject, _isPrimitive, _mapKeys, _mapValues, _mapObject, _objectNullValuesToUndefined, _deepEquals, _deepCopy, _isEmptyObject, _isEmpty, _merge, _deepTrim, _sortObjectDeep, _sortObject, _get, _set, _has, _unset, _mask, _invert, _invertMap, _by, _groupBy, _sortBy, _sortNumbers, _toFixed, _toPrecision, _round, _findLast, _takeWhile, _takeRightWhile, _dropWhile, _dropRightWhile, _countBy, _intersection, _difference, _shuffle, _mapToObject, _findKeyByValue, _anyToError, _anyToErrorObject, _errorToErrorObject, _errorObjectToAppError, _range, _uniq, _uniqBy, _flatten, _flattenDeep, _chunk, SimpleMovingAverage, _average, _averageWeighted, _percentile, _median, _debounce, _throttle, _Debounce, _Throttle, pMap, _passthroughMapper, _passUndefinedMapper, _passthroughPredicate, _passNothingPredicate, _noop, pBatch, ErrorMode, pFilter, pProps, pDelay, pDefer, pHang, pState, AggregatedError, pRetry, pTimeout, pTuple, _Retry, _Timeout, _tryCatch, _TryCatch, _try, pTry, _jsonParseIfPossible, _stringifyAny, _ms, _since, _hb, _gb, _mb, _kb, _snakeCase, _camelCase, _kebabCase, _sum, _sumBy, _clamp, _last, mergeJsonSchemaObjects, jsonSchema, JsonSchemaAnyBuilder, JSON_SCHEMA_ORDER, generateJsonSchemaFromData, _parseQueryString, _defineLazyProperty, _defineLazyProps, _lazyValue, commonLoggerMinLevel, commonLoggerNoop, commonLogLevelNumber, commonLoggerPipe, commonLoggerPrefix, _safeJsonStringify, PQueue, };
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports._isObject = exports._undefinedIfEmpty = exports._filterObject = exports._filterEmptyValues = exports._filterEmptyArrays = exports._filterNullishValues = exports._filterUndefinedValues = exports._filterFalsyValues = exports._omit = exports._pick = exports._truncateMiddle = exports._truncate = exports._nl2br = exports._replaceAll = exports._substringBetweenLast = exports._substringAfterLast = exports._substringAfter = exports._substringBeforeLast = exports._substringBefore = exports._removeWhitespace = exports._split = exports._lowerFirst = exports._upperFirst = exports._capitalize = exports._objectKeys = exports._stringMapEntries = exports._stringMapValues = exports._inRange = exports._createDeterministicRandom = exports._randomArrayItem = exports._randomInt = exports._assertTypeOf = exports._assertIsNumber = exports._assertIsString = exports._assertIsError = exports._assertDeepEquals = exports._assertEquals = exports._assert = exports._isHttpErrorResponse = exports._isHttpErrorObject = exports._isErrorObject = exports.AssertionError = exports.HttpError = exports.AppError = exports._createPromiseDecorator = exports._getArgsSignature = exports._LogMethod = exports._memoFn = exports._Memo = exports.is = void 0;
4
4
  exports._average = exports.SimpleMovingAverage = exports._chunk = exports._flattenDeep = exports._flatten = exports._uniqBy = exports._uniq = exports._range = exports._errorObjectToAppError = exports._errorToErrorObject = exports._anyToErrorObject = exports._anyToError = exports._findKeyByValue = exports._mapToObject = exports._shuffle = exports._difference = exports._intersection = exports._countBy = exports._dropRightWhile = exports._dropWhile = exports._takeRightWhile = exports._takeWhile = exports._findLast = exports._round = exports._toPrecision = exports._toFixed = exports._sortNumbers = exports._sortBy = exports._groupBy = exports._by = exports._invertMap = exports._invert = exports._mask = exports._unset = exports._has = exports._set = exports._get = exports._sortObject = exports._sortObjectDeep = exports._deepTrim = exports._merge = exports._isEmpty = exports._isEmptyObject = exports._deepCopy = exports._deepEquals = exports._objectNullValuesToUndefined = exports._mapObject = exports._mapValues = exports._mapKeys = exports._isPrimitive = void 0;
5
5
  exports.JSON_SCHEMA_ORDER = exports.JsonSchemaAnyBuilder = exports.jsonSchema = exports.mergeJsonSchemaObjects = exports._last = exports._clamp = exports._sumBy = exports._sum = exports._kebabCase = exports._camelCase = exports._snakeCase = exports._kb = exports._mb = exports._gb = exports._hb = exports._since = exports._ms = exports._stringifyAny = exports._jsonParseIfPossible = exports.pTry = exports._try = exports._TryCatch = exports._tryCatch = exports._Timeout = exports._Retry = exports.pTuple = exports.pTimeout = exports.pRetry = exports.AggregatedError = exports.pState = exports.pHang = exports.pDefer = exports.pDelay = exports.pProps = exports.pFilter = exports.ErrorMode = exports.pBatch = exports._noop = exports._passNothingPredicate = exports._passthroughPredicate = exports._passUndefinedMapper = exports._passthroughMapper = exports.pMap = exports._Throttle = exports._Debounce = exports._throttle = exports._debounce = exports._median = exports._percentile = exports._averageWeighted = void 0;
6
- exports._safeJsonStringify = exports.commonLoggerPrefix = exports.commonLoggerPipe = exports.commonLogLevelNumber = exports.commonLoggerNoop = exports.commonLoggerMinLevel = exports._lazyValue = exports._defineLazyProps = exports._defineLazyProperty = exports._parseQueryString = exports.generateJsonSchemaFromData = void 0;
6
+ exports.PQueue = exports._safeJsonStringify = exports.commonLoggerPrefix = exports.commonLoggerPipe = exports.commonLogLevelNumber = exports.commonLoggerNoop = exports.commonLoggerMinLevel = exports._lazyValue = exports._defineLazyProps = exports._defineLazyProperty = exports._parseQueryString = exports.generateJsonSchemaFromData = void 0;
7
7
  const array_util_1 = require("./array/array.util");
8
8
  Object.defineProperty(exports, "_by", { enumerable: true, get: function () { return array_util_1._by; } });
9
9
  Object.defineProperty(exports, "_chunk", { enumerable: true, get: function () { return array_util_1._chunk; } });
@@ -219,3 +219,5 @@ Object.defineProperty(exports, "commonLoggerPipe", { enumerable: true, get: func
219
219
  Object.defineProperty(exports, "commonLoggerPrefix", { enumerable: true, get: function () { return commonLogger_1.commonLoggerPrefix; } });
220
220
  const safeJsonStringify_1 = require("./string/safeJsonStringify");
221
221
  Object.defineProperty(exports, "_safeJsonStringify", { enumerable: true, get: function () { return safeJsonStringify_1._safeJsonStringify; } });
222
+ const pQueue_1 = require("./promise/pQueue");
223
+ Object.defineProperty(exports, "PQueue", { enumerable: true, get: function () { return pQueue_1.PQueue; } });
@@ -0,0 +1,43 @@
1
+ import { CommonLogger } from '../log/commonLogger';
2
+ export interface PQueueCfg {
3
+ concurrency: number;
4
+ /**
5
+ * Default: THROW_IMMEDIATELY
6
+ */
7
+ /**
8
+ * @default true
9
+ */
10
+ /**
11
+ * Default to `console`
12
+ */
13
+ logger?: CommonLogger;
14
+ /**
15
+ * If true - will LOG EVERYTHING:)
16
+ */
17
+ debug?: boolean;
18
+ }
19
+ export declare type PromiseReturningFunction = () => Promise<any>;
20
+ /**
21
+ * Inspired by: https://github.com/sindresorhus/p-queue
22
+ *
23
+ * Allows to push "jobs" to the queue and control its concurrency.
24
+ * Jobs are "promise-returning functions".
25
+ *
26
+ * API is @experimental
27
+ */
28
+ export declare class PQueue {
29
+ constructor(cfg: PQueueCfg);
30
+ private readonly cfg;
31
+ private debug;
32
+ inFlight: number;
33
+ private queue;
34
+ private onIdleListeners;
35
+ get queueSize(): number;
36
+ /**
37
+ * Returns a Promise that resolves when the queue is Idle (next time, since the call).
38
+ * Resolves immediately in case the queue is Idle.
39
+ * Idle means 0 queue and 0 inFlight.
40
+ */
41
+ onIdle(): Promise<void>;
42
+ push(fn: PromiseReturningFunction): void;
43
+ }
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PQueue = void 0;
4
+ const pDefer_1 = require("./pDefer");
5
+ /**
6
+ * Inspired by: https://github.com/sindresorhus/p-queue
7
+ *
8
+ * Allows to push "jobs" to the queue and control its concurrency.
9
+ * Jobs are "promise-returning functions".
10
+ *
11
+ * API is @experimental
12
+ */
13
+ class PQueue {
14
+ constructor(cfg) {
15
+ this.inFlight = 0;
16
+ this.queue = [];
17
+ this.onIdleListeners = [];
18
+ this.cfg = {
19
+ // concurrency: Number.MAX_SAFE_INTEGER,
20
+ logger: console,
21
+ debug: false,
22
+ ...cfg,
23
+ };
24
+ if (!cfg.debug) {
25
+ this.debug = () => { };
26
+ }
27
+ }
28
+ debug(...args) {
29
+ this.cfg.logger.log(...args);
30
+ }
31
+ get queueSize() {
32
+ return this.queue.length;
33
+ }
34
+ /**
35
+ * Returns a Promise that resolves when the queue is Idle (next time, since the call).
36
+ * Resolves immediately in case the queue is Idle.
37
+ * Idle means 0 queue and 0 inFlight.
38
+ */
39
+ onIdle() {
40
+ if (this.queue.length === 0)
41
+ return Promise.resolve();
42
+ const listener = (0, pDefer_1.pDefer)();
43
+ this.onIdleListeners.push(listener);
44
+ return listener;
45
+ }
46
+ push(fn) {
47
+ const { concurrency } = this.cfg;
48
+ if (this.inFlight < concurrency) {
49
+ // There is room for more jobs. Can start immediately
50
+ this.inFlight++;
51
+ this.debug(`inFlight++ ${this.inFlight}/${concurrency}, queue ${this.queue.length}`);
52
+ fn()
53
+ .catch(err => {
54
+ this.cfg.logger.error(err);
55
+ })
56
+ .finally(() => {
57
+ this.inFlight--;
58
+ this.debug(`inFlight-- ${this.inFlight}/${concurrency}, queue ${this.queue.length}`);
59
+ // check if there's room to start next job
60
+ if (this.queue.length && this.inFlight <= concurrency) {
61
+ const nextFn = this.queue.shift();
62
+ this.push(nextFn);
63
+ }
64
+ else {
65
+ if (this.inFlight === 0) {
66
+ this.debug('onIdle');
67
+ this.onIdleListeners.forEach(defer => defer.resolve());
68
+ this.onIdleListeners.length = 0; // empty the array
69
+ }
70
+ }
71
+ });
72
+ }
73
+ else {
74
+ this.queue.push(fn);
75
+ this.debug(`inFlight ${this.inFlight}/${concurrency}, queue++ ${this.queue.length}`);
76
+ }
77
+ }
78
+ }
79
+ exports.PQueue = PQueue;
@@ -1,3 +1,4 @@
1
+ import { AnyFunction } from '../types';
1
2
  export interface PTimeoutOptions {
2
3
  /**
3
4
  * Timeout in milliseconds.
@@ -19,4 +20,4 @@ export interface PTimeoutOptions {
19
20
  * Throws an Error if the Function is not resolved in a certain time.
20
21
  * If the Function rejects - passes this rejection further.
21
22
  */
22
- export declare function pTimeout<T extends Function>(fn: T, opt: PTimeoutOptions): T;
23
+ export declare function pTimeout<T extends AnyFunction>(fn: T, opt: PTimeoutOptions): T;
@@ -6,7 +6,6 @@ exports.pTimeout = void 0;
6
6
  * Throws an Error if the Function is not resolved in a certain time.
7
7
  * If the Function rejects - passes this rejection further.
8
8
  */
9
- // eslint-disable-next-line @typescript-eslint/ban-types
10
9
  function pTimeout(fn, opt) {
11
10
  // const fname = fn.name || 'function'
12
11
  const { timeout, name, onTimeout } = opt;
package/dist-esm/index.js CHANGED
@@ -52,4 +52,5 @@ import { _gb, _hb, _kb, _mb } from './unit/size.util';
52
52
  import { is } from './vendor/is';
53
53
  import { commonLoggerMinLevel, commonLoggerNoop, commonLogLevelNumber, commonLoggerPipe, commonLoggerPrefix, } from './log/commonLogger';
54
54
  import { _safeJsonStringify } from './string/safeJsonStringify';
55
- export { is, _Memo, _memoFn, _LogMethod, _getArgsSignature, _createPromiseDecorator, AppError, HttpError, AssertionError, _isErrorObject, _isHttpErrorObject, _isHttpErrorResponse, _assert, _assertEquals, _assertDeepEquals, _assertIsError, _assertIsString, _assertIsNumber, _assertTypeOf, _randomInt, _randomArrayItem, _createDeterministicRandom, _inRange, _stringMapValues, _stringMapEntries, _objectKeys, _capitalize, _upperFirst, _lowerFirst, _split, _removeWhitespace, _substringBefore, _substringBeforeLast, _substringAfter, _substringAfterLast, _substringBetweenLast, _replaceAll, _nl2br, _truncate, _truncateMiddle, _pick, _omit, _filterFalsyValues, _filterUndefinedValues, _filterNullishValues, _filterEmptyArrays, _filterEmptyValues, _filterObject, _undefinedIfEmpty, _isObject, _isPrimitive, _mapKeys, _mapValues, _mapObject, _objectNullValuesToUndefined, _deepEquals, _deepCopy, _isEmptyObject, _isEmpty, _merge, _deepTrim, _sortObjectDeep, _sortObject, _get, _set, _has, _unset, _mask, _invert, _invertMap, _by, _groupBy, _sortBy, _sortNumbers, _toFixed, _toPrecision, _round, _findLast, _takeWhile, _takeRightWhile, _dropWhile, _dropRightWhile, _countBy, _intersection, _difference, _shuffle, _mapToObject, _findKeyByValue, _anyToError, _anyToErrorObject, _errorToErrorObject, _errorObjectToAppError, _range, _uniq, _uniqBy, _flatten, _flattenDeep, _chunk, SimpleMovingAverage, _average, _averageWeighted, _percentile, _median, _debounce, _throttle, _Debounce, _Throttle, pMap, _passthroughMapper, _passUndefinedMapper, _passthroughPredicate, _passNothingPredicate, _noop, pBatch, ErrorMode, pFilter, pProps, pDelay, pDefer, pHang, pState, AggregatedError, pRetry, pTimeout, pTuple, _Retry, _Timeout, _tryCatch, _TryCatch, _try, pTry, _jsonParseIfPossible, _stringifyAny, _ms, _since, _hb, _gb, _mb, _kb, _snakeCase, _camelCase, _kebabCase, _sum, _sumBy, _clamp, _last, mergeJsonSchemaObjects, jsonSchema, JsonSchemaAnyBuilder, JSON_SCHEMA_ORDER, generateJsonSchemaFromData, _parseQueryString, _defineLazyProperty, _defineLazyProps, _lazyValue, commonLoggerMinLevel, commonLoggerNoop, commonLogLevelNumber, commonLoggerPipe, commonLoggerPrefix, _safeJsonStringify, };
55
+ import { PQueue } from './promise/pQueue';
56
+ export { is, _Memo, _memoFn, _LogMethod, _getArgsSignature, _createPromiseDecorator, AppError, HttpError, AssertionError, _isErrorObject, _isHttpErrorObject, _isHttpErrorResponse, _assert, _assertEquals, _assertDeepEquals, _assertIsError, _assertIsString, _assertIsNumber, _assertTypeOf, _randomInt, _randomArrayItem, _createDeterministicRandom, _inRange, _stringMapValues, _stringMapEntries, _objectKeys, _capitalize, _upperFirst, _lowerFirst, _split, _removeWhitespace, _substringBefore, _substringBeforeLast, _substringAfter, _substringAfterLast, _substringBetweenLast, _replaceAll, _nl2br, _truncate, _truncateMiddle, _pick, _omit, _filterFalsyValues, _filterUndefinedValues, _filterNullishValues, _filterEmptyArrays, _filterEmptyValues, _filterObject, _undefinedIfEmpty, _isObject, _isPrimitive, _mapKeys, _mapValues, _mapObject, _objectNullValuesToUndefined, _deepEquals, _deepCopy, _isEmptyObject, _isEmpty, _merge, _deepTrim, _sortObjectDeep, _sortObject, _get, _set, _has, _unset, _mask, _invert, _invertMap, _by, _groupBy, _sortBy, _sortNumbers, _toFixed, _toPrecision, _round, _findLast, _takeWhile, _takeRightWhile, _dropWhile, _dropRightWhile, _countBy, _intersection, _difference, _shuffle, _mapToObject, _findKeyByValue, _anyToError, _anyToErrorObject, _errorToErrorObject, _errorObjectToAppError, _range, _uniq, _uniqBy, _flatten, _flattenDeep, _chunk, SimpleMovingAverage, _average, _averageWeighted, _percentile, _median, _debounce, _throttle, _Debounce, _Throttle, pMap, _passthroughMapper, _passUndefinedMapper, _passthroughPredicate, _passNothingPredicate, _noop, pBatch, ErrorMode, pFilter, pProps, pDelay, pDefer, pHang, pState, AggregatedError, pRetry, pTimeout, pTuple, _Retry, _Timeout, _tryCatch, _TryCatch, _try, pTry, _jsonParseIfPossible, _stringifyAny, _ms, _since, _hb, _gb, _mb, _kb, _snakeCase, _camelCase, _kebabCase, _sum, _sumBy, _clamp, _last, mergeJsonSchemaObjects, jsonSchema, JsonSchemaAnyBuilder, JSON_SCHEMA_ORDER, generateJsonSchemaFromData, _parseQueryString, _defineLazyProperty, _defineLazyProps, _lazyValue, commonLoggerMinLevel, commonLoggerNoop, commonLogLevelNumber, commonLoggerPipe, commonLoggerPrefix, _safeJsonStringify, PQueue, };
@@ -0,0 +1,72 @@
1
+ import { pDefer } from './pDefer';
2
+ /**
3
+ * Inspired by: https://github.com/sindresorhus/p-queue
4
+ *
5
+ * Allows to push "jobs" to the queue and control its concurrency.
6
+ * Jobs are "promise-returning functions".
7
+ *
8
+ * API is @experimental
9
+ */
10
+ export class PQueue {
11
+ constructor(cfg) {
12
+ this.inFlight = 0;
13
+ this.queue = [];
14
+ this.onIdleListeners = [];
15
+ this.cfg = Object.assign({
16
+ // concurrency: Number.MAX_SAFE_INTEGER,
17
+ logger: console, debug: false }, cfg);
18
+ if (!cfg.debug) {
19
+ this.debug = () => { };
20
+ }
21
+ }
22
+ debug(...args) {
23
+ this.cfg.logger.log(...args);
24
+ }
25
+ get queueSize() {
26
+ return this.queue.length;
27
+ }
28
+ /**
29
+ * Returns a Promise that resolves when the queue is Idle (next time, since the call).
30
+ * Resolves immediately in case the queue is Idle.
31
+ * Idle means 0 queue and 0 inFlight.
32
+ */
33
+ onIdle() {
34
+ if (this.queue.length === 0)
35
+ return Promise.resolve();
36
+ const listener = pDefer();
37
+ this.onIdleListeners.push(listener);
38
+ return listener;
39
+ }
40
+ push(fn) {
41
+ const { concurrency } = this.cfg;
42
+ if (this.inFlight < concurrency) {
43
+ // There is room for more jobs. Can start immediately
44
+ this.inFlight++;
45
+ this.debug(`inFlight++ ${this.inFlight}/${concurrency}, queue ${this.queue.length}`);
46
+ fn()
47
+ .catch(err => {
48
+ this.cfg.logger.error(err);
49
+ })
50
+ .finally(() => {
51
+ this.inFlight--;
52
+ this.debug(`inFlight-- ${this.inFlight}/${concurrency}, queue ${this.queue.length}`);
53
+ // check if there's room to start next job
54
+ if (this.queue.length && this.inFlight <= concurrency) {
55
+ const nextFn = this.queue.shift();
56
+ this.push(nextFn);
57
+ }
58
+ else {
59
+ if (this.inFlight === 0) {
60
+ this.debug('onIdle');
61
+ this.onIdleListeners.forEach(defer => defer.resolve());
62
+ this.onIdleListeners.length = 0; // empty the array
63
+ }
64
+ }
65
+ });
66
+ }
67
+ else {
68
+ this.queue.push(fn);
69
+ this.debug(`inFlight ${this.inFlight}/${concurrency}, queue++ ${this.queue.length}`);
70
+ }
71
+ }
72
+ }
@@ -3,7 +3,6 @@
3
3
  * Throws an Error if the Function is not resolved in a certain time.
4
4
  * If the Function rejects - passes this rejection further.
5
5
  */
6
- // eslint-disable-next-line @typescript-eslint/ban-types
7
6
  export function pTimeout(fn, opt) {
8
7
  // const fname = fn.name || 'function'
9
8
  const { timeout, name, onTimeout } = opt;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naturalcycles/js-lib",
3
- "version": "14.68.0",
3
+ "version": "14.69.0",
4
4
  "scripts": {
5
5
  "prepare": "husky install",
6
6
  "build-prod": "build-prod-esm-cjs",
package/src/index.ts CHANGED
@@ -235,8 +235,10 @@ import {
235
235
  commonLoggerPrefix,
236
236
  } from './log/commonLogger'
237
237
  import { _safeJsonStringify } from './string/safeJsonStringify'
238
+ import { PQueue, PQueueCfg } from './promise/pQueue'
238
239
 
239
240
  export type {
241
+ PQueueCfg,
240
242
  MemoCache,
241
243
  PromiseDecoratorCfg,
242
244
  PromiseDecoratorResp,
@@ -473,4 +475,5 @@ export {
473
475
  commonLoggerPipe,
474
476
  commonLoggerPrefix,
475
477
  _safeJsonStringify,
478
+ PQueue,
476
479
  }
@@ -0,0 +1,117 @@
1
+ import { CommonLogger } from '../log/commonLogger'
2
+ import { DeferredPromise, pDefer } from './pDefer'
3
+
4
+ export interface PQueueCfg {
5
+ concurrency: number
6
+
7
+ /**
8
+ * Default: THROW_IMMEDIATELY
9
+ */
10
+ // errorMode?: ErrorMode
11
+
12
+ /**
13
+ * @default true
14
+ */
15
+ // autoStart?: boolean
16
+
17
+ /**
18
+ * Default to `console`
19
+ */
20
+ logger?: CommonLogger
21
+
22
+ /**
23
+ * If true - will LOG EVERYTHING:)
24
+ */
25
+ debug?: boolean
26
+
27
+ // logStatusChange?: boolean
28
+ // logSizeChange?: boolean
29
+
30
+ // timeout
31
+ }
32
+
33
+ export type PromiseReturningFunction = () => Promise<any>
34
+
35
+ /**
36
+ * Inspired by: https://github.com/sindresorhus/p-queue
37
+ *
38
+ * Allows to push "jobs" to the queue and control its concurrency.
39
+ * Jobs are "promise-returning functions".
40
+ *
41
+ * API is @experimental
42
+ */
43
+ export class PQueue {
44
+ constructor(cfg: PQueueCfg) {
45
+ this.cfg = {
46
+ // concurrency: Number.MAX_SAFE_INTEGER,
47
+ logger: console,
48
+ debug: false,
49
+ ...cfg,
50
+ }
51
+
52
+ if (!cfg.debug) {
53
+ this.debug = () => {}
54
+ }
55
+ }
56
+
57
+ private readonly cfg: Required<PQueueCfg>
58
+
59
+ private debug(...args: any[]): void {
60
+ this.cfg.logger.log(...args)
61
+ }
62
+
63
+ inFlight = 0
64
+ private queue: PromiseReturningFunction[] = []
65
+ private onIdleListeners: DeferredPromise[] = []
66
+
67
+ get queueSize(): number {
68
+ return this.queue.length
69
+ }
70
+
71
+ /**
72
+ * Returns a Promise that resolves when the queue is Idle (next time, since the call).
73
+ * Resolves immediately in case the queue is Idle.
74
+ * Idle means 0 queue and 0 inFlight.
75
+ */
76
+ onIdle(): Promise<void> {
77
+ if (this.queue.length === 0) return Promise.resolve()
78
+
79
+ const listener = pDefer()
80
+ this.onIdleListeners.push(listener)
81
+ return listener
82
+ }
83
+
84
+ push(fn: PromiseReturningFunction): void {
85
+ const { concurrency } = this.cfg
86
+
87
+ if (this.inFlight < concurrency) {
88
+ // There is room for more jobs. Can start immediately
89
+ this.inFlight++
90
+ this.debug(`inFlight++ ${this.inFlight}/${concurrency}, queue ${this.queue.length}`)
91
+
92
+ fn()
93
+ .catch(err => {
94
+ this.cfg.logger.error(err)
95
+ })
96
+ .finally(() => {
97
+ this.inFlight--
98
+ this.debug(`inFlight-- ${this.inFlight}/${concurrency}, queue ${this.queue.length}`)
99
+
100
+ // check if there's room to start next job
101
+ if (this.queue.length && this.inFlight <= concurrency) {
102
+ const nextFn = this.queue.shift()!
103
+ this.push(nextFn)
104
+ } else {
105
+ if (this.inFlight === 0) {
106
+ this.debug('onIdle')
107
+ this.onIdleListeners.forEach(defer => defer.resolve())
108
+ this.onIdleListeners.length = 0 // empty the array
109
+ }
110
+ }
111
+ })
112
+ } else {
113
+ this.queue.push(fn)
114
+ this.debug(`inFlight ${this.inFlight}/${concurrency}, queue++ ${this.queue.length}`)
115
+ }
116
+ }
117
+ }
@@ -1,3 +1,5 @@
1
+ import { AnyFunction } from '../types'
2
+
1
3
  export interface PTimeoutOptions {
2
4
  /**
3
5
  * Timeout in milliseconds.
@@ -22,8 +24,7 @@ export interface PTimeoutOptions {
22
24
  * Throws an Error if the Function is not resolved in a certain time.
23
25
  * If the Function rejects - passes this rejection further.
24
26
  */
25
- // eslint-disable-next-line @typescript-eslint/ban-types
26
- export function pTimeout<T extends Function>(fn: T, opt: PTimeoutOptions): T {
27
+ export function pTimeout<T extends AnyFunction>(fn: T, opt: PTimeoutOptions): T {
27
28
  // const fname = fn.name || 'function'
28
29
  const { timeout, name, onTimeout } = opt
29
30