pepka 1.5.3 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundle.cjs +30 -22
- package/dist/bundle.d.ts +90 -36
- package/dist/bundle.mjs +30 -23
- package/package.json +2 -2
- package/src/common.ts +2 -1
- package/src/curry.ts +2 -1
- package/src/internal_types.ts +7 -0
- package/src/quick.ts +12 -9
- package/src/safe.ts +63 -39
- package/src/strings.ts +2 -2
- package/src/types.ts +3 -7
package/dist/bundle.cjs
CHANGED
|
@@ -136,7 +136,6 @@ const qstartsWithWith = (comparator) => curry2((start, s) => {
|
|
|
136
136
|
return true;
|
|
137
137
|
});
|
|
138
138
|
|
|
139
|
-
// TODO: qoverProp, qover array ?
|
|
140
139
|
/** Then next fns seem to be excess due to their safe ver performance should be the same or better:
|
|
141
140
|
* qflat, qpick
|
|
142
141
|
*/
|
|
@@ -144,7 +143,7 @@ const qappend = curry2((s, xs) => { xs.push(s); return xs; });
|
|
|
144
143
|
const qassoc = curry3((prop, v, obj) => { obj[prop] = v; return obj; });
|
|
145
144
|
const qreduce = curry3((fn, accum, arr) => arr.reduce(fn, accum));
|
|
146
145
|
// strategy is for arrays: 1->clean, 2->merge, 3->push.
|
|
147
|
-
const mergeDeep$1 =
|
|
146
|
+
const mergeDeep$1 = (strategy) => curry2((o1, o2) => {
|
|
148
147
|
for (let k in o2) {
|
|
149
148
|
switch (type(o2[k])) {
|
|
150
149
|
case 'Array':
|
|
@@ -154,7 +153,7 @@ const mergeDeep$1 = curry3((strategy, o1, o2) => {
|
|
|
154
153
|
const o1k = o1[k], o2k = o2[k];
|
|
155
154
|
for (const i in o2k)
|
|
156
155
|
if (o1k[i])
|
|
157
|
-
mergeDeep$1(strategy
|
|
156
|
+
mergeDeep$1(strategy)(o1k[i], o2k[i]);
|
|
158
157
|
else
|
|
159
158
|
o1k[i] = o2k[i];
|
|
160
159
|
break;
|
|
@@ -165,7 +164,7 @@ const mergeDeep$1 = curry3((strategy, o1, o2) => {
|
|
|
165
164
|
break;
|
|
166
165
|
case 'Object':
|
|
167
166
|
if (type(o1[k]) === 'Object') {
|
|
168
|
-
mergeDeep$1(strategy
|
|
167
|
+
mergeDeep$1(strategy)(o1[k], o2[k]);
|
|
169
168
|
break;
|
|
170
169
|
}
|
|
171
170
|
default:
|
|
@@ -195,7 +194,7 @@ const qmapKeys = curry2((keyMap, o) => {
|
|
|
195
194
|
return o;
|
|
196
195
|
});
|
|
197
196
|
const qmap = curry2((pipe, arr) => {
|
|
198
|
-
for (
|
|
197
|
+
for (const i in arr)
|
|
199
198
|
arr[i] = pipe(arr[i], +i, arr);
|
|
200
199
|
return arr;
|
|
201
200
|
});
|
|
@@ -247,6 +246,8 @@ const qreverse = (arr) => arr.reverse();
|
|
|
247
246
|
const qomit = curry2((props, o) => qfilter((_, k) => !includes(k, props), o));
|
|
248
247
|
/** @param start string | any[] @param s string | any[] */
|
|
249
248
|
const qstartsWith = qstartsWithWith(eq);
|
|
249
|
+
/** @param prop string @param pipe(data[prop]) @param data any @returns data with prop over pipe. */
|
|
250
|
+
const qoverProp = curry3((prop, pipe, data) => qassoc(prop, pipe(data[prop]), data));
|
|
250
251
|
|
|
251
252
|
// TODO: possibly introduce a second argument limiting unfolding.
|
|
252
253
|
const uncurry = (fn) => (...args) => qreduce(((fn, arg) => fn ? fn(arg) : fn), fn, args);
|
|
@@ -273,10 +274,14 @@ const bind = curry2((fn, context) => fn.bind(context));
|
|
|
273
274
|
const nth = curry2((i, data) => data[i]);
|
|
274
275
|
const slice = curry3((from, to, o) => o.slice(from, (isNum(to) ? to : inf)));
|
|
275
276
|
const flip = (fn) => curry2((b, a) => fn(a, b));
|
|
276
|
-
/** @returns first element of an array. */
|
|
277
|
+
/** @returns first element of an array or a string. */
|
|
277
278
|
const head = nth(0);
|
|
278
|
-
/** @returns last element of an array. */
|
|
279
|
+
/** @returns last element of an array or a string. */
|
|
279
280
|
const tail = slice(1, inf);
|
|
281
|
+
/** Returns last element of an array, readonly array or a string.
|
|
282
|
+
* @param s Array to extract that element.
|
|
283
|
+
* @returns undefined if s is empty or last element. */
|
|
284
|
+
const last = (s) => s[length(s) - 1];
|
|
280
285
|
/** @param a @param b @returns a+b */
|
|
281
286
|
const add = curry2((a, b) => a + b);
|
|
282
287
|
/** @param a @param b @returns b-a */
|
|
@@ -295,11 +300,10 @@ const sort = curry2((sortFn, xs) => xs.sort(sortFn));
|
|
|
295
300
|
const find = curry2((fn, s) => s.find(fn));
|
|
296
301
|
const findIndex = curry2((fn, s) => s.findIndex(fn));
|
|
297
302
|
const indexOf = curry2((x, xs) => findIndex(equals(x), xs));
|
|
298
|
-
const divide = curry2((
|
|
303
|
+
const divide = curry2((a, b) => b / a);
|
|
299
304
|
const always = (s) => () => s;
|
|
300
305
|
const identity = (s) => s;
|
|
301
306
|
const trim = (s) => s.trim();
|
|
302
|
-
const last = (s) => s[length(s) - 1];
|
|
303
307
|
/** @param start string | any[] @param s string | any[] */
|
|
304
308
|
const startsWith = qstartsWithWith((x, y) => equals(x, y));
|
|
305
309
|
const not = (x) => !x;
|
|
@@ -343,14 +347,13 @@ const range = curry2((from, to) => genBy(add(from), to - from));
|
|
|
343
347
|
const uniq = (xs) => qreduce((accum, x) => find(equals(x), accum) ? accum : qappend(x, accum), [], xs);
|
|
344
348
|
const intersection = curry2((xs1, xs2) => xs1.filter(flip(includes)(xs2)));
|
|
345
349
|
const diff = curry2((_xs1, _xs2) => {
|
|
346
|
-
// BUG: if _xs1 is empty, results in [undefined, ...]
|
|
347
350
|
let len1 = length(_xs1);
|
|
348
|
-
let len2 = length(_xs2);
|
|
349
|
-
const xs1 = len1 > len2 ? _xs1 : _xs2;
|
|
350
|
-
const xs2 = len1 > len2 ? _xs2 : _xs1;
|
|
351
|
-
if (len1
|
|
351
|
+
let len2 = length(_xs2);
|
|
352
|
+
const xs1 = len1 > len2 ? _xs1 : _xs2;
|
|
353
|
+
const xs2 = len1 > len2 ? _xs2 : _xs1;
|
|
354
|
+
if (len1 < len2)
|
|
352
355
|
[len1, len2] = [len2, len1];
|
|
353
|
-
const xset2 = new Set(xs2);
|
|
356
|
+
const xset2 = new Set(xs2);
|
|
354
357
|
const common = new Set();
|
|
355
358
|
const out = [];
|
|
356
359
|
let i;
|
|
@@ -378,7 +381,10 @@ const once = (fn) => {
|
|
|
378
381
|
return cache = fn(...args);
|
|
379
382
|
};
|
|
380
383
|
};
|
|
381
|
-
const reverse = (xs) =>
|
|
384
|
+
const reverse = (xs) => {
|
|
385
|
+
const ln = length(xs) - 1;
|
|
386
|
+
return map((_, i) => xs[ln - i], xs);
|
|
387
|
+
};
|
|
382
388
|
const explore = (caption, level = 'log') => tap((v) => console[level](caption, v));
|
|
383
389
|
const cond = curry2((pairs, s) => {
|
|
384
390
|
for (const [cond, fn] of pairs)
|
|
@@ -444,7 +450,6 @@ const freezeShallow = (o) => qfreezeShallow(clone(o));
|
|
|
444
450
|
* @param array T2[]
|
|
445
451
|
*/
|
|
446
452
|
const reduce = curry3((reducer, accum, arr) => qreduce(reducer, clone(accum), arr));
|
|
447
|
-
const pickBy = curry2((cond, o) => filter(cond, o));
|
|
448
453
|
const pick = curry2((props, o) => {
|
|
449
454
|
const out = {};
|
|
450
455
|
for (const p of props)
|
|
@@ -452,6 +457,7 @@ const pick = curry2((props, o) => {
|
|
|
452
457
|
out[p] = o[p];
|
|
453
458
|
return out;
|
|
454
459
|
});
|
|
460
|
+
const pickBy = curry2((cond, o) => compose(flip(pick)(o), qfilter(cond), keys)(o));
|
|
455
461
|
const omit = curry2((props, o) => filter((_, k) => !includes(k, props), o));
|
|
456
462
|
const fromPairs = (pairs) => Object.fromEntries(pairs);
|
|
457
463
|
const concat = curry2(((a, b) => b.concat(a)));
|
|
@@ -502,9 +508,10 @@ const memoize = curry2((keyGen, fn) => {
|
|
|
502
508
|
};
|
|
503
509
|
});
|
|
504
510
|
const mergeShallow = curry2((o1, o2) => Object.assign({}, o1, o2));
|
|
505
|
-
const mergeDeep = curry2((a, b) => qmergeDeep(clone(a),
|
|
506
|
-
const mergeDeepX = curry2((a, b) => qmergeDeepX(clone(a),
|
|
507
|
-
const mergeDeepAdd = curry2((a, b) => qmergeDeepAdd(clone(a),
|
|
511
|
+
const mergeDeep = curry2((a, b) => qmergeDeep(clone(a), b));
|
|
512
|
+
const mergeDeepX = curry2((a, b) => qmergeDeepX(clone(a), b));
|
|
513
|
+
const mergeDeepAdd = curry2((a, b) => qmergeDeepAdd(clone(a), b));
|
|
514
|
+
/** @param prop string @param pipe(data[prop]) @param data any @returns data with prop over pipe. */
|
|
508
515
|
const overProp = curry3((prop, pipe, data) => assoc(prop, pipe(data[prop]), data));
|
|
509
516
|
/** mapKeys({ a: 'b' }, { a: 44 }) -> { b: 44 } */
|
|
510
517
|
const mapKeys = curry2((keyMap, o) => qmapKeys(keyMap, Object.assign({}, o)));
|
|
@@ -529,12 +536,12 @@ const some = any;
|
|
|
529
536
|
const ecran = '\\';
|
|
530
537
|
// TODO: make it splicy, not accumulatie by symbols.
|
|
531
538
|
/** Supports ecrans: '\\{"json": {yes} \\}'
|
|
532
|
-
@returns
|
|
539
|
+
@returns getTmpl('one{meme}two')({meme: 42}) -> one42two */
|
|
533
540
|
const getTmpl = (tmpl) => {
|
|
534
541
|
const parts = [];
|
|
535
542
|
const keymap = [];
|
|
536
543
|
const len = tmpl.length;
|
|
537
|
-
let i = 0, s, ln, start = 0, open = false, hasEcran =
|
|
544
|
+
let i = 0, s, ln, start = 0, open = false, hasEcran = false, hasEcranNext = false, nextChar;
|
|
538
545
|
for (i = 0; i < len; i++) {
|
|
539
546
|
s = tmpl[i];
|
|
540
547
|
switch (s) {
|
|
@@ -713,6 +720,7 @@ exports.qmergeDeepAdd = qmergeDeepAdd;
|
|
|
713
720
|
exports.qmergeDeepX = qmergeDeepX;
|
|
714
721
|
exports.qmergeShallow = qmergeShallow;
|
|
715
722
|
exports.qomit = qomit;
|
|
723
|
+
exports.qoverProp = qoverProp;
|
|
716
724
|
exports.qprepend = qprepend;
|
|
717
725
|
exports.qreduce = qreduce;
|
|
718
726
|
exports.qreverse = qreverse;
|
package/dist/bundle.d.ts
CHANGED
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
// Generated by dts-bundle-generator v9.5.1
|
|
2
2
|
|
|
3
|
+
type AnyArgs = any[];
|
|
4
|
+
type AnyArray<T = any> = T[] | readonly T[];
|
|
5
|
+
type Split<S extends string> = S extends `${infer U}${infer V}` ? [
|
|
6
|
+
U,
|
|
7
|
+
...Split<V>
|
|
8
|
+
] : [
|
|
9
|
+
];
|
|
10
|
+
type IndexesOfArray<A> = Exclude<keyof A, keyof [
|
|
11
|
+
]>;
|
|
3
12
|
export type Cond = (x1?: any, x2?: any, x3?: any) => boolean;
|
|
4
13
|
export interface AnyObject {
|
|
5
14
|
[k: string]: any;
|
|
6
15
|
}
|
|
7
|
-
export type AnyArgs = any[];
|
|
8
16
|
export type Reducer<T = any> = (accum: T, cur: any, index: number) => T;
|
|
9
17
|
export type AnyFunc<ReturnT = any, Args extends AnyArgs = AnyArgs> = (...args: Args) => ReturnT;
|
|
10
|
-
export type TupleFn<ARG1 = any, ARG2 = any, Out = any> = (a: ARG1, b: ARG2) => Out;
|
|
11
18
|
export type Curried<Args extends AnyArgs = AnyArgs, ReturnT = any> = (arg: Args[number]) => Curried<Args> | ReturnT;
|
|
12
|
-
export type BasicType = "String" | "Object" | "Number" | "Symbol" | "Array" | "Null" | "Undefined";
|
|
13
19
|
type Placeholder = symbol;
|
|
14
20
|
export declare const __: Placeholder;
|
|
15
21
|
export declare const curry: (fn: AnyFunc) => (...args: AnyArgs) => any;
|
|
@@ -33,7 +39,7 @@ export declare const typeIs: {
|
|
|
33
39
|
(a: string): (b: any) => boolean;
|
|
34
40
|
(a: string, b: any): boolean;
|
|
35
41
|
};
|
|
36
|
-
declare const length$1: (s:
|
|
42
|
+
declare const length$1: (s: AnyArray | string) => number;
|
|
37
43
|
export declare const isNil: (s: any) => boolean;
|
|
38
44
|
export declare const eq: {
|
|
39
45
|
(a: symbol, b: any): (a: any) => boolean;
|
|
@@ -78,10 +84,10 @@ export declare const bind: {
|
|
|
78
84
|
(a: any, b: any): any;
|
|
79
85
|
};
|
|
80
86
|
export declare const nth: {
|
|
81
|
-
(a: symbol, b: string |
|
|
82
|
-
(a: number, b: symbol): (b: string |
|
|
83
|
-
(a: number): (b: string |
|
|
84
|
-
(a: number, b: string |
|
|
87
|
+
(a: symbol, b: string | any[]): (a: number) => any;
|
|
88
|
+
(a: number, b: symbol): (b: string | any[]) => any;
|
|
89
|
+
(a: number): (b: string | any[]) => any;
|
|
90
|
+
(a: number, b: string | any[]): any;
|
|
85
91
|
};
|
|
86
92
|
export declare const slice: (...args: AnyArgs) => any;
|
|
87
93
|
export declare const flip: <T extends AnyFunc>(fn: T) => {
|
|
@@ -90,10 +96,42 @@ export declare const flip: <T extends AnyFunc>(fn: T) => {
|
|
|
90
96
|
(a: Parameters<T>[1]): (b: Parameters<T>[0]) => any;
|
|
91
97
|
(a: Parameters<T>[1], b: Parameters<T>[0]): any;
|
|
92
98
|
};
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
99
|
+
type FirstChar<T extends string> = T extends `${infer First}${string}` ? Split<T>["length"] extends 1 ? T : FirstChar<First> : T;
|
|
100
|
+
type HeadOverload = {
|
|
101
|
+
<T extends string>(s: T): FirstChar<T>;
|
|
102
|
+
<T extends readonly any[]>(s: T): T extends Array<0> ? undefined : T extends readonly [
|
|
103
|
+
infer U,
|
|
104
|
+
...any[]
|
|
105
|
+
] ? U : T extends (infer Y)[] ? Y : any;
|
|
106
|
+
<T extends any>(s: T[]): null;
|
|
107
|
+
};
|
|
108
|
+
/** @returns first element of an array or a string. */
|
|
109
|
+
export declare const head: HeadOverload;
|
|
110
|
+
type Tail<T extends string> = T extends `${string}${infer Tail}` ? Tail : T extends "" ? "" : string;
|
|
111
|
+
type TailOverload = {
|
|
112
|
+
<T extends string>(s: T): Tail<T>;
|
|
113
|
+
<T extends readonly any[]>(s: T): T extends Array<0> ? [
|
|
114
|
+
] : T extends readonly [
|
|
115
|
+
any,
|
|
116
|
+
...infer U
|
|
117
|
+
] ? U : T;
|
|
118
|
+
<T extends any>(s: T[]): null;
|
|
119
|
+
};
|
|
120
|
+
/** @returns last element of an array or a string. */
|
|
121
|
+
export declare const tail: TailOverload;
|
|
122
|
+
type LastChar<T extends string> = T extends `${string}${infer Rest}` ? (Split<T>["length"] extends 1 ? T : LastChar<Rest>) : T;
|
|
123
|
+
type LastOverload = {
|
|
124
|
+
<T extends string>(s: T): LastChar<T>;
|
|
125
|
+
<T extends readonly any[]>(s: T): T extends Array<0> ? undefined : T extends readonly [
|
|
126
|
+
...any[],
|
|
127
|
+
infer U
|
|
128
|
+
] ? U : T extends (infer Y)[] ? Y : any;
|
|
129
|
+
<T extends any>(s: T[]): null;
|
|
130
|
+
};
|
|
131
|
+
/** Returns last element of an array, readonly array or a string.
|
|
132
|
+
* @param s Array to extract that element.
|
|
133
|
+
* @returns undefined if s is empty or last element. */
|
|
134
|
+
export declare const last: LastOverload;
|
|
97
135
|
/** @param a @param b @returns a+b */
|
|
98
136
|
export declare const add: {
|
|
99
137
|
(a: symbol, b: number): (a: number) => number;
|
|
@@ -144,10 +182,10 @@ export declare const lte: {
|
|
|
144
182
|
(a: number, b: number): boolean;
|
|
145
183
|
};
|
|
146
184
|
export declare const sort: {
|
|
147
|
-
(a: symbol, b: any[]): (a: any) => any[];
|
|
148
|
-
(a: any, b: symbol): (b: any[]) => any[];
|
|
149
|
-
(a: any): (b: any[]) => any[];
|
|
150
|
-
(a: any, b: any[]): any[];
|
|
185
|
+
(a: symbol, b: any[]): (a: (a: any, b: any) => number) => any[];
|
|
186
|
+
(a: (a: any, b: any) => number, b: symbol): (b: any[]) => any[];
|
|
187
|
+
(a: (a: any, b: any) => number): (b: any[]) => any[];
|
|
188
|
+
(a: (a: any, b: any) => number, b: any[]): any[];
|
|
151
189
|
};
|
|
152
190
|
export declare const find: {
|
|
153
191
|
(a: symbol, b: any[]): (a: Cond) => any;
|
|
@@ -174,9 +212,8 @@ export declare const divide: {
|
|
|
174
212
|
(a: number, b: number): number;
|
|
175
213
|
};
|
|
176
214
|
export declare const always: <T = any>(s: T) => () => T;
|
|
177
|
-
export declare const identity: (s:
|
|
215
|
+
export declare const identity: <T = any>(s: T) => T;
|
|
178
216
|
export declare const trim: (s: string) => string;
|
|
179
|
-
export declare const last: (s: any[] | string) => any;
|
|
180
217
|
/** @param start string | any[] @param s string | any[] */
|
|
181
218
|
export declare const startsWith: {
|
|
182
219
|
(a: symbol, b: string | any[]): (a: string | any[]) => boolean;
|
|
@@ -190,11 +227,9 @@ type NotOverload = {
|
|
|
190
227
|
(x: any): boolean;
|
|
191
228
|
};
|
|
192
229
|
export declare const not: NotOverload;
|
|
193
|
-
type IndexesOfArray<A> = Exclude<keyof A, keyof [
|
|
194
|
-
]>;
|
|
195
230
|
type KeysOverload = {
|
|
196
|
-
<T extends any[]>(o: T): string[];
|
|
197
231
|
<T extends readonly any[]>(o: T): IndexesOfArray<T>[];
|
|
232
|
+
<T extends any[]>(o: T): string[];
|
|
198
233
|
<T extends AnyObject>(o: T): (keyof T)[];
|
|
199
234
|
};
|
|
200
235
|
export declare const keys: KeysOverload;
|
|
@@ -284,7 +319,7 @@ export declare const genBy: {
|
|
|
284
319
|
(a: (i: number) => any, b: number): any[];
|
|
285
320
|
};
|
|
286
321
|
export declare const once: <Func extends AnyFunc>(fn: Func) => (...args: Parameters<Func>) => any;
|
|
287
|
-
export declare const reverse: (xs:
|
|
322
|
+
export declare const reverse: <T extends unknown>(xs: T[]) => T[];
|
|
288
323
|
export declare const explore: (caption: string, level?: string) => (b: any) => any;
|
|
289
324
|
export declare const cond: {
|
|
290
325
|
(a: symbol, b: any): (a: [
|
|
@@ -361,18 +396,18 @@ export declare const freezeShallow: <T extends AnyObject>(o: T) => Readonly<T>;
|
|
|
361
396
|
* @param array T2[]
|
|
362
397
|
*/
|
|
363
398
|
export declare const reduce: (...args: AnyArgs) => any;
|
|
364
|
-
export declare const pickBy: {
|
|
365
|
-
(a: symbol, b: AnyObject): (a: Cond) => any;
|
|
366
|
-
(a: Cond, b: symbol): (b: AnyObject) => any;
|
|
367
|
-
(a: Cond): (b: AnyObject) => any;
|
|
368
|
-
(a: Cond, b: AnyObject): any;
|
|
369
|
-
};
|
|
370
399
|
export declare const pick: {
|
|
371
400
|
(a: symbol, b: AnyObject): (a: string[]) => {};
|
|
372
401
|
(a: string[], b: symbol): (b: AnyObject) => {};
|
|
373
402
|
(a: string[]): (b: AnyObject) => {};
|
|
374
403
|
(a: string[], b: AnyObject): {};
|
|
375
404
|
};
|
|
405
|
+
export declare const pickBy: {
|
|
406
|
+
(a: symbol, b: AnyObject): (a: Cond) => any;
|
|
407
|
+
(a: Cond, b: symbol): (b: AnyObject) => any;
|
|
408
|
+
(a: Cond): (b: AnyObject) => any;
|
|
409
|
+
(a: Cond, b: AnyObject): any;
|
|
410
|
+
};
|
|
376
411
|
export declare const omit: {
|
|
377
412
|
(a: symbol, b: AnyObject): (a: string[]) => any;
|
|
378
413
|
(a: string[], b: symbol): (b: AnyObject) => any;
|
|
@@ -459,6 +494,7 @@ export declare const mergeDeepAdd: {
|
|
|
459
494
|
(a: AnyObject): (b: AnyObject) => AnyObject;
|
|
460
495
|
(a: AnyObject, b: AnyObject): AnyObject;
|
|
461
496
|
};
|
|
497
|
+
/** @param prop string @param pipe(data[prop]) @param data any @returns data with prop over pipe. */
|
|
462
498
|
export declare const overProp: (...args: AnyArgs) => any;
|
|
463
499
|
/** mapKeys({ a: 'b' }, { a: 44 }) -> { b: 44 } */
|
|
464
500
|
export declare const mapKeys: {
|
|
@@ -494,9 +530,9 @@ export declare const zipObj: {
|
|
|
494
530
|
* @param b T2[]
|
|
495
531
|
*/
|
|
496
532
|
export declare const zipWith: (...args: AnyArgs) => any;
|
|
497
|
-
export declare const mirror: (s:
|
|
498
|
-
export declare const reflect: (s:
|
|
499
|
-
export declare const echo: (s:
|
|
533
|
+
export declare const mirror: <T = any>(s: T) => T;
|
|
534
|
+
export declare const reflect: <T = any>(s: T) => T;
|
|
535
|
+
export declare const echo: <T = any>(s: T) => T;
|
|
500
536
|
export declare const notf: (fn: AnyFunc) => (...args: any) => boolean | any;
|
|
501
537
|
export declare const push: {
|
|
502
538
|
(a: symbol, b: any[]): (a: any) => any[];
|
|
@@ -521,9 +557,24 @@ export declare const qappend: {
|
|
|
521
557
|
};
|
|
522
558
|
export declare const qassoc: (...args: AnyArgs) => any;
|
|
523
559
|
export declare const qreduce: (...args: AnyArgs) => any;
|
|
524
|
-
export declare const qmergeDeep:
|
|
525
|
-
|
|
526
|
-
|
|
560
|
+
export declare const qmergeDeep: {
|
|
561
|
+
(a: symbol, b: AnyObject): (a: AnyObject) => AnyObject;
|
|
562
|
+
(a: AnyObject, b: symbol): (b: AnyObject) => AnyObject;
|
|
563
|
+
(a: AnyObject): (b: AnyObject) => AnyObject;
|
|
564
|
+
(a: AnyObject, b: AnyObject): AnyObject;
|
|
565
|
+
};
|
|
566
|
+
export declare const qmergeDeepX: {
|
|
567
|
+
(a: symbol, b: AnyObject): (a: AnyObject) => AnyObject;
|
|
568
|
+
(a: AnyObject, b: symbol): (b: AnyObject) => AnyObject;
|
|
569
|
+
(a: AnyObject): (b: AnyObject) => AnyObject;
|
|
570
|
+
(a: AnyObject, b: AnyObject): AnyObject;
|
|
571
|
+
};
|
|
572
|
+
export declare const qmergeDeepAdd: {
|
|
573
|
+
(a: symbol, b: AnyObject): (a: AnyObject) => AnyObject;
|
|
574
|
+
(a: AnyObject, b: symbol): (b: AnyObject) => AnyObject;
|
|
575
|
+
(a: AnyObject): (b: AnyObject) => AnyObject;
|
|
576
|
+
(a: AnyObject, b: AnyObject): AnyObject;
|
|
577
|
+
};
|
|
527
578
|
export declare const qmergeShallow: {
|
|
528
579
|
(a: symbol, b: AnyObject): (a: AnyObject) => AnyObject;
|
|
529
580
|
(a: AnyObject, b: symbol): (b: AnyObject) => AnyObject;
|
|
@@ -563,7 +614,8 @@ export declare const qfilter: {
|
|
|
563
614
|
(a: (v: any, k: string | number) => boolean): (b: any[] | AnyObject) => any[] | AnyObject;
|
|
564
615
|
(a: (v: any, k: string | number) => boolean, b: any[] | AnyObject): any[] | AnyObject;
|
|
565
616
|
};
|
|
566
|
-
export declare const qempty:
|
|
617
|
+
export declare const qempty: <T extends any[] | AnyObject>(o: T) => T extends any[] ? [
|
|
618
|
+
] : {};
|
|
567
619
|
export declare const qfreeze: <T extends AnyObject>(o: T) => Readonly<T>;
|
|
568
620
|
export declare const qfreezeShallow: <T extends AnyObject>(o: T) => Readonly<T>;
|
|
569
621
|
export declare const qprepend: {
|
|
@@ -587,9 +639,11 @@ export declare const qstartsWith: {
|
|
|
587
639
|
(a: string | any[]): (b: string | any[]) => boolean;
|
|
588
640
|
(a: string | any[], b: string | any[]): boolean;
|
|
589
641
|
};
|
|
642
|
+
/** @param prop string @param pipe(data[prop]) @param data any @returns data with prop over pipe. */
|
|
643
|
+
export declare const qoverProp: (...args: AnyArgs) => any;
|
|
590
644
|
type StrTmpl = ((data: AnyObject) => string);
|
|
591
645
|
/** Supports ecrans: '\\{"json": {yes} \\}'
|
|
592
|
-
@returns
|
|
646
|
+
@returns getTmpl('one{meme}two')({meme: 42}) -> one42two */
|
|
593
647
|
export declare const getTmpl: (tmpl: string) => StrTmpl;
|
|
594
648
|
/** One promise waits for another. */
|
|
595
649
|
export declare const forEachSerial: {
|
package/dist/bundle.mjs
CHANGED
|
@@ -134,7 +134,6 @@ const qstartsWithWith = (comparator) => curry2((start, s) => {
|
|
|
134
134
|
return true;
|
|
135
135
|
});
|
|
136
136
|
|
|
137
|
-
// TODO: qoverProp, qover array ?
|
|
138
137
|
/** Then next fns seem to be excess due to their safe ver performance should be the same or better:
|
|
139
138
|
* qflat, qpick
|
|
140
139
|
*/
|
|
@@ -142,7 +141,7 @@ const qappend = curry2((s, xs) => { xs.push(s); return xs; });
|
|
|
142
141
|
const qassoc = curry3((prop, v, obj) => { obj[prop] = v; return obj; });
|
|
143
142
|
const qreduce = curry3((fn, accum, arr) => arr.reduce(fn, accum));
|
|
144
143
|
// strategy is for arrays: 1->clean, 2->merge, 3->push.
|
|
145
|
-
const mergeDeep$1 =
|
|
144
|
+
const mergeDeep$1 = (strategy) => curry2((o1, o2) => {
|
|
146
145
|
for (let k in o2) {
|
|
147
146
|
switch (type(o2[k])) {
|
|
148
147
|
case 'Array':
|
|
@@ -152,7 +151,7 @@ const mergeDeep$1 = curry3((strategy, o1, o2) => {
|
|
|
152
151
|
const o1k = o1[k], o2k = o2[k];
|
|
153
152
|
for (const i in o2k)
|
|
154
153
|
if (o1k[i])
|
|
155
|
-
mergeDeep$1(strategy
|
|
154
|
+
mergeDeep$1(strategy)(o1k[i], o2k[i]);
|
|
156
155
|
else
|
|
157
156
|
o1k[i] = o2k[i];
|
|
158
157
|
break;
|
|
@@ -163,7 +162,7 @@ const mergeDeep$1 = curry3((strategy, o1, o2) => {
|
|
|
163
162
|
break;
|
|
164
163
|
case 'Object':
|
|
165
164
|
if (type(o1[k]) === 'Object') {
|
|
166
|
-
mergeDeep$1(strategy
|
|
165
|
+
mergeDeep$1(strategy)(o1[k], o2[k]);
|
|
167
166
|
break;
|
|
168
167
|
}
|
|
169
168
|
default:
|
|
@@ -193,7 +192,7 @@ const qmapKeys = curry2((keyMap, o) => {
|
|
|
193
192
|
return o;
|
|
194
193
|
});
|
|
195
194
|
const qmap = curry2((pipe, arr) => {
|
|
196
|
-
for (
|
|
195
|
+
for (const i in arr)
|
|
197
196
|
arr[i] = pipe(arr[i], +i, arr);
|
|
198
197
|
return arr;
|
|
199
198
|
});
|
|
@@ -245,6 +244,8 @@ const qreverse = (arr) => arr.reverse();
|
|
|
245
244
|
const qomit = curry2((props, o) => qfilter((_, k) => !includes(k, props), o));
|
|
246
245
|
/** @param start string | any[] @param s string | any[] */
|
|
247
246
|
const qstartsWith = qstartsWithWith(eq);
|
|
247
|
+
/** @param prop string @param pipe(data[prop]) @param data any @returns data with prop over pipe. */
|
|
248
|
+
const qoverProp = curry3((prop, pipe, data) => qassoc(prop, pipe(data[prop]), data));
|
|
248
249
|
|
|
249
250
|
// TODO: possibly introduce a second argument limiting unfolding.
|
|
250
251
|
const uncurry = (fn) => (...args) => qreduce(((fn, arg) => fn ? fn(arg) : fn), fn, args);
|
|
@@ -271,10 +272,14 @@ const bind = curry2((fn, context) => fn.bind(context));
|
|
|
271
272
|
const nth = curry2((i, data) => data[i]);
|
|
272
273
|
const slice = curry3((from, to, o) => o.slice(from, (isNum(to) ? to : inf)));
|
|
273
274
|
const flip = (fn) => curry2((b, a) => fn(a, b));
|
|
274
|
-
/** @returns first element of an array. */
|
|
275
|
+
/** @returns first element of an array or a string. */
|
|
275
276
|
const head = nth(0);
|
|
276
|
-
/** @returns last element of an array. */
|
|
277
|
+
/** @returns last element of an array or a string. */
|
|
277
278
|
const tail = slice(1, inf);
|
|
279
|
+
/** Returns last element of an array, readonly array or a string.
|
|
280
|
+
* @param s Array to extract that element.
|
|
281
|
+
* @returns undefined if s is empty or last element. */
|
|
282
|
+
const last = (s) => s[length(s) - 1];
|
|
278
283
|
/** @param a @param b @returns a+b */
|
|
279
284
|
const add = curry2((a, b) => a + b);
|
|
280
285
|
/** @param a @param b @returns b-a */
|
|
@@ -293,11 +298,10 @@ const sort = curry2((sortFn, xs) => xs.sort(sortFn));
|
|
|
293
298
|
const find = curry2((fn, s) => s.find(fn));
|
|
294
299
|
const findIndex = curry2((fn, s) => s.findIndex(fn));
|
|
295
300
|
const indexOf = curry2((x, xs) => findIndex(equals(x), xs));
|
|
296
|
-
const divide = curry2((
|
|
301
|
+
const divide = curry2((a, b) => b / a);
|
|
297
302
|
const always = (s) => () => s;
|
|
298
303
|
const identity = (s) => s;
|
|
299
304
|
const trim = (s) => s.trim();
|
|
300
|
-
const last = (s) => s[length(s) - 1];
|
|
301
305
|
/** @param start string | any[] @param s string | any[] */
|
|
302
306
|
const startsWith = qstartsWithWith((x, y) => equals(x, y));
|
|
303
307
|
const not = (x) => !x;
|
|
@@ -341,14 +345,13 @@ const range = curry2((from, to) => genBy(add(from), to - from));
|
|
|
341
345
|
const uniq = (xs) => qreduce((accum, x) => find(equals(x), accum) ? accum : qappend(x, accum), [], xs);
|
|
342
346
|
const intersection = curry2((xs1, xs2) => xs1.filter(flip(includes)(xs2)));
|
|
343
347
|
const diff = curry2((_xs1, _xs2) => {
|
|
344
|
-
// BUG: if _xs1 is empty, results in [undefined, ...]
|
|
345
348
|
let len1 = length(_xs1);
|
|
346
|
-
let len2 = length(_xs2);
|
|
347
|
-
const xs1 = len1 > len2 ? _xs1 : _xs2;
|
|
348
|
-
const xs2 = len1 > len2 ? _xs2 : _xs1;
|
|
349
|
-
if (len1
|
|
349
|
+
let len2 = length(_xs2);
|
|
350
|
+
const xs1 = len1 > len2 ? _xs1 : _xs2;
|
|
351
|
+
const xs2 = len1 > len2 ? _xs2 : _xs1;
|
|
352
|
+
if (len1 < len2)
|
|
350
353
|
[len1, len2] = [len2, len1];
|
|
351
|
-
const xset2 = new Set(xs2);
|
|
354
|
+
const xset2 = new Set(xs2);
|
|
352
355
|
const common = new Set();
|
|
353
356
|
const out = [];
|
|
354
357
|
let i;
|
|
@@ -376,7 +379,10 @@ const once = (fn) => {
|
|
|
376
379
|
return cache = fn(...args);
|
|
377
380
|
};
|
|
378
381
|
};
|
|
379
|
-
const reverse = (xs) =>
|
|
382
|
+
const reverse = (xs) => {
|
|
383
|
+
const ln = length(xs) - 1;
|
|
384
|
+
return map((_, i) => xs[ln - i], xs);
|
|
385
|
+
};
|
|
380
386
|
const explore = (caption, level = 'log') => tap((v) => console[level](caption, v));
|
|
381
387
|
const cond = curry2((pairs, s) => {
|
|
382
388
|
for (const [cond, fn] of pairs)
|
|
@@ -442,7 +448,6 @@ const freezeShallow = (o) => qfreezeShallow(clone(o));
|
|
|
442
448
|
* @param array T2[]
|
|
443
449
|
*/
|
|
444
450
|
const reduce = curry3((reducer, accum, arr) => qreduce(reducer, clone(accum), arr));
|
|
445
|
-
const pickBy = curry2((cond, o) => filter(cond, o));
|
|
446
451
|
const pick = curry2((props, o) => {
|
|
447
452
|
const out = {};
|
|
448
453
|
for (const p of props)
|
|
@@ -450,6 +455,7 @@ const pick = curry2((props, o) => {
|
|
|
450
455
|
out[p] = o[p];
|
|
451
456
|
return out;
|
|
452
457
|
});
|
|
458
|
+
const pickBy = curry2((cond, o) => compose(flip(pick)(o), qfilter(cond), keys)(o));
|
|
453
459
|
const omit = curry2((props, o) => filter((_, k) => !includes(k, props), o));
|
|
454
460
|
const fromPairs = (pairs) => Object.fromEntries(pairs);
|
|
455
461
|
const concat = curry2(((a, b) => b.concat(a)));
|
|
@@ -500,9 +506,10 @@ const memoize = curry2((keyGen, fn) => {
|
|
|
500
506
|
};
|
|
501
507
|
});
|
|
502
508
|
const mergeShallow = curry2((o1, o2) => Object.assign({}, o1, o2));
|
|
503
|
-
const mergeDeep = curry2((a, b) => qmergeDeep(clone(a),
|
|
504
|
-
const mergeDeepX = curry2((a, b) => qmergeDeepX(clone(a),
|
|
505
|
-
const mergeDeepAdd = curry2((a, b) => qmergeDeepAdd(clone(a),
|
|
509
|
+
const mergeDeep = curry2((a, b) => qmergeDeep(clone(a), b));
|
|
510
|
+
const mergeDeepX = curry2((a, b) => qmergeDeepX(clone(a), b));
|
|
511
|
+
const mergeDeepAdd = curry2((a, b) => qmergeDeepAdd(clone(a), b));
|
|
512
|
+
/** @param prop string @param pipe(data[prop]) @param data any @returns data with prop over pipe. */
|
|
506
513
|
const overProp = curry3((prop, pipe, data) => assoc(prop, pipe(data[prop]), data));
|
|
507
514
|
/** mapKeys({ a: 'b' }, { a: 44 }) -> { b: 44 } */
|
|
508
515
|
const mapKeys = curry2((keyMap, o) => qmapKeys(keyMap, Object.assign({}, o)));
|
|
@@ -527,12 +534,12 @@ const some = any;
|
|
|
527
534
|
const ecran = '\\';
|
|
528
535
|
// TODO: make it splicy, not accumulatie by symbols.
|
|
529
536
|
/** Supports ecrans: '\\{"json": {yes} \\}'
|
|
530
|
-
@returns
|
|
537
|
+
@returns getTmpl('one{meme}two')({meme: 42}) -> one42two */
|
|
531
538
|
const getTmpl = (tmpl) => {
|
|
532
539
|
const parts = [];
|
|
533
540
|
const keymap = [];
|
|
534
541
|
const len = tmpl.length;
|
|
535
|
-
let i = 0, s, ln, start = 0, open = false, hasEcran =
|
|
542
|
+
let i = 0, s, ln, start = 0, open = false, hasEcran = false, hasEcranNext = false, nextChar;
|
|
536
543
|
for (i = 0; i < len; i++) {
|
|
537
544
|
s = tmpl[i];
|
|
538
545
|
switch (s) {
|
|
@@ -603,4 +610,4 @@ const composeAsync = (() => {
|
|
|
603
610
|
return (...fns) => (...input) => pipe(fns, input, fns.length - 1);
|
|
604
611
|
})();
|
|
605
612
|
|
|
606
|
-
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, 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, 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 };
|
|
613
|
+
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, diff, divide, echo, empty, eq, equals, explore, filter, find, findIndex, flat, flatShallow, flatTo, flip, forEach, forEachAsync, forEachSerial, freeze, freezeShallow, fromPairs, genBy, getTmpl, gt, gte, head, identity, ifElse, includes, indexOf, intersection, isEmpty, isNil, join, keys, last, length, lt, lte, map, mapKeys, mapObj, memoize, mergeDeep, mergeDeepAdd, mergeDeepX, mergeShallow, mirror, multiply, noop, not, notf, nth, omit, once, overProp, path, pathEq, pathExists, pathOr, pathsEq, pick, pickBy, prepend, prop, propEq, propsEq, push, qappend, qassoc, qassocPath, qempty, qfilter, qfreeze, qfreezeShallow, qmap, qmapKeys, qmapObj, qmergeDeep, qmergeDeepAdd, qmergeDeepX, qmergeShallow, qomit, qoverProp, qprepend, 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
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"prod": "npm run gentypes && npm run prod:es && npm run prod:cjs",
|
|
43
43
|
"all": "npm run dev && npm run prod"
|
|
44
44
|
},
|
|
45
|
-
"version": "1.
|
|
45
|
+
"version": "1.6.0",
|
|
46
46
|
"ava": {
|
|
47
47
|
"files": [
|
|
48
48
|
"./test/specs/*.ts"
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"dts-bundle-generator": "^9.5.1",
|
|
68
68
|
"nyc": "^15.1.0",
|
|
69
69
|
"prepend": "^1.0.2",
|
|
70
|
-
"rollup": "^4.
|
|
70
|
+
"rollup": "^4.17.0",
|
|
71
71
|
"rollup-plugin-typescript2": "^0.36.0",
|
|
72
72
|
"ts-node": "^10.9.2",
|
|
73
73
|
"tslint": "^6.1.3",
|
package/src/common.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { curry2 } from "./curry"
|
|
2
|
+
import { AnyArray } from "./internal_types"
|
|
2
3
|
import { to, isNull, isStr, isUndef } from "./utils"
|
|
3
4
|
|
|
4
5
|
// It's faster that toUpperCase() !
|
|
@@ -14,7 +15,7 @@ export const type = (s: any): string => {
|
|
|
14
15
|
: caseMap[t[0]] + t.slice(1)
|
|
15
16
|
}
|
|
16
17
|
export const typeIs = curry2((t: string, s: any) => type(s)===t)
|
|
17
|
-
export const length = (s:
|
|
18
|
+
export const length = (s: AnyArray | string) => s.length
|
|
18
19
|
export const isNil = (s: any) => isNull(s) || isUndef(s)
|
|
19
20
|
export const eq = curry2((a: any, b: any) => a===b)
|
|
20
21
|
export const equals = curry2((a: any, b: any) => {
|
package/src/curry.ts
CHANGED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type AnyArgs = any[]
|
|
2
|
+
export type BasicType = 'String'|'Object'|'Number'|'Symbol'|'Array'|'Null'|'Undefined'
|
|
3
|
+
export type TupleFn<ARG1=any, ARG2=any, Out=any> = (a: ARG1, b: ARG2) => Out
|
|
4
|
+
export type IDArray = Uint8Array|Uint16Array|Uint32Array
|
|
5
|
+
export type AnyArray<T=any> = T[] | readonly T[]
|
|
6
|
+
export type Split<S extends string> = S extends `${infer U}${infer V}` ? [U, ...Split<V>] : []
|
|
7
|
+
export type IndexesOfArray<A> = Exclude<keyof A, keyof []>
|
package/src/quick.ts
CHANGED
|
@@ -2,8 +2,6 @@ import { curry2, curry3 } from "./curry"
|
|
|
2
2
|
import { includes, isNil, type, eq, qstartsWithWith } from "./common"
|
|
3
3
|
import { AnyObject, Reducer, AnyFunc } from "./types"
|
|
4
4
|
import { isFunc, isArray, isObj } from "./utils"
|
|
5
|
-
// TODO: qoverProp, qover array ?
|
|
6
|
-
|
|
7
5
|
/** Then next fns seem to be excess due to their safe ver performance should be the same or better:
|
|
8
6
|
* qflat, qpick
|
|
9
7
|
*/
|
|
@@ -12,7 +10,7 @@ export const qappend = curry2((s: any, xs: any[]) => {xs.push(s); return xs})
|
|
|
12
10
|
export const qassoc = curry3((prop: string, v: any, obj: AnyObject) => { obj[prop] = v; return obj })
|
|
13
11
|
export const qreduce = curry3(<T>(fn: Reducer, accum: any, arr: T[]) => arr.reduce(fn, accum))
|
|
14
12
|
// strategy is for arrays: 1->clean, 2->merge, 3->push.
|
|
15
|
-
const mergeDeep =
|
|
13
|
+
const mergeDeep = (strategy: 1|2|3) => curry2((o1: AnyObject, o2: AnyObject): AnyObject => {
|
|
16
14
|
for(let k in o2) {
|
|
17
15
|
switch(type(o2[k])) {
|
|
18
16
|
case 'Array':
|
|
@@ -21,7 +19,7 @@ const mergeDeep = curry3((strategy: 1|2|3, o1: AnyObject, o2: AnyObject): AnyObj
|
|
|
21
19
|
case 2:
|
|
22
20
|
const o1k = o1[k], o2k = o2[k]
|
|
23
21
|
for(const i in o2k)
|
|
24
|
-
if(o1k[i]) mergeDeep(strategy
|
|
22
|
+
if(o1k[i]) mergeDeep(strategy)(o1k[i], o2k[i])
|
|
25
23
|
else o1k[i] = o2k[i]
|
|
26
24
|
break
|
|
27
25
|
case 3: o1[k].push(...o2[k])
|
|
@@ -31,7 +29,7 @@ const mergeDeep = curry3((strategy: 1|2|3, o1: AnyObject, o2: AnyObject): AnyObj
|
|
|
31
29
|
break
|
|
32
30
|
case 'Object':
|
|
33
31
|
if(type(o1[k])==='Object') {
|
|
34
|
-
mergeDeep(strategy
|
|
32
|
+
mergeDeep(strategy)(o1[k], o2[k])
|
|
35
33
|
break
|
|
36
34
|
}
|
|
37
35
|
default:
|
|
@@ -65,7 +63,7 @@ export const qmapKeys = curry2(
|
|
|
65
63
|
)
|
|
66
64
|
export const qmap = curry2(
|
|
67
65
|
(pipe: (s: any, i?: number, list?: any[]) => any, arr: any[]) => {
|
|
68
|
-
for(
|
|
66
|
+
for(const i in arr) arr[i] = pipe(arr[i], +i, arr)
|
|
69
67
|
return arr
|
|
70
68
|
}
|
|
71
69
|
)
|
|
@@ -93,10 +91,10 @@ export const qfilter = curry2(
|
|
|
93
91
|
return data
|
|
94
92
|
}
|
|
95
93
|
)
|
|
96
|
-
export const qempty =
|
|
94
|
+
export const qempty = <T extends AnyObject|any[]>(o: T): T extends any[] ? [] : {} => {
|
|
97
95
|
if(isArray(o)) o.splice(0)
|
|
98
96
|
else for(const i in o) delete o[i]
|
|
99
|
-
return o
|
|
97
|
+
return o as any
|
|
100
98
|
}
|
|
101
99
|
export const qfreeze = <T extends AnyObject>(o: T): Readonly<T> => {
|
|
102
100
|
let v: any
|
|
@@ -124,4 +122,9 @@ export const qomit = curry2(
|
|
|
124
122
|
)
|
|
125
123
|
)
|
|
126
124
|
/** @param start string | any[] @param s string | any[] */
|
|
127
|
-
export const qstartsWith = qstartsWithWith(eq)
|
|
125
|
+
export const qstartsWith = qstartsWithWith(eq)
|
|
126
|
+
/** @param prop string @param pipe(data[prop]) @param data any @returns data with prop over pipe. */
|
|
127
|
+
export const qoverProp = curry3(
|
|
128
|
+
(prop: string, pipe: AnyFunc, data: any) =>
|
|
129
|
+
qassoc(prop, pipe(data[prop]), data)
|
|
130
|
+
)
|
package/src/safe.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { __, curry, curry2, curry3 } from './curry'
|
|
2
|
-
import { isNum, undef,
|
|
2
|
+
import { isNum, undef, isArray, isFunc, isObj, inf } from './utils'
|
|
3
3
|
import { qmergeDeep, qreduce, qappend, qmapKeys, qmergeDeepX, qmergeDeepAdd, qfilter, qfreeze, qfreezeShallow, qmapObj } from './quick'
|
|
4
4
|
import { AnyFunc, Cond, AnyObject, Reducer } from './types'
|
|
5
5
|
import { symbol, type, length, equals, includes, isNil, qstartsWithWith } from './common'
|
|
6
|
+
import { Split, AnyArray, IndexesOfArray } from './internal_types'
|
|
6
7
|
// over, lensProp
|
|
7
8
|
|
|
8
9
|
export const take = (argN: number) => (...args: any[]) => args[argN]
|
|
@@ -38,10 +39,8 @@ export const compose = (
|
|
|
38
39
|
return s as any as TOut
|
|
39
40
|
}
|
|
40
41
|
)
|
|
41
|
-
export const bind = curry2<AnyFunc>(
|
|
42
|
-
|
|
43
|
-
)
|
|
44
|
-
export const nth = curry2(<T=any>(i: number, data: T[] | string) => data[i])
|
|
42
|
+
export const bind = curry2<AnyFunc>((fn: AnyFunc, context: any) => fn.bind(context))
|
|
43
|
+
export const nth = curry2((i: number, data: any[] | string) => data[i])
|
|
45
44
|
export const slice = curry3(
|
|
46
45
|
(from: number, to: number, o: any[] | string) =>
|
|
47
46
|
o.slice(from, (isNum(to)?to:inf) as number)
|
|
@@ -49,10 +48,42 @@ export const slice = curry3(
|
|
|
49
48
|
export const flip = <T extends AnyFunc>(fn: T) => curry2(
|
|
50
49
|
(b: Parameters<T>[1], a: Parameters<T>[0]) => fn(a, b)
|
|
51
50
|
)
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
51
|
+
type FirstChar<T extends string> = T extends `${infer First}${string}`
|
|
52
|
+
? Split<T>['length'] extends 1 ? T : FirstChar<First>
|
|
53
|
+
: T
|
|
54
|
+
type HeadOverload = {
|
|
55
|
+
<T extends string>(s: T): FirstChar<T>
|
|
56
|
+
<T extends readonly any[]>(s: T): T extends Array<0> ? undefined
|
|
57
|
+
: T extends readonly [infer U, ...any[]] ? U
|
|
58
|
+
: T extends (infer Y)[] ? Y : any
|
|
59
|
+
<T extends any>(s: T[]): null
|
|
60
|
+
}
|
|
61
|
+
/** @returns first element of an array or a string. */
|
|
62
|
+
export const head = nth(0) as HeadOverload
|
|
63
|
+
type Tail<T extends string> = T extends `${string}${infer Tail}`
|
|
64
|
+
? Tail : T extends '' ? '' : string
|
|
65
|
+
type TailOverload = {
|
|
66
|
+
<T extends string>(s: T): Tail<T>
|
|
67
|
+
<T extends readonly any[]>(s: T): T extends Array<0> ? []
|
|
68
|
+
: T extends readonly [any, ...infer U] ? U : T
|
|
69
|
+
<T extends any>(s: T[]): null
|
|
70
|
+
}
|
|
71
|
+
/** @returns last element of an array or a string. */
|
|
72
|
+
export const tail = slice(1, inf) as TailOverload
|
|
73
|
+
type LastChar<T extends string> = T extends `${string}${infer Rest}`
|
|
74
|
+
? (Split<T>['length'] extends 1 ? T : LastChar<Rest>) : T
|
|
75
|
+
type LastOverload = {
|
|
76
|
+
<T extends string>(s: T): LastChar<T>
|
|
77
|
+
<T extends readonly any[]>(s: T): T extends Array<0>
|
|
78
|
+
? undefined
|
|
79
|
+
: T extends readonly [...any[], infer U] ? U
|
|
80
|
+
: T extends (infer Y)[] ? Y : any
|
|
81
|
+
<T extends any>(s: T[]): null
|
|
82
|
+
}
|
|
83
|
+
/** Returns last element of an array, readonly array or a string.
|
|
84
|
+
* @param s Array to extract that element.
|
|
85
|
+
* @returns undefined if s is empty or last element. */
|
|
86
|
+
export const last: LastOverload = (s: string | AnyArray) => s[length(s)-1]
|
|
56
87
|
/** @param a @param b @returns a+b */
|
|
57
88
|
export const add = curry2((a: number, b: number) => a+b)
|
|
58
89
|
/** @param a @param b @returns b-a */
|
|
@@ -67,15 +98,15 @@ export const lt = curry2( (a: number, b: number) => a>b )
|
|
|
67
98
|
export const gte = curry2( (a: number, b: number) => a<=b )
|
|
68
99
|
/** @param a @param b @returns a≥b */
|
|
69
100
|
export const lte = curry2( (a: number, b: number) => a>=b )
|
|
70
|
-
export const sort = curry2((sortFn: any, xs: any[]) => xs.sort(sortFn))
|
|
101
|
+
export const sort = curry2((sortFn: (a: any, b: any) => number , xs: any[]) => xs.sort(sortFn))
|
|
71
102
|
export const find = curry2((fn: Cond, s: any[]) => s.find(fn))
|
|
72
103
|
export const findIndex = curry2((fn: Cond, s: any[]) => s.findIndex(fn))
|
|
73
104
|
export const indexOf = curry2((x: any, xs: any[]) => findIndex(equals(x), xs))
|
|
74
|
-
export const divide = curry2((
|
|
105
|
+
export const divide = curry2((a: number, b: number) => b/a)
|
|
75
106
|
export const always = <T=any>(s: T) => () => s
|
|
76
|
-
export const identity = (s:
|
|
107
|
+
export const identity = <T=any>(s: T) => s
|
|
77
108
|
export const trim = (s: string) => s.trim()
|
|
78
|
-
|
|
109
|
+
|
|
79
110
|
/** @param start string | any[] @param s string | any[] */
|
|
80
111
|
export const startsWith = qstartsWithWith((x: any, y: any) => equals(x, y))
|
|
81
112
|
type NotOverload = {
|
|
@@ -84,14 +115,12 @@ type NotOverload = {
|
|
|
84
115
|
(x: any): boolean
|
|
85
116
|
}
|
|
86
117
|
export const not: NotOverload = (x: any) => !x as any
|
|
87
|
-
type IndexesOfArray<A> = Exclude<keyof A, keyof []>
|
|
88
118
|
type KeysOverload = {
|
|
89
|
-
<T extends any[]>(o: T): string[]
|
|
90
119
|
<T extends readonly any[]>(o: T): IndexesOfArray<T>[]
|
|
120
|
+
<T extends any[]>(o: T): string[]
|
|
91
121
|
<T extends AnyObject>(o: T): (keyof T)[]
|
|
92
122
|
}
|
|
93
|
-
export const keys: KeysOverload = (o:
|
|
94
|
-
|
|
123
|
+
export const keys: KeysOverload = (o: any) => Object.keys(o)
|
|
95
124
|
export const values = (o: AnyObject | any[]) => Object.values(o)
|
|
96
125
|
export const toPairs = (o: AnyObject | any[]) => Object.entries(o)
|
|
97
126
|
export const test = curry2((re: RegExp, s: string) => re.test(s))
|
|
@@ -131,13 +160,12 @@ export const uniq = (xs: any[]) => qreduce(
|
|
|
131
160
|
[], xs)
|
|
132
161
|
export const intersection = curry2((xs1: any[], xs2: any[]) => xs1.filter(flip(includes)(xs2)))
|
|
133
162
|
export const diff = curry2((_xs1: any[], _xs2: any[]) => {
|
|
134
|
-
// BUG: if _xs1 is empty, results in [undefined, ...]
|
|
135
163
|
let len1 = length(_xs1)
|
|
136
|
-
let len2 = length(_xs2)
|
|
137
|
-
const xs1 = len1>len2 ? _xs1 : _xs2
|
|
138
|
-
const xs2 = len1>len2 ? _xs2 : _xs1
|
|
139
|
-
if(len1
|
|
140
|
-
const xset2 = new Set(xs2)
|
|
164
|
+
let len2 = length(_xs2)
|
|
165
|
+
const xs1 = len1>len2 ? _xs1 : _xs2
|
|
166
|
+
const xs2 = len1>len2 ? _xs2 : _xs1
|
|
167
|
+
if(len1<len2) [len1, len2] = [len2, len1]
|
|
168
|
+
const xset2 = new Set(xs2)
|
|
141
169
|
const common = new Set()
|
|
142
170
|
const out: any[] = []
|
|
143
171
|
let i: number
|
|
@@ -166,14 +194,10 @@ export const once = <Func extends AnyFunc>(fn: Func) => {
|
|
|
166
194
|
return cache = fn(...args)
|
|
167
195
|
}
|
|
168
196
|
}
|
|
169
|
-
export const reverse = (xs:
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
),
|
|
174
|
-
add(-1),
|
|
175
|
-
length
|
|
176
|
-
)(xs)
|
|
197
|
+
export const reverse = <T extends any>(xs: T[]): T[] => {
|
|
198
|
+
const ln = length(xs)-1
|
|
199
|
+
return map((_: any, i: number) => xs[ln-i], xs)
|
|
200
|
+
}
|
|
177
201
|
export const explore = (caption: string, level = 'log') => tap(
|
|
178
202
|
(v: any) => console[level](caption, v)
|
|
179
203
|
)
|
|
@@ -266,17 +290,16 @@ export const reduce = curry3(
|
|
|
266
290
|
<T = any>(reducer: Reducer<T>, accum: T, arr: any[]) =>
|
|
267
291
|
qreduce(reducer, clone(accum), arr)
|
|
268
292
|
)
|
|
269
|
-
export const pickBy = curry2(
|
|
270
|
-
(cond: Cond, o: AnyObject) => filter(cond, o)
|
|
271
|
-
)
|
|
272
293
|
export const pick = curry2(
|
|
273
294
|
(props: string[], o: AnyObject) => {
|
|
274
295
|
const out = {}
|
|
275
|
-
for(const p of props)
|
|
276
|
-
if(p in o) out[p] = o[p]
|
|
296
|
+
for(const p of props) if(p in o) out[p] = o[p]
|
|
277
297
|
return out
|
|
278
298
|
}
|
|
279
299
|
)
|
|
300
|
+
export const pickBy = curry2(
|
|
301
|
+
(cond: Cond, o: AnyObject) => compose(flip(pick)(o), qfilter(cond), keys)(o)
|
|
302
|
+
)
|
|
280
303
|
export const omit = curry2(
|
|
281
304
|
(props: string[], o: AnyObject) => filter(
|
|
282
305
|
(_: any, k: string) => !includes(k, props),
|
|
@@ -354,14 +377,15 @@ export const mergeShallow = curry2(
|
|
|
354
377
|
Object.assign({}, o1, o2)
|
|
355
378
|
)
|
|
356
379
|
export const mergeDeep = curry2(
|
|
357
|
-
(a: AnyObject, b: AnyObject) => qmergeDeep(clone(a),
|
|
380
|
+
(a: AnyObject, b: AnyObject) => qmergeDeep(clone(a), b) as AnyObject
|
|
358
381
|
)
|
|
359
382
|
export const mergeDeepX = curry2(
|
|
360
|
-
(a: AnyObject, b: AnyObject) => qmergeDeepX(clone(a),
|
|
383
|
+
(a: AnyObject, b: AnyObject) => qmergeDeepX(clone(a), b) as AnyObject
|
|
361
384
|
)
|
|
362
385
|
export const mergeDeepAdd = curry2(
|
|
363
|
-
(a: AnyObject, b: AnyObject) => qmergeDeepAdd(clone(a),
|
|
386
|
+
(a: AnyObject, b: AnyObject) => qmergeDeepAdd(clone(a), b) as AnyObject
|
|
364
387
|
)
|
|
388
|
+
/** @param prop string @param pipe(data[prop]) @param data any @returns data with prop over pipe. */
|
|
365
389
|
export const overProp = curry3(
|
|
366
390
|
(prop: string, pipe: AnyFunc, data: any) =>
|
|
367
391
|
assoc(prop, pipe(data[prop]), data)
|
package/src/strings.ts
CHANGED
|
@@ -6,13 +6,13 @@ const ecran = '\\'
|
|
|
6
6
|
|
|
7
7
|
// TODO: make it splicy, not accumulatie by symbols.
|
|
8
8
|
/** Supports ecrans: '\\{"json": {yes} \\}'
|
|
9
|
-
@returns
|
|
9
|
+
@returns getTmpl('one{meme}two')({meme: 42}) -> one42two */
|
|
10
10
|
export const getTmpl = (tmpl: string): StrTmpl => {
|
|
11
11
|
const parts: string[] = []
|
|
12
12
|
const keymap: string[] = []
|
|
13
13
|
const len = tmpl.length
|
|
14
14
|
let i = 0, s: string, ln: number, start = 0, open = false,
|
|
15
|
-
hasEcran =
|
|
15
|
+
hasEcran = false, hasEcranNext = false, nextChar: string
|
|
16
16
|
for(i=0; i<len; i++) {
|
|
17
17
|
s = tmpl[i]
|
|
18
18
|
switch(s) {
|
package/src/types.ts
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
|
+
import { AnyArgs } from "./internal_types"
|
|
2
|
+
|
|
1
3
|
export type Cond = (x1?: any, x2?: any, x3?: any) => boolean
|
|
2
4
|
export interface AnyObject { [k: string]: any }
|
|
3
|
-
export type AnyArgs = any[]
|
|
4
5
|
export type Reducer<T=any> = (accum: T, cur: any, index: number) => T
|
|
5
6
|
export type AnyFunc<ReturnT = any, Args extends AnyArgs = AnyArgs> = (...args: Args) => ReturnT
|
|
6
|
-
export type
|
|
7
|
-
export type Curried<
|
|
8
|
-
Args extends AnyArgs = AnyArgs,
|
|
9
|
-
ReturnT = any
|
|
10
|
-
> = (arg: Args[number]) => Curried<Args> | ReturnT
|
|
11
|
-
export type BasicType = 'String'|'Object'|'Number'|'Symbol'|'Array'|'Null'|'Undefined'
|
|
7
|
+
export type Curried<Args extends AnyArgs = AnyArgs, ReturnT = any> = (arg: Args[number]) => Curried<Args> | ReturnT
|