@naturalcycles/js-lib 14.79.0 → 14.82.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.
@@ -6,7 +6,7 @@ const __1 = require("..");
6
6
  function _Retry(opt = {}) {
7
7
  return (target, key, descriptor) => {
8
8
  const originalFn = descriptor.value;
9
- descriptor.value = (0, __1.pRetry)(originalFn, opt);
9
+ descriptor.value = (0, __1.pRetryFn)(originalFn, opt);
10
10
  return descriptor;
11
11
  };
12
12
  }
package/dist/index.d.ts CHANGED
@@ -34,14 +34,13 @@ export * from './object/object.util';
34
34
  export * from './object/sortObject';
35
35
  export * from './object/sortObjectDeep';
36
36
  import { AggregatedError } from './promise/AggregatedError';
37
- export * from './promise/pBatch';
38
37
  import { DeferredPromise, pDefer } from './promise/pDefer';
39
38
  export * from './promise/pDelay';
40
39
  export * from './promise/pFilter';
41
40
  export * from './promise/pHang';
42
41
  import { pMap, PMapOptions } from './promise/pMap';
43
42
  export * from './promise/pProps';
44
- import { pRetry, PRetryOptions } from './promise/pRetry';
43
+ import { pRetry, pRetryFn, PRetryOptions } from './promise/pRetry';
45
44
  export * from './promise/pState';
46
45
  import { pTimeout, pTimeoutFn, PTimeoutOptions } from './promise/pTimeout';
47
46
  export * from './promise/pTuple';
@@ -60,4 +59,4 @@ import { PQueue, PQueueCfg } from './promise/pQueue';
60
59
  export * from './seq/seq';
61
60
  export * from './math/stack.util';
62
61
  export type { AbortableMapper, AbortablePredicate, AbortableAsyncPredicate, AbortableAsyncMapper, 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, 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, };
63
- export { is, _createPromiseDecorator, _stringMapValues, _stringMapEntries, _objectKeys, pMap, _passthroughMapper, _passUndefinedMapper, _passthroughPredicate, _passNothingPredicate, _noop, ErrorMode, pDefer, AggregatedError, pRetry, pTimeout, pTimeoutFn, _tryCatch, _TryCatch, _stringifyAny, jsonSchema, JsonSchemaAnyBuilder, commonLoggerMinLevel, commonLoggerNoop, commonLogLevelNumber, commonLoggerPipe, commonLoggerPrefix, commonLoggerCreate, PQueue, END, SKIP, };
62
+ export { is, _createPromiseDecorator, _stringMapValues, _stringMapEntries, _objectKeys, pMap, _passthroughMapper, _passUndefinedMapper, _passthroughPredicate, _passNothingPredicate, _noop, ErrorMode, pDefer, AggregatedError, pRetry, pRetryFn, pTimeout, pTimeoutFn, _tryCatch, _TryCatch, _stringifyAny, jsonSchema, JsonSchemaAnyBuilder, commonLoggerMinLevel, commonLoggerNoop, commonLogLevelNumber, commonLoggerPipe, commonLoggerPrefix, commonLoggerCreate, PQueue, END, SKIP, };
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SKIP = exports.END = exports.PQueue = exports.commonLoggerCreate = exports.commonLoggerPrefix = exports.commonLoggerPipe = exports.commonLogLevelNumber = exports.commonLoggerNoop = exports.commonLoggerMinLevel = exports.JsonSchemaAnyBuilder = exports.jsonSchema = exports._stringifyAny = exports._TryCatch = exports._tryCatch = exports.pTimeoutFn = exports.pTimeout = exports.pRetry = exports.AggregatedError = exports.pDefer = exports.ErrorMode = exports._noop = exports._passNothingPredicate = exports._passthroughPredicate = exports._passUndefinedMapper = exports._passthroughMapper = exports.pMap = exports._objectKeys = exports._stringMapEntries = exports._stringMapValues = exports._createPromiseDecorator = exports.is = void 0;
3
+ exports.SKIP = exports.END = exports.PQueue = exports.commonLoggerCreate = exports.commonLoggerPrefix = exports.commonLoggerPipe = exports.commonLogLevelNumber = exports.commonLoggerNoop = exports.commonLoggerMinLevel = exports.JsonSchemaAnyBuilder = exports.jsonSchema = exports._stringifyAny = exports._TryCatch = exports._tryCatch = exports.pTimeoutFn = exports.pTimeout = exports.pRetryFn = exports.pRetry = exports.AggregatedError = exports.pDefer = exports.ErrorMode = exports._noop = exports._passNothingPredicate = exports._passthroughPredicate = exports._passUndefinedMapper = exports._passthroughMapper = exports.pMap = exports._objectKeys = exports._stringMapEntries = exports._stringMapValues = exports._createPromiseDecorator = exports.is = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  (0, tslib_1.__exportStar)(require("./array/array.util"), exports);
6
6
  (0, tslib_1.__exportStar)(require("./lazy"), exports);
