@naturalcycles/js-lib 14.69.1 → 14.70.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.
@@ -1,4 +1,4 @@
1
- import { AppError, ErrorData, ErrorObject, HttpErrorData, HttpErrorResponse, StringifyAnyOptions } from '..';
1
+ import { AppError, ErrorData, ErrorObject, HttpErrorData, HttpErrorResponse, StringifyAnyOptions, Class } from '..';
2
2
  /**
3
3
  * Useful to ensure that error in `catch (err) { ... }`
4
4
  * is indeed an Error (and not e.g `string` or `undefined`).
@@ -7,7 +7,7 @@ import { AppError, ErrorData, ErrorObject, HttpErrorData, HttpErrorResponse, Str
7
7
  *
8
8
  * Alternatively, if you're sure it's Error - you can use `_assertIsError(err)`.
9
9
  */
10
- export declare function _anyToError(o: any, opt?: StringifyAnyOptions): Error;
10
+ export declare function _anyToError<ERROR_TYPE extends Error = Error>(o: any, errorClass?: Class<ERROR_TYPE>, opt?: StringifyAnyOptions): ERROR_TYPE;
11
11
  /**
12
12
  * Converts "anything" to ErrorObject.
13
13
  * Detects if it's HttpErrorResponse, HttpErrorObject, ErrorObject, Error, etc..
@@ -17,6 +17,10 @@ export declare function _anyToError(o: any, opt?: StringifyAnyOptions): Error;
17
17
  export declare function _anyToErrorObject<DATA_TYPE extends ErrorData = ErrorData>(o: any, opt?: StringifyAnyOptions): ErrorObject<DATA_TYPE>;
18
18
  export declare function _errorToErrorObject<DATA_TYPE extends ErrorData = ErrorData>(e: AppError<DATA_TYPE> | Error, includeErrorStack?: boolean): ErrorObject<DATA_TYPE>;
19
19
  export declare function _errorObjectToAppError<DATA_TYPE>(o: ErrorObject<DATA_TYPE>): AppError<DATA_TYPE>;
20
+ export declare function _errorObjectToError<DATA_TYPE, ERROR_TYPE extends Error>(o: ErrorObject<DATA_TYPE>, errorClass?: Class<ERROR_TYPE>): ERROR_TYPE;
20
21
  export declare function _isHttpErrorResponse(o: any): o is HttpErrorResponse;
21
22
  export declare function _isHttpErrorObject(o: any): o is ErrorObject<HttpErrorData>;
23
+ /**
24
+ * Note: any instance of AppError is also automatically an ErrorObject
25
+ */
22
26
  export declare function _isErrorObject(o: any): o is ErrorObject;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports._isErrorObject = exports._isHttpErrorObject = exports._isHttpErrorResponse = exports._errorObjectToAppError = exports._errorToErrorObject = exports._anyToErrorObject = exports._anyToError = void 0;
3
+ exports._isErrorObject = exports._isHttpErrorObject = exports._isHttpErrorResponse = exports._errorObjectToError = exports._errorObjectToAppError = exports._errorToErrorObject = exports._anyToErrorObject = exports._anyToError = void 0;
4
4
  const __1 = require("..");
5
5
  /**
6
6
  * Useful to ensure that error in `catch (err) { ... }`
@@ -10,13 +10,12 @@ const __1 = require("..");
10
10
  *
11
11
  * Alternatively, if you're sure it's Error - you can use `_assertIsError(err)`.
12
12
  */
