pepka 1.3.0 → 1.3.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 +713 -1
- package/dist/bundle.d.ts +1 -1
- package/dist/bundle.mjs +567 -1
- package/package.json +3 -4
- package/rollup.config.js +2 -2
package/dist/bundle.cjs
CHANGED
|
@@ -1 +1,713 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const __ = Symbol('Placeholder');
|
|
4
|
+
const countArgs = (s) => {
|
|
5
|
+
let i = 0;
|
|
6
|
+
for (const v of s)
|
|
7
|
+
v !== __ && i++;
|
|
8
|
+
return i;
|
|
9
|
+
};
|
|
10
|
+
// TODO: try to make it mutable.
|
|
11
|
+
// { 0: __, 1: 10 }, [ 11 ]
|
|
12
|
+
const addArgs = (args, _args) => {
|
|
13
|
+
const len = args.length;
|
|
14
|
+
const new_args = args.slice();
|
|
15
|
+
const _args_len = _args.length;
|
|
16
|
+
let _args_left = _args_len;
|
|
17
|
+
let i = 0;
|
|
18
|
+
for (; _args_left && i < len; i++) {
|
|
19
|
+
if (new_args[i] === __) {
|
|
20
|
+
new_args[i] = _args[_args_len - _args_left];
|
|
21
|
+
_args_left--;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
for (i = len; _args_left; i++, _args_left--) {
|
|
25
|
+
new_args[i] = _args[_args_len - _args_left];
|
|
26
|
+
}
|
|
27
|
+
return new_args;
|
|
28
|
+
};
|
|
29
|
+
const _curry = (fn, args, new_args) => {
|
|
30
|
+
const args2add = fn.length - args.length - countArgs(new_args);
|
|
31
|
+
if (args2add < 1) {
|
|
32
|
+
return fn(...addArgs(args, new_args));
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
const curried = (...__args) => _curry(fn, addArgs(args, new_args), __args);
|
|
36
|
+
curried.$args_left = args2add;
|
|
37
|
+
return curried;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
const curry = (fn) => ((...args) => fn.length > countArgs(args)
|
|
41
|
+
? _curry(fn, [], args)
|
|
42
|
+
: fn(...args));
|
|
43
|
+
const endlessph = (fn) => {
|
|
44
|
+
function _endlessph(a) {
|
|
45
|
+
return a === __ ? fn : fn(a);
|
|
46
|
+
}
|
|
47
|
+
return _endlessph;
|
|
48
|
+
};
|
|
49
|
+
function curry2(fn) {
|
|
50
|
+
function curried2(a, b) {
|
|
51
|
+
const withPlaceholder1 = a === __;
|
|
52
|
+
const aln = arguments.length;
|
|
53
|
+
if (aln === 1 && withPlaceholder1)
|
|
54
|
+
throw new Error('Senseless placeholder usage.');
|
|
55
|
+
return aln > 1
|
|
56
|
+
? withPlaceholder1
|
|
57
|
+
? endlessph((a) => fn(a, b))
|
|
58
|
+
: fn(a, b)
|
|
59
|
+
: (b) => fn(a, b);
|
|
60
|
+
}
|
|
61
|
+
return curried2;
|
|
62
|
+
}
|
|
63
|
+
function curry3(fn) {
|
|
64
|
+
// type p0 = Parameters<Func>[0]
|
|
65
|
+
// type p1 = Parameters<Func>[1]
|
|
66
|
+
// type p2 = Parameters<Func>[2]
|
|
67
|
+
// type ReturnT = ReturnType<Func>
|
|
68
|
+
// TODO: optimize.
|
|
69
|
+
// Cannot use ts-toolbelt due to this error:
|
|
70
|
+
// Excessive stack depth comparing types 'GapsOf<?, L2>' and 'GapsOf<?, L2>'
|
|
71
|
+
return curry(fn);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const undef = undefined;
|
|
75
|
+
const nul = null;
|
|
76
|
+
const inf = Infinity;
|
|
77
|
+
const to = (s) => typeof s;
|
|
78
|
+
const isNull = (s) => s === nul;
|
|
79
|
+
const isUndef = (s) => s === undef;
|
|
80
|
+
const isNum = (s) => to(s) == 'number';
|
|
81
|
+
const isArray = (s) => Array.isArray(s);
|
|
82
|
+
const isFunc = (s) => to(s) === 'function';
|
|
83
|
+
const isStr = (s) => to(s) === 'string';
|
|
84
|
+
const isObj = (s) => !isNull(s) && to(s) === 'object';
|
|
85
|
+
|
|
86
|
+
// It's faster that toUpperCase() !
|
|
87
|
+
const caseMap = { u: 'U', b: 'B', n: 'N', s: 'S', f: 'F' };
|
|
88
|
+
const symbol = Symbol();
|
|
89
|
+
const toLower = (s) => s.toLowerCase();
|
|
90
|
+
const toUpper = (s) => s.toUpperCase();
|
|
91
|
+
const type = (s) => {
|
|
92
|
+
const t = to(s);
|
|
93
|
+
return t === 'object'
|
|
94
|
+
? isNull(s) ? 'Null' : s.constructor.name
|
|
95
|
+
: caseMap[t[0]] + t.slice(1);
|
|
96
|
+
};
|
|
97
|
+
const typeIs = curry2((t, s) => type(s) === t);
|
|
98
|
+
const length = (s) => s.length;
|
|
99
|
+
const isNil = (s) => isNull(s) || isUndef(s);
|
|
100
|
+
const eq = curry2((a, b) => a === b);
|
|
101
|
+
const equals = curry2((a, b) => {
|
|
102
|
+
const typea = type(a);
|
|
103
|
+
if (eq(typea, type(b)) && (eq(typea, 'Object') || eq(typea, 'Array'))) {
|
|
104
|
+
if (isNull(a) || isNull(b))
|
|
105
|
+
return eq(a, b);
|
|
106
|
+
if (eq(a, b))
|
|
107
|
+
return true;
|
|
108
|
+
for (const v of [a, b])
|
|
109
|
+
for (const k in v)
|
|
110
|
+
if (!((eq(v, b)) && (k in a)) &&
|
|
111
|
+
!((eq(v, a)) && (k in b) && equals(a[k], b[k])))
|
|
112
|
+
return false;
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
return eq(a, b);
|
|
116
|
+
});
|
|
117
|
+
const includes = curry2((s, ss) => {
|
|
118
|
+
if (isStr(ss))
|
|
119
|
+
return ss.includes(s);
|
|
120
|
+
else {
|
|
121
|
+
for (const a of ss)
|
|
122
|
+
if (equals(a, s))
|
|
123
|
+
return true;
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
/** @param start string | any[] @param s string | any[] */
|
|
128
|
+
const qstartsWithWith = (comparator) => curry2((start, s) => {
|
|
129
|
+
const len_start = length(start);
|
|
130
|
+
const len_s = length(s);
|
|
131
|
+
if (len_start > len_s)
|
|
132
|
+
return false;
|
|
133
|
+
for (let i = 0; i < len_start; i++)
|
|
134
|
+
if (!comparator(s[i], start[i]))
|
|
135
|
+
return false;
|
|
136
|
+
return true;
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
// TODO: qflat, qoverProp, qover array ?
|
|
140
|
+
const qappend = curry2((s, xs) => { xs.push(s); return xs; });
|
|
141
|
+
const qassoc = curry3((prop, v, obj) => { obj[prop] = v; return obj; });
|
|
142
|
+
const qreduce = curry3((fn, accum, arr) => arr.reduce(fn, accum));
|
|
143
|
+
// strategy is for arrays: 1->clean, 2->merge, 3->push.
|
|
144
|
+
const mergeDeep$1 = curry3((strategy, o1, o2) => {
|
|
145
|
+
for (let k in o2) {
|
|
146
|
+
switch (type(o2[k])) {
|
|
147
|
+
case 'Array':
|
|
148
|
+
if (strategy > 1 && type(o1[k]) === 'Array')
|
|
149
|
+
switch (strategy) {
|
|
150
|
+
case 2:
|
|
151
|
+
const o1k = o1[k], o2k = o2[k];
|
|
152
|
+
for (const i in o2k)
|
|
153
|
+
if (o1k[i])
|
|
154
|
+
mergeDeep$1(strategy, o1k[i], o2k[i]);
|
|
155
|
+
else
|
|
156
|
+
o1k[i] = o2k[i];
|
|
157
|
+
break;
|
|
158
|
+
case 3: o1[k].push(...o2[k]);
|
|
159
|
+
}
|
|
160
|
+
else
|
|
161
|
+
o1[k] = o2[k];
|
|
162
|
+
break;
|
|
163
|
+
case 'Object':
|
|
164
|
+
if (type(o1[k]) === 'Object') {
|
|
165
|
+
mergeDeep$1(strategy, o1[k], o2[k]);
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
default:
|
|
169
|
+
o1[k] = o2[k];
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return o1;
|
|
174
|
+
});
|
|
175
|
+
const qmergeDeep = mergeDeep$1(1);
|
|
176
|
+
const qmergeDeepX = mergeDeep$1(2);
|
|
177
|
+
const qmergeDeepAdd = mergeDeep$1(3);
|
|
178
|
+
const qmergeShallow = curry2((o1, o2) => Object.assign(o1, o2));
|
|
179
|
+
/** qmapKeys({ a: 'b' }, { a: 44 }) -> { b: 44 } */
|
|
180
|
+
const qmapKeys = curry2((keyMap, o) => {
|
|
181
|
+
let k, mapped, newKey, newValue;
|
|
182
|
+
for (k in keyMap)
|
|
183
|
+
if (k in o) {
|
|
184
|
+
mapped = keyMap[k];
|
|
185
|
+
[newKey, newValue] = isFunc(mapped)
|
|
186
|
+
? mapped(o[k], k, o)
|
|
187
|
+
: [mapped, o[k]];
|
|
188
|
+
o[isNil(newKey) ? k : newKey] = newValue;
|
|
189
|
+
if (k !== newKey)
|
|
190
|
+
delete o[k];
|
|
191
|
+
}
|
|
192
|
+
return o;
|
|
193
|
+
});
|
|
194
|
+
const qmap = curry2((pipe, arr) => {
|
|
195
|
+
for (let i in arr)
|
|
196
|
+
arr[i] = pipe(arr[i], +i, arr);
|
|
197
|
+
return arr;
|
|
198
|
+
});
|
|
199
|
+
const qmapObj = curry2((pipe, o) => qmap(pipe, o));
|
|
200
|
+
const qfilter = curry2((cond, data) => {
|
|
201
|
+
const isArr = isArray(data);
|
|
202
|
+
let indicies_offset, indicies2rm;
|
|
203
|
+
if (isArr) {
|
|
204
|
+
indicies_offset = 0;
|
|
205
|
+
indicies2rm = [];
|
|
206
|
+
}
|
|
207
|
+
for (let k in data)
|
|
208
|
+
if (!cond(data[k], k)) // @ts-ignore
|
|
209
|
+
if (isArr)
|
|
210
|
+
indicies2rm.push(+k);
|
|
211
|
+
else
|
|
212
|
+
delete data[k];
|
|
213
|
+
if (isArr) // @ts-ignore
|
|
214
|
+
for (const i of indicies2rm) // @ts-ignore
|
|
215
|
+
data.splice(i - indicies_offset++, 1);
|
|
216
|
+
return data;
|
|
217
|
+
});
|
|
218
|
+
const qempty = (o) => {
|
|
219
|
+
if (isArray(o))
|
|
220
|
+
o.splice(0);
|
|
221
|
+
else
|
|
222
|
+
for (const i in o)
|
|
223
|
+
delete o[i];
|
|
224
|
+
return o;
|
|
225
|
+
};
|
|
226
|
+
const qfreeze = (o) => {
|
|
227
|
+
let v;
|
|
228
|
+
for (const k in o) {
|
|
229
|
+
v = o[k];
|
|
230
|
+
if (isObj(v))
|
|
231
|
+
qfreeze(v);
|
|
232
|
+
}
|
|
233
|
+
return Object.freeze(o);
|
|
234
|
+
};
|
|
235
|
+
const qfreezeShallow = (o) => Object.freeze(o);
|
|
236
|
+
const qprepend = curry2((x, xs) => xs.unshift(x));
|
|
237
|
+
const qassocPath = curry3((_path, v, o) => {
|
|
238
|
+
const first = _path[0];
|
|
239
|
+
return qassoc(first, _path.length < 2
|
|
240
|
+
? v
|
|
241
|
+
: qassocPath(_path.slice(1), v, isObj(o[first]) ? o[first] : {}), o);
|
|
242
|
+
});
|
|
243
|
+
const qreverse = (arr) => arr.reverse();
|
|
244
|
+
const qomit = curry2((props, o) => qfilter((_, k) => !includes(k, props), o));
|
|
245
|
+
/** @param start string | any[] @param s string | any[] */
|
|
246
|
+
const qstartsWith = qstartsWithWith(eq);
|
|
247
|
+
|
|
248
|
+
// TODO: possibly introduce a second argument limiting unfolding.
|
|
249
|
+
const uncurry = (fn) => (...args) => qreduce(((fn, arg) => fn ? fn(arg) : fn), fn, args);
|
|
250
|
+
|
|
251
|
+
// over, lensProp
|
|
252
|
+
const take = (argN) => (...args) => args[argN];
|
|
253
|
+
const weakEq = curry2((a, b) => a == b);
|
|
254
|
+
const ifElse = curry((cond, pipeYes, pipeNo, s) => cond(s) ? pipeYes(s) : pipeNo(s));
|
|
255
|
+
const when = curry3((cond, pipe, s) => ifElse(cond, pipe, identity, s));
|
|
256
|
+
const compose = ((...fns) => (...args) => {
|
|
257
|
+
let first = true;
|
|
258
|
+
let s;
|
|
259
|
+
for (let i = length(fns) - 1; i > -1; i--) {
|
|
260
|
+
if (first) {
|
|
261
|
+
first = false;
|
|
262
|
+
s = fns[i](...args);
|
|
263
|
+
}
|
|
264
|
+
else
|
|
265
|
+
s = s === __ ? fns[i]() : fns[i](s);
|
|
266
|
+
}
|
|
267
|
+
return s;
|
|
268
|
+
});
|
|
269
|
+
const bind = curry2((fn, context) => fn.bind(context));
|
|
270
|
+
const nth = curry2((i, data) => data[i]);
|
|
271
|
+
const slice = curry3((from, to, o) => o.slice(from, (isNum(to) ? to : inf)));
|
|
272
|
+
const flip = (fn) => curry2((b, a) => fn(a, b));
|
|
273
|
+
/** @returns first element of an array. */
|
|
274
|
+
const head = nth(0);
|
|
275
|
+
/** @returns last element of an array. */
|
|
276
|
+
const tail = slice(1, inf);
|
|
277
|
+
/** @param a @param b @returns a+b */
|
|
278
|
+
const add = curry2((a, b) => a + b);
|
|
279
|
+
/** @param a @param b @returns b-a */
|
|
280
|
+
const subtract = curry2((a, b) => b - a);
|
|
281
|
+
/**@param a @param b @returns a*b */
|
|
282
|
+
const multiply = curry2((a, b) => a * b);
|
|
283
|
+
/** @param a @param b @returns a<b */
|
|
284
|
+
const gt = curry2((a, b) => a < b);
|
|
285
|
+
/** @param a @param b @returns a>b */
|
|
286
|
+
const lt = curry2((a, b) => a > b);
|
|
287
|
+
/** @param a @param b @returns a<=b */
|
|
288
|
+
const gte = curry2((a, b) => a <= b);
|
|
289
|
+
/** @param a @param b @returns a>=b */
|
|
290
|
+
const lte = curry2((a, b) => a >= b);
|
|
291
|
+
const sort = curry2((sortFn, xs) => xs.sort(sortFn));
|
|
292
|
+
const find = curry2((fn, s) => s.find(fn));
|
|
293
|
+
const findIndex = curry2((fn, s) => s.findIndex(fn));
|
|
294
|
+
const indexOf = curry2((x, xs) => findIndex(equals(x), xs));
|
|
295
|
+
const divide = curry2((n, m) => n / m);
|
|
296
|
+
const always = (s) => () => s;
|
|
297
|
+
const identity = (s) => s;
|
|
298
|
+
const trim = (s) => s.trim();
|
|
299
|
+
const last = (s) => s[length(s) - 1];
|
|
300
|
+
/** @param start string | any[] @param s string | any[] */
|
|
301
|
+
const startsWith = qstartsWithWith((x, y) => equals(x, y));
|
|
302
|
+
const not = (x) => !x;
|
|
303
|
+
const keys = (o) => Object.keys(o);
|
|
304
|
+
const values = (o) => Object.values(o);
|
|
305
|
+
const toPairs = (o) => Object.entries(o);
|
|
306
|
+
const test = curry2((re, s) => re.test(s));
|
|
307
|
+
const tap = curry2((fn, x) => { fn(x); return x; });
|
|
308
|
+
const append = curry2((x, xs) => [...xs, x]);
|
|
309
|
+
const prepend = curry2((x, xs) => [...xs, x]);
|
|
310
|
+
const flat = (xs) => xs.flat(inf);
|
|
311
|
+
const flatShallow = (xs) => xs.flat();
|
|
312
|
+
const flatTo = curry2((depth, xs) => xs.flat(depth));
|
|
313
|
+
const split = curry2((s, xs) => xs.split(s));
|
|
314
|
+
const T = always(true);
|
|
315
|
+
const F = always(false);
|
|
316
|
+
const callWith = curry2((args, fn) => fn(...args));
|
|
317
|
+
const noop = (() => { });
|
|
318
|
+
/** Calls a func from object.
|
|
319
|
+
* @param {any[]} [args] - arguments for the function.
|
|
320
|
+
* @param {string} [fnName] - property name of the function.
|
|
321
|
+
* @param {AnyObject} [o] - the object with the function. */
|
|
322
|
+
const callFrom = curry((args, fn, o) => o[fn](...args));
|
|
323
|
+
const complement = (fn) => (...args) => {
|
|
324
|
+
const out = fn(...args);
|
|
325
|
+
const f = isFunc(out);
|
|
326
|
+
return !f || f && out.$args_left <= 0 ? not(out) : complement(out);
|
|
327
|
+
};
|
|
328
|
+
const sizeof = (s) => {
|
|
329
|
+
if (type(s) === 'Object') {
|
|
330
|
+
let len = 0;
|
|
331
|
+
for (let _k in s)
|
|
332
|
+
len++;
|
|
333
|
+
return len;
|
|
334
|
+
}
|
|
335
|
+
else
|
|
336
|
+
return length(s);
|
|
337
|
+
};
|
|
338
|
+
const range = curry2((from, to) => genBy(add(from), to - from));
|
|
339
|
+
/** @param xs any[] @returns xs without duplicates. */
|
|
340
|
+
const uniq = (xs) => qreduce((accum, x) => find(equals(x), accum) ? accum : qappend(x, accum), [], xs);
|
|
341
|
+
const intersection = curry2((xs1, xs2) => xs1.filter(flip(includes)(xs2)));
|
|
342
|
+
const genBy = curry2((generator, length) => [...Array(length)].map((_, i) => generator(i)));
|
|
343
|
+
const once = (fn) => {
|
|
344
|
+
let done = false, cache;
|
|
345
|
+
return (...args) => {
|
|
346
|
+
if (done)
|
|
347
|
+
return cache;
|
|
348
|
+
done = true;
|
|
349
|
+
return cache = fn(...args);
|
|
350
|
+
};
|
|
351
|
+
};
|
|
352
|
+
const reverse = (xs) => compose((ln) => reduce((nxs, _, i) => qappend(xs[ln - i], nxs), [], xs), add(-1), length)(xs);
|
|
353
|
+
const explore = (caption, level = 'log') => tap((v) => console[level](caption, v));
|
|
354
|
+
const cond = curry2((pairs, s) => {
|
|
355
|
+
for (const [cond, fn] of pairs)
|
|
356
|
+
if (cond(s))
|
|
357
|
+
return fn(s);
|
|
358
|
+
});
|
|
359
|
+
/** Assigns a prop to an object.
|
|
360
|
+
* @param prop string
|
|
361
|
+
* @param value any
|
|
362
|
+
* @param object AnyObject
|
|
363
|
+
*/
|
|
364
|
+
const assoc = curry3((prop, v, obj) => ({ ...obj, [prop]: v }));
|
|
365
|
+
const assocPath = curry3((_path, v, o) => compose((first) => assoc(first, length(_path) < 2
|
|
366
|
+
? v
|
|
367
|
+
: assocPath(slice(1, inf, _path), v, isObj(o[first]) ? o[first] : {}), o), head)(_path));
|
|
368
|
+
const all = curry2((pred, xs) => xs.every(pred));
|
|
369
|
+
const any = curry2((pred, xs) => xs.some(pred));
|
|
370
|
+
const allPass = curry2((preds, x) => preds.every((pred) => pred(x)));
|
|
371
|
+
const anyPass = curry2((preds, x) => preds.some((pred) => pred(x)));
|
|
372
|
+
/** @param key string @param o AnyObject @returns o[key] */
|
|
373
|
+
const prop = curry2((key, o) => o[key]);
|
|
374
|
+
/** @param key string @param value any @param o AnyObject @returns o[key] equals value */
|
|
375
|
+
const propEq = curry3((key, value, o) => equals(o[key], value));
|
|
376
|
+
/** @param key string @param o1 AnyObject @param o2 AnyObject @returns o₁[key] equals o₂[key] */
|
|
377
|
+
const propsEq = curry3((key, o1, o2) => equals(o1[key], o2[key]));
|
|
378
|
+
const pathOr = curry3((_default, path, o) => length(path)
|
|
379
|
+
? isNil(o)
|
|
380
|
+
? _default
|
|
381
|
+
: compose((k) => k in o ? pathOr(_default, slice(1, inf, path), o[k]) : _default, head)(path)
|
|
382
|
+
: o);
|
|
383
|
+
const path = pathOr(undef);
|
|
384
|
+
const pathEq = curry3((_path, value, o) => equals(path(_path, o), value));
|
|
385
|
+
const pathsEq = curry3((_path, o1, o2) => equals(path(_path, o1), path(_path, o2)));
|
|
386
|
+
const pathExists = compose(ifElse(equals(symbol), F, T), pathOr(symbol));
|
|
387
|
+
const typed_arr_re = /^(.*?)(8|16|32|64)(Clamped)?Array$/;
|
|
388
|
+
const clone = (s, shallow = false) => {
|
|
389
|
+
const t = type(s);
|
|
390
|
+
switch (t) {
|
|
391
|
+
case 'Null': return s;
|
|
392
|
+
case 'Array': return shallow ? [...s] : map(compose(clone, take(0)), s);
|
|
393
|
+
case 'Object':
|
|
394
|
+
if (shallow)
|
|
395
|
+
return { ...s };
|
|
396
|
+
const out = {};
|
|
397
|
+
for (let k in s)
|
|
398
|
+
out[k] = clone(s[k]);
|
|
399
|
+
return out;
|
|
400
|
+
case 'String':
|
|
401
|
+
case 'Number':
|
|
402
|
+
case 'Boolean':
|
|
403
|
+
case 'Symbol':
|
|
404
|
+
return s;
|
|
405
|
+
default:
|
|
406
|
+
return typed_arr_re.test(t) ? s.constructor.from(s) : s;
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
const cloneShallow = (s) => clone(s, true);
|
|
410
|
+
const freeze = (o) => qfreeze(clone(o));
|
|
411
|
+
const freezeShallow = (o) => qfreezeShallow(clone(o));
|
|
412
|
+
/** types T1, T2
|
|
413
|
+
* @param reducer (accum: T1, current: T2, index: number) => newAccum: T1
|
|
414
|
+
* @param accum T1
|
|
415
|
+
* @param array T2[]
|
|
416
|
+
*/
|
|
417
|
+
const reduce = curry3((reducer, accum, arr) => qreduce(reducer, clone(accum), arr));
|
|
418
|
+
const pickBy = curry2((cond, o) => filter(cond, o));
|
|
419
|
+
const pick = curry2((props, o) => {
|
|
420
|
+
const out = {};
|
|
421
|
+
for (const p of props)
|
|
422
|
+
if (p in o)
|
|
423
|
+
out[p] = o[p];
|
|
424
|
+
return out;
|
|
425
|
+
});
|
|
426
|
+
const omit = curry2((props, o) => filter((_, k) => !includes(k, props), o));
|
|
427
|
+
const fromPairs = (pairs) => Object.fromEntries(pairs);
|
|
428
|
+
const concat = curry2(((a, b) => b.concat(a)));
|
|
429
|
+
const map = curry2((pipe, arr) => arr.map(pipe));
|
|
430
|
+
const mapObj = curry2((pipe, o) => qmapObj(pipe, cloneShallow(o)));
|
|
431
|
+
const join = curry2((delimeter, arr) => arr.join(delimeter));
|
|
432
|
+
const forEach = curry2((pipe, arr) => arr.forEach(pipe));
|
|
433
|
+
const both = curry3((cond1, cond2, s) => cond2(s) && cond1(s));
|
|
434
|
+
const isEmpty = (s) => {
|
|
435
|
+
switch (type(s)) {
|
|
436
|
+
case 'String':
|
|
437
|
+
case 'Array': return length(s) == 0;
|
|
438
|
+
case 'Object':
|
|
439
|
+
for (const _k in s)
|
|
440
|
+
return false;
|
|
441
|
+
return true;
|
|
442
|
+
default: return null;
|
|
443
|
+
}
|
|
444
|
+
};
|
|
445
|
+
const empty = (s) => {
|
|
446
|
+
switch (type(s)) {
|
|
447
|
+
case 'String': return '';
|
|
448
|
+
case 'Object': return {};
|
|
449
|
+
case 'Array': return [];
|
|
450
|
+
default: return undef;
|
|
451
|
+
}
|
|
452
|
+
};
|
|
453
|
+
const replace = curry3((a, b, where
|
|
454
|
+
// @ts-ignore Some bug with overload.
|
|
455
|
+
) => where.replace(a, b));
|
|
456
|
+
// FIXME: it thinks cond is a symbol in usage !!!
|
|
457
|
+
const filter = curry2((cond, data) => isArray(data)
|
|
458
|
+
? data.filter(cond)
|
|
459
|
+
: qfilter(cond, { ...data }));
|
|
460
|
+
const memoize = (fn) => {
|
|
461
|
+
let cache;
|
|
462
|
+
let cached = false;
|
|
463
|
+
return () => cached ? cache : (cached = true, cache = fn());
|
|
464
|
+
};
|
|
465
|
+
const mergeShallow = curry2((o1, o2) => Object.assign({}, o1, o2));
|
|
466
|
+
const mergeDeep = curry2((a, b) => qmergeDeep(clone(a), clone(b)));
|
|
467
|
+
const mergeDeepX = curry2((a, b) => qmergeDeepX(clone(a), clone(b)));
|
|
468
|
+
const mergeDeepAdd = curry2((a, b) => qmergeDeepAdd(clone(a), clone(b)));
|
|
469
|
+
const overProp = curry3((prop, pipe, data) => assoc(prop, pipe(data[prop]), data));
|
|
470
|
+
/** mapKeys({ a: 'b' }, { a: 44 }) -> { b: 44 } */
|
|
471
|
+
const mapKeys = curry2((keyMap, o) => qmapKeys(keyMap, Object.assign({}, o)));
|
|
472
|
+
const zip = curry2((a, b) => map((s, i) => [s, b[i]], a));
|
|
473
|
+
const zipObj = curry2((a, b) => reduce((ac, s, i) => assoc(s, b[i], ac), {}, a));
|
|
474
|
+
// TODO: Tuple curried functions to replace these `AnyFuncs`.
|
|
475
|
+
/** zips through a pipe. Types T1, T2, T3.
|
|
476
|
+
* @returns T3[]
|
|
477
|
+
* @param pipe (T1, T2) => T3
|
|
478
|
+
* @param a T1[]
|
|
479
|
+
* @param b T2[]
|
|
480
|
+
*/
|
|
481
|
+
const zipWith = curry3((pipe, a, b) => map((s, i) => pipe(s, b[i]), a));
|
|
482
|
+
// ALIASES
|
|
483
|
+
const mirror = identity;
|
|
484
|
+
const reflect = identity;
|
|
485
|
+
const echo = identity;
|
|
486
|
+
const notf = complement;
|
|
487
|
+
const push = append;
|
|
488
|
+
const some = any;
|
|
489
|
+
|
|
490
|
+
const ecran = '\\';
|
|
491
|
+
// TODO: make it splicy, not accumulatie by symbols.
|
|
492
|
+
/** Supports ecrans: '\\{"json": {yes} \\}'
|
|
493
|
+
@returns get_tmpl(one{meme}two)({meme: 42}) -> one42two */
|
|
494
|
+
const getTmpl = (tmpl) => {
|
|
495
|
+
const parts = [];
|
|
496
|
+
const keymap = [];
|
|
497
|
+
const len = tmpl.length;
|
|
498
|
+
let i = 0, s, ln, start = 0, open = false, hasEcran = head(tmpl), hasEcranNext = false, nextChar;
|
|
499
|
+
for (i = 0; i < len; i++) {
|
|
500
|
+
s = tmpl[i];
|
|
501
|
+
switch (s) {
|
|
502
|
+
case '{':
|
|
503
|
+
if (!hasEcran) {
|
|
504
|
+
open = true;
|
|
505
|
+
start = i;
|
|
506
|
+
break;
|
|
507
|
+
}
|
|
508
|
+
case '}':
|
|
509
|
+
if (!hasEcran) {
|
|
510
|
+
open = false;
|
|
511
|
+
parts.push('');
|
|
512
|
+
keymap.push(tmpl.slice(start + 1, i));
|
|
513
|
+
break;
|
|
514
|
+
}
|
|
515
|
+
default:
|
|
516
|
+
nextChar = tmpl[i + 1];
|
|
517
|
+
hasEcranNext = s === ecran;
|
|
518
|
+
if (!open && (!hasEcranNext || nextChar !== '{' && nextChar !== '}')) {
|
|
519
|
+
ln = parts.length - 1;
|
|
520
|
+
if (ln < 0) {
|
|
521
|
+
parts.push('');
|
|
522
|
+
ln++;
|
|
523
|
+
}
|
|
524
|
+
parts[ln] += s;
|
|
525
|
+
}
|
|
526
|
+
hasEcran = hasEcranNext;
|
|
527
|
+
break;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
return (data) => {
|
|
531
|
+
const out = [];
|
|
532
|
+
const ln = parts.length - 1;
|
|
533
|
+
for (const j in parts) {
|
|
534
|
+
i = +j;
|
|
535
|
+
out.push(parts[i]);
|
|
536
|
+
if (i !== ln)
|
|
537
|
+
out.push(path(keymap[i].split('.'), data));
|
|
538
|
+
}
|
|
539
|
+
return out.join('');
|
|
540
|
+
};
|
|
541
|
+
};
|
|
542
|
+
|
|
543
|
+
/** One promise waits for another. */
|
|
544
|
+
const forEachSerial = (() => {
|
|
545
|
+
const pipe = async (fn, items, i) => {
|
|
546
|
+
if (i < items.length) {
|
|
547
|
+
await fn(items[i]);
|
|
548
|
+
await pipe(fn, items, ++i);
|
|
549
|
+
}
|
|
550
|
+
};
|
|
551
|
+
return curry2((fn, items) => pipe(fn, items, 0));
|
|
552
|
+
})();
|
|
553
|
+
/** Promise.all wrapper for functional pipelining. */
|
|
554
|
+
const waitAll = (promises) => Promise.all(promises);
|
|
555
|
+
/** Waits for a Promise that been generated by the first arg, then returns an untoched value. Types T.
|
|
556
|
+
* @param {AnyFunc<Promise>} fn - function to wait.
|
|
557
|
+
* @param {T} s - any value to tap and return back
|
|
558
|
+
* @returns {T}
|
|
559
|
+
*/
|
|
560
|
+
const waitTap = curry2(async (fn, s) => { await fn(s); return s; });
|
|
561
|
+
/** Waits for all promises mapped by the fn. */
|
|
562
|
+
const forEachAsync = curry2((fn, items) => Promise.all(items.map(fn)));
|
|
563
|
+
/** The same as compose, but waits for promises in chains and returns a Promise. */
|
|
564
|
+
const composeAsync = (() => {
|
|
565
|
+
const pipe = async (fns, input, i) => ~i ? await pipe(fns, [await fns[i](...input)], --i) : head(input);
|
|
566
|
+
return (...fns) => (...input) => pipe(fns, input, fns.length - 1);
|
|
567
|
+
})();
|
|
568
|
+
|
|
569
|
+
exports.F = F;
|
|
570
|
+
exports.T = T;
|
|
571
|
+
exports.__ = __;
|
|
572
|
+
exports.add = add;
|
|
573
|
+
exports.all = all;
|
|
574
|
+
exports.allPass = allPass;
|
|
575
|
+
exports.always = always;
|
|
576
|
+
exports.any = any;
|
|
577
|
+
exports.anyPass = anyPass;
|
|
578
|
+
exports.append = append;
|
|
579
|
+
exports.assoc = assoc;
|
|
580
|
+
exports.assocPath = assocPath;
|
|
581
|
+
exports.bind = bind;
|
|
582
|
+
exports.both = both;
|
|
583
|
+
exports.callFrom = callFrom;
|
|
584
|
+
exports.callWith = callWith;
|
|
585
|
+
exports.clone = clone;
|
|
586
|
+
exports.cloneShallow = cloneShallow;
|
|
587
|
+
exports.complement = complement;
|
|
588
|
+
exports.compose = compose;
|
|
589
|
+
exports.composeAsync = composeAsync;
|
|
590
|
+
exports.concat = concat;
|
|
591
|
+
exports.cond = cond;
|
|
592
|
+
exports.curry = curry;
|
|
593
|
+
exports.curry2 = curry2;
|
|
594
|
+
exports.curry3 = curry3;
|
|
595
|
+
exports.divide = divide;
|
|
596
|
+
exports.echo = echo;
|
|
597
|
+
exports.empty = empty;
|
|
598
|
+
exports.eq = eq;
|
|
599
|
+
exports.equals = equals;
|
|
600
|
+
exports.explore = explore;
|
|
601
|
+
exports.filter = filter;
|
|
602
|
+
exports.find = find;
|
|
603
|
+
exports.findIndex = findIndex;
|
|
604
|
+
exports.flat = flat;
|
|
605
|
+
exports.flatShallow = flatShallow;
|
|
606
|
+
exports.flatTo = flatTo;
|
|
607
|
+
exports.flip = flip;
|
|
608
|
+
exports.forEach = forEach;
|
|
609
|
+
exports.forEachAsync = forEachAsync;
|
|
610
|
+
exports.forEachSerial = forEachSerial;
|
|
611
|
+
exports.freeze = freeze;
|
|
612
|
+
exports.freezeShallow = freezeShallow;
|
|
613
|
+
exports.fromPairs = fromPairs;
|
|
614
|
+
exports.genBy = genBy;
|
|
615
|
+
exports.getTmpl = getTmpl;
|
|
616
|
+
exports.gt = gt;
|
|
617
|
+
exports.gte = gte;
|
|
618
|
+
exports.head = head;
|
|
619
|
+
exports.identity = identity;
|
|
620
|
+
exports.ifElse = ifElse;
|
|
621
|
+
exports.includes = includes;
|
|
622
|
+
exports.indexOf = indexOf;
|
|
623
|
+
exports.intersection = intersection;
|
|
624
|
+
exports.isEmpty = isEmpty;
|
|
625
|
+
exports.isNil = isNil;
|
|
626
|
+
exports.join = join;
|
|
627
|
+
exports.keys = keys;
|
|
628
|
+
exports.last = last;
|
|
629
|
+
exports.length = length;
|
|
630
|
+
exports.lt = lt;
|
|
631
|
+
exports.lte = lte;
|
|
632
|
+
exports.map = map;
|
|
633
|
+
exports.mapKeys = mapKeys;
|
|
634
|
+
exports.mapObj = mapObj;
|
|
635
|
+
exports.memoize = memoize;
|
|
636
|
+
exports.mergeDeep = mergeDeep;
|
|
637
|
+
exports.mergeDeepAdd = mergeDeepAdd;
|
|
638
|
+
exports.mergeDeepX = mergeDeepX;
|
|
639
|
+
exports.mergeShallow = mergeShallow;
|
|
640
|
+
exports.mirror = mirror;
|
|
641
|
+
exports.multiply = multiply;
|
|
642
|
+
exports.noop = noop;
|
|
643
|
+
exports.not = not;
|
|
644
|
+
exports.notf = notf;
|
|
645
|
+
exports.nth = nth;
|
|
646
|
+
exports.omit = omit;
|
|
647
|
+
exports.once = once;
|
|
648
|
+
exports.overProp = overProp;
|
|
649
|
+
exports.path = path;
|
|
650
|
+
exports.pathEq = pathEq;
|
|
651
|
+
exports.pathExists = pathExists;
|
|
652
|
+
exports.pathOr = pathOr;
|
|
653
|
+
exports.pathsEq = pathsEq;
|
|
654
|
+
exports.pick = pick;
|
|
655
|
+
exports.pickBy = pickBy;
|
|
656
|
+
exports.prepend = prepend;
|
|
657
|
+
exports.prop = prop;
|
|
658
|
+
exports.propEq = propEq;
|
|
659
|
+
exports.propsEq = propsEq;
|
|
660
|
+
exports.push = push;
|
|
661
|
+
exports.qappend = qappend;
|
|
662
|
+
exports.qassoc = qassoc;
|
|
663
|
+
exports.qassocPath = qassocPath;
|
|
664
|
+
exports.qempty = qempty;
|
|
665
|
+
exports.qfilter = qfilter;
|
|
666
|
+
exports.qfreeze = qfreeze;
|
|
667
|
+
exports.qfreezeShallow = qfreezeShallow;
|
|
668
|
+
exports.qmap = qmap;
|
|
669
|
+
exports.qmapKeys = qmapKeys;
|
|
670
|
+
exports.qmapObj = qmapObj;
|
|
671
|
+
exports.qmergeDeep = qmergeDeep;
|
|
672
|
+
exports.qmergeDeepAdd = qmergeDeepAdd;
|
|
673
|
+
exports.qmergeDeepX = qmergeDeepX;
|
|
674
|
+
exports.qmergeShallow = qmergeShallow;
|
|
675
|
+
exports.qomit = qomit;
|
|
676
|
+
exports.qprepend = qprepend;
|
|
677
|
+
exports.qreduce = qreduce;
|
|
678
|
+
exports.qreverse = qreverse;
|
|
679
|
+
exports.qstartsWith = qstartsWith;
|
|
680
|
+
exports.qstartsWithWith = qstartsWithWith;
|
|
681
|
+
exports.range = range;
|
|
682
|
+
exports.reduce = reduce;
|
|
683
|
+
exports.reflect = reflect;
|
|
684
|
+
exports.replace = replace;
|
|
685
|
+
exports.reverse = reverse;
|
|
686
|
+
exports.sizeof = sizeof;
|
|
687
|
+
exports.slice = slice;
|
|
688
|
+
exports.some = some;
|
|
689
|
+
exports.sort = sort;
|
|
690
|
+
exports.split = split;
|
|
691
|
+
exports.startsWith = startsWith;
|
|
692
|
+
exports.subtract = subtract;
|
|
693
|
+
exports.symbol = symbol;
|
|
694
|
+
exports.tail = tail;
|
|
695
|
+
exports.take = take;
|
|
696
|
+
exports.tap = tap;
|
|
697
|
+
exports.test = test;
|
|
698
|
+
exports.toLower = toLower;
|
|
699
|
+
exports.toPairs = toPairs;
|
|
700
|
+
exports.toUpper = toUpper;
|
|
701
|
+
exports.trim = trim;
|
|
702
|
+
exports.type = type;
|
|
703
|
+
exports.typeIs = typeIs;
|
|
704
|
+
exports.uncurry = uncurry;
|
|
705
|
+
exports.uniq = uniq;
|
|
706
|
+
exports.values = values;
|
|
707
|
+
exports.waitAll = waitAll;
|
|
708
|
+
exports.waitTap = waitTap;
|
|
709
|
+
exports.weakEq = weakEq;
|
|
710
|
+
exports.when = when;
|
|
711
|
+
exports.zip = zip;
|
|
712
|
+
exports.zipObj = zipObj;
|
|
713
|
+
exports.zipWith = zipWith;
|
package/dist/bundle.d.ts
CHANGED
package/dist/bundle.mjs
CHANGED
|
@@ -1 +1,567 @@
|
|
|
1
|
-
const
|
|
1
|
+
const __ = Symbol('Placeholder');
|
|
2
|
+
const countArgs = (s) => {
|
|
3
|
+
let i = 0;
|
|
4
|
+
for (const v of s)
|
|
5
|
+
v !== __ && i++;
|
|
6
|
+
return i;
|
|
7
|
+
};
|
|
8
|
+
// TODO: try to make it mutable.
|
|
9
|
+
// { 0: __, 1: 10 }, [ 11 ]
|
|
10
|
+
const addArgs = (args, _args) => {
|
|
11
|
+
const len = args.length;
|
|
12
|
+
const new_args = args.slice();
|
|
13
|
+
const _args_len = _args.length;
|
|
14
|
+
let _args_left = _args_len;
|
|
15
|
+
let i = 0;
|
|
16
|
+
for (; _args_left && i < len; i++) {
|
|
17
|
+
if (new_args[i] === __) {
|
|
18
|
+
new_args[i] = _args[_args_len - _args_left];
|
|
19
|
+
_args_left--;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
for (i = len; _args_left; i++, _args_left--) {
|
|
23
|
+
new_args[i] = _args[_args_len - _args_left];
|
|
24
|
+
}
|
|
25
|
+
return new_args;
|
|
26
|
+
};
|
|
27
|
+
const _curry = (fn, args, new_args) => {
|
|
28
|
+
const args2add = fn.length - args.length - countArgs(new_args);
|
|
29
|
+
if (args2add < 1) {
|
|
30
|
+
return fn(...addArgs(args, new_args));
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
const curried = (...__args) => _curry(fn, addArgs(args, new_args), __args);
|
|
34
|
+
curried.$args_left = args2add;
|
|
35
|
+
return curried;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
const curry = (fn) => ((...args) => fn.length > countArgs(args)
|
|
39
|
+
? _curry(fn, [], args)
|
|
40
|
+
: fn(...args));
|
|
41
|
+
const endlessph = (fn) => {
|
|
42
|
+
function _endlessph(a) {
|
|
43
|
+
return a === __ ? fn : fn(a);
|
|
44
|
+
}
|
|
45
|
+
return _endlessph;
|
|
46
|
+
};
|
|
47
|
+
function curry2(fn) {
|
|
48
|
+
function curried2(a, b) {
|
|
49
|
+
const withPlaceholder1 = a === __;
|
|
50
|
+
const aln = arguments.length;
|
|
51
|
+
if (aln === 1 && withPlaceholder1)
|
|
52
|
+
throw new Error('Senseless placeholder usage.');
|
|
53
|
+
return aln > 1
|
|
54
|
+
? withPlaceholder1
|
|
55
|
+
? endlessph((a) => fn(a, b))
|
|
56
|
+
: fn(a, b)
|
|
57
|
+
: (b) => fn(a, b);
|
|
58
|
+
}
|
|
59
|
+
return curried2;
|
|
60
|
+
}
|
|
61
|
+
function curry3(fn) {
|
|
62
|
+
// type p0 = Parameters<Func>[0]
|
|
63
|
+
// type p1 = Parameters<Func>[1]
|
|
64
|
+
// type p2 = Parameters<Func>[2]
|
|
65
|
+
// type ReturnT = ReturnType<Func>
|
|
66
|
+
// TODO: optimize.
|
|
67
|
+
// Cannot use ts-toolbelt due to this error:
|
|
68
|
+
// Excessive stack depth comparing types 'GapsOf<?, L2>' and 'GapsOf<?, L2>'
|
|
69
|
+
return curry(fn);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const undef = undefined;
|
|
73
|
+
const nul = null;
|
|
74
|
+
const inf = Infinity;
|
|
75
|
+
const to = (s) => typeof s;
|
|
76
|
+
const isNull = (s) => s === nul;
|
|
77
|
+
const isUndef = (s) => s === undef;
|
|
78
|
+
const isNum = (s) => to(s) == 'number';
|
|
79
|
+
const isArray = (s) => Array.isArray(s);
|
|
80
|
+
const isFunc = (s) => to(s) === 'function';
|
|
81
|
+
const isStr = (s) => to(s) === 'string';
|
|
82
|
+
const isObj = (s) => !isNull(s) && to(s) === 'object';
|
|
83
|
+
|
|
84
|
+
// It's faster that toUpperCase() !
|
|
85
|
+
const caseMap = { u: 'U', b: 'B', n: 'N', s: 'S', f: 'F' };
|
|
86
|
+
const symbol = Symbol();
|
|
87
|
+
const toLower = (s) => s.toLowerCase();
|
|
88
|
+
const toUpper = (s) => s.toUpperCase();
|
|
89
|
+
const type = (s) => {
|
|
90
|
+
const t = to(s);
|
|
91
|
+
return t === 'object'
|
|
92
|
+
? isNull(s) ? 'Null' : s.constructor.name
|
|
93
|
+
: caseMap[t[0]] + t.slice(1);
|
|
94
|
+
};
|
|
95
|
+
const typeIs = curry2((t, s) => type(s) === t);
|
|
96
|
+
const length = (s) => s.length;
|
|
97
|
+
const isNil = (s) => isNull(s) || isUndef(s);
|
|
98
|
+
const eq = curry2((a, b) => a === b);
|
|
99
|
+
const equals = curry2((a, b) => {
|
|
100
|
+
const typea = type(a);
|
|
101
|
+
if (eq(typea, type(b)) && (eq(typea, 'Object') || eq(typea, 'Array'))) {
|
|
102
|
+
if (isNull(a) || isNull(b))
|
|
103
|
+
return eq(a, b);
|
|
104
|
+
if (eq(a, b))
|
|
105
|
+
return true;
|
|
106
|
+
for (const v of [a, b])
|
|
107
|
+
for (const k in v)
|
|
108
|
+
if (!((eq(v, b)) && (k in a)) &&
|
|
109
|
+
!((eq(v, a)) && (k in b) && equals(a[k], b[k])))
|
|
110
|
+
return false;
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
return eq(a, b);
|
|
114
|
+
});
|
|
115
|
+
const includes = curry2((s, ss) => {
|
|
116
|
+
if (isStr(ss))
|
|
117
|
+
return ss.includes(s);
|
|
118
|
+
else {
|
|
119
|
+
for (const a of ss)
|
|
120
|
+
if (equals(a, s))
|
|
121
|
+
return true;
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
/** @param start string | any[] @param s string | any[] */
|
|
126
|
+
const qstartsWithWith = (comparator) => curry2((start, s) => {
|
|
127
|
+
const len_start = length(start);
|
|
128
|
+
const len_s = length(s);
|
|
129
|
+
if (len_start > len_s)
|
|
130
|
+
return false;
|
|
131
|
+
for (let i = 0; i < len_start; i++)
|
|
132
|
+
if (!comparator(s[i], start[i]))
|
|
133
|
+
return false;
|
|
134
|
+
return true;
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
// TODO: qflat, qoverProp, qover array ?
|
|
138
|
+
const qappend = curry2((s, xs) => { xs.push(s); return xs; });
|
|
139
|
+
const qassoc = curry3((prop, v, obj) => { obj[prop] = v; return obj; });
|
|
140
|
+
const qreduce = curry3((fn, accum, arr) => arr.reduce(fn, accum));
|
|
141
|
+
// strategy is for arrays: 1->clean, 2->merge, 3->push.
|
|
142
|
+
const mergeDeep$1 = curry3((strategy, o1, o2) => {
|
|
143
|
+
for (let k in o2) {
|
|
144
|
+
switch (type(o2[k])) {
|
|
145
|
+
case 'Array':
|
|
146
|
+
if (strategy > 1 && type(o1[k]) === 'Array')
|
|
147
|
+
switch (strategy) {
|
|
148
|
+
case 2:
|
|
149
|
+
const o1k = o1[k], o2k = o2[k];
|
|
150
|
+
for (const i in o2k)
|
|
151
|
+
if (o1k[i])
|
|
152
|
+
mergeDeep$1(strategy, o1k[i], o2k[i]);
|
|
153
|
+
else
|
|
154
|
+
o1k[i] = o2k[i];
|
|
155
|
+
break;
|
|
156
|
+
case 3: o1[k].push(...o2[k]);
|
|
157
|
+
}
|
|
158
|
+
else
|
|
159
|
+
o1[k] = o2[k];
|
|
160
|
+
break;
|
|
161
|
+
case 'Object':
|
|
162
|
+
if (type(o1[k]) === 'Object') {
|
|
163
|
+
mergeDeep$1(strategy, o1[k], o2[k]);
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
default:
|
|
167
|
+
o1[k] = o2[k];
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return o1;
|
|
172
|
+
});
|
|
173
|
+
const qmergeDeep = mergeDeep$1(1);
|
|
174
|
+
const qmergeDeepX = mergeDeep$1(2);
|
|
175
|
+
const qmergeDeepAdd = mergeDeep$1(3);
|
|
176
|
+
const qmergeShallow = curry2((o1, o2) => Object.assign(o1, o2));
|
|
177
|
+
/** qmapKeys({ a: 'b' }, { a: 44 }) -> { b: 44 } */
|
|
178
|
+
const qmapKeys = curry2((keyMap, o) => {
|
|
179
|
+
let k, mapped, newKey, newValue;
|
|
180
|
+
for (k in keyMap)
|
|
181
|
+
if (k in o) {
|
|
182
|
+
mapped = keyMap[k];
|
|
183
|
+
[newKey, newValue] = isFunc(mapped)
|
|
184
|
+
? mapped(o[k], k, o)
|
|
185
|
+
: [mapped, o[k]];
|
|
186
|
+
o[isNil(newKey) ? k : newKey] = newValue;
|
|
187
|
+
if (k !== newKey)
|
|
188
|
+
delete o[k];
|
|
189
|
+
}
|
|
190
|
+
return o;
|
|
191
|
+
});
|
|
192
|
+
const qmap = curry2((pipe, arr) => {
|
|
193
|
+
for (let i in arr)
|
|
194
|
+
arr[i] = pipe(arr[i], +i, arr);
|
|
195
|
+
return arr;
|
|
196
|
+
});
|
|
197
|
+
const qmapObj = curry2((pipe, o) => qmap(pipe, o));
|
|
198
|
+
const qfilter = curry2((cond, data) => {
|
|
199
|
+
const isArr = isArray(data);
|
|
200
|
+
let indicies_offset, indicies2rm;
|
|
201
|
+
if (isArr) {
|
|
202
|
+
indicies_offset = 0;
|
|
203
|
+
indicies2rm = [];
|
|
204
|
+
}
|
|
205
|
+
for (let k in data)
|
|
206
|
+
if (!cond(data[k], k)) // @ts-ignore
|
|
207
|
+
if (isArr)
|
|
208
|
+
indicies2rm.push(+k);
|
|
209
|
+
else
|
|
210
|
+
delete data[k];
|
|
211
|
+
if (isArr) // @ts-ignore
|
|
212
|
+
for (const i of indicies2rm) // @ts-ignore
|
|
213
|
+
data.splice(i - indicies_offset++, 1);
|
|
214
|
+
return data;
|
|
215
|
+
});
|
|
216
|
+
const qempty = (o) => {
|
|
217
|
+
if (isArray(o))
|
|
218
|
+
o.splice(0);
|
|
219
|
+
else
|
|
220
|
+
for (const i in o)
|
|
221
|
+
delete o[i];
|
|
222
|
+
return o;
|
|
223
|
+
};
|
|
224
|
+
const qfreeze = (o) => {
|
|
225
|
+
let v;
|
|
226
|
+
for (const k in o) {
|
|
227
|
+
v = o[k];
|
|
228
|
+
if (isObj(v))
|
|
229
|
+
qfreeze(v);
|
|
230
|
+
}
|
|
231
|
+
return Object.freeze(o);
|
|
232
|
+
};
|
|
233
|
+
const qfreezeShallow = (o) => Object.freeze(o);
|
|
234
|
+
const qprepend = curry2((x, xs) => xs.unshift(x));
|
|
235
|
+
const qassocPath = curry3((_path, v, o) => {
|
|
236
|
+
const first = _path[0];
|
|
237
|
+
return qassoc(first, _path.length < 2
|
|
238
|
+
? v
|
|
239
|
+
: qassocPath(_path.slice(1), v, isObj(o[first]) ? o[first] : {}), o);
|
|
240
|
+
});
|
|
241
|
+
const qreverse = (arr) => arr.reverse();
|
|
242
|
+
const qomit = curry2((props, o) => qfilter((_, k) => !includes(k, props), o));
|
|
243
|
+
/** @param start string | any[] @param s string | any[] */
|
|
244
|
+
const qstartsWith = qstartsWithWith(eq);
|
|
245
|
+
|
|
246
|
+
// TODO: possibly introduce a second argument limiting unfolding.
|
|
247
|
+
const uncurry = (fn) => (...args) => qreduce(((fn, arg) => fn ? fn(arg) : fn), fn, args);
|
|
248
|
+
|
|
249
|
+
// over, lensProp
|
|
250
|
+
const take = (argN) => (...args) => args[argN];
|
|
251
|
+
const weakEq = curry2((a, b) => a == b);
|
|
252
|
+
const ifElse = curry((cond, pipeYes, pipeNo, s) => cond(s) ? pipeYes(s) : pipeNo(s));
|
|
253
|
+
const when = curry3((cond, pipe, s) => ifElse(cond, pipe, identity, s));
|
|
254
|
+
const compose = ((...fns) => (...args) => {
|
|
255
|
+
let first = true;
|
|
256
|
+
let s;
|
|
257
|
+
for (let i = length(fns) - 1; i > -1; i--) {
|
|
258
|
+
if (first) {
|
|
259
|
+
first = false;
|
|
260
|
+
s = fns[i](...args);
|
|
261
|
+
}
|
|
262
|
+
else
|
|
263
|
+
s = s === __ ? fns[i]() : fns[i](s);
|
|
264
|
+
}
|
|
265
|
+
return s;
|
|
266
|
+
});
|
|
267
|
+
const bind = curry2((fn, context) => fn.bind(context));
|
|
268
|
+
const nth = curry2((i, data) => data[i]);
|
|
269
|
+
const slice = curry3((from, to, o) => o.slice(from, (isNum(to) ? to : inf)));
|
|
270
|
+
const flip = (fn) => curry2((b, a) => fn(a, b));
|
|
271
|
+
/** @returns first element of an array. */
|
|
272
|
+
const head = nth(0);
|
|
273
|
+
/** @returns last element of an array. */
|
|
274
|
+
const tail = slice(1, inf);
|
|
275
|
+
/** @param a @param b @returns a+b */
|
|
276
|
+
const add = curry2((a, b) => a + b);
|
|
277
|
+
/** @param a @param b @returns b-a */
|
|
278
|
+
const subtract = curry2((a, b) => b - a);
|
|
279
|
+
/**@param a @param b @returns a*b */
|
|
280
|
+
const multiply = curry2((a, b) => a * b);
|
|
281
|
+
/** @param a @param b @returns a<b */
|
|
282
|
+
const gt = curry2((a, b) => a < b);
|
|
283
|
+
/** @param a @param b @returns a>b */
|
|
284
|
+
const lt = curry2((a, b) => a > b);
|
|
285
|
+
/** @param a @param b @returns a<=b */
|
|
286
|
+
const gte = curry2((a, b) => a <= b);
|
|
287
|
+
/** @param a @param b @returns a>=b */
|
|
288
|
+
const lte = curry2((a, b) => a >= b);
|
|
289
|
+
const sort = curry2((sortFn, xs) => xs.sort(sortFn));
|
|
290
|
+
const find = curry2((fn, s) => s.find(fn));
|
|
291
|
+
const findIndex = curry2((fn, s) => s.findIndex(fn));
|
|
292
|
+
const indexOf = curry2((x, xs) => findIndex(equals(x), xs));
|
|
293
|
+
const divide = curry2((n, m) => n / m);
|
|
294
|
+
const always = (s) => () => s;
|
|
295
|
+
const identity = (s) => s;
|
|
296
|
+
const trim = (s) => s.trim();
|
|
297
|
+
const last = (s) => s[length(s) - 1];
|
|
298
|
+
/** @param start string | any[] @param s string | any[] */
|
|
299
|
+
const startsWith = qstartsWithWith((x, y) => equals(x, y));
|
|
300
|
+
const not = (x) => !x;
|
|
301
|
+
const keys = (o) => Object.keys(o);
|
|
302
|
+
const values = (o) => Object.values(o);
|
|
303
|
+
const toPairs = (o) => Object.entries(o);
|
|
304
|
+
const test = curry2((re, s) => re.test(s));
|
|
305
|
+
const tap = curry2((fn, x) => { fn(x); return x; });
|
|
306
|
+
const append = curry2((x, xs) => [...xs, x]);
|
|
307
|
+
const prepend = curry2((x, xs) => [...xs, x]);
|
|
308
|
+
const flat = (xs) => xs.flat(inf);
|
|
309
|
+
const flatShallow = (xs) => xs.flat();
|
|
310
|
+
const flatTo = curry2((depth, xs) => xs.flat(depth));
|
|
311
|
+
const split = curry2((s, xs) => xs.split(s));
|
|
312
|
+
const T = always(true);
|
|
313
|
+
const F = always(false);
|
|
314
|
+
const callWith = curry2((args, fn) => fn(...args));
|
|
315
|
+
const noop = (() => { });
|
|
316
|
+
/** Calls a func from object.
|
|
317
|
+
* @param {any[]} [args] - arguments for the function.
|
|
318
|
+
* @param {string} [fnName] - property name of the function.
|
|
319
|
+
* @param {AnyObject} [o] - the object with the function. */
|
|
320
|
+
const callFrom = curry((args, fn, o) => o[fn](...args));
|
|
321
|
+
const complement = (fn) => (...args) => {
|
|
322
|
+
const out = fn(...args);
|
|
323
|
+
const f = isFunc(out);
|
|
324
|
+
return !f || f && out.$args_left <= 0 ? not(out) : complement(out);
|
|
325
|
+
};
|
|
326
|
+
const sizeof = (s) => {
|
|
327
|
+
if (type(s) === 'Object') {
|
|
328
|
+
let len = 0;
|
|
329
|
+
for (let _k in s)
|
|
330
|
+
len++;
|
|
331
|
+
return len;
|
|
332
|
+
}
|
|
333
|
+
else
|
|
334
|
+
return length(s);
|
|
335
|
+
};
|
|
336
|
+
const range = curry2((from, to) => genBy(add(from), to - from));
|
|
337
|
+
/** @param xs any[] @returns xs without duplicates. */
|
|
338
|
+
const uniq = (xs) => qreduce((accum, x) => find(equals(x), accum) ? accum : qappend(x, accum), [], xs);
|
|
339
|
+
const intersection = curry2((xs1, xs2) => xs1.filter(flip(includes)(xs2)));
|
|
340
|
+
const genBy = curry2((generator, length) => [...Array(length)].map((_, i) => generator(i)));
|
|
341
|
+
const once = (fn) => {
|
|
342
|
+
let done = false, cache;
|
|
343
|
+
return (...args) => {
|
|
344
|
+
if (done)
|
|
345
|
+
return cache;
|
|
346
|
+
done = true;
|
|
347
|
+
return cache = fn(...args);
|
|
348
|
+
};
|
|
349
|
+
};
|
|
350
|
+
const reverse = (xs) => compose((ln) => reduce((nxs, _, i) => qappend(xs[ln - i], nxs), [], xs), add(-1), length)(xs);
|
|
351
|
+
const explore = (caption, level = 'log') => tap((v) => console[level](caption, v));
|
|
352
|
+
const cond = curry2((pairs, s) => {
|
|
353
|
+
for (const [cond, fn] of pairs)
|
|
354
|
+
if (cond(s))
|
|
355
|
+
return fn(s);
|
|
356
|
+
});
|
|
357
|
+
/** Assigns a prop to an object.
|
|
358
|
+
* @param prop string
|
|
359
|
+
* @param value any
|
|
360
|
+
* @param object AnyObject
|
|
361
|
+
*/
|
|
362
|
+
const assoc = curry3((prop, v, obj) => ({ ...obj, [prop]: v }));
|
|
363
|
+
const assocPath = curry3((_path, v, o) => compose((first) => assoc(first, length(_path) < 2
|
|
364
|
+
? v
|
|
365
|
+
: assocPath(slice(1, inf, _path), v, isObj(o[first]) ? o[first] : {}), o), head)(_path));
|
|
366
|
+
const all = curry2((pred, xs) => xs.every(pred));
|
|
367
|
+
const any = curry2((pred, xs) => xs.some(pred));
|
|
368
|
+
const allPass = curry2((preds, x) => preds.every((pred) => pred(x)));
|
|
369
|
+
const anyPass = curry2((preds, x) => preds.some((pred) => pred(x)));
|
|
370
|
+
/** @param key string @param o AnyObject @returns o[key] */
|
|
371
|
+
const prop = curry2((key, o) => o[key]);
|
|
372
|
+
/** @param key string @param value any @param o AnyObject @returns o[key] equals value */
|
|
373
|
+
const propEq = curry3((key, value, o) => equals(o[key], value));
|
|
374
|
+
/** @param key string @param o1 AnyObject @param o2 AnyObject @returns o₁[key] equals o₂[key] */
|
|
375
|
+
const propsEq = curry3((key, o1, o2) => equals(o1[key], o2[key]));
|
|
376
|
+
const pathOr = curry3((_default, path, o) => length(path)
|
|
377
|
+
? isNil(o)
|
|
378
|
+
? _default
|
|
379
|
+
: compose((k) => k in o ? pathOr(_default, slice(1, inf, path), o[k]) : _default, head)(path)
|
|
380
|
+
: o);
|
|
381
|
+
const path = pathOr(undef);
|
|
382
|
+
const pathEq = curry3((_path, value, o) => equals(path(_path, o), value));
|
|
383
|
+
const pathsEq = curry3((_path, o1, o2) => equals(path(_path, o1), path(_path, o2)));
|
|
384
|
+
const pathExists = compose(ifElse(equals(symbol), F, T), pathOr(symbol));
|
|
385
|
+
const typed_arr_re = /^(.*?)(8|16|32|64)(Clamped)?Array$/;
|
|
386
|
+
const clone = (s, shallow = false) => {
|
|
387
|
+
const t = type(s);
|
|
388
|
+
switch (t) {
|
|
389
|
+
case 'Null': return s;
|
|
390
|
+
case 'Array': return shallow ? [...s] : map(compose(clone, take(0)), s);
|
|
391
|
+
case 'Object':
|
|
392
|
+
if (shallow)
|
|
393
|
+
return { ...s };
|
|
394
|
+
const out = {};
|
|
395
|
+
for (let k in s)
|
|
396
|
+
out[k] = clone(s[k]);
|
|
397
|
+
return out;
|
|
398
|
+
case 'String':
|
|
399
|
+
case 'Number':
|
|
400
|
+
case 'Boolean':
|
|
401
|
+
case 'Symbol':
|
|
402
|
+
return s;
|
|
403
|
+
default:
|
|
404
|
+
return typed_arr_re.test(t) ? s.constructor.from(s) : s;
|
|
405
|
+
}
|
|
406
|
+
};
|
|
407
|
+
const cloneShallow = (s) => clone(s, true);
|
|
408
|
+
const freeze = (o) => qfreeze(clone(o));
|
|
409
|
+
const freezeShallow = (o) => qfreezeShallow(clone(o));
|
|
410
|
+
/** types T1, T2
|
|
411
|
+
* @param reducer (accum: T1, current: T2, index: number) => newAccum: T1
|
|
412
|
+
* @param accum T1
|
|
413
|
+
* @param array T2[]
|
|
414
|
+
*/
|
|
415
|
+
const reduce = curry3((reducer, accum, arr) => qreduce(reducer, clone(accum), arr));
|
|
416
|
+
const pickBy = curry2((cond, o) => filter(cond, o));
|
|
417
|
+
const pick = curry2((props, o) => {
|
|
418
|
+
const out = {};
|
|
419
|
+
for (const p of props)
|
|
420
|
+
if (p in o)
|
|
421
|
+
out[p] = o[p];
|
|
422
|
+
return out;
|
|
423
|
+
});
|
|
424
|
+
const omit = curry2((props, o) => filter((_, k) => !includes(k, props), o));
|
|
425
|
+
const fromPairs = (pairs) => Object.fromEntries(pairs);
|
|
426
|
+
const concat = curry2(((a, b) => b.concat(a)));
|
|
427
|
+
const map = curry2((pipe, arr) => arr.map(pipe));
|
|
428
|
+
const mapObj = curry2((pipe, o) => qmapObj(pipe, cloneShallow(o)));
|
|
429
|
+
const join = curry2((delimeter, arr) => arr.join(delimeter));
|
|
430
|
+
const forEach = curry2((pipe, arr) => arr.forEach(pipe));
|
|
431
|
+
const both = curry3((cond1, cond2, s) => cond2(s) && cond1(s));
|
|
432
|
+
const isEmpty = (s) => {
|
|
433
|
+
switch (type(s)) {
|
|
434
|
+
case 'String':
|
|
435
|
+
case 'Array': return length(s) == 0;
|
|
436
|
+
case 'Object':
|
|
437
|
+
for (const _k in s)
|
|
438
|
+
return false;
|
|
439
|
+
return true;
|
|
440
|
+
default: return null;
|
|
441
|
+
}
|
|
442
|
+
};
|
|
443
|
+
const empty = (s) => {
|
|
444
|
+
switch (type(s)) {
|
|
445
|
+
case 'String': return '';
|
|
446
|
+
case 'Object': return {};
|
|
447
|
+
case 'Array': return [];
|
|
448
|
+
default: return undef;
|
|
449
|
+
}
|
|
450
|
+
};
|
|
451
|
+
const replace = curry3((a, b, where
|
|
452
|
+
// @ts-ignore Some bug with overload.
|
|
453
|
+
) => where.replace(a, b));
|
|
454
|
+
// FIXME: it thinks cond is a symbol in usage !!!
|
|
455
|
+
const filter = curry2((cond, data) => isArray(data)
|
|
456
|
+
? data.filter(cond)
|
|
457
|
+
: qfilter(cond, { ...data }));
|
|
458
|
+
const memoize = (fn) => {
|
|
459
|
+
let cache;
|
|
460
|
+
let cached = false;
|
|
461
|
+
return () => cached ? cache : (cached = true, cache = fn());
|
|
462
|
+
};
|
|
463
|
+
const mergeShallow = curry2((o1, o2) => Object.assign({}, o1, o2));
|
|
464
|
+
const mergeDeep = curry2((a, b) => qmergeDeep(clone(a), clone(b)));
|
|
465
|
+
const mergeDeepX = curry2((a, b) => qmergeDeepX(clone(a), clone(b)));
|
|
466
|
+
const mergeDeepAdd = curry2((a, b) => qmergeDeepAdd(clone(a), clone(b)));
|
|
467
|
+
const overProp = curry3((prop, pipe, data) => assoc(prop, pipe(data[prop]), data));
|
|
468
|
+
/** mapKeys({ a: 'b' }, { a: 44 }) -> { b: 44 } */
|
|
469
|
+
const mapKeys = curry2((keyMap, o) => qmapKeys(keyMap, Object.assign({}, o)));
|
|
470
|
+
const zip = curry2((a, b) => map((s, i) => [s, b[i]], a));
|
|
471
|
+
const zipObj = curry2((a, b) => reduce((ac, s, i) => assoc(s, b[i], ac), {}, a));
|
|
472
|
+
// TODO: Tuple curried functions to replace these `AnyFuncs`.
|
|
473
|
+
/** zips through a pipe. Types T1, T2, T3.
|
|
474
|
+
* @returns T3[]
|
|
475
|
+
* @param pipe (T1, T2) => T3
|
|
476
|
+
* @param a T1[]
|
|
477
|
+
* @param b T2[]
|
|
478
|
+
*/
|
|
479
|
+
const zipWith = curry3((pipe, a, b) => map((s, i) => pipe(s, b[i]), a));
|
|
480
|
+
// ALIASES
|
|
481
|
+
const mirror = identity;
|
|
482
|
+
const reflect = identity;
|
|
483
|
+
const echo = identity;
|
|
484
|
+
const notf = complement;
|
|
485
|
+
const push = append;
|
|
486
|
+
const some = any;
|
|
487
|
+
|
|
488
|
+
const ecran = '\\';
|
|
489
|
+
// TODO: make it splicy, not accumulatie by symbols.
|
|
490
|
+
/** Supports ecrans: '\\{"json": {yes} \\}'
|
|
491
|
+
@returns get_tmpl(one{meme}two)({meme: 42}) -> one42two */
|
|
492
|
+
const getTmpl = (tmpl) => {
|
|
493
|
+
const parts = [];
|
|
494
|
+
const keymap = [];
|
|
495
|
+
const len = tmpl.length;
|
|
496
|
+
let i = 0, s, ln, start = 0, open = false, hasEcran = head(tmpl), hasEcranNext = false, nextChar;
|
|
497
|
+
for (i = 0; i < len; i++) {
|
|
498
|
+
s = tmpl[i];
|
|
499
|
+
switch (s) {
|
|
500
|
+
case '{':
|
|
501
|
+
if (!hasEcran) {
|
|
502
|
+
open = true;
|
|
503
|
+
start = i;
|
|
504
|
+
break;
|
|
505
|
+
}
|
|
506
|
+
case '}':
|
|
507
|
+
if (!hasEcran) {
|
|
508
|
+
open = false;
|
|
509
|
+
parts.push('');
|
|
510
|
+
keymap.push(tmpl.slice(start + 1, i));
|
|
511
|
+
break;
|
|
512
|
+
}
|
|
513
|
+
default:
|
|
514
|
+
nextChar = tmpl[i + 1];
|
|
515
|
+
hasEcranNext = s === ecran;
|
|
516
|
+
if (!open && (!hasEcranNext || nextChar !== '{' && nextChar !== '}')) {
|
|
517
|
+
ln = parts.length - 1;
|
|
518
|
+
if (ln < 0) {
|
|
519
|
+
parts.push('');
|
|
520
|
+
ln++;
|
|
521
|
+
}
|
|
522
|
+
parts[ln] += s;
|
|
523
|
+
}
|
|
524
|
+
hasEcran = hasEcranNext;
|
|
525
|
+
break;
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
return (data) => {
|
|
529
|
+
const out = [];
|
|
530
|
+
const ln = parts.length - 1;
|
|
531
|
+
for (const j in parts) {
|
|
532
|
+
i = +j;
|
|
533
|
+
out.push(parts[i]);
|
|
534
|
+
if (i !== ln)
|
|
535
|
+
out.push(path(keymap[i].split('.'), data));
|
|
536
|
+
}
|
|
537
|
+
return out.join('');
|
|
538
|
+
};
|
|
539
|
+
};
|
|
540
|
+
|
|
541
|
+
/** One promise waits for another. */
|
|
542
|
+
const forEachSerial = (() => {
|
|
543
|
+
const pipe = async (fn, items, i) => {
|
|
544
|
+
if (i < items.length) {
|
|
545
|
+
await fn(items[i]);
|
|
546
|
+
await pipe(fn, items, ++i);
|
|
547
|
+
}
|
|
548
|
+
};
|
|
549
|
+
return curry2((fn, items) => pipe(fn, items, 0));
|
|
550
|
+
})();
|
|
551
|
+
/** Promise.all wrapper for functional pipelining. */
|
|
552
|
+
const waitAll = (promises) => Promise.all(promises);
|
|
553
|
+
/** Waits for a Promise that been generated by the first arg, then returns an untoched value. Types T.
|
|
554
|
+
* @param {AnyFunc<Promise>} fn - function to wait.
|
|
555
|
+
* @param {T} s - any value to tap and return back
|
|
556
|
+
* @returns {T}
|
|
557
|
+
*/
|
|
558
|
+
const waitTap = curry2(async (fn, s) => { await fn(s); return s; });
|
|
559
|
+
/** Waits for all promises mapped by the fn. */
|
|
560
|
+
const forEachAsync = curry2((fn, items) => Promise.all(items.map(fn)));
|
|
561
|
+
/** The same as compose, but waits for promises in chains and returns a Promise. */
|
|
562
|
+
const composeAsync = (() => {
|
|
563
|
+
const pipe = async (fns, input, i) => ~i ? await pipe(fns, [await fns[i](...input)], --i) : head(input);
|
|
564
|
+
return (...fns) => (...input) => pipe(fns, input, fns.length - 1);
|
|
565
|
+
})();
|
|
566
|
+
|
|
567
|
+
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, 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, qprepend, qreduce, qreverse, qstartsWith, qstartsWithWith, range, reduce, reflect, replace, reverse, sizeof, slice, some, sort, split, startsWith, subtract, symbol, tail, take, tap, test, toLower, toPairs, toUpper, trim, type, typeIs, uncurry, uniq, values, waitAll, waitTap, weakEq, when, zip, zipObj, zipWith };
|
package/package.json
CHANGED
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"prod": "npm run gentypes && npm run prod:es && npm run prod:cjs",
|
|
44
44
|
"all": "npm run dev && npm run prod"
|
|
45
45
|
},
|
|
46
|
-
"version": "1.3.
|
|
46
|
+
"version": "1.3.1",
|
|
47
47
|
"ava": {
|
|
48
48
|
"files": [
|
|
49
49
|
"./test/specs/*.ts"
|
|
@@ -61,15 +61,14 @@
|
|
|
61
61
|
"@rollup/plugin-commonjs": "^25.0.7",
|
|
62
62
|
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
63
63
|
"@rollup/plugin-replace": "^5.0.5",
|
|
64
|
-
"@rollup/plugin-terser": "^0.4.4",
|
|
65
64
|
"@types/node": "^20.12.7",
|
|
66
65
|
"ava": "^6.1.2",
|
|
67
66
|
"codecov": "^3.8.3",
|
|
68
67
|
"cross-env": "^7.0.3",
|
|
69
|
-
"dts-bundle-generator": "^9.
|
|
68
|
+
"dts-bundle-generator": "^9.5.1",
|
|
70
69
|
"nyc": "^15.1.0",
|
|
71
70
|
"prepend": "^1.0.2",
|
|
72
|
-
"rollup": "^4.
|
|
71
|
+
"rollup": "^4.16.1",
|
|
73
72
|
"rollup-plugin-typescript2": "^0.36.0",
|
|
74
73
|
"ts-node": "^10.9.2",
|
|
75
74
|
"tslint": "^6.1.3",
|
package/rollup.config.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import commonjs from '@rollup/plugin-commonjs'
|
|
2
2
|
import resolve from '@rollup/plugin-node-resolve'
|
|
3
3
|
import typescript from 'rollup-plugin-typescript2'
|
|
4
|
-
import terser from '@rollup/plugin-terser'
|
|
4
|
+
// import terser from '@rollup/plugin-terser'
|
|
5
5
|
import replace from '@rollup/plugin-replace'
|
|
6
6
|
import tsc from 'typescript'
|
|
7
7
|
|
|
@@ -29,7 +29,7 @@ export default {
|
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
}),
|
|
32
|
-
process.env.NODE_ENV!='development' && terser(),
|
|
32
|
+
// process.env.NODE_ENV!='development' && terser(),
|
|
33
33
|
replace({
|
|
34
34
|
preventAssignment: true,
|
|
35
35
|
values: {
|