@tutao/tutanota-utils 3.91.0 → 3.91.3
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 +1 -6
- package/dist/ArrayUtils.d.ts +148 -0
- package/dist/ArrayUtils.js +410 -0
- package/dist/AsyncResult.d.ts +23 -0
- package/dist/AsyncResult.js +31 -0
- package/dist/CollectionUtils.d.ts +5 -0
- package/dist/CollectionUtils.js +7 -0
- package/dist/DateUtils.d.ts +60 -0
- package/dist/DateUtils.js +114 -0
- package/dist/Encoding.d.ts +103 -0
- package/dist/Encoding.js +306 -0
- package/dist/LazyLoaded.d.ts +38 -0
- package/dist/LazyLoaded.js +72 -0
- package/dist/MapUtils.d.ts +9 -0
- package/dist/MapUtils.js +38 -0
- package/dist/MathUtils.d.ts +5 -0
- package/dist/MathUtils.js +9 -0
- package/dist/PromiseMap.d.ts +44 -0
- package/dist/PromiseMap.js +75 -0
- package/dist/PromiseUtils.d.ts +48 -0
- package/dist/PromiseUtils.js +127 -0
- package/dist/SortedArray.d.ts +16 -0
- package/dist/SortedArray.js +44 -0
- package/dist/StringUtils.d.ts +58 -0
- package/dist/StringUtils.js +110 -0
- package/dist/TypeRef.d.ts +12 -0
- package/dist/TypeRef.js +19 -0
- package/dist/Utils.d.ts +125 -0
- package/dist/Utils.js +359 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +14 -0
- package/package.json +8 -16
- package/lib/ArrayUtils.js +0 -448
- package/lib/AsyncResult.js +0 -37
- package/lib/CollectionUtils.js +0 -10
- package/lib/DateUtils.js +0 -134
- package/lib/Encoding.js +0 -329
- package/lib/LazyLoaded.js +0 -87
- package/lib/MapUtils.js +0 -42
- package/lib/MathUtils.js +0 -12
- package/lib/PromiseMap.js +0 -121
- package/lib/PromiseUtils.js +0 -144
- package/lib/SortedArray.js +0 -66
- package/lib/StringUtils.js +0 -126
- package/lib/TypeRef.js +0 -25
- package/lib/Utils.js +0 -416
- package/lib/index.js +0 -207
package/dist/Utils.d.ts
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
export declare type lazy<T> = () => T;
|
|
2
|
+
export declare type lazyAsync<T> = () => Promise<T>;
|
|
3
|
+
export declare type Thunk = () => unknown;
|
|
4
|
+
export declare type DeferredObject<T> = {
|
|
5
|
+
resolve: (arg0: T) => void;
|
|
6
|
+
reject: (arg0: Error) => void;
|
|
7
|
+
promise: Promise<T>;
|
|
8
|
+
};
|
|
9
|
+
export declare type DeferredObjectWithHandler<T, U> = {
|
|
10
|
+
resolve: (arg0: T) => void;
|
|
11
|
+
reject: (arg0: Error) => void;
|
|
12
|
+
promise: Promise<U>;
|
|
13
|
+
};
|
|
14
|
+
export declare function defer<T>(): DeferredObject<T>;
|
|
15
|
+
export declare function deferWithHandler<T, U>(handler: (arg0: T) => U): DeferredObjectWithHandler<T, U>;
|
|
16
|
+
export declare function asyncFind<T>(array: ReadonlyArray<T>, finder: (item: T, index: number, arrayLength: number) => Promise<boolean>): Promise<T | null | undefined>;
|
|
17
|
+
export declare function asyncFindAndMap<T, R>(array: ReadonlyArray<T>, finder: (item: T, index: number, arrayLength: number) => Promise<R | null>): Promise<R | null | undefined>;
|
|
18
|
+
/**
|
|
19
|
+
* Calls an executor function for slices of nbrOfElementsInGroup items of the given array until the executor function returns false.
|
|
20
|
+
*/
|
|
21
|
+
export declare function executeInGroups<T>(array: T[], nbrOfElementsInGroup: number, executor: (items: T[]) => Promise<boolean>): Promise<void>;
|
|
22
|
+
export declare function neverNull<T>(object: T): NonNullable<T>;
|
|
23
|
+
export declare function assertNotNull<T>(object: T | null | undefined, message?: string): T;
|
|
24
|
+
export declare function isNotNull<T>(t: T | null | undefined): t is T;
|
|
25
|
+
export declare function assert(assertion: MaybeLazy<boolean>, message: string): void;
|
|
26
|
+
export declare function downcast<R = any>(object: any): R;
|
|
27
|
+
export declare function clone<T>(instance: T): T;
|
|
28
|
+
/**
|
|
29
|
+
* Function which accepts another function. On first invocation
|
|
30
|
+
* of this resulting function result will be remembered and returned
|
|
31
|
+
* on consequent invocations.
|
|
32
|
+
*/
|
|
33
|
+
export declare function lazyMemoized<T>(source: () => T): () => T;
|
|
34
|
+
/**
|
|
35
|
+
* Returns a cached version of {@param fn}.
|
|
36
|
+
* Cached function checks that argument is the same (with ===) and if it is then it returns the cached result.
|
|
37
|
+
* If the cached argument has changed then {@param fn} will be called with new argument and result will be cached again.
|
|
38
|
+
* Only remembers the last argument.
|
|
39
|
+
*/
|
|
40
|
+
export declare function memoized<T, R>(fn: (arg0: T) => R): (arg0: T) => R;
|
|
41
|
+
/**
|
|
42
|
+
* Function which returns what was passed into it
|
|
43
|
+
*/
|
|
44
|
+
export declare function identity<T>(t: T): T;
|
|
45
|
+
/**
|
|
46
|
+
* Function which does nothing.
|
|
47
|
+
*/
|
|
48
|
+
export declare function noOp(): void;
|
|
49
|
+
/**
|
|
50
|
+
* Return a function, which executed {@param toThrottle} only after it is not invoked for {@param timeout} ms.
|
|
51
|
+
* Executes function with the last passed arguments
|
|
52
|
+
* @return {Function}
|
|
53
|
+
*/
|
|
54
|
+
export declare function debounce<F extends (...args: any) => void>(timeout: number, toThrottle: F): F;
|
|
55
|
+
/**
|
|
56
|
+
* Returns a debounced function. When invoked for the first time, will just invoke
|
|
57
|
+
* {@param toThrottle}. On subsequent invocations it will either invoke it right away
|
|
58
|
+
* (if {@param timeout} has passed) or will schedule it to be run after {@param timeout}.
|
|
59
|
+
* So the first and the last invocations in a series of invocations always take place
|
|
60
|
+
* but ones in the middle (which happen too often) are discarded.}
|
|
61
|
+
*/
|
|
62
|
+
export declare function debounceStart<F extends (...args: any) => void>(timeout: number, toThrottle: F): F;
|
|
63
|
+
export declare function randomIntFromInterval(min: number, max: number): number;
|
|
64
|
+
export declare function errorToString(error: Error): string;
|
|
65
|
+
/**
|
|
66
|
+
* Like {@link Object.entries} but preserves the type of the key and value
|
|
67
|
+
*/
|
|
68
|
+
export declare function objectEntries<A extends string | symbol, B>(object: Record<A, B>): Array<[A, B]>;
|
|
69
|
+
/**
|
|
70
|
+
* modified deepEquals from ospec is only needed as long as we use custom classes (TypeRef) and Date is not properly handled
|
|
71
|
+
*/
|
|
72
|
+
export declare function deepEqual(a: any, b: any): boolean;
|
|
73
|
+
/**
|
|
74
|
+
* returns an array of top-level properties that are in both objA and objB, but differ in value
|
|
75
|
+
* does not handle functions or circular references
|
|
76
|
+
* treats undefined and null as equal
|
|
77
|
+
*/
|
|
78
|
+
export declare function getChangedProps(objA: any, objB: any): Array<string>;
|
|
79
|
+
/**
|
|
80
|
+
* Disallow set, delete and clear on Map.
|
|
81
|
+
* Important: It is *not* a deep freeze.
|
|
82
|
+
* @param myMap
|
|
83
|
+
* @return {unknown}
|
|
84
|
+
*/
|
|
85
|
+
export declare function freezeMap<K, V>(myMap: Map<K, V>): Map<K, V>;
|
|
86
|
+
export declare function addressDomain(senderAddress: string): string;
|
|
87
|
+
/**
|
|
88
|
+
* Ignores the fact that Object.keys returns also not owned properties.
|
|
89
|
+
*/
|
|
90
|
+
export declare function typedKeys<K extends string, V>(obj: Record<K, V>): Array<K>;
|
|
91
|
+
/**
|
|
92
|
+
* Ignores the fact that Object.keys returns also not owned properties.
|
|
93
|
+
*/
|
|
94
|
+
export declare function typedEntries<K extends string, V>(obj: Record<K, V>): Array<[K, V]>;
|
|
95
|
+
/**
|
|
96
|
+
* Ignores the fact that Object.keys returns also not owned properties.
|
|
97
|
+
*/
|
|
98
|
+
export declare function typedValues<K extends string, V>(obj: Record<K, V>): Array<V>;
|
|
99
|
+
export declare type MaybeLazy<T> = T | lazy<T>;
|
|
100
|
+
export declare function resolveMaybeLazy<T>(maybe: MaybeLazy<T>): T;
|
|
101
|
+
export declare function getAsLazy<T>(maybe: MaybeLazy<T>): lazy<T>;
|
|
102
|
+
export declare function mapLazily<T, U>(maybe: MaybeLazy<T>, mapping: (arg0: T) => U): lazy<U>;
|
|
103
|
+
/**
|
|
104
|
+
* Stricter version of parseInt() from MDN. parseInt() allows some arbitrary characters at the end of the string.
|
|
105
|
+
* Returns NaN in case there's anything non-number in the string.
|
|
106
|
+
*/
|
|
107
|
+
export declare function filterInt(value: string): number;
|
|
108
|
+
interface Positioned {
|
|
109
|
+
x: number;
|
|
110
|
+
y: number;
|
|
111
|
+
}
|
|
112
|
+
interface Sized {
|
|
113
|
+
top: number;
|
|
114
|
+
left: number;
|
|
115
|
+
bottom: number;
|
|
116
|
+
right: number;
|
|
117
|
+
}
|
|
118
|
+
export declare function insideRect(point: Positioned, rect: Sized): boolean;
|
|
119
|
+
/**
|
|
120
|
+
* If val is non null, returns the result of val passed to action, else null
|
|
121
|
+
*/
|
|
122
|
+
export declare function mapNullable<T, U>(val: T | null | undefined, action: (arg0: T) => U | null | undefined): U | null;
|
|
123
|
+
/** Helper to take instead of `typeof setTimeout` which is hellish to reproduce */
|
|
124
|
+
export declare type TimeoutSetter = (fn: () => unknown, arg1: number) => ReturnType<typeof setTimeout>;
|
|
125
|
+
export {};
|
package/dist/Utils.js
ADDED
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
import { TypeRef } from "./TypeRef.js";
|
|
2
|
+
export function defer() {
|
|
3
|
+
let ret = {};
|
|
4
|
+
ret.promise = new Promise((resolve, reject) => {
|
|
5
|
+
ret.resolve = resolve;
|
|
6
|
+
ret.reject = reject;
|
|
7
|
+
});
|
|
8
|
+
return ret;
|
|
9
|
+
}
|
|
10
|
+
export function deferWithHandler(handler) {
|
|
11
|
+
const deferred = {};
|
|
12
|
+
deferred.promise = new Promise((resolve, reject) => {
|
|
13
|
+
deferred.resolve = resolve;
|
|
14
|
+
deferred.reject = reject;
|
|
15
|
+
}).then(handler);
|
|
16
|
+
return deferred;
|
|
17
|
+
}
|
|
18
|
+
export async function asyncFind(array, finder) {
|
|
19
|
+
for (let i = 0; i < array.length; i++) {
|
|
20
|
+
const item = array[i];
|
|
21
|
+
if (await finder(item, i, array.length)) {
|
|
22
|
+
return item;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
export async function asyncFindAndMap(array, finder) {
|
|
28
|
+
for (let i = 0; i < array.length; i++) {
|
|
29
|
+
const item = array[i];
|
|
30
|
+
const mapped = await finder(item, i, array.length);
|
|
31
|
+
if (mapped) {
|
|
32
|
+
return mapped;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Calls an executor function for slices of nbrOfElementsInGroup items of the given array until the executor function returns false.
|
|
39
|
+
*/
|
|
40
|
+
export function executeInGroups(array, nbrOfElementsInGroup, executor) {
|
|
41
|
+
if (array.length > 0) {
|
|
42
|
+
let nextSlice = Math.min(array.length, nbrOfElementsInGroup);
|
|
43
|
+
return executor(array.slice(0, nextSlice)).then(doContinue => {
|
|
44
|
+
if (doContinue) {
|
|
45
|
+
return executeInGroups(array.slice(nextSlice), nbrOfElementsInGroup, executor);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
return Promise.resolve();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export function neverNull(object) {
|
|
54
|
+
return object;
|
|
55
|
+
}
|
|
56
|
+
export function assertNotNull(object, message = "null") {
|
|
57
|
+
if (object == null) {
|
|
58
|
+
throw new Error("AssertNotNull failed : " + message);
|
|
59
|
+
}
|
|
60
|
+
return object;
|
|
61
|
+
}
|
|
62
|
+
export function isNotNull(t) {
|
|
63
|
+
return t != null;
|
|
64
|
+
}
|
|
65
|
+
export function assert(assertion, message) {
|
|
66
|
+
if (!resolveMaybeLazy(assertion)) {
|
|
67
|
+
throw new Error(`Assertion failed: ${message}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
export function downcast(object) {
|
|
71
|
+
return object;
|
|
72
|
+
}
|
|
73
|
+
export function clone(instance) {
|
|
74
|
+
if (instance instanceof Uint8Array) {
|
|
75
|
+
return downcast(instance.slice());
|
|
76
|
+
}
|
|
77
|
+
else if (instance instanceof Array) {
|
|
78
|
+
return downcast(instance.map(i => clone(i)));
|
|
79
|
+
}
|
|
80
|
+
else if (instance instanceof Date) {
|
|
81
|
+
return new Date(instance.getTime());
|
|
82
|
+
}
|
|
83
|
+
else if (instance instanceof TypeRef) {
|
|
84
|
+
return instance;
|
|
85
|
+
}
|
|
86
|
+
else if (instance instanceof Object) {
|
|
87
|
+
// Can only pass null or Object, cannot pass undefined
|
|
88
|
+
const copy = Object.create(Object.getPrototypeOf(instance) || null);
|
|
89
|
+
Object.assign(copy, instance);
|
|
90
|
+
for (let key of Object.keys(copy)) {
|
|
91
|
+
copy[key] = clone(copy[key]);
|
|
92
|
+
}
|
|
93
|
+
return copy;
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
return instance;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Function which accepts another function. On first invocation
|
|
101
|
+
* of this resulting function result will be remembered and returned
|
|
102
|
+
* on consequent invocations.
|
|
103
|
+
*/
|
|
104
|
+
export function lazyMemoized(source) {
|
|
105
|
+
// Using separate variable for tracking because value can be undefined and we want to the function call only once
|
|
106
|
+
let cached = false;
|
|
107
|
+
let value;
|
|
108
|
+
return () => {
|
|
109
|
+
if (cached) {
|
|
110
|
+
return value;
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
cached = true;
|
|
114
|
+
return (value = source());
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Returns a cached version of {@param fn}.
|
|
120
|
+
* Cached function checks that argument is the same (with ===) and if it is then it returns the cached result.
|
|
121
|
+
* If the cached argument has changed then {@param fn} will be called with new argument and result will be cached again.
|
|
122
|
+
* Only remembers the last argument.
|
|
123
|
+
*/
|
|
124
|
+
export function memoized(fn) {
|
|
125
|
+
let lastArg;
|
|
126
|
+
let lastResult;
|
|
127
|
+
let didCache = false;
|
|
128
|
+
return arg => {
|
|
129
|
+
if (!didCache || arg !== lastArg) {
|
|
130
|
+
lastArg = arg;
|
|
131
|
+
didCache = true;
|
|
132
|
+
lastResult = fn(arg);
|
|
133
|
+
}
|
|
134
|
+
return lastResult;
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Function which returns what was passed into it
|
|
139
|
+
*/
|
|
140
|
+
export function identity(t) {
|
|
141
|
+
return t;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Function which does nothing.
|
|
145
|
+
*/
|
|
146
|
+
export function noOp() {
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Return a function, which executed {@param toThrottle} only after it is not invoked for {@param timeout} ms.
|
|
150
|
+
* Executes function with the last passed arguments
|
|
151
|
+
* @return {Function}
|
|
152
|
+
*/
|
|
153
|
+
export function debounce(timeout, toThrottle) {
|
|
154
|
+
let timeoutId;
|
|
155
|
+
let toInvoke;
|
|
156
|
+
return downcast((...args) => {
|
|
157
|
+
if (timeoutId) {
|
|
158
|
+
clearTimeout(timeoutId);
|
|
159
|
+
}
|
|
160
|
+
toInvoke = toThrottle.bind(null, ...args);
|
|
161
|
+
timeoutId = setTimeout(toInvoke, timeout);
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Returns a debounced function. When invoked for the first time, will just invoke
|
|
166
|
+
* {@param toThrottle}. On subsequent invocations it will either invoke it right away
|
|
167
|
+
* (if {@param timeout} has passed) or will schedule it to be run after {@param timeout}.
|
|
168
|
+
* So the first and the last invocations in a series of invocations always take place
|
|
169
|
+
* but ones in the middle (which happen too often) are discarded.}
|
|
170
|
+
*/
|
|
171
|
+
export function debounceStart(timeout, toThrottle) {
|
|
172
|
+
let timeoutId;
|
|
173
|
+
let lastInvoked = 0;
|
|
174
|
+
return downcast((...args) => {
|
|
175
|
+
if (Date.now() - lastInvoked < timeout) {
|
|
176
|
+
timeoutId && clearTimeout(timeoutId);
|
|
177
|
+
timeoutId = setTimeout(() => {
|
|
178
|
+
timeoutId = null;
|
|
179
|
+
toThrottle.apply(null, args);
|
|
180
|
+
}, timeout);
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
toThrottle.apply(null, args);
|
|
184
|
+
}
|
|
185
|
+
lastInvoked = Date.now();
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
export function randomIntFromInterval(min, max) {
|
|
189
|
+
return Math.floor(Math.random() * (max - min + 1) + min);
|
|
190
|
+
}
|
|
191
|
+
export function errorToString(error) {
|
|
192
|
+
let errorString = error.name ? error.name : "?";
|
|
193
|
+
if (error.message) {
|
|
194
|
+
errorString += `\n Error message: ${error.message}`;
|
|
195
|
+
}
|
|
196
|
+
if (error.stack) {
|
|
197
|
+
// the error id is included in the stacktrace
|
|
198
|
+
errorString += `\nStacktrace: \n${error.stack}`;
|
|
199
|
+
}
|
|
200
|
+
return errorString;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Like {@link Object.entries} but preserves the type of the key and value
|
|
204
|
+
*/
|
|
205
|
+
export function objectEntries(object) {
|
|
206
|
+
return downcast(Object.entries(object));
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* modified deepEquals from ospec is only needed as long as we use custom classes (TypeRef) and Date is not properly handled
|
|
210
|
+
*/
|
|
211
|
+
export function deepEqual(a, b) {
|
|
212
|
+
if (a === b)
|
|
213
|
+
return true;
|
|
214
|
+
if (xor(a === null, b === null) || xor(a === undefined, b === undefined))
|
|
215
|
+
return false;
|
|
216
|
+
if (typeof a === "object" && typeof b === "object") {
|
|
217
|
+
const aIsArgs = isArguments(a), bIsArgs = isArguments(b);
|
|
218
|
+
if (a.length === b.length && ((a instanceof Array && b instanceof Array) || (aIsArgs && bIsArgs))) {
|
|
219
|
+
const aKeys = Object.getOwnPropertyNames(a), bKeys = Object.getOwnPropertyNames(b);
|
|
220
|
+
if (aKeys.length !== bKeys.length)
|
|
221
|
+
return false;
|
|
222
|
+
for (let i = 0; i < aKeys.length; i++) {
|
|
223
|
+
if (!hasOwn.call(b, aKeys[i]) || !deepEqual(a[aKeys[i]], b[aKeys[i]]))
|
|
224
|
+
return false;
|
|
225
|
+
}
|
|
226
|
+
return true;
|
|
227
|
+
}
|
|
228
|
+
if (a instanceof Date && b instanceof Date)
|
|
229
|
+
return a.getTime() === b.getTime();
|
|
230
|
+
if (a instanceof Object && b instanceof Object && !aIsArgs && !bIsArgs) {
|
|
231
|
+
for (let i in a) {
|
|
232
|
+
if (!(i in b) || !deepEqual(a[i], b[i]))
|
|
233
|
+
return false;
|
|
234
|
+
}
|
|
235
|
+
for (let i in b) {
|
|
236
|
+
if (!(i in a))
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
return true;
|
|
240
|
+
}
|
|
241
|
+
if (typeof Buffer === "function" && a instanceof Buffer && b instanceof Buffer) {
|
|
242
|
+
for (let i = 0; i < a.length; i++) {
|
|
243
|
+
if (a[i] !== b[i])
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
return true;
|
|
247
|
+
}
|
|
248
|
+
if (a.valueOf() === b.valueOf())
|
|
249
|
+
return true;
|
|
250
|
+
}
|
|
251
|
+
return false;
|
|
252
|
+
}
|
|
253
|
+
function xor(a, b) {
|
|
254
|
+
const aBool = !!a;
|
|
255
|
+
const bBool = !!b;
|
|
256
|
+
return (aBool && !bBool) || (bBool && !aBool);
|
|
257
|
+
}
|
|
258
|
+
function isArguments(a) {
|
|
259
|
+
if ("callee" in a) {
|
|
260
|
+
for (let i in a)
|
|
261
|
+
if (i === "callee")
|
|
262
|
+
return false;
|
|
263
|
+
return true;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
const hasOwn = {}.hasOwnProperty;
|
|
267
|
+
/**
|
|
268
|
+
* returns an array of top-level properties that are in both objA and objB, but differ in value
|
|
269
|
+
* does not handle functions or circular references
|
|
270
|
+
* treats undefined and null as equal
|
|
271
|
+
*/
|
|
272
|
+
export function getChangedProps(objA, objB) {
|
|
273
|
+
if (objA == null || objB == null || objA === objB)
|
|
274
|
+
return [];
|
|
275
|
+
return Object.keys(objA)
|
|
276
|
+
.filter(k => Object.keys(objB).includes(k))
|
|
277
|
+
.filter(k => ![null, undefined].includes(objA[k]) || ![null, undefined].includes(objB[k]))
|
|
278
|
+
.filter(k => !deepEqual(objA[k], objB[k]));
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Disallow set, delete and clear on Map.
|
|
282
|
+
* Important: It is *not* a deep freeze.
|
|
283
|
+
* @param myMap
|
|
284
|
+
* @return {unknown}
|
|
285
|
+
*/
|
|
286
|
+
export function freezeMap(myMap) {
|
|
287
|
+
function mapSet(key, value) {
|
|
288
|
+
throw new Error("Can't add property " + key + ", map is not extensible");
|
|
289
|
+
}
|
|
290
|
+
function mapDelete(key) {
|
|
291
|
+
throw new Error("Can't delete property " + key + ", map is frozen");
|
|
292
|
+
}
|
|
293
|
+
function mapClear() {
|
|
294
|
+
throw new Error("Can't clear map, map is frozen");
|
|
295
|
+
}
|
|
296
|
+
const anyMap = downcast(myMap);
|
|
297
|
+
anyMap.set = mapSet;
|
|
298
|
+
anyMap.delete = mapDelete;
|
|
299
|
+
anyMap.clear = mapClear;
|
|
300
|
+
Object.freeze(anyMap);
|
|
301
|
+
return anyMap;
|
|
302
|
+
}
|
|
303
|
+
export function addressDomain(senderAddress) {
|
|
304
|
+
return senderAddress.slice(senderAddress.lastIndexOf("@") + 1);
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Ignores the fact that Object.keys returns also not owned properties.
|
|
308
|
+
*/
|
|
309
|
+
export function typedKeys(obj) {
|
|
310
|
+
return downcast(Object.keys(obj));
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Ignores the fact that Object.keys returns also not owned properties.
|
|
314
|
+
*/
|
|
315
|
+
export function typedEntries(obj) {
|
|
316
|
+
return downcast(Object.entries(obj));
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Ignores the fact that Object.keys returns also not owned properties.
|
|
320
|
+
*/
|
|
321
|
+
export function typedValues(obj) {
|
|
322
|
+
return downcast(Object.values(obj));
|
|
323
|
+
}
|
|
324
|
+
export function resolveMaybeLazy(maybe) {
|
|
325
|
+
return typeof maybe === "function" ? maybe() : maybe;
|
|
326
|
+
}
|
|
327
|
+
export function getAsLazy(maybe) {
|
|
328
|
+
return typeof maybe === "function" ? downcast(maybe) : () => maybe;
|
|
329
|
+
}
|
|
330
|
+
export function mapLazily(maybe, mapping) {
|
|
331
|
+
return () => mapping(resolveMaybeLazy(maybe));
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Stricter version of parseInt() from MDN. parseInt() allows some arbitrary characters at the end of the string.
|
|
335
|
+
* Returns NaN in case there's anything non-number in the string.
|
|
336
|
+
*/
|
|
337
|
+
export function filterInt(value) {
|
|
338
|
+
if (/^\d+$/.test(value)) {
|
|
339
|
+
return parseInt(value, 10);
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
return NaN;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
export function insideRect(point, rect) {
|
|
346
|
+
return point.x >= rect.left && point.x < rect.right && point.y >= rect.top && point.y < rect.bottom;
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* If val is non null, returns the result of val passed to action, else null
|
|
350
|
+
*/
|
|
351
|
+
export function mapNullable(val, action) {
|
|
352
|
+
if (val != null) {
|
|
353
|
+
const result = action(val);
|
|
354
|
+
if (result != null) {
|
|
355
|
+
return result;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
return null;
|
|
359
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export { concat, numberRange, arrayEquals, arrayEqualsWithPredicate, arrayHash, remove, findAll, findAndRemove, findAllAndRemove, replace, mapAndFilterNull, filterNull, last, isEmpty, lastThrow, firstThrow, first, findLast, findLastIndex, contains, addAll, removeAll, groupByAndMapUniquely, groupByAndMap, groupBy, splitInChunks, flat, flatMap, insertIntoSortedArray, zip, deduplicate, binarySearch, lastIndex, union, difference, symmetricDifference, partition, } from "./ArrayUtils.js";
|
|
2
|
+
export { AsyncResult } from "./AsyncResult.js";
|
|
3
|
+
export { intersection } from "./CollectionUtils.js";
|
|
4
|
+
export { DAY_IN_MILLIS, getStartOfNextDay, getEndOfDay, getStartOfDay, getHourOfDay, isStartOfDay, isToday, isSameDay, getDayShifted, incrementDate, incrementMonth, isSameDayOfDate, formatSortableDate, formatSortableDateTime, sortableTimestamp, isValidDate, millisToDays, daysToMillis, } from "./DateUtils.js";
|
|
5
|
+
export { uint8ArrayToArrayBuffer, hexToBase64, base64ToHex, base64ToBase64Url, base64ToBase64Ext, base64ExtToBase64, base64UrlToBase64, stringToUtf8Uint8Array, utf8Uint8ArrayToString, hexToUint8Array, uint8ArrayToHex, uint8ArrayToBase64, int8ArrayToBase64, base64ToUint8Array, uint8ArrayToString, decodeQuotedPrintable, decodeBase64, stringToBase64, } from "./Encoding.js";
|
|
6
|
+
export type { Base64, Base64Ext, Base64Url, Hex } from "./Encoding.js";
|
|
7
|
+
export { LazyLoaded } from "./LazyLoaded.js";
|
|
8
|
+
export { mergeMaps, getFromMap, addMapEntry, deleteMapEntry } from "./MapUtils.js";
|
|
9
|
+
export { pMap } from "./PromiseMap.js";
|
|
10
|
+
export type { Mapper } from "./PromiseMap.js";
|
|
11
|
+
export { mapInCallContext, promiseMap, promiseMapCompat, PromisableWrapper, delay, tap, ofClass, promiseFilter, } from "./PromiseUtils.js";
|
|
12
|
+
export type { PromiseMapFn, $Promisable } from "./PromiseUtils.js";
|
|
13
|
+
export { SortedArray } from "./SortedArray.js";
|
|
14
|
+
export type { CompareFn } from "./SortedArray.js";
|
|
15
|
+
export { pad, startsWith, capitalizeFirstLetter, endsWith, lazyStringValue, repeat, cleanMatch, NBSP, splitAt, toLowerCase, localeCompare, byteLength, replaceAll, } from "./StringUtils.js";
|
|
16
|
+
export { TypeRef, isSameTypeRefByAttr, isSameTypeRef } from "./TypeRef.js";
|
|
17
|
+
export { defer, deferWithHandler, asyncFind, asyncFindAndMap, executeInGroups, neverNull, assertNotNull, assert, isNotNull, downcast, clone, lazyMemoized, memoized, identity, noOp, debounce, debounceStart, randomIntFromInterval, errorToString, objectEntries, deepEqual, getChangedProps, freezeMap, addressDomain, typedKeys, typedEntries, typedValues, resolveMaybeLazy, getAsLazy, mapLazily, filterInt, insideRect, mapNullable, } from "./Utils.js";
|
|
18
|
+
export type { DeferredObject, lazy, lazyAsync, Thunk, DeferredObjectWithHandler, MaybeLazy, TimeoutSetter } from "./Utils.js";
|
|
19
|
+
export { mod, clamp } from "./MathUtils.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { concat, numberRange, arrayEquals, arrayEqualsWithPredicate, arrayHash, remove, findAll, findAndRemove, findAllAndRemove, replace, mapAndFilterNull, filterNull, last, isEmpty, lastThrow, firstThrow, first, findLast, findLastIndex, contains, addAll, removeAll, groupByAndMapUniquely, groupByAndMap, groupBy, splitInChunks, flat, flatMap, insertIntoSortedArray, zip, deduplicate, binarySearch, lastIndex, union, difference, symmetricDifference, partition, } from "./ArrayUtils.js";
|
|
2
|
+
export { AsyncResult } from "./AsyncResult.js";
|
|
3
|
+
export { intersection } from "./CollectionUtils.js";
|
|
4
|
+
export { DAY_IN_MILLIS, getStartOfNextDay, getEndOfDay, getStartOfDay, getHourOfDay, isStartOfDay, isToday, isSameDay, getDayShifted, incrementDate, incrementMonth, isSameDayOfDate, formatSortableDate, formatSortableDateTime, sortableTimestamp, isValidDate, millisToDays, daysToMillis, } from "./DateUtils.js";
|
|
5
|
+
export { uint8ArrayToArrayBuffer, hexToBase64, base64ToHex, base64ToBase64Url, base64ToBase64Ext, base64ExtToBase64, base64UrlToBase64, stringToUtf8Uint8Array, utf8Uint8ArrayToString, hexToUint8Array, uint8ArrayToHex, uint8ArrayToBase64, int8ArrayToBase64, base64ToUint8Array, uint8ArrayToString, decodeQuotedPrintable, decodeBase64, stringToBase64, } from "./Encoding.js";
|
|
6
|
+
export { LazyLoaded } from "./LazyLoaded.js";
|
|
7
|
+
export { mergeMaps, getFromMap, addMapEntry, deleteMapEntry } from "./MapUtils.js";
|
|
8
|
+
export { pMap } from "./PromiseMap.js";
|
|
9
|
+
export { mapInCallContext, promiseMap, promiseMapCompat, PromisableWrapper, delay, tap, ofClass, promiseFilter, } from "./PromiseUtils.js";
|
|
10
|
+
export { SortedArray } from "./SortedArray.js";
|
|
11
|
+
export { pad, startsWith, capitalizeFirstLetter, endsWith, lazyStringValue, repeat, cleanMatch, NBSP, splitAt, toLowerCase, localeCompare, byteLength, replaceAll, } from "./StringUtils.js";
|
|
12
|
+
export { TypeRef, isSameTypeRefByAttr, isSameTypeRef } from "./TypeRef.js";
|
|
13
|
+
export { defer, deferWithHandler, asyncFind, asyncFindAndMap, executeInGroups, neverNull, assertNotNull, assert, isNotNull, downcast, clone, lazyMemoized, memoized, identity, noOp, debounce, debounceStart, randomIntFromInterval, errorToString, objectEntries, deepEqual, getChangedProps, freezeMap, addressDomain, typedKeys, typedEntries, typedValues, resolveMaybeLazy, getAsLazy, mapLazily, filterInt, insideRect, mapNullable, } from "./Utils.js";
|
|
14
|
+
export { mod, clamp } from "./MathUtils.js";
|
package/package.json
CHANGED
|
@@ -1,35 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tutao/tutanota-utils",
|
|
3
|
-
"version": "3.91.
|
|
3
|
+
"version": "3.91.3",
|
|
4
4
|
"license": "GPL-3.0",
|
|
5
|
-
"main": "./
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
6
7
|
"repository": {
|
|
7
8
|
"type": "git",
|
|
8
9
|
"url": "https://github.com/tutao/tutanota.git",
|
|
9
10
|
"directory": "packages/tutanota-utils"
|
|
10
11
|
},
|
|
11
12
|
"scripts": {
|
|
12
|
-
"
|
|
13
|
-
"
|
|
13
|
+
"test": "rm -r build; tsc --project test/tsconfig.json && cd build/test && node 'Suite.js'",
|
|
14
|
+
"build": "rm -r dist; tsc"
|
|
14
15
|
},
|
|
15
16
|
"type": "module",
|
|
16
17
|
"files": [
|
|
17
|
-
"
|
|
18
|
+
"dist/*",
|
|
18
19
|
"README.md",
|
|
19
20
|
"LICENSE.txt"
|
|
20
21
|
],
|
|
21
22
|
"devDependencies": {
|
|
22
|
-
"@
|
|
23
|
-
"
|
|
24
|
-
"@babel/plugin-transform-flow-strip-types": "7.4.4",
|
|
25
|
-
"@babel/plugin-proposal-nullish-coalescing-operator": "7.14.5",
|
|
26
|
-
"@babel/plugin-proposal-optional-chaining": "7.14.5",
|
|
27
|
-
"@rollup/plugin-commonjs": "21.0.1",
|
|
28
|
-
"@rollup/plugin-babel": "5.2.2",
|
|
29
|
-
"@rollup/plugin-node-resolve": "11.0.1",
|
|
30
|
-
"flow-bin": "0.152.0",
|
|
31
|
-
"rollup": "2.55.1",
|
|
32
|
-
"@tutao/tutanota-test-utils": "3.91.0",
|
|
23
|
+
"@tutao/tutanota-test-utils": "3.91.3",
|
|
24
|
+
"typescript": "4.5.4",
|
|
33
25
|
"ospec": "https://github.com/tutao/ospec.git#0472107629ede33be4c4d19e89f237a6d7b0cb11"
|
|
34
26
|
}
|
|
35
27
|
}
|