@naturalcycles/js-lib 14.101.0 → 14.104.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 (48) hide show
  1. package/dist/array/array.util.d.ts +15 -6
  2. package/dist/array/array.util.js +22 -8
  3. package/dist/decorators/memo.util.js +2 -2
  4. package/dist/index.d.ts +3 -2
  5. package/dist/index.js +1 -0
  6. package/dist/is.util.d.ts +40 -0
  7. package/dist/is.util.js +72 -0
  8. package/dist/json-schema/jsonSchemaBuilder.d.ts +3 -0
  9. package/dist/json-schema/jsonSchemaBuilder.js +7 -2
  10. package/dist/json-schema/jsonSchemas.js +4 -4
  11. package/dist/object/object.util.d.ts +0 -17
  12. package/dist/object/object.util.js +9 -52
  13. package/dist/object/sortObjectDeep.js +2 -2
  14. package/dist/types.d.ts +2 -0
  15. package/dist-esm/array/array.util.js +22 -8
  16. package/dist-esm/datetime/localTime.js +1 -2
  17. package/dist-esm/decorators/createPromiseDecorator.js +10 -5
  18. package/dist-esm/decorators/debounce.js +6 -1
  19. package/dist-esm/decorators/memo.util.js +1 -1
  20. package/dist-esm/error/assert.js +12 -3
  21. package/dist-esm/error/error.util.js +8 -7
  22. package/dist-esm/error/tryCatch.js +1 -1
  23. package/dist-esm/index.js +1 -0
  24. package/dist-esm/is.util.js +59 -0
  25. package/dist-esm/json-schema/jsonSchema.util.js +2 -3
  26. package/dist-esm/json-schema/jsonSchemaBuilder.js +8 -4
  27. package/dist-esm/json-schema/jsonSchemas.js +4 -4
  28. package/dist-esm/math/math.util.js +1 -1
  29. package/dist-esm/object/object.util.js +4 -44
  30. package/dist-esm/object/sortObjectDeep.js +1 -1
  31. package/dist-esm/promise/pMap.js +15 -27
  32. package/dist-esm/promise/pQueue.js +7 -2
  33. package/dist-esm/promise/pRetry.js +4 -1
  34. package/dist-esm/promise/pTimeout.js +4 -1
  35. package/dist-esm/string/json.util.js +1 -1
  36. package/dist-esm/string/safeJsonStringify.js +1 -1
  37. package/dist-esm/string/stringifyAny.js +1 -1
  38. package/dist-esm/vendor/is.js +7 -8
  39. package/package.json +1 -1
  40. package/src/array/array.util.ts +28 -14
  41. package/src/decorators/memo.util.ts +1 -1
  42. package/src/index.ts +6 -0
  43. package/src/is.util.ts +77 -0
  44. package/src/json-schema/jsonSchemaBuilder.ts +7 -2
  45. package/src/json-schema/jsonSchemas.ts +4 -4
  46. package/src/object/object.util.ts +1 -49
  47. package/src/object/sortObjectDeep.ts +1 -1
  48. package/src/types.ts +3 -0
@@ -18,7 +18,10 @@ import { AppError } from './app.error';
18
18
  export function _assert(condition, // will be evaluated as Boolean
19
19
  message, errorData) {
20
20
  if (!condition) {
21
- throw new AssertionError(message || 'see stacktrace', Object.assign({ userFriendly: true }, errorData));
21
+ throw new AssertionError(message || 'see stacktrace', {
22
+ userFriendly: true,
23
+ ...errorData,
24
+ });
22
25
  }
23
26
  }
