@naturalcycles/js-lib 14.70.0 → 14.72.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/error.util.js +2 -0
- 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/sma.d.ts +2 -2
- package/dist/math/stack.util.d.ts +21 -0
- package/dist/math/stack.util.js +36 -0
- 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/string/json.util.js +4 -1
- package/dist/typeFest.d.ts +0 -30
- package/dist/types.d.ts +13 -1
- package/dist/types.js +9 -1
- package/dist-esm/error/error.util.js +2 -0
- package/dist-esm/error/try.js +2 -0
- package/dist-esm/index.js +26 -24
- package/dist-esm/math/stack.util.js +32 -0
- 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/string/json.util.js +4 -1
- package/dist-esm/types.js +8 -0
- package/package.json +1 -1
- package/src/error/error.util.ts +2 -0
- package/src/error/try.ts +4 -1
- package/src/index.ts +36 -195
- package/src/math/sma.ts +1 -1
- package/src/math/stack.util.ts +35 -0
- 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/string/json.util.ts +5 -1
- package/src/typeFest.ts +0 -32
- package/src/types.ts +22 -1
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/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,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Implements a "round-robin" Stack with a limited size.
|
|
3
|
+
* Like an array of a fixed size. When it runs out of space - it starts writing on top of itself
|
|
4
|
+
* from index 0.
|
|
5
|
+
*/
|
|
6
|
+
export class SizeLimitedStack<T> {
|
|
7
|
+
constructor(public readonly size: number) {}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Index of a slot to get written TO next.
|
|
11
|
+
* Currently this slot contains OLDEST item (if any).
|
|
12
|
+
*/
|
|
13
|
+
private nextIndex = 0
|
|
14
|
+
|
|
15
|
+
readonly items: T[] = []
|
|
16
|
+
|
|
17
|
+
push(item: T): void {
|
|
18
|
+
this.items[this.nextIndex] = item
|
|
19
|
+
this.nextIndex = this.nextIndex === this.size - 1 ? 0 : this.nextIndex + 1
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Returns last items in the right order.
|
|
24
|
+
* Unlike raw `items` property that returns "items buffer" as-is (not ordered properly).
|
|
25
|
+
*/
|
|
26
|
+
get itemsOrdered(): T[] {
|
|
27
|
+
if (this.items.length < this.size) {
|
|
28
|
+
// Buffer is not filled yet, just return it as-is
|
|
29
|
+
return this.items
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Buffer was filled and started to "overwrite itself", will need to return 2 slices
|
|
33
|
+
return [...this.items.slice(this.nextIndex), ...this.items.slice(0, this.nextIndex)]
|
|
34
|
+
}
|
|
35
|
+
}
|
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(
|
package/src/promise/pMap.ts
CHANGED
|
@@ -7,8 +7,7 @@ Improvements:
|
|
|
7
7
|
- Compatible with pProps (that had typings issues)
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { ErrorMode } from '..'
|
|
11
|
-
import { AsyncMapper } from '../types'
|
|
10
|
+
import { AbortableAsyncMapper, END, ErrorMode, SKIP } from '..'
|
|
12
11
|
import { AggregatedError } from './AggregatedError'
|
|
13
12
|
|
|
14
13
|
export interface PMapOptions {
|
|
@@ -57,37 +56,38 @@ export interface PMapOptions {
|
|
|
57
56
|
*/
|
|
58
57
|
export async function pMap<IN, OUT>(
|
|
59
58
|
iterable: Iterable<IN | PromiseLike<IN>>,
|
|
60
|
-
mapper:
|
|
59
|
+
mapper: AbortableAsyncMapper<IN, OUT>,
|
|
61
60
|
opt: PMapOptions = {},
|
|
62
61
|
): Promise<OUT[]> {
|
|
63
62
|
return new Promise<OUT[]>((resolve, reject) => {
|
|
64
63
|
const { concurrency = Number.POSITIVE_INFINITY, errorMode = ErrorMode.THROW_IMMEDIATELY } = opt
|
|
65
64
|
|
|
66
|
-
const ret: OUT[] = []
|
|
65
|
+
const ret: (OUT | typeof SKIP)[] = []
|
|
67
66
|
const iterator = iterable[Symbol.iterator]()
|
|
68
67
|
const errors: Error[] = []
|
|
69
|
-
let
|
|
68
|
+
let isSettled = false
|
|
70
69
|
let isIterableDone = false
|
|
71
70
|
let resolvingCount = 0
|
|
72
71
|
let currentIndex = 0
|
|
73
72
|
|
|
74
|
-
const next = () => {
|
|
75
|
-
if (
|
|
73
|
+
const next = (skipped = false) => {
|
|
74
|
+
if (isSettled) {
|
|
76
75
|
return
|
|
77
76
|
}
|
|
78
77
|
|
|
79
78
|
const nextItem = iterator.next()
|
|
80
79
|
const i = currentIndex
|
|
81
|
-
currentIndex++
|
|
80
|
+
if (!skipped) currentIndex++
|
|
82
81
|
|
|
83
82
|
if (nextItem.done) {
|
|
84
83
|
isIterableDone = true
|
|
85
84
|
|
|
86
85
|
if (resolvingCount === 0) {
|
|
86
|
+
const r = ret.filter(r => r !== SKIP) as OUT[]
|
|
87
87
|
if (errors.length && errorMode === ErrorMode.THROW_AGGREGATED) {
|
|
88
|
-
reject(new AggregatedError(errors,
|
|
88
|
+
reject(new AggregatedError(errors, r))
|
|
89
89
|
} else {
|
|
90
|
-
resolve(
|
|
90
|
+
resolve(r)
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
|
|
@@ -100,13 +100,18 @@ export async function pMap<IN, OUT>(
|
|
|
100
100
|
.then(async element => await mapper(element, i))
|
|
101
101
|
.then(
|
|
102
102
|
value => {
|
|
103
|
+
if (value === END) {
|
|
104
|
+
isSettled = true
|
|
105
|
+
return resolve(ret.filter(r => r !== SKIP) as OUT[])
|
|
106
|
+
}
|
|
107
|
+
|
|
103
108
|
ret[i] = value
|
|
104
109
|
resolvingCount--
|
|
105
110
|
next()
|
|
106
111
|
},
|
|
107
112
|
err => {
|
|
108
113
|
if (errorMode === ErrorMode.THROW_IMMEDIATELY) {
|
|
109
|
-
|
|
114
|
+
isSettled = true
|
|
110
115
|
reject(err)
|
|
111
116
|
} else {
|
|
112
117
|
errors.push(err)
|
package/src/promise/pProps.ts
CHANGED
|
@@ -10,6 +10,9 @@ Improvements:
|
|
|
10
10
|
|
|
11
11
|
import { pMap, PMapOptions } from './pMap'
|
|
12
12
|
|
|
13
|
+
// todo: remove when eslint starts to know about Awaited
|
|
14
|
+
/* eslint-disable no-undef */
|
|
15
|
+
|
|
13
16
|
/**
|
|
14
17
|
* Promise.all for Object instead of Array.
|
|
15
18
|
* Supports concurrency.
|
|
@@ -17,13 +20,9 @@ import { pMap, PMapOptions } from './pMap'
|
|
|
17
20
|
export async function pProps<T>(
|
|
18
21
|
input: { [K in keyof T]: T[K] | Promise<T[K]> },
|
|
19
22
|
opt?: PMapOptions,
|
|
20
|
-
): Promise<T> {
|
|
23
|
+
): Promise<{ [K in keyof T]: Awaited<T[K]> }> {
|
|
24
|
+
const r = {} as { [K in keyof T]: Awaited<T[K]> }
|
|
21
25
|
const keys = Object.keys(input) as (keyof T)[]
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const r = {} as T
|
|
25
|
-
values.forEach((v, i) => {
|
|
26
|
-
r[keys[i]!] = v
|
|
27
|
-
})
|
|
26
|
+
await pMap(Object.values(input), (v, i) => (r[keys[i]!] = v), opt)
|
|
28
27
|
return r
|
|
29
28
|
}
|
package/src/seq/seq.ts
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { AbortableMapper, AbortablePredicate, END, SKIP } from '../types'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Inspired by Kotlin Sequences.
|
|
5
|
+
* Similar to arrays, but with lazy evaluation, abortable.
|
|
6
|
+
* Can be useful when it's not feasible/performant to create an array of values to iterate upfront
|
|
7
|
+
* (e.g to construct 1000 Dayjs instances only to find that 2 of them were needed).
|
|
8
|
+
*
|
|
9
|
+
* @experimental
|
|
10
|
+
*/
|
|
11
|
+
export class Seq<T> implements Iterable<T> {
|
|
12
|
+
private constructor(initialValue: T | typeof END, private nextFn: AbortableMapper<T, T>) {
|
|
13
|
+
this.currentValue = initialValue
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
[Symbol.iterator](): Iterator<T> {
|
|
17
|
+
return {
|
|
18
|
+
next: () => {
|
|
19
|
+
const value = this.next()
|
|
20
|
+
return value === END ? { done: true, value: undefined } : { value }
|
|
21
|
+
},
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
static create<T>(initialValue: T | typeof END, nextFn: AbortableMapper<T, T>): Seq<T> {
|
|
26
|
+
return new Seq(initialValue, nextFn)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
static range(minIncl: number, maxExcl: number, step = 1): Seq<number> {
|
|
30
|
+
const max = maxExcl - step
|
|
31
|
+
return new Seq(minIncl, n => (n < max ? n + step : END))
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
static from<T>(a: Iterable<T>): Seq<T> {
|
|
35
|
+
const it = a[Symbol.iterator]()
|
|
36
|
+
const v = it.next()
|
|
37
|
+
if (v.done) return new Seq<any>(END, () => {})
|
|
38
|
+
|
|
39
|
+
return new Seq(v.value, () => {
|
|
40
|
+
const v = it.next()
|
|
41
|
+
if (v.done) return END
|
|
42
|
+
return v.value
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
static empty<T = any>(): Seq<T> {
|
|
47
|
+
return new Seq(END as any, () => {})
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
private currentValue: T | typeof END
|
|
51
|
+
private sentInitialValue = false
|
|
52
|
+
private i = -1
|
|
53
|
+
|
|
54
|
+
next(): T | typeof END {
|
|
55
|
+
if (this.currentValue === END) return END
|
|
56
|
+
|
|
57
|
+
this.i++
|
|
58
|
+
|
|
59
|
+
let v: T | typeof SKIP | typeof END
|
|
60
|
+
|
|
61
|
+
if (!this.sentInitialValue) {
|
|
62
|
+
this.sentInitialValue = true
|
|
63
|
+
v = this.currentValue
|
|
64
|
+
} else {
|
|
65
|
+
v = this.nextFn(this.currentValue, this.i)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// console.log(`_seq`, v)
|
|
69
|
+
|
|
70
|
+
if (v === SKIP) return this.next()
|
|
71
|
+
|
|
72
|
+
return (this.currentValue = v)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Chainable functions - return another (chained) Sequence
|
|
76
|
+
// map<OUT>(mapper: Mapper<T, OUT | typeof SKIP | typeof END>): Seq<OUT> {
|
|
77
|
+
// if (this.currentValue === END) return this as any
|
|
78
|
+
//
|
|
79
|
+
// // Iterate until first valid value, to have as `initialValue` of the new Sequence
|
|
80
|
+
// let v: OUT | typeof SKIP | typeof END
|
|
81
|
+
//
|
|
82
|
+
// while (true) {
|
|
83
|
+
// v = mapper(this.currentValue, ++this.i)
|
|
84
|
+
// if (v === SKIP) continue
|
|
85
|
+
// if (v === END) return this as any
|
|
86
|
+
// }
|
|
87
|
+
//
|
|
88
|
+
// return new Seq<OUT>(v as OUT, (current, i) => {
|
|
89
|
+
// const v = mapper(current, i)
|
|
90
|
+
//
|
|
91
|
+
// })
|
|
92
|
+
// }
|
|
93
|
+
|
|
94
|
+
// Final functions - return final value, not a chained sequence
|
|
95
|
+
find(predicate: AbortablePredicate<T>): T | undefined {
|
|
96
|
+
do {
|
|
97
|
+
const v = this.next()
|
|
98
|
+
if (v === END) return // not found, end of sequence
|
|
99
|
+
const r = predicate(v, this.i)
|
|
100
|
+
if (r === END) return
|
|
101
|
+
if (r) return v
|
|
102
|
+
// otherwise proceed
|
|
103
|
+
} while (true) // eslint-disable-line no-constant-condition
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
some(predicate: AbortablePredicate<T>): boolean {
|
|
107
|
+
do {
|
|
108
|
+
const v = this.next()
|
|
109
|
+
if (v === END) return false
|
|
110
|
+
const r = predicate(v, this.i)
|
|
111
|
+
if (r === END) return false
|
|
112
|
+
if (r) return true
|
|
113
|
+
} while (true) // eslint-disable-line no-constant-condition
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
every(predicate: AbortablePredicate<T>): boolean {
|
|
117
|
+
do {
|
|
118
|
+
const v = this.next()
|
|
119
|
+
if (v === END) return true
|
|
120
|
+
const r = predicate(v, this.i)
|
|
121
|
+
if (r === END) return true
|
|
122
|
+
if (!r) return false
|
|
123
|
+
} while (true) // eslint-disable-line no-constant-condition
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
toArray(): T[] {
|
|
127
|
+
const a: T[] = []
|
|
128
|
+
|
|
129
|
+
// eslint-disable-next-line no-constant-condition
|
|
130
|
+
while (true) {
|
|
131
|
+
const v = this.next()
|
|
132
|
+
if (v === END) return a
|
|
133
|
+
a.push(v)
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Convenience function to create a Sequence.
|
|
140
|
+
*/
|
|
141
|
+
export function _seq<T>(initialValue: T | typeof END, nextFn: AbortableMapper<T, T>): Seq<T> {
|
|
142
|
+
return Seq.create(initialValue, nextFn)
|
|
143
|
+
}
|
package/src/string/json.util.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// const possibleJsonStartTokens = ['{', '[', '"']
|
|
2
|
+
const DETECT_JSON = /^\s*[{["\-\d]/
|
|
3
|
+
|
|
1
4
|
/**
|
|
2
5
|
* Attempts to parse object as JSON.
|
|
3
6
|
* Returns original object if JSON parse failed (silently).
|
|
@@ -6,7 +9,8 @@ export function _jsonParseIfPossible(
|
|
|
6
9
|
obj: any,
|
|
7
10
|
reviver?: (this: any, key: string, value: any) => any,
|
|
8
11
|
): any {
|
|
9
|
-
if
|
|
12
|
+
// Optimization: only try to parse if it looks like JSON: starts with a json possible character
|
|
13
|
+
if (typeof obj === 'string' && obj && DETECT_JSON.test(obj)) {
|
|
10
14
|
try {
|
|
11
15
|
return JSON.parse(obj, reviver)
|
|
12
16
|
} catch {}
|
package/src/typeFest.ts
CHANGED
|
@@ -151,38 +151,6 @@ export type Merge<FirstType, SecondType> = Simplify<Merge_<FirstType, SecondType
|
|
|
151
151
|
*/
|
|
152
152
|
export type Promisable<T> = T | PromiseLike<T>
|
|
153
153
|
|
|
154
|
-
/**
|
|
155
|
-
Returns the type that is wrapped inside a `Promise` type.
|
|
156
|
-
If the type is a nested Promise, it is unwrapped recursively until a non-Promise type is obtained.
|
|
157
|
-
If the type is not a `Promise`, the type itself is returned.
|
|
158
|
-
|
|
159
|
-
@example
|
|
160
|
-
```
|
|
161
|
-
import {PromiseValue} from 'type-fest';
|
|
162
|
-
|
|
163
|
-
type AsyncData = Promise<string>;
|
|
164
|
-
let asyncData: PromiseValue<AsyncData> = Promise.resolve('ABC');
|
|
165
|
-
|
|
166
|
-
type Data = PromiseValue<AsyncData>;
|
|
167
|
-
let data: Data = await asyncData;
|
|
168
|
-
|
|
169
|
-
// Here's an example that shows how this type reacts to non-Promise types.
|
|
170
|
-
type SyncData = PromiseValue<string>;
|
|
171
|
-
let syncData: SyncData = getSyncData();
|
|
172
|
-
|
|
173
|
-
// Here's an example that shows how this type reacts to recursive Promise types.
|
|
174
|
-
type RecursiveAsyncData = Promise<Promise<string> >;
|
|
175
|
-
let recursiveAsyncData: PromiseValue<RecursiveAsyncData> = Promise.resolve(Promise.resolve('ABC'));
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
@category Utilities
|
|
179
|
-
*/
|
|
180
|
-
export type PromiseValue<PromiseType, Otherwise = PromiseType> = PromiseType extends Promise<
|
|
181
|
-
infer Value
|
|
182
|
-
>
|
|
183
|
-
? { 0: PromiseValue<Value>; 1: Value }[PromiseType extends Promise<unknown> ? 0 : 1]
|
|
184
|
-
: Otherwise
|
|
185
|
-
|
|
186
154
|
/**
|
|
187
155
|
Extract the keys from a type where the value type of the key extends the given `Condition`.
|
|
188
156
|
Internally this is used for the `ConditionalPick` and `ConditionalExcept` types.
|