@tutao/tutanota-utils 3.93.7 → 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 -11
- package/dist/TypeRef.js +15 -15
- 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/ArrayUtils.js.gz +0 -0
- package/dist/AsyncResult.js.gz +0 -0
- package/dist/CollectionUtils.js.gz +0 -0
- package/dist/DateUtils.js.gz +0 -0
- package/dist/Encoding.js.gz +0 -0
- package/dist/LazyLoaded.js.gz +0 -0
- package/dist/MapUtils.js.gz +0 -0
- package/dist/MathUtils.js.gz +0 -0
- package/dist/PromiseMap.js.gz +0 -0
- package/dist/PromiseUtils.js.gz +0 -0
- package/dist/SortedArray.js.gz +0 -0
- package/dist/StringUtils.js.gz +0 -0
- package/dist/TypeRef.js.gz +0 -0
- package/dist/Utils.js.gz +0 -0
- package/dist/index.js.gz +0 -0
package/dist/ArrayUtils.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { downcast, identity, neverNull } from "./Utils.js"
|
|
2
|
-
import { getFromMap } from "./MapUtils.js"
|
|
1
|
+
import { downcast, identity, neverNull } from "./Utils.js"
|
|
2
|
+
import { getFromMap } from "./MapUtils.js"
|
|
3
3
|
export function concat(...arrays) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
let length = arrays.reduce((previous, current) => previous + current.length, 0)
|
|
5
|
+
let result = new Uint8Array(length)
|
|
6
|
+
let index = 0
|
|
7
|
+
arrays.forEach(array => {
|
|
8
|
+
result.set(array, index)
|
|
9
|
+
index += array.length
|
|
10
|
+
})
|
|
11
|
+
return result
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
14
14
|
* Create an array filled with the numbers min..max (inclusive)
|
|
15
15
|
*/
|
|
16
16
|
export function numberRange(min, max) {
|
|
17
|
-
|
|
17
|
+
return [...Array(max + 1).keys()].slice(min)
|
|
18
18
|
}
|
|
19
19
|
/**
|
|
20
20
|
* Compares two arrays for equality based on ===.
|
|
@@ -25,18 +25,18 @@ export function numberRange(min, max) {
|
|
|
25
25
|
* It is valid to compare Uint8Array to Array<T>, don't restrict it to be one type
|
|
26
26
|
*/
|
|
27
27
|
export function arrayEquals(a1, a2) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
28
|
+
if (a1 === a2) {
|
|
29
|
+
return true
|
|
30
|
+
}
|
|
31
|
+
if (a1.length === a2.length) {
|
|
32
|
+
for (let i = 0; i < a1.length; i++) {
|
|
33
|
+
if (a1[i] !== a2[i]) {
|
|
34
|
+
return false
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return true
|
|
38
|
+
}
|
|
39
|
+
return false
|
|
40
40
|
}
|
|
41
41
|
/**
|
|
42
42
|
* Compares two arrays for equality based on a predicate
|
|
@@ -46,24 +46,24 @@ export function arrayEquals(a1, a2) {
|
|
|
46
46
|
* @returns {boolean}
|
|
47
47
|
*/
|
|
48
48
|
export function arrayEqualsWithPredicate(a1, a2, predicate) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
49
|
+
if (a1.length === a2.length) {
|
|
50
|
+
for (let i = 0; i < a1.length; i++) {
|
|
51
|
+
if (!predicate(a1[i], a2[i])) {
|
|
52
|
+
return false
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return true
|
|
56
|
+
}
|
|
57
|
+
return false
|
|
58
58
|
}
|
|
59
59
|
export function arrayHash(array) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
60
|
+
let hash = 0
|
|
61
|
+
hash |= 0
|
|
62
|
+
for (let i = 0; i < array.length; i++) {
|
|
63
|
+
hash = (hash << 5) - hash + array[i]
|
|
64
|
+
hash |= 0 // Convert to 32bit integer
|
|
65
|
+
}
|
|
66
|
+
return hash
|
|
67
67
|
}
|
|
68
68
|
/**
|
|
69
69
|
* Remove the element from theArray if it is contained in the array.
|
|
@@ -72,26 +72,25 @@ export function arrayHash(array) {
|
|
|
72
72
|
* @return True if the element was removed, false otherwise.
|
|
73
73
|
*/
|
|
74
74
|
export function remove(theArray, elementToRemove) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
75
|
+
let i = theArray.indexOf(elementToRemove)
|
|
76
|
+
if (i !== -1) {
|
|
77
|
+
theArray.splice(i, 1)
|
|
78
|
+
return true
|
|
79
|
+
} else {
|
|
80
|
+
return false
|
|
81
|
+
}
|
|
83
82
|
}
|
|
84
83
|
/**
|
|
85
84
|
* Find all items in an array that pass the given predicate
|
|
86
85
|
*/
|
|
87
86
|
export function findAll(theArray, finder) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
87
|
+
const found = []
|
|
88
|
+
for (let element of theArray) {
|
|
89
|
+
if (finder(element)) {
|
|
90
|
+
found.push(element)
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return found
|
|
95
94
|
}
|
|
96
95
|
/**
|
|
97
96
|
* @param theArray
|
|
@@ -99,50 +98,48 @@ export function findAll(theArray, finder) {
|
|
|
99
98
|
* @return {boolean} if the element was found
|
|
100
99
|
*/
|
|
101
100
|
export function findAndRemove(theArray, finder) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
101
|
+
const index = theArray.findIndex(finder)
|
|
102
|
+
if (index !== -1) {
|
|
103
|
+
theArray.splice(index, 1)
|
|
104
|
+
return true
|
|
105
|
+
} else {
|
|
106
|
+
return false
|
|
107
|
+
}
|
|
110
108
|
}
|
|
111
109
|
export function findAllAndRemove(theArray, finder, startIndex = 0) {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
110
|
+
var removedElement = false
|
|
111
|
+
for (let i = theArray.length - 1; i >= startIndex; i--) {
|
|
112
|
+
if (finder(theArray[i])) {
|
|
113
|
+
theArray.splice(i, 1)
|
|
114
|
+
removedElement = true
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return removedElement
|
|
120
118
|
}
|
|
121
119
|
export function replace(theArray, oldElement, newElement) {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}
|
|
120
|
+
let i = theArray.indexOf(oldElement)
|
|
121
|
+
if (i !== -1) {
|
|
122
|
+
theArray.splice(i, 1, newElement)
|
|
123
|
+
return true
|
|
124
|
+
} else {
|
|
125
|
+
return false
|
|
126
|
+
}
|
|
130
127
|
}
|
|
131
128
|
/**
|
|
132
129
|
* Same as filterMap in some languages. Apply mapper and then only include non-nullable items.
|
|
133
130
|
*/
|
|
134
131
|
export function mapAndFilterNull(array, mapper) {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
132
|
+
const resultList = []
|
|
133
|
+
for (const item of array) {
|
|
134
|
+
const resultItem = mapper(item)
|
|
135
|
+
if (resultItem != null) {
|
|
136
|
+
resultList.push(resultItem)
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return resultList
|
|
143
140
|
}
|
|
144
141
|
export function filterNull(array) {
|
|
145
|
-
|
|
142
|
+
return downcast(array.filter(item => item != null))
|
|
146
143
|
}
|
|
147
144
|
/**
|
|
148
145
|
* Provides the last element of the given array.
|
|
@@ -150,62 +147,62 @@ export function filterNull(array) {
|
|
|
150
147
|
* @return The last element of the array.
|
|
151
148
|
*/
|
|
152
149
|
export function last(theArray) {
|
|
153
|
-
|
|
150
|
+
return theArray[theArray.length - 1]
|
|
154
151
|
}
|
|
155
152
|
export function isEmpty(array) {
|
|
156
|
-
|
|
153
|
+
return array.length === 0
|
|
157
154
|
}
|
|
158
155
|
export function lastThrow(array) {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
156
|
+
if (isEmpty(array)) {
|
|
157
|
+
throw new RangeError("Array is empty")
|
|
158
|
+
}
|
|
159
|
+
return neverNull(last(array))
|
|
163
160
|
}
|
|
164
161
|
export function firstThrow(array) {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
162
|
+
if (isEmpty(array)) {
|
|
163
|
+
throw new RangeError("Array is empty")
|
|
164
|
+
}
|
|
165
|
+
return array[0]
|
|
169
166
|
}
|
|
170
167
|
export function first(array) {
|
|
171
|
-
|
|
168
|
+
return array[0] || null
|
|
172
169
|
}
|
|
173
170
|
export function findLast(array, predicate) {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
171
|
+
const index = findLastIndex(array, predicate)
|
|
172
|
+
if (index !== -1) {
|
|
173
|
+
return array[index]
|
|
174
|
+
}
|
|
175
|
+
return null
|
|
179
176
|
}
|
|
180
177
|
export function findLastIndex(array, predicate) {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
178
|
+
for (let i = array.length - 1; i >= 0; i--) {
|
|
179
|
+
if (predicate(array[i])) {
|
|
180
|
+
return i
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return -1
|
|
187
184
|
}
|
|
188
185
|
export function contains(theArray, elementToCheck) {
|
|
189
|
-
|
|
186
|
+
return theArray.indexOf(elementToCheck) !== -1
|
|
190
187
|
}
|
|
191
188
|
export function addAll(array, elements) {
|
|
192
|
-
|
|
189
|
+
array.push(...elements)
|
|
193
190
|
}
|
|
194
191
|
export function removeAll(array, elements) {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
192
|
+
elements.forEach(element => {
|
|
193
|
+
remove(array, element)
|
|
194
|
+
})
|
|
198
195
|
}
|
|
199
196
|
/**
|
|
200
197
|
* Group an array based on the given discriminator, but each group will have only unique items
|
|
201
198
|
*/
|
|
202
199
|
export function groupByAndMapUniquely(iterable, discriminator, mapper) {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
200
|
+
const map = new Map()
|
|
201
|
+
for (let el of iterable) {
|
|
202
|
+
const key = discriminator(el)
|
|
203
|
+
getFromMap(map, key, () => new Set()).add(mapper(el))
|
|
204
|
+
}
|
|
205
|
+
return map
|
|
209
206
|
}
|
|
210
207
|
/**
|
|
211
208
|
* convert an Array of T's into a Map of Arrays of E's by
|
|
@@ -217,12 +214,12 @@ export function groupByAndMapUniquely(iterable, discriminator, mapper) {
|
|
|
217
214
|
* @returns {Map<R, Array<E>>}
|
|
218
215
|
*/
|
|
219
216
|
export function groupByAndMap(iterable, discriminator, mapper) {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
217
|
+
const map = new Map()
|
|
218
|
+
for (let el of iterable) {
|
|
219
|
+
const key = discriminator(el)
|
|
220
|
+
getFromMap(map, key, () => []).push(mapper(el))
|
|
221
|
+
}
|
|
222
|
+
return map
|
|
226
223
|
}
|
|
227
224
|
/**
|
|
228
225
|
* Group array elements based on keys produced by a discriminator
|
|
@@ -231,7 +228,7 @@ export function groupByAndMap(iterable, discriminator, mapper) {
|
|
|
231
228
|
* @returns {NodeJS.Global.Map<R, Array<T>>}
|
|
232
229
|
*/
|
|
233
230
|
export function groupBy(iterable, discriminator) {
|
|
234
|
-
|
|
231
|
+
return groupByAndMap(iterable, discriminator, identity)
|
|
235
232
|
}
|
|
236
233
|
/**
|
|
237
234
|
* split an array into chunks of a given size.
|
|
@@ -241,22 +238,22 @@ export function groupBy(iterable, discriminator) {
|
|
|
241
238
|
* @returns {Array<Array<T>>}
|
|
242
239
|
*/
|
|
243
240
|
export function splitInChunks(chunkSize, array) {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
241
|
+
if (chunkSize < 1) {
|
|
242
|
+
return []
|
|
243
|
+
}
|
|
244
|
+
let chunkNum = 0
|
|
245
|
+
const chunks = []
|
|
246
|
+
let end
|
|
247
|
+
do {
|
|
248
|
+
let start = chunkNum * chunkSize
|
|
249
|
+
end = start + chunkSize
|
|
250
|
+
chunks[chunkNum] = array.slice(start, end)
|
|
251
|
+
chunkNum++
|
|
252
|
+
} while (end < array.length)
|
|
253
|
+
return chunks
|
|
257
254
|
}
|
|
258
255
|
export function flat(arrays) {
|
|
259
|
-
|
|
256
|
+
return arrays.flat()
|
|
260
257
|
}
|
|
261
258
|
/**
|
|
262
259
|
* Maps an array into a nested array and then flattens it
|
|
@@ -265,12 +262,12 @@ export function flat(arrays) {
|
|
|
265
262
|
* @returns {T|*[]}
|
|
266
263
|
*/
|
|
267
264
|
export function flatMap(array, mapper) {
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
265
|
+
const result = []
|
|
266
|
+
for (const item of array) {
|
|
267
|
+
const mapped = mapper(item)
|
|
268
|
+
result.push(...mapped)
|
|
269
|
+
}
|
|
270
|
+
return result
|
|
274
271
|
}
|
|
275
272
|
/**
|
|
276
273
|
* Inserts element into the sorted array. Will find <b>the last</b> matching position.
|
|
@@ -282,41 +279,39 @@ export function flatMap(array, mapper) {
|
|
|
282
279
|
* @param replaceIf identity comparison for replacement
|
|
283
280
|
*/
|
|
284
281
|
export function insertIntoSortedArray(element, array, comparator, replaceIf = () => false) {
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
// This also handles empty array
|
|
302
|
-
array.splice(i, 0, element);
|
|
282
|
+
let i = 0
|
|
283
|
+
while (i < array.length) {
|
|
284
|
+
const compareResult = comparator(array[i], element)
|
|
285
|
+
// We need to check for replacement for each element that is equal or we might miss it
|
|
286
|
+
if (compareResult === 0 && replaceIf(element, array[i])) {
|
|
287
|
+
array.splice(i, 1, element)
|
|
288
|
+
return
|
|
289
|
+
} else if (compareResult <= 0) {
|
|
290
|
+
// We continue searching until the last suitable position
|
|
291
|
+
i++
|
|
292
|
+
} else {
|
|
293
|
+
break
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
// This also handles empty array
|
|
297
|
+
array.splice(i, 0, element)
|
|
303
298
|
}
|
|
304
299
|
export function zip(arr1, arr2) {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
300
|
+
const zipped = []
|
|
301
|
+
for (let i = 0; i < Math.min(arr1.length, arr2.length); i++) {
|
|
302
|
+
zipped.push([arr1[i], arr2[i]])
|
|
303
|
+
}
|
|
304
|
+
return zipped
|
|
310
305
|
}
|
|
311
306
|
export function deduplicate(arr, comp = (a, b) => a === b) {
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
307
|
+
const deduplicated = []
|
|
308
|
+
arr.forEach(a => {
|
|
309
|
+
const isDuplicate = deduplicated.some(b => comp(a, b))
|
|
310
|
+
if (!isDuplicate) {
|
|
311
|
+
deduplicated.push(a)
|
|
312
|
+
}
|
|
313
|
+
})
|
|
314
|
+
return deduplicated
|
|
320
315
|
}
|
|
321
316
|
/**
|
|
322
317
|
* http://jsfiddle.net/aryzhov/pkfst550/
|
|
@@ -333,36 +328,33 @@ export function deduplicate(arr, comp = (a, b) => a === b) {
|
|
|
333
328
|
* the returned value can be the index of any one of the equal elements.
|
|
334
329
|
*/
|
|
335
330
|
export function binarySearch(ar, el, compare_fn) {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
}
|
|
351
|
-
return -m - 1;
|
|
331
|
+
var m = 0
|
|
332
|
+
var n = ar.length - 1
|
|
333
|
+
while (m <= n) {
|
|
334
|
+
var k = (n + m) >> 1
|
|
335
|
+
var cmp = compare_fn(el, ar[k])
|
|
336
|
+
if (cmp > 0) {
|
|
337
|
+
m = k + 1
|
|
338
|
+
} else if (cmp < 0) {
|
|
339
|
+
n = k - 1
|
|
340
|
+
} else {
|
|
341
|
+
return k
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
return -m - 1
|
|
352
345
|
}
|
|
353
346
|
export function lastIndex(array) {
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
}
|
|
347
|
+
if (array.length === 0) {
|
|
348
|
+
return 0
|
|
349
|
+
} else {
|
|
350
|
+
return array.length - 1
|
|
351
|
+
}
|
|
360
352
|
}
|
|
361
353
|
/**
|
|
362
354
|
* All of the elements in all of the arguments combined, and deduplicated
|
|
363
355
|
*/
|
|
364
356
|
export function union(...iterables) {
|
|
365
|
-
|
|
357
|
+
return new Set(...iterables.map(iterable => Array.from(iterable)))
|
|
366
358
|
}
|
|
367
359
|
/**
|
|
368
360
|
* return a new array containing every item from array1 that isn't in array2
|
|
@@ -372,7 +364,7 @@ export function union(...iterables) {
|
|
|
372
364
|
* @returns {Array<$NonMaybeType<T>>|Array<T>}
|
|
373
365
|
*/
|
|
374
366
|
export function difference(array1, array2, compare = (a, b) => a === b) {
|
|
375
|
-
|
|
367
|
+
return array1.filter(element1 => !array2.some(element2 => compare(element1, element2)))
|
|
376
368
|
}
|
|
377
369
|
/**
|
|
378
370
|
* Returns a set with elements that are *not* in both sets.
|
|
@@ -380,18 +372,18 @@ export function difference(array1, array2, compare = (a, b) => a === b) {
|
|
|
380
372
|
* {a, b, c} △ {b, c, d} == {a, d}
|
|
381
373
|
*/
|
|
382
374
|
export function symmetricDifference(set1, set2) {
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
375
|
+
const diff = new Set()
|
|
376
|
+
for (const el of set1) {
|
|
377
|
+
if (!set2.has(el)) {
|
|
378
|
+
diff.add(el)
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
for (const el of set2) {
|
|
382
|
+
if (!set1.has(el)) {
|
|
383
|
+
diff.add(el)
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
return diff
|
|
395
387
|
}
|
|
396
388
|
/**
|
|
397
389
|
* Splits an array into two based on a predicate, where elements that match the predicate go into the left side
|
|
@@ -399,17 +391,16 @@ export function symmetricDifference(set1, set2) {
|
|
|
399
391
|
* @param predicate
|
|
400
392
|
*/
|
|
401
393
|
export function partition(array, predicate) {
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
return [left, right];
|
|
394
|
+
const left = []
|
|
395
|
+
const right = []
|
|
396
|
+
for (let item of array) {
|
|
397
|
+
if (predicate(item)) {
|
|
398
|
+
left.push(item)
|
|
399
|
+
} else {
|
|
400
|
+
right.push(item)
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
return [left, right]
|
|
413
404
|
}
|
|
414
405
|
/**
|
|
415
406
|
* like partition(), but async
|
|
@@ -418,13 +409,13 @@ export function partition(array, predicate) {
|
|
|
418
409
|
* @param predicate
|
|
419
410
|
*/
|
|
420
411
|
export async function partitionAsync(array, predicate) {
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
412
|
+
const mask = await Promise.all(array.map(predicate))
|
|
413
|
+
const [left, right] = partition(zip(mask, array), item => item[0])
|
|
414
|
+
return [left.map(i => i[1]), right.map(i => i[1])]
|
|
424
415
|
}
|
|
425
416
|
/**
|
|
426
417
|
* Create an array with n elements by calling the provided factory
|
|
427
418
|
*/
|
|
428
419
|
export function arrayOf(n, factory) {
|
|
429
|
-
|
|
420
|
+
return numberRange(0, n - 1).map(factory)
|
|
430
421
|
}
|
package/dist/AsyncResult.d.ts
CHANGED
|
@@ -1,23 +1,25 @@
|
|
|
1
1
|
declare type StatePending<T> = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
2
|
+
status: "pending"
|
|
3
|
+
}
|
|
5
4
|
declare type StateComplete<T> = {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
5
|
+
status: "complete"
|
|
6
|
+
result: T
|
|
7
|
+
}
|
|
9
8
|
declare type StateFailure = {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
declare type AsyncResultState<T> = StatePending<T> | StateComplete<T> | StateFailure
|
|
9
|
+
status: "failure"
|
|
10
|
+
error: any
|
|
11
|
+
}
|
|
12
|
+
declare type AsyncResultState<T> = StatePending<T> | StateComplete<T> | StateFailure
|
|
13
|
+
declare type PromiseCallback<T> = (resolve: (value: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void
|
|
14
14
|
/**
|
|
15
15
|
* Represents a resource that is either not ready, ready, or error
|
|
16
16
|
* Sort of fills a similar role to LazyLoaded, usage is more verbose but also more typesafe. maybe this should be reconciled.
|
|
17
17
|
*/
|
|
18
|
-
export declare class AsyncResult<T> {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
export declare class AsyncResult<T> extends Promise<T> {
|
|
19
|
+
private _state
|
|
20
|
+
constructor(promiseOrCallback: PromiseCallback<T> | Promise<T>)
|
|
21
|
+
state(): Readonly<AsyncResultState<T>>
|
|
22
|
+
result(): T | null
|
|
23
|
+
static completed<T>(value: T): AsyncResult<T>
|
|
22
24
|
}
|
|
23
|
-
export {}
|
|
25
|
+
export {}
|