pepka 1.6.22 → 1.7.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/bundle.cjs CHANGED
@@ -57,7 +57,16 @@ function curry2(fn) {
57
57
  }
58
58
  return curried2;
59
59
  }
60
- const curry3 = (fn) => curry(fn);
60
+ function curry3(fn) {
61
+ // type p0 = Parameters<Func>[0]
62
+ // type p1 = Parameters<Func>[1]
63
+ // type p2 = Parameters<Func>[2]
64
+ // type ReturnT = ReturnType<Func>
65
+ // TODO: optimize.
66
+ // Cannot use ts-toolbelt due to this error:
67
+ // Excessive stack depth comparing types 'GapsOf<?, L2>' and 'GapsOf<?, L2>'
68
+ return curry(fn);
69
+ }
61
70
 
62
71
  const length = (s) => s.length;
63
72
  const typed_arr_re = /^(.*?)(8|16|32|64)(Clamped)?Array$/;
@@ -127,9 +136,9 @@ const includes = curry2((s, ss) => {
127
136
  }
128
137
  });
129
138
 
130
- /* Then next fns seem to be excess due to their safe ver performance should be the same or better:
131
- * qflat, qpick, qslice, quniq, qflat, qflatShallow, qreduceAsync
132
- */
139
+ const { min } = Math;
140
+ const z = 0;
141
+ /* qflat, qflatShallow, qreduceAsync */
133
142
  const qappend = curry2((s, xs) => { xs.push(s); return xs; });
134
143
  const qassoc = curry3((prop, v, obj) => { obj[prop] = v; return obj; });
135
144
  const qreduce = curry3((fn, accum, arr) => arr.reduce(fn, accum));
@@ -245,6 +254,55 @@ const qomit = curry2((props, o) => qfilter((_, k) => !includes(k, props), o));
245
254
  /** @param prop string @param pipe (data[prop]): prop_value @param data any
246
255
  * @returns data with prop over pipe. */
247
256
  const qoverProp = curry3((prop, pipe, data) => qassoc(prop, pipe(data[prop]), data));
257
+ /** Slower than pick() (dictionary mode) !
258
+ * @param props (string|number)[]
259
+ * @param o AnyObject
260
+ * @returns AnyObject
261
+ */
262
+ const qpick = curry2((props, o) => {
263
+ for (const p in o)
264
+ if (!props.includes(p))
265
+ delete o[p];
266
+ return o;
267
+ });
268
+ const qslice = curry3((from, to, xs) => {
269
+ const right = (isNum(to) ? to : inf);
270
+ const window_width = min(right, length(xs)) - from;
271
+ if (isArray(xs)) {
272
+ xs = xs;
273
+ if (from > z)
274
+ for (let i = z; i < window_width; i++)
275
+ xs[i] = xs[from + i];
276
+ xs.length = window_width;
277
+ return xs;
278
+ }
279
+ else
280
+ return xs.slice(from, right); // strings are immutable.
281
+ });
282
+ /** Should be faster than .splice() 'cause does not make a new array. */
283
+ const rmel = (index, xs) => {
284
+ const len = length(xs);
285
+ for (let i = index; i < len; i++)
286
+ xs[i] = xs[i + 1];
287
+ xs.length = len - 1;
288
+ return xs;
289
+ };
290
+ const seen = new Set();
291
+ const quniq = (xs) => {
292
+ seen.clear();
293
+ let size = length(xs);
294
+ for (let i = z; i < size; i++) {
295
+ const x = xs[i];
296
+ if (seen.has(x)) {
297
+ rmel(i, xs);
298
+ size--;
299
+ i--;
300
+ }
301
+ else
302
+ seen.add(x);
303
+ }
304
+ return xs;
305
+ };
248
306
  // Aliases.
249
307
  const qpush = qappend;
250
308
 
@@ -371,7 +429,12 @@ const diff = curry2((_xs1, _xs2) => {
371
429
  }
372
430
  return out;
373
431
  });
