atomic-fns 0.1.1 → 0.2.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/.esdoc.json +9 -0
- package/README.md +14 -12
- package/package.json +22 -12
- package/{build → src}/collections.d.ts +30 -10
- package/{build → src}/collections.js +46 -21
- package/src/collections.ts +46 -23
- package/{build → src}/datetime.d.ts +0 -0
- package/{build → src}/datetime.js +0 -0
- package/{build → src}/functools.d.ts +3 -3
- package/{build → src}/functools.js +3 -3
- package/src/functools.ts +3 -3
- package/src/globals.d.ts +174 -4
- package/{build → src}/globals.js +18 -21
- package/src/globals.ts +16 -20
- package/{build → src}/index.d.ts +0 -0
- package/{build → src}/index.js +0 -0
- package/{build → src}/itertools.d.ts +0 -0
- package/{build → src}/itertools.js +4 -5
- package/src/itertools.ts +4 -5
- package/{build → src}/math.d.ts +1 -1
- package/{build → src}/math.js +1 -1
- package/src/math.ts +1 -1
- package/{build → src}/objects.d.ts +0 -0
- package/{build → src}/objects.js +0 -0
- package/{build → src}/operators.d.ts +1 -1
- package/{build → src}/operators.js +1 -1
- package/src/operators.ts +1 -1
- package/src/random.d.ts +22 -0
- package/src/random.js +48 -0
- package/src/random.ts +27 -7
- package/{build → src}/strings.d.ts +0 -0
- package/{build → src}/strings.js +0 -0
- package/{build → src}/util.d.ts +0 -0
- package/{build → src}/util.js +0 -0
- package/tests/globals.spec.ts +4 -2
- package/tsconfig.json +8 -2
- package/build/globals.d.ts +0 -175
- package/build/random.d.ts +0 -5
- package/build/random.js +0 -28
package/.esdoc.json
ADDED
package/README.md
CHANGED
|
@@ -4,15 +4,17 @@
|
|
|
4
4
|
|
|
5
5
|
Stop shipping code built for browsers from 2015. Really though, look at the [issues](https://github.com/lodash/lodash/issues/2930#issuecomment-370295020).
|
|
6
6
|
|
|
7
|
-
* Modular
|
|
8
|
-
*
|
|
9
|
-
* Lazy
|
|
10
|
-
* Fluent
|
|
11
|
-
* TypeScript &
|
|
7
|
+
* **Modular**: Pick what you need. Works with all bundlers and also supports tree-shaking.
|
|
8
|
+
* **ESNext**: Uses modern idiomatic syntax, data structures, and control flow techniques.
|
|
9
|
+
* **Lazy**: Leverage generators, iterators, and functional composition.
|
|
10
|
+
* **Fluent**: Pure functions and abstract classes. Include only what you need.
|
|
11
|
+
* **TypeScript & docs**: Includes both type declaration files and js with JSDocs for best in class experience.
|
|
12
|
+
|
|
13
|
+
## Get Started
|
|
12
14
|
|
|
13
15
|
This library is available as an npm package. To install the package just run:
|
|
14
16
|
|
|
15
|
-
```
|
|
17
|
+
```bash
|
|
16
18
|
npm install atomic-fns
|
|
17
19
|
```
|
|
18
20
|
|
|
@@ -21,24 +23,24 @@ npm install atomic-fns
|
|
|
21
23
|
import { id, reversed, sorted, times, uniqueId } from 'atomic-fns'
|
|
22
24
|
|
|
23
25
|
reverse([1, 2, 3, 4])
|
|
24
|
-
//
|
|
26
|
+
// -> [4, 3, 2, 1]
|
|
25
27
|
|
|
26
28
|
sorted([4, 3, 2, 1])
|
|
27
|
-
//
|
|
29
|
+
// -> [1, 2, 3, 4]
|
|
28
30
|
|
|
29
31
|
times(5, id)
|
|
30
|
-
//
|
|
32
|
+
// -> [0, 1, 2, 3, 4]
|
|
31
33
|
|
|
32
34
|
times(5, id)
|
|
33
|
-
//
|
|
35
|
+
// -> [0, 1, 2, 3, 4]
|
|
34
36
|
|
|
35
37
|
uniqueId('user_')
|
|
36
|
-
//
|
|
38
|
+
// -> 'user_101225005'
|
|
37
39
|
```
|
|
38
40
|
|
|
39
41
|
## Docs
|
|
40
42
|
|
|
41
|
-
|
|
43
|
+
🚢 Coming soon at [atomic-fns.dev](https://atomic-fns.dev).
|
|
42
44
|
|
|
43
45
|
💡 See the `src` directory for comments.
|
|
44
46
|
|
package/package.json
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "atomic-fns",
|
|
3
|
-
"description": "
|
|
4
|
-
"version": "0.
|
|
5
|
-
"main": "
|
|
3
|
+
"description": "Like Lodash, but for ESNext and with types. Stop shipping code built for browsers from 2015.",
|
|
4
|
+
"version": "0.2.0",
|
|
5
|
+
"main": "src/index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"devDependencies": {
|
|
8
8
|
"@types/jasmine": "^4.3.0",
|
|
9
9
|
"@typescript-eslint/eslint-plugin": "^5.39.0",
|
|
10
|
+
"esdoc": "^1.1.0",
|
|
11
|
+
"esdoc-standard-plugin": "^1.0.0",
|
|
10
12
|
"eslint": "^8.25.0",
|
|
11
13
|
"eslint-config-prettier": "^8.5.0",
|
|
12
14
|
"eslint-config-standard-with-typescript": "^23.0.0",
|
|
@@ -24,12 +26,13 @@
|
|
|
24
26
|
"typescript": "^4.8.4"
|
|
25
27
|
},
|
|
26
28
|
"scripts": {
|
|
27
|
-
"
|
|
29
|
+
"prepublishOnly": "npm test && npm run tsc",
|
|
28
30
|
"test": "NODE_OPTIONS=--loader=ts-node/esm jasmine --config=jasmine.json",
|
|
29
31
|
"tsc": "tsc -p ./tsconfig.xo.json --declaration",
|
|
30
32
|
"lint": "eslint src/**",
|
|
31
33
|
"lint:fix": "eslint src/** --fix",
|
|
32
|
-
"format": "prettier --write src/**"
|
|
34
|
+
"format": "prettier --write src/**",
|
|
35
|
+
"docs": "npm run tsc && esdoc"
|
|
33
36
|
},
|
|
34
37
|
"lint-staged": {
|
|
35
38
|
"*.ts": "eslint"
|
|
@@ -41,12 +44,14 @@
|
|
|
41
44
|
},
|
|
42
45
|
"repository": {
|
|
43
46
|
"type": "git",
|
|
44
|
-
"url": "
|
|
47
|
+
"url": "https://github.com/adrian2x/atomic-fns.git"
|
|
45
48
|
},
|
|
46
49
|
"keywords": [
|
|
47
|
-
"
|
|
50
|
+
"atomic",
|
|
51
|
+
"atomicfns",
|
|
52
|
+
"atomic-fns",
|
|
48
53
|
"esnext",
|
|
49
|
-
"
|
|
54
|
+
"es-next",
|
|
50
55
|
"@esnext",
|
|
51
56
|
"@es-next",
|
|
52
57
|
"es6",
|
|
@@ -56,16 +61,21 @@
|
|
|
56
61
|
"es2017",
|
|
57
62
|
"es2019",
|
|
58
63
|
"es2020",
|
|
64
|
+
"es2021",
|
|
65
|
+
"es2022",
|
|
66
|
+
"es2023",
|
|
67
|
+
"lodash",
|
|
68
|
+
"lazy",
|
|
59
69
|
"modules",
|
|
60
70
|
"stdlib",
|
|
61
71
|
"core-js",
|
|
62
72
|
"util",
|
|
63
73
|
"fp"
|
|
64
74
|
],
|
|
65
|
-
"author": "Adrian Cruz <
|
|
75
|
+
"author": "Adrian Cruz <kangoonie@gmail.com>",
|
|
66
76
|
"license": "Apache-2.0",
|
|
67
77
|
"bugs": {
|
|
68
|
-
"url": "https://github.com/adrian2x/
|
|
78
|
+
"url": "https://github.com/adrian2x/atomic-fns/issues"
|
|
69
79
|
},
|
|
70
|
-
"homepage": "https://github.com/adrian2x/
|
|
71
|
-
}
|
|
80
|
+
"homepage": "https://github.com/adrian2x/atomic-fns#readme"
|
|
81
|
+
}
|
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
/// <reference path="../src/globals.d.ts" />
|
|
2
1
|
import { Function, Iteratee } from './globals.js';
|
|
3
2
|
/**
|
|
4
3
|
* A container type that provides contains().
|
|
5
4
|
*
|
|
6
|
-
*
|
|
5
|
+
*
|
|
7
6
|
* @interface Container
|
|
8
7
|
*/
|
|
9
8
|
export interface Container {
|
|
10
9
|
contains: (x: any) => boolean;
|
|
11
10
|
}
|
|
12
11
|
/**
|
|
13
|
-
* These are the "rich comparison" methods,
|
|
12
|
+
* These are the "rich comparison" methods, inspired by Python operators.
|
|
13
|
+
*
|
|
14
14
|
*
|
|
15
|
-
* @export
|
|
16
15
|
* @interface Comparable
|
|
17
16
|
*/
|
|
18
17
|
export interface Comparable {
|
|
@@ -33,7 +32,7 @@ export interface Comparable {
|
|
|
33
32
|
* A Collection is an iterable container type.
|
|
34
33
|
* This is an abstract base class for user-defined collection types.
|
|
35
34
|
*
|
|
36
|
-
*
|
|
35
|
+
*
|
|
37
36
|
* @abstract
|
|
38
37
|
* @class Collection
|
|
39
38
|
* @implements {Container}
|
|
@@ -87,7 +86,7 @@ export interface Reversible<T = unknown> {
|
|
|
87
86
|
/**
|
|
88
87
|
* A sequence is an iterable type with efficient index-based access.
|
|
89
88
|
*
|
|
90
|
-
*
|
|
89
|
+
*
|
|
91
90
|
* @abstract
|
|
92
91
|
* @class Sequence
|
|
93
92
|
* @extends {Collection}
|
|
@@ -141,6 +140,14 @@ export declare abstract class Sequence<T> extends Collection implements Reversib
|
|
|
141
140
|
size(): number;
|
|
142
141
|
reversed(): Iterator<T>;
|
|
143
142
|
}
|
|
143
|
+
/**
|
|
144
|
+
* Returns a new immutable Set object with elements from `iterable`. Its contents cannot be altered after it's created.
|
|
145
|
+
*
|
|
146
|
+
*
|
|
147
|
+
* @class FrozenSet
|
|
148
|
+
* @extends {Set<T>}
|
|
149
|
+
* @template T
|
|
150
|
+
*/
|
|
144
151
|
export declare class FrozenSet<T = any> extends Set<T> {
|
|
145
152
|
constructor(iterable: Iterable<T>);
|
|
146
153
|
add(): this;
|
|
@@ -149,7 +156,20 @@ export declare class FrozenSet<T = any> extends Set<T> {
|
|
|
149
156
|
freeze(): Readonly<this>;
|
|
150
157
|
}
|
|
151
158
|
export declare const compact: (...arr: any[]) => any[];
|
|
152
|
-
|
|
159
|
+
/**
|
|
160
|
+
* Creates a function that can be used to create named tuple-like objects.
|
|
161
|
+
* @example
|
|
162
|
+
* ```
|
|
163
|
+
* let Point = namedtuple('x', 'y', 'z')
|
|
164
|
+
* let userObj = User(0, 0, 0)
|
|
165
|
+
* // -> {x: 0, y: 0, z: 0}
|
|
166
|
+
* ```
|
|
167
|
+
*
|
|
168
|
+
*
|
|
169
|
+
* @param {...string[]} fields
|
|
170
|
+
* @return
|
|
171
|
+
*/
|
|
172
|
+
export declare function namedtuple(...fields: string[]): (...args: any[]) => {};
|
|
153
173
|
export declare function filter(arr: any, fn?: Iteratee | PropertyKey | Object): any[] | undefined;
|
|
154
174
|
export declare function find(arr: any, fn: Iteratee | PropertyKey | Object): any;
|
|
155
175
|
export declare function findRight(arr: any, fn: Iteratee | PropertyKey | Object): any;
|
|
@@ -168,7 +188,7 @@ export declare function lastIndexOf(obj: any, x: any, start?: any): any;
|
|
|
168
188
|
/**
|
|
169
189
|
* Creates a clone of the given `obj`. If `deep` is `true` it will clone it recursively.
|
|
170
190
|
*
|
|
171
|
-
*
|
|
191
|
+
*
|
|
172
192
|
* @param {*} obj
|
|
173
193
|
* @param {boolean} [deep=false]
|
|
174
194
|
* @return The clone value
|
|
@@ -184,7 +204,7 @@ export declare function sortedUniq(arr: any, fn?: string | Iteratee): any[];
|
|
|
184
204
|
*
|
|
185
205
|
* Note: this method mutates `obj`
|
|
186
206
|
*
|
|
187
|
-
*
|
|
207
|
+
*
|
|
188
208
|
* @param {Object} obj
|
|
189
209
|
* @param {...Object} sources
|
|
190
210
|
* @return {Object} The destination object.
|
|
@@ -196,7 +216,7 @@ export declare function union(...args: any[]): Generator<unknown, void, unknown>
|
|
|
196
216
|
/**
|
|
197
217
|
* Creates an object composed of keys generated from the results of running each element of `arr` thru `func`. The order of grouped values is determined by the order they occur in `arr`. The corresponding value of each key is an array of elements responsible for generating the key.
|
|
198
218
|
*
|
|
199
|
-
*
|
|
219
|
+
*
|
|
200
220
|
* @param {(any[] | Object)} arr The collection to iterate over.
|
|
201
221
|
* @param {(Iteratee | PropertyKey)} [func=id] The iteratee to transform keys.
|
|
202
222
|
* @return {Object} Returns the composed aggregate object.
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
import { call, get, isArray, isArrayLike, isBool, isEmpty, isFunc, isNull, isNumber, isObject, isString, keys, NotImplementedError } from './globals.js';
|
|
1
|
+
import { call, get, isArray, isArrayLike, isBool, isEmpty, isFunc, isNull, isNumber, isObject, isString, keys, NotImplementedError, set } from './globals.js';
|
|
3
2
|
import { comp, eq, id } from './operators.js';
|
|
4
3
|
/**
|
|
5
4
|
* A Collection is an iterable container type.
|
|
6
5
|
* This is an abstract base class for user-defined collection types.
|
|
7
6
|
*
|
|
8
|
-
*
|
|
7
|
+
*
|
|
9
8
|
* @abstract
|
|
10
9
|
* @class Collection
|
|
11
10
|
* @implements {Container}
|
|
@@ -58,7 +57,7 @@ export class Collection {
|
|
|
58
57
|
/**
|
|
59
58
|
* A sequence is an iterable type with efficient index-based access.
|
|
60
59
|
*
|
|
61
|
-
*
|
|
60
|
+
*
|
|
62
61
|
* @abstract
|
|
63
62
|
* @class Sequence
|
|
64
63
|
* @extends {Collection}
|
|
@@ -124,6 +123,14 @@ export class Sequence extends Collection {
|
|
|
124
123
|
throw new NotImplementedError();
|
|
125
124
|
}
|
|
126
125
|
}
|
|
126
|
+
/**
|
|
127
|
+
* Returns a new immutable Set object with elements from `iterable`. Its contents cannot be altered after it's created.
|
|
128
|
+
*
|
|
129
|
+
*
|
|
130
|
+
* @class FrozenSet
|
|
131
|
+
* @extends {Set<T>}
|
|
132
|
+
* @template T
|
|
133
|
+
*/
|
|
127
134
|
export class FrozenSet extends Set {
|
|
128
135
|
constructor(iterable) {
|
|
129
136
|
super(iterable);
|
|
@@ -146,8 +153,21 @@ export class FrozenSet extends Set {
|
|
|
146
153
|
}
|
|
147
154
|
}
|
|
148
155
|
export const compact = (...arr) => arr.filter((x) => !isEmpty(x));
|
|
156
|
+
/**
|
|
157
|
+
* Creates a function that can be used to create named tuple-like objects.
|
|
158
|
+
* @example
|
|
159
|
+
* ```
|
|
160
|
+
* let Point = namedtuple('x', 'y', 'z')
|
|
161
|
+
* let userObj = User(0, 0, 0)
|
|
162
|
+
* // -> {x: 0, y: 0, z: 0}
|
|
163
|
+
* ```
|
|
164
|
+
*
|
|
165
|
+
*
|
|
166
|
+
* @param {...string[]} fields
|
|
167
|
+
* @return
|
|
168
|
+
*/
|
|
149
169
|
export function namedtuple(...fields) {
|
|
150
|
-
return (...args) => fields.
|
|
170
|
+
return (...args) => fields.reduce((prev, f, i) => set(prev, f, args[i], false, true), {});
|
|
151
171
|
}
|
|
152
172
|
export function filter(arr, fn = isNull) {
|
|
153
173
|
if (Array.isArray(arr)) {
|
|
@@ -155,18 +175,17 @@ export function filter(arr, fn = isNull) {
|
|
|
155
175
|
if (typeof fn === 'function')
|
|
156
176
|
return arr.filter(fn);
|
|
157
177
|
if (typeof fn === 'string')
|
|
158
|
-
return arr.filter((x) => x
|
|
178
|
+
return arr.filter((x) => get(x, fn));
|
|
159
179
|
if (isObject(fn))
|
|
160
180
|
return arr.filter(matches(fn));
|
|
161
181
|
}
|
|
162
182
|
}
|
|
163
183
|
export function find(arr, fn) {
|
|
164
184
|
if (Array.isArray(arr)) {
|
|
165
|
-
// @ts-expect-error function is not compatible?
|
|
166
185
|
if (typeof fn === 'function')
|
|
167
186
|
return arr.find(fn);
|
|
168
187
|
if (typeof fn === 'string')
|
|
169
|
-
return arr.find((x) => x
|
|
188
|
+
return arr.find((x) => x && x[fn]);
|
|
170
189
|
if (isObject(fn))
|
|
171
190
|
return arr.find(matches(fn));
|
|
172
191
|
}
|
|
@@ -180,7 +199,7 @@ export function findRight(arr, fn) {
|
|
|
180
199
|
return x;
|
|
181
200
|
}
|
|
182
201
|
else if (typeof fn === 'string') {
|
|
183
|
-
if (x
|
|
202
|
+
if (x && x[fn])
|
|
184
203
|
return x;
|
|
185
204
|
}
|
|
186
205
|
else if (isObject(fn)) {
|
|
@@ -191,8 +210,10 @@ export function findRight(arr, fn) {
|
|
|
191
210
|
}
|
|
192
211
|
}
|
|
193
212
|
export const matches = (o) => (x) => {
|
|
213
|
+
if (!o || !x)
|
|
214
|
+
return false;
|
|
194
215
|
for (const key in o) {
|
|
195
|
-
if (!eq(x
|
|
216
|
+
if (!eq(x[key], o[key]))
|
|
196
217
|
return false;
|
|
197
218
|
}
|
|
198
219
|
return true;
|
|
@@ -260,7 +281,7 @@ export const map = (arr, fn) => {
|
|
|
260
281
|
if (isObject(arr)) {
|
|
261
282
|
return Object.keys(arr).map((key) => {
|
|
262
283
|
if (typeof fn === 'string')
|
|
263
|
-
return arr[key]
|
|
284
|
+
return get(arr[key], fn);
|
|
264
285
|
return fn(arr[key], key, arr);
|
|
265
286
|
});
|
|
266
287
|
}
|
|
@@ -305,15 +326,17 @@ export function contains(arr, y) {
|
|
|
305
326
|
return indexOf(arr, y) >= 0;
|
|
306
327
|
}
|
|
307
328
|
export function indexOf(obj, x, start = 0) {
|
|
329
|
+
if (obj == null)
|
|
330
|
+
return;
|
|
308
331
|
const op = call(obj, 'indexOf', x, start);
|
|
309
332
|
if (op != null)
|
|
310
333
|
return op;
|
|
311
|
-
const length = obj
|
|
312
|
-
if (!length || start >= length)
|
|
313
|
-
return -1;
|
|
334
|
+
const length = obj.length;
|
|
314
335
|
if (length && start < 0) {
|
|
315
336
|
start = Math.max(start + length, 0);
|
|
316
337
|
}
|
|
338
|
+
if (!length || start >= length)
|
|
339
|
+
return -1;
|
|
317
340
|
for (; start < length; start++) {
|
|
318
341
|
if (eq(x, obj[start]))
|
|
319
342
|
return start;
|
|
@@ -321,14 +344,16 @@ export function indexOf(obj, x, start = 0) {
|
|
|
321
344
|
return -1;
|
|
322
345
|
}
|
|
323
346
|
export function lastIndexOf(obj, x, start) {
|
|
347
|
+
if (obj == null)
|
|
348
|
+
return;
|
|
324
349
|
const op = call(obj, 'lastIndexOf', x, start);
|
|
325
350
|
if (op != null)
|
|
326
351
|
return op;
|
|
327
|
-
const length = obj
|
|
328
|
-
if (!length)
|
|
329
|
-
return -1;
|
|
352
|
+
const length = obj.length;
|
|
330
353
|
if (start == null)
|
|
331
354
|
start = length - 1;
|
|
355
|
+
if (!length || start < 0)
|
|
356
|
+
return -1;
|
|
332
357
|
for (; start >= 0; start--) {
|
|
333
358
|
if (eq(x, obj[start]))
|
|
334
359
|
return start;
|
|
@@ -338,7 +363,7 @@ export function lastIndexOf(obj, x, start) {
|
|
|
338
363
|
/**
|
|
339
364
|
* Creates a clone of the given `obj`. If `deep` is `true` it will clone it recursively.
|
|
340
365
|
*
|
|
341
|
-
*
|
|
366
|
+
*
|
|
342
367
|
* @param {*} obj
|
|
343
368
|
* @param {boolean} [deep=false]
|
|
344
369
|
* @return The clone value
|
|
@@ -448,7 +473,7 @@ function baseMerge(obj, source, stack) {
|
|
|
448
473
|
const srcValue = source[key];
|
|
449
474
|
const objValue = obj[key];
|
|
450
475
|
if (typeof srcValue === 'object' && srcValue !== null) {
|
|
451
|
-
baseMergeDeep(obj, source, key, stack
|
|
476
|
+
baseMergeDeep(obj, source, key, stack || new WeakMap());
|
|
452
477
|
}
|
|
453
478
|
else {
|
|
454
479
|
if (objValue !== srcValue) {
|
|
@@ -462,7 +487,7 @@ function baseMerge(obj, source, stack) {
|
|
|
462
487
|
*
|
|
463
488
|
* Note: this method mutates `obj`
|
|
464
489
|
*
|
|
465
|
-
*
|
|
490
|
+
*
|
|
466
491
|
* @param {Object} obj
|
|
467
492
|
* @param {...Object} sources
|
|
468
493
|
* @return {Object} The destination object.
|
|
@@ -516,7 +541,7 @@ export function* union(...args) {
|
|
|
516
541
|
/**
|
|
517
542
|
* Creates an object composed of keys generated from the results of running each element of `arr` thru `func`. The order of grouped values is determined by the order they occur in `arr`. The corresponding value of each key is an array of elements responsible for generating the key.
|
|
518
543
|
*
|
|
519
|
-
*
|
|
544
|
+
*
|
|
520
545
|
* @param {(any[] | Object)} arr The collection to iterate over.
|
|
521
546
|
* @param {(Iteratee | PropertyKey)} [func=id] The iteratee to transform keys.
|
|
522
547
|
* @return {Object} Returns the composed aggregate object.
|
package/src/collections.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference path='globals.d.ts'/>
|
|
2
1
|
import {
|
|
3
2
|
call,
|
|
4
3
|
Function,
|
|
@@ -14,14 +13,15 @@ import {
|
|
|
14
13
|
isString,
|
|
15
14
|
Iteratee,
|
|
16
15
|
keys,
|
|
17
|
-
NotImplementedError
|
|
16
|
+
NotImplementedError,
|
|
17
|
+
set
|
|
18
18
|
} from './globals.js'
|
|
19
19
|
import { comp, eq, id } from './operators.js'
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* A container type that provides contains().
|
|
23
23
|
*
|
|
24
|
-
*
|
|
24
|
+
*
|
|
25
25
|
* @interface Container
|
|
26
26
|
*/
|
|
27
27
|
export interface Container {
|
|
@@ -29,9 +29,9 @@ export interface Container {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
|
-
* These are the "rich comparison" methods,
|
|
32
|
+
* These are the "rich comparison" methods, inspired by Python operators.
|
|
33
|
+
*
|
|
33
34
|
*
|
|
34
|
-
* @export
|
|
35
35
|
* @interface Comparable
|
|
36
36
|
*/
|
|
37
37
|
export interface Comparable {
|
|
@@ -53,7 +53,7 @@ export interface Comparable {
|
|
|
53
53
|
* A Collection is an iterable container type.
|
|
54
54
|
* This is an abstract base class for user-defined collection types.
|
|
55
55
|
*
|
|
56
|
-
*
|
|
56
|
+
*
|
|
57
57
|
* @abstract
|
|
58
58
|
* @class Collection
|
|
59
59
|
* @implements {Container}
|
|
@@ -122,7 +122,7 @@ export interface Reversible<T = unknown> {
|
|
|
122
122
|
/**
|
|
123
123
|
* A sequence is an iterable type with efficient index-based access.
|
|
124
124
|
*
|
|
125
|
-
*
|
|
125
|
+
*
|
|
126
126
|
* @abstract
|
|
127
127
|
* @class Sequence
|
|
128
128
|
* @extends {Collection}
|
|
@@ -196,6 +196,14 @@ export abstract class Sequence<T> extends Collection implements Reversible<T> {
|
|
|
196
196
|
}
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
+
/**
|
|
200
|
+
* Returns a new immutable Set object with elements from `iterable`. Its contents cannot be altered after it's created.
|
|
201
|
+
*
|
|
202
|
+
*
|
|
203
|
+
* @class FrozenSet
|
|
204
|
+
* @extends {Set<T>}
|
|
205
|
+
* @template T
|
|
206
|
+
*/
|
|
199
207
|
export class FrozenSet<T = any> extends Set<T> {
|
|
200
208
|
constructor(iterable: Iterable<T>) {
|
|
201
209
|
super(iterable)
|
|
@@ -224,24 +232,36 @@ export class FrozenSet<T = any> extends Set<T> {
|
|
|
224
232
|
|
|
225
233
|
export const compact = (...arr) => arr.filter((x) => !isEmpty(x))
|
|
226
234
|
|
|
235
|
+
/**
|
|
236
|
+
* Creates a function that can be used to create named tuple-like objects.
|
|
237
|
+
* @example
|
|
238
|
+
* ```
|
|
239
|
+
* let Point = namedtuple('x', 'y', 'z')
|
|
240
|
+
* let userObj = User(0, 0, 0)
|
|
241
|
+
* // -> {x: 0, y: 0, z: 0}
|
|
242
|
+
* ```
|
|
243
|
+
*
|
|
244
|
+
*
|
|
245
|
+
* @param {...string[]} fields
|
|
246
|
+
* @return
|
|
247
|
+
*/
|
|
227
248
|
export function namedtuple(...fields: string[]) {
|
|
228
|
-
return (...args) => fields.
|
|
249
|
+
return (...args) => fields.reduce((prev, f, i) => set(prev, f, args[i], false, true), {})
|
|
229
250
|
}
|
|
230
251
|
|
|
231
252
|
export function filter(arr, fn: Iteratee | PropertyKey | Object = isNull) {
|
|
232
253
|
if (Array.isArray(arr)) {
|
|
233
254
|
// @ts-expect-error function is not compatible?
|
|
234
255
|
if (typeof fn === 'function') return arr.filter(fn)
|
|
235
|
-
if (typeof fn === 'string') return arr.filter((x) => x
|
|
256
|
+
if (typeof fn === 'string') return arr.filter((x) => get(x, fn))
|
|
236
257
|
if (isObject(fn)) return arr.filter(matches(fn))
|
|
237
258
|
}
|
|
238
259
|
}
|
|
239
260
|
|
|
240
261
|
export function find(arr, fn: Iteratee | PropertyKey | Object) {
|
|
241
262
|
if (Array.isArray(arr)) {
|
|
242
|
-
|
|
243
|
-
if (typeof fn === '
|
|
244
|
-
if (typeof fn === 'string') return arr.find((x) => x?.[fn])
|
|
263
|
+
if (typeof fn === 'function') return arr.find(fn as Iteratee)
|
|
264
|
+
if (typeof fn === 'string') return arr.find((x) => x && x[fn])
|
|
245
265
|
if (isObject(fn)) return arr.find(matches(fn))
|
|
246
266
|
}
|
|
247
267
|
}
|
|
@@ -253,7 +273,7 @@ export function findRight(arr, fn: Iteratee | PropertyKey | Object) {
|
|
|
253
273
|
if (typeof fn === 'function') {
|
|
254
274
|
if (fn(x)) return x
|
|
255
275
|
} else if (typeof fn === 'string') {
|
|
256
|
-
if (x
|
|
276
|
+
if (x && x[fn]) return x
|
|
257
277
|
} else if (isObject(fn)) {
|
|
258
278
|
if (matches(fn)(x)) return x
|
|
259
279
|
}
|
|
@@ -262,8 +282,9 @@ export function findRight(arr, fn: Iteratee | PropertyKey | Object) {
|
|
|
262
282
|
}
|
|
263
283
|
|
|
264
284
|
export const matches = (o) => (x) => {
|
|
285
|
+
if (!o || !x) return false
|
|
265
286
|
for (const key in o) {
|
|
266
|
-
if (!eq(x
|
|
287
|
+
if (!eq(x[key], o[key])) return false
|
|
267
288
|
}
|
|
268
289
|
return true
|
|
269
290
|
}
|
|
@@ -329,7 +350,7 @@ export const map = (arr, fn: Function | string) => {
|
|
|
329
350
|
}
|
|
330
351
|
if (isObject(arr)) {
|
|
331
352
|
return Object.keys(arr).map((key) => {
|
|
332
|
-
if (typeof fn === 'string') return arr[key]
|
|
353
|
+
if (typeof fn === 'string') return get(arr[key], fn)
|
|
333
354
|
return fn(arr[key], key, arr)
|
|
334
355
|
})
|
|
335
356
|
}
|
|
@@ -374,13 +395,14 @@ export function contains(arr, y) {
|
|
|
374
395
|
}
|
|
375
396
|
|
|
376
397
|
export function indexOf(obj, x, start = 0) {
|
|
398
|
+
if (obj == null) return
|
|
377
399
|
const op = call(obj, 'indexOf', x, start)
|
|
378
400
|
if (op != null) return op
|
|
379
|
-
const length = obj
|
|
380
|
-
if (!length || start >= length) return -1
|
|
401
|
+
const length = obj.length
|
|
381
402
|
if (length && start < 0) {
|
|
382
403
|
start = Math.max(start + length, 0)
|
|
383
404
|
}
|
|
405
|
+
if (!length || start >= length) return -1
|
|
384
406
|
for (; start < length; start++) {
|
|
385
407
|
if (eq(x, obj[start])) return start
|
|
386
408
|
}
|
|
@@ -388,11 +410,12 @@ export function indexOf(obj, x, start = 0) {
|
|
|
388
410
|
}
|
|
389
411
|
|
|
390
412
|
export function lastIndexOf(obj, x, start?) {
|
|
413
|
+
if (obj == null) return
|
|
391
414
|
const op = call(obj, 'lastIndexOf', x, start)
|
|
392
415
|
if (op != null) return op
|
|
393
|
-
const length = obj
|
|
394
|
-
if (!length) return -1
|
|
416
|
+
const length = obj.length
|
|
395
417
|
if (start == null) start = length - 1
|
|
418
|
+
if (!length || start < 0) return -1
|
|
396
419
|
for (; start >= 0; start--) {
|
|
397
420
|
if (eq(x, obj[start])) return start
|
|
398
421
|
}
|
|
@@ -402,7 +425,7 @@ export function lastIndexOf(obj, x, start?) {
|
|
|
402
425
|
/**
|
|
403
426
|
* Creates a clone of the given `obj`. If `deep` is `true` it will clone it recursively.
|
|
404
427
|
*
|
|
405
|
-
*
|
|
428
|
+
*
|
|
406
429
|
* @param {*} obj
|
|
407
430
|
* @param {boolean} [deep=false]
|
|
408
431
|
* @return The clone value
|
|
@@ -512,7 +535,7 @@ function baseMerge(obj, source, stack?) {
|
|
|
512
535
|
const srcValue = source[key]
|
|
513
536
|
const objValue = obj[key]
|
|
514
537
|
if (typeof srcValue === 'object' && srcValue !== null) {
|
|
515
|
-
baseMergeDeep(obj, source, key, stack
|
|
538
|
+
baseMergeDeep(obj, source, key, stack || new WeakMap())
|
|
516
539
|
} else {
|
|
517
540
|
if (objValue !== srcValue) {
|
|
518
541
|
obj[key] = srcValue
|
|
@@ -526,7 +549,7 @@ function baseMerge(obj, source, stack?) {
|
|
|
526
549
|
*
|
|
527
550
|
* Note: this method mutates `obj`
|
|
528
551
|
*
|
|
529
|
-
*
|
|
552
|
+
*
|
|
530
553
|
* @param {Object} obj
|
|
531
554
|
* @param {...Object} sources
|
|
532
555
|
* @return {Object} The destination object.
|
|
@@ -586,7 +609,7 @@ export function* union(...args) {
|
|
|
586
609
|
/**
|
|
587
610
|
* Creates an object composed of keys generated from the results of running each element of `arr` thru `func`. The order of grouped values is determined by the order they occur in `arr`. The corresponding value of each key is an array of elements responsible for generating the key.
|
|
588
611
|
*
|
|
589
|
-
*
|
|
612
|
+
*
|
|
590
613
|
* @param {(any[] | Object)} arr The collection to iterate over.
|
|
591
614
|
* @param {(Iteratee | PropertyKey)} [func=id] The iteratee to transform keys.
|
|
592
615
|
* @return {Object} Returns the composed aggregate object.
|
|
File without changes
|
|
File without changes
|
|
@@ -7,7 +7,7 @@ export declare const compose: (...args: any[]) => (x: any) => any;
|
|
|
7
7
|
/**
|
|
8
8
|
* 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.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
10
|
+
*
|
|
11
11
|
* @param {Function} func The function to have its output memoized.
|
|
12
12
|
* @param {Function} [resolver] The function to resolve the cache key.
|
|
13
13
|
* @return {Function} Returns the new memoized function.
|
|
@@ -16,7 +16,7 @@ export declare function memoize(func: Function, resolver?: Function): Function;
|
|
|
16
16
|
/**
|
|
17
17
|
* 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.
|
|
18
18
|
*
|
|
19
|
-
*
|
|
19
|
+
*
|
|
20
20
|
* @param {Function} func The function to debounce.
|
|
21
21
|
* @param {number} wait The number of milliseconds to delay.
|
|
22
22
|
* @param {{ maxWait: number }} { maxWait } The maximum time `func` is allowed to be delayed before it's invoked.
|
|
@@ -28,7 +28,7 @@ export declare function debounce(func: Function, wait: number, { maxWait }: {
|
|
|
28
28
|
/**
|
|
29
29
|
* 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.
|
|
30
30
|
*
|
|
31
|
-
*
|
|
31
|
+
*
|
|
32
32
|
* @param {Function} func The function to throttle.
|
|
33
33
|
* @param {number} time The number of milliseconds to throttle invocations to.
|
|
34
34
|
* @return {Function} Returns the new throttled function.
|