@naturalcycles/js-lib 14.115.2 → 14.117.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.
Files changed (37) hide show
  1. package/dist/datetime/dateInterval.d.ts +2 -2
  2. package/dist/datetime/localDate.d.ts +5 -5
  3. package/dist/datetime/localTime.d.ts +3 -3
  4. package/dist/datetime/timeInterval.d.ts +2 -2
  5. package/dist/decorators/logMethod.decorator.d.ts +1 -1
  6. package/dist/decorators/logMethod.decorator.js +1 -1
  7. package/dist/decorators/memo.util.d.ts +1 -1
  8. package/dist/decorators/timeout.decorator.js +2 -2
  9. package/dist/error/try.d.ts +11 -2
  10. package/dist/error/try.js +18 -2
  11. package/dist/is.util.d.ts +3 -3
  12. package/dist/is.util.js +2 -2
  13. package/dist/json-schema/from-data/generateJsonSchemaFromData.js +1 -1
  14. package/dist/json-schema/jsonSchema.model.d.ts +1 -1
  15. package/dist/lodash.types.d.ts +4 -4
  16. package/dist/log/commonLogger.d.ts +3 -3
  17. package/dist/promise/pQueue.d.ts +1 -1
  18. package/dist/promise/pQueue.js +1 -1
  19. package/dist/promise/pTimeout.d.ts +10 -4
  20. package/dist/promise/pTimeout.js +12 -10
  21. package/dist/string/stringifyAny.d.ts +1 -1
  22. package/dist/typeFest.d.ts +16 -16
  23. package/dist/types.d.ts +36 -35
  24. package/dist/vendor/is.d.ts +4 -4
  25. package/dist-esm/decorators/logMethod.decorator.js +1 -1
  26. package/dist-esm/decorators/timeout.decorator.js +1 -1
  27. package/dist-esm/error/try.js +18 -2
  28. package/dist-esm/is.util.js +2 -2
  29. package/dist-esm/promise/pMap.js +23 -16
  30. package/dist-esm/promise/pTimeout.js +11 -9
  31. package/package.json +1 -1
  32. package/src/decorators/logMethod.decorator.ts +1 -1
  33. package/src/decorators/timeout.decorator.ts +1 -1
  34. package/src/error/try.ts +26 -2
  35. package/src/is.util.ts +2 -3
  36. package/src/promise/pTimeout.ts +18 -15
  37. package/src/types.ts +2 -1
@@ -1,7 +1,7 @@
1
1
  import type { Inclusiveness, LocalDateConfig, LocalDateUnit } from './localDate';
2
2
  import { LocalDate } from './localDate';
3
- export declare type DateIntervalConfig = DateInterval | DateIntervalString;
4
- export declare type DateIntervalString = string;
3
+ export type DateIntervalConfig = DateInterval | DateIntervalString;
4
+ export type DateIntervalString = string;
5
5
  /**
6
6
  * Class that supports ISO8601 "Time interval" standard that looks like `2022-02-24/2022-03-30`.
7
7
  *
@@ -1,10 +1,10 @@
1
1
  import type { IsoDateString, IsoDateTimeString, UnixTimestampMillisNumber, UnixTimestampNumber } from '../types';
2
2
  import { LocalTime } from './localTime';
3
- export declare type LocalDateUnit = LocalDateUnitStrict | 'week';
4
- export declare type LocalDateUnitStrict = 'year' | 'month' | 'day';
5
- export declare type Inclusiveness = '()' | '[]' | '[)' | '(]';
6
- export declare type LocalDateConfig = LocalDate | IsoDateString;
7
- export declare type LocalDateFormatter = (ld: LocalDate) => string;
3
+ export type LocalDateUnit = LocalDateUnitStrict | 'week';
4
+ export type LocalDateUnitStrict = 'year' | 'month' | 'day';
5
+ export type Inclusiveness = '()' | '[]' | '[)' | '(]';
6
+ export type LocalDateConfig = LocalDate | IsoDateString;
7
+ export type LocalDateFormatter = (ld: LocalDate) => string;
8
8
  /**
9
9
  * @experimental
10
10
  */
@@ -1,7 +1,7 @@
1
1
  import type { IsoDateString, IsoDateTimeString, UnixTimestampMillisNumber, UnixTimestampNumber } from '../types';
2
2
  import type { Inclusiveness } from './localDate';
3
3
  import { LocalDate } from './localDate';
