pepka 1.7.0 → 1.8.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/bundle.cjs CHANGED
@@ -101,11 +101,12 @@ const caseMap = { u: 'U', b: 'B', n: 'N', s: 'S', f: 'F' };
101
101
  const symbol = Symbol();
102
102
  const toLower = (s) => s.toLowerCase();
103
103
  const toUpper = (s) => s.toUpperCase();
104
+ const cap_type = (t) => caseMap[t[0]] + t.slice(1);
104
105
  const type = (s) => {
105
106
  const t = to(s);
106
107
  return t === 'object'
107
- ? isNull(s) ? 'Null' : s.constructor.name
108
- : caseMap[t[0]] + t.slice(1);
108
+ ? isNull(s) ? 'Null' : (s.constructor?.name || cap_type(t))
109
+ : cap_type(t);
109
110
  };
110
111
  const typeIs = curry2((t, s) => type(s) === t);
111
112
  const eq = curry2((a, b) => a === b);
@@ -195,32 +196,46 @@ const qmapKeys = curry2((keyMap, o) => {
195
196
  return o;
196
197
  });
197
198
  // FIXME: qmap(any, tags) -> some function!!!
199
+ /**
200
+ * @param pipe (v, i, list: T[]) -> T.
201
+ * @param data T[].
202
+ * @returns T[].
203
+ */
198
204
  const qmap = curry2((pipe, arr) => {
199
205
  for (const i in arr)
200
206
  arr[i] = pipe(arr[i], +i, arr);
201
207
  return arr;
202
208
  });
209
+ /**
210
+ * @param cond (v, k) -> boolean.
211
+ * @param data T extends AnyObject.
212
+ * @returns T
213
+ */
203
214
  const qmapObj = curry2((pipe, o) => {
204
215
  for (const k in o)
205
216
  o[k] = pipe(o[k], k, o);
206
217
  return o;
207
218
  });
