atomic-fns 0.2.2 → 0.3.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/.firebaserc +5 -0
- package/README.md +9 -4
- package/firebase.json +10 -0
- package/package.json +9 -9
- package/src/collections/index.d.ts +672 -0
- package/src/collections/index.js +1091 -0
- package/src/collections/index.ts +1186 -0
- package/src/datetime/index.d.ts +6 -0
- package/src/datetime/index.js +6 -0
- package/src/datetime/index.ts +7 -0
- package/src/functools/index.d.ts +107 -0
- package/src/functools/index.js +219 -0
- package/src/functools/index.ts +255 -0
- package/src/globals/index.d.ts +286 -0
- package/src/globals/index.js +388 -0
- package/src/globals/index.ts +451 -0
- package/src/index.d.ts +8 -7
- package/src/index.js +8 -7
- package/src/index.ts +8 -7
- package/src/itertools/index.d.ts +225 -0
- package/src/itertools/index.js +449 -0
- package/src/itertools/index.ts +471 -0
- package/src/math/index.d.ts +97 -0
- package/src/math/index.js +92 -0
- package/src/math/index.ts +152 -0
- package/src/{operators.d.ts → operators/index.d.ts} +11 -9
- package/src/operators/index.js +171 -0
- package/src/operators/index.ts +175 -0
- package/src/random/index.d.ts +42 -0
- package/src/random/index.js +65 -0
- package/src/random/index.ts +66 -0
- package/tests/collections.spec.ts +42 -25
- package/tests/globals.spec.ts +56 -60
- package/tests/itertools.spec.ts +176 -4
- package/tests/math.spec.ts +25 -0
- package/tests/operators.spec.ts +1 -26
- package/tests/random.spec.ts +46 -0
- package/tsconfig.json +12 -4
- package/src/collections.d.ts +0 -228
- package/src/collections.js +0 -553
- package/src/collections.ts +0 -641
- package/src/datetime.d.ts +0 -5
- package/src/datetime.js +0 -5
- package/src/datetime.ts +0 -6
- package/src/functools.d.ts +0 -40
- package/src/functools.js +0 -78
- package/src/functools.ts +0 -93
- package/src/globals.d.ts +0 -179
- package/src/globals.js +0 -309
- package/src/globals.ts +0 -377
- package/src/itertools.d.ts +0 -20
- package/src/itertools.js +0 -98
- package/src/itertools.ts +0 -116
- package/src/math.d.ts +0 -16
- package/src/math.js +0 -70
- package/src/math.ts +0 -77
- package/src/objects.d.ts +0 -0
- package/src/objects.js +0 -1
- package/src/objects.ts +0 -0
- package/src/operators.js +0 -109
- package/src/operators.ts +0 -130
- package/src/random.d.ts +0 -22
- package/src/random.js +0 -48
- package/src/random.ts +0 -53
- package/src/strings.d.ts +0 -0
- package/src/strings.js +0 -1
- package/src/strings.ts +0 -0
- package/src/util.d.ts +0 -0
- package/src/util.js +0 -1
- package/src/util.ts +0 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This module includes functions that promote a more functional programming style.
|
|
3
|
+
*
|
|
4
|
+
* @module Functions
|
|
5
|
+
*/
|
|
6
|
+
import { Function } from '../globals/index.js';
|
|
7
|
+
/**
|
|
8
|
+
* Creates a function that invokes `fn` with the this binding of `thisArg` and `partials` as partially applied arguments.
|
|
9
|
+
* @param {Function} fn The function to bind.
|
|
10
|
+
* @param {*} thisArg The `this` value of `fn`.
|
|
11
|
+
* @param {...*} [partials] The arguments to prepend to `fn`.
|
|
12
|
+
* @returns {Function} Returns the new bound function.
|
|
13
|
+
* @see {@link partial}
|
|
14
|
+
*/
|
|
15
|
+
export declare const bind: (fn: Function, thisArg: any, ...partials: any[]) => (...args: any[]) => any;
|
|
16
|
+
/**
|
|
17
|
+
* Creates a function that accepts arguments of `func` and either invokes `func` returning its result, if at least arity number of arguments have been provided, or returns a function that accepts the remaining `func` arguments, and so on. The arity of `func` may be specified if `func.length` is not sufficient.
|
|
18
|
+
* @param {Function} func The function to curry.
|
|
19
|
+
* @param {number} [arity=func.length]
|
|
20
|
+
* @returns Returns the new curried function.
|
|
21
|
+
*/
|
|
22
|
+
export declare const curry: (func: Function, arity?: number) => Function<any>;
|
|
23
|
+
/**
|
|
24
|
+
* Creates a function that invokes `fn` with partials prepended to the arguments it receives.
|
|
25
|
+
* **Note:** The given function will have `this` bound to `undefined`. If using `this` inside `fn`, consider {@link bind} instead.
|
|
26
|
+
* @param {Function} fn The function to bind.
|
|
27
|
+
* @param {...*} [args] The arguments to apply to `fn`.
|
|
28
|
+
* @returns {Function} Returns the new partially applied function
|
|
29
|
+
*/
|
|
30
|
+
export declare const partial: (fn: any, ...args: any[]) => (...args: any[]) => any;
|
|
31
|
+
/**
|
|
32
|
+
* Creates a function composition from a given set of functions that will be each applied on the result of the previous one from left to right.
|
|
33
|
+
* @param {...*} [args] The set of functions to apply.
|
|
34
|
+
* @returns {Function} A new function that applies each given function on the result of the previous one.
|
|
35
|
+
*/
|
|
36
|
+
export declare const flow: (...args: any[]) => (x: any) => any;
|
|
37
|
+
/**
|
|
38
|
+
* This is just an alias for the {@link flow} function.
|
|
39
|
+
* @see {@link flow}
|
|
40
|
+
*/
|
|
41
|
+
export declare const pipe: (...args: any[]) => (x: any) => any;
|
|
42
|
+
export declare const compose: (...args: any[]) => (x: any) => any;
|
|
43
|
+
/**
|
|
44
|
+
* Creates a function that memoizes the result of `func`. If `resolver` is provided, it determines the cache key for storing the result based on the arguments provided to the memoized function. By default, the first argument provided to the memoized function is used as the map cache key.
|
|
45
|
+
*
|
|
46
|
+
* @param {Function} func The function to have its output memoized.
|
|
47
|
+
* @param {Function} [resolver] The function to resolve the cache key.
|
|
48
|
+
* @return {Function} Returns the new memoized function.
|
|
49
|
+
*/
|
|
50
|
+
export declare function memoize(func: Function, resolver?: Function): Function;
|
|
51
|
+
export declare function cache(target: any, name: any, descriptor: any): any;
|
|
52
|
+
/**
|
|
53
|
+
* Creates a debounced function that delays invoking `func` until after `wait` milliseconds have elapsed since the last time the debounced function was invoked. Subsequent calls to the debounced function return the result of the last successful invocation. Provide options to set the `maxWait` milliseconds, regardless of when the function was last invoked.
|
|
54
|
+
*
|
|
55
|
+
* @param {Function} func The function to debounce.
|
|
56
|
+
* @param {number} wait The number of milliseconds to delay.
|
|
57
|
+
* @param {{ maxWait: number }} [opts] The maximum time `func` is allowed to be delayed before it's invoked.
|
|
58
|
+
* @returns Returns the new debounced function.
|
|
59
|
+
*/
|
|
60
|
+
export declare function debounce(func: Function, wait: number, { maxWait }?: {
|
|
61
|
+
maxWait?: number;
|
|
62
|
+
}): Function;
|
|
63
|
+
/**
|
|
64
|
+
* Creates a throttled function that only invokes `func` at most once per every `wait` milliseconds. Subsequent calls to the throttled function return the result of the last successful invocation.
|
|
65
|
+
*
|
|
66
|
+
* @param {Function} func The function to throttle.
|
|
67
|
+
* @param {number} wait The number of milliseconds to throttle invocations to.
|
|
68
|
+
* @return {Function} Returns the new throttled function.
|
|
69
|
+
*/
|
|
70
|
+
export declare function throttle(func: Function, wait: number): Function;
|
|
71
|
+
/**
|
|
72
|
+
* Creates a function that is restricted to invoking `func` once. Repeat calls to the function return the value of the first invocation. The `func` is invoked with the arguments of the created function.
|
|
73
|
+
*
|
|
74
|
+
* @param {Function} func The function to restrict
|
|
75
|
+
* @returns {Function} Returns the new restricted function.
|
|
76
|
+
* @example
|
|
77
|
+
```js
|
|
78
|
+
let func = x => x
|
|
79
|
+
let single = once(func)
|
|
80
|
+
single(1) // => 1
|
|
81
|
+
single(2) // => 1
|
|
82
|
+
single(3) // => 1
|
|
83
|
+
// ...
|
|
84
|
+
// => `func` is invoked only once.
|
|
85
|
+
```
|
|
86
|
+
*/
|
|
87
|
+
export declare function once(func: Function): (...args: any[]) => any;
|
|
88
|
+
export declare type Maybe<T> = T | undefined;
|
|
89
|
+
export declare type Result<T, E = any> = [Maybe<T>, Maybe<E>];
|
|
90
|
+
/**
|
|
91
|
+
* Wraps a function to catch any exceptions inside and return a `go` style error-return type.
|
|
92
|
+
*
|
|
93
|
+
* @param {Function} fun The function to wrap and catch if it throws.
|
|
94
|
+
* @param {?function(err: E, res: T): *} [onFinally] Optional callback that will be called on the `finally` clause if given.
|
|
95
|
+
* @returns {Function} A new function that wraps `fun`.
|
|
96
|
+
* @template T,E
|
|
97
|
+
*/
|
|
98
|
+
export declare function result<T = any, E = unknown>(fun: Function<T>, onFinally?: (err: E, res: T) => any): (...args: any[]) => Result<T, E>;
|
|
99
|
+
/**
|
|
100
|
+
* Wraps a function or promise to catch any exceptions inside and return a `go` style error-return type. This is like {@link result} but it deals with async functions or promises.
|
|
101
|
+
*
|
|
102
|
+
* @param {Function|Promise} awaitable The function or promise to await.
|
|
103
|
+
* @param {?function(err: E, res: T): *} [onFinally] Optional callback that will be called on the `finally` clause if given.
|
|
104
|
+
* @returns {Function} A new function that awaits the `awaitable` param and returns a return type.
|
|
105
|
+
* @template T,E
|
|
106
|
+
*/
|
|
107
|
+
export declare function resultAsync<T = any, E = unknown>(awaitable: Promise<T> | Function<Promise<T>>, onFinally?: (err: E, res: T) => any): (...args: any[]) => Promise<Result<T, E>>;
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This module includes functions that promote a more functional programming style.
|
|
3
|
+
*
|
|
4
|
+
* @module Functions
|
|
5
|
+
*/
|
|
6
|
+
import { isPromise } from '../globals/index.js';
|
|
7
|
+
/**
|
|
8
|
+
* Creates a function that invokes `fn` with the this binding of `thisArg` and `partials` as partially applied arguments.
|
|
9
|
+
* @param {Function} fn The function to bind.
|
|
10
|
+
* @param {*} thisArg The `this` value of `fn`.
|
|
11
|
+
* @param {...*} [partials] The arguments to prepend to `fn`.
|
|
12
|
+
* @returns {Function} Returns the new bound function.
|
|
13
|
+
* @see {@link partial}
|
|
14
|
+
*/
|
|
15
|
+
export const bind = (fn, thisArg, ...partials) => fn.bind(thisArg, ...partials);
|
|
16
|
+
/**
|
|
17
|
+
* Creates a function that accepts arguments of `func` and either invokes `func` returning its result, if at least arity number of arguments have been provided, or returns a function that accepts the remaining `func` arguments, and so on. The arity of `func` may be specified if `func.length` is not sufficient.
|
|
18
|
+
* @param {Function} func The function to curry.
|
|
19
|
+
* @param {number} [arity=func.length]
|
|
20
|
+
* @returns Returns the new curried function.
|
|
21
|
+
*/
|
|
22
|
+
export const curry = (func, arity) => {
|
|
23
|
+
if (typeof func !== 'function' || func.length < 2)
|
|
24
|
+
return func;
|
|
25
|
+
if (typeof arity !== 'number')
|
|
26
|
+
arity = func.length;
|
|
27
|
+
switch (arity) {
|
|
28
|
+
case 2:
|
|
29
|
+
return (arg0) => (arg1) => func(arg0, arg1);
|
|
30
|
+
case 3:
|
|
31
|
+
return (arg0) => (arg1) => (arg2) => func(arg0, arg1, arg2);
|
|
32
|
+
case 4:
|
|
33
|
+
return (arg0) => (arg1) => (arg2) => (arg3) => func(arg0, arg1, arg2, arg3);
|
|
34
|
+
case 5:
|
|
35
|
+
return (arg0) => (arg1) => (arg2) => (arg3) => (arg4) => func(arg0, arg1, arg2, arg3, arg4);
|
|
36
|
+
case 6:
|
|
37
|
+
return (arg0) => (arg1) => (arg2) => (arg3) => (arg4) => (arg5) => func(arg0, arg1, arg2, arg3, arg4, arg5);
|
|
38
|
+
case 7:
|
|
39
|
+
return (arg0) => (arg1) => (arg2) => (arg3) => (arg4) => (arg5) => (arg6) => func(arg0, arg1, arg2, arg3, arg4, arg5, arg6);
|
|
40
|
+
case 8:
|
|
41
|
+
return (arg0) => (arg1) => (arg2) => (arg3) => (arg4) => (arg5) => (arg6) => (arg7) => func(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
|
42
|
+
case 9:
|
|
43
|
+
return (arg0) => (arg1) => (arg2) => (arg3) => (arg4) => (arg5) => (arg6) => (arg7) => (arg8) => func(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
|
|
44
|
+
default:
|
|
45
|
+
throw Error('The specified function uses too many arguments. Consider refactoring it.');
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Creates a function that invokes `fn` with partials prepended to the arguments it receives.
|
|
50
|
+
* **Note:** The given function will have `this` bound to `undefined`. If using `this` inside `fn`, consider {@link bind} instead.
|
|
51
|
+
* @param {Function} fn The function to bind.
|
|
52
|
+
* @param {...*} [args] The arguments to apply to `fn`.
|
|
53
|
+
* @returns {Function} Returns the new partially applied function
|
|
54
|
+
*/
|
|
55
|
+
export const partial = (fn, ...args) => bind(fn, undefined, ...args);
|
|
56
|
+
/**
|
|
57
|
+
* Creates a function composition from a given set of functions that will be each applied on the result of the previous one from left to right.
|
|
58
|
+
* @param {...*} [args] The set of functions to apply.
|
|
59
|
+
* @returns {Function} A new function that applies each given function on the result of the previous one.
|
|
60
|
+
*/
|
|
61
|
+
export const flow = (...args) => (x) => {
|
|
62
|
+
for (const fn of args) {
|
|
63
|
+
x = fn(x);
|
|
64
|
+
}
|
|
65
|
+
return x;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* This is just an alias for the {@link flow} function.
|
|
69
|
+
* @see {@link flow}
|
|
70
|
+
*/
|
|
71
|
+
export const pipe = flow;
|
|
72
|
+
export const compose = (...args) => flow(args.reverse());
|
|
73
|
+
/**
|
|
74
|
+
* Creates a function that memoizes the result of `func`. If `resolver` is provided, it determines the cache key for storing the result based on the arguments provided to the memoized function. By default, the first argument provided to the memoized function is used as the map cache key.
|
|
75
|
+
*
|
|
76
|
+
* @param {Function} func The function to have its output memoized.
|
|
77
|
+
* @param {Function} [resolver] The function to resolve the cache key.
|
|
78
|
+
* @return {Function} Returns the new memoized function.
|
|
79
|
+
*/
|
|
80
|
+
export function memoize(func, resolver) {
|
|
81
|
+
const cache = new Map();
|
|
82
|
+
return (...args) => {
|
|
83
|
+
const key = resolver ? resolver(...args) : args[0];
|
|
84
|
+
const prev = cache.get(key);
|
|
85
|
+
if (prev !== undefined)
|
|
86
|
+
return prev;
|
|
87
|
+
const value = func(...args);
|
|
88
|
+
cache.set(key, value);
|
|
89
|
+
return value;
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
// TODO: also sized lru_cache
|
|
93
|
+
export function cache(target, name, descriptor) {
|
|
94
|
+
const original = descriptor.value;
|
|
95
|
+
if (typeof original === 'function') {
|
|
96
|
+
descriptor.value = memoize(original);
|
|
97
|
+
}
|
|
98
|
+
return descriptor;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Creates a debounced function that delays invoking `func` until after `wait` milliseconds have elapsed since the last time the debounced function was invoked. Subsequent calls to the debounced function return the result of the last successful invocation. Provide options to set the `maxWait` milliseconds, regardless of when the function was last invoked.
|
|
102
|
+
*
|
|
103
|
+
* @param {Function} func The function to debounce.
|
|
104
|
+
* @param {number} wait The number of milliseconds to delay.
|
|
105
|
+
* @param {{ maxWait: number }} [opts] The maximum time `func` is allowed to be delayed before it's invoked.
|
|
106
|
+
* @returns Returns the new debounced function.
|
|
107
|
+
*/
|
|
108
|
+
export function debounce(func, wait, { maxWait } = {}) {
|
|
109
|
+
let timer, maxTimer, lastResult;
|
|
110
|
+
return (...args) => {
|
|
111
|
+
if (timer)
|
|
112
|
+
clearTimeout(timer);
|
|
113
|
+
timer = setTimeout(() => {
|
|
114
|
+
clearTimeout(maxTimer);
|
|
115
|
+
maxTimer = null;
|
|
116
|
+
lastResult = func(...args);
|
|
117
|
+
}, wait);
|
|
118
|
+
if (maxWait && !maxTimer) {
|
|
119
|
+
maxTimer = setTimeout(() => {
|
|
120
|
+
clearTimeout(timer);
|
|
121
|
+
maxTimer = null;
|
|
122
|
+
lastResult = func(...args);
|
|
123
|
+
}, maxWait);
|
|
124
|
+
}
|
|
125
|
+
return lastResult;
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Creates a throttled function that only invokes `func` at most once per every `wait` milliseconds. Subsequent calls to the throttled function return the result of the last successful invocation.
|
|
130
|
+
*
|
|
131
|
+
* @param {Function} func The function to throttle.
|
|
132
|
+
* @param {number} wait The number of milliseconds to throttle invocations to.
|
|
133
|
+
* @return {Function} Returns the new throttled function.
|
|
134
|
+
*/
|
|
135
|
+
export function throttle(func, wait) {
|
|
136
|
+
let pending = false;
|
|
137
|
+
return (...args) => {
|
|
138
|
+
if (pending)
|
|
139
|
+
return;
|
|
140
|
+
func(...args);
|
|
141
|
+
pending = true;
|
|
142
|
+
setTimeout(() => {
|
|
143
|
+
pending = false;
|
|
144
|
+
}, wait);
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Creates a function that is restricted to invoking `func` once. Repeat calls to the function return the value of the first invocation. The `func` is invoked with the arguments of the created function.
|
|
149
|
+
*
|
|
150
|
+
* @param {Function} func The function to restrict
|
|
151
|
+
* @returns {Function} Returns the new restricted function.
|
|
152
|
+
* @example
|
|
153
|
+
```js
|
|
154
|
+
let func = x => x
|
|
155
|
+
let single = once(func)
|
|
156
|
+
single(1) // => 1
|
|
157
|
+
single(2) // => 1
|
|
158
|
+
single(3) // => 1
|
|
159
|
+
// ...
|
|
160
|
+
// => `func` is invoked only once.
|
|
161
|
+
```
|
|
162
|
+
*/
|
|
163
|
+
export function once(func) {
|
|
164
|
+
let result, isCalled;
|
|
165
|
+
return (...args) => {
|
|
166
|
+
if (!isCalled) {
|
|
167
|
+
result = func(...args);
|
|
168
|
+
isCalled = true;
|
|
169
|
+
}
|
|
170
|
+
return result;
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Wraps a function to catch any exceptions inside and return a `go` style error-return type.
|
|
175
|
+
*
|
|
176
|
+
* @param {Function} fun The function to wrap and catch if it throws.
|
|
177
|
+
* @param {?function(err: E, res: T): *} [onFinally] Optional callback that will be called on the `finally` clause if given.
|
|
178
|
+
* @returns {Function} A new function that wraps `fun`.
|
|
179
|
+
* @template T,E
|
|
180
|
+
*/
|
|
181
|
+
export function result(fun, onFinally) {
|
|
182
|
+
return (...args) => {
|
|
183
|
+
let value, err;
|
|
184
|
+
try {
|
|
185
|
+
value = fun(...args);
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
err = error;
|
|
189
|
+
}
|
|
190
|
+
finally {
|
|
191
|
+
onFinally?.(err, value);
|
|
192
|
+
}
|
|
193
|
+
return [value, err];
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Wraps a function or promise to catch any exceptions inside and return a `go` style error-return type. This is like {@link result} but it deals with async functions or promises.
|
|
198
|
+
*
|
|
199
|
+
* @param {Function|Promise} awaitable The function or promise to await.
|
|
200
|
+
* @param {?function(err: E, res: T): *} [onFinally] Optional callback that will be called on the `finally` clause if given.
|
|
201
|
+
* @returns {Function} A new function that awaits the `awaitable` param and returns a return type.
|
|
202
|
+
* @template T,E
|
|
203
|
+
*/
|
|
204
|
+
export function resultAsync(awaitable, onFinally) {
|
|
205
|
+
return async (...args) => {
|
|
206
|
+
let value, err;
|
|
207
|
+
try {
|
|
208
|
+
const promise = isPromise(awaitable) ? awaitable : awaitable(...args);
|
|
209
|
+
value = await promise;
|
|
210
|
+
}
|
|
211
|
+
catch (error) {
|
|
212
|
+
err = error;
|
|
213
|
+
}
|
|
214
|
+
finally {
|
|
215
|
+
onFinally?.(err, value);
|
|
216
|
+
}
|
|
217
|
+
return [value, err];
|
|
218
|
+
};
|
|
219
|
+
}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This module includes functions that promote a more functional programming style.
|
|
3
|
+
*
|
|
4
|
+
* @module Functions
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { Function, isPromise } from '../globals/index.js'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Creates a function that invokes `fn` with the this binding of `thisArg` and `partials` as partially applied arguments.
|
|
11
|
+
* @param {Function} fn The function to bind.
|
|
12
|
+
* @param {*} thisArg The `this` value of `fn`.
|
|
13
|
+
* @param {...*} [partials] The arguments to prepend to `fn`.
|
|
14
|
+
* @returns {Function} Returns the new bound function.
|
|
15
|
+
* @see {@link partial}
|
|
16
|
+
*/
|
|
17
|
+
export const bind = (fn: Function, thisArg, ...partials) => fn.bind(thisArg, ...partials)
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Creates a function that accepts arguments of `func` and either invokes `func` returning its result, if at least arity number of arguments have been provided, or returns a function that accepts the remaining `func` arguments, and so on. The arity of `func` may be specified if `func.length` is not sufficient.
|
|
21
|
+
* @param {Function} func The function to curry.
|
|
22
|
+
* @param {number} [arity=func.length]
|
|
23
|
+
* @returns Returns the new curried function.
|
|
24
|
+
*/
|
|
25
|
+
export const curry = (func: Function, arity?: number) => {
|
|
26
|
+
if (typeof func !== 'function' || func.length < 2) return func
|
|
27
|
+
if (typeof arity !== 'number') arity = func.length
|
|
28
|
+
switch (arity) {
|
|
29
|
+
case 2:
|
|
30
|
+
return (arg0) => (arg1) => func(arg0, arg1)
|
|
31
|
+
case 3:
|
|
32
|
+
return (arg0) => (arg1) => (arg2) => func(arg0, arg1, arg2)
|
|
33
|
+
case 4:
|
|
34
|
+
return (arg0) => (arg1) => (arg2) => (arg3) => func(arg0, arg1, arg2, arg3)
|
|
35
|
+
case 5:
|
|
36
|
+
return (arg0) => (arg1) => (arg2) => (arg3) => (arg4) => func(arg0, arg1, arg2, arg3, arg4)
|
|
37
|
+
case 6:
|
|
38
|
+
return (arg0) => (arg1) => (arg2) => (arg3) => (arg4) => (arg5) =>
|
|
39
|
+
func(arg0, arg1, arg2, arg3, arg4, arg5)
|
|
40
|
+
case 7:
|
|
41
|
+
return (arg0) => (arg1) => (arg2) => (arg3) => (arg4) => (arg5) => (arg6) =>
|
|
42
|
+
func(arg0, arg1, arg2, arg3, arg4, arg5, arg6)
|
|
43
|
+
case 8:
|
|
44
|
+
return (arg0) => (arg1) => (arg2) => (arg3) => (arg4) => (arg5) => (arg6) => (arg7) =>
|
|
45
|
+
func(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
|
|
46
|
+
case 9:
|
|
47
|
+
return (arg0) =>
|
|
48
|
+
(arg1) =>
|
|
49
|
+
(arg2) =>
|
|
50
|
+
(arg3) =>
|
|
51
|
+
(arg4) =>
|
|
52
|
+
(arg5) =>
|
|
53
|
+
(arg6) =>
|
|
54
|
+
(arg7) =>
|
|
55
|
+
(arg8) =>
|
|
56
|
+
func(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
|
|
57
|
+
|
|
58
|
+
default:
|
|
59
|
+
throw Error('The specified function uses too many arguments. Consider refactoring it.')
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Creates a function that invokes `fn` with partials prepended to the arguments it receives.
|
|
65
|
+
* **Note:** The given function will have `this` bound to `undefined`. If using `this` inside `fn`, consider {@link bind} instead.
|
|
66
|
+
* @param {Function} fn The function to bind.
|
|
67
|
+
* @param {...*} [args] The arguments to apply to `fn`.
|
|
68
|
+
* @returns {Function} Returns the new partially applied function
|
|
69
|
+
*/
|
|
70
|
+
export const partial = (fn, ...args) => bind(fn, undefined, ...args)
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Creates a function composition from a given set of functions that will be each applied on the result of the previous one from left to right.
|
|
74
|
+
* @param {...*} [args] The set of functions to apply.
|
|
75
|
+
* @returns {Function} A new function that applies each given function on the result of the previous one.
|
|
76
|
+
*/
|
|
77
|
+
export const flow =
|
|
78
|
+
(...args) =>
|
|
79
|
+
(x) => {
|
|
80
|
+
for (const fn of args) {
|
|
81
|
+
x = fn(x)
|
|
82
|
+
}
|
|
83
|
+
return x
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* This is just an alias for the {@link flow} function.
|
|
88
|
+
* @see {@link flow}
|
|
89
|
+
*/
|
|
90
|
+
export const pipe = flow
|
|
91
|
+
|
|
92
|
+
export const compose = (...args) => flow(args.reverse())
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Creates a function that memoizes the result of `func`. If `resolver` is provided, it determines the cache key for storing the result based on the arguments provided to the memoized function. By default, the first argument provided to the memoized function is used as the map cache key.
|
|
96
|
+
*
|
|
97
|
+
* @param {Function} func The function to have its output memoized.
|
|
98
|
+
* @param {Function} [resolver] The function to resolve the cache key.
|
|
99
|
+
* @return {Function} Returns the new memoized function.
|
|
100
|
+
*/
|
|
101
|
+
export function memoize(func: Function, resolver?: Function): Function {
|
|
102
|
+
const cache = new Map()
|
|
103
|
+
return (...args) => {
|
|
104
|
+
const key = resolver ? resolver(...args) : args[0]
|
|
105
|
+
const prev = cache.get(key)
|
|
106
|
+
if (prev !== undefined) return prev
|
|
107
|
+
const value = func(...args)
|
|
108
|
+
cache.set(key, value)
|
|
109
|
+
return value
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// TODO: also sized lru_cache
|
|
114
|
+
export function cache(target, name, descriptor) {
|
|
115
|
+
const original = descriptor.value
|
|
116
|
+
if (typeof original === 'function') {
|
|
117
|
+
descriptor.value = memoize(original)
|
|
118
|
+
}
|
|
119
|
+
return descriptor
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Creates a debounced function that delays invoking `func` until after `wait` milliseconds have elapsed since the last time the debounced function was invoked. Subsequent calls to the debounced function return the result of the last successful invocation. Provide options to set the `maxWait` milliseconds, regardless of when the function was last invoked.
|
|
124
|
+
*
|
|
125
|
+
* @param {Function} func The function to debounce.
|
|
126
|
+
* @param {number} wait The number of milliseconds to delay.
|
|
127
|
+
* @param {{ maxWait: number }} [opts] The maximum time `func` is allowed to be delayed before it's invoked.
|
|
128
|
+
* @returns Returns the new debounced function.
|
|
129
|
+
*/
|
|
130
|
+
export function debounce(
|
|
131
|
+
func: Function,
|
|
132
|
+
wait: number,
|
|
133
|
+
{ maxWait }: { maxWait?: number } = {}
|
|
134
|
+
): Function {
|
|
135
|
+
let timer, maxTimer, lastResult
|
|
136
|
+
return (...args) => {
|
|
137
|
+
if (timer) clearTimeout(timer)
|
|
138
|
+
timer = setTimeout(() => {
|
|
139
|
+
clearTimeout(maxTimer)
|
|
140
|
+
maxTimer = null
|
|
141
|
+
lastResult = func(...args)
|
|
142
|
+
}, wait)
|
|
143
|
+
|
|
144
|
+
if (maxWait && !maxTimer) {
|
|
145
|
+
maxTimer = setTimeout(() => {
|
|
146
|
+
clearTimeout(timer)
|
|
147
|
+
maxTimer = null
|
|
148
|
+
lastResult = func(...args)
|
|
149
|
+
}, maxWait)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return lastResult
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Creates a throttled function that only invokes `func` at most once per every `wait` milliseconds. Subsequent calls to the throttled function return the result of the last successful invocation.
|
|
158
|
+
*
|
|
159
|
+
* @param {Function} func The function to throttle.
|
|
160
|
+
* @param {number} wait The number of milliseconds to throttle invocations to.
|
|
161
|
+
* @return {Function} Returns the new throttled function.
|
|
162
|
+
*/
|
|
163
|
+
export function throttle(func: Function, wait: number): Function {
|
|
164
|
+
let pending = false
|
|
165
|
+
return (...args) => {
|
|
166
|
+
if (pending) return
|
|
167
|
+
func(...args)
|
|
168
|
+
pending = true
|
|
169
|
+
setTimeout(() => {
|
|
170
|
+
pending = false
|
|
171
|
+
}, wait)
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Creates a function that is restricted to invoking `func` once. Repeat calls to the function return the value of the first invocation. The `func` is invoked with the arguments of the created function.
|
|
177
|
+
*
|
|
178
|
+
* @param {Function} func The function to restrict
|
|
179
|
+
* @returns {Function} Returns the new restricted function.
|
|
180
|
+
* @example
|
|
181
|
+
```js
|
|
182
|
+
let func = x => x
|
|
183
|
+
let single = once(func)
|
|
184
|
+
single(1) // => 1
|
|
185
|
+
single(2) // => 1
|
|
186
|
+
single(3) // => 1
|
|
187
|
+
// ...
|
|
188
|
+
// => `func` is invoked only once.
|
|
189
|
+
```
|
|
190
|
+
*/
|
|
191
|
+
export function once(func: Function) {
|
|
192
|
+
let result, isCalled
|
|
193
|
+
return (...args) => {
|
|
194
|
+
if (!isCalled) {
|
|
195
|
+
result = func(...args)
|
|
196
|
+
isCalled = true
|
|
197
|
+
}
|
|
198
|
+
return result
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export type Maybe<T> = T | undefined
|
|
203
|
+
|
|
204
|
+
export type Result<T, E = any> = [Maybe<T>, Maybe<E>]
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Wraps a function to catch any exceptions inside and return a `go` style error-return type.
|
|
208
|
+
*
|
|
209
|
+
* @param {Function} fun The function to wrap and catch if it throws.
|
|
210
|
+
* @param {?function(err: E, res: T): *} [onFinally] Optional callback that will be called on the `finally` clause if given.
|
|
211
|
+
* @returns {Function} A new function that wraps `fun`.
|
|
212
|
+
* @template T,E
|
|
213
|
+
*/
|
|
214
|
+
export function result<T = any, E = unknown>(
|
|
215
|
+
fun: Function<T>,
|
|
216
|
+
onFinally?: (err: E, res: T) => any
|
|
217
|
+
) {
|
|
218
|
+
return (...args): Result<T, E> => {
|
|
219
|
+
let value, err
|
|
220
|
+
try {
|
|
221
|
+
value = fun(...args)
|
|
222
|
+
} catch (error) {
|
|
223
|
+
err = error
|
|
224
|
+
} finally {
|
|
225
|
+
onFinally?.(err, value)
|
|
226
|
+
}
|
|
227
|
+
return [value as T, err]
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Wraps a function or promise to catch any exceptions inside and return a `go` style error-return type. This is like {@link result} but it deals with async functions or promises.
|
|
233
|
+
*
|
|
234
|
+
* @param {Function|Promise} awaitable The function or promise to await.
|
|
235
|
+
* @param {?function(err: E, res: T): *} [onFinally] Optional callback that will be called on the `finally` clause if given.
|
|
236
|
+
* @returns {Function} A new function that awaits the `awaitable` param and returns a return type.
|
|
237
|
+
* @template T,E
|
|
238
|
+
*/
|
|
239
|
+
export function resultAsync<T = any, E = unknown>(
|
|
240
|
+
awaitable: Promise<T> | Function<Promise<T>>,
|
|
241
|
+
onFinally?: (err: E, res: T) => any
|
|
242
|
+
) {
|
|
243
|
+
return async (...args): Promise<Result<T, E>> => {
|
|
244
|
+
let value, err
|
|
245
|
+
try {
|
|
246
|
+
const promise = isPromise(awaitable) ? awaitable : awaitable(...args)
|
|
247
|
+
value = await promise
|
|
248
|
+
} catch (error) {
|
|
249
|
+
err = error
|
|
250
|
+
} finally {
|
|
251
|
+
onFinally?.(err, value)
|
|
252
|
+
}
|
|
253
|
+
return [value as T, err]
|
|
254
|
+
}
|
|
255
|
+
}
|