374
- const genBy = curry2((generator, length) => [...Array(length)].map((_, i) => generator(i)));
432
+ const genBy = curry2((generator, length) => {
433
+ const a = new Array(length);
434
+ for (let i = 0; i < length; i++)
435
+ a[i] = generator(i);
436
+ return a;
437
+ });
375
438
  const once = (fn) => {
376
439
  let done = false, cache;
377
440
  return function (...args) {
@@ -462,6 +525,11 @@ const freezeShallow = (o) => qfreezeShallow(clone(o));
462
525
  * @param array T2[]
463
526
  */
464
527
  const reduce = curry3((reducer, accum, arr) => qreduce(reducer, clone(accum), arr));
528
+ /**
529
+ * @param props (string|number)[]
530
+ * @param o AnyObject
531
+ * @returns AnyObject
532
+ */
465
533
  const pick = curry2((props, o) => {
466
534
  const out = {};
467
535
  for (const p of props)
@@ -545,6 +613,7 @@ const notf = complement;
545
613
  const push = append;
546
614
  const some = any;
547
615
  const weakEq = eq;
616
+ const uniqBy = uniqWith;
548
617
 
549
618
  /** One promise waits for another. */
550
619
  const forEachSerial = (() => {
@@ -766,11 +835,14 @@ exports.qmergeDeepX = qmergeDeepX;
766
835
  exports.qmergeShallow = qmergeShallow;
767
836
  exports.qomit = qomit;
768
837
  exports.qoverProp = qoverProp;
838
+ exports.qpick = qpick;
769
839
  exports.qprepend = qprepend;
770
840
  exports.qpush = qpush;
771
841
  exports.qreduce = qreduce;
772
842
  exports.qreverse = qreverse;
843
+ exports.qslice = qslice;
773
844
  exports.qsort = qsort;
845
+ exports.quniq = quniq;
774
846
  exports.range = range;
775
847
  exports.reduce = reduce;
776
848
  exports.reflect = reflect;
@@ -798,6 +870,7 @@ exports.type = type;
798
870
  exports.typeIs = typeIs;
799
871
  exports.uncurry = uncurry;
800
872
  exports.uniq = uniq;
873
+ exports.uniqBy = uniqBy;
801
874
  exports.uniqWith = uniqWith;
802
875
  exports.values = values;
803
876
  exports.wait = wait;
package/dist/bundle.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  // Generated by dts-bundle-generator v9.5.1
2
2
 
3
3
  type AnyArgs = any[];
4
- type AnyArray<T = any> = T[] | readonly T[];
4
+ type AnyArray<T = any> = T[] | readonly T[] | (ArrayBufferView & {
5
+ length: number;
6
+ });
5
7
  type Split<S extends string> = S extends `${infer U}${infer V}` ? [
6
8
  U,
7
9
  ...Split<V>
@@ -30,12 +32,6 @@ export type PathValue<O, Keys extends readonly PropertyKey[], Default> = Keys ex
30
32
  type Placeholder = symbol;
31
33
  export declare const __: Placeholder;
32
34
  export declare const curry: (fn: AnyFunc) => (...args: AnyArgs) => any;
33
- type Curried2<p0, p1, ReturnT> = {
34
- (a: Placeholder, b: p1): (a: p0) => ReturnT;
35
- (a: p0, b: Placeholder): (b: p1) => ReturnT;
36
- (a: p0): (b: p1) => ReturnT;
37
- (a: p0, b: p1): ReturnT;
38
- };
39
35
  type Func2 = (a: any, b: any) => any;
40
36
  export declare function curry2<Func extends Func2>(fn: Func): {
41
37
  (a: Placeholder, b: Parameters<Func>[1]): (a: Parameters<Func>[0]) => ReturnType<Func>;
@@ -43,12 +39,8 @@ export declare function curry2<Func extends Func2>(fn: Func): {
43
39
  (a: Parameters<Func>[0]): (b: Parameters<Func>[1]) => ReturnType<Func>;
44
40
  (a: Parameters<Func>[0], b: Parameters<Func>[1]): ReturnType<Func>;
45
41
  };
46
- type Curried3<A, B, C, R> = ((a: A) => Curried2<B, C, R>) & ((a: A, b: B) => (c: C) => R) & ((a: A, b: B, c: C) => R) & ((a: Placeholder, b: B, c: C) => (a: A) => R) & ((a: A, b: Placeholder, c: C) => (b: B) => R) & ((a: A, b: B, c: Placeholder) => (c: C) => R) & ((a: Placeholder, b: Placeholder, c: C) => (a: A, b: B) => R) & ((a: Placeholder, b: B, c: Placeholder) => (a: A, c: C) => R) & ((a: A, b: Placeholder, c: Placeholder) => (b: B, c: C) => R);
47
- export declare const curry3: <Params extends [
48
- any,
49
- any,
50
- any
51
- ], ReturnT, F = AnyFunc<ReturnT, Params>>(fn: F) => Curried3<Params[0], Params[1], Params[2], ReturnT>;
42
+ type Func3 = (a: any, b: any, c: any) => any;
43
+ export declare function curry3<Func extends Func3>(fn: Func): (...args: AnyArgs) => any;
52
44
  /** One promise waits for another. */
53
45
  export declare const forEachSerial: {
54
46
  (a: Placeholder, b: any[]): (a: AnyFunc) => Promise<void>;
@@ -113,8 +105,8 @@ export declare const qappend: {
113
105
  (a: any): (b: any[]) => any[];
114
106
  (a: any, b: any[]): any[];
115
107
  };
116
- export declare const qassoc: Curried3<any, any, any, unknown>;
117
- export declare const qreduce: Curried3<any, any, any, unknown>;
108
+ export declare const qassoc: (...args: AnyArgs) => any;
109
+ export declare const qreduce: (...args: AnyArgs) => any;
118
110
  export declare const qmergeDeep: {
119
111
  (a: Placeholder, b: AnyObject): (a: AnyObject) => AnyObject;
120
112
  (a: AnyObject, b: Placeholder): (b: AnyObject) => AnyObject;
@@ -189,7 +181,7 @@ export declare const qsort: {
189
181
  (a: (a: any, b: any) => number): (b: any[]) => any[];
190
182
  (a: (a: any, b: any) => number, b: any[]): any[];
191
183
  };
192
- export declare const qassocPath: Curried3<any, any, any, unknown>;
184
+ export declare const qassocPath: (...args: AnyArgs) => any;
193
185
  export declare const qreverse: (arr: any[]) => any[];
194
186
  export declare const qomit: {
195
187
  (a: Placeholder, b: AnyObject): (a: string[]) => any[] | AnyObject;
@@ -199,7 +191,20 @@ export declare const qomit: {
199
191
  };
200
192
  /** @param prop string @param pipe (data[prop]): prop_value @param data any
201
193
  * @returns data with prop over pipe. */
202
- export declare const qoverProp: Curried3<any, any, any, unknown>;
194
+ export declare const qoverProp: (...args: AnyArgs) => any;
195
+ /** Slower than pick() (dictionary mode) !
196
+ * @param props (string|number)[]
197
+ * @param o AnyObject
198
+ * @returns AnyObject
199
+ */
200
+ export declare const qpick: {
201
+ (a: Placeholder, b: AnyObject): (a: string[]) => AnyObject;
202
+ (a: string[], b: Placeholder): (b: AnyObject) => AnyObject;
203
+ (a: string[]): (b: AnyObject) => AnyObject;
204
+ (a: string[], b: AnyObject): AnyObject;
205
+ };
206
+ export declare const qslice: (...args: AnyArgs) => any;
207
+ export declare const quniq: (xs: any[]) => any[];
203
208
  export declare const qpush: {
204
209
  (a: Placeholder, b: any[]): (a: any) => any[];
205
210
  (a: any, b: Placeholder): (b: any[]) => any[];
@@ -209,7 +214,7 @@ export declare const qpush: {
209
214
  export declare const isNil: <T extends any>(s: T) => T extends (null | undefined) ? true : false;
210
215
  export declare const take: (argN: number) => (...args: any[]) => any;
211
216
  export declare const ifElse: (...args: AnyArgs) => any;
212
- export declare const when: Curried3<any, any, any, unknown>;
217
+ export declare const when: (...args: AnyArgs) => any;
213
218
  export declare const compose: <TIn extends any[] = any[], TOut = any>(...fns: AnyFunc[]) => Composed<TIn, TOut>;
214
219
  /** @param fn AnyFunc @param context any */
215
220
  export declare const bind: {
@@ -224,7 +229,7 @@ export declare const nth: {
224
229
  (a: number): (b: string | ArrayLike<unknown>) => unknown;
225
230
  (a: number, b: string | ArrayLike<unknown>): unknown;
226
231
  };
227
- export declare const slice: Curried3<any, any, any, unknown>;
232
+ export declare const slice: (...args: AnyArgs) => any;
228
233
  export declare const flip: <T extends AnyFunc>(fn: T) => {
229
234
  (a: Placeholder, b: Parameters<T>[0]): (a: Parameters<T>[1]) => any;
230
235
  (a: Parameters<T>[1], b: Placeholder): (b: Parameters<T>[0]) => any;
@@ -433,13 +438,13 @@ export declare const range: {
433
438
  };
434
439
  /** @param cond (x, y): bool @param xs any[] @returns xs without duplicates, using cond as a comparator. */
435
440
  export declare const uniqWith: {
436
- (a: Placeholder, b: any[]): (a: (x: any, y: any) => boolean) => unknown;
437
- (a: (x: any, y: any) => boolean, b: Placeholder): (b: any[]) => unknown;
438
- (a: (x: any, y: any) => boolean): (b: any[]) => unknown;
439
- (a: (x: any, y: any) => boolean, b: any[]): unknown;
441
+ (a: Placeholder, b: any[]): (a: (x: any, y: any) => boolean) => any;
442
+ (a: (x: any, y: any) => boolean, b: Placeholder): (b: any[]) => any;
443
+ (a: (x: any, y: any) => boolean): (b: any[]) => any;
444
+ (a: (x: any, y: any) => boolean, b: any[]): any;
440
445
  };
441
446
  /** @param xs any[] @returns xs without duplicates. */
442
- export declare const uniq: (b: any[]) => unknown;
447
+ export declare const uniq: (b: any[]) => any;
443
448
  export declare const intersection: {
444
449
  (a: Placeholder, b: any[]): (a: any[]) => any[];
445
450
  (a: any[], b: Placeholder): (b: any[]) => any[];
@@ -487,8 +492,8 @@ export declare const cond: {
487
492
  * @param value any
488
493
  * @param object AnyObject
489
494
  */
490
- export declare const assoc: Curried3<any, any, any, unknown>;
491
- export declare const assocPath: Curried3<any, any, any, unknown>;
495
+ export declare const assoc: (...args: AnyArgs) => any;
496
+ export declare const assocPath: (...args: AnyArgs) => any;
492
497
  export declare const all: {
493
498
  (a: Placeholder, b: any[]): (a: Cond) => boolean;
494
499
  (a: Cond, b: Placeholder): (b: any[]) => boolean;
@@ -535,13 +540,13 @@ export declare const prop: {
535
540
  (a: string, b: AnyObject): any;
536
541
  };
537
542
  /** @param key string @param value any @param o AnyObject @returns boolean o[key] equals value */
538
- export declare const propEq: Curried3<any, any, any, unknown>;
543
+ export declare const propEq: (...args: AnyArgs) => any;
539
544
  /** @param key string @param o1 AnyObject @param o2 AnyObject @returns o₁[key] equals o₂[key] */
540
- export declare const propsEq: Curried3<any, any, any, unknown>;
541
- export declare const pathOr: Curried3<any, (string | number)[], AnyObject, any>;
542
- export declare const path: Curried2<(string | number)[], AnyObject, any>;
543
- export declare const pathEq: Curried3<any, any, any, unknown>;
544
- export declare const pathsEq: Curried3<any, any, any, unknown>;
545
+ export declare const propsEq: (...args: AnyArgs) => any;
546
+ export declare const pathOr: (...args: AnyArgs) => any;
547
+ export declare const path: any;
548
+ export declare const pathEq: (...args: AnyArgs) => any;
549
+ export declare const pathsEq: (...args: AnyArgs) => any;
545
550
  export declare const pathExists: Composed<any[], any>;
546
551
  export declare const clone: <T extends any>(s: T, shallow?: boolean) => T;
547
552
  export declare const cloneShallow: (s: any) => any;
@@ -552,12 +557,17 @@ export declare const freezeShallow: <T extends AnyObject>(o: T) => Readonly<T>;
552
557
  * @param accum T1
553
558
  * @param array T2[]
554
559
  */
555
- export declare const reduce: Curried3<any, any, any, unknown>;
560
+ export declare const reduce: (...args: AnyArgs) => any;
561
+ /**
562
+ * @param props (string|number)[]
563
+ * @param o AnyObject
564
+ * @returns AnyObject
565
+ */
556
566
  export declare const pick: {
557
- (a: Placeholder, b: AnyObject): (a: string[]) => {};
558
- (a: string[], b: Placeholder): (b: AnyObject) => {};
559
- (a: string[]): (b: AnyObject) => {};
560
- (a: string[], b: AnyObject): {};
567
+ (a: Placeholder, b: AnyObject): (a: (string | number)[]) => {};
568
+ (a: (string | number)[], b: Placeholder): (b: AnyObject) => {};
569
+ (a: (string | number)[]): (b: AnyObject) => {};
570
+ (a: (string | number)[], b: AnyObject): {};
561
571
  };
562
572
  export declare const pickBy: {
563
573
  (a: Placeholder, b: AnyObject): (a: Cond) => any;
@@ -623,10 +633,10 @@ export declare const forEach: {
623
633
  (a: (s: unknown, i: number, arr: unknown[]) => any): (b: any[]) => void;
624
634
  (a: (s: unknown, i: number, arr: unknown[]) => any, b: any[]): void;
625
635
  };
626
- export declare const both: Curried3<any, any, any, unknown>;
636
+ export declare const both: (...args: AnyArgs) => any;
627
637
  export declare const isEmpty: (s: any) => boolean | null;
628
638
  export declare const empty: (s: any) => {} | undefined;
629
- export declare const replace: Curried3<any, any, any, unknown>;
639
+ export declare const replace: (...args: AnyArgs) => any;
630
640
  export declare const filter: {
631
641
  (a: Placeholder, b: any[] | AnyObject): (a: (v: any, k: string | number) => boolean) => any;
632
642
  (a: (v: any, k: string | number) => boolean, b: Placeholder): (b: any[] | AnyObject) => any;
@@ -668,7 +678,7 @@ export declare const mergeDeepAdd: {
668
678
  (a: AnyObject, b: AnyObject): AnyObject;
669
679
  };
670
680
  /** @param prop string @param pipe(data[prop]) @param data any @returns data with prop over pipe. */
671
- export declare const overProp: Curried3<any, any, any, unknown>;
681
+ export declare const overProp: (...args: AnyArgs) => any;
672
682
  /** mapKeys({ a: 'b' }, { a: 44 }) -> { b: 44 } */
673
683
  export declare const mapKeys: {
674
684
  (a: Placeholder, b: AnyObject): (a: {
@@ -691,10 +701,10 @@ export declare const zip: {
691
701
  (a: unknown[], b: unknown[]): any[];
692
702
  };
693
703
  export declare const zipObj: {
694
- (a: Placeholder, b: unknown[]): (a: unknown[]) => unknown;
695
- (a: unknown[], b: Placeholder): (b: unknown[]) => unknown;
696
- (a: unknown[]): (b: unknown[]) => unknown;
697
- (a: unknown[], b: unknown[]): unknown;
704
+ (a: Placeholder, b: unknown[]): (a: unknown[]) => any;
705
+ (a: unknown[], b: Placeholder): (b: unknown[]) => any;
706
+ (a: unknown[]): (b: unknown[]) => any;
707
+ (a: unknown[], b: unknown[]): any;
698
708
  };
699
709
  /** zips through a pipe. Types T1, T2, T3.
700
710
  * @returns T3[]
@@ -702,7 +712,7 @@ export declare const zipObj: {
702
712
  * @param a T1[]
703
713
  * @param b T2[]
704
714
  */
705
- export declare const zipWith: Curried3<any, any, any, unknown>;
715
+ export declare const zipWith: (...args: AnyArgs) => any;
706
716
  export declare const mirror: <T extends unknown>(s: T) => T;
707
717
  export declare const reflect: <T extends unknown>(s: T) => T;
708
718
  export declare const echo: <T extends unknown>(s: T) => T;
@@ -725,6 +735,12 @@ export declare const weakEq: {
725
735
  (a: any): (b: any) => boolean;
726
736
  (a: any, b: any): boolean;
727
737
  };
738
+ export declare const uniqBy: {
739
+ (a: Placeholder, b: any[]): (a: (x: any, y: any) => boolean) => any;
740
+ (a: (x: any, y: any) => boolean, b: Placeholder): (b: any[]) => any;
741
+ (a: (x: any, y: any) => boolean): (b: any[]) => any;
742
+ (a: (x: any, y: any) => boolean, b: any[]): any;
743
+ };
728
744
  type StrTmpl = ((data: AnyObject) => string);
729
745
  /** Supports ecrans: '\\{"json": {yes} \\}'
730
746
  @returns getTmpl('one{meme}two')({meme: 42}) -> one42two */
package/dist/bundle.mjs CHANGED
@@ -55,7 +55,16 @@ function curry2(fn) {
55
55
  }
56
56
  return curried2;
57
57
  }
58
- const curry3 = (fn) => curry(fn);
58
+ function curry3(fn) {
59
+ // type p0 = Parameters<Func>[0]
60
+ // type p1 = Parameters<Func>[1]
61
+ // type p2 = Parameters<Func>[2]
62
+ // type ReturnT = ReturnType<Func>
63
+ // TODO: optimize.
64
+ // Cannot use ts-toolbelt due to this error:
65
+ // Excessive stack depth comparing types 'GapsOf<?, L2>' and 'GapsOf<?, L2>'
66
+ return curry(fn);
67
+ }
59
68
 
60
69
  const length = (s) => s.length;
61
70
  const typed_arr_re = /^(.*?)(8|16|32|64)(Clamped)?Array$/;
@@ -125,9 +134,9 @@ const includes = curry2((s, ss) => {
125
134
  }
126
135
  });
127
136
 
128
- /* Then next fns seem to be excess due to their safe ver performance should be the same or better:
129
- * qflat, qpick, qslice, quniq, qflat, qflatShallow, qreduceAsync
130
- */
137
+ const { min } = Math;
138
+ const z = 0;
139
+ /* qflat, qflatShallow, qreduceAsync */
131
140
  const qappend = curry2((s, xs) => { xs.push(s); return xs; });
132
141
  const qassoc = curry3((prop, v, obj) => { obj[prop] = v; return obj; });
133
142
  const qreduce = curry3((fn, accum, arr) => arr.reduce(fn, accum));
@@ -243,6 +252,55 @@ const qomit = curry2((props, o) => qfilter((_, k) => !includes(k, props), o));
243
252
  /** @param prop string @param pipe (data[prop]): prop_value @param data any
244
253
  * @returns data with prop over pipe. */
245
254
  const qoverProp = curry3((prop, pipe, data) => qassoc(prop, pipe(data[prop]), data));
255
+ /** Slower than pick() (dictionary mode) !
256
+ * @param props (string|number)[]
257
+ * @param o AnyObject
258
+ * @returns AnyObject
259
+ */
260
+ const qpick = curry2((props, o) => {
261
+ for (const p in o)
262
+ if (!props.includes(p))
263
+ delete o[p];
264
+ return o;
265
+ });
266
+ const qslice = curry3((from, to, xs) => {
267
+ const right = (isNum(to) ? to : inf);
268
+ const window_width = min(right, length(xs)) - from;
269
+ if (isArray(xs)) {
270
+ xs = xs;
271
+ if (from > z)
272
+ for (let i = z; i < window_width; i++)
273
+ xs[i] = xs[from + i];
274
+ xs.length = window_width;
275
+ return xs;
276
+ }
277
+ else
278
+ return xs.slice(from, right); // strings are immutable.
279
+ });
280
+ /** Should be faster than .splice() 'cause does not make a new array. */
281
+ const rmel = (index, xs) => {
282
+ const len = length(xs);
283
+ for (let i = index; i < len; i++)
284
+ xs[i] = xs[i + 1];
285
+ xs.length = len - 1;
286
+ return xs;
287
+ };
288
+ const seen = new Set();
289
+ const quniq = (xs) => {
290
+ seen.clear();
291
+ let size = length(xs);
292
+ for (let i = z; i < size; i++) {
293
+ const x = xs[i];
294
+ if (seen.has(x)) {
295
+ rmel(i, xs);
296
+ size--;
297
+ i--;
298
+ }
299
+ else
300
+ seen.add(x);
301
+ }
302
+ return xs;
303
+ };
246
304
  // Aliases.
247
305
  const qpush = qappend;
248
306
 
@@ -369,7 +427,12 @@ const diff = curry2((_xs1, _xs2) => {
369
427
  }
370
428
  return out;
371
429
  });
372
- const genBy = curry2((generator, length) => [...Array(length)].map((_, i) => generator(i)));
430
+ const genBy = curry2((generator, length) => {
431
+ const a = new Array(length);
432
+ for (let i = 0; i < length; i++)
433
+ a[i] = generator(i);
434
+ return a;
435
+ });
373
436
  const once = (fn) => {
374
437
  let done = false, cache;
375
438
  return function (...args) {
@@ -460,6 +523,11 @@ const freezeShallow = (o) => qfreezeShallow(clone(o));
460
523
  * @param array T2[]
461
524
  */
462
525
  const reduce = curry3((reducer, accum, arr) => qreduce(reducer, clone(accum), arr));
526
+ /**
527
+ * @param props (string|number)[]
528
+ * @param o AnyObject
529
+ * @returns AnyObject
530
+ */
463
531
  const pick = curry2((props, o) => {
464
532
  const out = {};
465
533
  for (const p of props)
@@ -543,6 +611,7 @@ const notf = complement;
543
611
  const push = append;
544
612
  const some = any;
545
613
  const weakEq = eq;
614
+ const uniqBy = uniqWith;
546
615
 
547
616
  /** One promise waits for another. */
548
617
  const forEachSerial = (() => {
@@ -654,4 +723,4 @@ const wait = (time) => new Promise((ff) => setTimeout(ff, time));
654
723
  // TODO: possibly introduce a second argument limiting unfolding.
655
724
  const uncurry = (fn) => (...args) => qreduce(((fn, arg) => fn ? fn(arg) : fn), fn, args);
656
725
 
657
- export { F, T, __, add, all, allPass, always, any, anyPass, append, assoc, assocPath, bind, both, callFrom, callWith, clone, cloneShallow, complement, compose, composeAsync, concat, cond, curry, curry2, curry3, debounce, diff, divide, echo, empty, eq, equals, explore, filter, find, findIndex, flat, flatShallow, flatTo, flip, forEach, forEachAsync, forEachSerial, freeze, freezeShallow, fromPairs, genBy, getTmpl, gt, gte, head, identity, ifElse, includes, indexOf, intersection, isEmpty, isNil, join, keys, last, length, lt, lte, map, mapKeys, mapObj, memoize, mergeDeep, mergeDeepAdd, mergeDeepX, mergeShallow, mirror, multiply, noop, not, notf, nth, omit, once, overProp, path, pathEq, pathExists, pathOr, pathsEq, pick, pickBy, prepend, prop, propEq, propsEq, push, qappend, qassoc, qassocPath, qempty, qfilter, qfreeze, qfreezeShallow, qmap, qmapKeys, qmapObj, qmergeDeep, qmergeDeepAdd, qmergeDeepX, qmergeShallow, qomit, qoverProp, qprepend, qpush, qreduce, qreverse, qsort, range, reduce, reflect, replace, reverse, sizeof, slice, some, sort, split, startsWith, startsWithShallow, subtract, symbol, tail, take, tap, test, throttle, toLower, toPairs, toUpper, trim, type, typeIs, uncurry, uniq, uniqWith, values, wait, waitAll, waitTap, weakEq, when, zip, zipObj, zipWith };
726
+ export { F, T, __, add, all, allPass, always, any, anyPass, append, assoc, assocPath, bind, both, callFrom, callWith, clone, cloneShallow, complement, compose, composeAsync, concat, cond, curry, curry2, curry3, debounce, diff, divide, echo, empty, eq, equals, explore, filter, find, findIndex, flat, flatShallow, flatTo, flip, forEach, forEachAsync, forEachSerial, freeze, freezeShallow, fromPairs, genBy, getTmpl, gt, gte, head, identity, ifElse, includes, indexOf, intersection, isEmpty, isNil, join, keys, last, length, lt, lte, map, mapKeys, mapObj, memoize, mergeDeep, mergeDeepAdd, mergeDeepX, mergeShallow, mirror, multiply, noop, not, notf, nth, omit, once, overProp, path, pathEq, pathExists, pathOr, pathsEq, pick, pickBy, prepend, prop, propEq, propsEq, push, qappend, qassoc, qassocPath, qempty, qfilter, qfreeze, qfreezeShallow, qmap, qmapKeys, qmapObj, qmergeDeep, qmergeDeepAdd, qmergeDeepX, qmergeShallow, qomit, qoverProp, qpick, qprepend, qpush, qreduce, qreverse, qslice, qsort, quniq, range, reduce, reflect, replace, reverse, sizeof, slice, some, sort, split, startsWith, startsWithShallow, subtract, symbol, tail, take, tap, test, throttle, toLower, toPairs, toUpper, trim, type, typeIs, uncurry, uniq, uniqBy, uniqWith, values, wait, waitAll, waitTap, weakEq, when, zip, zipObj, zipWith };
package/package.json CHANGED
@@ -41,7 +41,7 @@
41
41
  "prod": "npm run gentypes && npm run prod:es && npm run prod:cjs",
42
42
  "all": "npm run dev && npm run prod"
43
43
  },
44
- "version": "1.6.22",
44
+ "version": "1.7.0",
45
45
  "devDependencies": {
46
46
  "@rollup/plugin-commonjs": "^29.0.0",
47
47
  "@rollup/plugin-node-resolve": "^16.0.3",
package/src/bench.ts ADDED
@@ -0,0 +1,33 @@
1
+ import { qpick } from "./quick"
2
+ import { genBy, identity, range } from "./safe"
3
+
4
+
5
+ if(false) {
6
+ // genBy with [...Array(length)].map(...) performs @ average 53.193s/1e5, 303ms/1e4.
7
+ console.time('genBy') // now: 17s/1e5, 65ms/1e4
8
+ for(let i=0; i<1e5; i++) genBy(identity, i)
9
+ console.timeEnd('genBy')
10
+ }
11
+
12
+ // qpick:
13
+ // if o = {1: 'yep', 4: 'yep', 'kakashka': 'noooo', 'anotherkakashka': 'nonono!'}:
14
+ // w/ Set: with range(0, 5) -> 83ms; range(0, 50) -> 189ms.
15
+ // w/o Set: with range(0, 5) -> 69ms; range(0, 50) -> 75ms.
16
+ // if o is generated with 52+ leaset keys are not included in props (generator included!):
17
+ // w/ Set: with range(0, 5) -> 998ms; range(0, 50) -> 1100ms.
18
+ // w/o Set: with range(0, 5) -> 1000ms; range(0, 50) -> 1065ms.
19
+ // pick:
20
+ // if o = {1: 'yep', 4: 'yep', 'kakashka': 'noooo', 'anotherkakashka': 'nonono!'}:
21
+ // w/o Set: with range(0, 5) -> 18ms; range(0, 50) -> 40ms.
22
+ // if o is generated with 52+ leaset keys are not included in props (generator included!):
23
+ // w/o Set: with range(0, 5) -> 600ms; range(0, 50) -> 647ms.
24
+ for(let j=0; j<1e4; j+=1e3) {
25
+ console.time('qpick @'+j)
26
+ const props = range(0, 5)
27
+ for(let i=0; i<1e5; i++) {
28
+ const o = {1: 'yep', 4: 'yep', 'kakashka': 'noooo', 'anotherkakashka': 'nonono!'}
29
+ // for(const x of range(0, 50)) o['_'+x] = x
30
+ qpick(props, o)
31
+ }
32
+ console.timeEnd('qpick @'+j)
33
+ }
package/src/curry.ts CHANGED
@@ -87,16 +87,14 @@ export function curry2<Func extends Func2>(fn: Func) {
87
87
  return curried2
88
88
  }
89
89
 
90
- export type Curried3<A, B, C, R> =
91
- & ((a: A) => Curried2<B, C, R>)
92
- & ((a: A, b: B) => (c: C) => R)
93
- & ((a: A, b: B, c: C) => R)
94
- & ((a: Placeholder, b: B, c: C) => (a: A) => R)
95
- & ((a: A, b: Placeholder, c: C) => (b: B) => R)
96
- & ((a: A, b: B, c: Placeholder) => (c: C) => R)
97
- & ((a: Placeholder, b: Placeholder, c: C) => (a: A, b: B) => R)
98
- & ((a: Placeholder, b: B, c: Placeholder) => (a: A, c: C) => R)
99
- & ((a: A, b: Placeholder, c: Placeholder) => (b: B, c: C) => R)
100
-
101
- export const curry3 = <Params extends [any, any, any], ReturnT, F = AnyFunc<ReturnT, Params>>(fn: F):
102
- Curried3<Params[0], Params[1], Params[2], ReturnT> => curry(fn as any)
90
+ type Func3 = (a: any, b: any, c: any) => any
91
+ export function curry3<Func extends Func3>(fn: Func) {
92
+ // type p0 = Parameters<Func>[0]
93
+ // type p1 = Parameters<Func>[1]
94
+ // type p2 = Parameters<Func>[2]
95
+ // type ReturnT = ReturnType<Func>
96
+ // TODO: optimize.
97
+ // Cannot use ts-toolbelt due to this error:
98
+ // Excessive stack depth comparing types 'GapsOf<?, L2>' and 'GapsOf<?, L2>'
99
+ return curry(fn)
100
+ }
package/src/internal.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { curry2 } from "./curry"
2
2
  import { AnyArray, StrLen } from "./internal_types"
3
3
 
4
- export const length = <T extends AnyArray | string>(s: T): T extends string ? StrLen<T> : T["length"] => s.length as any
4
+ export const length = <T extends AnyArray | string>(s: T): T extends string ? StrLen<T> : T['length'] => s.length as any
5
5
  const typed_arr_re = /^(.*?)(8|16|32|64)(Clamped)?Array$/
6
6
  export const is_typed_arr = (t: string) => typed_arr_re.test(t)
7
7
  /** @param start string | any[] @param s string | any[] */
@@ -2,7 +2,7 @@ export type AnyArgs = any[]
2
2
  export type BasicType = 'String'|'Object'|'Number'|'Symbol'|'Array'|'Null'|'Undefined'
3
3
  export type TupleFn<ARG1=any, ARG2=any, Out=any> = (a: ARG1, b: ARG2) => Out
4
4
  export type IDArray = Uint8Array|Uint16Array|Uint32Array
5
- export type AnyArray<T=any> = T[] | readonly T[]
5
+ export type AnyArray<T=any> = T[] | readonly T[] | (ArrayBufferView&{length: number})
6
6
  export type Split<S extends string> = S extends `${infer U}${infer V}` ? [U, ...Split<V>] : []
7
7
  export type IndexesOfArray<A> = Exclude<keyof A, keyof []>
8
8
  export type StrLen<S extends string, Acc extends 0[] = []> =
package/src/quick.ts CHANGED
@@ -1,10 +1,10 @@
1
+ import { includes, length, type } from "./common"
1
2
  import { curry2, curry3 } from "./curry"
2
- import { includes, type } from "./common"
3
- import { AnyObject, Reducer, AnyFunc } from "./types"
4
- import { isFunc, isArray, isObj, isNil } from "./utils"
5
- /* Then next fns seem to be excess due to their safe ver performance should be the same or better:
6
- * qflat, qpick, qslice, quniq, qflat, qflatShallow, qreduceAsync
7
- */
3
+ import { AnyFunc, AnyObject, Reducer } from "./types"
4
+ import { inf, isArray, isFunc, isNil, isNum, isObj } from "./utils"
5
+ const {min} = Math
6
+ const z = 0
7
+ /* qflat, qflatShallow, qreduceAsync */
8
8
 
9
9
  export const qappend = curry2((s: any, xs: any[]) => {xs.push(s); return xs})
10
10
  export const qassoc = curry3((prop: string, v: any, obj: AnyObject) => { obj[prop] = v; return obj })
@@ -132,6 +132,45 @@ export const qomit = curry2(
132
132
  export const qoverProp = curry3(
133
133
  (prop: string, pipe: AnyFunc, data: any) => qassoc(prop, pipe(data[prop]), data)
134
134
  )
135
+ /** Slower than pick() (dictionary mode) !
136
+ * @param props (string|number)[]
137
+ * @param o AnyObject
138
+ * @returns AnyObject
139
+ */
140
+ export const qpick = curry2((props: string[], o: AnyObject) => {
141
+ for(const p in o) if(!props.includes(p)) delete o[p]
142
+ return o
143
+ })
144
+ export const qslice = curry3(
145
+ (from: number, to: number, xs: any[] | string) => {
146
+ const right = (isNum(to)?to:inf) as number
147
+ const window_width = min(right, length(xs))-from
148
+ if(isArray(xs)) {
149
+ xs = xs as any[]
150
+ if(from>z) for(let i=z; i<window_width; i++) xs[i] = xs[from+i]
151
+ xs.length = window_width
152
+ return xs
153
+ } else return xs.slice(from, right) // strings are immutable.
154
+ }
155
+ )
156
+ /** Should be faster than .splice() 'cause does not make a new array. */
157
+ const rmel = (index: number, xs: any[]) => {
158
+ const len = length(xs)
159
+ for(let i=index; i<len; i++) xs[i]=xs[i+1]
160
+ xs.length = len-1
161
+ return xs
162
+ }
163
+ const seen = new Set()
164
+ export const quniq = (xs: any[]) => {
165
+ seen.clear()
166
+ let size = length(xs)
167
+ for(let i=z; i<size; i++) {
168
+ const x = xs[i]
169
+ if(seen.has(x)) {rmel(i, xs); size--; i--}
170
+ else seen.add(x)
171
+ }
172
+ return xs
173
+ }
135
174
 
136
175
  // Aliases.
137
176
  export const qpush = qappend
package/src/safe.ts CHANGED
@@ -198,7 +198,11 @@ export const genBy = curry2(
198
198
  (
199
199
  generator: (i: number) => any,
200
200
  length: number
201
- ) => [...Array(length)].map((_, i) => generator(i))
201
+ ) => {
202
+ const a = new Array(length)
203
+ for(let i=0; i<length; i++) a[i] = generator(i)
204
+ return a
205
+ }
202
206
  )
203
207
  export const once = <Func extends AnyFunc>(fn: Func) => {
204
208
  let done = false, cache: ReturnType<Func>
@@ -274,7 +278,7 @@ const _pathOr = (_default: any, path: (string | number)[], o: AnyObject) => leng
274
278
  head
275
279
  )(path)
276
280
  : o
277
- export const pathOr = curry3<[any, (string | number)[], AnyObject], any>(_pathOr) // it's more performant due to recursion there.
281
+ export const pathOr = curry3(_pathOr) // it's more performant due to recursion there.
278
282
  export const path = pathOr(undef)
279
283
  export const pathEq = curry3(
280
284
  (_path: string[], value: any, o: AnyObject) => equals(path(_path, o), value)
@@ -314,8 +318,13 @@ export const reduce = curry3(
314
318
  <T = any>(reducer: Reducer<T>, accum: T, arr: any[]) =>
315
319
  qreduce(reducer, clone(accum), arr)
316
320
  )
321
+ /**
322
+ * @param props (string|number)[]
323
+ * @param o AnyObject
324
+ * @returns AnyObject
325
+ */
317
326
  export const pick = curry2(
318
- (props: string[], o: AnyObject) => {
327
+ (props: (string|number)[], o: AnyObject) => {
319
328
  const out = {}
320
329
  for(const p of props) if(p in o) out[p] = o[p]
321
330
  return out
@@ -453,4 +462,5 @@ export const echo = identity
453
462
  export const notf = complement
454
463
  export const push = append
455
464
  export const some = any
456
- export const weakEq = eq
465
+ export const weakEq = eq
466
+ export const uniqBy = uniqWith