@naturalcycles/js-lib 14.74.0 → 14.77.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/seq/seq.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports._seq = exports.Seq = void 0;
3
+ exports.AsyncSequence = exports._seq = exports.Sequence = void 0;
4
4
  const types_1 = require("../types");
5
5
  /**
6
6
  * Inspired by Kotlin Sequences.
@@ -10,7 +10,7 @@ const types_1 = require("../types");
10
10
  *
11
11
  * @experimental
12
12
  */
13
- class Seq {
13
+ class Sequence {
14
14
  constructor(initialValue, nextFn) {
15
15
  this.nextFn = nextFn;
16
16
  this.sentInitialValue = false;
@@ -26,18 +26,18 @@ class Seq {
26
26
  };
27
27
  }
28
28
  static create(initialValue, nextFn) {
29
- return new Seq(initialValue, nextFn);
29
+ return new Sequence(initialValue, nextFn);
30
30
  }
31
31
  static range(minIncl, maxExcl, step = 1) {
32
32
  const max = maxExcl - step;
33
- return new Seq(minIncl, n => (n < max ? n + step : types_1.END));
33
+ return new Sequence(minIncl, n => (n < max ? n + step : types_1.END));
34
34
  }
35
35
  static from(a) {
36
36
  const it = a[Symbol.iterator]();
37
37
  const v = it.next();
38
38
  if (v.done)
39
- return new Seq(types_1.END, () => { });
40
- return new Seq(v.value, () => {
39
+ return new Sequence(types_1.END, () => { });
40
+ return new Sequence(v.value, () => {
41
41
  const v = it.next();
42
42
  if (v.done)
43
43
  return types_1.END;
@@ -45,7 +45,7 @@ class Seq {
45
45
  });
46
46
  }
47
47
  static empty() {
48
- return new Seq(types_1.END, () => { });
48
+ return new Sequence(types_1.END, () => { });
49
49
  }
50
50
  next() {
51
51
  if (this.currentValue === types_1.END)
@@ -130,12 +130,129 @@ class Seq {
130
130
  a.push(v);
131
131
  }
132
132
  }
133
+ forEach(fn) {
134
+ let i = -1;
135
+ // eslint-disable-next-line no-constant-condition
136
+ while (true) {
137
+ const v = this.next();
138
+ if (v === types_1.END)
139
+ return;
140
+ fn(v, ++i);
141
+ }
142
+ }
133
143
  }
134
- exports.Seq = Seq;
144
+ exports.Sequence = Sequence;
135
145
  /**
136
146
  * Convenience function to create a Sequence.
137
147
  */
138
148
  function _seq(initialValue, nextFn) {
139
- return Seq.create(initialValue, nextFn);
149
+ return Sequence.create(initialValue, nextFn);
140
150
  }
141
151
  exports._seq = _seq;
152
+ /* eslint-disable no-await-in-loop */
153
+ /**
154
+ * Experimental.
155
+ * Feasibility to be proven.
156
+ *
157
+ * @experimental
158
+ */
159
+ class AsyncSequence {
160
+ constructor(initialValue, nextFn) {
161
+ this.nextFn = nextFn;
162
+ this.sentInitialValue = false;
163
+ this.i = -1;
164
+ this.currentValue = initialValue;
165
+ }
166
+ [Symbol.asyncIterator]() {
167
+ return {
168
+ next: async () => {
169
+ const value = await this.next();
170
+ return value === types_1.END ? { done: true, value: undefined } : { value };
171
+ },
172
+ };
173
+ }
174
+ static create(initialValue, nextFn) {
175
+ return new AsyncSequence(initialValue, nextFn);
176
+ }
177
+ static async from(a) {
178
+ const it = a[Symbol.asyncIterator]();
179
+ const v = await it.next();
180
+ if (v.done)
181
+ return new AsyncSequence(types_1.END, () => { });
182
+ return new AsyncSequence(v.value, async () => {
183
+ const v = await it.next();
184
+ if (v.done)
185
+ return types_1.END;
186
+ return v.value;
187
+ });
188
+ }
189
+ static empty() {
190
+ return new AsyncSequence(types_1.END, () => { });
191
+ }
192
+ async next() {
193
+ if (this.currentValue === types_1.END)
194
+ return types_1.END;
195
+ this.i++;
196
+ let v;
197
+ if (!this.sentInitialValue) {
198
+ this.sentInitialValue = true;
199
+ v = this.currentValue;
200
+ }
201
+ else {
202
+ v = await this.nextFn(this.currentValue, this.i);
203
+ }
204
+ // console.log(`_seq`, v)
205
+ if (v === types_1.SKIP)
206
+ return await this.next();
207
+ return (this.currentValue = v);
208
+ }
209
+ // Final functions - return final value, not a chained sequence
210
+ async find(predicate) {
211
+ do {
212
+ const v = await this.next();
213
+ if (v === types_1.END)
214
+ return; // not found, end of sequence
215
+ const r = await predicate(v, this.i);
216
+ if (r === types_1.END)
217
+ return;
218
+ if (r)
219
+ return v;
220
+ // otherwise proceed
221
+ } while (true); // eslint-disable-line no-constant-condition
222
+ }
223
+ async some(predicate) {
224
+ do {
225
+ const v = await this.next();
226
+ if (v === types_1.END)
227
+ return false;
228
+ const r = await predicate(v, this.i);
229
+ if (r === types_1.END)
230
+ return false;
231
+ if (r)
232
+ return true;
233
+ } while (true); // eslint-disable-line no-constant-condition
234
+ }
235
+ async every(predicate) {
236
+ do {
237
+ const v = await this.next();
238
+ if (v === types_1.END)
239
+ return true;
240
+ const r = await predicate(v, this.i);
241
+ if (r === types_1.END)
242
+ return true;
243
+ if (!r)
244
+ return false;
245
+ } while (true); // eslint-disable-line no-constant-condition
246
+ }
247
+ async toArray() {
248
+ const a = [];
249
+ // eslint-disable-next-line no-constant-condition
250
+ while (true) {
251
+ const v = await this.next();
252
+ if (v === types_1.END)
253
+ return a;
254
+ a.push(v);
255
+ }
256
+ }
257
+ }
258
+ exports.AsyncSequence = AsyncSequence;
@@ -44,17 +44,19 @@ function _stringifyAny(obj, opt = {}) {
44
44
  //
45
45
  // Error or ErrorObject
46
46
  //
47
+ // Omit "default" error name as non-informative
48
+ // UPD: no, it's still important to understand that we're dealing with Error and not just some string
49
+ // if (obj?.name === 'Error') {
50
+ // s = obj.message
51
+ // }
52
+ s = [obj.name, obj.message].join(': ');
47
53
  if (opt.includeErrorStack && obj.stack) {
48
- // Stack includes message
49
- s = obj.stack;
50
- }
51
- else {
52
- // Omit "default" error name as non-informative
53
- // UPD: no, it's still important to understand that we're dealing with Error and not just some string
54
- // if (obj?.name === 'Error') {
55
- // s = obj.message
56
- // }
57
- s = [obj.name, obj.message].join(': ');
54
+ // Here we're using the previously-generated "title line" (e.g "Error: some_message"),
55
+ // concatenating it with the Stack (but without the title line of the Stack)
56
+ // This is to fix the rare error (happened with Got) where `err.message` was changed,
57
+ // but err.stack had "old" err.message
58
+ // This should "fix" that
59
+ s = [s, ...obj.stack.split('\n').slice(1)].join('\n');
58
60
  }
59
61
  if ((0, error_util_1._isErrorObject)(obj)) {
60
62
  if ((0, error_util_1._isHttpErrorObject)(obj)) {
@@ -5,3 +5,9 @@ export declare function _kb(b: number): number;
5
5
  * Byte size to Human byte size string
6
6
  */
7
7
  export declare function _hb(b?: number): string;
8
+ /**
9
+ * hc stands for "human count", similar to "human bytes" `_hb` function.
10
+ * Helpful to print big numbers, as it adds `K` (kilo), `M` (mega), etc to make
11
+ * them more readable.
12
+ */
13
+ export declare function _hc(c?: number): string;
@@ -1,12 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports._hb = exports._kb = exports._mb = exports._gb = void 0;
3
+ exports._hc = exports._hb = exports._kb = exports._mb = exports._gb = void 0;
4
4
  function _gb(b) {
5
- return Math.round(b / (1024 * 1024 * 1024));
5
+ return Math.round(b / 1024 ** 3);
6
6
  }
7
7
  exports._gb = _gb;
8
8
  function _mb(b) {
9
- return Math.round(b / (1024 * 1024));
9
+ return Math.round(b / 1024 ** 2);
10
10
  }
11
11
  exports._mb = _mb;
12
12
  function _kb(b) {
@@ -17,12 +17,35 @@ exports._kb = _kb;
17
17
  * Byte size to Human byte size string
18
18
  */
19
19
  function _hb(b = 0) {
20
- if (b < 800)
21
- return `${Math.round(b)} byte(s)`;
22
- if (b < 800 * 1024)
23
- return `${Math.round(b / 1024)} Kb`;
24
- if (b < 800 * 1024 * 1024)
25
- return `${Math.round(b / 1024 / 1024)} Mb`;
26
- return `${Math.round(b / 1024 / 1024 / 1024)} Gb`;
20
+ if (b < 1024)
21
+ return `${Math.round(b)} byte`;
22
+ if (b < 1024 ** 2)
23
+ return `${(b / 1024).toPrecision(3)} Kb`;
24
+ if (b < 1024 ** 3)
25
+ return `${(b / 1024 ** 2).toPrecision(3)} Mb`;
26
+ if (b < 1024 ** 4)
27
+ return `${(b / 1024 ** 3).toPrecision(3)} Gb`;
28
+ if (b < 1024 ** 5)
29
+ return `${(b / 1024 ** 4).toPrecision(3)} Tb`;
30
+ return `${Math.round(b / 1024 ** 4)} Tb`;
27
31
  }
28
32
  exports._hb = _hb;
33
+ /**
34
+ * hc stands for "human count", similar to "human bytes" `_hb` function.
35
+ * Helpful to print big numbers, as it adds `K` (kilo), `M` (mega), etc to make
36
+ * them more readable.
37
+ */
38
+ function _hc(c = 0) {
39
+ if (c < 10 ** 4)
40
+ return String(c);
41
+ if (c < 10 ** 6)
42
+ return (c / 10 ** 3).toPrecision(3) + ' K';
43
+ if (c < 10 ** 9)
44
+ return (c / 10 ** 6).toPrecision(3) + ' M'; // million
45
+ if (c < 10 ** 12)
46
+ return (c / 10 ** 9).toPrecision(3) + ' B'; // billion
47
+ if (c < 10 ** 15)
48
+ return (c / 10 ** 12).toPrecision(3) + ' T'; // trillion
49
+ return Math.round(c / 10 ** 12) + ' T';
50
+ }
51
+ exports._hc = _hc;
@@ -1,4 +1,4 @@
1
- import { SimpleMovingAverage, _stringifyAny } from '..';
1
+ import { SimpleMovingAverage, _stringifyAny, _assert } from '..';
2
2
  import { _ms } from '../time/time.util';
3
3
  import { _getArgsSignature, _getMethodSignature } from './decorator.util';
4
4
  /**
@@ -17,9 +17,7 @@ import { _getArgsSignature, _getMethodSignature } from './decorator.util';
17
17
  // eslint-disable-next-line @typescript-eslint/naming-convention
18
18
  export function _LogMethod(opt = {}) {
19
19
  return (target, key, descriptor) => {
20
- if (typeof descriptor.value !== 'function') {
21
- throw new TypeError('@_LogMethod can be applied only to methods');
22
- }
20
+ _assert(typeof descriptor.value === 'function', '@_LogMethod can be applied only to methods');
23
21
  const originalFn = descriptor.value;
24
22
  const keyStr = String(key);
25
23
  const { avg, noLogArgs, logStart, logResult, noLogResultLength, logger = console } = opt;
@@ -1,9 +1,17 @@
1
+ import { _assert } from '../error/assert';
1
2
  import { pTimeout } from '../promise/pTimeout';
3
+ import { _getMethodSignature } from './decorator.util';
2
4
  // eslint-disable-next-line @typescript-eslint/naming-convention
3
5
  export function _Timeout(opt) {
4
6
  return (target, key, descriptor) => {
7
+ _assert(typeof descriptor.value === 'function', '@_Timeout can be applied only to methods');
5
8
  const originalFn = descriptor.value;
6
- descriptor.value = pTimeout(originalFn, opt);
9
+ const keyStr = String(key);
10
+ descriptor.value = async function (...args) {
11
+ const ctx = this;
12
+ opt.name || (opt.name = _getMethodSignature(ctx, keyStr));
13
+ return await pTimeout(originalFn.apply(this, args), opt);
14
+ };
7
15
  return descriptor;
8
16
  };
9
17
  }
@@ -1,3 +1,4 @@
1
+ import { AppError } from './app.error';
1
2
  /**
2
3
  * Calls a function, returns a Tuple of [error, value].
3
4
  * Allows to write shorter code that avoids `try/catch`.
@@ -38,3 +39,45 @@ export async function pTry(promise) {
38
39
  return [err, undefined];
39
40
  }
40
41
  }
42
+ /**
43
+ * It is thrown when Error was expected, but didn't happen
44
+ * ("pass" happened instead).
45
+ * "Pass" means "no error".
46
+ */
47
+ export class UnexpectedPassError extends AppError {
48
+ constructor() {
49
+ super('_expectedError passed unexpectedly');
50
+ }
51
+ }
52
+ /**
53
+ * Calls `fn`, expects is to throw, catches the expected error and returns.
54
+ * If error was NOT thrown - throws UnexpectedPassError instead.
55
+ */
56
+ export function _expectedError(fn) {
57
+ try {
58
+ fn();
59
+ // Unexpected!
60
+ throw new UnexpectedPassError();
61
+ }
62
+ catch (err) {
63
+ if (err instanceof UnexpectedPassError)
64
+ throw err; // re-throw
65
+ return err; // this is expected!
66
+ }
67
+ }
68
+ /**
69
+ * Awaits passed `promise`, expects is to throw (reject), catches the expected error and returns.
70
+ * If error was NOT thrown - throws UnexpectedPassError instead.
71
+ */
72
+ export async function pExpectedError(promise) {
73
+ try {
74
+ await promise;
75
+ // Unexpected!
76
+ throw new UnexpectedPassError();
77
+ }
78
+ catch (err) {
79
+ if (err instanceof UnexpectedPassError)
80
+ throw err; // re-throw
81
+ return err; // this is expected!
82
+ }
83
+ }
package/dist-esm/index.js CHANGED
@@ -3,24 +3,24 @@ export * from './lazy';
3
3
  export * from './string/url.util';
4
4
  export * from './array/range';
5
5
  import { _createPromiseDecorator, } from './decorators/createPromiseDecorator';
6
- import { _debounce, _throttle } from './decorators/debounce';
7
- import { _Debounce, _Throttle } from './decorators/debounce.decorator';
8
- import { _getArgsSignature } from './decorators/decorator.util';
9
- import { _LogMethod } from './decorators/logMethod.decorator';
10
- import { _Memo } from './decorators/memo.decorator';
11
- import { _memoFn } from './decorators/memoFn';
12
- import { _Retry } from './decorators/retry.decorator';
13
- import { _Timeout } from './decorators/timeout.decorator';
14
- import { AppError } from './error/app.error';
15
- import { AssertionError, _assert, _assertDeepEquals, _assertEquals, _assertIsError, _assertIsNumber, _assertIsString, _assertTypeOf, } from './error/assert';
6
+ export * from './decorators/debounce';
7
+ export * from './decorators/debounce.decorator';
8
+ export * from './decorators/decorator.util';
9
+ export * from './decorators/logMethod.decorator';
10
+ export * from './decorators/memo.decorator';
11
+ export * from './decorators/memoFn';
12
+ export * from './decorators/retry.decorator';
13
+ export * from './decorators/timeout.decorator';
14
+ export * from './error/app.error';
15
+ export * from './error/assert';
16
16
  export * from './error/error.util';
17
17
  import { ErrorMode } from './error/errorMode';
18
- import { HttpError } from './error/http.error';
19
- import { _try, pTry } from './error/try';
18
+ export * from './error/http.error';
19
+ export * from './error/try';
20
20
  import { _TryCatch, _tryCatch } from './error/tryCatch';
21
- import { generateJsonSchemaFromData } from './json-schema/from-data/generateJsonSchemaFromData';
22
- import { JSON_SCHEMA_ORDER } from './json-schema/jsonSchema.cnst';
23
- import { mergeJsonSchemaObjects } from './json-schema/jsonSchema.util';
21
+ export * from './json-schema/from-data/generateJsonSchemaFromData';
22
+ export * from './json-schema/jsonSchema.cnst';
23
+ export * from './json-schema/jsonSchema.util';
24
24
  import { jsonSchema, JsonSchemaAnyBuilder, } from './json-schema/jsonSchemaBuilder';
25
25
  export * from './math/math.util';
26
26
  export * from './math/sma';
@@ -40,19 +40,19 @@ import { pMap } from './promise/pMap';
40
40
  export * from './promise/pProps';
41
41
  import { pRetry } from './promise/pRetry';
42
42
  export * from './promise/pState';
43
- import { pTimeout } from './promise/pTimeout';
43
+ import { pTimeout, pTimeoutFn } from './promise/pTimeout';
44
44
  export * from './promise/pTuple';
45
45
  export * from './string/case';
46
46
  export * from './string/json.util';
47
47
  export * from './string/string.util';
48
48
  import { _stringifyAny } from './string/stringifyAny';
49
- import { _ms, _since } from './time/time.util';
49
+ export * from './time/time.util';
50
50
  import { END, SKIP, _noop, _objectKeys, _passNothingPredicate, _passthroughMapper, _passthroughPredicate, _passUndefinedMapper, _stringMapEntries, _stringMapValues, } from './types';
51
- import { _gb, _hb, _kb, _mb } from './unit/size.util';
51
+ export * from './unit/size.util';
52
52
  import { is } from './vendor/is';
53
53
  import { commonLoggerMinLevel, commonLoggerNoop, commonLogLevelNumber, commonLoggerPipe, commonLoggerPrefix, commonLoggerCreate, } from './log/commonLogger';
54
- import { _safeJsonStringify } from './string/safeJsonStringify';
54
+ export * from './string/safeJsonStringify';
55
55
  import { PQueue } from './promise/pQueue';
56
56
  export * from './seq/seq';
57
57
  export * from './math/stack.util';
58
- export { is, _Memo, _memoFn, _LogMethod, _getArgsSignature, _createPromiseDecorator, AppError, HttpError, AssertionError, _assert, _assertEquals, _assertDeepEquals, _assertIsError, _assertIsString, _assertIsNumber, _assertTypeOf, _stringMapValues, _stringMapEntries, _objectKeys, _debounce, _throttle, _Debounce, _Throttle, pMap, _passthroughMapper, _passUndefinedMapper, _passthroughPredicate, _passNothingPredicate, _noop, ErrorMode, pDefer, AggregatedError, pRetry, pTimeout, _Retry, _Timeout, _tryCatch, _TryCatch, _try, pTry, _stringifyAny, _ms, _since, _hb, _gb, _mb, _kb, mergeJsonSchemaObjects, jsonSchema, JsonSchemaAnyBuilder, JSON_SCHEMA_ORDER, generateJsonSchemaFromData, commonLoggerMinLevel, commonLoggerNoop, commonLogLevelNumber, commonLoggerPipe, commonLoggerPrefix, commonLoggerCreate, _safeJsonStringify, PQueue, END, SKIP, };
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, };
@@ -5,7 +5,7 @@ import { _since, _stringifyAny } from '..';
5
5
  */
6
6
  // eslint-disable-next-line @typescript-eslint/ban-types
7
7
  export function pRetry(fn, opt = {}) {
8
- const { maxAttempts = 4, delay: initialDelay = 1000, delayMultiplier = 2, predicate, logger = console, } = opt;
8
+ const { maxAttempts = 4, delay: initialDelay = 1000, delayMultiplier = 2, predicate, logger = console, name = fn.name, } = opt;
9
9
  let { logFirstAttempt = false, logRetries = true, logFailures = false, logSuccess = false } = opt;
10
10
  if (opt.logAll) {
11
11
  logFirstAttempt = logRetries = logFailures = true;
@@ -13,7 +13,7 @@ export function pRetry(fn, opt = {}) {
13
13
  if (opt.logNone) {
14
14
  logSuccess = logFirstAttempt = logRetries = logFailures = false;
15
15
  }
16
- const fname = ['pRetry', fn.name].filter(Boolean).join('.');
16
+ const fname = ['pRetry', name].filter(Boolean).join('.');
17
17
  return async function (...args) {
18
18
  let delay = initialDelay;
19
19
  let attempt = 0;
@@ -33,9 +33,9 @@ export function pRetry(fn, opt = {}) {
33
33
  }
34
34
  catch (err) {
35
35
  if (logFailures) {
36
- logger.warn(`${fname} attempt #${attempt} error in ${_since(started)}:\n${_stringifyAny(err, {
36
+ logger.warn(`${fname} attempt #${attempt} error in ${_since(started)}:`, _stringifyAny(err, {
37
37
  includeErrorData: true,
38
- })}`);
38
+ }));
39
39
  }
40
40
  if (attempt >= maxAttempts || (predicate && !predicate(err, attempt, maxAttempts))) {
41
41
  // Give up
@@ -1,37 +1,49 @@
1
+ import { AppError } from '../error/app.error';
2
+ export class TimeoutError extends AppError {
3
+ }
1
4
  /**
2
5
  * Decorates a Function with a timeout.
3
6
  * Throws an Error if the Function is not resolved in a certain time.
4
7
  * If the Function rejects - passes this rejection further.
5
8
  */
6
- export function pTimeout(fn, opt) {
7
- // const fname = fn.name || 'function'
9
+ export function pTimeoutFn(fn, opt) {
10
+ opt.name || (opt.name = fn.name);
11
+ return async function pTimeoutInternalFn(...args) {
12
+ return await pTimeout(fn.apply(this, args), opt);
13
+ };
14
+ }
15
+ /**
16
+ * Decorates a Function with a timeout and immediately calls it.
17
+ * Throws an Error if the Function is not resolved in a certain time.
18
+ * If the Function rejects - passes this rejection further.
19
+ */
20
+ export async function pTimeout(promise, opt) {
21
+ // todo: check how we can automatically infer function name (only applicable to named functions)
8
22
  const { timeout, name, onTimeout } = opt;
9
- return async function (...args) {
10
- // eslint-disable-next-line no-async-promise-executor
11
- return await new Promise(async (resolve, reject) => {
12
- // Prepare the timeout timer
13
- const timer = setTimeout(() => {
14
- if (onTimeout) {
15
- try {
16
- resolve(onTimeout());
17
- }
18
- catch (err) {
19
- reject(err);
20
- }
21
- return;
23
+ // eslint-disable-next-line no-async-promise-executor
24
+ return await new Promise(async (resolve, reject) => {
25
+ // Prepare the timeout timer
26
+ const timer = setTimeout(() => {
27
+ if (onTimeout) {
28
+ try {
29
+ resolve(onTimeout());
22
30
  }
23
- reject(new Error(`"${name || fn.name || 'pTimeout function'}" timed out after ${timeout} ms`));
24
- }, timeout);
25
- // Execute the Function
26
- try {
27
- resolve(await fn.apply(this, args));
28
- }
29
- catch (err) {
30
- reject(err);
31
- }
32
- finally {
33
- clearTimeout(timer);
31
+ catch (err) {
32
+ reject(err);
33
+ }
34
+ return;
34
35
  }
35
- });
36
- };
36
+ reject(new TimeoutError(`"${name || 'pTimeout function'}" timed out after ${timeout} ms`));
37
+ }, timeout);
38
+ // Execute the Function
39
+ try {
40
+ resolve(await promise);
41
+ }
42
+ catch (err) {
43
+ reject(err);
44
+ }
45
+ finally {
46
+ clearTimeout(timer);
47
+ }
48
+ });
37
49
  }