219
+ /**
220
+ * @param cond (v, k) -> boolean.
221
+ * @param data T extends any[] | AnyObject.
222
+ * @returns T
223
+ */
208
224
  const qfilter = curry2((cond, data) => {
209
- const isArr = isArray(data);
210
- let indicies_offset, indicies2rm;
211
- if (isArr) {
212
- indicies_offset = 0;
213
- indicies2rm = [];
225
+ if (isArray(data)) {
226
+ let indicies_offset = 0;
227
+ const indicies2rm = [];
228
+ const len = length(data);
229
+ for (let i = 0; i < len; i++)
230
+ if (!cond(data[i], i))
231
+ indicies2rm.push(i);
232
+ for (const i of indicies2rm)
233
+ data.splice(i - indicies_offset++, 1);
214
234
  }
215
- for (let k in data)
216
- if (!cond(data[k], k)) // @ts-ignore
217
- if (isArr)
218
- indicies2rm.push(+k);
219
- else
235
+ else
236
+ for (const k in data)
237
+ if (!cond(data[k], k))
220
238
  delete data[k];
221
- if (isArr) // @ts-ignore
222
- for (const i of indicies2rm) // @ts-ignore
223
- data.splice(i - indicies_offset++, 1);
224
239
  return data;
225
240
  });
226
241
  const qempty = (o) => {
@@ -254,7 +269,7 @@ const qomit = curry2((props, o) => qfilter((_, k) => !includes(k, props), o));
254
269
  /** @param prop string @param pipe (data[prop]): prop_value @param data any
255
270
  * @returns data with prop over pipe. */
256
271
  const qoverProp = curry3((prop, pipe, data) => qassoc(prop, pipe(data[prop]), data));
257
- /** Slower than pick() (dictionary mode) !
272
+ /** Slower than pick() (dictionary mode) ! it's okay when the object is already in the dic mode !
258
273
  * @param props (string|number)[]
259
274
  * @param o AnyObject
260
275
  * @returns AnyObject
@@ -627,6 +642,13 @@ const forEachSerial = (() => {
627
642
  })();
628
643
  /** Promise.all wrapper for functional pipelining. */
629
644
  const waitAll = (promises) => Promise.all(promises);
645
+ const qwaitAll = async (xs) => new Promise((ff, rj) => {
646
+ const len = length(xs);
647
+ let j = len;
648
+ for (let i = 0; i < len; i++)
649
+ xs[i].then((x) => { xs[i] = x; if (--j)
650
+ ff(xs); }).catch(rj);
651
+ });
630
652
  /** Waits for a Promise that been generated by the first arg, then returns an untoched value. Types T.
631
653
  * @param {AnyFunc<Promise>} fn - function to wait.
632
654
  * @param {T} s - any value to tap and return back
@@ -640,6 +662,29 @@ const composeAsync = (() => {
640
662
  const pipe = async (fns, input, i) => ~i ? await pipe(fns, [await fns[i](...input)], --i) : head(input);
641
663
  return (...fns) => (...input) => pipe(fns, input, fns.length - 1);
642
664
  })();
665
+ /**
666
+ * @param cond async (v, k) -> boolean.
667
+ * @param data T extends any[] | AnyObject.
668
+ * @returns T
669
+ */
670
+ const qfilterAsync = curry2(async (cond, data // dunno how to merge it with sync version...
671
+ ) => {
672
+ if (isArray(data)) {
673
+ let indicies_offset = 0;
674
+ const indicies2rm = [];
675
+ const len = length(data);
676
+ for (let i = 0; i < len; i++)
677
+ if (!await cond(data[i], i))
678
+ indicies2rm.push(i);
679
+ for (const i of indicies2rm)
680
+ data.splice(i - indicies_offset++, 1);
681
+ }
682
+ else
683
+ for (const k in data)
684
+ if (!await cond(data[k], k))
685
+ delete data[k];
686
+ return data;
687
+ });
643
688
 
644
689
  const ecran = '\\';
645
690
  // TODO: make it splicy, not accumulatie by symbols.
@@ -824,6 +869,7 @@ exports.qassoc = qassoc;
824
869
  exports.qassocPath = qassocPath;
825
870
  exports.qempty = qempty;
826
871
  exports.qfilter = qfilter;
872
+ exports.qfilterAsync = qfilterAsync;
827
873
  exports.qfreeze = qfreeze;
828
874
  exports.qfreezeShallow = qfreezeShallow;
829
875
  exports.qmap = qmap;
@@ -843,6 +889,7 @@ exports.qreverse = qreverse;
843
889
  exports.qslice = qslice;
844
890
  exports.qsort = qsort;
845
891
  exports.quniq = quniq;
892
+ exports.qwaitAll = qwaitAll;
846
893
  exports.range = range;
847
894
  exports.reduce = reduce;
848
895
  exports.reflect = reflect;
package/dist/bundle.d.ts CHANGED
@@ -50,6 +50,7 @@ export declare const forEachSerial: {
50
50
  };
51
51
  /** Promise.all wrapper for functional pipelining. */
52
52
  export declare const waitAll: <T>(promises: Promise<T>[]) => Promise<Awaited<T>[]>;
53
+ export declare const qwaitAll: <T>(xs: Promise<T>[]) => Promise<T[]>;
53
54
  /** Waits for a Promise that been generated by the first arg, then returns an untoched value. Types T.
54
55
  * @param {AnyFunc<Promise>} fn - function to wait.
55
56
  * @param {T} s - any value to tap and return back
@@ -70,6 +71,17 @@ export declare const forEachAsync: {
70
71
  };
71
72
  /** The same as compose, but waits for promises in chains and returns a Promise. */
72
73
  export declare const composeAsync: <TIn extends any[] = any[], TOut = any>(...fns: AnyFunc[]) => Composed<TIn, Promise<TOut>>;
74
+ /**
75
+ * @param cond async (v, k) -> boolean.
76
+ * @param data T extends any[] | AnyObject.
77
+ * @returns T
78
+ */
79
+ export declare const qfilterAsync: {
80
+ (a: Placeholder, b: any[] | AnyObject): (a: (v: any, k: string | number) => Promise<boolean> | boolean) => Promise<any[] | AnyObject>;
81
+ (a: (v: any, k: string | number) => Promise<boolean> | boolean, b: Placeholder): (b: any[] | AnyObject) => Promise<any[] | AnyObject>;
82
+ (a: (v: any, k: string | number) => Promise<boolean> | boolean): (b: any[] | AnyObject) => Promise<any[] | AnyObject>;
83
+ (a: (v: any, k: string | number) => Promise<boolean> | boolean, b: any[] | AnyObject): Promise<any[] | AnyObject>;
84
+ };
73
85
  declare const length$1: <T extends AnyArray | string>(s: T) => T extends string ? StrLen<T> : T["length"];
74
86
  export declare const symbol: unique symbol;
75
87
  export declare const toLower: (s: string) => string;
@@ -147,18 +159,33 @@ export declare const qmapKeys: {
147
159
  [oldKey: string]: string | AnyFunc;
148
160
  }, b: AnyObject): AnyObject;
149
161
  };
