@naturalcycles/js-lib 15.75.0 → 15.76.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/array/array.util.d.ts +9 -0
- package/dist/array/array.util.js +13 -0
- package/dist/is.util.js +17 -3
- package/dist/object/object.util.d.ts +23 -0
- package/dist/object/object.util.js +41 -0
- package/package.json +2 -2
- package/src/array/array.util.ts +13 -0
- package/src/is.util.ts +14 -3
- package/src/object/object.util.ts +41 -0
|
@@ -217,6 +217,15 @@ export declare function _first<T>(array: readonly T[]): T;
|
|
|
217
217
|
* Returns first item of the array (or undefined if array is empty).
|
|
218
218
|
*/
|
|
219
219
|
export declare function _firstOrUndefined<T>(array: readonly T[]): T | undefined;
|
|
220
|
+
/**
|
|
221
|
+
* Returns the first item of an iterable (Set, Map.values(), generator, etc.),
|
|
222
|
+
* or `undefined` if the iterable is empty.
|
|
223
|
+
*
|
|
224
|
+
* Avoids the `Array.from(iter)[0]` pattern that materialises the entire iterable.
|
|
225
|
+
* `for...of` with an early return advances the iterator exactly once; if the
|
|
226
|
+
* iterator implements `return()` (generators, etc.), it is invoked for cleanup.
|
|
227
|
+
*/
|
|
228
|
+
export declare function _firstFromIterable<T>(iter: Iterable<T>): T | undefined;
|
|
220
229
|
export declare function _minOrUndefined<T>(array: readonly T[]): NonNullable<T> | undefined;
|
|
221
230
|
/**
|
|
222
231
|
* Filters out nullish values (undefined and null).
|
package/dist/array/array.util.js
CHANGED
|
@@ -403,6 +403,19 @@ export function _first(array) {
|
|
|
403
403
|
export function _firstOrUndefined(array) {
|
|
404
404
|
return array[0];
|
|
405
405
|
}
|
|
406
|
+
/**
|
|
407
|
+
* Returns the first item of an iterable (Set, Map.values(), generator, etc.),
|
|
408
|
+
* or `undefined` if the iterable is empty.
|
|
409
|
+
*
|
|
410
|
+
* Avoids the `Array.from(iter)[0]` pattern that materialises the entire iterable.
|
|
411
|
+
* `for...of` with an early return advances the iterator exactly once; if the
|
|
412
|
+
* iterator implements `return()` (generators, etc.), it is invoked for cleanup.
|
|
413
|
+
*/
|
|
414
|
+
export function _firstFromIterable(iter) {
|
|
415
|
+
for (const item of iter)
|
|
416
|
+
return item;
|
|
417
|
+
return undefined;
|
|
418
|
+
}
|
|
406
419
|
export function _minOrUndefined(array) {
|
|
407
420
|
let min;
|
|
408
421
|
for (const item of array) {
|
package/dist/is.util.js
CHANGED
|
@@ -33,10 +33,20 @@ export function _isPrimitive(v) {
|
|
|
33
33
|
typeof v === 'symbol');
|
|
34
34
|
}
|
|
35
35
|
export function _isEmptyObject(obj) {
|
|
36
|
-
return Object.keys
|
|
36
|
+
// for...in with early return avoids allocating the full Object.keys array.
|
|
37
|
+
// Object.hasOwn matches Object.keys() semantics (own enumerable keys only).
|
|
38
|
+
for (const k in obj) {
|
|
39
|
+
if (Object.hasOwn(obj, k))
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
return true;
|
|
37
43
|
}
|
|
38
44
|
export function _isNotEmptyObject(obj) {
|
|
39
|
-
|
|
45
|
+
for (const k in obj) {
|
|
46
|
+
if (Object.hasOwn(obj, k))
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
return false;
|
|
40
50
|
}
|
|
41
51
|
/**
|
|
42
52
|
* Object is considered empty if it's one of:
|
|
@@ -58,7 +68,11 @@ export function _isEmpty(obj) {
|
|
|
58
68
|
return obj.size === 0;
|
|
59
69
|
}
|
|
60
70
|
if (typeof obj === 'object') {
|
|
61
|
-
|
|
71
|
+
for (const k in obj) {
|
|
72
|
+
if (Object.hasOwn(obj, k))
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
return true;
|
|
62
76
|
}
|
|
63
77
|
return false;
|
|
64
78
|
}
|
|
@@ -87,6 +87,29 @@ export declare function _mapKeys<T extends AnyObject>(obj: T, mapper: ObjectMapp
|
|
|
87
87
|
*/
|
|
88
88
|
export declare function _mapObject<OUT = unknown, IN extends AnyObject = AnyObject>(obj: IN, mapper: ObjectMapper<IN, KeyValueTuple<string, any> | typeof SKIP>): OUT;
|
|
89
89
|
export declare function _findKeyByValue<T extends AnyObject>(obj: T, v: ValueOf<T>): keyof T | undefined;
|
|
90
|
+
/**
|
|
91
|
+
* Returns the first key of the object, or `undefined` if the object is empty.
|
|
92
|
+
*
|
|
93
|
+
* Performance-optimised: uses `for...in` with an early return to avoid
|
|
94
|
+
* allocating the full `Object.keys(obj)` array. The `Object.hasOwn` filter
|
|
95
|
+
* matches `Object.keys()` semantics (own enumerable string keys only) and
|
|
96
|
+
* satisfies the `guard-for-in` lint rule; cost is a single check before
|
|
97
|
+
* the early return. Iteration order matches `Object.keys()` for plain
|
|
98
|
+
* objects (integer-like keys ascending first, then string keys in
|
|
99
|
+
* insertion order).
|
|
100
|
+
*/
|
|
101
|
+
export declare function _firstKey<T extends AnyObject>(obj: T): keyof T | undefined;
|
|
102
|
+
/**
|
|
103
|
+
* Returns the first value of the object, or `undefined` if the object is empty.
|
|
104
|
+
* See `_firstKey` for the iteration-order contract.
|
|
105
|
+
*/
|
|
106
|
+
export declare function _firstValue<T extends AnyObject>(obj: T): ValueOf<T> | undefined;
|
|
107
|
+
/**
|
|
108
|
+
* Returns the first [key, value] tuple of the object,
|
|
109
|
+
* or `undefined` if the object is empty.
|
|
110
|
+
* See `_firstKey` for the iteration-order contract.
|
|
111
|
+
*/
|
|
112
|
+
export declare function _firstEntry<T extends AnyObject>(obj: T): [keyof T, ValueOf<T>] | undefined;
|
|
90
113
|
export declare function _objectNullValuesToUndefined<T extends AnyObject>(obj: T, opt?: MutateOptions): T;
|
|
91
114
|
/**
|
|
92
115
|
* Deep copy object (by json parse/stringify, since it has unbeatable performance+simplicity combo).
|
|
@@ -191,6 +191,47 @@ export function _mapObject(obj, mapper) {
|
|
|
191
191
|
export function _findKeyByValue(obj, v) {
|
|
192
192
|
return Object.entries(obj).find(([_, value]) => value === v)?.[0];
|
|
193
193
|
}
|
|
194
|
+
/**
|
|
195
|
+
* Returns the first key of the object, or `undefined` if the object is empty.
|
|
196
|
+
*
|
|
197
|
+
* Performance-optimised: uses `for...in` with an early return to avoid
|
|
198
|
+
* allocating the full `Object.keys(obj)` array. The `Object.hasOwn` filter
|
|
199
|
+
* matches `Object.keys()` semantics (own enumerable string keys only) and
|
|
200
|
+
* satisfies the `guard-for-in` lint rule; cost is a single check before
|
|
201
|
+
* the early return. Iteration order matches `Object.keys()` for plain
|
|
202
|
+
* objects (integer-like keys ascending first, then string keys in
|
|
203
|
+
* insertion order).
|
|
204
|
+
*/
|
|
205
|
+
export function _firstKey(obj) {
|
|
206
|
+
for (const k in obj) {
|
|
207
|
+
if (Object.hasOwn(obj, k))
|
|
208
|
+
return k;
|
|
209
|
+
}
|
|
210
|
+
return undefined;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Returns the first value of the object, or `undefined` if the object is empty.
|
|
214
|
+
* See `_firstKey` for the iteration-order contract.
|
|
215
|
+
*/
|
|
216
|
+
export function _firstValue(obj) {
|
|
217
|
+
for (const k in obj) {
|
|
218
|
+
if (Object.hasOwn(obj, k))
|
|
219
|
+
return obj[k];
|
|
220
|
+
}
|
|
221
|
+
return undefined;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Returns the first [key, value] tuple of the object,
|
|
225
|
+
* or `undefined` if the object is empty.
|
|
226
|
+
* See `_firstKey` for the iteration-order contract.
|
|
227
|
+
*/
|
|
228
|
+
export function _firstEntry(obj) {
|
|
229
|
+
for (const k in obj) {
|
|
230
|
+
if (Object.hasOwn(obj, k))
|
|
231
|
+
return [k, obj[k]];
|
|
232
|
+
}
|
|
233
|
+
return undefined;
|
|
234
|
+
}
|
|
194
235
|
export function _objectNullValuesToUndefined(obj, opt = {}) {
|
|
195
236
|
return _mapValues(obj, (_k, v) => (v === null ? undefined : v), opt);
|
|
196
237
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@naturalcycles/js-lib",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "15.
|
|
4
|
+
"version": "15.76.0",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"tslib": "^2"
|
|
7
7
|
},
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"@typescript/native-preview": "beta",
|
|
21
21
|
"crypto-js": "^4",
|
|
22
22
|
"dayjs": "^1",
|
|
23
|
-
"@naturalcycles/dev-lib": "
|
|
23
|
+
"@naturalcycles/dev-lib": "18.4.2"
|
|
24
24
|
},
|
|
25
25
|
"exports": {
|
|
26
26
|
".": "./dist/index.js",
|
package/src/array/array.util.ts
CHANGED
|
@@ -468,6 +468,19 @@ export function _firstOrUndefined<T>(array: readonly T[]): T | undefined {
|
|
|
468
468
|
return array[0]
|
|
469
469
|
}
|
|
470
470
|
|
|
471
|
+
/**
|
|
472
|
+
* Returns the first item of an iterable (Set, Map.values(), generator, etc.),
|
|
473
|
+
* or `undefined` if the iterable is empty.
|
|
474
|
+
*
|
|
475
|
+
* Avoids the `Array.from(iter)[0]` pattern that materialises the entire iterable.
|
|
476
|
+
* `for...of` with an early return advances the iterator exactly once; if the
|
|
477
|
+
* iterator implements `return()` (generators, etc.), it is invoked for cleanup.
|
|
478
|
+
*/
|
|
479
|
+
export function _firstFromIterable<T>(iter: Iterable<T>): T | undefined {
|
|
480
|
+
for (const item of iter) return item
|
|
481
|
+
return undefined
|
|
482
|
+
}
|
|
483
|
+
|
|
471
484
|
export function _minOrUndefined<T>(array: readonly T[]): NonNullable<T> | undefined {
|
|
472
485
|
let min: NonNullable<T> | undefined
|
|
473
486
|
for (const item of array) {
|
package/src/is.util.ts
CHANGED
|
@@ -45,11 +45,19 @@ export function _isPrimitive(v: any): v is Primitive {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
export function _isEmptyObject(obj: AnyObject): boolean {
|
|
48
|
-
return Object.keys
|
|
48
|
+
// for...in with early return avoids allocating the full Object.keys array.
|
|
49
|
+
// Object.hasOwn matches Object.keys() semantics (own enumerable keys only).
|
|
50
|
+
for (const k in obj) {
|
|
51
|
+
if (Object.hasOwn(obj, k)) return false
|
|
52
|
+
}
|
|
53
|
+
return true
|
|
49
54
|
}
|
|
50
55
|
|
|
51
56
|
export function _isNotEmptyObject(obj: AnyObject): boolean {
|
|
52
|
-
|
|
57
|
+
for (const k in obj) {
|
|
58
|
+
if (Object.hasOwn(obj, k)) return true
|
|
59
|
+
}
|
|
60
|
+
return false
|
|
53
61
|
}
|
|
54
62
|
|
|
55
63
|
/**
|
|
@@ -74,7 +82,10 @@ export function _isEmpty(obj: any): boolean {
|
|
|
74
82
|
}
|
|
75
83
|
|
|
76
84
|
if (typeof obj === 'object') {
|
|
77
|
-
|
|
85
|
+
for (const k in obj) {
|
|
86
|
+
if (Object.hasOwn(obj, k)) return false
|
|
87
|
+
}
|
|
88
|
+
return true
|
|
78
89
|
}
|
|
79
90
|
|
|
80
91
|
return false
|
|
@@ -242,6 +242,47 @@ export function _findKeyByValue<T extends AnyObject>(obj: T, v: ValueOf<T>): key
|
|
|
242
242
|
return Object.entries(obj).find(([_, value]) => value === v)?.[0] as keyof T
|
|
243
243
|
}
|
|
244
244
|
|
|
245
|
+
/**
|
|
246
|
+
* Returns the first key of the object, or `undefined` if the object is empty.
|
|
247
|
+
*
|
|
248
|
+
* Performance-optimised: uses `for...in` with an early return to avoid
|
|
249
|
+
* allocating the full `Object.keys(obj)` array. The `Object.hasOwn` filter
|
|
250
|
+
* matches `Object.keys()` semantics (own enumerable string keys only) and
|
|
251
|
+
* satisfies the `guard-for-in` lint rule; cost is a single check before
|
|
252
|
+
* the early return. Iteration order matches `Object.keys()` for plain
|
|
253
|
+
* objects (integer-like keys ascending first, then string keys in
|
|
254
|
+
* insertion order).
|
|
255
|
+
*/
|
|
256
|
+
export function _firstKey<T extends AnyObject>(obj: T): keyof T | undefined {
|
|
257
|
+
for (const k in obj) {
|
|
258
|
+
if (Object.hasOwn(obj, k)) return k as keyof T
|
|
259
|
+
}
|
|
260
|
+
return undefined
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Returns the first value of the object, or `undefined` if the object is empty.
|
|
265
|
+
* See `_firstKey` for the iteration-order contract.
|
|
266
|
+
*/
|
|
267
|
+
export function _firstValue<T extends AnyObject>(obj: T): ValueOf<T> | undefined {
|
|
268
|
+
for (const k in obj) {
|
|
269
|
+
if (Object.hasOwn(obj, k)) return obj[k] as ValueOf<T>
|
|
270
|
+
}
|
|
271
|
+
return undefined
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Returns the first [key, value] tuple of the object,
|
|
276
|
+
* or `undefined` if the object is empty.
|
|
277
|
+
* See `_firstKey` for the iteration-order contract.
|
|
278
|
+
*/
|
|
279
|
+
export function _firstEntry<T extends AnyObject>(obj: T): [keyof T, ValueOf<T>] | undefined {
|
|
280
|
+
for (const k in obj) {
|
|
281
|
+
if (Object.hasOwn(obj, k)) return [k as keyof T, obj[k] as ValueOf<T>]
|
|
282
|
+
}
|
|
283
|
+
return undefined
|
|
284
|
+
}
|
|
285
|
+
|
|
245
286
|
export function _objectNullValuesToUndefined<T extends AnyObject>(
|
|
246
287
|
obj: T,
|
|
247
288
|
opt: MutateOptions = {},
|