@naturalcycles/js-lib 14.116.0 → 14.117.1

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 (49) hide show
  1. package/dist/array/array.util.js +4 -4
  2. package/dist/datetime/dateInterval.js +1 -0
  3. package/dist/datetime/localDate.js +2 -0
  4. package/dist/datetime/localTime.js +2 -3
  5. package/dist/datetime/timeInterval.js +1 -0
  6. package/dist/decorators/asyncMemo.decorator.d.ts +2 -2
  7. package/dist/decorators/createPromiseDecorator.d.ts +6 -6
  8. package/dist/decorators/logMethod.decorator.js +4 -5
  9. package/dist/decorators/memo.decorator.d.ts +2 -2
  10. package/dist/error/tryCatch.d.ts +1 -1
  11. package/dist/object/deepEquals.js +1 -0
  12. package/dist/object/object.util.js +8 -10
  13. package/dist/promise/pRetry.d.ts +1 -1
  14. package/dist/promise/pTimeout.d.ts +4 -1
  15. package/dist/promise/pTimeout.js +5 -6
  16. package/dist/string/pupa.d.ts +2 -2
  17. package/dist/string/readingTime.d.ts +1 -1
  18. package/dist/string/safeJsonStringify.js +5 -7
  19. package/dist/string/url.util.js +1 -1
  20. package/dist-esm/array/array.util.js +4 -4
  21. package/dist-esm/datetime/dateInterval.js +1 -0
  22. package/dist-esm/datetime/localDate.js +2 -0
  23. package/dist-esm/datetime/localTime.js +2 -3
  24. package/dist-esm/datetime/timeInterval.js +1 -0
  25. package/dist-esm/decorators/logMethod.decorator.js +4 -5
  26. package/dist-esm/object/deepEquals.js +1 -0
  27. package/dist-esm/object/object.util.js +8 -10
  28. package/dist-esm/promise/pTimeout.js +5 -6
  29. package/dist-esm/string/safeJsonStringify.js +5 -7
  30. package/dist-esm/string/url.util.js +1 -1
  31. package/package.json +1 -1
  32. package/src/array/array.util.ts +4 -4
  33. package/src/datetime/dateInterval.ts +1 -0
  34. package/src/datetime/localDate.ts +2 -0
  35. package/src/datetime/localTime.ts +2 -2
  36. package/src/datetime/timeInterval.ts +1 -0
  37. package/src/decorators/asyncMemo.decorator.ts +2 -2
  38. package/src/decorators/createPromiseDecorator.ts +4 -4
  39. package/src/decorators/logMethod.decorator.ts +4 -4
  40. package/src/decorators/memo.decorator.ts +2 -2
  41. package/src/error/tryCatch.ts +1 -1
  42. package/src/object/deepEquals.ts +1 -0
  43. package/src/object/object.util.ts +7 -8
  44. package/src/promise/pRetry.ts +1 -1
  45. package/src/promise/pTimeout.ts +9 -9
  46. package/src/string/pupa.ts +1 -1
  47. package/src/string/readingTime.ts +1 -1
  48. package/src/string/safeJsonStringify.ts +3 -5
  49. package/src/string/url.util.ts +1 -1
