@naturalcycles/js-lib 15.49.0 → 15.50.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.
@@ -197,6 +197,10 @@ export declare function _lastOrUndefined<T>(array: readonly T[]): T | undefined;
197
197
  * Throws if array is empty.
198
198
  */
199
199
  export declare function _first<T>(array: readonly T[]): T;
200
+ /**
201
+ * Returns first item of the array (or undefined if array is empty).
202
+ */
203
+ export declare function _firstOrUndefined<T>(array: readonly T[]): T | undefined;
200
204
  export declare function _minOrUndefined<T>(array: readonly T[]): NonNullable<T> | undefined;
201
205
  /**
202
206
  * Filters out nullish values (undefined and null).
@@ -209,6 +213,10 @@ export declare function _maxOrUndefined<T>(array: readonly T[]): NonNullable<T>
209
213
  export declare function _max<T>(array: readonly T[]): NonNullable<T>;
210
214
  export declare function _maxBy<T>(array: readonly T[], mapper: Mapper<T, number | string | undefined>): T;
211
215
  export declare function _minBy<T>(array: readonly T[], mapper: Mapper<T, number | string | undefined>): T;
216
+ export declare function _minMax<T>(array: readonly T[]): [min: NonNullable<T>, max: NonNullable<T>];
217
+ export declare function _minMaxOrUndefined<T>(array: readonly T[]): [min: NonNullable<T>, max: NonNullable<T>] | undefined;
218
+ export declare function _minMaxBy<T>(array: readonly T[], mapper: Mapper<T, number | string | undefined>): [min: NonNullable<T>, max: NonNullable<T>];
219
+ export declare function _minMaxByOrUndefined<T>(array: readonly T[], mapper: Mapper<T, number | string | undefined>): [min: NonNullable<T>, max: NonNullable<T>] | undefined;
212
220
  export declare function _maxByOrUndefined<T>(array: readonly T[], mapper: Mapper<T, number | string | undefined>): T | undefined;
213
221
  export declare function _minByOrUndefined<T>(array: readonly T[], mapper: Mapper<T, number | string | undefined>): T | undefined;
214
222
  export declare function _zip<T1, T2>(array1: readonly T1[], array2: readonly T2[]): [T1, T2][];
@@ -363,6 +363,12 @@ export function _first(array) {
363
363
  throw new Error('_first called on empty array');
364
364
  return array[0];
365
365
  }
366
+ /**
367
+ * Returns first item of the array (or undefined if array is empty).
368
+ */
369
+ export function _firstOrUndefined(array) {
370
+ return array[0];
371
+ }
366
372
  export function _minOrUndefined(array) {
367
373
  let min;
368
374
  for (const item of array) {
@@ -411,6 +417,75 @@ export function _minBy(array, mapper) {
411
417
  _assert(min !== undefined, '_minBy returned undefined');
412
418
  return min;
413
419
  }
420
+ export function _minMax(array) {
421
+ if (!array.length)
422
+ throw new Error('_minMax called on empty array');
423
+ const result = _minMaxOrUndefined(array);
424
+ _assert(result !== undefined, '_minBy returned undefined');
425
+ return result;
426
+ }
427
+ export function _minMaxOrUndefined(array) {
428
+ if (!array.length)
429
+ return;
430
+ let min;
431
+ let max;
432
+ for (let item of array) {
433
+ if (item === undefined || item === null)
434
+ continue;
435
+ if (min === undefined)
436
+ min = item;
437
+ if (max === undefined)
438
+ max = item;
439
+ if (item < min)
440
+ min = item;
441
+ if (item > max)
442
+ max = item;
443
+ }
444
+ if (min === undefined || max === undefined || min === null || max === null)
445
+ return;
446
+ return [min, max];
447
+ }
448
+ export function _minMaxBy(array, mapper) {
449
+ if (!array.length)
450
+ throw new Error('_minMaxBy called on empty array');
451
+ const result = _minMaxByOrUndefined(array, mapper);
452
+ _assert(result !== undefined, '_minMaxBy returned undefined');
453
+ return result;
454
+ }
455
+ export function _minMaxByOrUndefined(array, mapper) {
456
+ if (!array.length)
457
+ return;
458
+ let min;
459
+ let minItem;
460
+ let max;
461
+ let maxItem;
462
+ for (let item of array) {
463
+ if (item === undefined || item === null)
464
+ continue;
465
+ const value = mapper(item);
466
+ if (!value)
467
+ continue;
468
+ if (min === undefined) {
469
+ min = value;
470
+ minItem = item;
471
+ }
472
+ if (max === undefined) {
473
+ max = value;
474
+ maxItem = item;
475
+ }
476
+ if (value < min) {
477
+ min = value;
478
+ minItem = item;
479
+ }
480
+ if (value > max) {
481
+ max = value;
482
+ maxItem = item;
483
+ }
484
+ }
485
+ if (minItem === undefined || maxItem === undefined || minItem === null || maxItem === null)
486
+ return;
487
+ return [minItem, maxItem];
488
+ }
414
489
  // todo: looks like it _maxByOrUndefined/_minByOrUndefined can be DRYer
415
490
  export function _maxByOrUndefined(array, mapper) {
416
491
  if (!array.length)
package/dist/types.d.ts CHANGED
@@ -288,23 +288,17 @@ export declare const _stringMapValues: <T>(map: StringMap<T>) => T[];
288
288
  */
289
289
  export declare const _stringMapEntries: <T>(map: StringMap<T>) => [k: string, v: T][];
290
290
  /**
291
- * Resolves to a string literal union of the keys of T, meaning they are
292
- * always keys of T and always strings (never numbers or symbols).
293
- */
294
- export type ObjectKey<T> = `${Extract<keyof T, string | number>}`;
295
- /**
296
- * Alias of `Object.keys`, but returns keys with a string type that's as
297
- * narrow as possible.
291
+ * Alias of `Object.keys`, but returns keys typed as `keyof T`, not as just `string`.
298
292
  * This is how TypeScript should work, actually.
299
293
  */
300
- export declare const _objectKeys: <T extends AnyObject>(obj: T) => ObjectKey<T>[];
294
+ export declare const _objectKeys: <T extends AnyObject>(obj: T) => (keyof T)[];
301
295
  /**
302
296
  * Alias of `Object.entries`, but returns better-typed output.
303
297
  *
304
298
  * So e.g you can use _objectEntries(obj).map([k, v] => {})
305
299
  * and `k` will be `keyof obj` instead of generic `string`.
306
300
  */
307
- export declare const _objectEntries: <T extends AnyObject>(obj: T) => [k: ObjectKey<T>, v: T[ObjectKey<T>]][];
301
+ export declare const _objectEntries: <T extends AnyObject>(obj: T) => [k: keyof T, v: T[keyof T]][];
308
302
  export type NullishValue = null | undefined;
309
303
  export type FalsyValue = false | '' | 0 | null | undefined;
310
304
  /**
package/dist/types.js CHANGED
@@ -31,8 +31,7 @@ export const _stringMapValues = Object.values;
31
31
  */
32
32
  export const _stringMapEntries = Object.entries;
33
33
  /**
34
- * Alias of `Object.keys`, but returns keys with a string type that's as
35
- * narrow as possible.
34
+ * Alias of `Object.keys`, but returns keys typed as `keyof T`, not as just `string`.
36
35
  * This is how TypeScript should work, actually.
37
36
  */
38
37
  export const _objectKeys = Object.keys;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@naturalcycles/js-lib",
3
3
  "type": "module",
4
- "version": "15.49.0",
4
+ "version": "15.50.0",
5
5
  "dependencies": {
6
6
  "tslib": "^2",
7
7
  "undici": "^7",
@@ -424,6 +424,13 @@ export function _first<T>(array: readonly T[]): T {
424
424
  return array[0]!
425
425
  }
426
426
 
427
+ /**
428
+ * Returns first item of the array (or undefined if array is empty).
429
+ */
430
+ export function _firstOrUndefined<T>(array: readonly T[]): T | undefined {
431
+ return array[0]
432
+ }
433
+
427
434
  export function _minOrUndefined<T>(array: readonly T[]): NonNullable<T> | undefined {
428
435
  let min: NonNullable<T> | undefined
429
436
  for (const item of array) {
@@ -476,6 +483,87 @@ export function _minBy<T>(array: readonly T[], mapper: Mapper<T, number | string
476
483
  return min
477
484
  }
478
485
 
486
+ export function _minMax<T>(array: readonly T[]): [min: NonNullable<T>, max: NonNullable<T>] {
487
+ if (!array.length) throw new Error('_minMax called on empty array')
488
+ const result = _minMaxOrUndefined(array)
489
+ _assert(result !== undefined, '_minBy returned undefined')
490
+ return result
491
+ }
492
+
493
+ export function _minMaxOrUndefined<T>(
494
+ array: readonly T[],
495
+ ): [min: NonNullable<T>, max: NonNullable<T>] | undefined {
496
+ if (!array.length) return
497
+
498
+ let min: T | undefined
499
+ let max: T | undefined
500
+
501
+ for (let item of array) {
502
+ if (item === undefined || item === null) continue
503
+ if (min === undefined) min = item
504
+ if (max === undefined) max = item
505
+ if (item < min) min = item
506
+ if (item > max) max = item
507
+ }
508
+
509
+ if (min === undefined || max === undefined || min === null || max === null) return
510
+
511
+ return [min, max]
512
+ }
513
+
514
+ export function _minMaxBy<T>(
515
+ array: readonly T[],
516
+ mapper: Mapper<T, number | string | undefined>,
517
+ ): [min: NonNullable<T>, max: NonNullable<T>] {
518
+ if (!array.length) throw new Error('_minMaxBy called on empty array')
519
+ const result = _minMaxByOrUndefined(array, mapper)
520
+ _assert(result !== undefined, '_minMaxBy returned undefined')
521
+ return result
522
+ }
523
+
524
+ export function _minMaxByOrUndefined<T>(
525
+ array: readonly T[],
526
+ mapper: Mapper<T, number | string | undefined>,
527
+ ): [min: NonNullable<T>, max: NonNullable<T>] | undefined {
528
+ if (!array.length) return
529
+
530
+ let min: ReturnType<typeof mapper> | undefined
531
+ let minItem: T | undefined
532
+ let max: ReturnType<typeof mapper> | undefined
533
+ let maxItem: T | undefined
534
+
535
+ for (let item of array) {
536
+ if (item === undefined || item === null) continue
537
+
538
+ const value = mapper(item)
539
+ if (!value) continue
540
+
541
+ if (min === undefined) {
542
+ min = value
543
+ minItem = item
544
+ }
545
+
546
+ if (max === undefined) {
547
+ max = value
548
+ maxItem = item
549
+ }
550
+
551
+ if (value < min) {
552
+ min = value
553
+ minItem = item
554
+ }
555
+
556
+ if (value > max) {
557
+ max = value
558
+ maxItem = item
559
+ }
560
+ }
561
+
562
+ if (minItem === undefined || maxItem === undefined || minItem === null || maxItem === null) return
563
+
564
+ return [minItem, maxItem]
565
+ }
566
+
479
567
  // todo: looks like it _maxByOrUndefined/_minByOrUndefined can be DRYer
480
568
 
481
569
  export function _maxByOrUndefined<T>(
@@ -14,7 +14,8 @@ import type {
14
14
  import type { HttpMethod, HttpStatusFamily } from './http.model.js'
15
15
 
16
16
  export interface FetcherNormalizedCfg
17
- extends Required<Omit<FetcherCfg, 'dispatcher'>>,
17
+ extends
18
+ Required<Omit<FetcherCfg, 'dispatcher'>>,
18
19
  Omit<
19
20
  FetcherRequest,
20
21
  | 'started'
@@ -148,8 +149,10 @@ export interface FetcherRetryOptions {
148
149
  timeoutMultiplier: number
149
150
  }
150
151
 
151
- export interface FetcherRequest
152
- extends Omit<FetcherOptions, 'method' | 'headers' | 'baseUrl' | 'url'> {
152
+ export interface FetcherRequest extends Omit<
153
+ FetcherOptions,
154
+ 'method' | 'headers' | 'baseUrl' | 'url'
155
+ > {
153
156
  /**
154
157
  * inputUrl is only the part that was passed in the request,
155
158
  * without baseUrl or searchParams.
package/src/types.ts CHANGED
@@ -361,17 +361,10 @@ export const _stringMapValues = Object.values as <T>(map: StringMap<T>) => T[]
361
361
  export const _stringMapEntries = Object.entries as <T>(map: StringMap<T>) => [k: string, v: T][]
362
362
 
363
363
  /**
364
- * Resolves to a string literal union of the keys of T, meaning they are
365
- * always keys of T and always strings (never numbers or symbols).
366
- */
367
- export type ObjectKey<T> = `${Extract<keyof T, string | number>}`
368
-
369
- /**
370
- * Alias of `Object.keys`, but returns keys with a string type that's as
371
- * narrow as possible.
364
+ * Alias of `Object.keys`, but returns keys typed as `keyof T`, not as just `string`.
372
365
  * This is how TypeScript should work, actually.
373
366
  */
374
- export const _objectKeys = Object.keys as <T extends AnyObject>(obj: T) => ObjectKey<T>[]
367
+ export const _objectKeys = Object.keys as <T extends AnyObject>(obj: T) => (keyof T)[]
375
368
 
376
369
  /**
377
370
  * Alias of `Object.entries`, but returns better-typed output.
@@ -381,7 +374,7 @@ export const _objectKeys = Object.keys as <T extends AnyObject>(obj: T) => Objec
381
374
  */
382
375
  export const _objectEntries = Object.entries as <T extends AnyObject>(
383
376
  obj: T,
384
- ) => [k: ObjectKey<T>, v: T[ObjectKey<T>]][]
377
+ ) => [k: keyof T, v: T[keyof T]][]
385
378
 
386
379
  export type NullishValue = null | undefined
387
380
  export type FalsyValue = false | '' | 0 | null | undefined
@@ -499,8 +492,10 @@ export type ReadonlyDeep<T> = T extends Primitive | ((...args: any[]) => unknown
499
492
  /**
500
493
  Same as `ReadonlyDeep`, but accepts only `ReadonlyMap`s as inputs. Internal helper for `ReadonlyDeep`.
501
494
  */
502
- interface ReadonlyMapDeep<KeyType, ValueType>
503
- extends ReadonlyMap<ReadonlyDeep<KeyType>, ReadonlyDeep<ValueType>> {}
495
+ interface ReadonlyMapDeep<KeyType, ValueType> extends ReadonlyMap<
496
+ ReadonlyDeep<KeyType>,
497
+ ReadonlyDeep<ValueType>
498
+ > {}
504
499
 
505
500
  /**
506
501
  Same as `ReadonlyDeep`, but accepts only `ReadonlySet`s as inputs. Internal helper for `ReadonlyDeep`.