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 +63 -16
- package/dist/bundle.d.ts +32 -5
- package/dist/bundle.mjs +62 -17
- package/package.json +4 -4
- package/src/async.ts +30 -3
- package/src/common.ts +6 -4
- package/src/quick.ts +34 -22
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
|
|
108
|
-
:
|
|
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
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
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
|
-
|
|
216
|
-
|
|
217
|
-
if (
|
|
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
|
|
106
|
-
:
|
|
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
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
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
|
-
|
|
214
|
-
|
|
215
|
-
if (
|
|
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.
|
|
44
|
+
"version": "1.8.1",
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@rollup/plugin-commonjs": "^29.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
|
|
49
|
+
"@types/node": "^25.5.0",
|
|
50
50
|
"cross-env": "^10.1.0",
|
|
51
51
|
"dts-bundle-generator": "^9.5.1",
|
|
52
|
-
"rollup": "^4.
|
|
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 {
|
|
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
|
|
15
|
-
:
|
|
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?:
|
|
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
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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
|