@@ -160,24 +160,24 @@ function _findLast(items, predicate) {
160
160
  exports._findLast = _findLast;
161
161
  function _takeWhile(items, predicate) {
162
162
  let proceed = true;
163
- return items.filter((v, index) => (proceed = proceed && predicate(v, index)));
163
+ return items.filter((v, index) => (proceed &&= predicate(v, index)));
164
164
  }
165
165
  exports._takeWhile = _takeWhile;
166
166
  function _takeRightWhile(items, predicate) {
167
167
  let proceed = true;
168
- return [...items].reverse().filter((v, index) => (proceed = proceed && predicate(v, index)));
168
+ return [...items].reverse().filter((v, index) => (proceed &&= predicate(v, index)));
169
169
  }
170
170
  exports._takeRightWhile = _takeRightWhile;
171
171
  function _dropWhile(items, predicate) {
172
172
  let proceed = false;
173
- return items.filter((v, index) => (proceed = proceed || !predicate(v, index)));
173
+ return items.filter((v, index) => (proceed ||= !predicate(v, index)));
174
174
  }
175
175
  exports._dropWhile = _dropWhile;
176
176
  function _dropRightWhile(items, predicate) {
177
177
  let proceed = false;
178
178
  return [...items]
179
179
  .reverse()
180
- .filter((v, index) => (proceed = proceed || !predicate(v, index)))
180
+ .filter((v, index) => (proceed ||= !predicate(v, index)))
181
181
  .reverse();
182
182
  }
183
183
  exports._dropRightWhile = _dropRightWhile;
@@ -49,6 +49,7 @@ class DateInterval {
49
49
  */
50
50
  includes(d, incl = '[]') {
51
51
  d = localDate_1.LocalDate.of(d);
52
+ // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
52
53
  return d.isAfter(this.start, incl[0] === '[') && d.isBefore(this.end, incl[1] === ']');
53
54
  }
54
55
  intersects(int, inclusive = true) {
@@ -112,6 +112,7 @@ class LocalDate {
112
112
  const $min = LocalDate.of(min);
113
113
  const $max = LocalDate.of(max).startOf(stepUnit);
114
114
  let current = $min.startOf(stepUnit);
115
+ // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
115
116
  if (current.isAfter($min, incl[0] === '[')) {
116
117
  // ok
117
118
  }
@@ -170,6 +171,7 @@ class LocalDate {
170
171
  }
171
172
  isBetween(min, max, incl = '[)') {
172
173
  let r = this.cmp(min);
174
+ // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
173
175
  if (r < 0 || (r === 0 && incl[0] === '('))
174
176
  return false;
175
177
  r = this.cmp(max);
@@ -347,6 +347,7 @@ class LocalTime {
347
347
  }
348
348
  isBetween(min, max, incl = '[)') {
349
349
  let r = this.cmp(min);
350
+ // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
350
351
  if (r < 0 || (r === 0 && incl[0] === '('))
351
352
  return false;
352
353
  r = this.cmp(max);
@@ -525,9 +526,7 @@ function getWeekYear(date) {
525
526
  else if (date.getTime() >= startOfThisYear.getTime()) {
526
527
  return year;
527
528
  }
528
- else {
529
- return year - 1;
530
- }
529
+ return year - 1;
531
530
  }
532
531
  // based on: https://github.com/date-fns/date-fns/blob/fd6bb1a0bab143f2da068c05a9c562b9bee1357d/src/startOfWeek/index.ts
533
532
  function startOfWeek(date, mutate = false) {
@@ -59,6 +59,7 @@ class TimeInterval {
59
59
  }
60
60
  includes(d, incl = '[)') {
61
61
  d = localTime_1.LocalTime.parseToUnixTimestamp(d);
62
+ // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
62
63
  if (d < this.$start || (d === this.$start && incl[0] === '('))
63
64
  return false;
64
65
  if (d > this.$end || (d === this.$end && incl[1] === ')'))
@@ -6,11 +6,11 @@ export interface AsyncMemoOptions {
6
6
  * Function that creates an instance of `MemoCache`.
7
7
  * e.g LRUMemoCache from `@naturalcycles/nodejs-lib`.
8
8
  */
9
- cacheFactory?: () => AsyncMemoCache;
9
+ cacheFactory?(): AsyncMemoCache;
10
10
  /**
11
11
  * Provide a custom implementation of CacheKey function.
12
12
  */
13
- cacheKeyFn?: (args: any[]) => any;
13
+ cacheKeyFn?(args: any[]): any;
14
14
  /**
15
15
  * Default true.
16
16
  *
@@ -4,15 +4,15 @@ export interface PromiseDecoratorCfg<RES = any, PARAMS = any> {
4
4
  * Called BEFORE the original function.
5
5
  * If Promise is returned - it will be awaited.
6
6
  */
7
- beforeFn?: (r: PromiseDecoratorResp<PARAMS>) => void | Promise<void>;
7
+ beforeFn?(r: PromiseDecoratorResp<PARAMS>): void | Promise<void>;
8
8
  /**
9
9
  * Called just AFTER the original function.
10
10
  * The output of this hook will be passed further,
11
11
  * so, pay attention to pass through (or modify) the result.
12
12
  */
13
- thenFn?: (r: PromiseDecoratorResp<PARAMS> & {
13
+ thenFn?(r: PromiseDecoratorResp<PARAMS> & {
14
14
  res: RES;
15
- }) => RES;
15
+ }): RES;
16
16
  /**
17
17
  * Called on Promise.reject.
18
18
  * If `catchFn` is not present - will re-throw the error,
@@ -20,14 +20,14 @@ export interface PromiseDecoratorCfg<RES = any, PARAMS = any> {
20
20
  * If `catchFn` is present - it's responsible for handling or re-throwing the error.
21
21
  * Whatever `catchFn` returns - passed to the original output.
22
22
  */
23
- catchFn?: (r: PromiseDecoratorResp<PARAMS> & {
23
+ catchFn?(r: PromiseDecoratorResp<PARAMS> & {
24
24
  err: any;
25
- }) => RES;
25
+ }): RES;
26
26
  /**
27
27
  * Fires AFTER thenFn / catchFn, like a usual Promise.finally().
28
28
  * Doesn't have access to neither res nor err (same as Promise.finally).
29
29
  */
30
- finallyFn?: (r: PromiseDecoratorResp<PARAMS>) => any;
30
+ finallyFn?(r: PromiseDecoratorResp<PARAMS>): any;
31
31
  }
32
32
  export interface PromiseDecoratorResp<PARAMS> {
33
33
  decoratorParams: PARAMS;
@@ -59,11 +59,9 @@ function _LogMethod(opt = {}) {
59
59
  throw err;
60
60
  });
61
61
  }
62
- else {
63
- // not a Promise
64
- logFinished(logger, callSignature, started, sma, logResultFn, res);
65
- return res;
66
- }
62
+ // not a Promise
63
+ logFinished(logger, callSignature, started, sma, logResultFn, res);
64
+ return res;
67
65
  }
68
66
  catch (err) {
69
67
  logFinished(logger, callSignature, started, sma, logResultFn, undefined, err);
@@ -74,6 +72,7 @@ function _LogMethod(opt = {}) {
74
72
  };
75
73
  }
76
74
  exports._LogMethod = _LogMethod;
75
+ // eslint-disable-next-line max-params
77
76
  function logFinished(logger, callSignature, started, sma, logResultFn, res, err) {
78
77
  const millis = Date.now() - started;
79
78
  const t = ['<<', callSignature, 'took', (0, time_util_1._ms)(millis)];
@@ -6,11 +6,11 @@ export interface MemoOptions {
6
6
  * Function that creates an instance of `MemoCache`.
7
7
  * e.g LRUMemoCache from `@naturalcycles/nodejs-lib`
8
8
  */
9
- cacheFactory?: () => MemoCache;
9
+ cacheFactory?(): MemoCache;
10
10
  /**
11
11
  * Provide a custom implementation of CacheKey function.
12
12
  */
13
- cacheKeyFn?: (args: any[]) => any;
13
+ cacheKeyFn?(args: any[]): any;
14
14
  /**
15
15
  * Defaults to true.
16
16
  * Set to false to skip caching errors.
@@ -5,7 +5,7 @@ export interface TryCatchOptions {
5
5
  * The value returned from the function will be returned from the wrapped method (!).
6
6
  * onError function may be asynchronous.
7
7
  */
8
- onError?: (err: Error) => any;
8
+ onError?(err: Error): any;
9
9
  /**
10
10
  * @default false
11
11
  */
@@ -54,6 +54,7 @@ function _deepEquals(a, b) {
54
54
  }
55
55
  return true;
56
56
  }
57
+ // eslint-disable-next-line no-self-compare
57
58
  return a !== a && b !== b;
58
59
  }
59
60
  exports._deepEquals = _deepEquals;
@@ -15,14 +15,12 @@ function _pick(obj, props, mutate = false) {
15
15
  return r;
16
16
  }, obj);
17
17
  }
18
- else {
19
- // Start as empty object, pick/add needed properties
20
- return props.reduce((r, prop) => {
21
- if (prop in obj)
22
- r[prop] = obj[prop];
23
- return r;
24
- }, {});
25
- }
18
+ // Start as empty object, pick/add needed properties
19
+ return props.reduce((r, prop) => {
20
+ if (prop in obj)
21
+ r[prop] = obj[prop];
22
+ return r;
23
+ }, {});
26
24
  }
27
25
  exports._pick = _pick;
28
26
  /**
@@ -259,7 +257,7 @@ function _unset(obj, prop) {
259
257
  }
260
258
  const segs = prop.split('.');
261
259
  let last = segs.pop();
262
- while (segs.length && segs[segs.length - 1].slice(-1) === '\\') {
260
+ while (segs.length && segs[segs.length - 1].endsWith('\\')) {
263
261
  last = segs.pop().slice(0, -1) + '.' + last;
264
262
  }
265
263
  while (segs.length && (0, is_util_1._isObject)(obj)) {
@@ -329,7 +327,7 @@ function _set(obj, path, value) {
329
327
  a[c]
330
328
  : // No: create the key. Is the next key a potential array-index?
331
329
  (a[c] =
332
- // @ts-ignore
330
+ // @ts-expect-error
333
331
  // eslint-disable-next-line
334
332
  Math.abs(path[i + 1]) >> 0 === +path[i + 1]
335
333
  ? [] // Yes: assign a new array object
@@ -35,7 +35,7 @@ export interface PRetryOptions {
35
35
  *
36
36
  * @default () => true
37
37
  */
38
- predicate?: (err: Error, attempt: number, maxAttempts: number) => boolean;
38
+ predicate?(err: Error, attempt: number, maxAttempts: number): boolean;
39
39
  /**
40
40
  * Log the first attempt (which is not a "retry" yet).
41
41
  *
@@ -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!).
@@ -26,16 +26,18 @@ exports.pTimeoutFn = pTimeoutFn;
26
26
  * If the Function rejects - passes this rejection further.
27
27
  */
28
28
  async function pTimeout(fn, opt) {
29
- // todo: check how we can automatically infer function name (only applicable to named functions)
30
- const { timeout, name, onTimeout, keepStackTrace = true } = opt;
29
+ const { timeout, name = fn.name || 'pTimeout function', onTimeout, keepStackTrace = true } = opt;
31
30
  const fakeError = keepStackTrace ? new Error('TimeoutError') : undefined;
32
31
  // eslint-disable-next-line no-async-promise-executor
33
32
  return await new Promise(async (resolve, reject) => {
34
33
  // Prepare the timeout timer
35
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
36
38
  if (onTimeout) {
37
39
  try {
38
- resolve(onTimeout());
40
+ resolve(onTimeout(err));
39
41
  }
40
42
  catch (err) {
41
43
  if (fakeError)
@@ -48,9 +50,6 @@ async function pTimeout(fn, opt) {
48
50
  }
49
51
  return;
50
52
  }
51
- const err = new TimeoutError(`"${name || 'pTimeout function'}" timed out after ${timeout} ms`, opt.errorData);
52
- if (fakeError)
53
- err.stack = fakeError.stack; // keep original stack
54
53
  reject(err);
55
54
  }, timeout);
56
55
  // Execute the Function
@@ -11,10 +11,10 @@ export interface PupaOptions {
11
11
  /**
12
12
  * Performs arbitrary operation for each interpolation. If the returned value was `undefined`, it behaves differently depending on the `ignoreMissing` option. Otherwise, the returned value will be interpolated into a string (and escaped when double-braced) and embedded into the template.
13
13
  */
14
- transform?: (data: {
14
+ transform?(data: {
15
15
  value: any;
16
16
  key: string;
17
- }) => unknown;
17
+ }): unknown;
18
18
  }
19
19
  /**
20
20
  * API: https://github.com/sindresorhus/pupa
@@ -4,7 +4,7 @@ export interface ReadingTimeOptions {
4
4
  * A function that returns a boolean value depending on if a character is considered as a word bound.
5
5
  * Default: spaces, new lines and tabs
6
6
  */
7
- wordBound?: (char: string) => boolean;
7
+ wordBound?(char: string): boolean;
8
8
  /**
9
9
  * Default 200
10
10
  */
@@ -21,13 +21,11 @@ exports._safeJsonStringify = _safeJsonStringify;
21
21
  function serializer(replacer, cycleReplacer) {
22
22
  const stack = [];
23
23
  const keys = [];
24
- if (cycleReplacer == null) {
25
- cycleReplacer = function (key, value) {
26
- if (stack[0] === value)
27
- return '[Circular ~]';
28
- return '[Circular ~.' + keys.slice(0, stack.indexOf(value)).join('.') + ']';
29
- };
30
- }
24
+ cycleReplacer ??= function (key, value) {
25
+ if (stack[0] === value)
26
+ return '[Circular ~]';
27
+ return '[Circular ~.' + keys.slice(0, stack.indexOf(value)).join('.') + ']';
28
+ };
31
29
  return function (key, value) {
32
30
  if (stack.length > 0) {
33
31
  const thisPos = stack.indexOf(this);
@@ -17,7 +17,7 @@ exports._parseQueryString = void 0;
17
17
  function _parseQueryString(search) {
18
18
  const qs = {};
19
19
  search
20
- .slice(search[0] === '?' ? 1 : 0)
20
+ .slice(search.startsWith('?') ? 1 : 0)
21
21
  .split('&')
22
22
  .forEach(p => {
23
23
  const [k, v] = p.split('=');
@@ -148,21 +148,21 @@ export function _findLast(items, predicate) {
148
148
  }
149
149
  export function _takeWhile(items, predicate) {
150
150
  let proceed = true;
151
- return items.filter((v, index) => (proceed = proceed && predicate(v, index)));
151
+ return items.filter((v, index) => (proceed && (proceed = predicate(v, index))));
152
152
  }
153
153
  export function _takeRightWhile(items, predicate) {
154
154
  let proceed = true;
155
- return [...items].reverse().filter((v, index) => (proceed = proceed && predicate(v, index)));
155
+ return [...items].reverse().filter((v, index) => (proceed && (proceed = predicate(v, index))));
156
156
  }
157
157
  export function _dropWhile(items, predicate) {
158
158
  let proceed = false;
159
- return items.filter((v, index) => (proceed = proceed || !predicate(v, index)));
159
+ return items.filter((v, index) => (proceed || (proceed = !predicate(v, index))));
160
160
  }
161
161
  export function _dropRightWhile(items, predicate) {
162
162
  let proceed = false;
163
163
  return [...items]
164
164
  .reverse()
165
- .filter((v, index) => (proceed = proceed || !predicate(v, index)))
165
+ .filter((v, index) => (proceed || (proceed = !predicate(v, index))))
166
166
  .reverse();
167
167
  }
168
168
  export function _countBy(items, mapper) {
@@ -46,6 +46,7 @@ export class DateInterval {
46
46
  */
47
47
  includes(d, incl = '[]') {
48
48
  d = LocalDate.of(d);
49
+ // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
49
50
  return d.isAfter(this.start, incl[0] === '[') && d.isBefore(this.end, incl[1] === ']');
50
51
  }
51
52
  intersects(int, inclusive = true) {
@@ -109,6 +109,7 @@ export class LocalDate {
109
109
  const $min = LocalDate.of(min);
110
110
  const $max = LocalDate.of(max).startOf(stepUnit);
111
111
  let current = $min.startOf(stepUnit);
112
+ // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
112
113
  if (current.isAfter($min, incl[0] === '[')) {
113
114
  // ok
114
115
  }
@@ -167,6 +168,7 @@ export class LocalDate {
167
168
  }
168
169
  isBetween(min, max, incl = '[)') {
169
170
  let r = this.cmp(min);
171
+ // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
170
172
  if (r < 0 || (r === 0 && incl[0] === '('))
171
173
  return false;
172
174
  r = this.cmp(max);
@@ -345,6 +345,7 @@ export class LocalTime {
345
345
  }
346
346
  isBetween(min, max, incl = '[)') {
347
347
  let r = this.cmp(min);
348
+ // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
348
349
  if (r < 0 || (r === 0 && incl[0] === '('))
349
350
  return false;
350
351
  r = this.cmp(max);
@@ -521,9 +522,7 @@ function getWeekYear(date) {
521
522
  else if (date.getTime() >= startOfThisYear.getTime()) {
522
523
  return year;
523
524
  }
524
- else {
525
- return year - 1;
526
- }
525
+ return year - 1;
527
526
  }
528
527
  // based on: https://github.com/date-fns/date-fns/blob/fd6bb1a0bab143f2da068c05a9c562b9bee1357d/src/startOfWeek/index.ts
529
528
  function startOfWeek(date, mutate = false) {
@@ -56,6 +56,7 @@ export class TimeInterval {
56
56
  }
57
57
  includes(d, incl = '[)') {
58
58
  d = LocalTime.parseToUnixTimestamp(d);
59
+ // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
59
60
  if (d < this.$start || (d === this.$start && incl[0] === '('))
60
61
  return false;
61
62
  if (d > this.$end || (d === this.$end && incl[1] === ')'))
@@ -56,11 +56,9 @@ export function _LogMethod(opt = {}) {
56
56
  throw err;
57
57
  });
58
58
  }
59
- else {
60
- // not a Promise
61
- logFinished(logger, callSignature, started, sma, logResultFn, res);
62
- return res;
63
- }
59
+ // not a Promise
60
+ logFinished(logger, callSignature, started, sma, logResultFn, res);
61
+ return res;
64
62
  }
65
63
  catch (err) {
66
64
  logFinished(logger, callSignature, started, sma, logResultFn, undefined, err);
@@ -70,6 +68,7 @@ export function _LogMethod(opt = {}) {
70
68
  return descriptor;
71
69
  };
72
70
  }
71
+ // eslint-disable-next-line max-params
73
72
  function logFinished(logger, callSignature, started, sma, logResultFn, res, err) {
74
73
  const millis = Date.now() - started;
75
74
  const t = ['<<', callSignature, 'took', _ms(millis)];
@@ -51,5 +51,6 @@ export function _deepEquals(a, b) {
51
51
  }
52
52
  return true;
53
53
  }
54
+ // eslint-disable-next-line no-self-compare
54
55
  return a !== a && b !== b;
55
56
  }
@@ -12,14 +12,12 @@ export function _pick(obj, props, mutate = false) {
12
12
  return r;
13
13
  }, obj);
14
14
  }
15
- else {
16
- // Start as empty object, pick/add needed properties
17
- return props.reduce((r, prop) => {
18
- if (prop in obj)
19
- r[prop] = obj[prop];
20
- return r;
21
- }, {});
22
- }
15
+ // Start as empty object, pick/add needed properties
16
+ return props.reduce((r, prop) => {
17
+ if (prop in obj)
18
+ r[prop] = obj[prop];
19
+ return r;
20
+ }, {});
23
21
  }
24
22
  /**
25
23
  * Returns clone of `obj` with `props` omitted.
@@ -239,7 +237,7 @@ export function _unset(obj, prop) {
239
237
  }
240
238
  const segs = prop.split('.');
241
239
  let last = segs.pop();
242
- while (segs.length && segs[segs.length - 1].slice(-1) === '\\') {
240
+ while (segs.length && segs[segs.length - 1].endsWith('\\')) {
243
241
  last = segs.pop().slice(0, -1) + '.' + last;
244
242
  }
245
243
  while (segs.length && _isObject(obj)) {
@@ -305,7 +303,7 @@ export function _set(obj, path, value) {
305
303
  a[c]
306
304
  : // No: create the key. Is the next key a potential array-index?
307
305
  (a[c] =
308
- // @ts-ignore
306
+ // @ts-expect-error
309
307
  // eslint-disable-next-line
310
308
  Math.abs(path[i + 1]) >> 0 === +path[i + 1]
311
309
  ? [] // Yes: assign a new array object
@@ -21,16 +21,18 @@ export function pTimeoutFn(fn, opt) {
21
21
  * If the Function rejects - passes this rejection further.
22
22
  */
23
23
  export async function pTimeout(fn, opt) {
24
- // todo: check how we can automatically infer function name (only applicable to named functions)
25
- const { timeout, name, onTimeout, keepStackTrace = true } = opt;
24
+ const { timeout, name = fn.name || 'pTimeout function', onTimeout, keepStackTrace = true } = opt;
26
25
  const fakeError = keepStackTrace ? new Error('TimeoutError') : undefined;
27
26
  // eslint-disable-next-line no-async-promise-executor
28
27
  return await new Promise(async (resolve, reject) => {
29
28
  // Prepare the timeout timer
30
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
31
33
  if (onTimeout) {
32
34
  try {
33
- resolve(onTimeout());
35
+ resolve(onTimeout(err));
34
36
  }
35
37
  catch (err) {
36
38
  if (fakeError)
@@ -40,9 +42,6 @@ export async function pTimeout(fn, opt) {
40
42
  }
41
43
  return;
42
44
  }
43
- const err = new TimeoutError(`"${name || 'pTimeout function'}" timed out after ${timeout} ms`, opt.errorData);
44
- if (fakeError)
45
- err.stack = fakeError.stack; // keep original stack
46
45
  reject(err);
47
46
  }, timeout);
48
47
  // Execute the Function
@@ -17,13 +17,11 @@ export function _safeJsonStringify(obj, replacer, spaces, cycleReplacer) {
17
17
  function serializer(replacer, cycleReplacer) {
18
18
  const stack = [];
19
19
  const keys = [];
20
- if (cycleReplacer == null) {
21
- cycleReplacer = function (key, value) {
22
- if (stack[0] === value)
23
- return '[Circular ~]';
24
- return '[Circular ~.' + keys.slice(0, stack.indexOf(value)).join('.') + ']';
25
- };
26
- }
20
+ cycleReplacer !== null && cycleReplacer !== void 0 ? cycleReplacer : (cycleReplacer = function (key, value) {
21
+ if (stack[0] === value)
22
+ return '[Circular ~]';
23
+ return '[Circular ~.' + keys.slice(0, stack.indexOf(value)).join('.') + ']';
24
+ });
27
25
  return function (key, value) {
28
26
  if (stack.length > 0) {
29
27
  const thisPos = stack.indexOf(this);
@@ -14,7 +14,7 @@
14
14
  export function _parseQueryString(search) {
15
15
  const qs = {};
16
16
  search
17
- .slice(search[0] === '?' ? 1 : 0)
17
+ .slice(search.startsWith('?') ? 1 : 0)
18
18
  .split('&')
19
19
  .forEach(p => {
20
20
  const [k, v] = p.split('=');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naturalcycles/js-lib",
3
- "version": "14.116.0",
3
+ "version": "14.117.1",
4
4
  "scripts": {
5
5
  "prepare": "husky install",
6
6
  "build-prod": "build-prod-esm-cjs",
@@ -164,24 +164,24 @@ export function _findLast<T>(items: T[], predicate: Predicate<T>): T | undefined
164
164
 
165
165
  export function _takeWhile<T>(items: T[], predicate: Predicate<T>): T[] {
166
166
  let proceed = true
167
- return items.filter((v, index) => (proceed = proceed && predicate(v, index)))
167
+ return items.filter((v, index) => (proceed &&= predicate(v, index)))
168
168
  }
169
169
 
170
170
  export function _takeRightWhile<T>(items: T[], predicate: Predicate<T>): T[] {
171
171
  let proceed = true
172
- return [...items].reverse().filter((v, index) => (proceed = proceed && predicate(v, index)))
172
+ return [...items].reverse().filter((v, index) => (proceed &&= predicate(v, index)))
173
173
  }
174
174
 
175
175
  export function _dropWhile<T>(items: T[], predicate: Predicate<T>): T[] {
176
176
  let proceed = false
177
- return items.filter((v, index) => (proceed = proceed || !predicate(v, index)))
177
+ return items.filter((v, index) => (proceed ||= !predicate(v, index)))
178
178
  }
179
179
 
180
180
  export function _dropRightWhile<T>(items: T[], predicate: Predicate<T>): T[] {
181
181
  let proceed = false
182
182
  return [...items]
183
183
  .reverse()
184
- .filter((v, index) => (proceed = proceed || !predicate(v, index)))
184
+ .filter((v, index) => (proceed ||= !predicate(v, index)))
185
185
  .reverse()
186
186
  }
187
187
 
@@ -58,6 +58,7 @@ export class DateInterval {
58
58
  */
59
59
  includes(d: LocalDateConfig, incl: Inclusiveness = '[]'): boolean {
60
60
  d = LocalDate.of(d)
61
+ // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
61
62
  return d.isAfter(this.start, incl[0] === '[') && d.isBefore(this.end, incl[1] === ']')
62
63
  }
63
64
 
@@ -154,6 +154,7 @@ export class LocalDate {
154
154
  const $max = LocalDate.of(max).startOf(stepUnit)
155
155
 
156
156
  let current = $min.startOf(stepUnit)
157
+ // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
157
158
  if (current.isAfter($min, incl[0] === '[')) {
158
159
  // ok
159
160
  } else {
@@ -228,6 +229,7 @@ export class LocalDate {
228
229
 
229
230
  isBetween(min: LocalDateConfig, max: LocalDateConfig, incl: Inclusiveness = '[)'): boolean {
230
231
  let r = this.cmp(min)
232
+ // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
231
233
  if (r < 0 || (r === 0 && incl[0] === '(')) return false
232
234
  r = this.cmp(max)
233
235
  if (r > 0 || (r === 0 && incl[1] === ')')) return false
@@ -431,6 +431,7 @@ export class LocalTime {
431
431
 
432
432
  isBetween(min: LocalTimeConfig, max: LocalTimeConfig, incl: Inclusiveness = '[)'): boolean {
433
433
  let r = this.cmp(min)
434
+ // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
434
435
  if (r < 0 || (r === 0 && incl[0] === '(')) return false
435
436
  r = this.cmp(max)
436
437
  if (r > 0 || (r === 0 && incl[1] === ')')) return false
@@ -641,9 +642,8 @@ function getWeekYear(date: Date): number {
641
642
  return year + 1
642
643
  } else if (date.getTime() >= startOfThisYear.getTime()) {
643
644
  return year
644
- } else {
645
- return year - 1
646
645
  }
646
+ return year - 1
647
647
  }
648
648
 
649
649
  // based on: https://github.com/date-fns/date-fns/blob/fd6bb1a0bab143f2da068c05a9c562b9bee1357d/src/startOfWeek/index.ts
@@ -77,6 +77,7 @@ export class TimeInterval {
77
77
 
78
78
  includes(d: LocalTimeConfig, incl: Inclusiveness = '[)'): boolean {
79
79
  d = LocalTime.parseToUnixTimestamp(d)
80
+ // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
80
81
  if (d < this.$start || (d === this.$start && incl[0] === '(')) return false
81
82
  if (d > this.$end || (d === this.$end && incl[1] === ')')) return false
82
83
  return true
@@ -11,12 +11,12 @@ export interface AsyncMemoOptions {
11
11
  * Function that creates an instance of `MemoCache`.
12
12
  * e.g LRUMemoCache from `@naturalcycles/nodejs-lib`.
13
13
  */
14
- cacheFactory?: () => AsyncMemoCache
14
+ cacheFactory?(): AsyncMemoCache
15
15
 
16
16
  /**
17
17
  * Provide a custom implementation of CacheKey function.
18
18
  */
19
- cacheKeyFn?: (args: any[]) => any
19
+ cacheKeyFn?(args: any[]): any
20
20
 
21
21
  /**
22
22
  * Default true.
@@ -7,14 +7,14 @@ export interface PromiseDecoratorCfg<RES = any, PARAMS = any> {
7
7
  * Called BEFORE the original function.
8
8
  * If Promise is returned - it will be awaited.
9
9
  */
10
- beforeFn?: (r: PromiseDecoratorResp<PARAMS>) => void | Promise<void>
10
+ beforeFn?(r: PromiseDecoratorResp<PARAMS>): void | Promise<void>
11
11
 
12
12
  /**
13
13
  * Called just AFTER the original function.
14
14
  * The output of this hook will be passed further,
15
15
  * so, pay attention to pass through (or modify) the result.
16
16
  */
17
- thenFn?: (r: PromiseDecoratorResp<PARAMS> & { res: RES }) => RES
17
+ thenFn?(r: PromiseDecoratorResp<PARAMS> & { res: RES }): RES
18
18
 
19
19
  /**
20
20
  * Called on Promise.reject.
@@ -23,13 +23,13 @@ export interface PromiseDecoratorCfg<RES = any, PARAMS = any> {
23
23
  * If `catchFn` is present - it's responsible for handling or re-throwing the error.
24
24
  * Whatever `catchFn` returns - passed to the original output.
25
25
  */
26
- catchFn?: (r: PromiseDecoratorResp<PARAMS> & { err: any }) => RES
26
+ catchFn?(r: PromiseDecoratorResp<PARAMS> & { err: any }): RES
27
27
 
28
28
  /**
29
29
  * Fires AFTER thenFn / catchFn, like a usual Promise.finally().
30
30
  * Doesn't have access to neither res nor err (same as Promise.finally).
31
31
  */
32
- finallyFn?: (r: PromiseDecoratorResp<PARAMS>) => any
32
+ finallyFn?(r: PromiseDecoratorResp<PARAMS>): any
33
33
  }
34
34
 
35
35
  export interface PromiseDecoratorResp<PARAMS> {
@@ -122,11 +122,10 @@ export function _LogMethod(opt: LogMethodOptions = {}): MethodDecorator {
122
122
  logFinished(logger, callSignature, started, sma, logResultFn, undefined, err)
123
123
  throw err
124
124
  })
125
- } else {
126
- // not a Promise
127
- logFinished(logger, callSignature, started, sma, logResultFn, res)
128
- return res
129
125
  }
126
+ // not a Promise
127
+ logFinished(logger, callSignature, started, sma, logResultFn, res)
128
+ return res
130
129
  } catch (err) {
131
130
  logFinished(logger, callSignature, started, sma, logResultFn, undefined, err)
132
131
  throw err // rethrow
@@ -137,6 +136,7 @@ export function _LogMethod(opt: LogMethodOptions = {}): MethodDecorator {
137
136
  }
138
137
  }
139
138
 
139
+ // eslint-disable-next-line max-params
140
140
  function logFinished(
141
141
  logger: CommonLogger,
142
142
  callSignature: string,
@@ -11,12 +11,12 @@ export interface MemoOptions {
11
11
  * Function that creates an instance of `MemoCache`.
12
12
  * e.g LRUMemoCache from `@naturalcycles/nodejs-lib`
13
13
  */
14
- cacheFactory?: () => MemoCache
14
+ cacheFactory?(): MemoCache
15
15
 
16
16
  /**
17
17
  * Provide a custom implementation of CacheKey function.
18
18
  */
19
- cacheKeyFn?: (args: any[]) => any
19
+ cacheKeyFn?(args: any[]): any
20
20
 
21
21
  /**
22
22
  * Defaults to true.
@@ -7,7 +7,7 @@ export interface TryCatchOptions {
7
7
  * The value returned from the function will be returned from the wrapped method (!).
8
8
  * onError function may be asynchronous.
9
9
  */
10
- onError?: (err: Error) => any
10
+ onError?(err: Error): any
11
11
 
12
12
  /**
13
13
  * @default false
@@ -51,5 +51,6 @@ export function _deepEquals(a: any, b: any): boolean {
51
51
  return true
52
52
  }
53
53
 
54
+ // eslint-disable-next-line no-self-compare
54
55
  return a !== a && b !== b
55
56
  }
@@ -17,13 +17,12 @@ export function _pick<T extends AnyObject, K extends keyof T>(
17
17
  if (!props.includes(prop as K)) delete r[prop]
18
18
  return r
19
19
  }, obj)
20
- } else {
21
- // Start as empty object, pick/add needed properties
22
- return props.reduce((r, prop) => {
23
- if (prop in obj) r[prop] = obj[prop]
24
- return r
25
- }, {} as T)
26
20
  }
21
+ // Start as empty object, pick/add needed properties
22
+ return props.reduce((r, prop) => {
23
+ if (prop in obj) r[prop] = obj[prop]
24
+ return r
25
+ }, {} as T)
27
26
  }
28
27
 
29
28
  /**
@@ -285,7 +284,7 @@ export function _unset<T extends AnyObject>(obj: T, prop: string): void {
285
284
 
286
285
  const segs = prop.split('.')
287
286
  let last = segs.pop()
288
- while (segs.length && segs[segs.length - 1]!.slice(-1) === '\\') {
287
+ while (segs.length && segs[segs.length - 1]!.endsWith('\\')) {
289
288
  last = segs.pop()!.slice(0, -1) + '.' + last
290
289
  }
291
290
  while (segs.length && _isObject(obj)) {
@@ -359,7 +358,7 @@ export function _set<T extends AnyObject>(obj: T, path: PropertyPath, value: any
359
358
  a[c]
360
359
  : // No: create the key. Is the next key a potential array-index?
361
360
  (a[c] =
362
- // @ts-ignore
361
+ // @ts-expect-error
363
362
  // eslint-disable-next-line
364
363
  Math.abs(path[i + 1]) >> 0 === +path[i + 1]
365
364
  ? [] // Yes: assign a new array object
@@ -43,7 +43,7 @@ export interface PRetryOptions {
43
43
  *
44
44
  * @default () => true
45
45
  */
46
- predicate?: (err: Error, attempt: number, maxAttempts: number) => boolean
46
+ predicate?(err: Error, attempt: number, maxAttempts: number): boolean
47
47
 
48
48
  /**
49
49
  * Log the first attempt (which is not a "retry" yet).
@@ -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.
@@ -59,17 +62,19 @@ export function pTimeoutFn<T extends AnyAsyncFunction>(fn: T, opt: PTimeoutOptio
59
62
  * If the Function rejects - passes this rejection further.
60
63
  */
61
64
  export async function pTimeout<T>(fn: AnyAsyncFunction<T>, opt: PTimeoutOptions): Promise<T> {
62
- // todo: check how we can automatically infer function name (only applicable to named functions)
63
- const { timeout, name, onTimeout, keepStackTrace = true } = opt
65
+ const { timeout, name = fn.name || 'pTimeout function', onTimeout, keepStackTrace = true } = opt
64
66
  const fakeError = keepStackTrace ? new Error('TimeoutError') : undefined
65
67
 
66
68
  // eslint-disable-next-line no-async-promise-executor
67
69
  return await new Promise(async (resolve, reject) => {
68
70
  // Prepare the timeout timer
69
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
+
70
75
  if (onTimeout) {
71
76
  try {
72
- resolve(onTimeout())
77
+ resolve(onTimeout(err))
73
78
  } catch (err: any) {
74
79
  if (fakeError) err.stack = fakeError.stack // keep original stack
75
80
  err.data = {
@@ -81,11 +86,6 @@ export async function pTimeout<T>(fn: AnyAsyncFunction<T>, opt: PTimeoutOptions)
81
86
  return
82
87
  }
83
88
 
84
- const err = new TimeoutError(
85
- `"${name || 'pTimeout function'}" timed out after ${timeout} ms`,
86
- opt.errorData,
87
- )
88
- if (fakeError) err.stack = fakeError.stack // keep original stack
89
89
  reject(err)
90
90
  }, timeout)
91
91
 
@@ -31,7 +31,7 @@ export interface PupaOptions {
31
31
  /**
32
32
  * Performs arbitrary operation for each interpolation. If the returned value was `undefined`, it behaves differently depending on the `ignoreMissing` option. Otherwise, the returned value will be interpolated into a string (and escaped when double-braced) and embedded into the template.
33
33
  */
34
- transform?: (data: { value: any; key: string }) => unknown
34
+ transform?(data: { value: any; key: string }): unknown
35
35
  }
36
36
 
37
37
  /**
@@ -16,7 +16,7 @@ export interface ReadingTimeOptions {
16
16
  * A function that returns a boolean value depending on if a character is considered as a word bound.
17
17
  * Default: spaces, new lines and tabs
18
18
  */
19
- wordBound?: (char: string) => boolean
19
+ wordBound?(char: string): boolean
20
20
  /**
21
21
  * Default 200
22
22
  */
@@ -26,11 +26,9 @@ function serializer(replacer?: Reviver, cycleReplacer?: Reviver): Reviver {
26
26
  const stack: any[] = []
27
27
  const keys: string[] = []
28
28
 
29
- if (cycleReplacer == null) {
30
- cycleReplacer = function (key, value) {
31
- if (stack[0] === value) return '[Circular ~]'
32
- return '[Circular ~.' + keys.slice(0, stack.indexOf(value)).join('.') + ']'
33
- }
29
+ cycleReplacer ??= function (key, value) {
30
+ if (stack[0] === value) return '[Circular ~]'
31
+ return '[Circular ~.' + keys.slice(0, stack.indexOf(value)).join('.') + ']'
34
32
  }
35
33
 
36
34
  return function (key, value) {
@@ -16,7 +16,7 @@ import type { StringMap } from '../types'
16
16
  export function _parseQueryString(search: string): StringMap {
17
17
  const qs: StringMap = {}
18
18
  search
19
- .slice(search[0] === '?' ? 1 : 0)
19
+ .slice(search.startsWith('?') ? 1 : 0)
20
20
  .split('&')
21
21
  .forEach(p => {
22
22
  const [k, v] = p.split('=')