@rimbu/common 0.8.2 → 0.9.2
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/README.md +26 -15
- package/dist/main/async-optlazy.js +6 -2
- package/dist/main/async-optlazy.js.map +1 -1
- package/dist/main/async-reducer.js +22 -22
- package/dist/main/async-reducer.js.map +1 -1
- package/dist/main/collect.js +1 -1
- package/dist/main/comp.js +29 -6
- package/dist/main/comp.js.map +1 -1
- package/dist/main/eq.js +27 -1
- package/dist/main/eq.js.map +1 -1
- package/dist/main/err.js +3 -1
- package/dist/main/err.js.map +1 -1
- package/dist/main/index-range.js +1 -1
- package/dist/main/index-range.js.map +1 -1
- package/dist/main/index.js +6 -1
- package/dist/main/index.js.map +1 -1
- package/dist/main/internal.js +13 -13
- package/dist/main/internal.js.map +1 -1
- package/dist/main/optlazy.js +4 -0
- package/dist/main/optlazy.js.map +1 -1
- package/dist/main/range.js.map +1 -1
- package/dist/main/reducer.js +75 -19
- package/dist/main/reducer.js.map +1 -1
- package/dist/main/update.js +3 -1
- package/dist/main/update.js.map +1 -1
- package/dist/module/async-optlazy.js +4 -0
- package/dist/module/async-optlazy.js.map +1 -1
- package/dist/module/async-reducer.js +12 -12
- package/dist/module/async-reducer.js.map +1 -1
- package/dist/module/collect.js +1 -1
- package/dist/module/comp.js +28 -5
- package/dist/module/comp.js.map +1 -1
- package/dist/module/eq.js +26 -0
- package/dist/module/eq.js.map +1 -1
- package/dist/module/err.js +2 -0
- package/dist/module/err.js.map +1 -1
- package/dist/module/index-range.js.map +1 -1
- package/dist/module/index.js +5 -0
- package/dist/module/index.js.map +1 -1
- package/dist/module/optlazy.js +4 -0
- package/dist/module/optlazy.js.map +1 -1
- package/dist/module/range.js.map +1 -1
- package/dist/module/reducer.js +75 -19
- package/dist/module/reducer.js.map +1 -1
- package/dist/module/update.js +3 -1
- package/dist/module/update.js.map +1 -1
- package/dist/types/async-optlazy.d.ts +4 -0
- package/dist/types/async-reducer.d.ts +37 -22
- package/dist/types/collect.d.ts +2 -2
- package/dist/types/comp.d.ts +32 -5
- package/dist/types/eq.d.ts +26 -0
- package/dist/types/err.d.ts +2 -0
- package/dist/types/index-range.d.ts +14 -13
- package/dist/types/index.d.ts +5 -0
- package/dist/types/optlazy.d.ts +4 -0
- package/dist/types/range.d.ts +11 -10
- package/dist/types/reducer.d.ts +100 -29
- package/dist/types/types.d.ts +0 -4
- package/dist/types/update.d.ts +3 -1
- package/package.json +6 -4
- package/src/async-optlazy.ts +4 -0
- package/src/async-reducer.ts +37 -22
- package/src/collect.ts +2 -2
- package/src/comp.ts +40 -13
- package/src/eq.ts +26 -0
- package/src/err.ts +2 -0
- package/src/index-range.ts +14 -13
- package/src/index.ts +6 -0
- package/src/optlazy.ts +4 -0
- package/src/range.ts +11 -10
- package/src/reducer.ts +107 -31
- package/src/types.ts +0 -5
- package/src/update.ts +3 -1
package/src/async-reducer.ts
CHANGED
|
@@ -45,61 +45,71 @@ export namespace AsyncReducer {
|
|
|
45
45
|
onClose?(state: S, error?: unknown): MaybePromise<void>;
|
|
46
46
|
/**
|
|
47
47
|
* Returns an `AsyncReducer` instance that only passes values to the reducer that satisy the given `pred` predicate.
|
|
48
|
-
* @param pred - a potaentially asynchronous function that returns true if the value should be passed to the reducer based on the following inputs
|
|
49
|
-
* - value: the current input value
|
|
50
|
-
* - index: the current input index
|
|
48
|
+
* @param pred - a potaentially asynchronous function that returns true if the value should be passed to the reducer based on the following inputs:<br/>
|
|
49
|
+
* - value: the current input value<br/>
|
|
50
|
+
* - index: the current input index<br/>
|
|
51
51
|
* - halt: function that, when called, ensures no more new values are passed to the reducer
|
|
52
52
|
* @example
|
|
53
|
+
* ```ts
|
|
53
54
|
* AsyncReducer
|
|
54
55
|
* .createMono(0, async (c, v) => c + v)
|
|
55
56
|
* .filterInput(async v => v > 10)
|
|
56
57
|
* // this reducer will only sum values larger than 10
|
|
58
|
+
* ```
|
|
57
59
|
*/
|
|
58
60
|
filterInput(
|
|
59
61
|
pred: (value: I, index: number, halt: () => void) => MaybePromise<boolean>
|
|
60
62
|
): AsyncReducer<I, O>;
|
|
61
63
|
/**
|
|
62
64
|
* Returns an `AsyncReducer` instance that converts its input values using given `mapFun` before passing them to the reducer.
|
|
63
|
-
* @param mapFun - a potentially asynchronous function that returns a new value to pass to the reducer based on the following inputs
|
|
64
|
-
* - value: the current input value
|
|
65
|
+
* @param mapFun - a potentially asynchronous function that returns a new value to pass to the reducer based on the following inputs:<br/>
|
|
66
|
+
* - value: the current input value<br/>
|
|
65
67
|
* - index: the current input index
|
|
66
68
|
* @example
|
|
69
|
+
* ```ts
|
|
67
70
|
* AsyncReducer
|
|
68
71
|
* .createMono(0, async (c, v) => c + v)
|
|
69
72
|
* .mapInput(async v => v * 2)
|
|
70
73
|
* // this reducer will double all input values before summing them
|
|
74
|
+
* ```
|
|
71
75
|
*/
|
|
72
76
|
mapInput<I2>(
|
|
73
77
|
mapFun: (value: I2, index: number) => MaybePromise<I>
|
|
74
78
|
): AsyncReducer<I2, O>;
|
|
75
79
|
/**
|
|
76
80
|
* Returns an `AsyncReducer` instance that converts or filters its input values using given `collectFun` before passing them to the reducer.
|
|
77
|
-
* @param collectFun - a function receiving
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
81
|
+
* @param collectFun - a function receiving<br/>
|
|
82
|
+
* - `value`: the next value<br/>
|
|
83
|
+
* - `index`: the value index<br/>
|
|
84
|
+
* - `skip`: a token that, when returned, will not add a value to the resulting collection<br/>
|
|
85
|
+
* - `halt`: a function that, when called, ensures no next elements are passed
|
|
82
86
|
* @example
|
|
87
|
+
* ```ts
|
|
83
88
|
* AsyncReducer
|
|
84
89
|
* .createMono(0, async (c, v) => c + v)
|
|
85
90
|
* .collectInput(async (v, _, skip) => v <= 10 ? skip : v * 2)
|
|
86
91
|
* // this reducer will double all input values larger thant 10 before summing them,
|
|
87
92
|
* // and will skip all values smaller than 10
|
|
93
|
+
* ```
|
|
88
94
|
*/
|
|
89
95
|
collectInput<I2>(collectFun: AsyncCollectFun<I2, I>): AsyncReducer<I2, O>;
|
|
90
96
|
/**
|
|
91
97
|
* Returns an `AsyncReducer` instance that converts its output values using given `mapFun`.
|
|
92
98
|
* @param mapFun - a potentially asynchronous function that takes the current output value and converts it to a new output value
|
|
99
|
+
* @example
|
|
100
|
+
* ```ts
|
|
93
101
|
* AsyncReducer
|
|
94
102
|
* .createMono(0, async (c, v) => c + v)
|
|
95
103
|
* .mapOutput(async v => String(v))
|
|
96
104
|
* // this reducer will convert all its results to string before returning them
|
|
105
|
+
* ```
|
|
97
106
|
*/
|
|
98
107
|
mapOutput<O2>(mapFun: (value: O) => MaybePromise<O2>): AsyncReducer<I, O2>;
|
|
99
108
|
/**
|
|
100
109
|
* Returns an `AsyncReducer` instance that takes at most the given `amount` of input elements, and will ignore subsequent elements.
|
|
101
110
|
* @param amount - the amount of elements to accept
|
|
102
111
|
* @example
|
|
112
|
+
* ```ts
|
|
103
113
|
* await AsyncStream
|
|
104
114
|
* .from(Stream.range({ end: 10 }))
|
|
105
115
|
* .reduce(
|
|
@@ -108,12 +118,14 @@ export namespace AsyncReducer {
|
|
|
108
118
|
* .takeInput(2)
|
|
109
119
|
* )
|
|
110
120
|
* // => 1
|
|
121
|
+
* ```
|
|
111
122
|
*/
|
|
112
123
|
takeInput(amount: number): AsyncReducer<I, O>;
|
|
113
124
|
/**
|
|
114
125
|
* Returns a `Reducer` instance that skips the first given `amount` of input elements, and will process subsequent elements.
|
|
115
126
|
* @param amount - the amount of elements to skip
|
|
116
127
|
* @example
|
|
128
|
+
* ```ts
|
|
117
129
|
* await AsyncStream
|
|
118
130
|
* .from(Stream.range({ end: 10 }))
|
|
119
131
|
* .reduce(
|
|
@@ -122,6 +134,7 @@ export namespace AsyncReducer {
|
|
|
122
134
|
* .dropInput(9)
|
|
123
135
|
* )
|
|
124
136
|
* // => 19
|
|
137
|
+
* ```
|
|
125
138
|
*/
|
|
126
139
|
dropInput(amount: number): AsyncReducer<I, O>;
|
|
127
140
|
/**
|
|
@@ -129,6 +142,7 @@ export namespace AsyncReducer {
|
|
|
129
142
|
* @param from - (default: 0) the index at which to start processing elements
|
|
130
143
|
* @param amount - (optional) the amount of elements to process, if not given, processes all elements from the `from` index
|
|
131
144
|
* @example
|
|
145
|
+
* ```ts
|
|
132
146
|
* await AsyncStream
|
|
133
147
|
* .from(Stream.range({ end: 10 }))
|
|
134
148
|
* .reduce(
|
|
@@ -137,6 +151,7 @@ export namespace AsyncReducer {
|
|
|
137
151
|
* .sliceInput(1, 2)
|
|
138
152
|
* )
|
|
139
153
|
* // => 3
|
|
154
|
+
* ```
|
|
140
155
|
*/
|
|
141
156
|
sliceInput(from?: number, amount?: number): AsyncReducer<I, O>;
|
|
142
157
|
}
|
|
@@ -269,10 +284,10 @@ export namespace AsyncReducer {
|
|
|
269
284
|
/**
|
|
270
285
|
* Returns an `AsyncReducer` with the given options:
|
|
271
286
|
* @param init - the optionally lazy and/or promised initial state value
|
|
272
|
-
* @param next - returns (potentially asynchronously) the next state value based on the given inputs
|
|
273
|
-
* - current: the current state
|
|
274
|
-
* - next: the current input value
|
|
275
|
-
* - index: the input index value
|
|
287
|
+
* @param next - returns (potentially asynchronously) the next state value based on the given inputs:<br/>
|
|
288
|
+
* - current: the current state<br/>
|
|
289
|
+
* - next: the current input value<br/>
|
|
290
|
+
* - index: the input index value<br/>
|
|
276
291
|
* - halt: function that, when called, ensures no more elements are passed to the reducer
|
|
277
292
|
* @param stateToResult - a potentially asynchronous function that converts the current state to an output value
|
|
278
293
|
* @param onClose - (optional) a function that will be called when the reducer will no longer receive values
|
|
@@ -297,10 +312,10 @@ export namespace AsyncReducer {
|
|
|
297
312
|
/**
|
|
298
313
|
* Returns an `AsyncReducer` of which the input, state, and output types are the same.
|
|
299
314
|
* @param init - the optionally lazy and/or promised initial state value
|
|
300
|
-
* @param next - returns (potentially asynchronously) the next state value based on the given inputs
|
|
301
|
-
* - current: the current state
|
|
302
|
-
* - next: the current input value
|
|
303
|
-
* - index: the input index value
|
|
315
|
+
* @param next - returns (potentially asynchronously) the next state value based on the given inputs:<br/>
|
|
316
|
+
* - current: the current state<br/>
|
|
317
|
+
* - next: the current input value<br/>
|
|
318
|
+
* - index: the input index value<br/>
|
|
304
319
|
* - halt: function that, when called, ensures no more elements are passed to the reducer
|
|
305
320
|
* @param stateToResult - a potentially asynchronous function that converts the current state to an output value
|
|
306
321
|
* @param onClose - (optional) a function that will be called when the reducer will no longer receive values
|
|
@@ -325,10 +340,10 @@ export namespace AsyncReducer {
|
|
|
325
340
|
/**
|
|
326
341
|
* Returns an `AsyncReducer` of which the state and output types are the same.
|
|
327
342
|
* @param init - the optionally lazy and/or promised initial state value
|
|
328
|
-
* @param next - returns (potentially asynchronously) the next state value based on the given inputs
|
|
329
|
-
* - current: the current state
|
|
330
|
-
* - next: the current input value
|
|
331
|
-
* - index: the input index value
|
|
343
|
+
* @param next - returns (potentially asynchronously) the next state value based on the given inputs:<br/>
|
|
344
|
+
* - current: the current state<br/>
|
|
345
|
+
* - next: the current input value<br/>
|
|
346
|
+
* - index: the input index value<br/>
|
|
332
347
|
* - halt: function that, when called, ensures no more elements are passed to the reducer
|
|
333
348
|
* @param stateToResult - a potentially asynchronous function that converts the current state to an output value
|
|
334
349
|
* @param onClose - (optional) a function that will be called when the reducer will no longer receive values
|
package/src/collect.ts
CHANGED
|
@@ -17,12 +17,12 @@ export type CollectFun<T, R> = (
|
|
|
17
17
|
|
|
18
18
|
export namespace CollectFun {
|
|
19
19
|
/**
|
|
20
|
-
* Indicates, when returned from a collect function, to skip the
|
|
20
|
+
* Indicates, when returned from a collect function, to skip the value.
|
|
21
21
|
*/
|
|
22
22
|
export const Skip = Symbol('Skip');
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
|
-
* Indicates, when returned from a collect function, to skip the
|
|
25
|
+
* Indicates, when returned from a collect function, to skip the value.
|
|
26
26
|
*/
|
|
27
27
|
export type Skip = typeof Skip;
|
|
28
28
|
}
|
package/src/comp.ts
CHANGED
|
@@ -11,6 +11,7 @@ export interface Comp<K> {
|
|
|
11
11
|
* @param value1 - the first value to compare
|
|
12
12
|
* @param value2 - the seconds value to compare
|
|
13
13
|
* @example
|
|
14
|
+
* ```ts
|
|
14
15
|
* const c = Comp.numberComp()
|
|
15
16
|
* console.log(c.compare(5, 5))
|
|
16
17
|
* // => 0
|
|
@@ -18,17 +19,20 @@ export interface Comp<K> {
|
|
|
18
19
|
* // => -2
|
|
19
20
|
* console.log(c.compare(5, 3))
|
|
20
21
|
* // => 2
|
|
22
|
+
* ```
|
|
21
23
|
*/
|
|
22
24
|
compare(value1: K, value2: K): number;
|
|
23
25
|
/**
|
|
24
26
|
* Returns true if this instance can compare given `obj`.
|
|
25
27
|
* @param obj - the object to check
|
|
26
28
|
* @example
|
|
29
|
+
* ```ts
|
|
27
30
|
* const c = Comp.numberComp()
|
|
28
31
|
* console.log(c.isComparable(5))
|
|
29
32
|
* // => true
|
|
30
33
|
* console.log(c.isComparable('a'))
|
|
31
34
|
* // => false
|
|
35
|
+
* ```
|
|
32
36
|
*/
|
|
33
37
|
isComparable(obj: any): obj is K;
|
|
34
38
|
}
|
|
@@ -73,9 +77,11 @@ export namespace Comp {
|
|
|
73
77
|
/**
|
|
74
78
|
* Returns a default number Comp instance that orders numbers naturally.
|
|
75
79
|
* @example
|
|
80
|
+
* ```ts
|
|
76
81
|
* const c = Comp.numberComp();
|
|
77
82
|
* console.log(c.compare(3, 5))
|
|
78
83
|
* // => -2
|
|
84
|
+
* ```
|
|
79
85
|
*/
|
|
80
86
|
export function numberComp(): Comp<number> {
|
|
81
87
|
return _numberComp;
|
|
@@ -93,11 +99,13 @@ export namespace Comp {
|
|
|
93
99
|
/**
|
|
94
100
|
* Returns a default boolean Comp instance that orders booleans according to false < true.
|
|
95
101
|
* @example
|
|
102
|
+
* ```ts
|
|
96
103
|
* const c = Comp.booleanComp();
|
|
97
104
|
* console.log(c.compare(false, true) < 0)
|
|
98
105
|
* // => true
|
|
99
106
|
* console.log(c.compare(true, true))
|
|
100
107
|
* // => 0
|
|
108
|
+
* ```
|
|
101
109
|
*/
|
|
102
110
|
export function booleanComp(): Comp<boolean> {
|
|
103
111
|
return _booleanComp;
|
|
@@ -233,7 +241,7 @@ export namespace Comp {
|
|
|
233
241
|
isComparable(obj): obj is T {
|
|
234
242
|
return obj instanceof cls;
|
|
235
243
|
},
|
|
236
|
-
compare(v1, v2) {
|
|
244
|
+
compare(v1, v2): number {
|
|
237
245
|
return valueComp.compare(v1.valueOf(), v2.valueOf());
|
|
238
246
|
},
|
|
239
247
|
};
|
|
@@ -256,7 +264,7 @@ export namespace Comp {
|
|
|
256
264
|
typeof obj === 'object' && obj !== null && Symbol.iterator in obj
|
|
257
265
|
);
|
|
258
266
|
},
|
|
259
|
-
compare(v1, v2) {
|
|
267
|
+
compare(v1, v2): number {
|
|
260
268
|
const iter1 = v1[Symbol.iterator]();
|
|
261
269
|
const iter2 = v2[Symbol.iterator]();
|
|
262
270
|
|
|
@@ -283,11 +291,13 @@ export namespace Comp {
|
|
|
283
291
|
* Returns a Comp instance for Iterable objects that orders the Iterables by comparing the elements with the given `itemComp` Comp instance.
|
|
284
292
|
* @param itemComp - (optional) the Comp instance to use to compare the Iterable's elements.
|
|
285
293
|
* @example
|
|
294
|
+
* ```ts
|
|
286
295
|
* const c = Comp.iterableComp();
|
|
287
296
|
* console.log(c.compare([1, 3, 2], [1, 3, 2]))
|
|
288
297
|
* // => 0
|
|
289
298
|
* console.log(c.compare([1, 2, 3, 4], [1, 3, 2]) < 0)
|
|
290
299
|
* // => true
|
|
300
|
+
* ```
|
|
291
301
|
*/
|
|
292
302
|
export function iterableComp<T>(itemComp?: Comp<T>): Comp<Iterable<T>> {
|
|
293
303
|
if (undefined === itemComp) return _iterableAnyComp;
|
|
@@ -329,7 +339,7 @@ export namespace Comp {
|
|
|
329
339
|
isComparable(obj): obj is Record<any, any> {
|
|
330
340
|
return true;
|
|
331
341
|
},
|
|
332
|
-
compare(v1, v2) {
|
|
342
|
+
compare(v1, v2): number {
|
|
333
343
|
const keys1 = Object.keys(v1);
|
|
334
344
|
const keys2 = Object.keys(v2);
|
|
335
345
|
|
|
@@ -371,14 +381,16 @@ export namespace Comp {
|
|
|
371
381
|
|
|
372
382
|
/**
|
|
373
383
|
* Returns a Comp instance for objects that orders the object keys according to the given `keyComp`, and then compares the corresponding
|
|
374
|
-
* values using the given `valueComp`. Objects are then compared as follows
|
|
375
|
-
*
|
|
376
|
-
*
|
|
377
|
-
*
|
|
378
|
-
*
|
|
384
|
+
* values using the given `valueComp`. Objects are then compared as follows:<br/>
|
|
385
|
+
* starting with the smallest key of either object:<br/>
|
|
386
|
+
* - if only one of the objects has the key, the object with the key is considered to be larger than the other<br/>
|
|
387
|
+
* - if both objects have the key, the values are compared with `valueComp`. If the values are not equal, this result is returned.<br/>
|
|
388
|
+
*
|
|
389
|
+
* if the objects have the same keys with the same values, they are considered equal<br/>
|
|
379
390
|
* @param keyComp - (optional) the Comp instance used to order the object keys
|
|
380
391
|
* @param valueComp - (optional) the Comp instance used to order the object values
|
|
381
392
|
* @example
|
|
393
|
+
* ```ts
|
|
382
394
|
* const c = Comp.objectComp();
|
|
383
395
|
* console.log(c.compare({ a: 1 }, { a: 1 }))
|
|
384
396
|
* // => 0
|
|
@@ -390,6 +402,7 @@ export namespace Comp {
|
|
|
390
402
|
* // => true
|
|
391
403
|
* console.log(c.compare({ a: 1, b: 2 }, { b: 2, a: 1 }))
|
|
392
404
|
* // => 0
|
|
405
|
+
* ```
|
|
393
406
|
*/
|
|
394
407
|
export function objectComp(options?: {
|
|
395
408
|
keyComp?: Comp<any>;
|
|
@@ -405,7 +418,7 @@ export namespace Comp {
|
|
|
405
418
|
isComparable(obj): obj is any {
|
|
406
419
|
return true;
|
|
407
420
|
},
|
|
408
|
-
compare(v1, v2) {
|
|
421
|
+
compare(v1, v2): number {
|
|
409
422
|
if (Object.is(v1, v2)) return 0;
|
|
410
423
|
|
|
411
424
|
const type1 = typeof v1;
|
|
@@ -472,10 +485,12 @@ export namespace Comp {
|
|
|
472
485
|
* Returns a Comp instance that compares any value using default comparison functions, but never recursively compares
|
|
473
486
|
* Iterables or objects. In those cases, it will use the stringComp instance.
|
|
474
487
|
* @example
|
|
488
|
+
* ```ts
|
|
475
489
|
* const c = Comp.anyFlatComp();
|
|
476
490
|
* console.log(c.compare({ a: 1, b: 1 }, { b: 1, a: 1 }) < 0)
|
|
477
491
|
* // => true
|
|
478
492
|
* // First object is smaller because the objects are converted to a string with and then compares the resulting string.
|
|
493
|
+
* ```
|
|
479
494
|
*/
|
|
480
495
|
export function anyFlatComp<T>(): Comp<T> {
|
|
481
496
|
return _anyFlatComp;
|
|
@@ -485,12 +500,14 @@ export namespace Comp {
|
|
|
485
500
|
* Returns a Comp instance that compares any value using default comparison functions. For Iterables and objects, their elements are compared
|
|
486
501
|
* only one level deep for performance and to avoid infinite recursion.
|
|
487
502
|
* @example
|
|
503
|
+
* ```ts
|
|
488
504
|
* const c = Comp.anyShallowComp();
|
|
489
505
|
* console.log(c.compare({ a: 1, b: 1 }, { b: 1, a: 1 }))
|
|
490
506
|
* // => 0
|
|
491
507
|
* console.log(c.compare([{ a: 1, b: 1 }], [{ b: 1, a: 1 }]) < 0)
|
|
492
508
|
* // => true
|
|
493
509
|
* // First object is smaller because the objects are converted to a string and then compares the resulting string.
|
|
510
|
+
* ```
|
|
494
511
|
*/
|
|
495
512
|
export function anyShallowComp<T>(): Comp<T> {
|
|
496
513
|
return _anyShallowComp;
|
|
@@ -501,11 +518,13 @@ export namespace Comp {
|
|
|
501
518
|
* recursively.
|
|
502
519
|
* @note can become slow with large nested arrays and objects, and circular structures can cause infinite loops
|
|
503
520
|
* @example
|
|
521
|
+
* ```ts
|
|
504
522
|
* const c = Comp.anyDeepComp();
|
|
505
523
|
* console.log(c.compare({ a: 1, b: 1 }, { b: 1, a: 1 }))
|
|
506
524
|
* // => 0
|
|
507
525
|
* console.log(c.compare([{ a: 1, b: 1 }], [{ b: 1, a: 1 }]))
|
|
508
526
|
* // => 0
|
|
527
|
+
* ```
|
|
509
528
|
*/
|
|
510
529
|
export function anyDeepComp<T>(): Comp<T> {
|
|
511
530
|
return _anyDeepComp;
|
|
@@ -516,18 +535,20 @@ export namespace Comp {
|
|
|
516
535
|
* than any other value, and equal to another undefined.
|
|
517
536
|
* @param comp - the Comp instance to wrap
|
|
518
537
|
* @example
|
|
538
|
+
* ```ts
|
|
519
539
|
* const c = Comp.withUndefined(Comp.numberComp())
|
|
520
540
|
* console.log(c.compare(undefined, 5) < 0)
|
|
521
541
|
* // => true
|
|
522
542
|
* console.log(c.compare(undefined, undefined))
|
|
523
543
|
* // => 0
|
|
544
|
+
* ```
|
|
524
545
|
*/
|
|
525
546
|
export function withUndefined<T>(comp: Comp<T>): Comp<T | undefined> {
|
|
526
547
|
return {
|
|
527
548
|
isComparable(obj): obj is T | undefined {
|
|
528
549
|
return undefined === obj || comp.isComparable(obj);
|
|
529
550
|
},
|
|
530
|
-
compare(v1, v2) {
|
|
551
|
+
compare(v1, v2): number {
|
|
531
552
|
if (undefined === v1) {
|
|
532
553
|
if (undefined === v2) return 0;
|
|
533
554
|
return -1;
|
|
@@ -543,18 +564,20 @@ export namespace Comp {
|
|
|
543
564
|
* than any other value, and equal to another null.
|
|
544
565
|
* @param comp - the Comp instance to wrap
|
|
545
566
|
* @example
|
|
567
|
+
* ```ts
|
|
546
568
|
* const c = Comp.withNull(Comp.numberComp())
|
|
547
569
|
* console.log(c.compare(null, 5) < 0)
|
|
548
570
|
* // => true
|
|
549
571
|
* console.log(c.compare(null, null))
|
|
550
572
|
* // => 0
|
|
573
|
+
* ```
|
|
551
574
|
*/
|
|
552
575
|
export function withNull<T>(comp: Comp<T>): Comp<T | null> {
|
|
553
576
|
return {
|
|
554
577
|
isComparable(obj): obj is T | null {
|
|
555
578
|
return null === obj || comp.isComparable(obj);
|
|
556
579
|
},
|
|
557
|
-
compare(v1, v2) {
|
|
580
|
+
compare(v1, v2): number {
|
|
558
581
|
if (null === v1) {
|
|
559
582
|
if (null === v2) return 0;
|
|
560
583
|
return -1;
|
|
@@ -569,15 +592,17 @@ export namespace Comp {
|
|
|
569
592
|
* Returns a Comp instance the reverses the order of the given `comp` instance.
|
|
570
593
|
* @param comp - the Comp instance to wrap
|
|
571
594
|
* @example
|
|
595
|
+
* ```ts
|
|
572
596
|
* const c = Comp.invert(Comp.numberComp())
|
|
573
597
|
* console.log(c.compare(3, 5) > 0)
|
|
574
598
|
* // => true
|
|
575
599
|
* console.log(c.compare(5, 5))
|
|
576
600
|
* // => 0
|
|
601
|
+
* ```
|
|
577
602
|
*/
|
|
578
603
|
export function invert<T>(comp: Comp<T>): Comp<T> {
|
|
579
604
|
return {
|
|
580
|
-
compare(v1, v2) {
|
|
605
|
+
compare(v1, v2): number {
|
|
581
606
|
return comp.compare(v2, v1);
|
|
582
607
|
},
|
|
583
608
|
isComparable: comp.isComparable,
|
|
@@ -588,11 +613,13 @@ export namespace Comp {
|
|
|
588
613
|
* Returns an `Eq` equality instance thet will return true when the given `comp` comparable instance returns 0.
|
|
589
614
|
* @param comp - the `Comp` comparable instance to convert
|
|
590
615
|
* @example
|
|
616
|
+
* ```ts
|
|
591
617
|
* const eq = Comp.toEq(Comp.objectComp())
|
|
592
618
|
* console.log(eq({ a: 1, b: 2 }, { b: 2, a: 1 }))
|
|
593
619
|
* // => true
|
|
620
|
+
* ```
|
|
594
621
|
*/
|
|
595
622
|
export function toEq<T>(comp: Comp<T>): Eq<T> {
|
|
596
|
-
return (v1, v2) => comp.compare(v1, v2) === 0;
|
|
623
|
+
return (v1: T, v2: T): boolean => comp.compare(v1, v2) === 0;
|
|
597
624
|
}
|
|
598
625
|
}
|
package/src/eq.ts
CHANGED
|
@@ -32,11 +32,13 @@ export namespace Eq {
|
|
|
32
32
|
/**
|
|
33
33
|
* An Eq instance that uses `Object.is` to determine if two objects are equal.
|
|
34
34
|
* @example
|
|
35
|
+
* ```ts
|
|
35
36
|
* const eq = Eq.objectIs
|
|
36
37
|
* console.log(eq(5, 5))
|
|
37
38
|
* // => true
|
|
38
39
|
* console.log(eq(5, 'a'))
|
|
39
40
|
* // => false
|
|
41
|
+
* ```
|
|
40
42
|
*/
|
|
41
43
|
export const objectIs: Eq<any> = Object.is;
|
|
42
44
|
|
|
@@ -48,11 +50,13 @@ export namespace Eq {
|
|
|
48
50
|
* @typeparam T - the object type containing a valueOf function of type V
|
|
49
51
|
* @typeparam V - the valueOf result type
|
|
50
52
|
* @example
|
|
53
|
+
* ```ts
|
|
51
54
|
* const eq = Eq.valueOfEq()
|
|
52
55
|
* console.log(eq(new Number(5), new Number(5)))
|
|
53
56
|
* // => true
|
|
54
57
|
* console.log(eq(new Number(5), new Number(3)))
|
|
55
58
|
* // => false
|
|
59
|
+
* ```
|
|
56
60
|
*/
|
|
57
61
|
export function valueOfEq<T extends { valueOf(): V }, V>(): Eq<T> {
|
|
58
62
|
return _valueOfEq;
|
|
@@ -61,11 +65,13 @@ export namespace Eq {
|
|
|
61
65
|
/**
|
|
62
66
|
* Returns an Eq instance that compares Date objects according to their `valueOf` value.
|
|
63
67
|
* @example
|
|
68
|
+
* ```ts
|
|
64
69
|
* const eq = Eq.dateEq()
|
|
65
70
|
* console.log(eq(new Date(2020, 1, 1), new Date(2020, 1, 1))
|
|
66
71
|
* // => true
|
|
67
72
|
* console.log(eq(new Date(2020, 1, 1), new Date(2020, 2, 1))
|
|
68
73
|
* // => false
|
|
74
|
+
* ```
|
|
69
75
|
*/
|
|
70
76
|
export function dateEq(): Eq<Date> {
|
|
71
77
|
return _valueOfEq;
|
|
@@ -96,11 +102,13 @@ export namespace Eq {
|
|
|
96
102
|
* @typeparam T - the Iterable element type
|
|
97
103
|
* @param itemEq - (optional) the Eq instance to use to compare the Iterable's elements
|
|
98
104
|
* @example
|
|
105
|
+
* ```ts
|
|
99
106
|
* const eq = Eq.iterableEq();
|
|
100
107
|
* console.log(eq([1, 2, 3], [1, 2, 3])
|
|
101
108
|
* // => true
|
|
102
109
|
* console.log(eq([1, 2, 3], [1, 3, 2])
|
|
103
110
|
* // => false
|
|
111
|
+
* ```
|
|
104
112
|
*/
|
|
105
113
|
export function iterableEq<T>(itemEq?: Eq<T>): Eq<Iterable<T>> {
|
|
106
114
|
if (undefined === itemEq) return _iterableAnyEq;
|
|
@@ -141,11 +149,13 @@ export namespace Eq {
|
|
|
141
149
|
* @typeparam - the object property value type
|
|
142
150
|
* @param valueEq - (optional) the Eq instance to use to compare property values
|
|
143
151
|
* @example
|
|
152
|
+
* ```ts
|
|
144
153
|
* const eq = Eq.objectEq()
|
|
145
154
|
* console.log(eq({ a: 1, b: { c: 2 }}, { b: { c: 2 }, a: 1 }))
|
|
146
155
|
* // => true
|
|
147
156
|
* console.log(eq({ a: 1, b: { c: 2 }}, { a: 1, b: { c: 3 }}))
|
|
148
157
|
* // => false
|
|
158
|
+
* ```
|
|
149
159
|
*/
|
|
150
160
|
export function objectEq<V = any>(valueEq?: Eq<V>): Eq<Record<any, V>> {
|
|
151
161
|
if (undefined === valueEq) return _objectEq;
|
|
@@ -217,11 +227,13 @@ export namespace Eq {
|
|
|
217
227
|
* it will compare with Object.is.
|
|
218
228
|
* @typeparam T - the value type
|
|
219
229
|
* @example
|
|
230
|
+
* ```ts
|
|
220
231
|
* const eq = anyFlatEq()
|
|
221
232
|
* console.log(eq(1, 'a'))
|
|
222
233
|
* // => false
|
|
223
234
|
* console.log(eq({ a: 1, b: 2 }, { b: 2, a: 1 }))
|
|
224
235
|
* // => false
|
|
236
|
+
* ```
|
|
225
237
|
*/
|
|
226
238
|
export function anyFlatEq<T = any>(): Eq<T> {
|
|
227
239
|
return _anyFlatEq;
|
|
@@ -233,6 +245,7 @@ export namespace Eq {
|
|
|
233
245
|
* with Object.is.
|
|
234
246
|
* @typeparam T - the value type
|
|
235
247
|
* @example
|
|
248
|
+
* ```ts
|
|
236
249
|
* const eq = anyFlatEq()
|
|
237
250
|
* console.log(eq(1, 'a'))
|
|
238
251
|
* // => false
|
|
@@ -240,6 +253,7 @@ export namespace Eq {
|
|
|
240
253
|
* // => true
|
|
241
254
|
* console.log(eq([{ a: 1, b: 2 }], [{ b: 2, a: 1 }]))
|
|
242
255
|
* // => false
|
|
256
|
+
* ```
|
|
243
257
|
*/
|
|
244
258
|
export function anyShallowEq<T = any>(): Eq<T> {
|
|
245
259
|
return _anyShallowEq;
|
|
@@ -252,6 +266,7 @@ export namespace Eq {
|
|
|
252
266
|
* may cause infinite loops
|
|
253
267
|
* @typeparam T - the value type
|
|
254
268
|
* @example
|
|
269
|
+
* ```ts
|
|
255
270
|
* const eq = anyFlatEq()
|
|
256
271
|
* console.log(eq(1, 'a'))
|
|
257
272
|
* // => false
|
|
@@ -259,6 +274,7 @@ export namespace Eq {
|
|
|
259
274
|
* // => true
|
|
260
275
|
* console.log(eq([{ a: 1, b: 2 }], [{ b: 2, a: 1 }]))
|
|
261
276
|
* // => false
|
|
277
|
+
* ```
|
|
262
278
|
*/
|
|
263
279
|
export function anyDeepEq<T = any>(): Eq<T> {
|
|
264
280
|
return _anyDeepEq;
|
|
@@ -274,11 +290,13 @@ export namespace Eq {
|
|
|
274
290
|
* @param locales - (optional) a locale or list of locales
|
|
275
291
|
* @param options - (optional) see String.localeCompare for details
|
|
276
292
|
* @example
|
|
293
|
+
* ```ts
|
|
277
294
|
* const eq = Eq.createStringCollatorEq()
|
|
278
295
|
* console.log(eq('a', 'a'))
|
|
279
296
|
* // => true
|
|
280
297
|
* console.log(eq('abc', 'aBc'))
|
|
281
298
|
* // => false
|
|
299
|
+
* ```
|
|
282
300
|
*/
|
|
283
301
|
export function createStringCollatorEq(
|
|
284
302
|
...args: ConstructorParameters<typeof Intl.Collator>
|
|
@@ -297,11 +315,13 @@ export namespace Eq {
|
|
|
297
315
|
/**
|
|
298
316
|
* Returns an Eq instance that considers strings equal regardless of their case.
|
|
299
317
|
* @example
|
|
318
|
+
* ```ts
|
|
300
319
|
* const eq = Eq.stringCaseInsentitiveEq()
|
|
301
320
|
* console.log(eq('aB', 'Ab'))
|
|
302
321
|
* // => true
|
|
303
322
|
* console.log(eq('aBc', 'abB'))
|
|
304
323
|
* // => false
|
|
324
|
+
* ```
|
|
305
325
|
*/
|
|
306
326
|
export function stringCaseInsentitiveEq(): Eq<string> {
|
|
307
327
|
return _stringCaseInsensitiveEq;
|
|
@@ -324,11 +344,13 @@ export namespace Eq {
|
|
|
324
344
|
/**
|
|
325
345
|
* Returns an Eq instance that considers strings equal when all their charcodes are equal.
|
|
326
346
|
* @example
|
|
347
|
+
* ```ts
|
|
327
348
|
* const eq = Eq.stringCharCodeEq()
|
|
328
349
|
* console.log(eq('a', 'a'))
|
|
329
350
|
* // => true
|
|
330
351
|
* console.log(eq('abc', 'aBc'))
|
|
331
352
|
* // => false
|
|
353
|
+
* ```
|
|
332
354
|
*/
|
|
333
355
|
export function stringCharCodeEq(): Eq<string> {
|
|
334
356
|
return _stringCharCodeEq;
|
|
@@ -347,11 +369,13 @@ export namespace Eq {
|
|
|
347
369
|
/**
|
|
348
370
|
* Returns an Eq instance that considers values equal their JSON.stringify values are equal.
|
|
349
371
|
* @example
|
|
372
|
+
* ```ts
|
|
350
373
|
* const eq = Eq.anyJsonEq()
|
|
351
374
|
* console.log(eq({ a: 1, b: 2 }, { a: 1, b: 2 }))
|
|
352
375
|
* // => true
|
|
353
376
|
* console.log(eq({ a: 1, b: 2 }, { b: 2, a: 1 }))
|
|
354
377
|
* // => false
|
|
378
|
+
* ```
|
|
355
379
|
*/
|
|
356
380
|
export function anyJsonEq(): Eq<any> {
|
|
357
381
|
return _anyJsonEq;
|
|
@@ -362,6 +386,7 @@ export namespace Eq {
|
|
|
362
386
|
* or if [A, B] equals [D, C]
|
|
363
387
|
* @param eq - (optional) an alternative `Eq` instance to use for the values in the tuple
|
|
364
388
|
* @example
|
|
389
|
+
* ```ts
|
|
365
390
|
* const eq = Eq.tupleSymmetric()
|
|
366
391
|
* console.log(eq([1, 2], [1, 2]))
|
|
367
392
|
* // => true
|
|
@@ -369,6 +394,7 @@ export namespace Eq {
|
|
|
369
394
|
* // => true
|
|
370
395
|
* console.log(eq([1, 3], [2, 1]))
|
|
371
396
|
* // => false
|
|
397
|
+
* ```
|
|
372
398
|
*/
|
|
373
399
|
export function tupleSymmetric<T>(
|
|
374
400
|
eq: Eq<T> = defaultEq()
|
package/src/err.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Throws an `Err.ForcedError` error when called.
|
|
3
3
|
* @example
|
|
4
|
+
* ```ts
|
|
4
5
|
* const emptyMap = HashMap.empty<number, string>()
|
|
5
6
|
* emptyMap.get(5, Err);
|
|
6
7
|
* // throws: Err.CustomError(message: 'Err: forced to throw error')
|
|
8
|
+
* ```
|
|
7
9
|
*/
|
|
8
10
|
export function Err(): never {
|
|
9
11
|
return ErrBase.msg('Err: Forced to throw error')();
|
package/src/index-range.ts
CHANGED
|
@@ -3,19 +3,20 @@ import type { Range } from './internal';
|
|
|
3
3
|
/**
|
|
4
4
|
* A flexible range specification for numeric indices.
|
|
5
5
|
* If a start or end is defined, a tuple can be used where the second item is a boolean
|
|
6
|
-
* indicating whether that end is inclusive or exclusive
|
|
7
|
-
* An IndexRange can have one of the following forms
|
|
8
|
-
*
|
|
9
|
-
* - {
|
|
10
|
-
* - { start: number
|
|
11
|
-
* - { start: number,
|
|
12
|
-
* - { start: number, end:
|
|
13
|
-
* - { start: [number, boolean] }
|
|
14
|
-
* - { start: [number, boolean]
|
|
15
|
-
* - { start: [number, boolean],
|
|
16
|
-
* - { start: [number, boolean], end:
|
|
17
|
-
* - { end: number }
|
|
18
|
-
* - { end:
|
|
6
|
+
* indicating whether that end is inclusive or exclusive.<br/>
|
|
7
|
+
* An IndexRange can have one of the following forms:<br/>
|
|
8
|
+
* <br/>
|
|
9
|
+
* - { amount: number }<br/>
|
|
10
|
+
* - { start: number }<br/>
|
|
11
|
+
* - { start: number, amount: number }<br/>
|
|
12
|
+
* - { start: number, end: number }<br/>
|
|
13
|
+
* - { start: number, end: [number, boolean] }<br/>
|
|
14
|
+
* - { start: [number, boolean] }<br/>
|
|
15
|
+
* - { start: [number, boolean], amount: number }<br/>
|
|
16
|
+
* - { start: [number, boolean], end: number }<br/>
|
|
17
|
+
* - { start: [number, boolean], end: [number, boolean] }<br/>
|
|
18
|
+
* - { end: number }<br/>
|
|
19
|
+
* - { end: [number, boolean] }<br/>
|
|
19
20
|
*/
|
|
20
21
|
export type IndexRange =
|
|
21
22
|
| { amount: number; start?: number | [number, boolean]; end?: undefined }
|