@@ -42,7 +42,6 @@ Object.defineProperty(exports, "JsonSchemaAnyBuilder", { enumerable: true, get:
42
42
  (0, tslib_1.__exportStar)(require("./object/sortObjectDeep"), exports);
43
43
  const AggregatedError_1 = require("./promise/AggregatedError");
44
44
  Object.defineProperty(exports, "AggregatedError", { enumerable: true, get: function () { return AggregatedError_1.AggregatedError; } });
45
- (0, tslib_1.__exportStar)(require("./promise/pBatch"), exports);
46
45
  const pDefer_1 = require("./promise/pDefer");
47
46
  Object.defineProperty(exports, "pDefer", { enumerable: true, get: function () { return pDefer_1.pDefer; } });
48
47
  (0, tslib_1.__exportStar)(require("./promise/pDelay"), exports);
@@ -53,6 +52,7 @@ Object.defineProperty(exports, "pMap", { enumerable: true, get: function () { re
53
52
  (0, tslib_1.__exportStar)(require("./promise/pProps"), exports);
54
53
  const pRetry_1 = require("./promise/pRetry");
55
54
  Object.defineProperty(exports, "pRetry", { enumerable: true, get: function () { return pRetry_1.pRetry; } });
55
+ Object.defineProperty(exports, "pRetryFn", { enumerable: true, get: function () { return pRetry_1.pRetryFn; } });
56
56
  (0, tslib_1.__exportStar)(require("./promise/pState"), exports);
57
57
  const pTimeout_1 = require("./promise/pTimeout");
58
58
  Object.defineProperty(exports, "pTimeout", { enumerable: true, get: function () { return pTimeout_1.pTimeout; } });
@@ -113,8 +113,8 @@ export declare class JsonSchemaObjectBuilder<T extends AnyObject> extends JsonSc
113
113
  minProps(minProperties: number): this;
114
114
  maxProps(maxProperties: number): this;
115
115
  additionalProps(additionalProperties: boolean): this;
116
- baseDBEntity(): JsonSchemaObjectBuilder<T & BaseDBEntity>;
117
- savedDBEntity(): JsonSchemaObjectBuilder<T & SavedDBEntity>;
116
+ baseDBEntity<ID = string>(idType?: string): JsonSchemaObjectBuilder<T & BaseDBEntity<ID>>;
117
+ savedDBEntity<ID = string>(idType?: string): JsonSchemaObjectBuilder<T & SavedDBEntity<ID>>;
118
118
  extend<T2 extends AnyObject>(s2: JsonSchemaObjectBuilder<T2>): JsonSchemaObjectBuilder<T & T2>;
119
119
  }
120
120
  export declare class JsonSchemaArrayBuilder<ITEM> extends JsonSchemaAnyBuilder<ITEM[], JsonSchemaArray<ITEM>> {
@@ -306,16 +306,16 @@ class JsonSchemaObjectBuilder extends JsonSchemaAnyBuilder {
306
306
  Object.assign(this.schema, { additionalProperties });
307
307
  return this;
308
308
  }
309
- baseDBEntity() {
309
+ baseDBEntity(idType = 'string') {
310
310
  Object.assign(this.schema.properties, {
311
- id: { type: 'string' },
311
+ id: { type: idType },
312
312
  created: { type: 'number', format: 'unixTimestamp' },
313
313
  updated: { type: 'number', format: 'unixTimestamp' },
314
314
  });
315
315
  return this;
316
316
  }
317
- savedDBEntity() {
318
- return this.baseDBEntity().addRequired(['id', 'created', 'updated']);
317
+ savedDBEntity(idType = 'string') {
318
+ return this.baseDBEntity(idType).addRequired(['id', 'created', 'updated']);
319
319
  }
320
320
  extend(s2) {
321
321
  const builder = new JsonSchemaObjectBuilder();
@@ -1,3 +1,3 @@
1
1
  import { SavedDBEntity } from '../types';
2
- export declare const baseDBEntityJsonSchema: import("./jsonSchemaBuilder").JsonSchemaObjectBuilder<Partial<SavedDBEntity>>;
3
- export declare const savedDBEntityJsonSchema: import("./jsonSchemaBuilder").JsonSchemaObjectBuilder<SavedDBEntity>;
2
+ export declare const baseDBEntityJsonSchema: import("./jsonSchemaBuilder").JsonSchemaObjectBuilder<Partial<SavedDBEntity<string>>>;
3
+ export declare const savedDBEntityJsonSchema: import("./jsonSchemaBuilder").JsonSchemaObjectBuilder<SavedDBEntity<string>>;
@@ -6,5 +6,5 @@
6
6
  export declare class AggregatedError<RESULT = any> extends Error {
7
7
  errors: Error[];
8
8
  results: RESULT[];
9
- constructor(errors: (Error | string)[], results?: RESULT[]);
9
+ constructor(errors: Error[], results?: RESULT[]);
10
10
  }
@@ -8,17 +8,12 @@ exports.AggregatedError = void 0;
8
8
  */
9
9
  class AggregatedError extends Error {
10
10
  constructor(errors, results = []) {
11
- const mappedErrors = errors.map(e => {
12
- if (typeof e === 'string')
13
- return new Error(e);
14
- return e;
15
- });
16
11
  const message = [
17
12
  `${errors.length} errors:`,
18
- ...mappedErrors.map((e, i) => `${i + 1}. ${e.message}`),
13
+ ...errors.map((e, i) => `${i + 1}. ${e.message}`),
19
14
  ].join('\n');
20
15
  super(message);
21
- this.errors = mappedErrors;
16
+ this.errors = errors;
22
17
  this.results = results;
23
18
  Object.defineProperty(this, 'name', {
24
19
  value: this.constructor.name,
@@ -1,3 +1,2 @@
1
- import { AbortableAsyncPredicate } from '../types';
2
- import { PMapOptions } from './pMap';
3
- export declare function pFilter<T>(iterable: Iterable<T | PromiseLike<T>>, filterFn: AbortableAsyncPredicate<T>, opt?: PMapOptions): Promise<T[]>;
1
+ import { AsyncPredicate } from '../types';
2
+ export declare function pFilter<T>(iterable: Iterable<T>, filterFn: AsyncPredicate<T>): Promise<T[]>;
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.pFilter = void 0;
4
- const pMap_1 = require("./pMap");
5
- async function pFilter(iterable, filterFn, opt) {
6
- const values = await (0, pMap_1.pMap)(iterable, async (item, index) => await Promise.all([filterFn(item, index), item]), opt);
7
- return values.filter(value => Boolean(value[0])).map(value => value[1]);
4
+ async function pFilter(iterable, filterFn) {
5
+ const items = [...iterable];
6
+ const predicates = await Promise.all(items.map((item, i) => filterFn(item, i)));
7
+ return items.filter((item, i) => predicates[i]);
8
8
  }
9
9
  exports.pFilter = pFilter;
@@ -41,4 +41,4 @@ export interface PMapOptions {
41
41
  * //=> ['http://ava.li/', 'http://todomvc.com/']
42
42
  * })();
43
43
  */
44
- export declare function pMap<IN, OUT>(iterable: Iterable<IN | PromiseLike<IN>>, mapper: AbortableAsyncMapper<IN, OUT>, opt?: PMapOptions): Promise<OUT[]>;
44
+ export declare function pMap<IN, OUT>(iterable: Iterable<IN>, mapper: AbortableAsyncMapper<IN, OUT>, opt?: PMapOptions): Promise<OUT[]>;
@@ -38,28 +38,74 @@ const AggregatedError_1 = require("./AggregatedError");
38
38
  * })();
39
39
  */
40
40
  async function pMap(iterable, mapper, opt = {}) {
41
+ const ret = [];
42
+ // const iterator = iterable[Symbol.iterator]()
43
+ const items = [...iterable];
44
+ const itemsLength = items.length;
45
+ if (itemsLength === 0)
46
+ return []; // short circuit
47
+ const { concurrency = itemsLength, errorMode = __1.ErrorMode.THROW_IMMEDIATELY } = opt;
48
+ const errors = [];
49
+ let isSettled = false;
50
+ let resolvingCount = 0;
51
+ let currentIndex = 0;
52
+ // Special cases that are able to preserve async stack traces
53
+ if (concurrency === 1) {
54
+ // Special case for concurrency == 1
55
+ for await (const item of items) {
56
+ try {
57
+ const r = await mapper(item, currentIndex++);
58
+ if (r === __1.END)
59
+ break;
60
+ if (r !== __1.SKIP)
61
+ ret.push(r);
62
+ }
63
+ catch (err) {
64
+ if (errorMode === __1.ErrorMode.THROW_IMMEDIATELY)
65
+ throw err;
66
+ if (errorMode === __1.ErrorMode.THROW_AGGREGATED) {
67
+ errors.push(err);
68
+ }
69
+ // otherwise, suppress completely
70
+ }
71
+ }
72
+ if (errors.length) {
73
+ throw new AggregatedError_1.AggregatedError(errors, ret);
74
+ }
75
+ return ret;
76
+ }
77
+ else if (!opt.concurrency || items.length <= opt.concurrency) {
78
+ // Special case for concurrency == infinity or iterable.length < concurrency
79
+ if (errorMode === __1.ErrorMode.THROW_IMMEDIATELY) {
80
+ return (await Promise.all(items.map((item, i) => mapper(item, i)))).filter(r => r !== __1.SKIP && r !== __1.END);
81
+ }
82
+ ;
83
+ (await Promise.allSettled(items.map((item, i) => mapper(item, i)))).forEach(r => {
84
+ if (r.status === 'fulfilled') {
85
+ if (r.value !== __1.SKIP && r.value !== __1.END)
86
+ ret.push(r.value);
87
+ }
88
+ else if (errorMode === __1.ErrorMode.THROW_AGGREGATED) {
89
+ errors.push(r.reason);
90
+ }
91
+ });
92
+ if (errors.length) {
93
+ throw new AggregatedError_1.AggregatedError(errors, ret);
94
+ }
95
+ return ret;
96
+ }
41
97
  return new Promise((resolve, reject) => {
42
- const { concurrency = Number.POSITIVE_INFINITY, errorMode = __1.ErrorMode.THROW_IMMEDIATELY } = opt;
43
- const ret = [];
44
- const iterator = iterable[Symbol.iterator]();
45
- const errors = [];
46
- let isSettled = false;
47
- let isIterableDone = false;
48
- let resolvingCount = 0;
49
- let currentIndex = 0;
50
- const next = (skipped = false) => {
98
+ const next = () => {
51
99
  if (isSettled) {
52
100
  return;
53
101
  }
54
- const nextItem = iterator.next();
55
- const i = currentIndex;
56
- if (!skipped)
57
- currentIndex++;
58
- if (nextItem.done) {
59
- isIterableDone = true;
102
+ const nextItem = items[currentIndex];
103
+ const i = currentIndex++;
104
+ if (currentIndex > itemsLength) {
60
105
  if (resolvingCount === 0) {
106
+ isSettled = true;
61
107
  const r = ret.filter(r => r !== __1.SKIP);
62
- if (errors.length && errorMode === __1.ErrorMode.THROW_AGGREGATED) {
108
+ if (errors.length) {
63
109
  reject(new AggregatedError_1.AggregatedError(errors, r));
64
110
  }
65
111
  else {
@@ -69,7 +115,7 @@ async function pMap(iterable, mapper, opt = {}) {
69
115
  return;
70
116
  }
71
117
  resolvingCount++;
72
- Promise.resolve(nextItem.value)
118
+ Promise.resolve(nextItem)
73
119
  .then(async (element) => await mapper(element, i))
74
120
  .then(value => {
75
121
  if (value === __1.END) {
@@ -85,7 +131,9 @@ async function pMap(iterable, mapper, opt = {}) {
85
131
  reject(err);
86
132
  }
87
133
  else {
88
- errors.push(err);
134
+ if (errorMode === __1.ErrorMode.THROW_AGGREGATED) {
135
+ errors.push(err);
136
+ }
89
137
  resolvingCount--;
90
138
  next();
91
139
  }
@@ -93,7 +141,7 @@ async function pMap(iterable, mapper, opt = {}) {
93
141
  };
94
142
  for (let i = 0; i < concurrency; i++) {
95
143
  next();
96
- if (isIterableDone) {
144
+ if (isSettled) {
97
145
  break;
98
146
  }
99
147
  }
@@ -5,6 +5,12 @@ export interface PRetryOptions {
5
5
  * Can be used to identify the place in the code that failed.
6
6
  */
7
7
  name?: string;
8
+ /**
9
+ * Timeout for each Try, in milliseconds.
10
+ *
11
+ * Defaults to no timeout.
12
+ */
13
+ timeout?: number;
8
14
  /**
9
15
  * How many attempts to try.
10
16
  * First attempt is not a retry, but "initial try". It still counts.
@@ -29,7 +35,7 @@ export interface PRetryOptions {
29
35
  *
30
36
  * @default () => true
31
37
  */
32
- predicate?: (err: unknown, attempt: number, maxAttempts: number) => boolean;
38
+ predicate?: (err: Error, attempt: number, maxAttempts: number) => boolean;
33
39
  /**
34
40
  * Log the first attempt (which is not a "retry" yet).
35
41
  *
@@ -62,9 +68,18 @@ export interface PRetryOptions {
62
68
  * Default to `console`
63
69
  */
64
70
  logger?: CommonLogger;
71
+ /**
72
+ * Defaults to true.
73
+ * If true - preserves the stack trace in case of a Timeout (usually - very useful!).
74
+ * It has a certain perf cost.
75
+ *
76
+ * @experimental
77
+ */
78
+ keepStackTrace?: boolean;
65
79
  }
66
80
  /**
67
81
  * Returns a Function (!), enhanced with retry capabilities.
68
82
  * Implements "Exponential back-off strategy" by multiplying the delay by `delayMultiplier` with each try.
69
83
  */
70
- export declare function pRetry<T extends AnyFunction>(fn: T, opt?: PRetryOptions): T;
84
+ export declare function pRetryFn<T extends AnyFunction>(fn: T, opt?: PRetryOptions): T;
85
+ export declare function pRetry<T>(fn: (attempt: number) => Promise<T>, opt?: PRetryOptions): Promise<T>;
@@ -1,58 +1,90 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.pRetry = void 0;
3
+ exports.pRetry = exports.pRetryFn = void 0;
4
4
  const __1 = require("..");
5
+ const pTimeout_1 = require("./pTimeout");
5
6
  /**
6
7
  * Returns a Function (!), enhanced with retry capabilities.
7
8
  * Implements "Exponential back-off strategy" by multiplying the delay by `delayMultiplier` with each try.
8
9
  */
9
- // eslint-disable-next-line @typescript-eslint/ban-types
10
- function pRetry(fn, opt = {}) {
11
- const { maxAttempts = 4, delay: initialDelay = 1000, delayMultiplier = 2, predicate, logger = console, name = fn.name, } = opt;
10
+ function pRetryFn(fn, opt = {}) {
11
+ return async function pRetryFunction(...args) {
12
+ return await pRetry(() => fn.call(this, ...args), opt);
13
+ };
14
+ }
15
+ exports.pRetryFn = pRetryFn;
16
+ async function pRetry(fn, opt = {}) {
17
+ const { maxAttempts = 4, delay: initialDelay = 1000, delayMultiplier = 2, predicate, logger = console, name, keepStackTrace = true, timeout, } = opt;
18
+ const fakeError = keepStackTrace ? new Error('RetryError') : undefined;
12
19
  let { logFirstAttempt = false, logRetries = true, logFailures = false, logSuccess = false } = opt;
13
20
  if (opt.logAll) {
14
- logFirstAttempt = logRetries = logFailures = true;
21
+ logSuccess = logFirstAttempt = logRetries = logFailures = true;
15
22
  }
16
23
  if (opt.logNone) {
17
24
  logSuccess = logFirstAttempt = logRetries = logFailures = false;
18
25
  }
19
- const fname = ['pRetry', name].filter(Boolean).join('.');
20
- return async function (...args) {
21
- let delay = initialDelay;
22
- let attempt = 0;
23
- return await new Promise((resolve, reject) => {
24
- const next = async () => {
25
- const started = Date.now();
26
- try {
27
- attempt++;
28
- if ((attempt === 1 && logFirstAttempt) || (attempt > 1 && logRetries)) {
29
- logger.log(`${fname} attempt #${attempt}...`);
30
- }
31
- const r = await fn.apply(this, args);
32
- if (logSuccess) {
33
- logger.log(`${fname} attempt #${attempt} succeeded in ${(0, __1._since)(started)}`);
34
- }
35
- resolve(r);
26
+ const fname = name || fn.name || 'pRetry function';
27
+ let delay = initialDelay;
28
+ let attempt = 0;
29
+ let timer;
30
+ let timedOut = false;
31
+ return await new Promise((resolve, reject) => {
32
+ const rejectWithTimeout = () => {
33
+ timedOut = true; // to prevent more tries
34
+ const err = new pTimeout_1.TimeoutError(`"${fname}" timed out after ${timeout} ms`);
35
+ if (fakeError) {
36
+ // keep original stack
37
+ err.stack = fakeError.stack.replace('Error: RetryError', 'TimeoutError');
38
+ }
39
+ reject(err);
40
+ };
41
+ const next = async () => {
42
+ if (timedOut)
43
+ return;
44
+ if (timeout) {
45
+ timer = setTimeout(rejectWithTimeout, timeout);
46
+ }
47
+ const started = Date.now();
48
+ try {
49
+ attempt++;
50
+ if ((attempt === 1 && logFirstAttempt) || (attempt > 1 && logRetries)) {
51
+ logger.log(`${fname} attempt #${attempt}...`);
36
52
  }
37
- catch (err) {
38
- if (logFailures) {
39
- logger.warn(`${fname} attempt #${attempt} error in ${(0, __1._since)(started)}:`, (0, __1._stringifyAny)(err, {
40
- includeErrorData: true,
41
- }));
42
- }
43
- if (attempt >= maxAttempts || (predicate && !predicate(err, attempt, maxAttempts))) {
44
- // Give up
45
- reject(err);
46
- }
47
- else {
48
- // Retry after delay
49
- delay *= delayMultiplier;
50
- setTimeout(next, delay);
53
+ const r = await fn(attempt);
54
+ clearTimeout(timer);
55
+ if (logSuccess) {
56
+ logger.log(`${fname} attempt #${attempt} succeeded in ${(0, __1._since)(started)}`);
57
+ }
58
+ resolve(r);
59
+ }
60
+ catch (err) {
61
+ clearTimeout(timer);
62
+ if (logFailures) {
63
+ logger.warn(`${fname} attempt #${attempt} error in ${(0, __1._since)(started)}:`, (0, __1._stringifyAny)(err, {
64
+ includeErrorData: true,
65
+ }));
66
+ }
67
+ if (attempt >= maxAttempts ||
68
+ (predicate && !predicate(err, attempt, maxAttempts))) {
69
+ // Give up
70
+ if (fakeError) {
71
+ // Preserve the original call stack
72
+ Object.defineProperty(err, 'stack', {
73
+ value: err.stack +
74
+ '\n --' +
75
+ fakeError.stack.replace('Error: RetryError', ''),
76
+ });
51
77
  }
78
+ reject(err);
52
79
  }
53
- };
54
- void next();
55
- });
56
- };
80
+ else {
81
+ // Retry after delay
82
+ delay *= delayMultiplier;
83
+ setTimeout(next, delay);
84
+ }
85
+ }
86
+ };
87
+ void next();
88
+ });
57
89
  }
58
90
  exports.pRetry = pRetry;
package/dist/types.d.ts CHANGED
@@ -24,13 +24,13 @@ export interface CreatedUpdated {
24
24
  created: number;
25
25
  updated: number;
26
26
  }
27
- export interface CreatedUpdatedId extends CreatedUpdated {
28
- id: string;
27
+ export interface CreatedUpdatedId<ID = string> extends CreatedUpdated {
28
+ id: ID;
29
29
  }
30
- export interface ObjectWithId {
31
- id: string;
30
+ export interface ObjectWithId<ID = string> {
31
+ id: ID;
32
32
  }
33
- export interface AnyObjectWithId extends AnyObject, ObjectWithId {
33
+ export interface AnyObjectWithId<ID = string> extends AnyObject, ObjectWithId<ID> {
34
34
  }
35
35
  /**
36
36
  * Convenience type shorthand.
@@ -127,8 +127,8 @@ export declare type UnixTimestamp = number;
127
127
  /**
128
128
  * Base interface for any Entity that was saved to DB.
129
129
  */
130
- export interface SavedDBEntity {
131
- id: string;
130
+ export interface SavedDBEntity<ID = string> {
131
+ id: ID;
132
132
  /**
133
133
  * unixTimestamp of when the entity was first created (in the DB).
134
134
  */
@@ -144,9 +144,9 @@ export interface SavedDBEntity {
144
144
  * hence `id`, `created` and `updated` fields CAN BE undefined (yet).
145
145
  * When it's known to be saved - `SavedDBEntity` interface can be used instead.
146
146
  */
147
- export declare type BaseDBEntity = Partial<SavedDBEntity>;
148
- export declare type Saved<E> = Merge<E, SavedDBEntity>;
149
- export declare type Unsaved<E> = Merge<E, BaseDBEntity>;
147
+ export declare type BaseDBEntity<ID = string> = Partial<SavedDBEntity<ID>>;
148
+ export declare type Saved<E, ID = string> = Merge<E, SavedDBEntity<ID>>;
149
+ export declare type Unsaved<E, ID = string> = Merge<E, BaseDBEntity<ID>>;
150
150
  /**
151
151
  * Named type for JSON.parse / JSON.stringify second argument
152
152
  */
@@ -1,9 +1,9 @@
1
- import { pRetry } from '..';
1
+ import { pRetryFn } from '..';
2
2
  // eslint-disable-next-line @typescript-eslint/naming-convention
3
3
  export function _Retry(opt = {}) {
4
4
  return (target, key, descriptor) => {
5
5
  const originalFn = descriptor.value;
6
- descriptor.value = pRetry(originalFn, opt);
6
+ descriptor.value = pRetryFn(originalFn, opt);
7
7
  return descriptor;
8
8
  };
9
9
  }
package/dist-esm/index.js CHANGED
@@ -31,14 +31,13 @@ export * from './object/object.util';
31
31
  export * from './object/sortObject';
32
32
  export * from './object/sortObjectDeep';
33
33
  import { AggregatedError } from './promise/AggregatedError';
34
- export * from './promise/pBatch';
35
34
  import { pDefer } from './promise/pDefer';
36
35
  export * from './promise/pDelay';
37
36
  export * from './promise/pFilter';
38
37
  export * from './promise/pHang';
39
38
  import { pMap } from './promise/pMap';
40
39
  export * from './promise/pProps';
41
- import { pRetry } from './promise/pRetry';
40
+ import { pRetry, pRetryFn } from './promise/pRetry';
42
41
  export * from './promise/pState';
43
42
  import { pTimeout, pTimeoutFn } from './promise/pTimeout';
44
43
  export * from './promise/pTuple';
@@ -55,4 +54,4 @@ export * from './string/safeJsonStringify';
55
54
  import { PQueue } from './promise/pQueue';
56
55
  export * from './seq/seq';
57
56
  export * from './math/stack.util';
58
- export { is, _createPromiseDecorator, _stringMapValues, _stringMapEntries, _objectKeys, pMap, _passthroughMapper, _passUndefinedMapper, _passthroughPredicate, _passNothingPredicate, _noop, ErrorMode, pDefer, AggregatedError, pRetry, pTimeout, pTimeoutFn, _tryCatch, _TryCatch, _stringifyAny, jsonSchema, JsonSchemaAnyBuilder, commonLoggerMinLevel, commonLoggerNoop, commonLogLevelNumber, commonLoggerPipe, commonLoggerPrefix, commonLoggerCreate, PQueue, END, SKIP, };
57
+ export { is, _createPromiseDecorator, _stringMapValues, _stringMapEntries, _objectKeys, pMap, _passthroughMapper, _passUndefinedMapper, _passthroughPredicate, _passNothingPredicate, _noop, ErrorMode, pDefer, AggregatedError, pRetry, pRetryFn, pTimeout, pTimeoutFn, _tryCatch, _TryCatch, _stringifyAny, jsonSchema, JsonSchemaAnyBuilder, commonLoggerMinLevel, commonLoggerNoop, commonLogLevelNumber, commonLoggerPipe, commonLoggerPrefix, commonLoggerCreate, PQueue, END, SKIP, };
@@ -301,16 +301,16 @@ export class JsonSchemaObjectBuilder extends JsonSchemaAnyBuilder {
301
301
  Object.assign(this.schema, { additionalProperties });
302
302
  return this;
303
303
  }
304
- baseDBEntity() {
304
+ baseDBEntity(idType = 'string') {
305
305
  Object.assign(this.schema.properties, {
306
- id: { type: 'string' },
306
+ id: { type: idType },
307
307
  created: { type: 'number', format: 'unixTimestamp' },
308
308
  updated: { type: 'number', format: 'unixTimestamp' },
309
309
  });
310
310
  return this;
311
311
  }
312
- savedDBEntity() {
313
- return this.baseDBEntity().addRequired(['id', 'created', 'updated']);
312
+ savedDBEntity(idType = 'string') {
313
+ return this.baseDBEntity(idType).addRequired(['id', 'created', 'updated']);
314
314
  }
315
315
  extend(s2) {
316
316
  const builder = new JsonSchemaObjectBuilder();
@@ -5,17 +5,12 @@
5
5
  */
6
6
  export class AggregatedError extends Error {
7
7
  constructor(errors, results = []) {
8
- const mappedErrors = errors.map(e => {
9
- if (typeof e === 'string')
10
- return new Error(e);
11
- return e;
12
- });
13
8
  const message = [
14
9
  `${errors.length} errors:`,
15
- ...mappedErrors.map((e, i) => `${i + 1}. ${e.message}`),
10
+ ...errors.map((e, i) => `${i + 1}. ${e.message}`),
16
11
  ].join('\n');
17
12
  super(message);
18
- this.errors = mappedErrors;
13
+ this.errors = errors;
19
14
  this.results = results;
20
15
  Object.defineProperty(this, 'name', {
21
16
  value: this.constructor.name,
@@ -1,5 +1,5 @@
1
- import { pMap } from './pMap';
2
- export async function pFilter(iterable, filterFn, opt) {
3
- const values = await pMap(iterable, async (item, index) => await Promise.all([filterFn(item, index), item]), opt);
4
- return values.filter(value => Boolean(value[0])).map(value => value[1]);
1
+ export async function pFilter(iterable, filterFn) {
2
+ const items = [...iterable];
3
+ const predicates = await Promise.all(items.map((item, i) => filterFn(item, i)));
4
+ return items.filter((item, i) => predicates[i]);
5
5
  }