@naturalcycles/js-lib 14.70.2 → 14.74.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/error/try.d.ts +1 -1
- package/dist/error/try.js +2 -0
- package/dist/index.d.ts +28 -26
- package/dist/index.js +28 -122
- package/dist/math/math.util.d.ts +4 -0
- package/dist/math/math.util.js +18 -1
- package/dist/math/sma.d.ts +2 -2
- package/dist/math/stack.util.d.ts +50 -0
- package/dist/math/stack.util.js +87 -0
- package/dist/number/number.util.d.ts +1 -1
- package/dist/number/number.util.js +1 -1
- package/dist/promise/pBatch.d.ts +2 -3
- package/dist/promise/pFilter.d.ts +2 -2
- package/dist/promise/pMap.d.ts +2 -3
- package/dist/promise/pMap.js +13 -7
- package/dist/promise/pProps.d.ts +3 -1
- package/dist/promise/pProps.js +4 -5
- package/dist/seq/seq.d.ts +30 -0
- package/dist/seq/seq.js +141 -0
- package/dist/typeFest.d.ts +0 -30
- package/dist/types.d.ts +13 -1
- package/dist/types.js +9 -1
- package/dist-esm/error/try.js +2 -0
- package/dist-esm/index.js +26 -24
- package/dist-esm/math/math.util.js +16 -0
- package/dist-esm/math/stack.util.js +82 -0
- package/dist-esm/number/number.util.js +1 -1
- package/dist-esm/promise/pMap.js +14 -8
- package/dist-esm/promise/pProps.js +4 -5
- package/dist-esm/seq/seq.js +136 -0
- package/dist-esm/types.js +8 -0
- package/package.json +1 -1
- package/src/error/try.ts +4 -1
- package/src/index.ts +36 -195
- package/src/math/math.util.ts +21 -0
- package/src/math/sma.ts +1 -1
- package/src/math/stack.util.ts +94 -0
- package/src/number/number.util.ts +1 -1
- package/src/promise/pBatch.ts +2 -3
- package/src/promise/pFilter.ts +2 -2
- package/src/promise/pMap.ts +16 -11
- package/src/promise/pProps.ts +6 -7
- package/src/seq/seq.ts +143 -0
- package/src/typeFest.ts +0 -32
- package/src/types.ts +22 -1
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { END, SKIP } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Inspired by Kotlin Sequences.
|
|
4
|
+
* Similar to arrays, but with lazy evaluation, abortable.
|
|
5
|
+
* Can be useful when it's not feasible/performant to create an array of values to iterate upfront
|
|
6
|
+
* (e.g to construct 1000 Dayjs instances only to find that 2 of them were needed).
|
|
7
|
+
*
|
|
8
|
+
* @experimental
|
|
9
|
+
*/
|
|
10
|
+
export class Seq {
|
|
11
|
+
constructor(initialValue, nextFn) {
|
|
12
|
+
this.nextFn = nextFn;
|
|
13
|
+
this.sentInitialValue = false;
|
|
14
|
+
this.i = -1;
|
|
15
|
+
this.currentValue = initialValue;
|
|
16
|
+
}
|
|
17
|
+
[Symbol.iterator]() {
|
|
18
|
+
return {
|
|
19
|
+
next: () => {
|
|
20
|
+
const value = this.next();
|
|
21
|
+
return value === END ? { done: true, value: undefined } : { value };
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
static create(initialValue, nextFn) {
|
|
26
|
+
return new Seq(initialValue, nextFn);
|
|
27
|
+
}
|
|
28
|
+
static range(minIncl, maxExcl, step = 1) {
|
|
29
|
+
const max = maxExcl - step;
|
|
30
|
+
return new Seq(minIncl, n => (n < max ? n + step : END));
|
|
31
|
+
}
|
|
32
|
+
static from(a) {
|
|
33
|
+
const it = a[Symbol.iterator]();
|
|
34
|
+
const v = it.next();
|
|
35
|
+
if (v.done)
|
|
36
|
+
return new Seq(END, () => { });
|
|
37
|
+
return new Seq(v.value, () => {
|
|
38
|
+
const v = it.next();
|
|
39
|
+
if (v.done)
|
|
40
|
+
return END;
|
|
41
|
+
return v.value;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
static empty() {
|
|
45
|
+
return new Seq(END, () => { });
|
|
46
|
+
}
|
|
47
|
+
next() {
|
|
48
|
+
if (this.currentValue === END)
|
|
49
|
+
return END;
|
|
50
|
+
this.i++;
|
|
51
|
+
let v;
|
|
52
|
+
if (!this.sentInitialValue) {
|
|
53
|
+
this.sentInitialValue = true;
|
|
54
|
+
v = this.currentValue;
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
v = this.nextFn(this.currentValue, this.i);
|
|
58
|
+
}
|
|
59
|
+
// console.log(`_seq`, v)
|
|
60
|
+
if (v === SKIP)
|
|
61
|
+
return this.next();
|
|
62
|
+
return (this.currentValue = v);
|
|
63
|
+
}
|
|
64
|
+
// Chainable functions - return another (chained) Sequence
|
|
65
|
+
// map<OUT>(mapper: Mapper<T, OUT | typeof SKIP | typeof END>): Seq<OUT> {
|
|
66
|
+
// if (this.currentValue === END) return this as any
|
|
67
|
+
//
|
|
68
|
+
// // Iterate until first valid value, to have as `initialValue` of the new Sequence
|
|
69
|
+
// let v: OUT | typeof SKIP | typeof END
|
|
70
|
+
//
|
|
71
|
+
// while (true) {
|
|
72
|
+
// v = mapper(this.currentValue, ++this.i)
|
|
73
|
+
// if (v === SKIP) continue
|
|
74
|
+
// if (v === END) return this as any
|
|
75
|
+
// }
|
|
76
|
+
//
|
|
77
|
+
// return new Seq<OUT>(v as OUT, (current, i) => {
|
|
78
|
+
// const v = mapper(current, i)
|
|
79
|
+
//
|
|
80
|
+
// })
|
|
81
|
+
// }
|
|
82
|
+
// Final functions - return final value, not a chained sequence
|
|
83
|
+
find(predicate) {
|
|
84
|
+
do {
|
|
85
|
+
const v = this.next();
|
|
86
|
+
if (v === END)
|
|
87
|
+
return; // not found, end of sequence
|
|
88
|
+
const r = predicate(v, this.i);
|
|
89
|
+
if (r === END)
|
|
90
|
+
return;
|
|
91
|
+
if (r)
|
|
92
|
+
return v;
|
|
93
|
+
// otherwise proceed
|
|
94
|
+
} while (true); // eslint-disable-line no-constant-condition
|
|
95
|
+
}
|
|
96
|
+
some(predicate) {
|
|
97
|
+
do {
|
|
98
|
+
const v = this.next();
|
|
99
|
+
if (v === END)
|
|
100
|
+
return false;
|
|
101
|
+
const r = predicate(v, this.i);
|
|
102
|
+
if (r === END)
|
|
103
|
+
return false;
|
|
104
|
+
if (r)
|
|
105
|
+
return true;
|
|
106
|
+
} while (true); // eslint-disable-line no-constant-condition
|
|
107
|
+
}
|
|
108
|
+
every(predicate) {
|
|
109
|
+
do {
|
|
110
|
+
const v = this.next();
|
|
111
|
+
if (v === END)
|
|
112
|
+
return true;
|
|
113
|
+
const r = predicate(v, this.i);
|
|
114
|
+
if (r === END)
|
|
115
|
+
return true;
|
|
116
|
+
if (!r)
|
|
117
|
+
return false;
|
|
118
|
+
} while (true); // eslint-disable-line no-constant-condition
|
|
119
|
+
}
|
|
120
|
+
toArray() {
|
|
121
|
+
const a = [];
|
|
122
|
+
// eslint-disable-next-line no-constant-condition
|
|
123
|
+
while (true) {
|
|
124
|
+
const v = this.next();
|
|
125
|
+
if (v === END)
|
|
126
|
+
return a;
|
|
127
|
+
a.push(v);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Convenience function to create a Sequence.
|
|
133
|
+
*/
|
|
134
|
+
export function _seq(initialValue, nextFn) {
|
|
135
|
+
return Seq.create(initialValue, nextFn);
|
|
136
|
+
}
|
package/dist-esm/types.js
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Symbol to indicate END of Sequence.
|
|
3
|
+
*/
|
|
4
|
+
export const END = Symbol('END');
|
|
5
|
+
/**
|
|
6
|
+
* Symbol to indicate SKIP of item (e.g in AbortableMapper)
|
|
7
|
+
*/
|
|
8
|
+
export const SKIP = Symbol('SKIP');
|
|
1
9
|
export const _passthroughMapper = item => item;
|
|
2
10
|
export const _passUndefinedMapper = () => undefined;
|
|
3
11
|
/**
|
package/package.json
CHANGED
package/src/error/try.ts
CHANGED
|
@@ -24,6 +24,9 @@ export function _try<ERR = unknown, RETURN = void>(
|
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
// todo: remove when eslint starts to know about Awaited
|
|
28
|
+
/* eslint-disable no-undef */
|
|
29
|
+
|
|
27
30
|
/**
|
|
28
31
|
* Like _try, but for Promises.
|
|
29
32
|
*
|
|
@@ -32,7 +35,7 @@ export function _try<ERR = unknown, RETURN = void>(
|
|
|
32
35
|
*/
|
|
33
36
|
export async function pTry<ERR = unknown, RETURN = void>(
|
|
34
37
|
promise: Promise<RETURN>,
|
|
35
|
-
): Promise<[err: ERR | null, value: RETURN]> {
|
|
38
|
+
): Promise<[err: ERR | null, value: Awaited<RETURN>]> {
|
|
36
39
|
try {
|
|
37
40
|
return [null, await promise]
|
|
38
41
|
} catch (err) {
|
package/src/index.ts
CHANGED
|
@@ -1,29 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
_difference,
|
|
6
|
-
_dropRightWhile,
|
|
7
|
-
_dropWhile,
|
|
8
|
-
_findLast,
|
|
9
|
-
_flatten,
|
|
10
|
-
_flattenDeep,
|
|
11
|
-
_groupBy,
|
|
12
|
-
_intersection,
|
|
13
|
-
_last,
|
|
14
|
-
_mapToObject,
|
|
15
|
-
_shuffle,
|
|
16
|
-
_sortBy,
|
|
17
|
-
_sum,
|
|
18
|
-
_sumBy,
|
|
19
|
-
_takeRightWhile,
|
|
20
|
-
_takeWhile,
|
|
21
|
-
_uniq,
|
|
22
|
-
_uniqBy,
|
|
23
|
-
} from './array/array.util'
|
|
24
|
-
import { _defineLazyProperty, _defineLazyProps, _lazyValue } from './lazy'
|
|
25
|
-
import { _parseQueryString } from './string/url.util'
|
|
26
|
-
import { _range } from './array/range'
|
|
1
|
+
export * from './array/array.util'
|
|
2
|
+
export * from './lazy'
|
|
3
|
+
export * from './string/url.util'
|
|
4
|
+
export * from './array/range'
|
|
27
5
|
import {
|
|
28
6
|
PromiseDecoratorCfg,
|
|
29
7
|
PromiseDecoratorResp,
|
|
@@ -89,82 +67,29 @@ import {
|
|
|
89
67
|
JsonSchemaAnyBuilder,
|
|
90
68
|
JsonSchemaBuilder,
|
|
91
69
|
} from './json-schema/jsonSchemaBuilder'
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
_round,
|
|
101
|
-
_sortNumbers,
|
|
102
|
-
_toFixed,
|
|
103
|
-
_toPrecision,
|
|
104
|
-
} from './number/number.util'
|
|
105
|
-
import { _deepEquals } from './object/deepEquals'
|
|
106
|
-
import {
|
|
107
|
-
_deepCopy,
|
|
108
|
-
_deepTrim,
|
|
109
|
-
_filterEmptyArrays,
|
|
110
|
-
_filterEmptyValues,
|
|
111
|
-
_filterFalsyValues,
|
|
112
|
-
_filterNullishValues,
|
|
113
|
-
_filterObject,
|
|
114
|
-
_filterUndefinedValues,
|
|
115
|
-
_findKeyByValue,
|
|
116
|
-
_get,
|
|
117
|
-
_has,
|
|
118
|
-
_invert,
|
|
119
|
-
_invertMap,
|
|
120
|
-
_isEmpty,
|
|
121
|
-
_isEmptyObject,
|
|
122
|
-
_isObject,
|
|
123
|
-
_isPrimitive,
|
|
124
|
-
_mapKeys,
|
|
125
|
-
_mapObject,
|
|
126
|
-
_mapValues,
|
|
127
|
-
_mask,
|
|
128
|
-
_merge,
|
|
129
|
-
_objectNullValuesToUndefined,
|
|
130
|
-
_omit,
|
|
131
|
-
_pick,
|
|
132
|
-
_set,
|
|
133
|
-
_undefinedIfEmpty,
|
|
134
|
-
_unset,
|
|
135
|
-
} from './object/object.util'
|
|
136
|
-
import { _sortObject } from './object/sortObject'
|
|
137
|
-
import { _sortObjectDeep } from './object/sortObjectDeep'
|
|
70
|
+
export * from './math/math.util'
|
|
71
|
+
export * from './math/sma'
|
|
72
|
+
export * from './number/createDeterministicRandom'
|
|
73
|
+
export * from './number/number.util'
|
|
74
|
+
export * from './object/deepEquals'
|
|
75
|
+
export * from './object/object.util'
|
|
76
|
+
export * from './object/sortObject'
|
|
77
|
+
export * from './object/sortObjectDeep'
|
|
138
78
|
import { AggregatedError } from './promise/AggregatedError'
|
|
139
|
-
|
|
79
|
+
export * from './promise/pBatch'
|
|
140
80
|
import { DeferredPromise, pDefer } from './promise/pDefer'
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
81
|
+
export * from './promise/pDelay'
|
|
82
|
+
export * from './promise/pFilter'
|
|
83
|
+
export * from './promise/pHang'
|
|
144
84
|
import { pMap, PMapOptions } from './promise/pMap'
|
|
145
|
-
|
|
85
|
+
export * from './promise/pProps'
|
|
146
86
|
import { pRetry, PRetryOptions } from './promise/pRetry'
|
|
147
|
-
|
|
87
|
+
export * from './promise/pState'
|
|
148
88
|
import { pTimeout, PTimeoutOptions } from './promise/pTimeout'
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
_capitalize,
|
|
154
|
-
_lowerFirst,
|
|
155
|
-
_nl2br,
|
|
156
|
-
_removeWhitespace,
|
|
157
|
-
_replaceAll,
|
|
158
|
-
_split,
|
|
159
|
-
_substringAfter,
|
|
160
|
-
_substringAfterLast,
|
|
161
|
-
_substringBefore,
|
|
162
|
-
_substringBeforeLast,
|
|
163
|
-
_substringBetweenLast,
|
|
164
|
-
_truncate,
|
|
165
|
-
_truncateMiddle,
|
|
166
|
-
_upperFirst,
|
|
167
|
-
} from './string/string.util'
|
|
89
|
+
export * from './promise/pTuple'
|
|
90
|
+
export * from './string/case'
|
|
91
|
+
export * from './string/json.util'
|
|
92
|
+
export * from './string/string.util'
|
|
168
93
|
import { JsonStringifyFunction, StringifyAnyOptions, _stringifyAny } from './string/stringifyAny'
|
|
169
94
|
import { _ms, _since } from './time/time.util'
|
|
170
95
|
import {
|
|
@@ -173,7 +98,6 @@ import {
|
|
|
173
98
|
ConditionalPick,
|
|
174
99
|
Merge,
|
|
175
100
|
Promisable,
|
|
176
|
-
PromiseValue,
|
|
177
101
|
ReadonlyDeep,
|
|
178
102
|
Simplify,
|
|
179
103
|
} from './typeFest'
|
|
@@ -205,6 +129,12 @@ import {
|
|
|
205
129
|
UnixTimestamp,
|
|
206
130
|
ValueOf,
|
|
207
131
|
ValuesOf,
|
|
132
|
+
AbortableMapper,
|
|
133
|
+
AbortableAsyncPredicate,
|
|
134
|
+
AbortableAsyncMapper,
|
|
135
|
+
AbortablePredicate,
|
|
136
|
+
END,
|
|
137
|
+
SKIP,
|
|
208
138
|
_noop,
|
|
209
139
|
_objectKeys,
|
|
210
140
|
_passNothingPredicate,
|
|
@@ -230,8 +160,14 @@ import {
|
|
|
230
160
|
} from './log/commonLogger'
|
|
231
161
|
import { _safeJsonStringify } from './string/safeJsonStringify'
|
|
232
162
|
import { PQueue, PQueueCfg } from './promise/pQueue'
|
|
163
|
+
export * from './seq/seq'
|
|
164
|
+
export * from './math/stack.util'
|
|
233
165
|
|
|
234
166
|
export type {
|
|
167
|
+
AbortableMapper,
|
|
168
|
+
AbortablePredicate,
|
|
169
|
+
AbortableAsyncPredicate,
|
|
170
|
+
AbortableAsyncMapper,
|
|
235
171
|
PQueueCfg,
|
|
236
172
|
MemoCache,
|
|
237
173
|
PromiseDecoratorCfg,
|
|
@@ -270,7 +206,6 @@ export type {
|
|
|
270
206
|
Merge,
|
|
271
207
|
ReadonlyDeep,
|
|
272
208
|
Promisable,
|
|
273
|
-
PromiseValue,
|
|
274
209
|
Simplify,
|
|
275
210
|
ConditionalPick,
|
|
276
211
|
ConditionalExcept,
|
|
@@ -325,86 +260,9 @@ export {
|
|
|
325
260
|
_assertIsString,
|
|
326
261
|
_assertIsNumber,
|
|
327
262
|
_assertTypeOf,
|
|
328
|
-
_randomInt,
|
|
329
|
-
_randomArrayItem,
|
|
330
|
-
_createDeterministicRandom,
|
|
331
|
-
_inRange,
|
|
332
263
|
_stringMapValues,
|
|
333
264
|
_stringMapEntries,
|
|
334
265
|
_objectKeys,
|
|
335
|
-
_capitalize,
|
|
336
|
-
_upperFirst,
|
|
337
|
-
_lowerFirst,
|
|
338
|
-
_split,
|
|
339
|
-
_removeWhitespace,
|
|
340
|
-
_substringBefore,
|
|
341
|
-
_substringBeforeLast,
|
|
342
|
-
_substringAfter,
|
|
343
|
-
_substringAfterLast,
|
|
344
|
-
_substringBetweenLast,
|
|
345
|
-
_replaceAll,
|
|
346
|
-
_nl2br,
|
|
347
|
-
_truncate,
|
|
348
|
-
_truncateMiddle,
|
|
349
|
-
_pick,
|
|
350
|
-
_omit,
|
|
351
|
-
_filterFalsyValues,
|
|
352
|
-
_filterUndefinedValues,
|
|
353
|
-
_filterNullishValues,
|
|
354
|
-
_filterEmptyArrays,
|
|
355
|
-
_filterEmptyValues,
|
|
356
|
-
_filterObject,
|
|
357
|
-
_undefinedIfEmpty,
|
|
358
|
-
_isObject,
|
|
359
|
-
_isPrimitive,
|
|
360
|
-
_mapKeys,
|
|
361
|
-
_mapValues,
|
|
362
|
-
_mapObject,
|
|
363
|
-
_objectNullValuesToUndefined,
|
|
364
|
-
_deepEquals,
|
|
365
|
-
_deepCopy,
|
|
366
|
-
_isEmptyObject,
|
|
367
|
-
_isEmpty,
|
|
368
|
-
_merge,
|
|
369
|
-
_deepTrim,
|
|
370
|
-
_sortObjectDeep,
|
|
371
|
-
_sortObject,
|
|
372
|
-
_get,
|
|
373
|
-
_set,
|
|
374
|
-
_has,
|
|
375
|
-
_unset,
|
|
376
|
-
_mask,
|
|
377
|
-
_invert,
|
|
378
|
-
_invertMap,
|
|
379
|
-
_by,
|
|
380
|
-
_groupBy,
|
|
381
|
-
_sortBy,
|
|
382
|
-
_sortNumbers,
|
|
383
|
-
_toFixed,
|
|
384
|
-
_toPrecision,
|
|
385
|
-
_round,
|
|
386
|
-
_findLast,
|
|
387
|
-
_takeWhile,
|
|
388
|
-
_takeRightWhile,
|
|
389
|
-
_dropWhile,
|
|
390
|
-
_dropRightWhile,
|
|
391
|
-
_countBy,
|
|
392
|
-
_intersection,
|
|
393
|
-
_difference,
|
|
394
|
-
_shuffle,
|
|
395
|
-
_mapToObject,
|
|
396
|
-
_findKeyByValue,
|
|
397
|
-
_range,
|
|
398
|
-
_uniq,
|
|
399
|
-
_uniqBy,
|
|
400
|
-
_flatten,
|
|
401
|
-
_flattenDeep,
|
|
402
|
-
_chunk,
|
|
403
|
-
SimpleMovingAverage,
|
|
404
|
-
_average,
|
|
405
|
-
_averageWeighted,
|
|
406
|
-
_percentile,
|
|
407
|
-
_median,
|
|
408
266
|
_debounce,
|
|
409
267
|
_throttle,
|
|
410
268
|
_Debounce,
|
|
@@ -415,25 +273,17 @@ export {
|
|
|
415
273
|
_passthroughPredicate,
|
|
416
274
|
_passNothingPredicate,
|
|
417
275
|
_noop,
|
|
418
|
-
pBatch,
|
|
419
276
|
ErrorMode,
|
|
420
|
-
pFilter,
|
|
421
|
-
pProps,
|
|
422
|
-
pDelay,
|
|
423
277
|
pDefer,
|
|
424
|
-
pHang,
|
|
425
|
-
pState,
|
|
426
278
|
AggregatedError,
|
|
427
279
|
pRetry,
|
|
428
280
|
pTimeout,
|
|
429
|
-
pTuple,
|
|
430
281
|
_Retry,
|
|
431
282
|
_Timeout,
|
|
432
283
|
_tryCatch,
|
|
433
284
|
_TryCatch,
|
|
434
285
|
_try,
|
|
435
286
|
pTry,
|
|
436
|
-
_jsonParseIfPossible,
|
|
437
287
|
_stringifyAny,
|
|
438
288
|
_ms,
|
|
439
289
|
_since,
|
|
@@ -441,22 +291,11 @@ export {
|
|
|
441
291
|
_gb,
|
|
442
292
|
_mb,
|
|
443
293
|
_kb,
|
|
444
|
-
_snakeCase,
|
|
445
|
-
_camelCase,
|
|
446
|
-
_kebabCase,
|
|
447
|
-
_sum,
|
|
448
|
-
_sumBy,
|
|
449
|
-
_clamp,
|
|
450
|
-
_last,
|
|
451
294
|
mergeJsonSchemaObjects,
|
|
452
295
|
jsonSchema,
|
|
453
296
|
JsonSchemaAnyBuilder,
|
|
454
297
|
JSON_SCHEMA_ORDER,
|
|
455
298
|
generateJsonSchemaFromData,
|
|
456
|
-
_parseQueryString,
|
|
457
|
-
_defineLazyProperty,
|
|
458
|
-
_defineLazyProps,
|
|
459
|
-
_lazyValue,
|
|
460
299
|
commonLoggerMinLevel,
|
|
461
300
|
commonLoggerNoop,
|
|
462
301
|
commonLogLevelNumber,
|
|
@@ -465,4 +304,6 @@ export {
|
|
|
465
304
|
commonLoggerCreate,
|
|
466
305
|
_safeJsonStringify,
|
|
467
306
|
PQueue,
|
|
307
|
+
END,
|
|
308
|
+
SKIP,
|
|
468
309
|
}
|
package/src/math/math.util.ts
CHANGED
|
@@ -47,6 +47,27 @@ export function _percentile(values: number[], pc: number): number {
|
|
|
47
47
|
return _averageWeighted([sorted[floorPos]!, sorted[ceilPos]!], [1 - dec, dec])
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
/**
|
|
51
|
+
* A tiny bit more efficient function than calling _percentile individually.
|
|
52
|
+
*/
|
|
53
|
+
export function _percentiles(values: number[], pcs: number[]): Record<number, number> {
|
|
54
|
+
const r = {} as Record<number, number>
|
|
55
|
+
|
|
56
|
+
const sorted = _sortNumbers(values)
|
|
57
|
+
|
|
58
|
+
pcs.forEach(pc => {
|
|
59
|
+
// Floating pos in the range of [0; length - 1]
|
|
60
|
+
const pos = ((values.length - 1) * pc) / 100
|
|
61
|
+
const dec = pos % 1
|
|
62
|
+
const floorPos = Math.floor(pos)
|
|
63
|
+
const ceilPos = Math.ceil(pos)
|
|
64
|
+
|
|
65
|
+
r[pc] = _averageWeighted([sorted[floorPos]!, sorted[ceilPos]!], [1 - dec, dec])
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
return r
|
|
69
|
+
}
|
|
70
|
+
|
|
50
71
|
/**
|
|
51
72
|
* @example
|
|
52
73
|
*
|
package/src/math/sma.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Implements a Simple Moving Average algorithm.
|
|
3
3
|
*/
|
|
4
4
|
export class SimpleMovingAverage {
|
|
5
|
-
constructor(public size: number, public data: number[] = []) {}
|
|
5
|
+
constructor(public readonly size: number, public readonly data: number[] = []) {}
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Next index of array to push to
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { _average, _percentile, _percentiles, _range } from '../index'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Implements a "round-robin" Stack ("first-in last-out" aka FILO) with a limited size.
|
|
5
|
+
* Like an array of a fixed size. When it runs out of space - it starts writing on top of itself
|
|
6
|
+
* from index 0.
|
|
7
|
+
*
|
|
8
|
+
*
|
|
9
|
+
*/
|
|
10
|
+
export class Stack<T> {
|
|
11
|
+
constructor(public readonly size: number) {}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Index of a slot to get written TO next.
|
|
15
|
+
* Currently this slot contains OLDEST item (if any).
|
|
16
|
+
*/
|
|
17
|
+
private nextIndex = 0
|
|
18
|
+
|
|
19
|
+
readonly items: T[] = []
|
|
20
|
+
|
|
21
|
+
push(item: T): this {
|
|
22
|
+
this.items[this.nextIndex] = item
|
|
23
|
+
this.nextIndex = this.nextIndex === this.size - 1 ? 0 : this.nextIndex + 1
|
|
24
|
+
return this
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Fill (overwrite) the whole Stack (all its items) with the passed `item`.
|
|
29
|
+
*/
|
|
30
|
+
fill(item: T): this {
|
|
31
|
+
_range(this.size).forEach(i => (this.items[i] = item))
|
|
32
|
+
return this
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Returns last items in the right order.
|
|
37
|
+
* Unlike raw `items` property that returns "items buffer" as-is (not ordered properly).
|
|
38
|
+
*/
|
|
39
|
+
get itemsOrdered(): T[] {
|
|
40
|
+
if (this.items.length < this.size) {
|
|
41
|
+
// Buffer is not filled yet, just return it as-is
|
|
42
|
+
return this.items
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Buffer was filled and started to "overwrite itself", will need to return 2 slices
|
|
46
|
+
return [...this.items.slice(this.nextIndex), ...this.items.slice(0, this.nextIndex)]
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Fixed-size FILO stack of Numbers.
|
|
52
|
+
* Has convenience stat methods, e.g percentile, avg, etc.
|
|
53
|
+
*/
|
|
54
|
+
export class NumberStack extends Stack<number> {
|
|
55
|
+
avg(): number {
|
|
56
|
+
// _assert(this.items.length, 'NumberStack.avg cannot be called on empty stack')
|
|
57
|
+
return _average(this.items)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Returns null if Stack is empty.
|
|
62
|
+
*/
|
|
63
|
+
avgOrNull(): number | null {
|
|
64
|
+
return this.items.length === 0 ? null : _average(this.items)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
median(): number {
|
|
68
|
+
return _percentile(this.items, 50)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
medianOrNull(): number | null {
|
|
72
|
+
return this.items.length === 0 ? null : _percentile(this.items, 50)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* `pc` is a number from 0 to 100 inclusive.
|
|
77
|
+
*/
|
|
78
|
+
percentile(pc: number): number {
|
|
79
|
+
// _assert(this.items.length, 'NumberStack.percentile cannot be called on empty stack')
|
|
80
|
+
return _percentile(this.items, pc)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* `pc` is a number from 0 to 100 inclusive.
|
|
85
|
+
* Returns null if Stack is empty.
|
|
86
|
+
*/
|
|
87
|
+
percentileOrNull(pc: number): number | null {
|
|
88
|
+
return this.items.length === 0 ? null : _percentile(this.items, pc)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
percentiles(pcs: number[]): Record<number, number> {
|
|
92
|
+
return _percentiles(this.items, pcs)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -65,7 +65,7 @@ export function _toFixed(n: number, fractionDigits: number): number {
|
|
|
65
65
|
* _toPrecision(1634.56, 1)
|
|
66
66
|
* // 2000
|
|
67
67
|
*
|
|
68
|
-
* _toPrecision(
|
|
68
|
+
* _toPrecision(1634.56, 2)
|
|
69
69
|
* // 1600
|
|
70
70
|
*/
|
|
71
71
|
export function _toPrecision(n: number, precision: number): number {
|
package/src/promise/pBatch.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { BatchResult, ErrorMode } from '..'
|
|
2
|
-
import { AsyncMapper } from '../types'
|
|
1
|
+
import { AbortableAsyncMapper, BatchResult, ErrorMode } from '..'
|
|
3
2
|
import { AggregatedError } from './AggregatedError'
|
|
4
3
|
import { pMap } from './pMap'
|
|
5
4
|
|
|
@@ -8,7 +7,7 @@ import { pMap } from './pMap'
|
|
|
8
7
|
*/
|
|
9
8
|
export async function pBatch<IN, OUT>(
|
|
10
9
|
iterable: Iterable<IN | PromiseLike<IN>>,
|
|
11
|
-
mapper:
|
|
10
|
+
mapper: AbortableAsyncMapper<IN, OUT>,
|
|
12
11
|
opt?: { concurrency?: number },
|
|
13
12
|
): Promise<BatchResult<OUT>> {
|
|
14
13
|
try {
|
package/src/promise/pFilter.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AbortableAsyncPredicate } from '../types'
|
|
2
2
|
import { pMap, PMapOptions } from './pMap'
|
|
3
3
|
|
|
4
4
|
export async function pFilter<T>(
|
|
5
5
|
iterable: Iterable<T | PromiseLike<T>>,
|
|
6
|
-
filterFn:
|
|
6
|
+
filterFn: AbortableAsyncPredicate<T>,
|
|
7
7
|
opt?: PMapOptions,
|
|
8
8
|
): Promise<T[]> {
|
|
9
9
|
const values = await pMap(
|