@naturalcycles/js-lib 15.75.0 → 15.76.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.
- package/dist/array/array.util.d.ts +14 -0
- package/dist/array/array.util.js +22 -0
- package/dist/is.util.js +17 -3
- package/dist/object/object.util.d.ts +40 -0
- package/dist/object/object.util.js +76 -0
- package/package.json +2 -2
- package/src/array/array.util.ts +22 -0
- package/src/is.util.ts +14 -3
- package/src/object/object.util.ts +78 -0
|
@@ -217,6 +217,20 @@ 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 a non-empty iterable (Set, Map.values(), generator, etc.).
|
|
222
|
+
* Throws 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;
|
|
229
|
+
/**
|
|
230
|
+
* Returns the first item of an iterable (or undefined if the iterable is empty).
|
|
231
|
+
* See `_firstFromIterable` for the iteration semantics.
|
|
232
|
+
*/
|
|
233
|
+
export declare function _firstOrUndefinedFromIterable<T>(iter: Iterable<T>): T | undefined;
|
|
220
234
|
export declare function _minOrUndefined<T>(array: readonly T[]): NonNullable<T> | undefined;
|
|
221
235
|
/**
|
|
222
236
|
* Filters out nullish values (undefined and null).
|
package/dist/array/array.util.js
CHANGED
|
@@ -403,6 +403,28 @@ export function _first(array) {
|
|
|
403
403
|
export function _firstOrUndefined(array) {
|
|
404
404
|
return array[0];
|
|
405
405
|
}
|
|
406
|
+
/**
|
|
407
|
+
* Returns the first item of a non-empty iterable (Set, Map.values(), generator, etc.).
|
|
408
|
+
* Throws 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
|
+
throw new Error('_firstFromIterable called on empty iterable');
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Returns the first item of an iterable (or undefined if the iterable is empty).
|
|
421
|
+
* See `_firstFromIterable` for the iteration semantics.
|
|
422
|
+
*/
|
|
423
|
+
export function _firstOrUndefinedFromIterable(iter) {
|
|
424
|
+
for (const item of iter)
|
|
425
|
+
return item;
|
|
426
|
+
return undefined;
|
|
427
|
+
}
|
|
406
428
|
export function _minOrUndefined(array) {
|
|
407
429
|
let min;
|
|
408
430
|
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,46 @@ 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 a non-empty object.
|
|
92
|
+
* Throws if the object is empty.
|
|
93
|
+
*
|
|
94
|
+
* Performance-optimised: uses `for...in` with an early return to avoid
|
|
95
|
+
* allocating the full `Object.keys(obj)` array. The `Object.hasOwn` filter
|
|
96
|
+
* matches `Object.keys()` semantics (own enumerable string keys only) and
|
|
97
|
+
* satisfies the `guard-for-in` lint rule; cost is a single check before
|
|
98
|
+
* the early return. Iteration order matches `Object.keys()` for plain
|
|
99
|
+
* objects (integer-like keys ascending first, then string keys in
|
|
100
|
+
* insertion order).
|
|
101
|
+
*/
|
|
102
|
+
export declare function _firstKey<T extends AnyObject>(obj: T): keyof T;
|
|
103
|
+
/**
|
|
104
|
+
* Returns the first key of the object (or undefined if the object is empty).
|
|
105
|
+
* See `_firstKey` for the iteration-order contract.
|
|
106
|
+
*/
|
|
107
|
+
export declare function _firstKeyOrUndefined<T extends AnyObject>(obj: T): keyof T | undefined;
|
|
108
|
+
/**
|
|
109
|
+
* Returns the first value of a non-empty object.
|
|
110
|
+
* Throws if the object is empty.
|
|
111
|
+
* See `_firstKey` for the iteration-order contract.
|
|
112
|
+
*/
|
|
113
|
+
export declare function _firstValue<T extends AnyObject>(obj: T): ValueOf<T>;
|
|
114
|
+
/**
|
|
115
|
+
* Returns the first value of the object (or undefined if the object is empty).
|
|
116
|
+
* See `_firstKey` for the iteration-order contract.
|
|
117
|
+
*/
|
|
118
|
+
export declare function _firstValueOrUndefined<T extends AnyObject>(obj: T): ValueOf<T> | undefined;
|
|
119
|
+
/**
|
|
120
|
+
* Returns the first [key, value] tuple of a non-empty object.
|
|
121
|
+
* Throws if the object is empty.
|
|
122
|
+
* See `_firstKey` for the iteration-order contract.
|
|
123
|
+
*/
|
|
124
|
+
export declare function _firstEntry<T extends AnyObject>(obj: T): [keyof T, ValueOf<T>];
|
|
125
|
+
/**
|
|
126
|
+
* Returns the first [key, value] tuple of the object (or undefined if the object is empty).
|
|
127
|
+
* See `_firstKey` for the iteration-order contract.
|
|
128
|
+
*/
|
|
129
|
+
export declare function _firstEntryOrUndefined<T extends AnyObject>(obj: T): [keyof T, ValueOf<T>] | undefined;
|
|
90
130
|
export declare function _objectNullValuesToUndefined<T extends AnyObject>(obj: T, opt?: MutateOptions): T;
|
|
91
131
|
/**
|
|
92
132
|
* Deep copy object (by json parse/stringify, since it has unbeatable performance+simplicity combo).
|
|
@@ -191,6 +191,82 @@ 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 a non-empty object.
|
|
196
|
+
* Throws if the object is empty.
|
|
197
|
+
*
|
|
198
|
+
* Performance-optimised: uses `for...in` with an early return to avoid
|
|
199
|
+
* allocating the full `Object.keys(obj)` array. The `Object.hasOwn` filter
|
|
200
|
+
* matches `Object.keys()` semantics (own enumerable string keys only) and
|
|
201
|
+
* satisfies the `guard-for-in` lint rule; cost is a single check before
|
|
202
|
+
* the early return. Iteration order matches `Object.keys()` for plain
|
|
203
|
+
* objects (integer-like keys ascending first, then string keys in
|
|
204
|
+
* insertion order).
|
|
205
|
+
*/
|
|
206
|
+
export function _firstKey(obj) {
|
|
207
|
+
for (const k in obj) {
|
|
208
|
+
if (Object.hasOwn(obj, k))
|
|
209
|
+
return k;
|
|
210
|
+
}
|
|
211
|
+
throw new Error('_firstKey called on empty object');
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Returns the first key of the object (or undefined if the object is empty).
|
|
215
|
+
* See `_firstKey` for the iteration-order contract.
|
|
216
|
+
*/
|
|
217
|
+
export function _firstKeyOrUndefined(obj) {
|
|
218
|
+
for (const k in obj) {
|
|
219
|
+
if (Object.hasOwn(obj, k))
|
|
220
|
+
return k;
|
|
221
|
+
}
|
|
222
|
+
return undefined;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Returns the first value of a non-empty object.
|
|
226
|
+
* Throws if the object is empty.
|
|
227
|
+
* See `_firstKey` for the iteration-order contract.
|
|
228
|
+
*/
|
|
229
|
+
export function _firstValue(obj) {
|
|
230
|
+
for (const k in obj) {
|
|
231
|
+
if (Object.hasOwn(obj, k))
|
|
232
|
+
return obj[k];
|
|
233
|
+
}
|
|
234
|
+
throw new Error('_firstValue called on empty object');
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Returns the first value of the object (or undefined if the object is empty).
|
|
238
|
+
* See `_firstKey` for the iteration-order contract.
|
|
239
|
+
*/
|
|
240
|
+
export function _firstValueOrUndefined(obj) {
|
|
241
|
+
for (const k in obj) {
|
|
242
|
+
if (Object.hasOwn(obj, k))
|
|
243
|
+
return obj[k];
|
|
244
|
+
}
|
|
245
|
+
return undefined;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Returns the first [key, value] tuple of a non-empty object.
|
|
249
|
+
* Throws if the object is empty.
|
|
250
|
+
* See `_firstKey` for the iteration-order contract.
|
|
251
|
+
*/
|
|
252
|
+
export function _firstEntry(obj) {
|
|
253
|
+
for (const k in obj) {
|
|
254
|
+
if (Object.hasOwn(obj, k))
|
|
255
|
+
return [k, obj[k]];
|
|
256
|
+
}
|
|
257
|
+
throw new Error('_firstEntry called on empty object');
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Returns the first [key, value] tuple of the object (or undefined if the object is empty).
|
|
261
|
+
* See `_firstKey` for the iteration-order contract.
|
|
262
|
+
*/
|
|
263
|
+
export function _firstEntryOrUndefined(obj) {
|
|
264
|
+
for (const k in obj) {
|
|
265
|
+
if (Object.hasOwn(obj, k))
|
|
266
|
+
return [k, obj[k]];
|
|
267
|
+
}
|
|
268
|
+
return undefined;
|
|
269
|
+
}
|
|
194
270
|
export function _objectNullValuesToUndefined(obj, opt = {}) {
|
|
195
271
|
return _mapValues(obj, (_k, v) => (v === null ? undefined : v), opt);
|
|
196
272
|
}
|
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.1",
|
|
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,28 @@ 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 a non-empty iterable (Set, Map.values(), generator, etc.).
|
|
473
|
+
* Throws 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 {
|
|
480
|
+
for (const item of iter) return item
|
|
481
|
+
throw new Error('_firstFromIterable called on empty iterable')
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* Returns the first item of an iterable (or undefined if the iterable is empty).
|
|
486
|
+
* See `_firstFromIterable` for the iteration semantics.
|
|
487
|
+
*/
|
|
488
|
+
export function _firstOrUndefinedFromIterable<T>(iter: Iterable<T>): T | undefined {
|
|
489
|
+
for (const item of iter) return item
|
|
490
|
+
return undefined
|
|
491
|
+
}
|
|
492
|
+
|
|
471
493
|
export function _minOrUndefined<T>(array: readonly T[]): NonNullable<T> | undefined {
|
|
472
494
|
let min: NonNullable<T> | undefined
|
|
473
495
|
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,84 @@ 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 a non-empty object.
|
|
247
|
+
* Throws if the object is empty.
|
|
248
|
+
*
|
|
249
|
+
* Performance-optimised: uses `for...in` with an early return to avoid
|
|
250
|
+
* allocating the full `Object.keys(obj)` array. The `Object.hasOwn` filter
|
|
251
|
+
* matches `Object.keys()` semantics (own enumerable string keys only) and
|
|
252
|
+
* satisfies the `guard-for-in` lint rule; cost is a single check before
|
|
253
|
+
* the early return. Iteration order matches `Object.keys()` for plain
|
|
254
|
+
* objects (integer-like keys ascending first, then string keys in
|
|
255
|
+
* insertion order).
|
|
256
|
+
*/
|
|
257
|
+
export function _firstKey<T extends AnyObject>(obj: T): keyof T {
|
|
258
|
+
for (const k in obj) {
|
|
259
|
+
if (Object.hasOwn(obj, k)) return k as keyof T
|
|
260
|
+
}
|
|
261
|
+
throw new Error('_firstKey called on empty object')
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Returns the first key of the object (or undefined if the object is empty).
|
|
266
|
+
* See `_firstKey` for the iteration-order contract.
|
|
267
|
+
*/
|
|
268
|
+
export function _firstKeyOrUndefined<T extends AnyObject>(obj: T): keyof T | undefined {
|
|
269
|
+
for (const k in obj) {
|
|
270
|
+
if (Object.hasOwn(obj, k)) return k as keyof T
|
|
271
|
+
}
|
|
272
|
+
return undefined
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Returns the first value of a non-empty object.
|
|
277
|
+
* Throws if the object is empty.
|
|
278
|
+
* See `_firstKey` for the iteration-order contract.
|
|
279
|
+
*/
|
|
280
|
+
export function _firstValue<T extends AnyObject>(obj: T): ValueOf<T> {
|
|
281
|
+
for (const k in obj) {
|
|
282
|
+
if (Object.hasOwn(obj, k)) return obj[k] as ValueOf<T>
|
|
283
|
+
}
|
|
284
|
+
throw new Error('_firstValue called on empty object')
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Returns the first value of the object (or undefined if the object is empty).
|
|
289
|
+
* See `_firstKey` for the iteration-order contract.
|
|
290
|
+
*/
|
|
291
|
+
export function _firstValueOrUndefined<T extends AnyObject>(obj: T): ValueOf<T> | undefined {
|
|
292
|
+
for (const k in obj) {
|
|
293
|
+
if (Object.hasOwn(obj, k)) return obj[k] as ValueOf<T>
|
|
294
|
+
}
|
|
295
|
+
return undefined
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Returns the first [key, value] tuple of a non-empty object.
|
|
300
|
+
* Throws if the object is empty.
|
|
301
|
+
* See `_firstKey` for the iteration-order contract.
|
|
302
|
+
*/
|
|
303
|
+
export function _firstEntry<T extends AnyObject>(obj: T): [keyof T, ValueOf<T>] {
|
|
304
|
+
for (const k in obj) {
|
|
305
|
+
if (Object.hasOwn(obj, k)) return [k as keyof T, obj[k] as ValueOf<T>]
|
|
306
|
+
}
|
|
307
|
+
throw new Error('_firstEntry called on empty object')
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Returns the first [key, value] tuple of the object (or undefined if the object is empty).
|
|
312
|
+
* See `_firstKey` for the iteration-order contract.
|
|
313
|
+
*/
|
|
314
|
+
export function _firstEntryOrUndefined<T extends AnyObject>(
|
|
315
|
+
obj: T,
|
|
316
|
+
): [keyof T, ValueOf<T>] | undefined {
|
|
317
|
+
for (const k in obj) {
|
|
318
|
+
if (Object.hasOwn(obj, k)) return [k as keyof T, obj[k] as ValueOf<T>]
|
|
319
|
+
}
|
|
320
|
+
return undefined
|
|
321
|
+
}
|
|
322
|
+
|
|
245
323
|
export function _objectNullValuesToUndefined<T extends AnyObject>(
|
|
246
324
|
obj: T,
|
|
247
325
|
opt: MutateOptions = {},
|