4
- export declare type LocalTimeUnit = 'year' | 'month' | 'week' | 'day' | 'hour' | 'minute' | 'second';
4
+ export type LocalTimeUnit = 'year' | 'month' | 'week' | 'day' | 'hour' | 'minute' | 'second';
5
5
  export declare enum ISODayOfWeek {
6
6
  MONDAY = 1,
7
7
  TUESDAY = 2,
@@ -11,8 +11,8 @@ export declare enum ISODayOfWeek {
11
11
  SATURDAY = 6,
12
12
  SUNDAY = 7
13
13
  }
14
- export declare type LocalTimeConfig = LocalTime | Date | IsoDateTimeString | UnixTimestampNumber;
15
- export declare type LocalTimeFormatter = (ld: LocalTime) => string;
14
+ export type LocalTimeConfig = LocalTime | Date | IsoDateTimeString | UnixTimestampNumber;
15
+ export type LocalTimeFormatter = (ld: LocalTime) => string;
16
16
  export interface LocalTimeComponents {
17
17
  year: number;
18
18
  month: number;
@@ -2,8 +2,8 @@ import type { UnixTimestampNumber } from '../types';
2
2
  import type { Inclusiveness } from './localDate';
3
3
  import type { LocalTimeConfig } from './localTime';
4
4
  import { LocalTime } from './localTime';
5
- export declare type TimeIntervalConfig = TimeInterval | TimeIntervalString;
6
- export declare type TimeIntervalString = string;
5
+ export type TimeIntervalConfig = TimeInterval | TimeIntervalString;
6
+ export type TimeIntervalString = string;
7
7
  /**
8
8
  * Class that supports an "interval of time" between 2 timestamps - start and end.
9
9
  * Example: `1649267185/1649267187`.
@@ -4,7 +4,7 @@ import type { CommonLogger } from '..';
4
4
  *
5
5
  * @returns array of tokens that will be `.filter(Boolean).join(' ')`
6
6
  */
7
- declare type LogResultFn = (r: any) => any[];
7
+ type LogResultFn = (r: any) => any[];
8
8
  export interface LogMethodOptions {
9
9
  /**
10
10
  * Log "moving average" elapsed time for up to `avg` last method calls
@@ -80,7 +80,7 @@ function logFinished(logger, callSignature, started, sma, logResultFn, res, err)
80
80
  if (sma) {
81
81
  t.push(`(avg ${(0, time_util_1._ms)(sma.push(millis))})`);
82
82
  }
83
- if (typeof err !== 'undefined') {
83
+ if (err !== undefined) {
84
84
  t.push('ERROR:', (0, __1._stringifyAny)(err, { includeErrorData: true }));
85
85
  }
86
86
  else if (logResultFn) {
@@ -1,5 +1,5 @@
1
1
  import type { Promisable } from '../typeFest';
2
- export declare type MemoSerializer = (args: any[]) => any;
2
+ export type MemoSerializer = (args: any[]) => any;
3
3
  export declare const jsonMemoSerializer: MemoSerializer;
4
4
  export interface MemoCache<KEY = any, VALUE = any> {
5
5
  has(k: KEY): boolean;
@@ -12,8 +12,8 @@ function _Timeout(opt) {
12
12
  const keyStr = String(key);
13
13
  descriptor.value = async function (...args) {
14
14
  const ctx = this;
15
- opt.name || (opt.name = (0, decorator_util_1._getMethodSignature)(ctx, keyStr));
16
- return await (0, pTimeout_1.pTimeout)(originalFn.apply(this, args), opt);
15
+ opt.name ||= (0, decorator_util_1._getMethodSignature)(ctx, keyStr);
16
+ return await (0, pTimeout_1.pTimeout)(() => originalFn.apply(this, args), opt);
17
17
  };
18
18
  return descriptor;
19
19
  };
@@ -1,3 +1,4 @@
1
+ import type { Class } from '../typeFest';
1
2
  import type { AnyFunction } from '../types';
2
3
  import { AppError } from './app.error';
3
4
  /**
@@ -41,10 +42,18 @@ export declare class UnexpectedPassError extends AppError {
41
42
  /**
42
43
  * Calls `fn`, expects is to throw, catches the expected error and returns.
43
44
  * If error was NOT thrown - throws UnexpectedPassError instead.
45
+ *
46
+ * If `errorClass` is passed:
47
+ * 1. It automatically infers it's type
48
+ * 2. It does `instanceof` check and throws if wrong Error instance was thrown.
44
49
  */
45
- export declare function _expectedError<ERR = Error>(fn: AnyFunction): ERR;
50
+ export declare function _expectedError<ERR = Error>(fn: AnyFunction, errorClass?: Class<ERR>): ERR;
46
51
  /**
47
52
  * Awaits passed `promise`, expects is to throw (reject), catches the expected error and returns.
48
53
  * If error was NOT thrown - throws UnexpectedPassError instead.
54
+ *
55
+ * If `errorClass` is passed:
56
+ * 1. It automatically infers it's type
57
+ * 2. It does `instanceof` check and throws if wrong Error instance was thrown.
49
58
  */
50
- export declare function pExpectedError<ERR = Error>(promise: Promise<any>): Promise<ERR>;
59
+ export declare function pExpectedError<ERR = Error>(promise: Promise<any>, errorClass?: Class<ERR>): Promise<ERR>;
package/dist/error/try.js CHANGED
@@ -62,8 +62,12 @@ exports.UnexpectedPassError = UnexpectedPassError;
62
62
  /**
63
63
  * Calls `fn`, expects is to throw, catches the expected error and returns.
64
64
  * If error was NOT thrown - throws UnexpectedPassError instead.
65
+ *
66
+ * If `errorClass` is passed:
67
+ * 1. It automatically infers it's type
68
+ * 2. It does `instanceof` check and throws if wrong Error instance was thrown.
65
69
  */
66
- function _expectedError(fn) {
70
+ function _expectedError(fn, errorClass) {
67
71
  try {
68
72
  fn();
69
73
  // Unexpected!
@@ -72,6 +76,10 @@ function _expectedError(fn) {
72
76
  catch (err) {
73
77
  if (err instanceof UnexpectedPassError)
74
78
  throw err; // re-throw
79
+ if (errorClass && !(err instanceof errorClass)) {
80
+ console.warn(`_expectedError expected ${errorClass.constructor.name} but got different error class`);
81
+ throw err;
82
+ }
75
83
  return err; // this is expected!
76
84
  }
77
85
  }
@@ -79,8 +87,12 @@ exports._expectedError = _expectedError;
79
87
  /**
80
88
  * Awaits passed `promise`, expects is to throw (reject), catches the expected error and returns.
81
89
  * If error was NOT thrown - throws UnexpectedPassError instead.
90
+ *
91
+ * If `errorClass` is passed:
92
+ * 1. It automatically infers it's type
93
+ * 2. It does `instanceof` check and throws if wrong Error instance was thrown.
82
94
  */
83
- async function pExpectedError(promise) {
95
+ async function pExpectedError(promise, errorClass) {
84
96
  try {
85
97
  await promise;
86
98
  // Unexpected!
@@ -89,6 +101,10 @@ async function pExpectedError(promise) {
89
101
  catch (err) {
90
102
  if (err instanceof UnexpectedPassError)
91
103
  throw err; // re-throw
104
+ if (errorClass && !(err instanceof errorClass)) {
105
+ console.warn(`pExpectedError expected ${errorClass.constructor.name} but got different error class`);
106
+ throw err;
107
+ }
92
108
  return err; // this is expected!
93
109
  }
94
110
  }
package/dist/is.util.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import type { Primitive } from './typeFest';
2
2
  import type { AnyObject, FalsyValue, NullishValue } from './types';
3
- declare type Nullish<T> = T extends NullishValue ? T : never;
4
- declare type Truthy<T> = T extends FalsyValue ? never : T;
5
- declare type Falsy<T> = T extends FalsyValue ? T : never;
3
+ type Nullish<T> = T extends NullishValue ? T : never;
4
+ type Truthy<T> = T extends FalsyValue ? never : T;
5
+ type Falsy<T> = T extends FalsyValue ? T : never;
6
6
  export declare const _isNull: <T>(v: T) => v is T extends null ? T : never;
7
7
  export declare const _isUndefined: <T>(v: T) => v is T extends undefined ? T : never;
8
8
  export declare const _isNullish: <T>(v: T) => v is Nullish<T>;
package/dist/is.util.js CHANGED
@@ -3,9 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports._isEmpty = exports._isEmptyObject = exports._isPrimitive = exports._isObject = exports._isFalsy = exports._isTruthy = exports._isNotNullish = exports._isNullish = exports._isUndefined = exports._isNull = void 0;
4
4
  const _isNull = (v) => v === null;
5
5
  exports._isNull = _isNull;
6
- const _isUndefined = (v) => typeof v === 'undefined';
6
+ const _isUndefined = (v) => v === undefined;
7
7
  exports._isUndefined = _isUndefined;
8
- const _isNullish = (v) => typeof v === 'undefined' || v === null;
8
+ const _isNullish = (v) => v === undefined || v === null;
9
9
  exports._isNullish = _isNullish;
10
10
  const _isNotNullish = (v) => v !== undefined && v !== null;
11
11
  exports._isNotNullish = _isNotNullish;
@@ -15,7 +15,7 @@ function objectToJsonSchema(rows) {
15
15
  const typesByKey = {};
16
16
  rows.forEach(r => {
17
17
  Object.keys(r).forEach(key => {
18
- typesByKey[key] || (typesByKey[key] = new Set());
18
+ typesByKey[key] ||= new Set();
19
19
  typesByKey[key].add(getTypeOfValue(r[key]));
20
20
  });
21
21
  });
@@ -1,5 +1,5 @@
1
1
  import type { AnyObject, StringMap } from '../types';
2
- export declare type JsonSchema<T = unknown> = JsonSchemaAny<T> | JsonSchemaOneOf<T> | JsonSchemaAllOf<T> | JsonSchemaAnyOf<T> | JsonSchemaNot<T> | JsonSchemaRef<T> | JsonSchemaConst<T> | JsonSchemaEnum<T> | JsonSchemaString | JsonSchemaNumber | JsonSchemaBoolean | JsonSchemaNull | JsonSchemaObject | JsonSchemaArray<T> | JsonSchemaTuple<T>;
2
+ export type JsonSchema<T = unknown> = JsonSchemaAny<T> | JsonSchemaOneOf<T> | JsonSchemaAllOf<T> | JsonSchemaAnyOf<T> | JsonSchemaNot<T> | JsonSchemaRef<T> | JsonSchemaConst<T> | JsonSchemaEnum<T> | JsonSchemaString | JsonSchemaNumber | JsonSchemaBoolean | JsonSchemaNull | JsonSchemaObject | JsonSchemaArray<T> | JsonSchemaTuple<T>;
3
3
  export interface JsonSchemaAny<T = unknown> {
4
4
  $schema?: string;
5
5
  $id?: string;
@@ -1,4 +1,4 @@
1
- export declare type PropertyName = string | number | symbol;
2
- export declare type RecursiveArray<T> = (T | RecursiveArray<T>)[];
3
- export declare type Many<T> = T | readonly T[];
4
- export declare type PropertyPath = Many<PropertyName>;
1
+ export type PropertyName = string | number | symbol;
2
+ export type RecursiveArray<T> = (T | RecursiveArray<T>)[];
3
+ export type Many<T> = T | readonly T[];
4
+ export type PropertyPath = Many<PropertyName>;
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * @experimental
10
10
  */
11
- export declare type CommonLogLevel = 'log' | 'warn' | 'error';
11
+ export type CommonLogLevel = 'log' | 'warn' | 'error';
12
12
  export declare const commonLogLevelNumber: Record<CommonLogLevel, number>;
13
13
  /**
14
14
  * Function that takes any number of arguments and logs them all.
@@ -16,8 +16,8 @@ export declare const commonLogLevelNumber: Record<CommonLogLevel, number>;
16
16
  *
17
17
  * @experimental
18
18
  */
19
- export declare type CommonLogFunction = (...args: any[]) => void;
20
- export declare type CommonLogWithLevelFunction = (level: CommonLogLevel, args: any[]) => void;
19
+ export type CommonLogFunction = (...args: any[]) => void;
20
+ export type CommonLogWithLevelFunction = (level: CommonLogLevel, args: any[]) => void;
21
21
  /**
22
22
  * Interface is inspired/compatible with `console.*`
23
23
  * So, `console` is a valid CommonLogger implementation as-is.
@@ -31,7 +31,7 @@ export interface PQueueCfg {
31
31
  */
32
32
  resolveOn?: 'finish' | 'start';
33
33
  }
34
- export declare type PromiseReturningFunction<R> = () => Promise<R>;
34
+ export type PromiseReturningFunction<R> = () => Promise<R>;
35
35
  /**
36
36
  * Inspired by: https://github.com/sindresorhus/p-queue
37
37
  *
@@ -54,7 +54,7 @@ class PQueue {
54
54
  const { concurrency } = this.cfg;
55
55
  const resolveOnStart = this.cfg.resolveOn === 'start';
56
56
  const fn = fn_;
57
- fn.defer || (fn.defer = (0, pDefer_1.pDefer)());
57
+ fn.defer ||= (0, pDefer_1.pDefer)();
58
58
  if (this.inFlight < concurrency) {
59
59
  // There is room for more jobs. Can start immediately
60
60
  this.inFlight++;
@@ -1,6 +1,6 @@
1
1
  import { AppError } from '../error/app.error';
2
2
  import type { ErrorData } from '../error/error.model';
3
- import type { AnyFunction } from '../types';
3
+ import type { AnyAsyncFunction } from '../types';
4
4
  export declare class TimeoutError extends AppError {
5
5
  }
6
6
  export interface PTimeoutOptions {
@@ -16,8 +16,11 @@ export interface PTimeoutOptions {
16
16
  /**
17
17
  * If provided - will be called INSTEAD of throwing an error.
18
18
  * Can be used to thrown a custom error OR resolve a promise without throwing.
19
+ *
20
+ * err (which is TimeoutError) is passed as an argument for convenience, so it can
21
+ * be logged or such. You don't have to consume it in any way though.
19
22
  */
20
- onTimeout?: () => any;
23
+ onTimeout?: (err: TimeoutError) => any;
21
24
  /**
22
25
  * Defaults to true.
23
26
  * If true - preserves the stack trace in case of a Timeout (usually - very useful!).
@@ -33,13 +36,16 @@ export interface PTimeoutOptions {
33
36
  }
34
37
  /**
35
38
  * Decorates a Function with a timeout.
39
+ * Returns a decorated Function.
40
+ *
36
41
  * Throws an Error if the Function is not resolved in a certain time.
37
42
  * If the Function rejects - passes this rejection further.
38
43
  */
39
- export declare function pTimeoutFn<T extends AnyFunction>(fn: T, opt: PTimeoutOptions): T;
44
+ export declare function pTimeoutFn<T extends AnyAsyncFunction>(fn: T, opt: PTimeoutOptions): T;
40
45
  /**
41
46
  * Decorates a Function with a timeout and immediately calls it.
47
+ *
42
48
  * Throws an Error if the Function is not resolved in a certain time.
43
49
  * If the Function rejects - passes this rejection further.
44
50
  */
45
- export declare function pTimeout<T>(promise: Promise<T>, opt: PTimeoutOptions): Promise<T>;
51
+ export declare function pTimeout<T>(fn: AnyAsyncFunction<T>, opt: PTimeoutOptions): Promise<T>;
@@ -7,32 +7,37 @@ class TimeoutError extends app_error_1.AppError {
7
7
  exports.TimeoutError = TimeoutError;
8
8
  /**
9
9
  * Decorates a Function with a timeout.
10
+ * Returns a decorated Function.
11
+ *
10
12
  * Throws an Error if the Function is not resolved in a certain time.
11
13
  * If the Function rejects - passes this rejection further.
12
14
  */
13
15
  function pTimeoutFn(fn, opt) {
14
- opt.name || (opt.name = fn.name);
16
+ opt.name ||= fn.name;
15
17
  return async function pTimeoutInternalFn(...args) {
16
- return await pTimeout(fn.apply(this, args), opt);
18
+ return await pTimeout(() => fn.apply(this, args), opt);
17
19
  };
18
20
  }
19
21
  exports.pTimeoutFn = pTimeoutFn;
20
22
  /**
21
23
  * Decorates a Function with a timeout and immediately calls it.
24
+ *
22
25
  * Throws an Error if the Function is not resolved in a certain time.
23
26
  * If the Function rejects - passes this rejection further.
24
27
  */
25
- async function pTimeout(promise, opt) {
26
- // todo: check how we can automatically infer function name (only applicable to named functions)
27
- const { timeout, name, onTimeout, keepStackTrace = true } = opt;
28
+ async function pTimeout(fn, opt) {
29
+ const { timeout, name = fn.name || 'pTimeout function', onTimeout, keepStackTrace = true } = opt;
28
30
  const fakeError = keepStackTrace ? new Error('TimeoutError') : undefined;
29
31
  // eslint-disable-next-line no-async-promise-executor
30
32
  return await new Promise(async (resolve, reject) => {
31
33
  // Prepare the timeout timer
32
34
  const timer = setTimeout(() => {
35
+ const err = new TimeoutError(`"${name}" timed out after ${timeout} ms`, opt.errorData);
36
+ if (fakeError)
37
+ err.stack = fakeError.stack; // keep original stack
33
38
  if (onTimeout) {
34
39
  try {
35
- resolve(onTimeout());
40
+ resolve(onTimeout(err));
36
41
  }
37
42
  catch (err) {
38
43
  if (fakeError)
@@ -45,14 +50,11 @@ async function pTimeout(promise, opt) {
45
50
  }
46
51
  return;
47
52
  }
48
- const err = new TimeoutError(`"${name || 'pTimeout function'}" timed out after ${timeout} ms`, opt.errorData);
49
- if (fakeError)
50
- err.stack = fakeError.stack; // keep original stack
51
53
  reject(err);
52
54
  }, timeout);
53
55
  // Execute the Function
54
56
  try {
55
- resolve(await promise);
57
+ resolve(await fn());
56
58
  }
57
59
  catch (err) {
58
60
  reject(err);
@@ -1,5 +1,5 @@
1
1
  import type { Reviver } from '../types';
2
- export declare type JsonStringifyFunction = (obj: any, reviver?: Reviver, space?: number) => string;
2
+ export type JsonStringifyFunction = (obj: any, reviver?: Reviver, space?: number) => string;
3
3
  export interface StringifyAnyOptions {
4
4
  /**
5
5
  * @default 10_000
@@ -3,11 +3,11 @@
3
3
 
4
4
  @category Basic
5
5
  */
6
- export declare type Primitive = null | undefined | string | number | boolean | symbol | bigint;
6
+ export type Primitive = null | undefined | string | number | boolean | symbol | bigint;
7
7
  /**
8
8
  Flatten the type output to improve type hints shown in editors.
9
9
  */
10
- export declare type Simplify<T> = {
10
+ export type Simplify<T> = {
11
11
  [KeyType in keyof T]: T[KeyType];
12
12
  };
13
13
  /**
@@ -15,14 +15,14 @@ export declare type Simplify<T> = {
15
15
  @link https://github.com/microsoft/TypeScript/issues/27024#issuecomment-421529650
16
16
  @link https://stackoverflow.com/questions/68961864/how-does-the-equals-work-in-typescript/68963796#68963796
17
17
  */
18
- export declare type IsEqual<T, U> = (<G>() => G extends T ? 1 : 2) extends <G>() => G extends U ? 1 : 2 ? true : false;
18
+ export type IsEqual<T, U> = (<G>() => G extends T ? 1 : 2) extends <G>() => G extends U ? 1 : 2 ? true : false;
19
19
  /**
20
20
  * Filter out keys from an object.
21
21
  * Returns `never` if `Exclude` is strictly equal to `Key`.
22
22
  * Returns `never` if `Key` extends `Exclude`.
23
23
  * Returns `Key` otherwise.
24
24
  */
25
- declare type Filter<KeyType, ExcludeType> = IsEqual<KeyType, ExcludeType> extends true ? never : KeyType extends ExcludeType ? never : KeyType;
25
+ type Filter<KeyType, ExcludeType> = IsEqual<KeyType, ExcludeType> extends true ? never : KeyType extends ExcludeType ? never : KeyType;
26
26
  /**
27
27
  Create a type from an object type without certain keys.
28
28
 
@@ -46,7 +46,7 @@ declare type Filter<KeyType, ExcludeType> = IsEqual<KeyType, ExcludeType> extend
46
46
 
47
47
  @category Utilities
48
48
  */
49
- export declare type Except<ObjectType, KeysType extends keyof ObjectType> = {
49
+ export type Except<ObjectType, KeysType extends keyof ObjectType> = {
50
50
  [KeyType in keyof ObjectType as Filter<KeyType, KeysType>]: ObjectType[KeyType];
51
51
  };
52
52
  /**
@@ -80,7 +80,7 @@ export declare type Except<ObjectType, KeysType extends keyof ObjectType> = {
80
80
 
81
81
  @category Utilities
82
82
  */
83
- export declare type ReadonlyDeep<T> = T extends Primitive | ((...args: any[]) => unknown) ? T : T extends ReadonlyMap<infer KeyType, infer ValueType> ? ReadonlyMapDeep<KeyType, ValueType> : T extends ReadonlySet<infer ItemType> ? ReadonlySetDeep<ItemType> : T extends object ? ReadonlyObjectDeep<T> : unknown;
83
+ export type ReadonlyDeep<T> = T extends Primitive | ((...args: any[]) => unknown) ? T : T extends ReadonlyMap<infer KeyType, infer ValueType> ? ReadonlyMapDeep<KeyType, ValueType> : T extends ReadonlySet<infer ItemType> ? ReadonlySetDeep<ItemType> : T extends object ? ReadonlyObjectDeep<T> : unknown;
84
84
  /**
85
85
  Same as `ReadonlyDeep`, but accepts only `ReadonlyMap`s as inputs. Internal helper for `ReadonlyDeep`.
86
86
  */
@@ -94,7 +94,7 @@ interface ReadonlySetDeep<ItemType> extends ReadonlySet<ReadonlyDeep<ItemType>>
94
94
  /**
95
95
  Same as `ReadonlyDeep`, but accepts only `object`s as inputs. Internal helper for `ReadonlyDeep`.
96
96
  */
97
- declare type ReadonlyObjectDeep<ObjectType extends object> = {
97
+ type ReadonlyObjectDeep<ObjectType extends object> = {
98
98
  readonly [KeyType in keyof ObjectType]: ReadonlyDeep<ObjectType[KeyType]>;
99
99
  };
100
100
  /**
@@ -102,7 +102,7 @@ declare type ReadonlyObjectDeep<ObjectType extends object> = {
102
102
  * This is the counterpart of `OmitIndexSignature`.
103
103
  * When you use a type that will iterate through an object that has indexed keys and explicitly defined keys you end up with a type where only the indexed keys are kept. This is because `keyof` of an indexed type always returns `string | number | symbol`, because every key is possible in that object. With this type, you can save the indexed keys and reinject them later, like in the second example below.
104
104
  */
105
- export declare type PickIndexSignature<ObjectType> = {
105
+ export type PickIndexSignature<ObjectType> = {
106
106
  [KeyType in keyof ObjectType as {} extends Record<KeyType, unknown> ? KeyType : never]: ObjectType[KeyType];
107
107
  };
108
108
  /**
@@ -115,7 +115,7 @@ export declare type PickIndexSignature<ObjectType> = {
115
115
  * It relies on the fact that an empty object (`{}`) is assignable to an object with just an index signature, like `Record<string, unknown>`, but not to an object with explicitly defined keys, like `Record<'foo' | 'bar', unknown>`.
116
116
  * (The actual value type, `unknown`, is irrelevant and could be any type. Only the key type matters.)
117
117
  */
118
- export declare type OmitIndexSignature<ObjectType> = {
118
+ export type OmitIndexSignature<ObjectType> = {
119
119
  [KeyType in keyof ObjectType as {} extends Record<KeyType, unknown> ? never : KeyType]: ObjectType[KeyType];
120
120
  };
121
121
  /**
@@ -139,7 +139,7 @@ export declare type OmitIndexSignature<ObjectType> = {
139
139
 
140
140
  @category Utilities
141
141
  */
142
- export declare type Merge<Destination, Source> = {
142
+ export type Merge<Destination, Source> = {
143
143
  [Key in keyof OmitIndexSignature<Destination & Source>]: Key extends keyof Source ? Source[Key] : Key extends keyof Destination ? Destination[Key] : never;
144
144
  } & PickIndexSignature<Destination & Source>;
145
145
  /**
@@ -166,7 +166,7 @@ export declare type Merge<Destination, Source> = {
166
166
  @category Utilities
167
167
  ```
168
168
  */
169
- export declare type Promisable<T> = T | PromiseLike<T>;
169
+ export type Promisable<T> = T | PromiseLike<T>;
170
170
  /**
171
171
  Extract the keys from a type where the value type of the key extends the given `Condition`.
172
172
  Internally this is used for the `ConditionalPick` and `ConditionalExcept` types.
@@ -190,7 +190,7 @@ export declare type Promisable<T> = T | PromiseLike<T>;
190
190
  ```
191
191
  @category Utilities
192
192
  */
193
- export declare type ConditionalKeys<Base, Condition> = NonNullable<{
193
+ export type ConditionalKeys<Base, Condition> = NonNullable<{
194
194
  [Key in keyof Base]: Base[Key] extends Condition ? Key : never;
195
195
  }[keyof Base]>;
196
196
  /**
@@ -222,7 +222,7 @@ export declare type ConditionalKeys<Base, Condition> = NonNullable<{
222
222
  ```
223
223
  @category Utilities
224
224
  */
225
- export declare type ConditionalExcept<Base, Condition> = Except<Base, ConditionalKeys<Base, Condition>>;
225
+ export type ConditionalExcept<Base, Condition> = Except<Base, ConditionalKeys<Base, Condition>>;
226
226
  /**
227
227
  Pick keys from the shape that matches the given `Condition`.
228
228
  This is useful when you want to create a new type from a specific subset of an existing type. For example, you might want to pick all the primitive properties from a class and form a new automatically derived type.
@@ -252,16 +252,16 @@ export declare type ConditionalExcept<Base, Condition> = Except<Base, Conditiona
252
252
  ```
253
253
  @category Utilities
254
254
  */
255
- export declare type ConditionalPick<Base, Condition> = Pick<Base, ConditionalKeys<Base, Condition>>;
255
+ export type ConditionalPick<Base, Condition> = Pick<Base, ConditionalKeys<Base, Condition>>;
256
256
  /**
257
257
  Matches a [`class` constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes).
258
258
  @category Basic
259
259
  */
260
- export declare type Class<T = any> = new (...args: any[]) => T;
260
+ export type Class<T = any> = new (...args: any[]) => T;
261
261
  /**
262
262
  Matches any [typed array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray), like `Uint8Array` or `Float64Array`.
263
263
  */
264
- export declare type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array | BigInt64Array | BigUint64Array;
264
+ export type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array | BigInt64Array | BigUint64Array;
265
265
  declare global {
266
266
  interface SymbolConstructor {
267
267
  readonly observable: symbol;
package/dist/types.d.ts CHANGED
@@ -11,10 +11,10 @@ export interface StringMap<T = string> {
11
11
  * Convenience shorthand for `Record<string, any>`.
12
12
  * Because `object` type is not safe/recommended to be used (e.g discouraged by eslint-typescript due to: https://github.com/microsoft/TypeScript/issues/21732)
13
13
  */
14
- export declare type AnyObject = Record<string, any>;
15
- export declare type AnyEnum = NumberEnum;
16
- export declare type NumberEnum = Record<string, number | string>;
17
- export declare type StringEnum = Record<string, string>;
14
+ export type AnyObject = Record<string, any>;
15
+ export type AnyEnum = NumberEnum;
16
+ export type NumberEnum = Record<string, number | string>;
17
+ export type StringEnum = Record<string, string>;
18
18
  export interface CreatedUpdated {
19
19
  created: number;
20
20
  updated: number;
@@ -47,17 +47,18 @@ export interface SavedDBEntity<ID extends string | number = string> {
47
47
  * hence `id`, `created` and `updated` fields CAN BE undefined (yet).
48
48
  * When it's known to be saved - `SavedDBEntity` interface can be used instead.
49
49
  */
50
- export declare type BaseDBEntity<ID extends string | number = string> = Partial<SavedDBEntity<ID>>;
51
- export declare type Saved<T extends Partial<ObjectWithId>> = T extends AnyObject ? Omit<T, 'id' | 'created' | 'updated'> & SavedDBEntity<NonNullable<T['id']>> : T;
52
- export declare type Unsaved<T extends Partial<ObjectWithId>> = T extends AnyObject ? Omit<T, 'id' | 'created' | 'updated'> & BaseDBEntity<NonNullable<T['id']>> : T;
53
- export declare type UnsavedId<T extends Partial<ObjectWithId>> = Omit<T, 'id'> & {
50
+ export type BaseDBEntity<ID extends string | number = string> = Partial<SavedDBEntity<ID>>;
51
+ export type Saved<T extends Partial<ObjectWithId>> = T extends AnyObject ? Omit<T, 'id' | 'created' | 'updated'> & SavedDBEntity<NonNullable<T['id']>> : T;
52
+ export type Unsaved<T extends Partial<ObjectWithId>> = T extends AnyObject ? Omit<T, 'id' | 'created' | 'updated'> & BaseDBEntity<NonNullable<T['id']>> : T;
53
+ export type UnsavedId<T extends Partial<ObjectWithId>> = Omit<T, 'id'> & {
54
54
  id?: T['id'];
55
55
  };
56
56
  /**
57
57
  * Convenience type shorthand.
58
58
  * Because `Function` type is discouraged by eslint.
59
59
  */
60
- export declare type AnyFunction = (...args: any[]) => any;
60
+ export type AnyFunction<T = any> = (...args: any[]) => T;
61
+ export type AnyAsyncFunction<T = any> = (...args: any[]) => Promise<T>;
61
62
  /**
62
63
  * Symbol to indicate END of Sequence.
63
64
  */
@@ -69,20 +70,20 @@ export declare const SKIP: unique symbol;
69
70
  /**
70
71
  * Function which is called for every item in `input`. Expected to return a `Promise` or value.
71
72
  */
72
- export declare type AsyncMapper<IN = any, OUT = any> = (input: IN, index: number) => OUT | PromiseLike<OUT>;
73
- export declare type Mapper<IN = any, OUT = any> = (input: IN, index: number) => OUT;
73
+ export type AsyncMapper<IN = any, OUT = any> = (input: IN, index: number) => OUT | PromiseLike<OUT>;
74
+ export type Mapper<IN = any, OUT = any> = (input: IN, index: number) => OUT;
74
75
  export declare const _passthroughMapper: Mapper;
75
76
  export declare const _passUndefinedMapper: Mapper<any, void>;
76
77
  /**
77
78
  * Function that does nothings and returns `undefined`.
78
79
  */
79
80
  export declare const _noop: (..._args: any[]) => undefined;
80
- export declare type Predicate<T> = (item: T, index: number) => boolean;
81
- export declare type AsyncPredicate<T> = (item: T, index: number) => boolean | PromiseLike<boolean>;
82
- export declare type AbortablePredicate<T> = (item: T, i: number) => boolean | typeof END;
83
- export declare type AbortableAsyncPredicate<T> = (item: T, i: number) => Promisable<boolean | typeof END>;
84
- export declare type AbortableMapper<IN = any, OUT = any> = (input: IN, i: number) => OUT | typeof SKIP | typeof END;
85
- export declare type AbortableAsyncMapper<IN = any, OUT = any> = (input: IN, i: number) => Promisable<OUT | typeof SKIP | typeof END>;
81
+ export type Predicate<T> = (item: T, index: number) => boolean;
82
+ export type AsyncPredicate<T> = (item: T, index: number) => boolean | PromiseLike<boolean>;
83
+ export type AbortablePredicate<T> = (item: T, i: number) => boolean | typeof END;
84
+ export type AbortableAsyncPredicate<T> = (item: T, i: number) => Promisable<boolean | typeof END>;
85
+ export type AbortableMapper<IN = any, OUT = any> = (input: IN, i: number) => OUT | typeof SKIP | typeof END;
86
+ export type AbortableAsyncMapper<IN = any, OUT = any> = (input: IN, i: number) => Promisable<OUT | typeof SKIP | typeof END>;
86
87
  export declare const _passthroughPredicate: Predicate<any>;
87
88
  export declare const _passNothingPredicate: Predicate<any>;
88
89
  export interface BatchResult<RES = any, ERR = Error> {
@@ -105,7 +106,7 @@ export interface BatchResult<RES = any, ERR = Error> {
105
106
  * const arr = ['a', 'b'] as const
106
107
  * type Foo = ValuesOf<typeof arr> // 'a' | 'b'
107
108
  */
108
- export declare type ValuesOf<T extends readonly any[]> = T[number];
109
+ export type ValuesOf<T extends readonly any[]> = T[number];
109
110
  /**
110
111
  * Based on: https://stackoverflow.com/a/49286056/4919972
111
112
  *
@@ -114,10 +115,10 @@ export declare type ValuesOf<T extends readonly any[]> = T[number];
114
115
  * type Foo = { a: string, b: number }
115
116
  * type ValueOfFoo = ValueOf<Foo> // string | number
116
117
  */
117
- export declare type ValueOf<T> = T[keyof T];
118
- export declare type KeyValueTuple<K, V> = [key: K, value: V];
119
- export declare type ObjectMapper<OBJ, OUT> = (key: string, value: Exclude<OBJ[keyof OBJ], undefined>, obj: OBJ) => OUT;
120
- export declare type ObjectPredicate<OBJ> = (key: keyof OBJ, value: Exclude<OBJ[keyof OBJ], undefined>, obj: OBJ) => boolean;
118
+ export type ValueOf<T> = T[keyof T];
119
+ export type KeyValueTuple<K, V> = [key: K, value: V];
120
+ export type ObjectMapper<OBJ, OUT> = (key: string, value: Exclude<OBJ[keyof OBJ], undefined>, obj: OBJ) => OUT;
121
+ export type ObjectPredicate<OBJ> = (key: keyof OBJ, value: Exclude<OBJ[keyof OBJ], undefined>, obj: OBJ) => boolean;
121
122
  /**
122
123
  * Allows to identify instance of Class by `instanceId`.
123
124
  */
@@ -132,44 +133,44 @@ export interface InstanceId {
132
133
  *
133
134
  * @example '2019-06-21'
134
135
  */
135
- export declare type IsoDateString = string;
136
+ export type IsoDateString = string;
136
137
  /**
137
138
  * @deprecated use IsoDateString
138
139
  */
139
- export declare type IsoDate = string;
140
+ export type IsoDate = string;
140
141
  /**
141
142
  * Interface explicitly states that the value is an ISO DateTime string (with time).
142
143
  *
143
144
  * @example '2019-06-21T05:21:73Z'
144
145
  */
145
- export declare type IsoDateTimeString = string;
146
+ export type IsoDateTimeString = string;
146
147
  /**
147
148
  * Interface explicitly states that the value is a Unix timestamp (in seconds).
148
149
  *
149
150
  * @example 1628945450
150
151
  */
151
- export declare type UnixTimestampNumber = number;
152
+ export type UnixTimestampNumber = number;
152
153
  /**
153
154
  * Interface explicitly states that the value is a "Unix timestamp in **milleseconds**" (not seconds)
154
155
  *
155
156
  * @example 1628945450000
156
157
  */
157
- export declare type UnixTimestampMillisNumber = number;
158
+ export type UnixTimestampMillisNumber = number;
158
159
  /**
159
160
  * @deprecated use UnixTimestampNumber
160
161
  */
161
- export declare type UnixTimestamp = number;
162
+ export type UnixTimestamp = number;
162
163
  /**
163
164
  * Same as `number`, but with semantic meaning that it's an Integer.
164
165
  */
165
- export declare type Integer = number;
166
- export declare type Base64String = string;
167
- export declare type Base64UrlString = string;
168
- export declare type JWTString = string;
166
+ export type Integer = number;
167
+ export type Base64String = string;
168
+ export type Base64UrlString = string;
169
+ export type JWTString = string;
169
170
  /**
170
171
  * Named type for JSON.parse / JSON.stringify second argument
171
172
  */
172
- export declare type Reviver = (this: any, key: string, value: any) => any;
173
+ export type Reviver = (this: any, key: string, value: any) => any;
173
174
  /**
174
175
  * Needed due to https://github.com/microsoft/TypeScript/issues/13778
175
176
  * Only affects typings, no runtime effect.
@@ -185,8 +186,8 @@ export declare const _stringMapEntries: <T>(m: StringMap<T>) => [k: string, v: T
185
186
  * This is how TypeScript should work, actually.
186
187
  */
187
188
  export declare const _objectKeys: <T extends AnyObject>(obj: T) => (keyof T)[];
188
- export declare type NullishValue = null | undefined;
189
- export declare type FalsyValue = false | '' | 0 | null | undefined;
189
+ export type NullishValue = null | undefined;
190
+ export type FalsyValue = false | '' | 0 | null | undefined;
190
191
  /**
191
192
  * Utility function that helps to cast *existing variable* to needed type T.
192
193
  *
@@ -5,10 +5,10 @@
5
5
  /// <reference lib="dom" />
6
6
  import { Class, ObservableLike, Primitive, TypedArray } from '../typeFest';
7
7
  declare const objectTypeNames: readonly ["Function", "Generator", "AsyncGenerator", "GeneratorFunction", "AsyncGeneratorFunction", "AsyncFunction", "Observable", "Array", "Buffer", "Object", "RegExp", "Date", "Error", "Map", "Set", "WeakMap", "WeakSet", "ArrayBuffer", "SharedArrayBuffer", "DataView", "Promise", "URL", "FormData", "URLSearchParams", "HTMLElement", "Int8Array", "Uint8Array", "Uint8ClampedArray", "Int16Array", "Uint16Array", "Int32Array", "Uint32Array", "Float32Array", "Float64Array", "BigInt64Array", "BigUint64Array"];
8
- declare type ObjectTypeName = typeof objectTypeNames[number];
8
+ type ObjectTypeName = typeof objectTypeNames[number];
9
9
  declare const primitiveTypeNames: readonly ["null", "undefined", "string", "number", "bigint", "boolean", "symbol"];
10
- declare type PrimitiveTypeName = typeof primitiveTypeNames[number];
11
- export declare type TypeName = ObjectTypeName | PrimitiveTypeName;
10
+ type PrimitiveTypeName = typeof primitiveTypeNames[number];
11
+ export type TypeName = ObjectTypeName | PrimitiveTypeName;
12
12
  export declare function is(value: unknown): TypeName;
13
13
  export declare namespace is {
14
14
  var undefined: (value: unknown) => value is undefined;
@@ -101,7 +101,7 @@ export interface NodeStream extends NodeJS.EventEmitter {
101
101
  end?: boolean;
102
102
  }): T;
103
103
  }
104
- export declare type Predicate = (value: unknown) => boolean;
104
+ export type Predicate = (value: unknown) => boolean;
105
105
  export declare const enum AssertionTypeDescription {
106
106
  class_ = "Class",
107
107
  numericString = "string with a number",
@@ -76,7 +76,7 @@ function logFinished(logger, callSignature, started, sma, logResultFn, res, err)
76
76
  if (sma) {
77
77
  t.push(`(avg ${_ms(sma.push(millis))})`);
78
78
  }
79
- if (typeof err !== 'undefined') {
79
+ if (err !== undefined) {
80
80
  t.push('ERROR:', _stringifyAny(err, { includeErrorData: true }));
81
81
  }
82
82
  else if (logResultFn) {
@@ -10,7 +10,7 @@ export function _Timeout(opt) {
10
10
  descriptor.value = async function (...args) {
11
11
  const ctx = this;
12
12
  opt.name || (opt.name = _getMethodSignature(ctx, keyStr));
13
- return await pTimeout(originalFn.apply(this, args), opt);
13
+ return await pTimeout(() => originalFn.apply(this, args), opt);
14
14
  };
15
15
  return descriptor;
16
16
  };
@@ -56,8 +56,12 @@ export class UnexpectedPassError extends AppError {
56
56
  /**
57
57
  * Calls `fn`, expects is to throw, catches the expected error and returns.
58
58
  * If error was NOT thrown - throws UnexpectedPassError instead.
59
+ *
60
+ * If `errorClass` is passed:
61
+ * 1. It automatically infers it's type
62
+ * 2. It does `instanceof` check and throws if wrong Error instance was thrown.
59
63
  */
60
- export function _expectedError(fn) {
64
+ export function _expectedError(fn, errorClass) {
61
65
  try {
62
66
  fn();
63
67
  // Unexpected!
@@ -66,14 +70,22 @@ export function _expectedError(fn) {
66
70
  catch (err) {
67
71
  if (err instanceof UnexpectedPassError)
68
72
  throw err; // re-throw
73
+ if (errorClass && !(err instanceof errorClass)) {
74
+ console.warn(`_expectedError expected ${errorClass.constructor.name} but got different error class`);
75
+ throw err;
76
+ }
69
77
  return err; // this is expected!
70
78
  }
71
79
  }
72
80
  /**
73
81
  * Awaits passed `promise`, expects is to throw (reject), catches the expected error and returns.
74
82
  * If error was NOT thrown - throws UnexpectedPassError instead.
83
+ *
84
+ * If `errorClass` is passed:
85
+ * 1. It automatically infers it's type
86
+ * 2. It does `instanceof` check and throws if wrong Error instance was thrown.
75
87
  */
76
- export async function pExpectedError(promise) {
88
+ export async function pExpectedError(promise, errorClass) {
77
89
  try {
78
90
  await promise;
79
91
  // Unexpected!
@@ -82,6 +94,10 @@ export async function pExpectedError(promise) {
82
94
  catch (err) {
83
95
  if (err instanceof UnexpectedPassError)
84
96
  throw err; // re-throw
97
+ if (errorClass && !(err instanceof errorClass)) {
98
+ console.warn(`pExpectedError expected ${errorClass.constructor.name} but got different error class`);
99
+ throw err;
100
+ }
85
101
  return err; // this is expected!
86
102
  }
87
103
  }
@@ -1,6 +1,6 @@
1
1
  export const _isNull = (v) => v === null;
2
- export const _isUndefined = (v) => typeof v === 'undefined';
3
- export const _isNullish = (v) => typeof v === 'undefined' || v === null;
2
+ export const _isUndefined = (v) => v === undefined;
3
+ export const _isNullish = (v) => v === undefined || v === null;
4
4
  export const _isNotNullish = (v) => v !== undefined && v !== null;
5
5
  /**
6
6
  * Same as Boolean, but with correct type output.
@@ -36,7 +36,7 @@ import { AggregatedError } from './AggregatedError';
36
36
  * })();
37
37
  */
38
38
  export async function pMap(iterable, mapper, opt = {}) {
39
- var e_1, _a;
39
+ var _a, e_1, _b, _c;
40
40
  const ret = [];
41
41
  // const iterator = iterable[Symbol.iterator]()
42
42
  const items = [...iterable];
@@ -52,29 +52,36 @@ export async function pMap(iterable, mapper, opt = {}) {
52
52
  if (concurrency === 1) {
53
53
  try {
54
54
  // Special case for concurrency == 1
55
- for (var items_1 = __asyncValues(items), items_1_1; items_1_1 = await items_1.next(), !items_1_1.done;) {
56
- const item = items_1_1.value;
55
+ for (var _d = true, items_1 = __asyncValues(items), items_1_1; items_1_1 = await items_1.next(), _a = items_1_1.done, !_a;) {
56
+ _c = items_1_1.value;
57
+ _d = false;
57
58
  try {
58
- const r = await mapper(item, currentIndex++);
59
- if (r === END)
60
- break;
61
- if (r !== SKIP)
62
- ret.push(r);
63
- }
64
- catch (err) {
65
- if (errorMode === ErrorMode.THROW_IMMEDIATELY)
66
- throw err;
67
- if (errorMode === ErrorMode.THROW_AGGREGATED) {
68
- errors.push(err);
59
+ const item = _c;
60
+ try {
61
+ const r = await mapper(item, currentIndex++);
62
+ if (r === END)
63
+ break;
64
+ if (r !== SKIP)
65
+ ret.push(r);
69
66
  }
70
- // otherwise, suppress completely
67
+ catch (err) {
68
+ if (errorMode === ErrorMode.THROW_IMMEDIATELY)
69
+ throw err;
70
+ if (errorMode === ErrorMode.THROW_AGGREGATED) {
71
+ errors.push(err);
72
+ }
73
+ // otherwise, suppress completely
74
+ }
75
+ }
76
+ finally {
77
+ _d = true;
71
78
  }
72
79
  }
73
80
  }
74
81
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
75
82
  finally {
76
83
  try {
77
- if (items_1_1 && !items_1_1.done && (_a = items_1.return)) await _a.call(items_1);
84
+ if (!_d && !_a && (_b = items_1.return)) await _b.call(items_1);
78
85
  }
79
86
  finally { if (e_1) throw e_1.error; }
80
87
  }
@@ -3,31 +3,36 @@ export class TimeoutError extends AppError {
3
3
  }
4
4
  /**
5
5
  * Decorates a Function with a timeout.
6
+ * Returns a decorated Function.
7
+ *
6
8
  * Throws an Error if the Function is not resolved in a certain time.
7
9
  * If the Function rejects - passes this rejection further.
8
10
  */
9
11
  export function pTimeoutFn(fn, opt) {
10
12
  opt.name || (opt.name = fn.name);
11
13
  return async function pTimeoutInternalFn(...args) {
12
- return await pTimeout(fn.apply(this, args), opt);
14
+ return await pTimeout(() => fn.apply(this, args), opt);
13
15
  };
14
16
  }
15
17
  /**
16
18
  * Decorates a Function with a timeout and immediately calls it.
19
+ *
17
20
  * Throws an Error if the Function is not resolved in a certain time.
18
21
  * If the Function rejects - passes this rejection further.
19
22
  */
20
- export async function pTimeout(promise, opt) {
21
- // todo: check how we can automatically infer function name (only applicable to named functions)
22
- const { timeout, name, onTimeout, keepStackTrace = true } = opt;
23
+ export async function pTimeout(fn, opt) {
24
+ const { timeout, name = fn.name || 'pTimeout function', onTimeout, keepStackTrace = true } = opt;
23
25
  const fakeError = keepStackTrace ? new Error('TimeoutError') : undefined;
24
26
  // eslint-disable-next-line no-async-promise-executor
25
27
  return await new Promise(async (resolve, reject) => {
26
28
  // Prepare the timeout timer
27
29
  const timer = setTimeout(() => {
30
+ const err = new TimeoutError(`"${name}" timed out after ${timeout} ms`, opt.errorData);
31
+ if (fakeError)
32
+ err.stack = fakeError.stack; // keep original stack
28
33
  if (onTimeout) {
29
34
  try {
30
- resolve(onTimeout());
35
+ resolve(onTimeout(err));
31
36
  }
32
37
  catch (err) {
33
38
  if (fakeError)
@@ -37,14 +42,11 @@ export async function pTimeout(promise, opt) {
37
42
  }
38
43
  return;
39
44
  }
40
- const err = new TimeoutError(`"${name || 'pTimeout function'}" timed out after ${timeout} ms`, opt.errorData);
41
- if (fakeError)
42
- err.stack = fakeError.stack; // keep original stack
43
45
  reject(err);
44
46
  }, timeout);
45
47
  // Execute the Function
46
48
  try {
47
- resolve(await promise);
49
+ resolve(await fn());
48
50
  }
49
51
  catch (err) {
50
52
  reject(err);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naturalcycles/js-lib",
3
- "version": "14.115.2",
3
+ "version": "14.117.0",
4
4
  "scripts": {
5
5
  "prepare": "husky install",
6
6
  "build-prod": "build-prod-esm-cjs",
@@ -154,7 +154,7 @@ function logFinished(
154
154
  t.push(`(avg ${_ms(sma.push(millis))})`)
155
155
  }
156
156
 
157
- if (typeof err !== 'undefined') {
157
+ if (err !== undefined) {
158
158
  t.push('ERROR:', _stringifyAny(err, { includeErrorData: true }))
159
159
  } else if (logResultFn) {
160
160
  t.push(...logResultFn(res))
@@ -14,7 +14,7 @@ export function _Timeout(opt: PTimeoutOptions): MethodDecorator {
14
14
  descriptor.value = async function (this: typeof target, ...args: any[]) {
15
15
  const ctx = this
16
16
  opt.name ||= _getMethodSignature(ctx, keyStr)
17
- return await pTimeout(originalFn.apply(this, args), opt)
17
+ return await pTimeout(() => originalFn.apply(this, args), opt)
18
18
  } as any
19
19
 
20
20
  return descriptor
package/src/error/try.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { Class } from '../typeFest'
1
2
  import type { AnyFunction } from '../types'
2
3
  import { AppError } from './app.error'
3
4
 
@@ -63,14 +64,24 @@ export class UnexpectedPassError extends AppError {
63
64
  /**
64
65
  * Calls `fn`, expects is to throw, catches the expected error and returns.
65
66
  * If error was NOT thrown - throws UnexpectedPassError instead.
67
+ *
68
+ * If `errorClass` is passed:
69
+ * 1. It automatically infers it's type
70
+ * 2. It does `instanceof` check and throws if wrong Error instance was thrown.
66
71
  */
67
- export function _expectedError<ERR = Error>(fn: AnyFunction): ERR {
72
+ export function _expectedError<ERR = Error>(fn: AnyFunction, errorClass?: Class<ERR>): ERR {
68
73
  try {
69
74
  fn()
70
75
  // Unexpected!
71
76
  throw new UnexpectedPassError()
72
77
  } catch (err) {
73
78
  if (err instanceof UnexpectedPassError) throw err // re-throw
79
+ if (errorClass && !(err instanceof errorClass)) {
80
+ console.warn(
81
+ `_expectedError expected ${errorClass.constructor.name} but got different error class`,
82
+ )
83
+ throw err
84
+ }
74
85
  return err as ERR // this is expected!
75
86
  }
76
87
  }
@@ -78,14 +89,27 @@ export function _expectedError<ERR = Error>(fn: AnyFunction): ERR {
78
89
  /**
79
90
  * Awaits passed `promise`, expects is to throw (reject), catches the expected error and returns.
80
91
  * If error was NOT thrown - throws UnexpectedPassError instead.
92
+ *
93
+ * If `errorClass` is passed:
94
+ * 1. It automatically infers it's type
95
+ * 2. It does `instanceof` check and throws if wrong Error instance was thrown.
81
96
  */
82
- export async function pExpectedError<ERR = Error>(promise: Promise<any>): Promise<ERR> {
97
+ export async function pExpectedError<ERR = Error>(
98
+ promise: Promise<any>,
99
+ errorClass?: Class<ERR>,
100
+ ): Promise<ERR> {
83
101
  try {
84
102
  await promise
85
103
  // Unexpected!
86
104
  throw new UnexpectedPassError()
87
105
  } catch (err) {
88
106
  if (err instanceof UnexpectedPassError) throw err // re-throw
107
+ if (errorClass && !(err instanceof errorClass)) {
108
+ console.warn(
109
+ `pExpectedError expected ${errorClass.constructor.name} but got different error class`,
110
+ )
111
+ throw err
112
+ }
89
113
  return err as ERR // this is expected!
90
114
  }
91
115
  }
package/src/is.util.ts CHANGED
@@ -6,9 +6,8 @@ type Truthy<T> = T extends FalsyValue ? never : T
6
6
  type Falsy<T> = T extends FalsyValue ? T : never
7
7
 
8
8
  export const _isNull = <T>(v: T): v is T extends null ? T : never => v === null
9
- export const _isUndefined = <T>(v: T): v is T extends undefined ? T : never =>
10
- typeof v === 'undefined'
11
- export const _isNullish = <T>(v: T): v is Nullish<T> => typeof v === 'undefined' || v === null
9
+ export const _isUndefined = <T>(v: T): v is T extends undefined ? T : never => v === undefined
10
+ export const _isNullish = <T>(v: T): v is Nullish<T> => v === undefined || v === null
12
11
  export const _isNotNullish = <T>(v: T): v is NonNullable<T> => v !== undefined && v !== null
13
12
 
14
13
  /**
@@ -1,6 +1,6 @@
1
1
  import { AppError } from '../error/app.error'
2
2
  import type { ErrorData } from '../error/error.model'
3
- import type { AnyFunction } from '../types'
3
+ import type { AnyAsyncFunction } from '../types'
4
4
 
5
5
  export class TimeoutError extends AppError {}
6
6
 
@@ -19,8 +19,11 @@ export interface PTimeoutOptions {
19
19
  /**
20
20
  * If provided - will be called INSTEAD of throwing an error.
21
21
  * Can be used to thrown a custom error OR resolve a promise without throwing.
22
+ *
23
+ * err (which is TimeoutError) is passed as an argument for convenience, so it can
24
+ * be logged or such. You don't have to consume it in any way though.
22
25
  */
23
- onTimeout?: () => any
26
+ onTimeout?: (err: TimeoutError) => any
24
27
 
25
28
  /**
26
29
  * Defaults to true.
@@ -39,34 +42,39 @@ export interface PTimeoutOptions {
39
42
 
40
43
  /**
41
44
  * Decorates a Function with a timeout.
45
+ * Returns a decorated Function.
46
+ *
42
47
  * Throws an Error if the Function is not resolved in a certain time.
43
48
  * If the Function rejects - passes this rejection further.
44
49
  */
45
- export function pTimeoutFn<T extends AnyFunction>(fn: T, opt: PTimeoutOptions): T {
50
+ export function pTimeoutFn<T extends AnyAsyncFunction>(fn: T, opt: PTimeoutOptions): T {
46
51
  opt.name ||= fn.name
47
52
 
48
53
  return async function pTimeoutInternalFn(this: any, ...args: any[]) {
49
- return await pTimeout(fn.apply(this, args), opt)
50
- } as any
54
+ return await pTimeout(() => fn.apply(this, args), opt)
55
+ } as T
51
56
  }
52
57
 
53
58
  /**
54
59
  * Decorates a Function with a timeout and immediately calls it.
60
+ *
55
61
  * Throws an Error if the Function is not resolved in a certain time.
56
62
  * If the Function rejects - passes this rejection further.
57
63
  */
58
- export async function pTimeout<T>(promise: Promise<T>, opt: PTimeoutOptions): Promise<T> {
59
- // todo: check how we can automatically infer function name (only applicable to named functions)
60
- const { timeout, name, onTimeout, keepStackTrace = true } = opt
64
+ export async function pTimeout<T>(fn: AnyAsyncFunction<T>, opt: PTimeoutOptions): Promise<T> {
65
+ const { timeout, name = fn.name || 'pTimeout function', onTimeout, keepStackTrace = true } = opt
61
66
  const fakeError = keepStackTrace ? new Error('TimeoutError') : undefined
62
67
 
63
68
  // eslint-disable-next-line no-async-promise-executor
64
69
  return await new Promise(async (resolve, reject) => {
65
70
  // Prepare the timeout timer
66
71
  const timer = setTimeout(() => {
72
+ const err = new TimeoutError(`"${name}" timed out after ${timeout} ms`, opt.errorData)
73
+ if (fakeError) err.stack = fakeError.stack // keep original stack
74
+
67
75
  if (onTimeout) {
68
76
  try {
69
- resolve(onTimeout())
77
+ resolve(onTimeout(err))
70
78
  } catch (err: any) {
71
79
  if (fakeError) err.stack = fakeError.stack // keep original stack
72
80
  err.data = {
@@ -78,17 +86,12 @@ export async function pTimeout<T>(promise: Promise<T>, opt: PTimeoutOptions): Pr
78
86
  return
79
87
  }
80
88
 
81
- const err = new TimeoutError(
82
- `"${name || 'pTimeout function'}" timed out after ${timeout} ms`,
83
- opt.errorData,
84
- )
85
- if (fakeError) err.stack = fakeError.stack // keep original stack
86
89
  reject(err)
87
90
  }, timeout)
88
91
 
89
92
  // Execute the Function
90
93
  try {
91
- resolve(await promise)
94
+ resolve(await fn())
92
95
  } catch (err) {
93
96
  reject(err)
94
97
  } finally {
package/src/types.ts CHANGED
@@ -78,7 +78,8 @@ export type UnsavedId<T extends Partial<ObjectWithId>> = Omit<T, 'id'> & {
78
78
  * Convenience type shorthand.
79
79
  * Because `Function` type is discouraged by eslint.
80
80
  */
81
- export type AnyFunction = (...args: any[]) => any
81
+ export type AnyFunction<T = any> = (...args: any[]) => T
82
+ export type AnyAsyncFunction<T = any> = (...args: any[]) => Promise<T>
82
83
 
83
84
  /**
84
85
  * Symbol to indicate END of Sequence.