13
- function _anyToError(o, opt) {
14
- if (o instanceof Error) {
15
- // Already an Error - return as-is
13
+ function _anyToError(o, errorClass = Error, opt) {
14
+ if (o instanceof errorClass)
16
15
  return o;
17
- }
18
- const message = (0, __1._stringifyAny)(o, opt);
19
- return new Error(message);
16
+ // If it's an instance of Error, but ErrorClass is something else (e.g AppError) - it'll be "repacked" into AppError
17
+ const errorObject = _isErrorObject(o) ? o : _anyToErrorObject(o, opt);
18
+ return _errorObjectToError(errorObject, errorClass);
20
19
  }
21
20
  exports._anyToError = _anyToError;
22
21
  /**
@@ -27,7 +26,7 @@ exports._anyToError = _anyToError;
27
26
  */
28
27
  function _anyToErrorObject(o, opt) {
29
28
  if (o instanceof Error) {
30
- return _errorToErrorObject(o, opt?.includeErrorStack);
29
+ return _errorToErrorObject(o, opt?.includeErrorStack ?? true);
31
30
  }
32
31
  o = (0, __1._jsonParseIfPossible)(o);
33
32
  if (_isHttpErrorResponse(o)) {
@@ -51,7 +50,7 @@ function _anyToErrorObject(o, opt) {
51
50
  };
52
51
  }
53
52
  exports._anyToErrorObject = _anyToErrorObject;
54
- function _errorToErrorObject(e, includeErrorStack = false) {
53
+ function _errorToErrorObject(e, includeErrorStack = true) {
55
54
  const obj = {
56
55
  name: e.name,
57
56
  message: e.message,
@@ -64,31 +63,46 @@ function _errorToErrorObject(e, includeErrorStack = false) {
64
63
  }
65
64
  exports._errorToErrorObject = _errorToErrorObject;
66
65
  function _errorObjectToAppError(o) {
67
- const err = Object.assign(new __1.AppError(o.message, o.data), {
66
+ return _errorObjectToError(o, __1.AppError);
67
+ }
68
+ exports._errorObjectToAppError = _errorObjectToAppError;
69
+ function _errorObjectToError(o, errorClass = Error) {
70
+ const err = new errorClass(o.message);
68
71
  // name: err.name, // cannot be assigned to a readonly property like this
69
72
  // stack: o.stack, // also readonly e.g in Firefox
70
- });
71
73
  Object.defineProperty(err, 'name', {
72
74
  value: o.name,
73
75
  configurable: true,
74
76
  });
75
- Object.defineProperty(err, 'stack', {
76
- value: o.stack,
77
+ Object.defineProperty(err, 'data', {
78
+ value: o.data,
79
+ writable: true,
80
+ configurable: true,
81
+ enumerable: false,
77
82
  });
83
+ if (o.stack) {
84
+ Object.defineProperty(err, 'stack', {
85
+ value: o.stack,
86
+ });
87
+ }
78
88
  return err;
79
89
  }
80
- exports._errorObjectToAppError = _errorObjectToAppError;
90
+ exports._errorObjectToError = _errorObjectToError;
81
91
  function _isHttpErrorResponse(o) {
82
92
  return _isHttpErrorObject(o?.error);
83
93
  }
84
94
  exports._isHttpErrorResponse = _isHttpErrorResponse;
85
95
  function _isHttpErrorObject(o) {
86
- return (typeof o?.name === 'string' &&
87
- typeof o?.message === 'string' &&
88
- typeof o?.data?.httpStatusCode === 'number');
96
+ return (!!o &&
97
+ typeof o.name === 'string' &&
98
+ typeof o.message === 'string' &&
99
+ typeof o.data?.httpStatusCode === 'number');
89
100
  }
90
101
  exports._isHttpErrorObject = _isHttpErrorObject;
102
+ /**
103
+ * Note: any instance of AppError is also automatically an ErrorObject
104
+ */
91
105
  function _isErrorObject(o) {
92
- return (typeof o?.name === 'string' && typeof o?.message === 'string' && typeof o?.data === 'object');
106
+ return (!!o && typeof o.name === 'string' && typeof o.message === 'string' && typeof o.data === 'object');
93
107
  }
94
108
  exports._isErrorObject = _isErrorObject;
package/dist/index.d.ts CHANGED
@@ -15,7 +15,7 @@ import { _Timeout } from './decorators/timeout.decorator';
15
15
  import { AppError } from './error/app.error';
16
16
  import { AssertionError, _assert, _assertDeepEquals, _assertEquals, _assertIsError, _assertIsNumber, _assertIsString, _assertTypeOf } from './error/assert';
17
17
  import { Admin401ErrorData, Admin403ErrorData, ErrorData, ErrorObject, HttpErrorData, HttpErrorResponse } from './error/error.model';
18
- import { _anyToError, _anyToErrorObject, _errorObjectToAppError, _errorToErrorObject, _isErrorObject, _isHttpErrorObject, _isHttpErrorResponse } from './error/error.util';
18
+ export * from './error/error.util';
19
19
  import { ErrorMode } from './error/errorMode';
20
20
  import { HttpError } from './error/http.error';
21
21
  import { _try, pTry } from './error/try';
@@ -54,8 +54,8 @@ import { Class, ConditionalExcept, ConditionalPick, Merge, Promisable, PromiseVa
54
54
  import { AsyncMapper, AsyncPredicate, BaseDBEntity, CreatedUpdated, CreatedUpdatedId, ObjectWithId, AnyObjectWithId, Saved, Unsaved, BatchResult, InstanceId, IsoDate, IsoDateTime, KeyValueTuple, Mapper, ObjectMapper, ObjectPredicate, Predicate, PromiseMap, AnyObject, AnyFunction, Reviver, SavedDBEntity, StringMap, UnixTimestamp, ValueOf, ValuesOf, _noop, _objectKeys, _passNothingPredicate, _passthroughMapper, _passthroughPredicate, _passUndefinedMapper, _stringMapEntries, _stringMapValues } from './types';
55
55
  import { _gb, _hb, _kb, _mb } from './unit/size.util';
56
56
  import { is } from './vendor/is';
57
- import { CommonLogLevel, CommonLogFunction, CommonLogger, commonLoggerMinLevel, commonLoggerNoop, commonLogLevelNumber, commonLoggerPipe, commonLoggerPrefix } from './log/commonLogger';
57
+ import { CommonLogLevel, CommonLogFunction, CommonLogger, commonLoggerMinLevel, commonLoggerNoop, commonLogLevelNumber, commonLoggerPipe, commonLoggerPrefix, CommonLogWithLevelFunction, commonLoggerCreate } from './log/commonLogger';
58
58
  import { _safeJsonStringify } from './string/safeJsonStringify';
59
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, };
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, CommonLogWithLevelFunction, CommonLogFunction, CommonLogger, };
61
+ export { is, _Memo, _memoFn, _LogMethod, _getArgsSignature, _createPromiseDecorator, AppError, HttpError, AssertionError, _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, _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, commonLoggerCreate, _safeJsonStringify, PQueue, };
package/dist/index.js CHANGED
@@ -1,9 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
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
- 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
- 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.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;
3
+ exports._mapValues = exports._mapKeys = exports._isPrimitive = 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.AssertionError = exports.HttpError = exports.AppError = exports._createPromiseDecorator = exports._getArgsSignature = exports._LogMethod = exports._memoFn = exports._Memo = exports.is = void 0;
4
+ exports._Throttle = exports._Debounce = exports._throttle = exports._debounce = exports._median = exports._percentile = exports._averageWeighted = exports._average = exports.SimpleMovingAverage = exports._chunk = exports._flattenDeep = exports._flatten = exports._uniqBy = exports._uniq = exports._range = 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 = void 0;
5
+ exports.commonLoggerNoop = exports.commonLoggerMinLevel = exports._lazyValue = exports._defineLazyProps = exports._defineLazyProperty = exports._parseQueryString = exports.generateJsonSchemaFromData = 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 = void 0;
6
+ exports.PQueue = exports._safeJsonStringify = exports.commonLoggerCreate = exports.commonLoggerPrefix = exports.commonLoggerPipe = exports.commonLogLevelNumber = void 0;
7
+ const tslib_1 = require("tslib");
7
8
  const array_util_1 = require("./array/array.util");
8
9
  Object.defineProperty(exports, "_by", { enumerable: true, get: function () { return array_util_1._by; } });
9
10
  Object.defineProperty(exports, "_chunk", { enumerable: true, get: function () { return array_util_1._chunk; } });
@@ -65,14 +66,7 @@ Object.defineProperty(exports, "_assertIsError", { enumerable: true, get: functi
65
66
  Object.defineProperty(exports, "_assertIsNumber", { enumerable: true, get: function () { return assert_1._assertIsNumber; } });
66
67
  Object.defineProperty(exports, "_assertIsString", { enumerable: true, get: function () { return assert_1._assertIsString; } });
67
68
  Object.defineProperty(exports, "_assertTypeOf", { enumerable: true, get: function () { return assert_1._assertTypeOf; } });
68
- const error_util_1 = require("./error/error.util");
69
- Object.defineProperty(exports, "_anyToError", { enumerable: true, get: function () { return error_util_1._anyToError; } });
70
- Object.defineProperty(exports, "_anyToErrorObject", { enumerable: true, get: function () { return error_util_1._anyToErrorObject; } });
71
- Object.defineProperty(exports, "_errorObjectToAppError", { enumerable: true, get: function () { return error_util_1._errorObjectToAppError; } });
72
- Object.defineProperty(exports, "_errorToErrorObject", { enumerable: true, get: function () { return error_util_1._errorToErrorObject; } });
73
- Object.defineProperty(exports, "_isErrorObject", { enumerable: true, get: function () { return error_util_1._isErrorObject; } });
74
- Object.defineProperty(exports, "_isHttpErrorObject", { enumerable: true, get: function () { return error_util_1._isHttpErrorObject; } });
75
- Object.defineProperty(exports, "_isHttpErrorResponse", { enumerable: true, get: function () { return error_util_1._isHttpErrorResponse; } });
69
+ (0, tslib_1.__exportStar)(require("./error/error.util"), exports);
76
70
  const errorMode_1 = require("./error/errorMode");
77
71
  Object.defineProperty(exports, "ErrorMode", { enumerable: true, get: function () { return errorMode_1.ErrorMode; } });
78
72
  const http_error_1 = require("./error/http.error");
@@ -217,6 +211,7 @@ Object.defineProperty(exports, "commonLoggerNoop", { enumerable: true, get: func
217
211
  Object.defineProperty(exports, "commonLogLevelNumber", { enumerable: true, get: function () { return commonLogger_1.commonLogLevelNumber; } });
218
212
  Object.defineProperty(exports, "commonLoggerPipe", { enumerable: true, get: function () { return commonLogger_1.commonLoggerPipe; } });
219
213
  Object.defineProperty(exports, "commonLoggerPrefix", { enumerable: true, get: function () { return commonLogger_1.commonLoggerPrefix; } });
214
+ Object.defineProperty(exports, "commonLoggerCreate", { enumerable: true, get: function () { return commonLogger_1.commonLoggerCreate; } });
220
215
  const safeJsonStringify_1 = require("./string/safeJsonStringify");
221
216
  Object.defineProperty(exports, "_safeJsonStringify", { enumerable: true, get: function () { return safeJsonStringify_1._safeJsonStringify; } });
222
217
  const pQueue_1 = require("./promise/pQueue");
@@ -17,6 +17,7 @@ export declare const commonLogLevelNumber: Record<CommonLogLevel, number>;
17
17
  * @experimental
18
18
  */
19
19
  export declare type CommonLogFunction = (...args: any[]) => void;
20
+ export declare type CommonLogWithLevelFunction = (level: CommonLogLevel, args: any[]) => void;
20
21
  /**
21
22
  * Interface is inspired/compatible with `console.*`
22
23
  * So, `console` is a valid CommonLogger implementation as-is.
@@ -46,3 +47,7 @@ export declare function commonLoggerPipe(loggers: CommonLogger[]): CommonLogger;
46
47
  * Creates a "child" CommonLogger with prefix (one or multiple).
47
48
  */
48
49
  export declare function commonLoggerPrefix(logger: CommonLogger, ...prefixes: any[]): CommonLogger;
50
+ /**
51
+ * Creates a CommonLogger from a single function that takes `level` and `args`.
52
+ */
53
+ export declare function commonLoggerCreate(fn: CommonLogWithLevelFunction): CommonLogger;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.commonLoggerPrefix = exports.commonLoggerPipe = exports.commonLoggerMinLevel = exports.commonLoggerNoop = exports.commonLogLevelNumber = void 0;
3
+ exports.commonLoggerCreate = exports.commonLoggerPrefix = exports.commonLoggerPipe = exports.commonLoggerMinLevel = exports.commonLoggerNoop = exports.commonLogLevelNumber = void 0;
4
4
  const index_1 = require("../index");
5
5
  exports.commonLogLevelNumber = {
6
6
  log: 10,
@@ -71,3 +71,14 @@ function commonLoggerPrefix(logger, ...prefixes) {
71
71
  };
72
72
  }
73
73
  exports.commonLoggerPrefix = commonLoggerPrefix;
74
+ /**
75
+ * Creates a CommonLogger from a single function that takes `level` and `args`.
76
+ */
77
+ function commonLoggerCreate(fn) {
78
+ return {
79
+ log: (...args) => fn('log', args),
80
+ warn: (...args) => fn('warn', args),
81
+ error: (...args) => fn('error', args),
82
+ };
83
+ }
84
+ exports.commonLoggerCreate = commonLoggerCreate;
@@ -21,6 +21,15 @@ export interface PQueueCfg {
21
21
  * If true - will LOG EVERYTHING:)
22
22
  */
23
23
  debug?: boolean;
24
+ /**
25
+ * By default .push method resolves when the Promise is done (finished).
26
+ *
27
+ * If you set resolveOn = 'start' - .push method will resolve the Promise (with void) upon
28
+ * the START of the processing.
29
+ *
30
+ * @default finish
31
+ */
32
+ resolveOn?: 'finish' | 'start';
24
33
  }
25
34
  export declare type PromiseReturningFunction<R> = () => Promise<R>;
26
35
  /**
@@ -21,6 +21,7 @@ class PQueue {
21
21
  errorMode: errorMode_1.ErrorMode.THROW_IMMEDIATELY,
22
22
  logger: console,
23
23
  debug: false,
24
+ resolveOn: 'finish',
24
25
  ...cfg,
25
26
  };
26
27
  if (!cfg.debug) {
@@ -39,7 +40,7 @@ class PQueue {
39
40
  * Idle means 0 queue and 0 inFlight.
40
41
  */
41
42
  onIdle() {
42
- if (this.queue.length === 0)
43
+ if (this.queue.length === 0 && this.inFlight === 0)
43
44
  return Promise.resolve();
44
45
  const listener = (0, pDefer_1.pDefer)();
45
46
  this.onIdleListeners.push(listener);
@@ -51,16 +52,24 @@ class PQueue {
51
52
  */
52
53
  push(fn_) {
53
54
  const { concurrency } = this.cfg;
55
+ const resolveOnStart = this.cfg.resolveOn === 'start';
54
56
  const fn = fn_;
55
57
  fn.defer || (fn.defer = (0, pDefer_1.pDefer)());
56
58
  if (this.inFlight < concurrency) {
57
59
  // There is room for more jobs. Can start immediately
58
60
  this.inFlight++;
59
61
  this.debug(`inFlight++ ${this.inFlight}/${concurrency}, queue ${this.queue.length}`);
62
+ if (resolveOnStart)
63
+ fn.defer.resolve();
60
64
  fn()
61
- .then(result => fn.defer.resolve(result))
65
+ .then(result => {
66
+ if (!resolveOnStart)
67
+ fn.defer.resolve(result);
68
+ })
62
69
  .catch(err => {
63
70
  this.cfg.logger.error(err);
71
+ if (resolveOnStart)
72
+ return;
64
73
  if (this.cfg.errorMode === errorMode_1.ErrorMode.SUPPRESS) {
65
74
  fn.defer.resolve(); // resolve with `void`
66
75
  }
@@ -7,13 +7,12 @@ import { AppError, _jsonParseIfPossible, _stringifyAny, } from '..';
7
7
  *
8
8
  * Alternatively, if you're sure it's Error - you can use `_assertIsError(err)`.
9
9
  */
10
- export function _anyToError(o, opt) {
11
- if (o instanceof Error) {
12
- // Already an Error - return as-is
10
+ export function _anyToError(o, errorClass = Error, opt) {
11
+ if (o instanceof errorClass)
13
12
  return o;
14
- }
15
- const message = _stringifyAny(o, opt);
16
- return new Error(message);
13
+ // If it's an instance of Error, but ErrorClass is something else (e.g AppError) - it'll be "repacked" into AppError
14
+ const errorObject = _isErrorObject(o) ? o : _anyToErrorObject(o, opt);
15
+ return _errorObjectToError(errorObject, errorClass);
17
16
  }
18
17
  /**
19
18
  * Converts "anything" to ErrorObject.
@@ -22,8 +21,9 @@ export function _anyToError(o, opt) {
22
21
  * Objects (not Errors) get converted to prettified JSON string (via `_stringifyAny`).
23
22
  */
24
23
  export function _anyToErrorObject(o, opt) {
24
+ var _a;
25
25
  if (o instanceof Error) {
26
- return _errorToErrorObject(o, opt === null || opt === void 0 ? void 0 : opt.includeErrorStack);
26
+ return _errorToErrorObject(o, (_a = opt === null || opt === void 0 ? void 0 : opt.includeErrorStack) !== null && _a !== void 0 ? _a : true);
27
27
  }
28
28
  o = _jsonParseIfPossible(o);
29
29
  if (_isHttpErrorResponse(o)) {
@@ -43,7 +43,7 @@ export function _anyToErrorObject(o, opt) {
43
43
  data: {}, // empty
44
44
  };
45
45
  }
46
- export function _errorToErrorObject(e, includeErrorStack = false) {
46
+ export function _errorToErrorObject(e, includeErrorStack = true) {
47
47
  const obj = {
48
48
  name: e.name,
49
49
  message: e.message,
@@ -55,17 +55,27 @@ export function _errorToErrorObject(e, includeErrorStack = false) {
55
55
  return obj;
56
56
  }
57
57
  export function _errorObjectToAppError(o) {
58
- const err = Object.assign(new AppError(o.message, o.data), {
58
+ return _errorObjectToError(o, AppError);
59
+ }
60
+ export function _errorObjectToError(o, errorClass = Error) {
61
+ const err = new errorClass(o.message);
59
62
  // name: err.name, // cannot be assigned to a readonly property like this
60
63
  // stack: o.stack, // also readonly e.g in Firefox
61
- });
62
64
  Object.defineProperty(err, 'name', {
63
65
  value: o.name,
64
66
  configurable: true,
65
67
  });
66
- Object.defineProperty(err, 'stack', {
67
- value: o.stack,
68
+ Object.defineProperty(err, 'data', {
69
+ value: o.data,
70
+ writable: true,
71
+ configurable: true,
72
+ enumerable: false,
68
73
  });
74
+ if (o.stack) {
75
+ Object.defineProperty(err, 'stack', {
76
+ value: o.stack,
77
+ });
78
+ }
69
79
  return err;
70
80
  }
71
81
  export function _isHttpErrorResponse(o) {
@@ -73,10 +83,14 @@ export function _isHttpErrorResponse(o) {
73
83
  }
74
84
  export function _isHttpErrorObject(o) {
75
85
  var _a;
76
- return (typeof (o === null || o === void 0 ? void 0 : o.name) === 'string' &&
77
- typeof (o === null || o === void 0 ? void 0 : o.message) === 'string' &&
78
- typeof ((_a = o === null || o === void 0 ? void 0 : o.data) === null || _a === void 0 ? void 0 : _a.httpStatusCode) === 'number');
86
+ return (!!o &&
87
+ typeof o.name === 'string' &&
88
+ typeof o.message === 'string' &&
89
+ typeof ((_a = o.data) === null || _a === void 0 ? void 0 : _a.httpStatusCode) === 'number');
79
90
  }
91
+ /**
92
+ * Note: any instance of AppError is also automatically an ErrorObject
93
+ */
80
94
  export function _isErrorObject(o) {
81
- return (typeof (o === null || o === void 0 ? void 0 : o.name) === 'string' && typeof (o === null || o === void 0 ? void 0 : o.message) === 'string' && typeof (o === null || o === void 0 ? void 0 : o.data) === 'object');
95
+ return (!!o && typeof o.name === 'string' && typeof o.message === 'string' && typeof o.data === 'object');
82
96
  }
package/dist-esm/index.js CHANGED
@@ -13,7 +13,7 @@ import { _Retry } from './decorators/retry.decorator';
13
13
  import { _Timeout } from './decorators/timeout.decorator';
14
14
  import { AppError } from './error/app.error';
15
15
  import { AssertionError, _assert, _assertDeepEquals, _assertEquals, _assertIsError, _assertIsNumber, _assertIsString, _assertTypeOf, } from './error/assert';
16
- import { _anyToError, _anyToErrorObject, _errorObjectToAppError, _errorToErrorObject, _isErrorObject, _isHttpErrorObject, _isHttpErrorResponse, } from './error/error.util';
16
+ export * from './error/error.util';
17
17
  import { ErrorMode } from './error/errorMode';
18
18
  import { HttpError } from './error/http.error';
19
19
  import { _try, pTry } from './error/try';
@@ -50,7 +50,7 @@ import { _ms, _since } from './time/time.util';
50
50
  import { _noop, _objectKeys, _passNothingPredicate, _passthroughMapper, _passthroughPredicate, _passUndefinedMapper, _stringMapEntries, _stringMapValues, } from './types';
51
51
  import { _gb, _hb, _kb, _mb } from './unit/size.util';
52
52
  import { is } from './vendor/is';
53
- import { commonLoggerMinLevel, commonLoggerNoop, commonLogLevelNumber, commonLoggerPipe, commonLoggerPrefix, } from './log/commonLogger';
53
+ import { commonLoggerMinLevel, commonLoggerNoop, commonLogLevelNumber, commonLoggerPipe, commonLoggerPrefix, commonLoggerCreate, } from './log/commonLogger';
54
54
  import { _safeJsonStringify } from './string/safeJsonStringify';
55
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, };
56
+ export { is, _Memo, _memoFn, _LogMethod, _getArgsSignature, _createPromiseDecorator, AppError, HttpError, AssertionError, _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, _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, commonLoggerCreate, _safeJsonStringify, PQueue, };
@@ -65,3 +65,13 @@ export function commonLoggerPrefix(logger, ...prefixes) {
65
65
  error: (...args) => logger.error(...prefixes, ...args),
66
66
  };
67
67
  }
68
+ /**
69
+ * Creates a CommonLogger from a single function that takes `level` and `args`.
70
+ */
71
+ export function commonLoggerCreate(fn) {
72
+ return {
73
+ log: (...args) => fn('log', args),
74
+ warn: (...args) => fn('warn', args),
75
+ error: (...args) => fn('error', args),
76
+ };
77
+ }
@@ -15,7 +15,7 @@ export class PQueue {
15
15
  this.onIdleListeners = [];
16
16
  this.cfg = Object.assign({
17
17
  // concurrency: Number.MAX_SAFE_INTEGER,
18
- errorMode: ErrorMode.THROW_IMMEDIATELY, logger: console, debug: false }, cfg);
18
+ errorMode: ErrorMode.THROW_IMMEDIATELY, logger: console, debug: false, resolveOn: 'finish' }, cfg);
19
19
  if (!cfg.debug) {
20
20
  this.debug = () => { };
21
21
  }
@@ -32,7 +32,7 @@ export class PQueue {
32
32
  * Idle means 0 queue and 0 inFlight.
33
33
  */
34
34
  onIdle() {
35
- if (this.queue.length === 0)
35
+ if (this.queue.length === 0 && this.inFlight === 0)
36
36
  return Promise.resolve();
37
37
  const listener = pDefer();
38
38
  this.onIdleListeners.push(listener);
@@ -44,16 +44,24 @@ export class PQueue {
44
44
  */
45
45
  push(fn_) {
46
46
  const { concurrency } = this.cfg;
47
+ const resolveOnStart = this.cfg.resolveOn === 'start';
47
48
  const fn = fn_;
48
49
  fn.defer || (fn.defer = pDefer());
49
50
  if (this.inFlight < concurrency) {
50
51
  // There is room for more jobs. Can start immediately
51
52
  this.inFlight++;
52
53
  this.debug(`inFlight++ ${this.inFlight}/${concurrency}, queue ${this.queue.length}`);
54
+ if (resolveOnStart)
55
+ fn.defer.resolve();
53
56
  fn()
54
- .then(result => fn.defer.resolve(result))
57
+ .then(result => {
58
+ if (!resolveOnStart)
59
+ fn.defer.resolve(result);
60
+ })
55
61
  .catch(err => {
56
62
  this.cfg.logger.error(err);
63
+ if (resolveOnStart)
64
+ return;
57
65
  if (this.cfg.errorMode === ErrorMode.SUPPRESS) {
58
66
  fn.defer.resolve(); // resolve with `void`
59
67
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naturalcycles/js-lib",
3
- "version": "14.69.1",
3
+ "version": "14.70.0",
4
4
  "scripts": {
5
5
  "prepare": "husky install",
6
6
  "build-prod": "build-prod-esm-cjs",
@@ -7,6 +7,7 @@ import {
7
7
  StringifyAnyOptions,
8
8
  _jsonParseIfPossible,
9
9
  _stringifyAny,
10
+ Class,
10
11
  } from '..'
11
12
 
12
13
  /**
@@ -17,14 +18,17 @@ import {
17
18
  *
18
19
  * Alternatively, if you're sure it's Error - you can use `_assertIsError(err)`.
19
20
  */
20
- export function _anyToError(o: any, opt?: StringifyAnyOptions): Error {
21
- if (o instanceof Error) {
22
- // Already an Error - return as-is
23
- return o
24
- }
21
+ export function _anyToError<ERROR_TYPE extends Error = Error>(
22
+ o: any,
23
+ errorClass: Class<ERROR_TYPE> = Error as any,
24
+ opt?: StringifyAnyOptions,
25
+ ): ERROR_TYPE {
26
+ if (o instanceof errorClass) return o
25
27
 
26
- const message = _stringifyAny(o, opt)
27
- return new Error(message)
28
+ // If it's an instance of Error, but ErrorClass is something else (e.g AppError) - it'll be "repacked" into AppError
29
+
30
+ const errorObject = _isErrorObject(o) ? o : _anyToErrorObject(o, opt)
31
+ return _errorObjectToError(errorObject, errorClass)
28
32
  }
29
33
 
30
34
  /**
@@ -38,7 +42,7 @@ export function _anyToErrorObject<DATA_TYPE extends ErrorData = ErrorData>(
38
42
  opt?: StringifyAnyOptions,
39
43
  ): ErrorObject<DATA_TYPE> {
40
44
  if (o instanceof Error) {
41
- return _errorToErrorObject<DATA_TYPE>(o, opt?.includeErrorStack)
45
+ return _errorToErrorObject<DATA_TYPE>(o, opt?.includeErrorStack ?? true)
42
46
  }
43
47
 
44
48
  o = _jsonParseIfPossible(o)
@@ -70,7 +74,7 @@ export function _anyToErrorObject<DATA_TYPE extends ErrorData = ErrorData>(
70
74
 
71
75
  export function _errorToErrorObject<DATA_TYPE extends ErrorData = ErrorData>(
72
76
  e: AppError<DATA_TYPE> | Error,
73
- includeErrorStack = false,
77
+ includeErrorStack = true,
74
78
  ): ErrorObject<DATA_TYPE> {
75
79
  const obj: ErrorObject<DATA_TYPE> = {
76
80
  name: e.name,
@@ -86,20 +90,35 @@ export function _errorToErrorObject<DATA_TYPE extends ErrorData = ErrorData>(
86
90
  }
87
91
 
88
92
  export function _errorObjectToAppError<DATA_TYPE>(o: ErrorObject<DATA_TYPE>): AppError<DATA_TYPE> {
89
- const err = Object.assign(new AppError(o.message, o.data), {
90
- // name: err.name, // cannot be assigned to a readonly property like this
91
- // stack: o.stack, // also readonly e.g in Firefox
92
- })
93
+ return _errorObjectToError(o, AppError)
94
+ }
95
+
96
+ export function _errorObjectToError<DATA_TYPE, ERROR_TYPE extends Error>(
97
+ o: ErrorObject<DATA_TYPE>,
98
+ errorClass: Class<ERROR_TYPE> = Error as any,
99
+ ): ERROR_TYPE {
100
+ const err = new errorClass(o.message)
101
+ // name: err.name, // cannot be assigned to a readonly property like this
102
+ // stack: o.stack, // also readonly e.g in Firefox
93
103
 
94
104
  Object.defineProperty(err, 'name', {
95
105
  value: o.name,
96
106
  configurable: true,
97
107
  })
98
108
 
99
- Object.defineProperty(err, 'stack', {
100
- value: o.stack,
109
+ Object.defineProperty(err, 'data', {
110
+ value: o.data,
111
+ writable: true,
112
+ configurable: true,
113
+ enumerable: false,
101
114
  })
102
115
 
116
+ if (o.stack) {
117
+ Object.defineProperty(err, 'stack', {
118
+ value: o.stack,
119
+ })
120
+ }
121
+
103
122
  return err
104
123
  }
105
124
 
@@ -109,14 +128,18 @@ export function _isHttpErrorResponse(o: any): o is HttpErrorResponse {
109
128
 
110
129
  export function _isHttpErrorObject(o: any): o is ErrorObject<HttpErrorData> {
111
130
  return (
112
- typeof o?.name === 'string' &&
113
- typeof o?.message === 'string' &&
114
- typeof o?.data?.httpStatusCode === 'number'
131
+ !!o &&
132
+ typeof o.name === 'string' &&
133
+ typeof o.message === 'string' &&
134
+ typeof o.data?.httpStatusCode === 'number'
115
135
  )
116
136
  }
117
137
 
138
+ /**
139
+ * Note: any instance of AppError is also automatically an ErrorObject
140
+ */
118
141
  export function _isErrorObject(o: any): o is ErrorObject {
119
142
  return (
120
- typeof o?.name === 'string' && typeof o?.message === 'string' && typeof o?.data === 'object'
143
+ !!o && typeof o.name === 'string' && typeof o.message === 'string' && typeof o.data === 'object'
121
144
  )
122
145
  }
package/src/index.ts CHANGED
@@ -57,15 +57,7 @@ import {
57
57
  HttpErrorData,
58
58
  HttpErrorResponse,
59
59
  } from './error/error.model'
60
- import {
61
- _anyToError,
62
- _anyToErrorObject,
63
- _errorObjectToAppError,
64
- _errorToErrorObject,
65
- _isErrorObject,
66
- _isHttpErrorObject,
67
- _isHttpErrorResponse,
68
- } from './error/error.util'
60
+ export * from './error/error.util'
69
61
  import { ErrorMode } from './error/errorMode'
70
62
  import { HttpError } from './error/http.error'
71
63
  import { _try, pTry } from './error/try'
@@ -233,6 +225,8 @@ import {
233
225
  commonLogLevelNumber,
234
226
  commonLoggerPipe,
235
227
  commonLoggerPrefix,
228
+ CommonLogWithLevelFunction,
229
+ commonLoggerCreate,
236
230
  } from './log/commonLogger'
237
231
  import { _safeJsonStringify } from './string/safeJsonStringify'
238
232
  import { PQueue, PQueueCfg } from './promise/pQueue'
@@ -309,6 +303,7 @@ export type {
309
303
  JsonSchemaTuple,
310
304
  JsonSchemaBuilder,
311
305
  CommonLogLevel,
306
+ CommonLogWithLevelFunction,
312
307
  CommonLogFunction,
313
308
  CommonLogger,
314
309
  }
@@ -323,9 +318,6 @@ export {
323
318
  AppError,
324
319
  HttpError,
325
320
  AssertionError,
326
- _isErrorObject,
327
- _isHttpErrorObject,
328
- _isHttpErrorResponse,
329
321
  _assert,
330
322
  _assertEquals,
331
323
  _assertDeepEquals,
@@ -402,10 +394,6 @@ export {
402
394
  _shuffle,
403
395
  _mapToObject,
404
396
  _findKeyByValue,
405
- _anyToError,
406
- _anyToErrorObject,
407
- _errorToErrorObject,
408
- _errorObjectToAppError,
409
397
  _range,
410
398
  _uniq,
411
399
  _uniqBy,
@@ -474,6 +462,7 @@ export {
474
462
  commonLogLevelNumber,
475
463
  commonLoggerPipe,
476
464
  commonLoggerPrefix,
465
+ commonLoggerCreate,
477
466
  _safeJsonStringify,
478
467
  PQueue,
479
468
  }
@@ -25,6 +25,7 @@ export const commonLogLevelNumber: Record<CommonLogLevel, number> = {
25
25
  * @experimental
26
26
  */
27
27
  export type CommonLogFunction = (...args: any[]) => void
28
+ export type CommonLogWithLevelFunction = (level: CommonLogLevel, args: any[]) => void
28
29
 
29
30
  /**
30
31
  * Interface is inspired/compatible with `console.*`
@@ -109,3 +110,14 @@ export function commonLoggerPrefix(logger: CommonLogger, ...prefixes: any[]): Co
109
110
  error: (...args) => logger.error(...prefixes, ...args),
110
111
  }
111
112
  }
113
+
114
+ /**
115
+ * Creates a CommonLogger from a single function that takes `level` and `args`.
116
+ */
117
+ export function commonLoggerCreate(fn: CommonLogWithLevelFunction): CommonLogger {
118
+ return {
119
+ log: (...args) => fn('log', args),
120
+ warn: (...args) => fn('warn', args),
121
+ error: (...args) => fn('error', args),
122
+ }
123
+ }
@@ -33,6 +33,16 @@ export interface PQueueCfg {
33
33
  // logSizeChange?: boolean
34
34
 
35
35
  // timeout
36
+
37
+ /**
38
+ * By default .push method resolves when the Promise is done (finished).
39
+ *
40
+ * If you set resolveOn = 'start' - .push method will resolve the Promise (with void) upon
41
+ * the START of the processing.
42
+ *
43
+ * @default finish
44
+ */
45
+ resolveOn?: 'finish' | 'start'
36
46
  }
37
47
 
38
48
  export type PromiseReturningFunction<R> = () => Promise<R>
@@ -56,6 +66,7 @@ export class PQueue {
56
66
  errorMode: ErrorMode.THROW_IMMEDIATELY,
57
67
  logger: console,
58
68
  debug: false,
69
+ resolveOn: 'finish',
59
70
  ...cfg,
60
71
  }
61
72
 
@@ -84,7 +95,7 @@ export class PQueue {
84
95
  * Idle means 0 queue and 0 inFlight.
85
96
  */
86
97
  onIdle(): Promise<void> {
87
- if (this.queue.length === 0) return Promise.resolve()
98
+ if (this.queue.length === 0 && this.inFlight === 0) return Promise.resolve()
88
99
 
89
100
  const listener = pDefer()
90
101
  this.onIdleListeners.push(listener)
@@ -97,6 +108,7 @@ export class PQueue {
97
108
  */
98
109
  push<R>(fn_: PromiseReturningFunction<R>): Promise<R> {
99
110
  const { concurrency } = this.cfg
111
+ const resolveOnStart = this.cfg.resolveOn === 'start'
100
112
 
101
113
  const fn = fn_ as PromiseReturningFunctionWithDefer<R>
102
114
  fn.defer ||= pDefer<R>()
@@ -105,11 +117,16 @@ export class PQueue {
105
117
  // There is room for more jobs. Can start immediately
106
118
  this.inFlight++
107
119
  this.debug(`inFlight++ ${this.inFlight}/${concurrency}, queue ${this.queue.length}`)
120
+ if (resolveOnStart) fn.defer.resolve()
108
121
 
109
122
  fn()
110
- .then(result => fn.defer.resolve(result))
123
+ .then(result => {
124
+ if (!resolveOnStart) fn.defer.resolve(result)
125
+ })
111
126
  .catch(err => {
112
127
  this.cfg.logger.error(err)
128
+ if (resolveOnStart) return
129
+
113
130
  if (this.cfg.errorMode === ErrorMode.SUPPRESS) {
114
131
  fn.defer.resolve() // resolve with `void`
115
132
  } else {