@tutao/tutanota-utils 3.93.5 → 3.94.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/ArrayUtils.d.ts +44 -39
- package/dist/ArrayUtils.js +220 -229
- package/dist/AsyncResult.d.ts +17 -15
- package/dist/AsyncResult.js +33 -21
- package/dist/CollectionUtils.d.ts +1 -1
- package/dist/CollectionUtils.js +1 -1
- package/dist/DateUtils.d.ts +18 -18
- package/dist/DateUtils.js +40 -38
- package/dist/Encoding.d.ts +25 -25
- package/dist/Encoding.js +175 -181
- package/dist/LazyLoaded.d.ts +32 -32
- package/dist/LazyLoaded.js +65 -66
- package/dist/MapUtils.d.ts +4 -4
- package/dist/MapUtils.js +24 -25
- package/dist/MathUtils.d.ts +2 -2
- package/dist/MathUtils.js +2 -2
- package/dist/PromiseMap.d.ts +8 -4
- package/dist/PromiseMap.js +49 -50
- package/dist/PromiseUtils.d.ts +19 -16
- package/dist/PromiseUtils.js +72 -76
- package/dist/SortedArray.d.ts +11 -11
- package/dist/SortedArray.js +30 -30
- package/dist/StringUtils.d.ts +14 -14
- package/dist/StringUtils.js +31 -36
- package/dist/TypeRef.d.ts +11 -10
- package/dist/TypeRef.js +15 -12
- package/dist/Utils.d.ts +59 -53
- package/dist/Utils.js +207 -227
- package/dist/index.d.ts +145 -19
- package/dist/index.js +140 -14
- package/dist/tsbuildinfo +1 -1
- package/package.json +2 -2
package/dist/LazyLoaded.js
CHANGED
|
@@ -1,72 +1,71 @@
|
|
|
1
|
-
import { neverNull } from "./Utils.js"
|
|
1
|
+
import { neverNull } from "./Utils.js"
|
|
2
2
|
/**
|
|
3
3
|
* A wrapper for an object that shall be lazy loaded asynchronously. If loading the object is triggered in parallel (getAsync()) the object is actually only loaded once but returned to all calls of getAsync().
|
|
4
4
|
* If the object was loaded once it is not loaded again.
|
|
5
5
|
*/
|
|
6
6
|
export class LazyLoaded {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
7
|
+
/**
|
|
8
|
+
* @param loadFunction The function that actually loads the object as soon as getAsync() is called the first time.
|
|
9
|
+
* @param defaultValue The value that shall be returned by getSync() or getLoaded() as long as the object is not loaded yet.
|
|
10
|
+
*/
|
|
11
|
+
constructor(loadFunction, defaultValue) {
|
|
12
|
+
this._isLoaded = false
|
|
13
|
+
this._loadFunction = loadFunction
|
|
14
|
+
this._loadingPromise = null
|
|
15
|
+
this._loadedObject = defaultValue !== null && defaultValue !== void 0 ? defaultValue : null
|
|
16
|
+
}
|
|
17
|
+
load() {
|
|
18
|
+
this.getAsync()
|
|
19
|
+
return this
|
|
20
|
+
}
|
|
21
|
+
isLoaded() {
|
|
22
|
+
return this._isLoaded
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Loads the object if it is not loaded yet. May be called in parallel and takes care that the load function is only called once.
|
|
26
|
+
*/
|
|
27
|
+
getAsync() {
|
|
28
|
+
if (this.isLoaded()) {
|
|
29
|
+
return Promise.resolve(neverNull(this._loadedObject))
|
|
30
|
+
} else {
|
|
31
|
+
if (!this._loadingPromise) {
|
|
32
|
+
this._loadingPromise = this._loadFunction().then(result => {
|
|
33
|
+
this._loadedObject = result
|
|
34
|
+
this._isLoaded = true
|
|
35
|
+
return result
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
return this._loadingPromise
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Returns null if the object is not loaded yet.
|
|
43
|
+
*/
|
|
44
|
+
getSync() {
|
|
45
|
+
return this._loadedObject
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Only call this function if you know that the object is already loaded.
|
|
49
|
+
*/
|
|
50
|
+
getLoaded() {
|
|
51
|
+
return neverNull(this._loadedObject)
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Removes the currently loaded object, so it will be loaded again with the next getAsync() call. Does not set any default value.
|
|
55
|
+
*/
|
|
56
|
+
reset() {
|
|
57
|
+
this._isLoaded = false
|
|
58
|
+
this._loadingPromise = null
|
|
59
|
+
this._loadedObject = null
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Loads the object again and replaces the current one
|
|
63
|
+
*/
|
|
64
|
+
reload() {
|
|
65
|
+
return this._loadFunction().then(result => {
|
|
66
|
+
this._isLoaded = true
|
|
67
|
+
this._loadedObject = result
|
|
68
|
+
return result
|
|
69
|
+
})
|
|
70
|
+
}
|
|
72
71
|
}
|
package/dist/MapUtils.d.ts
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Merges multiple maps into a single map with lists of values.
|
|
3
3
|
* @param maps
|
|
4
4
|
*/
|
|
5
|
-
export declare function mergeMaps<T>(maps: Map<string, T>[]): Map<string, T[]
|
|
6
|
-
export declare function getFromMap<K, V>(map: Map<K, V>, key: K, byDefault: () => V): V
|
|
5
|
+
export declare function mergeMaps<T>(maps: Map<string, T>[]): Map<string, T[]>
|
|
6
|
+
export declare function getFromMap<K, V>(map: Map<K, V>, key: K, byDefault: () => V): V
|
|
7
7
|
/** Creates a new map with key and value added to {@param map}. It is like set() but for immutable map. */
|
|
8
|
-
export declare function addMapEntry<K, V>(map: ReadonlyMap<K, V>, key: K, value: V): Map<K, V
|
|
9
|
-
export declare function deleteMapEntry<K, V>(map: ReadonlyMap<K, V>, key: K): Map<K, V
|
|
8
|
+
export declare function addMapEntry<K, V>(map: ReadonlyMap<K, V>, key: K, value: V): Map<K, V>
|
|
9
|
+
export declare function deleteMapEntry<K, V>(map: ReadonlyMap<K, V>, key: K): Map<K, V>
|
package/dist/MapUtils.js
CHANGED
|
@@ -1,38 +1,37 @@
|
|
|
1
|
-
import { neverNull } from "./Utils.js"
|
|
1
|
+
import { neverNull } from "./Utils.js"
|
|
2
2
|
/**
|
|
3
3
|
* Merges multiple maps into a single map with lists of values.
|
|
4
4
|
* @param maps
|
|
5
5
|
*/
|
|
6
6
|
export function mergeMaps(maps) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}, new Map());
|
|
7
|
+
return maps.reduce((mergedMap, map) => {
|
|
8
|
+
// merge same key of multiple attributes
|
|
9
|
+
map.forEach((value, key) => {
|
|
10
|
+
if (mergedMap.has(key)) {
|
|
11
|
+
neverNull(mergedMap.get(key)).push(value)
|
|
12
|
+
} else {
|
|
13
|
+
mergedMap.set(key, [value])
|
|
14
|
+
}
|
|
15
|
+
})
|
|
16
|
+
return mergedMap
|
|
17
|
+
}, new Map())
|
|
19
18
|
}
|
|
20
19
|
export function getFromMap(map, key, byDefault) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
let value = map.get(key)
|
|
21
|
+
if (!value) {
|
|
22
|
+
value = byDefault()
|
|
23
|
+
map.set(key, value)
|
|
24
|
+
}
|
|
25
|
+
return value
|
|
27
26
|
}
|
|
28
27
|
/** Creates a new map with key and value added to {@param map}. It is like set() but for immutable map. */
|
|
29
28
|
export function addMapEntry(map, key, value) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
const newMap = new Map(map)
|
|
30
|
+
newMap.set(key, value)
|
|
31
|
+
return newMap
|
|
33
32
|
}
|
|
34
33
|
export function deleteMapEntry(map, key) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
const newMap = new Map(map)
|
|
35
|
+
newMap.delete(key)
|
|
36
|
+
return newMap
|
|
38
37
|
}
|
package/dist/MathUtils.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export declare function mod(n: number, m: number): number
|
|
1
|
+
export declare function mod(n: number, m: number): number
|
|
2
2
|
/**
|
|
3
3
|
* Clamp value to between min and max (inclusive)
|
|
4
4
|
*/
|
|
5
|
-
export declare function clamp(value: number, min: number, max: number): number
|
|
5
|
+
export declare function clamp(value: number, min: number, max: number): number
|
package/dist/MathUtils.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export function mod(n, m) {
|
|
2
|
-
|
|
2
|
+
return ((n % m) + m) % m
|
|
3
3
|
}
|
|
4
4
|
/**
|
|
5
5
|
* Clamp value to between min and max (inclusive)
|
|
6
6
|
*/
|
|
7
7
|
export function clamp(value, min, max) {
|
|
8
|
-
|
|
8
|
+
return Math.max(min, Math.min(value, max))
|
|
9
9
|
}
|
package/dist/PromiseMap.d.ts
CHANGED
|
@@ -5,19 +5,19 @@
|
|
|
5
5
|
* Changed: default concurrency level is 1 and not Infinite
|
|
6
6
|
*/
|
|
7
7
|
export interface Options {
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
9
|
Number of concurrently pending promises returned by `mapper`.
|
|
10
10
|
Must be an integer from 1 and up or `Infinity`.
|
|
11
11
|
@default 1
|
|
12
12
|
*/
|
|
13
|
-
|
|
13
|
+
readonly concurrency?: number
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
16
|
Function which is called for every item in `input`. Expected to return a `Promise` or value.
|
|
17
17
|
@param element - Iterated element.
|
|
18
18
|
@param index - Index of the element in the source array.
|
|
19
19
|
*/
|
|
20
|
-
export declare type Mapper<Element, NewElement> = (element: Element, index: number) => Promise<NewElement> | NewElement
|
|
20
|
+
export declare type Mapper<Element, NewElement> = (element: Element, index: number) => Promise<NewElement> | NewElement
|
|
21
21
|
/**
|
|
22
22
|
@param iterable - Iterated over concurrently in the `mapper` function.
|
|
23
23
|
@param mapper - Function which is called for every item in `input`. Expected to return a `Promise` or value.
|
|
@@ -41,4 +41,8 @@ export declare type Mapper<Element, NewElement> = (element: Element, index: numb
|
|
|
41
41
|
//=> ['https://sindresorhus.com/', 'https://avajs.dev/', 'https://github.com/']
|
|
42
42
|
```
|
|
43
43
|
*/
|
|
44
|
-
export declare function pMap<Element, NewElement>(
|
|
44
|
+
export declare function pMap<Element, NewElement>(
|
|
45
|
+
iterable: Iterable<Element>,
|
|
46
|
+
mapper: Mapper<Element, NewElement>,
|
|
47
|
+
options?: Options,
|
|
48
|
+
): Promise<Array<NewElement>>
|
package/dist/PromiseMap.js
CHANGED
|
@@ -22,54 +22,53 @@
|
|
|
22
22
|
```
|
|
23
23
|
*/
|
|
24
24
|
export async function pMap(iterable, mapper, options = {}) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
});
|
|
25
|
+
const { concurrency = 1 } = options
|
|
26
|
+
return new Promise((resolve, reject) => {
|
|
27
|
+
if (typeof mapper !== "function") {
|
|
28
|
+
throw new TypeError("Mapper function is required")
|
|
29
|
+
}
|
|
30
|
+
if (!((Number.isSafeInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency >= 1)) {
|
|
31
|
+
throw new TypeError(`Expected \`concurrency\` to be an integer from 1 and up or \`Infinity\`, got \`${concurrency}\` (${typeof concurrency})`)
|
|
32
|
+
}
|
|
33
|
+
const result = []
|
|
34
|
+
const errors = []
|
|
35
|
+
const iterator = iterable[Symbol.iterator]()
|
|
36
|
+
let isRejected = false
|
|
37
|
+
let isIterableDone = false
|
|
38
|
+
let resolvingCount = 0
|
|
39
|
+
let currentIndex = 0
|
|
40
|
+
const next = () => {
|
|
41
|
+
if (isRejected) {
|
|
42
|
+
return
|
|
43
|
+
}
|
|
44
|
+
const nextItem = iterator.next()
|
|
45
|
+
const index = currentIndex
|
|
46
|
+
currentIndex++
|
|
47
|
+
if (nextItem.done) {
|
|
48
|
+
isIterableDone = true
|
|
49
|
+
if (resolvingCount === 0) {
|
|
50
|
+
resolve(result)
|
|
51
|
+
}
|
|
52
|
+
return
|
|
53
|
+
}
|
|
54
|
+
resolvingCount++
|
|
55
|
+
;(async () => {
|
|
56
|
+
try {
|
|
57
|
+
const element = await nextItem.value
|
|
58
|
+
result[index] = await mapper(element, index)
|
|
59
|
+
resolvingCount--
|
|
60
|
+
next()
|
|
61
|
+
} catch (error) {
|
|
62
|
+
isRejected = true
|
|
63
|
+
reject(error)
|
|
64
|
+
}
|
|
65
|
+
})()
|
|
66
|
+
}
|
|
67
|
+
for (let index = 0; index < concurrency; index++) {
|
|
68
|
+
next()
|
|
69
|
+
if (isIterableDone) {
|
|
70
|
+
break
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
})
|
|
75
74
|
}
|
package/dist/PromiseUtils.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Options as PromiseMapOptions } from "./PromiseMap.js"
|
|
2
|
-
export declare type $Promisable<T> = Promise<T> | T
|
|
3
|
-
declare type PromiseMapCallback<T, U> = (el: T, index: number) => $Promisable<U
|
|
1
|
+
import type { Options as PromiseMapOptions } from "./PromiseMap.js"
|
|
2
|
+
export declare type $Promisable<T> = Promise<T> | T
|
|
3
|
+
declare type PromiseMapCallback<T, U> = (el: T, index: number) => $Promisable<U>
|
|
4
4
|
/**
|
|
5
5
|
* Map array of values to promise of arrays or array. Mapper function may return promise or value. If value is returned,
|
|
6
6
|
* we avoid promise scheduling.
|
|
@@ -8,24 +8,27 @@ declare type PromiseMapCallback<T, U> = (el: T, index: number) => $Promisable<U>
|
|
|
8
8
|
* This is needed to run the whole operation in one microtask (e.g. keep IndexedDB transaction active, which is closed in
|
|
9
9
|
* some browsers (e.g. Safari) when event loop iteration ends).
|
|
10
10
|
*/
|
|
11
|
-
export declare function mapInCallContext<T, U>(values: T[], callback: PromiseMapCallback<T, U>): PromisableWrapper<Array<U
|
|
12
|
-
export { pMap as promiseMap } from "./PromiseMap.js"
|
|
13
|
-
export declare type PromiseMapFn = <T, U>(values: T[], callback: PromiseMapCallback<T, U>, options?: PromiseMapOptions) => PromisableWrapper<U[]
|
|
11
|
+
export declare function mapInCallContext<T, U>(values: T[], callback: PromiseMapCallback<T, U>): PromisableWrapper<Array<U>>
|
|
12
|
+
export { pMap as promiseMap } from "./PromiseMap.js"
|
|
13
|
+
export declare type PromiseMapFn = <T, U>(values: T[], callback: PromiseMapCallback<T, U>, options?: PromiseMapOptions) => PromisableWrapper<U[]>
|
|
14
14
|
/** Factory function which gives you ack promiseMap implementation. {@see mapInCallContext} for what it means. */
|
|
15
|
-
export declare function promiseMapCompat(useMapInCallContext: boolean): PromiseMapFn
|
|
15
|
+
export declare function promiseMapCompat(useMapInCallContext: boolean): PromiseMapFn
|
|
16
16
|
export declare class PromisableWrapper<T> {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
static from<U>(value: $Promisable<U>): PromisableWrapper<U>
|
|
18
|
+
value: $Promisable<T>
|
|
19
|
+
constructor(value: $Promisable<PromisableWrapper<T> | T>)
|
|
20
|
+
thenOrApply<R>(
|
|
21
|
+
onFulfill: (arg0: T) => $Promisable<PromisableWrapper<R> | R>,
|
|
22
|
+
onReject?: (arg0: any) => $Promisable<R | PromisableWrapper<R>>,
|
|
23
|
+
): PromisableWrapper<R>
|
|
24
|
+
toPromise(): Promise<T>
|
|
22
25
|
}
|
|
23
|
-
export declare function delay(ms: number): Promise<void
|
|
26
|
+
export declare function delay(ms: number): Promise<void>
|
|
24
27
|
/**
|
|
25
28
|
* Pass to Promise.then to perform an action while forwarding on the result
|
|
26
29
|
* @param action
|
|
27
30
|
*/
|
|
28
|
-
export declare function tap<T>(action: (arg0: T) => unknown): (arg0: T) => T
|
|
31
|
+
export declare function tap<T>(action: (arg0: T) => unknown): (arg0: T) => T
|
|
29
32
|
/**
|
|
30
33
|
* Helper utility intended to be used with typed exceptions and .catch() method of promise like so:
|
|
31
34
|
*
|
|
@@ -41,8 +44,8 @@ export declare function tap<T>(action: (arg0: T) => unknown): (arg0: T) => T;
|
|
|
41
44
|
* @param catcher to handle only errors of type cls
|
|
42
45
|
* @returns handler which either forwards to catcher or rethrows
|
|
43
46
|
*/
|
|
44
|
-
export declare function ofClass<E, R>(cls: Class<E>, catcher: (arg0: E) => $Promisable<R>): (arg0: any) => Promise<R
|
|
47
|
+
export declare function ofClass<E, R>(cls: Class<E>, catcher: (arg0: E) => $Promisable<R>): (arg0: any) => Promise<R>
|
|
45
48
|
/**
|
|
46
49
|
* Filter iterable. Just like Array.prototype.filter but callback can return promises
|
|
47
50
|
*/
|
|
48
|
-
export declare function promiseFilter<T>(iterable: Iterable<T>, filter: (item: T, index: number) => $Promisable<boolean>): Promise<Array<T
|
|
51
|
+
export declare function promiseFilter<T>(iterable: Iterable<T>, filter: (item: T, index: number) => $Promisable<boolean>): Promise<Array<T>>
|
package/dist/PromiseUtils.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { pMap as promiseMap } from "./PromiseMap.js"
|
|
1
|
+
import { pMap as promiseMap } from "./PromiseMap.js"
|
|
2
2
|
/**
|
|
3
3
|
* Map array of values to promise of arrays or array. Mapper function may return promise or value. If value is returned,
|
|
4
4
|
* we avoid promise scheduling.
|
|
@@ -7,81 +7,78 @@ import { pMap as promiseMap } from "./PromiseMap.js";
|
|
|
7
7
|
* some browsers (e.g. Safari) when event loop iteration ends).
|
|
8
8
|
*/
|
|
9
9
|
export function mapInCallContext(values, callback) {
|
|
10
|
-
|
|
10
|
+
return new PromisableWrapper(_mapInCallContext(values, callback, 0, []))
|
|
11
11
|
}
|
|
12
12
|
function _mapInCallContext(values, callback, index, acc) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
13
|
+
if (index >= values.length) {
|
|
14
|
+
return acc
|
|
15
|
+
}
|
|
16
|
+
let mappedValue = callback(values[index], index)
|
|
17
|
+
if (mappedValue instanceof Promise) {
|
|
18
|
+
return mappedValue.then(v => {
|
|
19
|
+
acc.push(v)
|
|
20
|
+
return _mapInCallContext(values, callback, index + 1, acc)
|
|
21
|
+
})
|
|
22
|
+
} else {
|
|
23
|
+
acc.push(mappedValue)
|
|
24
|
+
return _mapInCallContext(values, callback, index + 1, acc)
|
|
25
|
+
}
|
|
27
26
|
}
|
|
28
|
-
export { pMap as promiseMap } from "./PromiseMap.js"
|
|
27
|
+
export { pMap as promiseMap } from "./PromiseMap.js"
|
|
29
28
|
function mapNoFallback(values, callback, options) {
|
|
30
|
-
|
|
29
|
+
return PromisableWrapper.from(promiseMap(values, callback, options))
|
|
31
30
|
}
|
|
32
31
|
/** Factory function which gives you ack promiseMap implementation. {@see mapInCallContext} for what it means. */
|
|
33
32
|
export function promiseMapCompat(useMapInCallContext) {
|
|
34
|
-
|
|
33
|
+
return useMapInCallContext ? mapInCallContext : mapNoFallback
|
|
35
34
|
}
|
|
36
35
|
function flatWrapper(value) {
|
|
37
|
-
|
|
36
|
+
return value instanceof PromisableWrapper ? value.value : value
|
|
38
37
|
}
|
|
39
38
|
// It kinda implements 'thenable' protocol so you can freely pass it around as a generic promise
|
|
40
39
|
export class PromisableWrapper {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
return Promise.resolve(this.value);
|
|
66
|
-
}
|
|
40
|
+
constructor(value) {
|
|
41
|
+
this.value = value instanceof Promise ? value.then(flatWrapper) : flatWrapper(value)
|
|
42
|
+
}
|
|
43
|
+
static from(value) {
|
|
44
|
+
return new PromisableWrapper(value)
|
|
45
|
+
}
|
|
46
|
+
thenOrApply(onFulfill, onReject) {
|
|
47
|
+
if (this.value instanceof Promise) {
|
|
48
|
+
const v = this.value.then(onFulfill, onReject)
|
|
49
|
+
return new PromisableWrapper(v)
|
|
50
|
+
} else {
|
|
51
|
+
try {
|
|
52
|
+
return new PromisableWrapper(onFulfill(this.value))
|
|
53
|
+
} catch (e) {
|
|
54
|
+
if (onReject) {
|
|
55
|
+
return new PromisableWrapper(onReject(e))
|
|
56
|
+
}
|
|
57
|
+
throw e
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
toPromise() {
|
|
62
|
+
return Promise.resolve(this.value)
|
|
63
|
+
}
|
|
67
64
|
}
|
|
68
65
|
export function delay(ms) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
66
|
+
if (Number.isNaN(ms) || ms < 0) {
|
|
67
|
+
throw new Error(`Invalid delay: ${ms}`)
|
|
68
|
+
}
|
|
69
|
+
return new Promise(resolve => {
|
|
70
|
+
setTimeout(resolve, ms)
|
|
71
|
+
})
|
|
75
72
|
}
|
|
76
73
|
/**
|
|
77
74
|
* Pass to Promise.then to perform an action while forwarding on the result
|
|
78
75
|
* @param action
|
|
79
76
|
*/
|
|
80
77
|
export function tap(action) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
78
|
+
return function (value) {
|
|
79
|
+
action(value)
|
|
80
|
+
return value
|
|
81
|
+
}
|
|
85
82
|
}
|
|
86
83
|
/**
|
|
87
84
|
* Helper utility intended to be used with typed exceptions and .catch() method of promise like so:
|
|
@@ -99,29 +96,28 @@ export function tap(action) {
|
|
|
99
96
|
* @returns handler which either forwards to catcher or rethrows
|
|
100
97
|
*/
|
|
101
98
|
export function ofClass(cls, catcher) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
};
|
|
99
|
+
return async e => {
|
|
100
|
+
if (e instanceof cls) {
|
|
101
|
+
return catcher(e)
|
|
102
|
+
} else {
|
|
103
|
+
// It's okay to rethrow because:
|
|
104
|
+
// 1. It preserves the original stacktrace
|
|
105
|
+
// 2. Because of 1. it is not that expensive
|
|
106
|
+
throw e
|
|
107
|
+
}
|
|
108
|
+
}
|
|
113
109
|
}
|
|
114
110
|
/**
|
|
115
111
|
* Filter iterable. Just like Array.prototype.filter but callback can return promises
|
|
116
112
|
*/
|
|
117
113
|
export async function promiseFilter(iterable, filter) {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
114
|
+
let index = 0
|
|
115
|
+
const result = []
|
|
116
|
+
for (let item of iterable) {
|
|
117
|
+
if (await filter(item, index)) {
|
|
118
|
+
result.push(item)
|
|
119
|
+
}
|
|
120
|
+
index++
|
|
121
|
+
}
|
|
122
|
+
return result
|
|
127
123
|
}
|