24
27
  /**
@@ -36,7 +39,10 @@ export function _assertEquals(actual, expected, message, errorData) {
36
39
  ]
37
40
  .filter(Boolean)
38
41
  .join('\n');
39
- throw new AssertionError(msg, Object.assign({ userFriendly: true }, errorData));
42
+ throw new AssertionError(msg, {
43
+ userFriendly: true,
44
+ ...errorData,
45
+ });
40
46
  }
41
47
  }
42
48
  /**
@@ -54,7 +60,10 @@ export function _assertDeepEquals(actual, expected, message, errorData) {
54
60
  ]
55
61
  .filter(Boolean)
56
62
  .join('\n');
57
- throw new AssertionError(msg, Object.assign({ userFriendly: true }, errorData));
63
+ throw new AssertionError(msg, {
64
+ userFriendly: true,
65
+ ...errorData,
66
+ });
58
67
  }
59
68
  }
60
69
  export function _assertIsError(err, message) {
@@ -21,9 +21,8 @@ export function _anyToError(o, errorClass = Error, opt) {
21
21
  * Objects (not Errors) get converted to prettified JSON string (via `_stringifyAny`).
22
22
  */
23
23
  export function _anyToErrorObject(o, opt) {
24
- var _a;
25
24
  if (o instanceof Error) {
26
- return _errorToErrorObject(o, (_a = opt === null || opt === void 0 ? void 0 : opt.includeErrorStack) !== null && _a !== void 0 ? _a : true);
25
+ return _errorToErrorObject(o, opt?.includeErrorStack ?? true);
27
26
  }
28
27
  o = _jsonParseIfPossible(o);
29
28
  if (_isHttpErrorResponse(o)) {
@@ -36,7 +35,10 @@ export function _anyToErrorObject(o, opt) {
36
35
  // so, fair to return `data: {}` in the end
37
36
  // Also we're sure it includes no "error name", e.g no `Error: ...`,
38
37
  // so, fair to include `name: 'Error'`
39
- const message = _stringifyAny(o, Object.assign({ includeErrorData: true }, opt));
38
+ const message = _stringifyAny(o, {
39
+ includeErrorData: true,
40
+ ...opt,
41
+ });
40
42
  return {
41
43
  name: 'Error',
42
44
  message,
@@ -47,7 +49,7 @@ export function _errorToErrorObject(e, includeErrorStack = true) {
47
49
  const obj = {
48
50
  name: e.name,
49
51
  message: e.message,
50
- data: Object.assign({}, e.data), // empty by default
52
+ data: { ...e.data }, // empty by default
51
53
  };
52
54
  if (includeErrorStack) {
53
55
  obj.stack = e.stack;
@@ -81,14 +83,13 @@ export function _errorObjectToError(o, errorClass = Error) {
81
83
  return err;
82
84
  }
83
85
  export function _isHttpErrorResponse(o) {
84
- return _isHttpErrorObject(o === null || o === void 0 ? void 0 : o.error);
86
+ return _isHttpErrorObject(o?.error);
85
87
  }
86
88
  export function _isHttpErrorObject(o) {
87
- var _a;
88
89
  return (!!o &&
89
90
  typeof o.name === 'string' &&
90
91
  typeof o.message === 'string' &&
91
- typeof ((_a = o.data) === null || _a === void 0 ? void 0 : _a.httpStatusCode) === 'number');
92
+ typeof o.data?.httpStatusCode === 'number');
92
93
  }
93
94
  /**
94
95
  * Note: any instance of AppError is also automatically an ErrorObject
@@ -29,7 +29,7 @@ export function _tryCatch(fn, opt = {}) {
29
29
  try {
30
30
  return await onError(_anyToError(err)); // eslint-disable-line @typescript-eslint/return-await
31
31
  }
32
- catch (_a) { }
32
+ catch { }
33
33
  }
34
34
  // returns undefined, but doesn't rethrow
35
35
  }
package/dist-esm/index.js CHANGED
@@ -47,6 +47,7 @@ export * from './string/json.util';
47
47
  export * from './string/string.util';
48
48
  import { _stringifyAny } from './string/stringifyAny';
49
49
  export * from './time/time.util';
50
+ export * from './is.util';
50
51
  import { END, SKIP, _noop, _objectKeys, _passNothingPredicate, _passthroughMapper, _passthroughPredicate, _passUndefinedMapper, _stringMapEntries, _stringMapValues, } from './types';
51
52
  export * from './unit/size.util';
52
53
  import { is } from './vendor/is';
@@ -0,0 +1,59 @@
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;
4
+ export const _isNotNullish = (v) => v !== undefined && v !== null;
5
+ /**
6
+ * Same as Boolean, but with correct type output.
7
+ * Related:
8
+ * https://github.com/microsoft/TypeScript/issues/16655
9
+ * https://www.karltarvas.com/2021/03/11/typescript-array-filter-boolean.html
10
+ *
11
+ * @example
12
+ *
13
+ * [1, 2, undefined].filter(_isTruthy)
14
+ * // => [1, 2]
15
+ */
16
+ export const _isTruthy = (v) => !!v;
17
+ export const _isFalsy = (v) => !v;
18
+ /**
19
+ * Returns true if item is Object, not null and not Array.
20
+ */
21
+ export function _isObject(item) {
22
+ return (typeof item === 'object' && item !== null && !Array.isArray(item)) || false;
23
+ }
24
+ export function _isPrimitive(v) {
25
+ return (v === null ||
26
+ v === undefined ||
27
+ typeof v === 'number' ||
28
+ typeof v === 'boolean' ||
29
+ typeof v === 'string' ||
30
+ typeof v === 'bigint' ||
31
+ typeof v === 'symbol');
32
+ }
33
+ export function _isEmptyObject(obj) {
34
+ return obj && obj.constructor === Object && Object.keys(obj).length === 0;
35
+ }
36
+ /**
37
+ * Object is considered empty if it's one of:
38
+ * undefined
39
+ * null
40
+ * '' (empty string)
41
+ * [] (empty array)
42
+ * {} (empty object)
43
+ * new Map() (empty Map)
44
+ * new Set() (empty Set)
45
+ */
46
+ export function _isEmpty(obj) {
47
+ if (obj === undefined || obj === null)
48
+ return true;
49
+ if (typeof obj === 'string' || Array.isArray(obj)) {
50
+ return obj.length === 0;
51
+ }
52
+ if (obj instanceof Map || obj instanceof Set) {
53
+ return obj.size === 0;
54
+ }
55
+ if (typeof obj === 'object') {
56
+ return Object.keys(obj).length === 0;
57
+ }
58
+ return false;
59
+ }
@@ -6,7 +6,6 @@ import { _filterNullishValues } from '../object/object.util';
6
6
  * API similar to Object.assign(s1, s2)
7
7
  */
8
8
  export function mergeJsonSchemaObjects(s1, s2) {
9
- var _a, _b;
10
9
  // Merge `properties`
11
10
  Object.entries(s2.properties).forEach(([k, v]) => {
12
11
  ;
@@ -18,8 +17,8 @@ export function mergeJsonSchemaObjects(s1, s2) {
18
17
  s1.patternProperties[k] = v;
19
18
  });
20
19
  s1.propertyNames = s2.propertyNames || s1.propertyNames;
21
- s1.minProperties = (_a = s2.minProperties) !== null && _a !== void 0 ? _a : s1.minProperties;
22
- s1.maxProperties = (_b = s2.maxProperties) !== null && _b !== void 0 ? _b : s1.maxProperties;
20
+ s1.minProperties = s2.minProperties ?? s1.minProperties;
21
+ s1.maxProperties = s2.maxProperties ?? s1.maxProperties;
23
22
  // Merge `required`
24
23
  s1.required.push(...s2.required);
25
24
  s1.required = _uniq(s1.required).sort();
@@ -47,6 +47,9 @@ export const jsonSchema = {
47
47
  unixTimestamp() {
48
48
  return new JsonSchemaNumberBuilder().unixTimestamp();
49
49
  },
50
+ unixTimestamp2000() {
51
+ return new JsonSchemaNumberBuilder().unixTimestamp2000();
52
+ },
50
53
  // string types
51
54
  string() {
52
55
  return new JsonSchemaStringBuilder();
@@ -163,7 +166,9 @@ export class JsonSchemaNumberBuilder extends JsonSchemaAnyBuilder {
163
166
  this.float = () => this.format('float');
164
167
  this.double = () => this.format('double');
165
168
  this.unixTimestamp = () => this.format('unixTimestamp');
169
+ this.unixTimestamp2000 = () => this.format('unixTimestamp2000');
166
170
  this.unixTimestampMillis = () => this.format('unixTimestampMillis');
171
+ this.unixTimestampMillis2000 = () => this.format('unixTimestampMillis2000');
167
172
  this.utcOffset = () => this.format('utcOffset');
168
173
  this.utcOffsetHours = () => this.format('utcOffsetHours');
169
174
  }
@@ -245,12 +250,11 @@ export class JsonSchemaStringBuilder extends JsonSchemaAnyBuilder {
245
250
  return this;
246
251
  }
247
252
  transformModify(t, add) {
248
- var _a;
249
253
  if (add) {
250
254
  this.schema.transform = _uniq([...(this.schema.transform || []), t]);
251
255
  }
252
256
  else {
253
- this.schema.transform = (_a = this.schema.transform) === null || _a === void 0 ? void 0 : _a.filter(s => s !== t);
257
+ this.schema.transform = this.schema.transform?.filter(s => s !== t);
254
258
  }
255
259
  return this;
256
260
  }
@@ -304,8 +308,8 @@ export class JsonSchemaObjectBuilder extends JsonSchemaAnyBuilder {
304
308
  baseDBEntity(idType = 'string') {
305
309
  Object.assign(this.schema.properties, {
306
310
  id: { type: idType },
307
- created: { type: 'number', format: 'unixTimestamp' },
308
- updated: { type: 'number', format: 'unixTimestamp' },
311
+ created: { type: 'number', format: 'unixTimestamp2000' },
312
+ updated: { type: 'number', format: 'unixTimestamp2000' },
309
313
  });
310
314
  return this;
311
315
  }
@@ -1,11 +1,11 @@
1
1
  import { jsonSchema } from './jsonSchemaBuilder';
2
2
  export const baseDBEntityJsonSchema = jsonSchema.object({
3
3
  id: jsonSchema.string().optional(),
4
- created: jsonSchema.unixTimestamp().optional(),
5
- updated: jsonSchema.unixTimestamp().optional(),
4
+ created: jsonSchema.unixTimestamp2000().optional(),
5
+ updated: jsonSchema.unixTimestamp2000().optional(),
6
6
  });
7
7
  export const savedDBEntityJsonSchema = jsonSchema.object({
8
8
  id: jsonSchema.string(),
9
- created: jsonSchema.unixTimestamp(),
10
- updated: jsonSchema.unixTimestamp(),
9
+ created: jsonSchema.unixTimestamp2000(),
10
+ updated: jsonSchema.unixTimestamp2000(),
11
11
  });
@@ -14,7 +14,7 @@ export function _average(values) {
14
14
  * Same as _average, but safely returns null if input array is empty or nullish.
15
15
  */
16
16
  export function _averageOrNull(values) {
17
- return (values === null || values === void 0 ? void 0 : values.length) ? values.reduce((a, b) => a + b) / values.length : null;
17
+ return values?.length ? values.reduce((a, b) => a + b) / values.length : null;
18
18
  }
19
19
  /**
20
20
  * valuesArray and weightsArray length is expected to be the same.
@@ -1,3 +1,4 @@
1
+ import { _isEmpty, _isObject } from '../is.util';
1
2
  /**
2
3
  * Returns clone of `obj` with only `props` preserved.
3
4
  * Opposite of Omit.
@@ -28,7 +29,7 @@ export function _omit(obj, props, mutate = false) {
28
29
  return props.reduce((r, prop) => {
29
30
  delete r[prop];
30
31
  return r;
31
- }, mutate ? obj : Object.assign({}, obj));
32
+ }, mutate ? obj : { ...obj });
32
33
  }
33
34
  /**
34
35
  * Returns object with filtered keys from `props` array.
@@ -75,7 +76,7 @@ export function _filterObject(obj, predicate, mutate = false) {
75
76
  if (!predicate(k, r[k], obj))
76
77
  delete r[k];
77
78
  return r;
78
- }, mutate ? obj : Object.assign({}, obj));
79
+ }, mutate ? obj : { ...obj });
79
80
  }
80
81
  /**
81
82
  * var users = {
@@ -136,8 +137,7 @@ export function _mapObject(obj, mapper) {
136
137
  }, {});
137
138
  }
138
139
  export function _findKeyByValue(obj, v) {
139
- var _a;
140
- return (_a = Object.entries(obj).find(([_, value]) => value === v)) === null || _a === void 0 ? void 0 : _a[0];
140
+ return Object.entries(obj).find(([_, value]) => value === v)?.[0];
141
141
  }
142
142
  export function _objectNullValuesToUndefined(obj, mutate = false) {
143
143
  return _mapValues(obj, (_k, v) => (v === null ? undefined : v), mutate);
@@ -148,46 +148,6 @@ export function _objectNullValuesToUndefined(obj, mutate = false) {
148
148
  export function _deepCopy(o) {
149
149
  return JSON.parse(JSON.stringify(o));
150
150
  }
151
- /**
152
- * Returns true if item is Object, not null and not Array.
153
- */
154
- export function _isObject(item) {
155
- return (typeof item === 'object' && item !== null && !Array.isArray(item)) || false;
156
- }
157
- export function _isPrimitive(v) {
158
- return (v === null ||
159
- v === undefined ||
160
- typeof v === 'number' ||
161
- typeof v === 'boolean' ||
162
- typeof v === 'string');
163
- }
164
- export function _isEmptyObject(obj) {
165
- return obj && obj.constructor === Object && Object.keys(obj).length === 0;
166
- }
167
- /**
168
- * Object is considered empty if it's one of:
169
- * undefined
170
- * null
171
- * '' (empty string)
172
- * [] (empty array)
173
- * {} (empty object)
174
- * new Map() (empty Map)
175
- * new Set() (empty Set)
176
- */
177
- export function _isEmpty(obj) {
178
- if (obj === undefined || obj === null)
179
- return true;
180
- if (typeof obj === 'string' || Array.isArray(obj)) {
181
- return obj.length === 0;
182
- }
183
- if (obj instanceof Map || obj instanceof Set) {
184
- return obj.size === 0;
185
- }
186
- if (typeof obj === 'object') {
187
- return Object.keys(obj).length === 0;
188
- }
189
- return false;
190
- }
191
151
  /**
192
152
  * Returns `undefined` if it's empty (according to `_isEmpty()` specification),
193
153
  * otherwise returns the original object.
@@ -1,4 +1,4 @@
1
- import { _isObject } from './object.util';
1
+ import { _isObject } from '..';
2
2
  /**
3
3
  * based on: https://github.com/IndigoUnited/js-deep-sort-object
4
4
  */
@@ -6,7 +6,6 @@ Improvements:
6
6
  - Included Typescript typings (no need for @types/p-map)
7
7
  - Compatible with pProps (that had typings issues)
8
8
  */
9
- import { __asyncValues } from "tslib";
10
9
  import { END, ErrorMode, SKIP } from '..';
11
10
  import { AggregatedError } from './AggregatedError';
12
11
  /**
@@ -36,7 +35,6 @@ import { AggregatedError } from './AggregatedError';
36
35
  * })();
37
36
  */
38
37
  export async function pMap(iterable, mapper, opt = {}) {
39
- var e_1, _a;
40
38
  const ret = [];
41
39
  // const iterator = iterable[Symbol.iterator]()
42
40
  const items = [...iterable];
@@ -50,33 +48,23 @@ export async function pMap(iterable, mapper, opt = {}) {
50
48
  let currentIndex = 0;
51
49
  // Special cases that are able to preserve async stack traces
52
50
  if (concurrency === 1) {
53
- try {
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;
57
- 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);
69
- }
70
- // otherwise, suppress completely
71
- }
72
- }
73
- }
74
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
75
- finally {
51
+ // Special case for concurrency == 1
52
+ for await (const item of items) {
76
53
  try {
77
- if (items_1_1 && !items_1_1.done && (_a = items_1.return)) await _a.call(items_1);
54
+ const r = await mapper(item, currentIndex++);
55
+ if (r === END)
56
+ break;
57
+ if (r !== SKIP)
58
+ ret.push(r);
59
+ }
60
+ catch (err) {
61
+ if (errorMode === ErrorMode.THROW_IMMEDIATELY)
62
+ throw err;
63
+ if (errorMode === ErrorMode.THROW_AGGREGATED) {
64
+ errors.push(err);
65
+ }
66
+ // otherwise, suppress completely
78
67
  }
79
- finally { if (e_1) throw e_1.error; }
80
68
  }
81
69
  if (errors.length) {
82
70
  throw new AggregatedError(errors, ret);
@@ -13,9 +13,14 @@ export class PQueue {
13
13
  this.inFlight = 0;
14
14
  this.queue = [];
15
15
  this.onIdleListeners = [];
16
- this.cfg = Object.assign({
16
+ this.cfg = {
17
17
  // concurrency: Number.MAX_SAFE_INTEGER,
18
- errorMode: ErrorMode.THROW_IMMEDIATELY, logger: console, debug: false, resolveOn: 'finish' }, cfg);
18
+ errorMode: ErrorMode.THROW_IMMEDIATELY,
19
+ logger: console,
20
+ debug: false,
21
+ resolveOn: 'finish',
22
+ ...cfg,
23
+ };
19
24
  if (!cfg.debug) {
20
25
  this.debug = () => { };
21
26
  }
@@ -72,7 +72,10 @@ export async function pRetry(fn, opt = {}) {
72
72
  });
73
73
  }
74
74
  ;
75
- err.data = Object.assign(Object.assign({}, err.data), opt.errorData);
75
+ err.data = {
76
+ ...err.data,
77
+ ...opt.errorData,
78
+ };
76
79
  reject(err);
77
80
  }
78
81
  else {
@@ -32,7 +32,10 @@ export async function pTimeout(promise, opt) {
32
32
  catch (err) {
33
33
  if (fakeError)
34
34
  err.stack = fakeError.stack; // keep original stack
35
- err.data = Object.assign(Object.assign({}, err.data), opt.errorData);
35
+ err.data = {
36
+ ...err.data,
37
+ ...opt.errorData,
38
+ };
36
39
  reject(err);
37
40
  }
38
41
  return;
@@ -10,7 +10,7 @@ export function _jsonParseIfPossible(obj, reviver) {
10
10
  try {
11
11
  return JSON.parse(obj, reviver);
12
12
  }
13
- catch (_a) { }
13
+ catch { }
14
14
  }
15
15
  return obj;
16
16
  }
@@ -8,7 +8,7 @@ export function _safeJsonStringify(obj, replacer, spaces, cycleReplacer) {
8
8
  // Try native first (as it's ~3 times faster)
9
9
  return JSON.stringify(obj, replacer, spaces);
10
10
  }
11
- catch (_a) {
11
+ catch {
12
12
  // Native failed - resort to the "safe" serializer
13
13
  return JSON.stringify(obj, serializer(replacer, cycleReplacer), spaces);
14
14
  }
@@ -85,7 +85,7 @@ export function _stringifyAny(obj, opt = {}) {
85
85
  const { stringifyFn = _safeJsonStringify } = opt;
86
86
  s = stringifyFn(obj, undefined, 2);
87
87
  }
88
- catch (_a) {
88
+ catch {
89
89
  s = String(obj); // fallback
90
90
  }
91
91
  }
@@ -138,15 +138,15 @@ is.array = (value, assertion) => {
138
138
  }
139
139
  return value.every(assertion);
140
140
  };
141
- is.buffer = (value) => { var _a, _b, _c; return (_c = (_b = (_a = value === null || value === void 0 ? void 0 : value.constructor) === null || _a === void 0 ? void 0 : _a.isBuffer) === null || _b === void 0 ? void 0 : _b.call(_a, value)) !== null && _c !== void 0 ? _c : false; };
141
+ is.buffer = (value) => value?.constructor?.isBuffer?.(value) ?? false;
142
142
  is.nullOrUndefined = (value) => is.null_(value) || is.undefined(value);
143
143
  is.object = (value) => !is.null_(value) && (typeof value === 'object' || is.function_(value));
144
- is.iterable = (value) => is.function_(value === null || value === void 0 ? void 0 : value[Symbol.iterator]);
145
- is.asyncIterable = (value) => is.function_(value === null || value === void 0 ? void 0 : value[Symbol.asyncIterator]);
144
+ is.iterable = (value) => is.function_(value?.[Symbol.iterator]);
145
+ is.asyncIterable = (value) => is.function_(value?.[Symbol.asyncIterator]);
146
146
  is.generator = (value) => is.iterable(value) && is.function_(value.next) && is.function_(value.throw);
147
147
  is.asyncGenerator = (value) => is.asyncIterable(value) && is.function_(value.next) && is.function_(value.throw);
148
148
  is.nativePromise = (value) => isObjectOfType('Promise')(value);
149
- const hasPromiseAPI = (value) => is.function_(value === null || value === void 0 ? void 0 : value.then) && is.function_(value === null || value === void 0 ? void 0 : value.catch);
149
+ const hasPromiseAPI = (value) => is.function_(value?.then) && is.function_(value?.catch);
150
150
  is.promise = (value) => is.nativePromise(value) || hasPromiseAPI(value);
151
151
  is.generatorFunction = isObjectOfType('GeneratorFunction');
152
152
  is.asyncGeneratorFunction = (value) => getObjectType(value) === 'AsyncGeneratorFunction';
@@ -184,7 +184,7 @@ is.urlString = (value) => {
184
184
  new URL(value); // eslint-disable-line no-new
185
185
  return true;
186
186
  }
187
- catch (_a) {
187
+ catch {
188
188
  return false;
189
189
  }
190
190
  };
@@ -235,14 +235,13 @@ is.domElement = (value) => {
235
235
  DOM_PROPERTIES_TO_CHECK.every(property => property in value));
236
236
  };
237
237
  is.observable = (value) => {
238
- var _a, _b, _c, _d;
239
238
  if (!value) {
240
239
  return false;
241
240
  }
242
- if (value === ((_b = (_a = value)[Symbol.observable]) === null || _b === void 0 ? void 0 : _b.call(_a))) {
241
+ if (value === value[Symbol.observable]?.()) {
243
242
  return true;
244
243
  }
245
- if (value === ((_d = (_c = value)['@@observable']) === null || _d === void 0 ? void 0 : _d.call(_c))) {
244
+ if (value === value['@@observable']?.()) {
246
245
  return true;
247
246
  }
248
247
  return false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naturalcycles/js-lib",
3
- "version": "14.101.0",
3
+ "version": "14.104.0",
4
4
  "scripts": {
5
5
  "prepare": "husky install",
6
6
  "build-prod": "build-prod-esm-cjs",
@@ -1,5 +1,6 @@
1
+ import { _isNotNullish } from '../is.util'
1
2
  import { RecursiveArray } from '../lodash.types'
2
- import { Mapper, Predicate, StringMap } from '../types'
3
+ import { FalsyValue, Mapper, Predicate, StringMap } from '../types'
3
4
 
4
5
  /**
5
6
  * Creates an array of elements split into groups the length of size. If collection can’t be split evenly, the
@@ -216,6 +217,9 @@ export function _difference<T>(source: T[], ...diffs: T[][]): T[] {
216
217
  return diffs.reduce((a, b) => a.filter(c => !b.includes(c)), source)
217
218
  }
218
219
 
220
+ /**
221
+ * Returns the sum of items, or 0 for empty array.
222
+ */
219
223
  export function _sum(items: number[]): number {
220
224
  return items.reduce((sum, n) => sum + n, 0)
221
225
  }
@@ -242,7 +246,7 @@ export function _sumBy<T>(items: T[], mapper: Mapper<T, number | undefined>): nu
242
246
  */
243
247
  export function _mapToObject<T, V>(
244
248
  array: T[],
245
- mapper: (item: T) => [key: any, value: V] | undefined | null | false | 0 | void,
249
+ mapper: (item: T) => [key: any, value: V] | FalsyValue,
246
250
  ): StringMap<V> {
247
251
  const m: StringMap<V> = {}
248
252
 
@@ -288,22 +292,32 @@ export function _lastOrUndefined<T>(array: T[]): T | undefined {
288
292
  return array[array.length - 1]
289
293
  }
290
294
 
291
- export function _minOrUndefined<T>(array: T[]): T | undefined {
292
- if (!array.length) return
293
- return _min(array)
295
+ export function _minOrUndefined<T>(array: T[]): NonNullable<T> | undefined {
296
+ const a = array.filter(_isNotNullish)
297
+ if (!a.length) return
298
+ return _min(a)
294
299
  }
295
300
 
296
- export function _min<T>(array: T[]): T {
297
- if (!array.length) throw new Error('_min called on empty array')
298
- return array.reduce((min, item) => (min <= item ? min : item))
301
+ /**
302
+ * Filters out nullish values (undefined and null).
303
+ */
304
+ export function _min<T>(array: T[]): NonNullable<T> {
305
+ const a = array.filter(_isNotNullish)
306
+ if (!a.length) throw new Error('_min called on empty array')
307
+ return a.reduce((min, item) => (min <= item ? min : item))
299
308
  }
300
309
 
301
- export function _maxOrUndefined<T>(array: T[]): T | undefined {
302
- if (!array.length) return
303
- return _max(array)
310
+ export function _maxOrUndefined<T>(array: T[]): NonNullable<T> | undefined {
311
+ const a = array.filter(_isNotNullish)
312
+ if (!a.length) return
313
+ return _max(a)
304
314
  }
305
315
 
306
- export function _max<T>(array: T[]): T {
307
- if (!array.length) throw new Error('_max called on empty array')
308
- return array.reduce((max, item) => (max >= item ? max : item))
316
+ /**
317
+ * Filters out nullish values (undefined and null).
318
+ */
319
+ export function _max<T>(array: T[]): NonNullable<T> {
320
+ const a = array.filter(_isNotNullish)
321
+ if (!a.length) throw new Error('_max called on empty array')
322
+ return a.reduce((max, item) => (max >= item ? max : item))
309
323
  }
@@ -1,4 +1,4 @@
1
- import { _isPrimitive } from '../object/object.util'
1
+ import { _isPrimitive } from '..'
2
2
  import { Promisable } from '../typeFest'
3
3
 
4
4
  export type MemoSerializer = (args: any[]) => any
package/src/index.ts CHANGED
@@ -83,6 +83,8 @@ export * from './string/json.util'
83
83
  export * from './string/string.util'
84
84
  import { JsonStringifyFunction, StringifyAnyOptions, _stringifyAny } from './string/stringifyAny'
85
85
  export * from './time/time.util'
86
+ export * from './is.util'
87
+
86
88
  import {
87
89
  Class,
88
90
  ConditionalExcept,
@@ -129,6 +131,8 @@ import {
129
131
  AbortableAsyncPredicate,
130
132
  AbortableAsyncMapper,
131
133
  AbortablePredicate,
134
+ NullishValue,
135
+ FalsyValue,
132
136
  END,
133
137
  SKIP,
134
138
  _noop,
@@ -224,6 +228,8 @@ export type {
224
228
  IsoDateString,
225
229
  IsoDateTimeString,
226
230
  Reviver,
231
+ FalsyValue,
232
+ NullishValue,
227
233
  PMapOptions,
228
234
  Mapper,
229
235
  AsyncMapper,