162
+ /**
163
+ * @param pipe (v, i, list: T[]) -> T.
164
+ * @param data T[].
165
+ * @returns T[].
166
+ */
150
167
  export declare const qmap: {
151
- (a: Placeholder, b: any[]): (a: (s: any, i?: number, list?: any[]) => any) => any[];
152
- (a: (s: any, i?: number, list?: any[]) => any, b: Placeholder): (b: any[]) => any[];
153
- (a: (s: any, i?: number, list?: any[]) => any): (b: any[]) => any[];
154
- (a: (s: any, i?: number, list?: any[]) => any, b: any[]): any[];
168
+ (a: Placeholder, b: any[] | AnyObject): (a: (s: any, i?: number, list?: any[] | AnyObject | undefined) => any) => any[] | AnyObject;
169
+ (a: (s: any, i?: number, list?: any[] | AnyObject | undefined) => any, b: Placeholder): (b: any[] | AnyObject) => any[] | AnyObject;
170
+ (a: (s: any, i?: number, list?: any[] | AnyObject | undefined) => any): (b: any[] | AnyObject) => any[] | AnyObject;
171
+ (a: (s: any, i?: number, list?: any[] | AnyObject | undefined) => any, b: any[] | AnyObject): any[] | AnyObject;
155
172
  };
173
+ /**
174
+ * @param cond (v, k) -> boolean.
175
+ * @param data T extends AnyObject.
176
+ * @returns T
177
+ */
156
178
  export declare const qmapObj: {
157
179
  (a: Placeholder, b: AnyObject): (a: (s: any, k?: string, o?: AnyObject) => any) => AnyObject;
158
180
  (a: (s: any, k?: string, o?: AnyObject) => any, b: Placeholder): (b: AnyObject) => AnyObject;
159
181
  (a: (s: any, k?: string, o?: AnyObject) => any): (b: AnyObject) => AnyObject;
160
182
  (a: (s: any, k?: string, o?: AnyObject) => any, b: AnyObject): AnyObject;
161
183
  };
