@tutao/tutanota-utils 3.89.24 → 3.91.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.
@@ -1,144 +0,0 @@
1
- //@flow
2
- import type {Options as PromiseMapOptions} from "./PromiseMap"
3
- import {pMap as promiseMap} from "./PromiseMap"
4
-
5
- export type $Promisable<+T> = Promise<T> | T;
6
- type PromiseMapCallback<T, U> = (el: T, index: number) => $Promisable<U>
7
-
8
-
9
- /**
10
- * Map array of values to promise of arrays or array. Mapper function may return promise or value. If value is returned,
11
- * we avoid promise scheduling.
12
- *
13
- * This is needed to run the whole operation in one microtask (e.g. keep IndexedDB transaction active, which is closed in
14
- * some browsers (e.g. Safari) when event loop iteration ends).
15
- */
16
- export function mapInCallContext<T, U>(values: T[], callback: PromiseMapCallback<T, U>): PromisableWrapper<Array<U>> {
17
- return new PromisableWrapper(_mapInCallContext(values, callback, 0, []))
18
- }
19
-
20
- function _mapInCallContext<T, U>(values: T[], callback: PromiseMapCallback<T, U>, index: number, acc: U[]): $Promisable<Array<U>> {
21
- if (index >= values.length) {
22
- return acc
23
- }
24
- let mappedValue = callback(values[index], index)
25
- if (mappedValue instanceof Promise) {
26
- return mappedValue.then((v) => {
27
- acc.push(v)
28
- return _mapInCallContext(values, callback, index + 1, acc)
29
- })
30
- } else {
31
- acc.push(mappedValue)
32
- return _mapInCallContext(values, callback, index + 1, acc)
33
- }
34
- }
35
-
36
- export {pMap as promiseMap} from "./PromiseMap"
37
-
38
- export type PromiseMapFn = <T, U>(values: T[], callback: PromiseMapCallback<T, U>, options?: PromiseMapOptions) => PromisableWrapper<U[]>
39
-
40
- function mapNoFallback<T, U>(values: Array<T>, callback: PromiseMapCallback<T, U>, options?: PromiseMapOptions) {
41
- return PromisableWrapper.from(promiseMap(values, callback, options))
42
- }
43
-
44
- /** Factory function which gives you ack promiseMap implementation. {@see mapInCallContext} for what it means. */
45
- export function promiseMapCompat(useMapInCallContext: boolean): PromiseMapFn {
46
- return useMapInCallContext ? mapInCallContext : mapNoFallback
47
- }
48
-
49
- function flatWrapper<T>(value: PromisableWrapper<T> | T): $Promisable<T> {
50
- return value instanceof PromisableWrapper ? value.value : value
51
- }
52
-
53
- // It kinda implements 'thenable' protocol so you can freely pass it around as a generic promise
54
- export class PromisableWrapper<T> {
55
- static from(value: $Promisable<T>): PromisableWrapper<T> {
56
- return new PromisableWrapper(value)
57
- }
58
-
59
- value: $Promisable<T>;
60
-
61
- constructor(value: $Promisable<PromisableWrapper<T> | T>) {
62
- this.value = value instanceof Promise ? value.then(flatWrapper) : flatWrapper(value);
63
- }
64
-
65
- thenOrApply<R>(onFulfill: (T) => $Promisable<PromisableWrapper<R> | R>, onReject?: (any) => $Promisable<R | PromisableWrapper<R>>): PromisableWrapper<R> {
66
- if (this.value instanceof Promise) {
67
- const v: Promise<PromisableWrapper<R> | R> = this.value.then(onFulfill, onReject)
68
- return new PromisableWrapper(v)
69
- } else {
70
- try {
71
- return new PromisableWrapper(onFulfill(this.value))
72
- } catch (e) {
73
- if (onReject) {
74
- return new PromisableWrapper<R>(onReject(e))
75
- }
76
- throw e
77
- }
78
- }
79
- }
80
-
81
- toPromise(): Promise<T> {
82
- return Promise.resolve(this.value)
83
- }
84
- }
85
-
86
- export function delay(ms: number): Promise<void> {
87
- return new Promise((resolve) => {
88
- setTimeout(resolve, ms)
89
- })
90
- }
91
-
92
- /**
93
- * Pass to Promise.then to perform an action while forwarding on the result
94
- * @param action
95
- */
96
- export function tap<T>(action: T => mixed): T => T {
97
- return function (value) {
98
- action(value)
99
- return value
100
- }
101
- }
102
-
103
- /**
104
- * Helper utility intended to be used with typed excpetions and .catch() method of promise like so:
105
- *
106
- * ```js
107
- * class SpecificError extends Error {}
108
- *
109
- * Promise.reject(new SpecificError())
110
- * .catch(ofClass(SpecificError, (e) => console.log("some error", e)))
111
- * .catch((e) => console.log("generic error", e))
112
- * ```
113
- *
114
- * @param cls Class which will be caught
115
- * @param catcher to handle only errors of type cls
116
- * @returns handler which either forwards to catcher or rethrows
117
- */
118
- export function ofClass<E, R>(cls: Class<E>, catcher: (E) => $Promisable<R>): ((any) => Promise<R>) {
119
- return async (e) => {
120
- if (e instanceof cls) {
121
- return catcher(e)
122
- } else {
123
- // It's okay to rethrow because:
124
- // 1. It preserves the original stacktrace
125
- // 2. Because of 1. it is not that expensive
126
- throw e
127
- }
128
- }
129
- }
130
-
131
- /**
132
- * Filter iterable. Just like Array.prototype.filter but callback can return promises
133
- */
134
- export async function promiseFilter<T>(iterable: Iterable<T>, filter: (item: T, index: number) => $Promisable<boolean>): Promise<Array<T>> {
135
- let index = 0
136
- const result = []
137
- for (let item of iterable) {
138
- if (await filter(item, index)) {
139
- result.push(item)
140
- }
141
- index++
142
- }
143
- return result
144
- }
@@ -1,66 +0,0 @@
1
- // @flow
2
-
3
- import {findAndRemove, insertIntoSortedArray} from "./ArrayUtils"
4
-
5
- export type CompareFn<T> = (T, T) => number
6
-
7
- /**
8
- * Compared based on the type's natural ordering
9
- * @param a
10
- * @param b
11
- * @returns {number}
12
- */
13
- // <T: Object> to get flow off my back about using comparison operator
14
- // It should be fine for 99% of use cases? worst case it just returns 0 always
15
- function defaultCompare<T: Object>(a: T, b: T): number {
16
- return a < b
17
- ? -1
18
- : a > b
19
- ? 1 : 0
20
- }
21
-
22
- /**
23
- * An array that keeps itself sorted
24
- */
25
- export class SortedArray<T> {
26
- +_contents: Array<T>
27
- +_compareFn: CompareFn<T>
28
-
29
- constructor(compareFn: CompareFn<T> = defaultCompare) {
30
- this._contents = []
31
- this._compareFn = compareFn
32
- }
33
-
34
- static from(array: $ReadOnlyArray<T>, compareFn?: CompareFn<T>): SortedArray<T> {
35
- const list = new SortedArray<T>(compareFn)
36
- list.insertAll(array)
37
- return list
38
- }
39
-
40
- get length(): number {
41
- return this._contents.length
42
- }
43
-
44
- get array(): $ReadOnlyArray<T> {
45
- return this._contents
46
- }
47
-
48
- get(index: number): T {
49
- return this._contents[index]
50
- }
51
-
52
- insertAll(array: $ReadOnlyArray<T>) {
53
- this._contents.push(...array)
54
- this._contents.sort(this._compareFn)
55
- }
56
-
57
- insert(item: T): void {
58
- insertIntoSortedArray(item, this._contents, this._compareFn)
59
- }
60
-
61
- removeFirst(finder: (T) => boolean): boolean {
62
- return findAndRemove(this._contents, finder)
63
- }
64
- }
65
-
66
-
@@ -1,126 +0,0 @@
1
- // @flow
2
-
3
- import type {lazy} from "./Utils.js"
4
-
5
- /**
6
- * Returns a string which contains the given number padded with 0s.
7
- * @param num The number to pad.
8
- * @param size The number of resulting digits.
9
- * @return The padded number as string.
10
- */
11
- export function pad(num: number, size: number): string {
12
- var s = num + "";
13
- while (s.length < size)
14
- s = "0" + s;
15
- return s;
16
- }
17
-
18
- /**
19
- * Checks if a string starts with another string.
20
- * @param string The string to test.
21
- * @param substring If the other string begins with this one, we return true.
22
- * @return True if string begins with substring, false otherwise.
23
- */
24
- export function startsWith(string: string, substring: string): boolean {
25
- return string.startsWith(substring)
26
- }
27
-
28
- /**
29
- * uppercase the first letter of a string, lowercase the rest
30
- * @param str string to transform
31
- * @returns {string} str in lowercase with first letter Capitalized
32
- */
33
- export function capitalizeFirstLetter(str: string): string {
34
- return str[0].toUpperCase() + str.toLowerCase().slice(1);
35
- }
36
-
37
- /**
38
- * Checks if a string ends with another string.
39
- * @param string The string to test.
40
- * @param substring If the other string ends with this one, we return true.
41
- * @return True if string ends with substring, false otherwise.
42
- */
43
- export function endsWith(string: string, substring: string): boolean {
44
- return string.endsWith(substring)
45
- }
46
-
47
-
48
- export function lazyStringValue(valueOrLazy: string | lazy<string>): string {
49
- return typeof valueOrLazy === "function"
50
- ? valueOrLazy()
51
- : valueOrLazy
52
- }
53
-
54
- export function repeat(value: string, length: number): string {
55
- let result = ""
56
- for (let i = 0; i < length; i++) {
57
- result += value;
58
- }
59
- return result
60
- }
61
-
62
- export function cleanMatch(s1: string, s2: string): boolean {
63
- return s1.toLowerCase().trim() === s2.toLowerCase().trim()
64
- }
65
-
66
- /**
67
- * Non-breaking space character
68
- */
69
- export const NBSP = "\u00A0";
70
-
71
- /**
72
- * split a string at a given index
73
- * @param str
74
- * @param index
75
- */
76
- export function splitAt(str: string, index: number): [string, string] {
77
- return [str.substring(0, index), str.substring(index)]
78
- }
79
-
80
- /**
81
- * Wrapper around String.prototype.toLowerCase, nice for calls to Array.prototype.map
82
- * @param str
83
- */
84
- export function toLowerCase(str: string): string {
85
- return str.toLowerCase()
86
- }
87
-
88
- /**
89
- * Wrapper around String.prototype.localeCompare, for passing to Array.prototype.sort
90
- * @param a
91
- * @param b
92
- * @returns {number}
93
- */
94
- export function localeCompare(a: string, b: string): number {
95
- return a.localeCompare(b)
96
- }
97
-
98
- export function byteLength(str: ?string): number {
99
- if (str == null) return 0
100
- // returns the byte length of an utf8 string
101
- var s = str.length;
102
- for (var i = str.length - 1; i >= 0; i--) {
103
- var code = str.charCodeAt(i);
104
- if (code > 0x7f && code <= 0x7ff) {
105
- s++;
106
- } else if (code > 0x7ff && code <= 0xffff) s += 2;
107
- if (code >= 0xDC00 && code <= 0xDFFF) i--; //trail surrogate
108
- }
109
- return s;
110
- }
111
-
112
- /**
113
- * replace all instances of substr in str with replacement
114
- */
115
- export function replaceAll(str: string, substr: string, replacement: string): string {
116
- const regex = escapedStringRegExp(substr, 'g')
117
- return str.replace(regex, replacement)
118
- }
119
-
120
- /**
121
- * Create a regex to exactly match a given string, by escaping any special regex characters
122
- * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping
123
- * */
124
- function escapedStringRegExp(str: string, flags: string): RegExp {
125
- return new RegExp(str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), flags)
126
- }
package/lib/TypeRef.js DELETED
@@ -1,25 +0,0 @@
1
- //@flow
2
-
3
- /**
4
- * Attention: TypeRef must be defined as class and not as Flow type because object types use structural typing and TypeRef does not
5
- * reference T. See https://github.com/facebook/flow/issues/3348
6
- * T should be bound to entities but we have no type to define them yet.
7
- */
8
- export class TypeRef<+T> {
9
- +app: string;
10
- +type: string;
11
-
12
- constructor(app: string, type: string) {
13
- this.app = app
14
- this.type = type
15
- Object.freeze(this)
16
- }
17
- }
18
-
19
- export function isSameTypeRefByAttr(typeRef: TypeRef<any>, app: string, type: string): boolean {
20
- return typeRef.app === app && typeRef.type === type
21
- }
22
-
23
- export function isSameTypeRef(typeRef1: TypeRef<any>, typeRef2: TypeRef<any>): boolean {
24
- return isSameTypeRefByAttr(typeRef1, typeRef2.app, typeRef2.type)
25
- }