184
+ /**
185
+ * @param cond (v, k) -> boolean.
186
+ * @param data T extends any[] | AnyObject.
187
+ * @returns T
188
+ */
162
189
  export declare const qfilter: {
163
190
  (a: Placeholder, b: any[] | AnyObject): (a: (v: any, k: string | number) => boolean) => any[] | AnyObject;
164
191
  (a: (v: any, k: string | number) => boolean, b: Placeholder): (b: any[] | AnyObject) => any[] | AnyObject;
@@ -192,7 +219,7 @@ export declare const qomit: {
192
219
  /** @param prop string @param pipe (data[prop]): prop_value @param data any
193
220
  * @returns data with prop over pipe. */
194
221
  export declare const qoverProp: (...args: AnyArgs) => any;
195
- /** Slower than pick() (dictionary mode) !
222
+ /** Slower than pick() (dictionary mode) ! it's okay when the object is already in the dic mode !
196
223
  * @param props (string|number)[]
197
224
  * @param o AnyObject
198
225
  * @returns AnyObject
package/dist/bundle.mjs CHANGED
@@ -99,11 +99,12 @@ const caseMap = { u: 'U', b: 'B', n: 'N', s: 'S', f: 'F' };
99
99
  const symbol = Symbol();
100
100
  const toLower = (s) => s.toLowerCase();
101
101
  const toUpper = (s) => s.toUpperCase();
102
+ const cap_type = (t) => caseMap[t[0]] + t.slice(1);
102
103
  const type = (s) => {
103
104
  const t = to(s);
104
105
  return t === 'object'
105
- ? isNull(s) ? 'Null' : s.constructor.name
106
- : caseMap[t[0]] + t.slice(1);
106
+ ? isNull(s) ? 'Null' : (s.constructor?.name || cap_type(t))
107
+ : cap_type(t);
107
108
  };
108
109
  const typeIs = curry2((t, s) => type(s) === t);
109
110
  const eq = curry2((a, b) => a === b);
@@ -193,32 +194,46 @@ const qmapKeys = curry2((keyMap, o) => {
193
194
  return o;
194
195
  });
195
196
  // FIXME: qmap(any, tags) -> some function!!!
197
+ /**
198
+ * @param pipe (v, i, list: T[]) -> T.
199
+ * @param data T[].
200
+ * @returns T[].
201
+ */
196
202
  const qmap = curry2((pipe, arr) => {
197
203
  for (const i in arr)
198
204
  arr[i] = pipe(arr[i], +i, arr);
199
205
  return arr;
200
206
  });
207
+ /**
208
+ * @param cond (v, k) -> boolean.
209
+ * @param data T extends AnyObject.
210
+ * @returns T
211
+ */
201
212
  const qmapObj = curry2((pipe, o) => {
202
213
  for (const k in o)
203
214
  o[k] = pipe(o[k], k, o);
204
215
  return o;
205
216
  });
217
+ /**
218
+ * @param cond (v, k) -> boolean.
219
+ * @param data T extends any[] | AnyObject.
220
+ * @returns T
221
+ */
206
222
  const qfilter = curry2((cond, data) => {
207
- const isArr = isArray(data);
208
- let indicies_offset, indicies2rm;
209
- if (isArr) {
210
- indicies_offset = 0;
211
- indicies2rm = [];
223
+ if (isArray(data)) {
224
+ let indicies_offset = 0;
225
+ const indicies2rm = [];
226
+ const len = length(data);
227
+ for (let i = 0; i < len; i++)
228
+ if (!cond(data[i], i))
229
+ indicies2rm.push(i);
230
+ for (const i of indicies2rm)
231
+ data.splice(i - indicies_offset++, 1);
212
232
  }
213
- for (let k in data)
214
- if (!cond(data[k], k)) // @ts-ignore
215
- if (isArr)
216
- indicies2rm.push(+k);
217
- else
233
+ else
234
+ for (const k in data)
235
+ if (!cond(data[k], k))
218
236
  delete data[k];
219
- if (isArr) // @ts-ignore
220
- for (const i of indicies2rm) // @ts-ignore
221
- data.splice(i - indicies_offset++, 1);
222
237
  return data;
223
238
  });
224
239
  const qempty = (o) => {
@@ -252,7 +267,7 @@ const qomit = curry2((props, o) => qfilter((_, k) => !includes(k, props), o));
252
267
  /** @param prop string @param pipe (data[prop]): prop_value @param data any
253
268
  * @returns data with prop over pipe. */
254
269
  const qoverProp = curry3((prop, pipe, data) => qassoc(prop, pipe(data[prop]), data));
255
- /** Slower than pick() (dictionary mode) !
270
+ /** Slower than pick() (dictionary mode) ! it's okay when the object is already in the dic mode !
256
271
  * @param props (string|number)[]
257
272
  * @param o AnyObject
258
273
  * @returns AnyObject
@@ -625,6 +640,13 @@ const forEachSerial = (() => {
625
640
  })();
626
641
  /** Promise.all wrapper for functional pipelining. */
627
642
  const waitAll = (promises) => Promise.all(promises);
643
+ const qwaitAll = async (xs) => new Promise((ff, rj) => {
644
+ const len = length(xs);
645
+ let j = len;
646
+ for (let i = 0; i < len; i++)
647
+ xs[i].then((x) => { xs[i] = x; if (--j)
648
+ ff(xs); }).catch(rj);
649
+ });
628
650
  /** Waits for a Promise that been generated by the first arg, then returns an untoched value. Types T.
629
651
  * @param {AnyFunc<Promise>} fn - function to wait.
630
652
  * @param {T} s - any value to tap and return back
@@ -638,6 +660,29 @@ const composeAsync = (() => {
638
660
  const pipe = async (fns, input, i) => ~i ? await pipe(fns, [await fns[i](...input)], --i) : head(input);
639
661
  return (...fns) => (...input) => pipe(fns, input, fns.length - 1);
640
662
  })();
663
+ /**
664
+ * @param cond async (v, k) -> boolean.
665
+ * @param data T extends any[] | AnyObject.
666
+ * @returns T
667
+ */
668
+ const qfilterAsync = curry2(async (cond, data // dunno how to merge it with sync version...
669
+ ) => {
670
+ if (isArray(data)) {
671
+ let indicies_offset = 0;
672
+ const indicies2rm = [];
673
+ const len = length(data);
674
+ for (let i = 0; i < len; i++)
675
+ if (!await cond(data[i], i))
676
+ indicies2rm.push(i);
677
+ for (const i of indicies2rm)
678
+ data.splice(i - indicies_offset++, 1);
679
+ }
680
+ else
681
+ for (const k in data)
682
+ if (!await cond(data[k], k))
683
+ delete data[k];
684
+ return data;
685
+ });
641
686
 
642
687
  const ecran = '\\';
643
688
  // TODO: make it splicy, not accumulatie by symbols.
@@ -723,4 +768,4 @@ const wait = (time) => new Promise((ff) => setTimeout(ff, time));
723
768
  // TODO: possibly introduce a second argument limiting unfolding.
724
769
  const uncurry = (fn) => (...args) => qreduce(((fn, arg) => fn ? fn(arg) : fn), fn, args);
725
770
 
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 };
771
+ 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, qfilterAsync, qfreeze, qfreezeShallow, qmap, qmapKeys, qmapObj, qmergeDeep, qmergeDeepAdd, qmergeDeepX, qmergeShallow, qomit, qoverProp, qpick, qprepend, qpush, qreduce, qreverse, qslice, qsort, quniq, qwaitAll, 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,15 +41,15 @@
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.7.0",
44
+ "version": "1.8.1",
45
45
  "devDependencies": {
46
- "@rollup/plugin-commonjs": "^29.0.0",
46
+ "@rollup/plugin-commonjs": "^29.0.2",
47
47
  "@rollup/plugin-node-resolve": "^16.0.3",
48
48
  "@rollup/plugin-replace": "^6.0.3",
49
- "@types/node": "^25.0.3",
49
+ "@types/node": "^25.5.0",
50
50
  "cross-env": "^10.1.0",
51
51
  "dts-bundle-generator": "^9.5.1",
52
- "rollup": "^4.54.0",
52
+ "rollup": "^4.59.0",
53
53
  "rollup-plugin-typescript2": "^0.36.0",
54
54
  "ts-node": "^10.9.2",
55
55
  "tslint": "^6.1.3",
package/src/async.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { curry2 } from "./curry"
2
- import { head } from "./safe"
3
- import { AnyFunc, Composed } from "./types"
2
+ import { head, length } from "./safe"
3
+ import { AnyFunc, AnyObject, Composed } from "./types"
4
+ import { isArray } from "./utils"
4
5
 
5
6
  /** One promise waits for another. */
6
7
  export const forEachSerial = (() => {
@@ -16,6 +17,10 @@ export const forEachSerial = (() => {
16
17
  })()
17
18
  /** Promise.all wrapper for functional pipelining. */
18
19
  export const waitAll = <T>(promises: Promise<T>[]) => Promise.all<T>(promises)
20
+ export const qwaitAll = async <T>(xs: Promise<T>[]) => new Promise<T[]>((ff, rj) => {
21
+ const len = length(xs); let j = len
22
+ for(let i=0; i<len; i++) xs[i].then((x: T) => {xs[i]=x as any; if(--j) ff(xs as any)}).catch(rj)
23
+ })
19
24
  /** Waits for a Promise that been generated by the first arg, then returns an untoched value. Types T.
20
25
  * @param {AnyFunc<Promise>} fn - function to wait.
21
26
  * @param {T} s - any value to tap and return back
@@ -32,4 +37,26 @@ export const composeAsync = (() => {
32
37
  ~i ? await pipe(fns, [await fns[i](...input)], --i) : head(input)
33
38
  return <TIn extends any[] = any[], TOut = any>(...fns: AnyFunc[]): Composed<TIn, Promise<TOut>> =>
34
39
  (...input: any[]) => pipe(fns, input, fns.length-1)
35
- })()
40
+ })()
41
+ /**
42
+ * @param cond async (v, k) -> boolean.
43
+ * @param data T extends any[] | AnyObject.
44
+ * @returns T
45
+ */
46
+ export const qfilterAsync = curry2(async <T extends any[] | AnyObject>(
47
+ cond: (v: any, k: string | number) => Promise<boolean> | boolean,
48
+ data: T // dunno how to merge it with sync version...
49
+ ): Promise<T> => {
50
+ if(isArray(data)) {
51
+ let indicies_offset = 0
52
+ const indicies2rm: number[] = []
53
+ const len = length(data as any[])
54
+ for(let i = 0; i<len; i++)
55
+ if(!await cond(data[i], i))
56
+ indicies2rm.push(i)
57
+ for(const i of indicies2rm)
58
+ data.splice(i - indicies_offset++, 1)
59
+ } else for(const k in data)
60
+ if(!await cond(data[k], k)) delete data[k]
61
+ return data
62
+ })
package/src/common.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { curry2 } from "./curry"
2
2
  import { is_typed_arr } from "./internal"
3
- import { to, isNull, isStr } from "./utils"
3
+ import { isNull, isStr, to } from "./utils"
4
4
 
5
5
  // It's faster that toUpperCase() !
6
6
  const caseMap = { u: 'U', b: 'B', n: 'N', s: 'S', f: 'F' }
@@ -8,11 +8,12 @@ const caseMap = { u: 'U', b: 'B', n: 'N', s: 'S', f: 'F' }
8
8
  export const symbol = Symbol()
9
9
  export const toLower = (s: string) => s.toLowerCase()
10
10
  export const toUpper = (s: string) => s.toUpperCase()
11
+ const cap_type = (t: string) => caseMap[t[0]] + t.slice(1)
11
12
  export const type = (s: any): string => {
12
13
  const t = to(s)
13
14
  return t==='object'
14
- ? isNull(s) ? 'Null' : s.constructor.name
15
- : caseMap[t[0]] + t.slice(1)
15
+ ? isNull(s) ? 'Null' : (s.constructor?.name||cap_type(t))
16
+ : cap_type(t)
16
17
  }
17
18
  export const typeIs = curry2((t: string, s: any) => type(s)===t)
18
19
 
@@ -41,4 +42,5 @@ export const includes = curry2(
41
42
  }
42
43
  }
43
44
  )
44
- export {length} from './internal'
45
+ export { length } from './internal'
46
+
package/src/quick.ts CHANGED
@@ -63,39 +63,51 @@ export const qmapKeys = curry2(
63
63
  }
64
64
  )
65
65
  // FIXME: qmap(any, tags) -> some function!!!
66
+ /**
67
+ * @param pipe (v, i, list: T[]) -> T.
68
+ * @param data T[].
69
+ * @returns T[].
70
+ */
66
71
  export const qmap = curry2(
67
- (pipe: (s: any, i?: number, list?: any[]) => any, arr: any[]) => {
72
+ <T extends any[]|AnyObject>(pipe: (s: any, i?: number, list?: T) => T[Extract<keyof T, string>], arr: T) => {
68
73
  for(const i in arr) arr[i] = pipe(arr[i], +i, arr)
69
74
  return arr
70
75
  }
71
76
  )
77
+ /**
78
+ * @param cond (v, k) -> boolean.
79
+ * @param data T extends AnyObject.
80
+ * @returns T
81
+ */
72
82
  export const qmapObj = curry2(
73
83
  (pipe: (s: any, k?: string, o?: AnyObject) => any, o: AnyObject) => {
74
84
  for(const k in o) o[k] = pipe(o[k], k, o)
75
85
  return o
76
86
  }
77
87
  )
88
+ /**
89
+ * @param cond (v, k) -> boolean.
90
+ * @param data T extends any[] | AnyObject.
91
+ * @returns T
92
+ */
78
93
  export const qfilter = curry2(
79
- <T extends any[] | AnyObject>(
80
- cond: (v: any, k: string | number) => boolean,
81
- data: T
82
- ): T => {
83
- const isArr = isArray(data)
84
- let indicies_offset: number, indicies2rm: number[]
85
- if(isArr) {
86
- indicies_offset = 0
87
- indicies2rm = []
88
- }
89
- for(let k in data)
90
- if(!cond(data[k], k)) // @ts-ignore
91
- if(isArr) indicies2rm.push(+k)
92
- else delete data[k]
93
- if(isArr)// @ts-ignore
94
- for(const i of indicies2rm) // @ts-ignore
95
- data.splice(i - indicies_offset++, 1)
96
- return data
97
- }
98
- )
94
+ <T extends any[] | AnyObject>(
95
+ cond: (v: any, k: string | number) => boolean,
96
+ data: T
97
+ ): T => {
98
+ if(isArray(data)) {
99
+ let indicies_offset = 0
100
+ const indicies2rm: number[] = []
101
+ const len = length(data as any[])
102
+ for(let i = 0; i<len; i++)
103
+ if(!cond(data[i], i))
104
+ indicies2rm.push(i)
105
+ for(const i of indicies2rm)
106
+ data.splice(i - indicies_offset++, 1)
107
+ } else for(const k in data)
108
+ if(!cond(data[k], k)) delete data[k]
109
+ return data
110
+ })
99
111
  export const qempty = <T extends AnyObject|any[]>(o: T): T extends any[] ? [] : {} => {
100
112
  if(isArray(o)) o.splice(0)
101
113
  else for(const i in o) delete o[i]
@@ -132,7 +144,7 @@ export const qomit = curry2(
132
144
  export const qoverProp = curry3(
133
145
  (prop: string, pipe: AnyFunc, data: any) => qassoc(prop, pipe(data[prop]), data)
134
146
  )
135
- /** Slower than pick() (dictionary mode) !
147
+ /** Slower than pick() (dictionary mode) ! it's okay when the object is already in the dic mode !
136
148
  * @param props (string|number)[]
137
149
  * @param o AnyObject
138
150
  * @returns AnyObject