lib0 0.2.42 → 0.2.45
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 +128 -72
- package/bin/gendocs.js +1 -1
- package/cache.d.ts +51 -0
- package/cache.d.ts.map +1 -0
- package/cache.js +197 -0
- package/cache.test.d.ts +3 -0
- package/cache.test.d.ts.map +1 -0
- package/component.d.ts +4 -1
- package/component.d.ts.map +1 -1
- package/component.js +4 -1
- package/diff.d.ts +5 -0
- package/diff.d.ts.map +1 -1
- package/diff.js +47 -10
- package/diff.test.d.ts +1 -0
- package/diff.test.d.ts.map +1 -1
- package/dist/{broadcastchannel-8a61b21a.cjs → broadcastchannel-7da37795.cjs} +2 -2
- package/dist/{broadcastchannel-8a61b21a.cjs.map → broadcastchannel-7da37795.cjs.map} +1 -1
- package/dist/broadcastchannel.cjs +5 -5
- package/dist/{buffer-ac2cdedf.cjs → buffer-b0dea3b0.cjs} +4 -4
- package/dist/{buffer-ac2cdedf.cjs.map → buffer-b0dea3b0.cjs.map} +1 -1
- package/dist/buffer.cjs +4 -4
- package/dist/cache.cjs +205 -0
- package/dist/cache.cjs.map +1 -0
- package/dist/cache.d.ts +51 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.test.d.ts +3 -0
- package/dist/cache.test.d.ts.map +1 -0
- package/dist/component.cjs +7 -4
- package/dist/component.cjs.map +1 -1
- package/dist/component.d.ts +4 -1
- package/dist/component.d.ts.map +1 -1
- package/dist/decoding.cjs +4 -4
- package/dist/{diff-75787d87.cjs → diff-233747fa.cjs} +51 -12
- package/dist/diff-233747fa.cjs.map +1 -0
- package/dist/diff.cjs +2 -1
- package/dist/diff.cjs.map +1 -1
- package/dist/diff.d.ts +5 -0
- package/dist/diff.d.ts.map +1 -1
- package/dist/diff.test.d.ts +1 -0
- package/dist/diff.test.d.ts.map +1 -1
- package/dist/dom.d.ts.map +1 -1
- package/dist/encoding.cjs +4 -4
- package/dist/{environment-7e2ffaea.cjs → environment-60b83194.cjs} +2 -2
- package/dist/{environment-7e2ffaea.cjs.map → environment-60b83194.cjs.map} +1 -1
- package/dist/environment.cjs +2 -2
- package/dist/{error-55a9a8c8.cjs → error-873c9cbf.cjs} +4 -4
- package/dist/error-873c9cbf.cjs.map +1 -0
- package/dist/error.cjs +1 -1
- package/dist/error.d.ts.map +1 -1
- package/dist/index.cjs +13 -13
- package/dist/{indexeddb-44227700.cjs → indexeddb-5b4b0e13.cjs} +27 -25
- package/dist/indexeddb-5b4b0e13.cjs.map +1 -0
- package/dist/indexeddb.cjs +3 -3
- package/dist/indexeddb.d.ts +2 -2
- package/dist/indexeddb.d.ts.map +1 -1
- package/dist/isomorphic.cjs +2 -6
- package/dist/isomorphic.cjs.map +1 -1
- package/dist/list.cjs +172 -0
- package/dist/list.cjs.map +1 -0
- package/dist/list.d.ts +33 -0
- package/dist/list.d.ts.map +1 -0
- package/dist/list.test.d.ts +4 -0
- package/dist/list.test.d.ts.map +1 -0
- package/dist/{logging-7cc36806.cjs → logging-f6d41f58.cjs} +2 -2
- package/dist/{logging-7cc36806.cjs.map → logging-f6d41f58.cjs.map} +1 -1
- package/dist/logging.cjs +3 -3
- package/dist/{number-24f1eabe.cjs → number-e62129bc.cjs} +5 -2
- package/dist/number-e62129bc.cjs.map +1 -0
- package/dist/number.cjs +2 -1
- package/dist/number.cjs.map +1 -1
- package/dist/number.d.ts +1 -0
- package/dist/number.d.ts.map +1 -1
- package/dist/observable.cjs +1 -1
- package/dist/{prng-695120cc.cjs → prng-25602bac.cjs} +3 -3
- package/dist/{prng-695120cc.cjs.map → prng-25602bac.cjs.map} +1 -1
- package/dist/prng.cjs +5 -5
- package/dist/{promise-f0a086b2.cjs → promise-1a9fe712.cjs} +10 -1
- package/dist/{promise-f0a086b2.cjs.map → promise-1a9fe712.cjs.map} +1 -1
- package/dist/promise.cjs +2 -1
- package/dist/promise.cjs.map +1 -1
- package/dist/promise.d.ts +1 -0
- package/dist/promise.d.ts.map +1 -1
- package/dist/queue.cjs +3 -0
- package/dist/queue.cjs.map +1 -1
- package/dist/queue.d.ts.map +1 -1
- package/dist/queue.test.d.ts.map +1 -1
- package/dist/set-b596ef38.cjs +49 -0
- package/dist/set-b596ef38.cjs.map +1 -0
- package/dist/set.cjs +3 -1
- package/dist/set.cjs.map +1 -1
- package/dist/set.d.ts +2 -0
- package/dist/set.d.ts.map +1 -1
- package/dist/set.test.d.ts +2 -0
- package/dist/set.test.d.ts.map +1 -1
- package/dist/{string-f3c3d805.cjs → string-ad04f734.cjs} +12 -2
- package/dist/{string-f3c3d805.cjs.map → string-ad04f734.cjs.map} +1 -1
- package/dist/string.cjs +3 -4
- package/dist/string.cjs.map +1 -1
- package/dist/string.d.ts +1 -0
- package/dist/string.d.ts.map +1 -1
- package/dist/string.test.d.ts +1 -0
- package/dist/string.test.d.ts.map +1 -1
- package/dist/test.cjs +779 -125
- package/dist/test.cjs.map +1 -1
- package/dist/test.js +780 -126
- package/dist/test.js.map +1 -1
- package/dist/testing.cjs +12 -9
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.ts.map +1 -1
- package/dist/{websocket-bfe7f545.cjs → websocket-08bd4c7b.cjs} +1 -1
- package/dist/{websocket-bfe7f545.cjs.map → websocket-08bd4c7b.cjs.map} +1 -1
- package/dist/websocket.cjs +2 -2
- package/dist/websocket.d.ts +1 -1
- package/dist/websocket.d.ts.map +1 -1
- package/dom.d.ts.map +1 -1
- package/error.d.ts.map +1 -1
- package/error.js +3 -3
- package/indexeddb.d.ts +2 -2
- package/indexeddb.d.ts.map +1 -1
- package/indexeddb.js +25 -23
- package/list.d.ts +33 -0
- package/list.d.ts.map +1 -0
- package/list.js +155 -0
- package/list.test.d.ts +4 -0
- package/list.test.d.ts.map +1 -0
- package/number.d.ts +1 -0
- package/number.d.ts.map +1 -1
- package/number.js +1 -0
- package/package.json +15 -3
- package/promise.d.ts +1 -0
- package/promise.d.ts.map +1 -1
- package/promise.js +7 -0
- package/queue.d.ts.map +1 -1
- package/queue.js +3 -0
- package/queue.test.d.ts.map +1 -1
- package/set.d.ts +2 -0
- package/set.d.ts.map +1 -1
- package/set.js +18 -0
- package/set.test.d.ts +2 -0
- package/set.test.d.ts.map +1 -1
- package/string.d.ts +1 -0
- package/string.d.ts.map +1 -1
- package/string.js +8 -0
- package/string.test.d.ts +1 -0
- package/string.test.d.ts.map +1 -1
- package/test.js +7 -1
- package/testing.d.ts.map +1 -1
- package/testing.js +5 -2
- package/websocket.d.ts +1 -1
- package/websocket.d.ts.map +1 -1
- package/dist/diff-75787d87.cjs.map +0 -1
- package/dist/error-55a9a8c8.cjs.map +0 -1
- package/dist/indexeddb-44227700.cjs.map +0 -1
- package/dist/number-24f1eabe.cjs.map +0 -1
- package/dist/set-7ae96d21.cjs +0 -27
- package/dist/set-7ae96d21.cjs.map +0 -1
package/dist/test.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*
|
|
16
16
|
* @function
|
|
17
17
|
*/
|
|
18
|
-
const create$
|
|
18
|
+
const create$a = () => new Map();
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* Copy a Map object into a fresh Map object.
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
* @return {Map<X,Y>}
|
|
27
27
|
*/
|
|
28
28
|
const copy = m => {
|
|
29
|
-
const r = create$
|
|
29
|
+
const r = create$a();
|
|
30
30
|
m.forEach((v, k) => { r.set(k, v); });
|
|
31
31
|
return r
|
|
32
32
|
};
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
* @param {function():T} createT
|
|
47
47
|
* @return {T}
|
|
48
48
|
*/
|
|
49
|
-
const setIfUndefined = (map, key, createT) => {
|
|
49
|
+
const setIfUndefined$1 = (map, key, createT) => {
|
|
50
50
|
let set = map.get(key);
|
|
51
51
|
if (set === undefined) {
|
|
52
52
|
map.set(key, set = createT());
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
* @param {function(V,K):R} f
|
|
66
66
|
* @return {Array<R>}
|
|
67
67
|
*/
|
|
68
|
-
const map$
|
|
68
|
+
const map$4 = (m, f) => {
|
|
69
69
|
const res = [];
|
|
70
70
|
for (const [key, value] of m) {
|
|
71
71
|
res.push(f(value, key));
|
|
@@ -188,6 +188,14 @@
|
|
|
188
188
|
/* istanbul ignore next */
|
|
189
189
|
const decodeUtf8 = utf8TextDecoder ? _decodeUtf8Native : _decodeUtf8Polyfill;
|
|
190
190
|
|
|
191
|
+
/**
|
|
192
|
+
* @param {string} str The initial string
|
|
193
|
+
* @param {number} index Starting position
|
|
194
|
+
* @param {number} remove Number of characters to remove
|
|
195
|
+
* @param {string} insert New content to insert
|
|
196
|
+
*/
|
|
197
|
+
const splice = (str, index, remove, insert = '') => str.slice(0, index) + insert + str.slice(index + remove);
|
|
198
|
+
|
|
191
199
|
/**
|
|
192
200
|
* Often used conditions.
|
|
193
201
|
*
|
|
@@ -288,7 +296,7 @@
|
|
|
288
296
|
const computeParams = () => {
|
|
289
297
|
if (params === undefined) {
|
|
290
298
|
if (isNode) {
|
|
291
|
-
params = create$
|
|
299
|
+
params = create$a();
|
|
292
300
|
const pargs = process.argv;
|
|
293
301
|
let currParamName = null;
|
|
294
302
|
/* istanbul ignore next */
|
|
@@ -311,7 +319,7 @@
|
|
|
311
319
|
}
|
|
312
320
|
// in ReactNative for example this would not be true (unless connected to the Remote Debugger)
|
|
313
321
|
} else if (typeof location === 'object') {
|
|
314
|
-
params = create$
|
|
322
|
+
params = create$a()
|
|
315
323
|
// eslint-disable-next-line no-undef
|
|
316
324
|
;(location.search || '?').slice(1).split('&').forEach(kv => {
|
|
317
325
|
if (kv.length !== 0) {
|
|
@@ -321,7 +329,7 @@
|
|
|
321
329
|
}
|
|
322
330
|
});
|
|
323
331
|
} else {
|
|
324
|
-
params = create$
|
|
332
|
+
params = create$a();
|
|
325
333
|
}
|
|
326
334
|
}
|
|
327
335
|
return params
|
|
@@ -371,7 +379,7 @@
|
|
|
371
379
|
*
|
|
372
380
|
* @return {Symbol}
|
|
373
381
|
*/
|
|
374
|
-
const create$
|
|
382
|
+
const create$9 = Symbol;
|
|
375
383
|
|
|
376
384
|
/**
|
|
377
385
|
* Working with value pairs.
|
|
@@ -399,7 +407,7 @@
|
|
|
399
407
|
* @param {R} right
|
|
400
408
|
* @return {Pair<L,R>}
|
|
401
409
|
*/
|
|
402
|
-
const create$
|
|
410
|
+
const create$8 = (left, right) => new Pair(left, right);
|
|
403
411
|
|
|
404
412
|
/**
|
|
405
413
|
* @template L,R
|
|
@@ -422,7 +430,7 @@
|
|
|
422
430
|
* @param {function(L, R):X} f
|
|
423
431
|
* @return {Array<X>}
|
|
424
432
|
*/
|
|
425
|
-
const map$
|
|
433
|
+
const map$3 = (arr, f) => arr.map(p => f(p.left, p.right));
|
|
426
434
|
|
|
427
435
|
/* eslint-env browser */
|
|
428
436
|
|
|
@@ -541,7 +549,7 @@
|
|
|
541
549
|
* @return {string}
|
|
542
550
|
*/
|
|
543
551
|
/* istanbul ignore next */
|
|
544
|
-
const mapToStyleString = m => map$
|
|
552
|
+
const mapToStyleString = m => map$4(m, (value, key) => `${key}:${value};`).join('');
|
|
545
553
|
|
|
546
554
|
/**
|
|
547
555
|
* @param {Node} parent
|
|
@@ -551,6 +559,14 @@
|
|
|
551
559
|
/* istanbul ignore next */
|
|
552
560
|
const appendChild = (parent, child) => parent.appendChild(child);
|
|
553
561
|
|
|
562
|
+
doc.ELEMENT_NODE;
|
|
563
|
+
doc.TEXT_NODE;
|
|
564
|
+
doc.CDATA_SECTION_NODE;
|
|
565
|
+
doc.COMMENT_NODE;
|
|
566
|
+
doc.DOCUMENT_NODE;
|
|
567
|
+
doc.DOCUMENT_TYPE_NODE;
|
|
568
|
+
doc.DOCUMENT_FRAGMENT_NODE;
|
|
569
|
+
|
|
554
570
|
/**
|
|
555
571
|
* JSON utility functions.
|
|
556
572
|
*
|
|
@@ -855,7 +871,7 @@
|
|
|
855
871
|
/**
|
|
856
872
|
* @return {Object<string,any>} obj
|
|
857
873
|
*/
|
|
858
|
-
const create$
|
|
874
|
+
const create$7 = () => Object.create(null);
|
|
859
875
|
|
|
860
876
|
/**
|
|
861
877
|
* Object.assign
|
|
@@ -883,7 +899,7 @@
|
|
|
883
899
|
* @param {function(any,string):R} f
|
|
884
900
|
* @return {Array<R>}
|
|
885
901
|
*/
|
|
886
|
-
const map$
|
|
902
|
+
const map$2 = (obj, f) => {
|
|
887
903
|
const results = [];
|
|
888
904
|
for (const key in obj) {
|
|
889
905
|
results.push(f(obj[key], key));
|
|
@@ -1050,29 +1066,29 @@
|
|
|
1050
1066
|
* @module logging
|
|
1051
1067
|
*/
|
|
1052
1068
|
|
|
1053
|
-
const BOLD = create$
|
|
1054
|
-
const UNBOLD = create$
|
|
1055
|
-
const BLUE = create$
|
|
1056
|
-
const GREY = create$
|
|
1057
|
-
const GREEN = create$
|
|
1058
|
-
const RED = create$
|
|
1059
|
-
const PURPLE = create$
|
|
1060
|
-
const ORANGE = create$
|
|
1061
|
-
const UNCOLOR = create$
|
|
1069
|
+
const BOLD = create$9();
|
|
1070
|
+
const UNBOLD = create$9();
|
|
1071
|
+
const BLUE = create$9();
|
|
1072
|
+
const GREY = create$9();
|
|
1073
|
+
const GREEN = create$9();
|
|
1074
|
+
const RED = create$9();
|
|
1075
|
+
const PURPLE = create$9();
|
|
1076
|
+
const ORANGE = create$9();
|
|
1077
|
+
const UNCOLOR = create$9();
|
|
1062
1078
|
|
|
1063
1079
|
/**
|
|
1064
1080
|
* @type {Object<Symbol,pair.Pair<string,string>>}
|
|
1065
1081
|
*/
|
|
1066
1082
|
const _browserStyleMap = {
|
|
1067
|
-
[BOLD]: create$
|
|
1068
|
-
[UNBOLD]: create$
|
|
1069
|
-
[BLUE]: create$
|
|
1070
|
-
[GREEN]: create$
|
|
1071
|
-
[GREY]: create$
|
|
1072
|
-
[RED]: create$
|
|
1073
|
-
[PURPLE]: create$
|
|
1074
|
-
[ORANGE]: create$
|
|
1075
|
-
[UNCOLOR]: create$
|
|
1083
|
+
[BOLD]: create$8('font-weight', 'bold'),
|
|
1084
|
+
[UNBOLD]: create$8('font-weight', 'normal'),
|
|
1085
|
+
[BLUE]: create$8('color', 'blue'),
|
|
1086
|
+
[GREEN]: create$8('color', 'green'),
|
|
1087
|
+
[GREY]: create$8('color', 'grey'),
|
|
1088
|
+
[RED]: create$8('color', 'red'),
|
|
1089
|
+
[PURPLE]: create$8('color', 'purple'),
|
|
1090
|
+
[ORANGE]: create$8('color', 'orange'), // not well supported in chrome when debugging node with inspector - TODO: deprecate
|
|
1091
|
+
[UNCOLOR]: create$8('color', 'black')
|
|
1076
1092
|
};
|
|
1077
1093
|
|
|
1078
1094
|
const _nodeStyleMap = {
|
|
@@ -1095,7 +1111,7 @@
|
|
|
1095
1111
|
const computeBrowserLoggingArgs = args => {
|
|
1096
1112
|
const strBuilder = [];
|
|
1097
1113
|
const styles = [];
|
|
1098
|
-
const currentStyle = create$
|
|
1114
|
+
const currentStyle = create$a();
|
|
1099
1115
|
/**
|
|
1100
1116
|
* @type {Array<string|Object|number>}
|
|
1101
1117
|
*/
|
|
@@ -1273,7 +1289,7 @@
|
|
|
1273
1289
|
} else {
|
|
1274
1290
|
if (arg.constructor === String || arg.constructor === Number) {
|
|
1275
1291
|
// @ts-ignore
|
|
1276
|
-
const span = element('span', [create$
|
|
1292
|
+
const span = element('span', [create$8('style', mapToStyleString(currentStyle))], [text(arg)]);
|
|
1277
1293
|
if (span.innerHTML === '') {
|
|
1278
1294
|
span.innerHTML = ' ';
|
|
1279
1295
|
}
|
|
@@ -1319,10 +1335,10 @@
|
|
|
1319
1335
|
*/
|
|
1320
1336
|
group (args, collapsed = false) {
|
|
1321
1337
|
enqueue$1(() => {
|
|
1322
|
-
const triangleDown = element('span', [create$
|
|
1323
|
-
const triangleRight = element('span', [create$
|
|
1324
|
-
const content = element('div', [create$
|
|
1325
|
-
const nextContainer = element('div', [create$
|
|
1338
|
+
const triangleDown = element('span', [create$8('hidden', collapsed), create$8('style', 'color:grey;font-size:120%;')], [text('▼')]);
|
|
1339
|
+
const triangleRight = element('span', [create$8('hidden', !collapsed), create$8('style', 'color:grey;font-size:125%;')], [text('▶')]);
|
|
1340
|
+
const content = element('div', [create$8('style', `${lineStyle};padding-left:${this.depth * 10}px`)], [triangleDown, triangleRight, text(' ')].concat(_computeLineSpans(args)));
|
|
1341
|
+
const nextContainer = element('div', [create$8('hidden', collapsed)]);
|
|
1326
1342
|
const nextLine = element('div', [], [content, nextContainer]);
|
|
1327
1343
|
append(this.ccontainer, [nextLine]);
|
|
1328
1344
|
this.ccontainer = nextContainer;
|
|
@@ -1358,7 +1374,7 @@
|
|
|
1358
1374
|
*/
|
|
1359
1375
|
print (args) {
|
|
1360
1376
|
enqueue$1(() => {
|
|
1361
|
-
append(this.ccontainer, [element('div', [create$
|
|
1377
|
+
append(this.ccontainer, [element('div', [create$8('style', `${lineStyle};padding-left:${this.depth * 10}px`)], _computeLineSpans(args))]);
|
|
1362
1378
|
});
|
|
1363
1379
|
}
|
|
1364
1380
|
|
|
@@ -1375,7 +1391,7 @@
|
|
|
1375
1391
|
*/
|
|
1376
1392
|
printImg (url, height) {
|
|
1377
1393
|
enqueue$1(() => {
|
|
1378
|
-
append(this.ccontainer, [element('img', [create$
|
|
1394
|
+
append(this.ccontainer, [element('img', [create$8('src', url), create$8('height', `${round(height * 1.5)}px`)])]);
|
|
1379
1395
|
});
|
|
1380
1396
|
}
|
|
1381
1397
|
|
|
@@ -1445,11 +1461,8 @@
|
|
|
1445
1461
|
while (left < a.length && left < b.length && a[left] === b[left]) {
|
|
1446
1462
|
left++;
|
|
1447
1463
|
}
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
while (right + left < a.length && right + left < b.length && a[a.length - right - 1] === b[b.length - right - 1]) {
|
|
1451
|
-
right++;
|
|
1452
|
-
}
|
|
1464
|
+
while (right + left < a.length && right + left < b.length && a[a.length - right - 1] === b[b.length - right - 1]) {
|
|
1465
|
+
right++;
|
|
1453
1466
|
}
|
|
1454
1467
|
return {
|
|
1455
1468
|
index: left,
|
|
@@ -1458,12 +1471,6 @@
|
|
|
1458
1471
|
}
|
|
1459
1472
|
};
|
|
1460
1473
|
|
|
1461
|
-
/**
|
|
1462
|
-
* @todo Remove in favor of simpleDiffString
|
|
1463
|
-
* @deprecated
|
|
1464
|
-
*/
|
|
1465
|
-
const simpleDiff = simpleDiffString;
|
|
1466
|
-
|
|
1467
1474
|
/**
|
|
1468
1475
|
* Create a diff between two arrays. This diff implementation is highly
|
|
1469
1476
|
* efficient, but not very sophisticated.
|
|
@@ -1485,11 +1492,51 @@
|
|
|
1485
1492
|
while (left < a.length && left < b.length && compare(a[left], b[left])) {
|
|
1486
1493
|
left++;
|
|
1487
1494
|
}
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1495
|
+
while (right + left < a.length && right + left < b.length && compare(a[a.length - right - 1], b[b.length - right - 1])) {
|
|
1496
|
+
right++;
|
|
1497
|
+
}
|
|
1498
|
+
return {
|
|
1499
|
+
index: left,
|
|
1500
|
+
remove: a.length - left - right,
|
|
1501
|
+
insert: b.slice(left, b.length - right)
|
|
1502
|
+
}
|
|
1503
|
+
};
|
|
1504
|
+
|
|
1505
|
+
/**
|
|
1506
|
+
* Diff text and try to diff at the current cursor position.
|
|
1507
|
+
*
|
|
1508
|
+
* @param {string} a
|
|
1509
|
+
* @param {string} b
|
|
1510
|
+
* @param {number} cursor This should refer to the current left cursor-range position
|
|
1511
|
+
*/
|
|
1512
|
+
const simpleDiffStringWithCursor = (a, b, cursor) => {
|
|
1513
|
+
let left = 0; // number of same characters counting from left
|
|
1514
|
+
let right = 0; // number of same characters counting from right
|
|
1515
|
+
// Iterate left to the right until we find a changed character
|
|
1516
|
+
// First iteration considers the current cursor position
|
|
1517
|
+
while (
|
|
1518
|
+
left < a.length &&
|
|
1519
|
+
left < b.length &&
|
|
1520
|
+
a[left] === b[left] &&
|
|
1521
|
+
left < cursor
|
|
1522
|
+
) {
|
|
1523
|
+
left++;
|
|
1524
|
+
}
|
|
1525
|
+
// Iterate right to the left until we find a changed character
|
|
1526
|
+
while (
|
|
1527
|
+
right + left < a.length &&
|
|
1528
|
+
right + left < b.length &&
|
|
1529
|
+
a[a.length - right - 1] === b[b.length - right - 1]
|
|
1530
|
+
) {
|
|
1531
|
+
right++;
|
|
1532
|
+
}
|
|
1533
|
+
// Try to iterate left further to the right without caring about the current cursor position
|
|
1534
|
+
while (
|
|
1535
|
+
right + left < a.length &&
|
|
1536
|
+
right + left < b.length &&
|
|
1537
|
+
a[left] === b[left]
|
|
1538
|
+
) {
|
|
1539
|
+
left++;
|
|
1493
1540
|
}
|
|
1494
1541
|
return {
|
|
1495
1542
|
index: left,
|
|
@@ -1983,7 +2030,7 @@
|
|
|
1983
2030
|
* @param {number} pos Position to which to write data
|
|
1984
2031
|
* @param {number} num Unsigned 8-bit integer
|
|
1985
2032
|
*/
|
|
1986
|
-
const set = (encoder, pos, num) => {
|
|
2033
|
+
const set$2 = (encoder, pos, num) => {
|
|
1987
2034
|
let buffer = null;
|
|
1988
2035
|
// iterate all buffers and adjust position
|
|
1989
2036
|
for (let i = 0; i < encoder.bufs.length && buffer === null; i++) {
|
|
@@ -2018,7 +2065,7 @@
|
|
|
2018
2065
|
* @param {number} pos The location where the data will be written.
|
|
2019
2066
|
* @param {number} num The number that is to be encoded.
|
|
2020
2067
|
*/
|
|
2021
|
-
const setUint8 = set;
|
|
2068
|
+
const setUint8 = set$2;
|
|
2022
2069
|
|
|
2023
2070
|
/**
|
|
2024
2071
|
* Write two bytes as an unsigned integer.
|
|
@@ -2040,8 +2087,8 @@
|
|
|
2040
2087
|
* @param {number} num The number that is to be encoded.
|
|
2041
2088
|
*/
|
|
2042
2089
|
const setUint16 = (encoder, pos, num) => {
|
|
2043
|
-
set(encoder, pos, num & BITS8);
|
|
2044
|
-
set(encoder, pos + 1, (num >>> 8) & BITS8);
|
|
2090
|
+
set$2(encoder, pos, num & BITS8);
|
|
2091
|
+
set$2(encoder, pos + 1, (num >>> 8) & BITS8);
|
|
2045
2092
|
};
|
|
2046
2093
|
|
|
2047
2094
|
/**
|
|
@@ -2082,7 +2129,7 @@
|
|
|
2082
2129
|
*/
|
|
2083
2130
|
const setUint32 = (encoder, pos, num) => {
|
|
2084
2131
|
for (let i = 0; i < 4; i++) {
|
|
2085
|
-
set(encoder, pos + i, num & BITS8);
|
|
2132
|
+
set$2(encoder, pos + i, num & BITS8);
|
|
2086
2133
|
num >>>= 8;
|
|
2087
2134
|
}
|
|
2088
2135
|
};
|
|
@@ -3385,7 +3432,7 @@
|
|
|
3385
3432
|
* @param {number} seed A positive 32bit integer. Do not use negative numbers.
|
|
3386
3433
|
* @return {PRNG}
|
|
3387
3434
|
*/
|
|
3388
|
-
const create$
|
|
3435
|
+
const create$6 = seed => new DefaultPRNG(seed);
|
|
3389
3436
|
|
|
3390
3437
|
/**
|
|
3391
3438
|
* Generates a single random bool.
|
|
@@ -3575,7 +3622,7 @@
|
|
|
3575
3622
|
* @param {function(PromiseResolve<T>,function(Error):void):any} f
|
|
3576
3623
|
* @return {Promise<T>}
|
|
3577
3624
|
*/
|
|
3578
|
-
const create$
|
|
3625
|
+
const create$5 = f => /** @type {Promise<T>} */ (new Promise(f));
|
|
3579
3626
|
|
|
3580
3627
|
/**
|
|
3581
3628
|
* @param {function(function():void,function(Error):void):void} f
|
|
@@ -3604,6 +3651,13 @@
|
|
|
3604
3651
|
*/
|
|
3605
3652
|
const resolve = res => Promise.resolve(res);
|
|
3606
3653
|
|
|
3654
|
+
/**
|
|
3655
|
+
* @template T
|
|
3656
|
+
* @param {T} res
|
|
3657
|
+
* @return {Promise<T>}
|
|
3658
|
+
*/
|
|
3659
|
+
const resolveWith = res => Promise.resolve(res);
|
|
3660
|
+
|
|
3607
3661
|
/**
|
|
3608
3662
|
* @todo Next version, reorder parameters: check, [timeout, [intervalResolution]]
|
|
3609
3663
|
*
|
|
@@ -3612,7 +3666,7 @@
|
|
|
3612
3666
|
* @param {number} [intervalResolution]
|
|
3613
3667
|
* @return {Promise<void>}
|
|
3614
3668
|
*/
|
|
3615
|
-
const until = (timeout, check, intervalResolution = 10) => create$
|
|
3669
|
+
const until = (timeout, check, intervalResolution = 10) => create$5((resolve, reject) => {
|
|
3616
3670
|
const startTime = getUnixTime();
|
|
3617
3671
|
const hasTimeout = timeout > 0;
|
|
3618
3672
|
const untilInterval = () => {
|
|
@@ -3634,7 +3688,7 @@
|
|
|
3634
3688
|
* @param {number} timeout
|
|
3635
3689
|
* @return {Promise<undefined>}
|
|
3636
3690
|
*/
|
|
3637
|
-
const wait = timeout => create$
|
|
3691
|
+
const wait = timeout => create$5((resolve, reject) => setTimeout(resolve, timeout));
|
|
3638
3692
|
|
|
3639
3693
|
/**
|
|
3640
3694
|
* Checks if an object is a promise using ducktyping.
|
|
@@ -3741,7 +3795,7 @@
|
|
|
3741
3795
|
get prng () {
|
|
3742
3796
|
/* istanbul ignore else */
|
|
3743
3797
|
if (this._prng === null) {
|
|
3744
|
-
this._prng = create$
|
|
3798
|
+
this._prng = create$6(this.seed);
|
|
3745
3799
|
}
|
|
3746
3800
|
return this._prng
|
|
3747
3801
|
}
|
|
@@ -3782,6 +3836,9 @@
|
|
|
3782
3836
|
const times = [];
|
|
3783
3837
|
const start = performance.now();
|
|
3784
3838
|
let lastTime = start;
|
|
3839
|
+
/**
|
|
3840
|
+
* @type {any}
|
|
3841
|
+
*/
|
|
3785
3842
|
let err = null;
|
|
3786
3843
|
performance.mark(`${name}-start`);
|
|
3787
3844
|
do {
|
|
@@ -4002,7 +4059,7 @@
|
|
|
4002
4059
|
*/
|
|
4003
4060
|
const compareStrings = (a, b, m = 'Strings match') => {
|
|
4004
4061
|
if (a !== b) {
|
|
4005
|
-
const diff =
|
|
4062
|
+
const diff = simpleDiffString(a, b);
|
|
4006
4063
|
print(GREY, a.slice(0, diff.index), RED, a.slice(diff.index, diff.remove), GREEN, diff.insert, GREY, a.slice(diff.index + diff.remove));
|
|
4007
4064
|
fail(m);
|
|
4008
4065
|
}
|
|
@@ -4165,7 +4222,7 @@
|
|
|
4165
4222
|
* @param {Object<string, Object<string, function(TestCase):void|Promise<any>>>} tests
|
|
4166
4223
|
*/
|
|
4167
4224
|
const runTests = async tests => {
|
|
4168
|
-
const numberOfTests = map$
|
|
4225
|
+
const numberOfTests = map$2(tests, mod => map$2(mod, f => /* istanbul ignore next */ f ? 1 : 0).reduce(add$1, 0)).reduce(add$1, 0);
|
|
4169
4226
|
let successfulTests = 0;
|
|
4170
4227
|
let testnumber = 0;
|
|
4171
4228
|
const start = performance.now();
|
|
@@ -4331,12 +4388,22 @@
|
|
|
4331
4388
|
}
|
|
4332
4389
|
};
|
|
4333
4390
|
|
|
4391
|
+
/**
|
|
4392
|
+
* @param {t.TestCase} tc
|
|
4393
|
+
*/
|
|
4394
|
+
const testSplice = tc => {
|
|
4395
|
+
const initial = 'xyz';
|
|
4396
|
+
compareStrings(splice(initial, 0, 2), 'z');
|
|
4397
|
+
compareStrings(splice(initial, 0, 2, 'u'), 'uz');
|
|
4398
|
+
};
|
|
4399
|
+
|
|
4334
4400
|
var string = /*#__PURE__*/Object.freeze({
|
|
4335
4401
|
__proto__: null,
|
|
4336
4402
|
testLowercaseTransformation: testLowercaseTransformation,
|
|
4337
4403
|
testRepeatStringUtf8Encoding: testRepeatStringUtf8Encoding,
|
|
4338
4404
|
testRepeatStringUtf8Decoding: testRepeatStringUtf8Decoding,
|
|
4339
|
-
testBomEncodingDecoding: testBomEncodingDecoding
|
|
4405
|
+
testBomEncodingDecoding: testBomEncodingDecoding,
|
|
4406
|
+
testSplice: testSplice
|
|
4340
4407
|
});
|
|
4341
4408
|
|
|
4342
4409
|
/* global BigInt */
|
|
@@ -5046,6 +5113,7 @@
|
|
|
5046
5113
|
function runDiffTest (a, b, expected) {
|
|
5047
5114
|
const result = simpleDiffString(a, b);
|
|
5048
5115
|
compare(result, expected);
|
|
5116
|
+
compare(result, simpleDiffStringWithCursor(a, b, a.length)); // check that the withCursor approach returns the same result
|
|
5049
5117
|
const arrResult = simpleDiffArray(a.split(''), b.split(''));
|
|
5050
5118
|
compare(arrResult, assign({}, result, { insert: result.insert.split('') }));
|
|
5051
5119
|
}
|
|
@@ -5071,10 +5139,43 @@
|
|
|
5071
5139
|
const a = word(tc.prng);
|
|
5072
5140
|
const b = word(tc.prng);
|
|
5073
5141
|
const change = simpleDiffString(a, b);
|
|
5074
|
-
const recomposed =
|
|
5142
|
+
const recomposed = splice(a, change.index, change.remove, change.insert);
|
|
5075
5143
|
compareStrings(recomposed, b);
|
|
5076
5144
|
};
|
|
5077
5145
|
|
|
5146
|
+
/**
|
|
5147
|
+
* @param {t.TestCase} tc
|
|
5148
|
+
*/
|
|
5149
|
+
const testSimpleDiffWithCursor = tc => {
|
|
5150
|
+
const initial = 'Hello WorldHello World';
|
|
5151
|
+
const expected = 'Hello World';
|
|
5152
|
+
{
|
|
5153
|
+
const change = simpleDiffStringWithCursor(initial, 'Hello World', 0); // should delete the first hello world
|
|
5154
|
+
compare(change, { insert: '', remove: 11, index: 0 });
|
|
5155
|
+
const recomposed = splice(initial, change.index, change.remove, change.insert);
|
|
5156
|
+
compareStrings(expected, recomposed);
|
|
5157
|
+
}
|
|
5158
|
+
{
|
|
5159
|
+
const change = simpleDiffStringWithCursor(initial, 'Hello World', 11); // should delete the second hello world
|
|
5160
|
+
compare(change, { insert: '', remove: 11, index: 11 });
|
|
5161
|
+
const recomposedSecond = splice(initial, change.index, change.remove, change.insert);
|
|
5162
|
+
compareStrings(recomposedSecond, expected);
|
|
5163
|
+
}
|
|
5164
|
+
{
|
|
5165
|
+
const change = simpleDiffStringWithCursor(initial, 'Hello World', 5); // should delete in the midst of Hello World
|
|
5166
|
+
compare(change, { insert: '', remove: 11, index: 5 });
|
|
5167
|
+
const recomposed = splice(initial, change.index, change.remove, change.insert);
|
|
5168
|
+
compareStrings(expected, recomposed);
|
|
5169
|
+
}
|
|
5170
|
+
{
|
|
5171
|
+
const initial = 'Hello my World';
|
|
5172
|
+
const change = simpleDiffStringWithCursor(initial, 'Hello World', 0); // Should delete after the current cursor position
|
|
5173
|
+
compare(change, { insert: '', remove: 3, index: 5 });
|
|
5174
|
+
const recomposed = splice(initial, change.index, change.remove, change.insert);
|
|
5175
|
+
compareStrings(expected, recomposed);
|
|
5176
|
+
}
|
|
5177
|
+
};
|
|
5178
|
+
|
|
5078
5179
|
/**
|
|
5079
5180
|
* @param {t.TestCase} tc
|
|
5080
5181
|
*/
|
|
@@ -5090,6 +5191,7 @@
|
|
|
5090
5191
|
__proto__: null,
|
|
5091
5192
|
testDiffing: testDiffing,
|
|
5092
5193
|
testRepeatDiffing: testRepeatDiffing,
|
|
5194
|
+
testSimpleDiffWithCursor: testSimpleDiffWithCursor,
|
|
5093
5195
|
testArrayDiffing: testArrayDiffing
|
|
5094
5196
|
});
|
|
5095
5197
|
|
|
@@ -5102,7 +5204,7 @@
|
|
|
5102
5204
|
compare([1, 2], [1, 2], 'simple compare (array)');
|
|
5103
5205
|
compare({ a: [1, 2] }, { a: [1, 2] }, 'simple compare nested');
|
|
5104
5206
|
compare(new Set(['3', 1234]), new Set(['3', 1234]), 'compare Sets');
|
|
5105
|
-
const map1 = create$
|
|
5207
|
+
const map1 = create$a();
|
|
5106
5208
|
map1.set(1, 2);
|
|
5107
5209
|
map1.set('x', {});
|
|
5108
5210
|
map1.set(98, 'tst');
|
|
@@ -5206,7 +5308,7 @@
|
|
|
5206
5308
|
};
|
|
5207
5309
|
|
|
5208
5310
|
const testAsync = async () => {
|
|
5209
|
-
await measureTimeAsync('time', () => create$
|
|
5311
|
+
await measureTimeAsync('time', () => create$5(r => setTimeout(r)));
|
|
5210
5312
|
await groupAsync('some description', () => wait(1));
|
|
5211
5313
|
};
|
|
5212
5314
|
|
|
@@ -5234,23 +5336,32 @@
|
|
|
5234
5336
|
* @module error
|
|
5235
5337
|
*/
|
|
5236
5338
|
|
|
5339
|
+
/* istanbul ignore next */
|
|
5237
5340
|
/**
|
|
5238
5341
|
* @param {string} s
|
|
5239
5342
|
* @return {Error}
|
|
5240
5343
|
*/
|
|
5344
|
+
const create$4 = s => new Error(s);
|
|
5345
|
+
|
|
5241
5346
|
/* istanbul ignore next */
|
|
5242
|
-
|
|
5347
|
+
/**
|
|
5348
|
+
* @throws {Error}
|
|
5349
|
+
* @return {never}
|
|
5350
|
+
*/
|
|
5351
|
+
const unexpectedCase = () => {
|
|
5352
|
+
throw create$4('Unexpected case')
|
|
5353
|
+
};
|
|
5243
5354
|
|
|
5244
5355
|
/* eslint-env browser */
|
|
5245
5356
|
|
|
5357
|
+
/* istanbul ignore next */
|
|
5246
5358
|
/**
|
|
5247
5359
|
* IDB Request to Promise transformer
|
|
5248
5360
|
*
|
|
5249
5361
|
* @param {IDBRequest} request
|
|
5250
5362
|
* @return {Promise<any>}
|
|
5251
5363
|
*/
|
|
5252
|
-
|
|
5253
|
-
const rtop = request => create$2((resolve, reject) => {
|
|
5364
|
+
const rtop = request => create$5((resolve, reject) => {
|
|
5254
5365
|
/* istanbul ignore next */
|
|
5255
5366
|
// @ts-ignore
|
|
5256
5367
|
request.onerror = event => reject(new Error(event.target.error));
|
|
@@ -5261,13 +5372,13 @@
|
|
|
5261
5372
|
request.onsuccess = event => resolve(event.target.result);
|
|
5262
5373
|
});
|
|
5263
5374
|
|
|
5375
|
+
/* istanbul ignore next */
|
|
5264
5376
|
/**
|
|
5265
5377
|
* @param {string} name
|
|
5266
5378
|
* @param {function(IDBDatabase):any} initDB Called when the database is first created
|
|
5267
5379
|
* @return {Promise<IDBDatabase>}
|
|
5268
5380
|
*/
|
|
5269
|
-
|
|
5270
|
-
const openDB = (name, initDB) => create$2((resolve, reject) => {
|
|
5381
|
+
const openDB = (name, initDB) => create$5((resolve, reject) => {
|
|
5271
5382
|
const request = indexedDB.open(name);
|
|
5272
5383
|
/**
|
|
5273
5384
|
* @param {any} event
|
|
@@ -5277,7 +5388,7 @@
|
|
|
5277
5388
|
/**
|
|
5278
5389
|
* @param {any} event
|
|
5279
5390
|
*/
|
|
5280
|
-
request.onerror = event => reject(create$
|
|
5391
|
+
request.onerror = event => reject(create$4(event.target.error));
|
|
5281
5392
|
/* istanbul ignore next */
|
|
5282
5393
|
request.onblocked = () => location.reload();
|
|
5283
5394
|
/**
|
|
@@ -5298,82 +5409,82 @@
|
|
|
5298
5409
|
};
|
|
5299
5410
|
});
|
|
5300
5411
|
|
|
5412
|
+
/* istanbul ignore next */
|
|
5301
5413
|
/**
|
|
5302
5414
|
* @param {string} name
|
|
5303
5415
|
*/
|
|
5304
|
-
/* istanbul ignore next */
|
|
5305
5416
|
const deleteDB = name => rtop(indexedDB.deleteDatabase(name));
|
|
5306
5417
|
|
|
5418
|
+
/* istanbul ignore next */
|
|
5307
5419
|
/**
|
|
5308
5420
|
* @param {IDBDatabase} db
|
|
5309
5421
|
* @param {Array<Array<string>|Array<string|IDBObjectStoreParameters|undefined>>} definitions
|
|
5310
5422
|
*/
|
|
5311
|
-
/* istanbul ignore next */
|
|
5312
5423
|
const createStores = (db, definitions) => definitions.forEach(d =>
|
|
5313
5424
|
// @ts-ignore
|
|
5314
5425
|
db.createObjectStore.apply(db, d)
|
|
5315
5426
|
);
|
|
5316
5427
|
|
|
5428
|
+
/* istanbul ignore next */
|
|
5317
5429
|
/**
|
|
5318
5430
|
* @param {IDBObjectStore} store
|
|
5319
5431
|
* @param {String | number | ArrayBuffer | Date | Array<any> } key
|
|
5320
5432
|
* @return {Promise<String | number | ArrayBuffer | Date | Array<any>>}
|
|
5321
5433
|
*/
|
|
5322
|
-
|
|
5323
|
-
const get = (store, key) =>
|
|
5434
|
+
const get$1 = (store, key) =>
|
|
5324
5435
|
rtop(store.get(key));
|
|
5325
5436
|
|
|
5437
|
+
/* istanbul ignore next */
|
|
5326
5438
|
/**
|
|
5327
5439
|
* @param {IDBObjectStore} store
|
|
5328
5440
|
* @param {String | number | ArrayBuffer | Date | IDBKeyRange | Array<any> } key
|
|
5329
5441
|
*/
|
|
5330
|
-
/* istanbul ignore next */
|
|
5331
5442
|
const del = (store, key) =>
|
|
5332
5443
|
rtop(store.delete(key));
|
|
5333
5444
|
|
|
5445
|
+
/* istanbul ignore next */
|
|
5334
5446
|
/**
|
|
5335
5447
|
* @param {IDBObjectStore} store
|
|
5336
5448
|
* @param {String | number | ArrayBuffer | Date | boolean} item
|
|
5337
5449
|
* @param {String | number | ArrayBuffer | Date | Array<any>} [key]
|
|
5338
5450
|
*/
|
|
5339
|
-
/* istanbul ignore next */
|
|
5340
5451
|
const put = (store, item, key) =>
|
|
5341
5452
|
rtop(store.put(item, key));
|
|
5342
5453
|
|
|
5454
|
+
/* istanbul ignore next */
|
|
5343
5455
|
/**
|
|
5344
5456
|
* @param {IDBObjectStore} store
|
|
5345
5457
|
* @param {String | number | ArrayBuffer | Date | boolean} item
|
|
5346
5458
|
* @param {String | number | ArrayBuffer | Date | Array<any>} key
|
|
5347
5459
|
* @return {Promise<any>}
|
|
5348
5460
|
*/
|
|
5349
|
-
/* istanbul ignore next */
|
|
5350
5461
|
const add = (store, item, key) =>
|
|
5351
5462
|
rtop(store.add(item, key));
|
|
5352
5463
|
|
|
5464
|
+
/* istanbul ignore next */
|
|
5353
5465
|
/**
|
|
5354
5466
|
* @param {IDBObjectStore} store
|
|
5355
5467
|
* @param {String | number | ArrayBuffer | Date} item
|
|
5356
5468
|
* @return {Promise<number>} Returns the generated key
|
|
5357
5469
|
*/
|
|
5358
|
-
/* istanbul ignore next */
|
|
5359
5470
|
const addAutoKey = (store, item) =>
|
|
5360
5471
|
rtop(store.add(item));
|
|
5361
5472
|
|
|
5473
|
+
/* istanbul ignore next */
|
|
5362
5474
|
/**
|
|
5363
5475
|
* @param {IDBObjectStore} store
|
|
5364
5476
|
* @param {IDBKeyRange} [range]
|
|
5365
5477
|
* @return {Promise<Array<any>>}
|
|
5366
5478
|
*/
|
|
5367
|
-
/* istanbul ignore next */
|
|
5368
5479
|
const getAll = (store, range) =>
|
|
5369
5480
|
rtop(store.getAll(range));
|
|
5370
5481
|
|
|
5482
|
+
/* istanbul ignore next */
|
|
5371
5483
|
/**
|
|
5372
5484
|
* @param {IDBObjectStore} store
|
|
5373
5485
|
* @param {IDBKeyRange} [range]
|
|
5374
5486
|
* @return {Promise<Array<any>>}
|
|
5375
5487
|
*/
|
|
5376
|
-
/* istanbul ignore next */
|
|
5377
5488
|
const getAllKeys = (store, range) =>
|
|
5378
5489
|
rtop(store.getAllKeys(range));
|
|
5379
5490
|
|
|
@@ -5384,23 +5495,23 @@
|
|
|
5384
5495
|
* @property {any} v Value
|
|
5385
5496
|
*/
|
|
5386
5497
|
|
|
5498
|
+
/* istanbul ignore next */
|
|
5387
5499
|
/**
|
|
5388
5500
|
* @param {IDBObjectStore} store
|
|
5389
5501
|
* @param {IDBKeyRange} [range]
|
|
5390
5502
|
* @return {Promise<Array<KeyValuePair>>}
|
|
5391
5503
|
*/
|
|
5392
|
-
/* istanbul ignore next */
|
|
5393
5504
|
const getAllKeysValues = (store, range) =>
|
|
5394
5505
|
// @ts-ignore
|
|
5395
5506
|
all([getAllKeys(store, range), getAll(store, range)]).then(([ks, vs]) => ks.map((k, i) => ({ k, v: vs[i] })));
|
|
5396
5507
|
|
|
5508
|
+
/* istanbul ignore next */
|
|
5397
5509
|
/**
|
|
5398
5510
|
* @param {any} request
|
|
5399
5511
|
* @param {function(IDBCursorWithValue):void|boolean} f
|
|
5400
5512
|
* @return {Promise<void>}
|
|
5401
5513
|
*/
|
|
5402
|
-
|
|
5403
|
-
const iterateOnRequest = (request, f) => create$2((resolve, reject) => {
|
|
5514
|
+
const iterateOnRequest = (request, f) => create$5((resolve, reject) => {
|
|
5404
5515
|
/* istanbul ignore next */
|
|
5405
5516
|
request.onerror = reject;
|
|
5406
5517
|
/**
|
|
@@ -5415,6 +5526,7 @@
|
|
|
5415
5526
|
};
|
|
5416
5527
|
});
|
|
5417
5528
|
|
|
5529
|
+
/* istanbul ignore next */
|
|
5418
5530
|
/**
|
|
5419
5531
|
* Iterate on keys and values
|
|
5420
5532
|
* @param {IDBObjectStore} store
|
|
@@ -5422,10 +5534,10 @@
|
|
|
5422
5534
|
* @param {function(any,any):void|boolean} f Callback that receives (value, key)
|
|
5423
5535
|
* @param {'next'|'prev'|'nextunique'|'prevunique'} direction
|
|
5424
5536
|
*/
|
|
5425
|
-
/* istanbul ignore next */
|
|
5426
5537
|
const iterate = (store, keyrange, f, direction = 'next') =>
|
|
5427
5538
|
iterateOnRequest(store.openCursor(keyrange, direction), cursor => f(cursor.value, cursor.key));
|
|
5428
5539
|
|
|
5540
|
+
/* istanbul ignore next */
|
|
5429
5541
|
/**
|
|
5430
5542
|
* Iterate on the keys (no values)
|
|
5431
5543
|
*
|
|
@@ -5434,26 +5546,25 @@
|
|
|
5434
5546
|
* @param {function(any):void|boolean} f callback that receives the key
|
|
5435
5547
|
* @param {'next'|'prev'|'nextunique'|'prevunique'} direction
|
|
5436
5548
|
*/
|
|
5437
|
-
/* istanbul ignore next */
|
|
5438
5549
|
const iterateKeys = (store, keyrange, f, direction = 'next') =>
|
|
5439
5550
|
iterateOnRequest(store.openKeyCursor(keyrange, direction), cursor => f(cursor.key));
|
|
5440
5551
|
|
|
5552
|
+
/* istanbul ignore next */
|
|
5441
5553
|
/**
|
|
5442
5554
|
* Open store from transaction
|
|
5443
5555
|
* @param {IDBTransaction} t
|
|
5444
5556
|
* @param {String} store
|
|
5445
5557
|
* @returns {IDBObjectStore}
|
|
5446
5558
|
*/
|
|
5447
|
-
/* istanbul ignore next */
|
|
5448
5559
|
const getStore$1 = (t, store) => t.objectStore(store);
|
|
5449
5560
|
|
|
5561
|
+
/* istanbul ignore next */
|
|
5450
5562
|
/**
|
|
5451
5563
|
* @param {any} lower
|
|
5452
5564
|
* @param {any} upper
|
|
5453
5565
|
* @param {boolean} lowerOpen
|
|
5454
5566
|
* @param {boolean} upperOpen
|
|
5455
5567
|
*/
|
|
5456
|
-
/* istanbul ignore next */
|
|
5457
5568
|
const createIDBKeyRangeBound = (lower, upper, lowerOpen, upperOpen) => IDBKeyRange.bound(lower, upper, lowerOpen, upperOpen);
|
|
5458
5569
|
|
|
5459
5570
|
/* istanbul ignore next */
|
|
@@ -5531,19 +5642,19 @@
|
|
|
5531
5642
|
await iterateTests('range!=null', range);
|
|
5532
5643
|
|
|
5533
5644
|
describe('idb.get');
|
|
5534
|
-
const getV = await get(store, ['t', 1]);
|
|
5645
|
+
const getV = await get$1(store, ['t', 1]);
|
|
5535
5646
|
assert(getV === 0);
|
|
5536
5647
|
describe('idb.del');
|
|
5537
5648
|
await del(store, ['t', 0]);
|
|
5538
|
-
const getVDel = await get(store, ['t', 0]);
|
|
5649
|
+
const getVDel = await get$1(store, ['t', 0]);
|
|
5539
5650
|
assert(getVDel === undefined);
|
|
5540
5651
|
describe('idb.add');
|
|
5541
5652
|
await add(store, 99, 42);
|
|
5542
|
-
const idbVAdd = await get(store, 42);
|
|
5653
|
+
const idbVAdd = await get$1(store, 42);
|
|
5543
5654
|
assert(idbVAdd === 99);
|
|
5544
5655
|
describe('idb.addAutoKey');
|
|
5545
5656
|
const key = await addAutoKey(store, 1234);
|
|
5546
|
-
const retrieved = await get(store, key);
|
|
5657
|
+
const retrieved = await get$1(store, key);
|
|
5547
5658
|
assert(retrieved === 1234);
|
|
5548
5659
|
};
|
|
5549
5660
|
|
|
@@ -5993,7 +6104,7 @@
|
|
|
5993
6104
|
* @param {Promise<T>} p
|
|
5994
6105
|
* @return {Promise<T>}
|
|
5995
6106
|
*/
|
|
5996
|
-
const failsP = p => create$
|
|
6107
|
+
const failsP = p => create$5((resolve, reject) => p.then(() => reject(create$4('Promise should fail')), resolve));
|
|
5997
6108
|
|
|
5998
6109
|
/**
|
|
5999
6110
|
* @param {t.TestCase} tc
|
|
@@ -6019,7 +6130,7 @@
|
|
|
6019
6130
|
*/
|
|
6020
6131
|
const testispromise = tc => {
|
|
6021
6132
|
assert(isPromise(new Promise(() => {})));
|
|
6022
|
-
assert(isPromise(create$
|
|
6133
|
+
assert(isPromise(create$5(() => {})));
|
|
6023
6134
|
const rej = reject();
|
|
6024
6135
|
assert(isPromise(rej));
|
|
6025
6136
|
rej.catch(() => {});
|
|
@@ -6064,12 +6175,12 @@
|
|
|
6064
6175
|
*
|
|
6065
6176
|
* @return {Queue}
|
|
6066
6177
|
*/
|
|
6067
|
-
const create = () => new Queue();
|
|
6178
|
+
const create$3 = () => new Queue();
|
|
6068
6179
|
|
|
6069
6180
|
/**
|
|
6070
6181
|
* @param {Queue} queue
|
|
6071
6182
|
*/
|
|
6072
|
-
const isEmpty = queue => queue.start === null;
|
|
6183
|
+
const isEmpty$1 = queue => queue.start === null;
|
|
6073
6184
|
|
|
6074
6185
|
/**
|
|
6075
6186
|
* @param {Queue} queue
|
|
@@ -6094,12 +6205,15 @@
|
|
|
6094
6205
|
if (n !== null) {
|
|
6095
6206
|
// @ts-ignore
|
|
6096
6207
|
queue.start = n.next;
|
|
6208
|
+
if (queue.start === null) {
|
|
6209
|
+
queue.end = null;
|
|
6210
|
+
}
|
|
6097
6211
|
return n
|
|
6098
6212
|
}
|
|
6099
6213
|
return null
|
|
6100
6214
|
};
|
|
6101
6215
|
|
|
6102
|
-
class QueueItem extends QueueNode {
|
|
6216
|
+
class QueueItem$1 extends QueueNode {
|
|
6103
6217
|
/**
|
|
6104
6218
|
* @param {number} v
|
|
6105
6219
|
*/
|
|
@@ -6112,51 +6226,62 @@
|
|
|
6112
6226
|
/**
|
|
6113
6227
|
* @param {t.TestCase} tc
|
|
6114
6228
|
*/
|
|
6115
|
-
const testEnqueueDequeue = tc => {
|
|
6229
|
+
const testEnqueueDequeue$1 = tc => {
|
|
6116
6230
|
const N = 30;
|
|
6117
6231
|
/**
|
|
6118
6232
|
* @type {queue.Queue}
|
|
6119
6233
|
*/
|
|
6120
|
-
const q = create();
|
|
6121
|
-
assert(isEmpty(q));
|
|
6234
|
+
const q = create$3();
|
|
6235
|
+
assert(isEmpty$1(q));
|
|
6122
6236
|
assert(dequeue(q) === null);
|
|
6123
6237
|
for (let i = 0; i < N; i++) {
|
|
6124
|
-
enqueue(q, new QueueItem(i));
|
|
6125
|
-
assert(!isEmpty(q));
|
|
6238
|
+
enqueue(q, new QueueItem$1(i));
|
|
6239
|
+
assert(!isEmpty$1(q));
|
|
6240
|
+
}
|
|
6241
|
+
for (let i = 0; i < N; i++) {
|
|
6242
|
+
const item = /** @type {QueueItem} */ (dequeue(q));
|
|
6243
|
+
assert(item !== null && item.v === i);
|
|
6244
|
+
}
|
|
6245
|
+
assert(isEmpty$1(q));
|
|
6246
|
+
assert(dequeue(q) === null);
|
|
6247
|
+
for (let i = 0; i < N; i++) {
|
|
6248
|
+
enqueue(q, new QueueItem$1(i));
|
|
6249
|
+
assert(!isEmpty$1(q));
|
|
6126
6250
|
}
|
|
6127
6251
|
for (let i = 0; i < N; i++) {
|
|
6128
6252
|
const item = /** @type {QueueItem} */ (dequeue(q));
|
|
6129
6253
|
assert(item !== null && item.v === i);
|
|
6130
6254
|
}
|
|
6255
|
+
assert(isEmpty$1(q));
|
|
6131
6256
|
assert(dequeue(q) === null);
|
|
6132
6257
|
};
|
|
6133
6258
|
|
|
6134
6259
|
var queue = /*#__PURE__*/Object.freeze({
|
|
6135
6260
|
__proto__: null,
|
|
6136
|
-
testEnqueueDequeue: testEnqueueDequeue
|
|
6261
|
+
testEnqueueDequeue: testEnqueueDequeue$1
|
|
6137
6262
|
});
|
|
6138
6263
|
|
|
6139
6264
|
/**
|
|
6140
6265
|
* @param {t.TestCase} tc
|
|
6141
6266
|
*/
|
|
6142
6267
|
const testMap = tc => {
|
|
6143
|
-
const m = create$
|
|
6268
|
+
const m = create$a();
|
|
6144
6269
|
m.set(1, 2);
|
|
6145
6270
|
m.set(2, 3);
|
|
6146
|
-
assert(map$
|
|
6271
|
+
assert(map$4(m, (value, key) => value * 2 + key).reduce(add$1) === 13);
|
|
6147
6272
|
let numberOfWrites = 0;
|
|
6148
6273
|
const createT = () => {
|
|
6149
6274
|
numberOfWrites++;
|
|
6150
6275
|
return {}
|
|
6151
6276
|
};
|
|
6152
|
-
setIfUndefined(m, 3, createT);
|
|
6153
|
-
setIfUndefined(m, 3, createT);
|
|
6154
|
-
setIfUndefined(m, 3, createT);
|
|
6277
|
+
setIfUndefined$1(m, 3, createT);
|
|
6278
|
+
setIfUndefined$1(m, 3, createT);
|
|
6279
|
+
setIfUndefined$1(m, 3, createT);
|
|
6155
6280
|
compare(copy(m), m);
|
|
6156
6281
|
assert(numberOfWrites === 1);
|
|
6157
6282
|
};
|
|
6158
6283
|
|
|
6159
|
-
var map = /*#__PURE__*/Object.freeze({
|
|
6284
|
+
var map$1 = /*#__PURE__*/Object.freeze({
|
|
6160
6285
|
__proto__: null,
|
|
6161
6286
|
testMap: testMap
|
|
6162
6287
|
});
|
|
@@ -6191,7 +6316,7 @@
|
|
|
6191
6316
|
set = true;
|
|
6192
6317
|
});
|
|
6193
6318
|
timeout$1.destroy();
|
|
6194
|
-
await create$
|
|
6319
|
+
await create$5(resolve => {
|
|
6195
6320
|
timeout(10, resolve);
|
|
6196
6321
|
});
|
|
6197
6322
|
assert(set === false);
|
|
@@ -6229,7 +6354,7 @@
|
|
|
6229
6354
|
* @param {t.TestCase} tc
|
|
6230
6355
|
*/
|
|
6231
6356
|
const testIdleCallback = async tc => {
|
|
6232
|
-
await create$
|
|
6357
|
+
await create$5(resolve => {
|
|
6233
6358
|
idleCallback(resolve);
|
|
6234
6359
|
});
|
|
6235
6360
|
};
|
|
@@ -6284,7 +6409,7 @@
|
|
|
6284
6409
|
* @param {t.TestCase} tc
|
|
6285
6410
|
*/
|
|
6286
6411
|
const testPair = tc => {
|
|
6287
|
-
const ps = [create$
|
|
6412
|
+
const ps = [create$8(1, 2), create$8(3, 4), createReversed(6, 5)];
|
|
6288
6413
|
describe('Counting elements in pair list');
|
|
6289
6414
|
let countLeft = 0;
|
|
6290
6415
|
let countRight = 0;
|
|
@@ -6294,8 +6419,8 @@
|
|
|
6294
6419
|
});
|
|
6295
6420
|
assert(countLeft === 9);
|
|
6296
6421
|
assert(countRight === 12);
|
|
6297
|
-
assert(countLeft === map$
|
|
6298
|
-
assert(countRight === map$
|
|
6422
|
+
assert(countLeft === map$3(ps, left => left).reduce(add$1));
|
|
6423
|
+
assert(countRight === map$3(ps, (left, right) => right).reduce(add$1));
|
|
6299
6424
|
};
|
|
6300
6425
|
|
|
6301
6426
|
var pair = /*#__PURE__*/Object.freeze({
|
|
@@ -6307,7 +6432,7 @@
|
|
|
6307
6432
|
* @param {t.TestCase} tc
|
|
6308
6433
|
*/
|
|
6309
6434
|
const testObject = tc => {
|
|
6310
|
-
assert(create$
|
|
6435
|
+
assert(create$7().constructor === undefined, 'object.create creates an empty object without constructor');
|
|
6311
6436
|
describe('object.equalFlat');
|
|
6312
6437
|
assert(equalFlat({}, {}), 'comparing equal objects');
|
|
6313
6438
|
assert(equalFlat({ x: 1 }, { x: 1 }), 'comparing equal objects');
|
|
@@ -6328,7 +6453,7 @@
|
|
|
6328
6453
|
forEach({ x: 1, y: 3 }, (v, k) => { forEachSum += v; });
|
|
6329
6454
|
assert(forEachSum === 4);
|
|
6330
6455
|
describe('object.map');
|
|
6331
|
-
assert(map$
|
|
6456
|
+
assert(map$2({ x: 1, z: 5 }, (v, k) => v).reduce(add$1) === 6);
|
|
6332
6457
|
describe('object.length');
|
|
6333
6458
|
assert(length$1({}) === 0);
|
|
6334
6459
|
assert(length$1({ x: 1 }) === 1);
|
|
@@ -6428,6 +6553,50 @@
|
|
|
6428
6553
|
testAnyEncoding: testAnyEncoding
|
|
6429
6554
|
});
|
|
6430
6555
|
|
|
6556
|
+
/**
|
|
6557
|
+
* Utility module to work with sets.
|
|
6558
|
+
*
|
|
6559
|
+
* @module set
|
|
6560
|
+
*/
|
|
6561
|
+
|
|
6562
|
+
const create$2 = () => new Set();
|
|
6563
|
+
|
|
6564
|
+
/**
|
|
6565
|
+
* @template T
|
|
6566
|
+
* @param {Set<T>} set
|
|
6567
|
+
* @return {T}
|
|
6568
|
+
*/
|
|
6569
|
+
const first = set => {
|
|
6570
|
+
return set.values().next().value || undefined
|
|
6571
|
+
};
|
|
6572
|
+
|
|
6573
|
+
/**
|
|
6574
|
+
* @template T
|
|
6575
|
+
* @param {Iterable<T>} entries
|
|
6576
|
+
* @return {Set<T>}
|
|
6577
|
+
*/
|
|
6578
|
+
const from = entries => {
|
|
6579
|
+
return new Set(entries)
|
|
6580
|
+
};
|
|
6581
|
+
|
|
6582
|
+
/**
|
|
6583
|
+
* @template T
|
|
6584
|
+
* @param {t.TestCase} tc
|
|
6585
|
+
*/
|
|
6586
|
+
const testFirst = tc => {
|
|
6587
|
+
const two = from(['a', 'b']);
|
|
6588
|
+
const one = from(['b']);
|
|
6589
|
+
const zero = create$2();
|
|
6590
|
+
assert(first(two) === 'a');
|
|
6591
|
+
assert(first(one) === 'b');
|
|
6592
|
+
assert(first(zero) === undefined);
|
|
6593
|
+
};
|
|
6594
|
+
|
|
6595
|
+
var set$1 = /*#__PURE__*/Object.freeze({
|
|
6596
|
+
__proto__: null,
|
|
6597
|
+
testFirst: testFirst
|
|
6598
|
+
});
|
|
6599
|
+
|
|
6431
6600
|
/**
|
|
6432
6601
|
* Efficient sort implementations.
|
|
6433
6602
|
*
|
|
@@ -6720,7 +6889,7 @@
|
|
|
6720
6889
|
* @return {string}
|
|
6721
6890
|
*/
|
|
6722
6891
|
const encodeQueryParams = params =>
|
|
6723
|
-
map$
|
|
6892
|
+
map$2(params, (val, key) => `${encodeURIComponent(key)}=${encodeURIComponent(val)}`).join('&');
|
|
6724
6893
|
|
|
6725
6894
|
/**
|
|
6726
6895
|
* @param {Object<string,any>} params
|
|
@@ -6884,6 +7053,488 @@
|
|
|
6884
7053
|
testStorageModule: testStorageModule
|
|
6885
7054
|
});
|
|
6886
7055
|
|
|
7056
|
+
class ListNode {
|
|
7057
|
+
constructor () {
|
|
7058
|
+
/**
|
|
7059
|
+
* @type {this|null}
|
|
7060
|
+
*/
|
|
7061
|
+
this.next = null;
|
|
7062
|
+
/**
|
|
7063
|
+
* @type {this|null}
|
|
7064
|
+
*/
|
|
7065
|
+
this.prev = null;
|
|
7066
|
+
}
|
|
7067
|
+
}
|
|
7068
|
+
|
|
7069
|
+
/**
|
|
7070
|
+
* @template {ListNode} N
|
|
7071
|
+
*/
|
|
7072
|
+
class List {
|
|
7073
|
+
constructor () {
|
|
7074
|
+
/**
|
|
7075
|
+
* @type {N | null}
|
|
7076
|
+
*/
|
|
7077
|
+
this.start = null;
|
|
7078
|
+
/**
|
|
7079
|
+
* @type {N | null}
|
|
7080
|
+
*/
|
|
7081
|
+
this.end = null;
|
|
7082
|
+
}
|
|
7083
|
+
}
|
|
7084
|
+
|
|
7085
|
+
/**
|
|
7086
|
+
* @note The queue implementation is experimental and unfinished.
|
|
7087
|
+
* Don't use this in production yet.
|
|
7088
|
+
*
|
|
7089
|
+
* @template {ListNode} N
|
|
7090
|
+
*
|
|
7091
|
+
* @return {List<N>}
|
|
7092
|
+
*/
|
|
7093
|
+
const create$1 = () => new List();
|
|
7094
|
+
|
|
7095
|
+
/**
|
|
7096
|
+
* @template {ListNode} N
|
|
7097
|
+
*
|
|
7098
|
+
* @param {List<N>} queue
|
|
7099
|
+
*/
|
|
7100
|
+
const isEmpty = queue => queue.start === null;
|
|
7101
|
+
|
|
7102
|
+
/**
|
|
7103
|
+
* Remove a single node from the queue. Only works with Queues that operate on Doubly-linked lists of nodes.
|
|
7104
|
+
*
|
|
7105
|
+
* @template {ListNode} N
|
|
7106
|
+
*
|
|
7107
|
+
* @param {List<N>} queue
|
|
7108
|
+
* @param {N} node
|
|
7109
|
+
*/
|
|
7110
|
+
const removeNode = (queue, node) => {
|
|
7111
|
+
const prev = node.prev;
|
|
7112
|
+
const next = node.next;
|
|
7113
|
+
if (prev) {
|
|
7114
|
+
prev.next = next;
|
|
7115
|
+
} else {
|
|
7116
|
+
queue.start = next;
|
|
7117
|
+
}
|
|
7118
|
+
if (next) {
|
|
7119
|
+
next.prev = prev;
|
|
7120
|
+
} else {
|
|
7121
|
+
queue.end = prev;
|
|
7122
|
+
}
|
|
7123
|
+
return node
|
|
7124
|
+
};
|
|
7125
|
+
|
|
7126
|
+
/**
|
|
7127
|
+
* @template {ListNode} N
|
|
7128
|
+
*
|
|
7129
|
+
* @param {List<N>} queue
|
|
7130
|
+
* @param {N| null} left
|
|
7131
|
+
* @param {N| null} right
|
|
7132
|
+
* @param {N} node
|
|
7133
|
+
*/
|
|
7134
|
+
const insertBetween = (queue, left, right, node) => {
|
|
7135
|
+
/* istanbul ignore if */
|
|
7136
|
+
if (left != null && left.next !== right) {
|
|
7137
|
+
throw unexpectedCase()
|
|
7138
|
+
}
|
|
7139
|
+
if (left) {
|
|
7140
|
+
left.next = node;
|
|
7141
|
+
} else {
|
|
7142
|
+
queue.start = node;
|
|
7143
|
+
}
|
|
7144
|
+
if (right) {
|
|
7145
|
+
right.prev = node;
|
|
7146
|
+
} else {
|
|
7147
|
+
queue.end = node;
|
|
7148
|
+
}
|
|
7149
|
+
node.prev = left;
|
|
7150
|
+
node.next = right;
|
|
7151
|
+
};
|
|
7152
|
+
|
|
7153
|
+
/**
|
|
7154
|
+
* @template {ListNode} N
|
|
7155
|
+
*
|
|
7156
|
+
* @param {List<N>} queue
|
|
7157
|
+
* @param {N} n
|
|
7158
|
+
*/
|
|
7159
|
+
const pushEnd = (queue, n) =>
|
|
7160
|
+
insertBetween(queue, queue.end, null, n);
|
|
7161
|
+
|
|
7162
|
+
/**
|
|
7163
|
+
* @template {ListNode} N
|
|
7164
|
+
*
|
|
7165
|
+
* @param {List<N>} queue
|
|
7166
|
+
* @param {N} n
|
|
7167
|
+
*/
|
|
7168
|
+
const pushFront = (queue, n) =>
|
|
7169
|
+
insertBetween(queue, null, queue.start, n);
|
|
7170
|
+
|
|
7171
|
+
/**
|
|
7172
|
+
* @template {ListNode} N
|
|
7173
|
+
*
|
|
7174
|
+
* @param {List<N>} list
|
|
7175
|
+
* @return {N| null}
|
|
7176
|
+
*/
|
|
7177
|
+
const popFront = list =>
|
|
7178
|
+
list.start ? removeNode(list, list.start) : null;
|
|
7179
|
+
|
|
7180
|
+
/**
|
|
7181
|
+
* @template {ListNode} N
|
|
7182
|
+
*
|
|
7183
|
+
* @param {List<N>} list
|
|
7184
|
+
* @return {N| null}
|
|
7185
|
+
*/
|
|
7186
|
+
const popEnd = list =>
|
|
7187
|
+
list.end ? removeNode(list, list.end) : null;
|
|
7188
|
+
|
|
7189
|
+
/**
|
|
7190
|
+
* @template {ListNode} N
|
|
7191
|
+
* @template M
|
|
7192
|
+
*
|
|
7193
|
+
* @param {List<N>} list
|
|
7194
|
+
* @param {function(N):M} f
|
|
7195
|
+
* @return {Array<M>}
|
|
7196
|
+
*/
|
|
7197
|
+
const map = (list, f) => {
|
|
7198
|
+
/**
|
|
7199
|
+
* @type {Array<M>}
|
|
7200
|
+
*/
|
|
7201
|
+
const arr = [];
|
|
7202
|
+
let n = list.start;
|
|
7203
|
+
while (n) {
|
|
7204
|
+
arr.push(f(n));
|
|
7205
|
+
n = n.next;
|
|
7206
|
+
}
|
|
7207
|
+
return arr
|
|
7208
|
+
};
|
|
7209
|
+
|
|
7210
|
+
class QueueItem extends ListNode {
|
|
7211
|
+
/**
|
|
7212
|
+
* @param {number} v
|
|
7213
|
+
*/
|
|
7214
|
+
constructor (v) {
|
|
7215
|
+
super();
|
|
7216
|
+
this.v = v;
|
|
7217
|
+
}
|
|
7218
|
+
}
|
|
7219
|
+
|
|
7220
|
+
/**
|
|
7221
|
+
* @param {t.TestCase} tc
|
|
7222
|
+
*/
|
|
7223
|
+
const testEnqueueDequeue = tc => {
|
|
7224
|
+
const N = 30;
|
|
7225
|
+
/**
|
|
7226
|
+
* @type {list.List<QueueItem>}
|
|
7227
|
+
*/
|
|
7228
|
+
const q = create$1();
|
|
7229
|
+
assert(isEmpty(q));
|
|
7230
|
+
assert(popFront(q) === null);
|
|
7231
|
+
for (let i = 0; i < N; i++) {
|
|
7232
|
+
pushEnd(q, new QueueItem(i));
|
|
7233
|
+
assert(!isEmpty(q));
|
|
7234
|
+
}
|
|
7235
|
+
for (let i = 0; i < N; i++) {
|
|
7236
|
+
const item = /** @type {QueueItem} */ (popFront(q));
|
|
7237
|
+
assert(item !== null && item.v === i);
|
|
7238
|
+
}
|
|
7239
|
+
assert(isEmpty(q));
|
|
7240
|
+
assert(popFront(q) === null);
|
|
7241
|
+
for (let i = 0; i < N; i++) {
|
|
7242
|
+
pushEnd(q, new QueueItem(i));
|
|
7243
|
+
assert(!isEmpty(q));
|
|
7244
|
+
}
|
|
7245
|
+
for (let i = 0; i < N; i++) {
|
|
7246
|
+
const item = /** @type {QueueItem} */ (popFront(q));
|
|
7247
|
+
assert(item !== null && item.v === i);
|
|
7248
|
+
}
|
|
7249
|
+
assert(isEmpty(q));
|
|
7250
|
+
assert(popFront(q) === null);
|
|
7251
|
+
};
|
|
7252
|
+
|
|
7253
|
+
/**
|
|
7254
|
+
* @param {t.TestCase} tc
|
|
7255
|
+
*/
|
|
7256
|
+
const testSelectivePop = tc => {
|
|
7257
|
+
/**
|
|
7258
|
+
* @type {list.List<QueueItem>}
|
|
7259
|
+
*/
|
|
7260
|
+
const l = create$1();
|
|
7261
|
+
pushFront(l, new QueueItem(1));
|
|
7262
|
+
pushEnd(l, new QueueItem(3));
|
|
7263
|
+
const middleNode = new QueueItem(2);
|
|
7264
|
+
insertBetween(l, l.start, l.end, middleNode);
|
|
7265
|
+
compare(map(l, n => n.v), [1, 2, 3]);
|
|
7266
|
+
assert(removeNode(l, middleNode) === middleNode);
|
|
7267
|
+
compare(/** @type {QueueItem} */ (popEnd(l)).v, 3);
|
|
7268
|
+
compare(/** @type {QueueItem} */ (popEnd(l)).v, 1);
|
|
7269
|
+
compare(popEnd(l), null);
|
|
7270
|
+
assert(l.start === null);
|
|
7271
|
+
assert(l.end === null);
|
|
7272
|
+
};
|
|
7273
|
+
|
|
7274
|
+
var list = /*#__PURE__*/Object.freeze({
|
|
7275
|
+
__proto__: null,
|
|
7276
|
+
testEnqueueDequeue: testEnqueueDequeue,
|
|
7277
|
+
testSelectivePop: testSelectivePop
|
|
7278
|
+
});
|
|
7279
|
+
|
|
7280
|
+
/**
|
|
7281
|
+
* @template K, V
|
|
7282
|
+
*
|
|
7283
|
+
* @implements {list.ListNode}
|
|
7284
|
+
*/
|
|
7285
|
+
class Entry {
|
|
7286
|
+
/**
|
|
7287
|
+
* @param {K} key
|
|
7288
|
+
* @param {V | Promise<V>} val
|
|
7289
|
+
*/
|
|
7290
|
+
constructor (key, val) {
|
|
7291
|
+
/**
|
|
7292
|
+
* @type {this | null}
|
|
7293
|
+
*/
|
|
7294
|
+
this.prev = null;
|
|
7295
|
+
/**
|
|
7296
|
+
* @type {this | null}
|
|
7297
|
+
*/
|
|
7298
|
+
this.next = null;
|
|
7299
|
+
this.created = getUnixTime();
|
|
7300
|
+
this.val = val;
|
|
7301
|
+
this.key = key;
|
|
7302
|
+
}
|
|
7303
|
+
}
|
|
7304
|
+
|
|
7305
|
+
/**
|
|
7306
|
+
* @template K, V
|
|
7307
|
+
*/
|
|
7308
|
+
class Cache {
|
|
7309
|
+
/**
|
|
7310
|
+
* @param {number} timeout
|
|
7311
|
+
*/
|
|
7312
|
+
constructor (timeout) {
|
|
7313
|
+
this.timeout = timeout;
|
|
7314
|
+
/**
|
|
7315
|
+
* @type list.List<Entry<K, V>>
|
|
7316
|
+
*/
|
|
7317
|
+
this._q = create$1();
|
|
7318
|
+
/**
|
|
7319
|
+
* @type {Map<K, Entry<K, V>>}
|
|
7320
|
+
*/
|
|
7321
|
+
this._map = create$a();
|
|
7322
|
+
}
|
|
7323
|
+
}
|
|
7324
|
+
|
|
7325
|
+
/**
|
|
7326
|
+
* @template K, V
|
|
7327
|
+
*
|
|
7328
|
+
* @param {Cache<K, V>} cache
|
|
7329
|
+
* @return {number} Returns the current timestamp
|
|
7330
|
+
*/
|
|
7331
|
+
const removeStale = cache => {
|
|
7332
|
+
const now = getUnixTime();
|
|
7333
|
+
const q = cache._q;
|
|
7334
|
+
while (q.start && now - q.start.created > cache.timeout) {
|
|
7335
|
+
cache._map.delete(q.start.key);
|
|
7336
|
+
popFront(q);
|
|
7337
|
+
}
|
|
7338
|
+
return now
|
|
7339
|
+
};
|
|
7340
|
+
|
|
7341
|
+
/**
|
|
7342
|
+
* @template K, V
|
|
7343
|
+
*
|
|
7344
|
+
* @param {Cache<K, V>} cache
|
|
7345
|
+
* @param {K} key
|
|
7346
|
+
* @param {V} value
|
|
7347
|
+
*/
|
|
7348
|
+
const set = (cache, key, value) => {
|
|
7349
|
+
const now = removeStale(cache);
|
|
7350
|
+
const q = cache._q;
|
|
7351
|
+
const n = cache._map.get(key);
|
|
7352
|
+
if (n) {
|
|
7353
|
+
removeNode(q, n);
|
|
7354
|
+
pushEnd(q, n);
|
|
7355
|
+
n.created = now;
|
|
7356
|
+
n.val = value;
|
|
7357
|
+
} else {
|
|
7358
|
+
const node = new Entry(key, value);
|
|
7359
|
+
pushEnd(q, node);
|
|
7360
|
+
cache._map.set(key, node);
|
|
7361
|
+
}
|
|
7362
|
+
};
|
|
7363
|
+
|
|
7364
|
+
/**
|
|
7365
|
+
* @template K, V
|
|
7366
|
+
*
|
|
7367
|
+
* @param {Cache<K, V>} cache
|
|
7368
|
+
* @param {K} key
|
|
7369
|
+
* @return {Entry<K, V> | undefined}
|
|
7370
|
+
*/
|
|
7371
|
+
const getNode = (cache, key) => {
|
|
7372
|
+
const now = removeStale(cache);
|
|
7373
|
+
const q = cache._q;
|
|
7374
|
+
const n = cache._map.get(key);
|
|
7375
|
+
if (n) {
|
|
7376
|
+
removeNode(q, n);
|
|
7377
|
+
pushEnd(q, n);
|
|
7378
|
+
n.created = now;
|
|
7379
|
+
return n
|
|
7380
|
+
}
|
|
7381
|
+
};
|
|
7382
|
+
|
|
7383
|
+
/**
|
|
7384
|
+
* @template K, V
|
|
7385
|
+
*
|
|
7386
|
+
* @param {Cache<K, V>} cache
|
|
7387
|
+
* @param {K} key
|
|
7388
|
+
* @return {V | undefined}
|
|
7389
|
+
*/
|
|
7390
|
+
const get = (cache, key) => {
|
|
7391
|
+
const n = getNode(cache, key);
|
|
7392
|
+
return n && !(n.val instanceof Promise) ? n.val : undefined
|
|
7393
|
+
};
|
|
7394
|
+
|
|
7395
|
+
/**
|
|
7396
|
+
* Works well in conjunktion with setIfUndefined which has an async init function.
|
|
7397
|
+
* Using getAsync & setIfUndefined ensures that the init function is only called once.
|
|
7398
|
+
*
|
|
7399
|
+
* @template K, V
|
|
7400
|
+
*
|
|
7401
|
+
* @param {Cache<K, V>} cache
|
|
7402
|
+
* @param {K} key
|
|
7403
|
+
* @return {V | Promise<V> | undefined}
|
|
7404
|
+
*/
|
|
7405
|
+
const getAsync = (cache, key) => {
|
|
7406
|
+
const n = getNode(cache, key);
|
|
7407
|
+
return n ? n.val : undefined
|
|
7408
|
+
};
|
|
7409
|
+
|
|
7410
|
+
/**
|
|
7411
|
+
* @template K, V
|
|
7412
|
+
*
|
|
7413
|
+
* @param {Cache<K, V>} cache
|
|
7414
|
+
* @param {K} key
|
|
7415
|
+
*/
|
|
7416
|
+
const remove = (cache, key) => {
|
|
7417
|
+
const n = cache._map.get(key);
|
|
7418
|
+
if (n) {
|
|
7419
|
+
removeNode(cache._q, n);
|
|
7420
|
+
cache._map.delete(key);
|
|
7421
|
+
return n.val && !(n.val instanceof Promise) ? n.val : undefined
|
|
7422
|
+
}
|
|
7423
|
+
};
|
|
7424
|
+
|
|
7425
|
+
/**
|
|
7426
|
+
* @template K, V
|
|
7427
|
+
*
|
|
7428
|
+
* @param {Cache<K, V>} cache
|
|
7429
|
+
* @param {K} key
|
|
7430
|
+
* @param {function():Promise<V>} init
|
|
7431
|
+
* @param {boolean} removeNull Optional argument that automatically removes values that resolve to null/undefined from the cache.
|
|
7432
|
+
* @return {Promise<V> | V}
|
|
7433
|
+
*/
|
|
7434
|
+
const setIfUndefined = (cache, key, init, removeNull = false) => {
|
|
7435
|
+
const now = removeStale(cache);
|
|
7436
|
+
const q = cache._q;
|
|
7437
|
+
const n = cache._map.get(key);
|
|
7438
|
+
if (n) {
|
|
7439
|
+
removeNode(q, n);
|
|
7440
|
+
pushEnd(q, n);
|
|
7441
|
+
n.created = now;
|
|
7442
|
+
return n.val
|
|
7443
|
+
} else {
|
|
7444
|
+
const p = init();
|
|
7445
|
+
const node = new Entry(key, p);
|
|
7446
|
+
pushEnd(q, node);
|
|
7447
|
+
cache._map.set(key, node);
|
|
7448
|
+
p.then(v => {
|
|
7449
|
+
if (p === node.val) {
|
|
7450
|
+
node.val = v;
|
|
7451
|
+
}
|
|
7452
|
+
if (removeNull && v == null) {
|
|
7453
|
+
remove(cache, key);
|
|
7454
|
+
}
|
|
7455
|
+
});
|
|
7456
|
+
return p
|
|
7457
|
+
}
|
|
7458
|
+
};
|
|
7459
|
+
|
|
7460
|
+
/**
|
|
7461
|
+
* @param {number} timeout
|
|
7462
|
+
*/
|
|
7463
|
+
const create = timeout => new Cache(timeout);
|
|
7464
|
+
|
|
7465
|
+
/**
|
|
7466
|
+
* @param {t.TestCase} tc
|
|
7467
|
+
*/
|
|
7468
|
+
const testCache = async tc => {
|
|
7469
|
+
/**
|
|
7470
|
+
* @type {cache.Cache<string, string>}
|
|
7471
|
+
*/
|
|
7472
|
+
const c = create(50);
|
|
7473
|
+
set(c, 'a', '1');
|
|
7474
|
+
assert(get(c, 'a') === '1');
|
|
7475
|
+
assert(await getAsync(c, 'a') === '1');
|
|
7476
|
+
const p = setIfUndefined(c, 'b', () => resolveWith('2'));
|
|
7477
|
+
const q = setIfUndefined(c, 'b', () => resolveWith('3'));
|
|
7478
|
+
assert(p === q);
|
|
7479
|
+
assert(get(c, 'b') == null);
|
|
7480
|
+
assert(getAsync(c, 'b') === p);
|
|
7481
|
+
assert(await p === '2');
|
|
7482
|
+
assert(get(c, 'b') === '2');
|
|
7483
|
+
assert(getAsync(c, 'b') === '2');
|
|
7484
|
+
|
|
7485
|
+
await wait(5); // keys shouldn't be timed out yet
|
|
7486
|
+
assert(get(c, 'a') === '1');
|
|
7487
|
+
assert(get(c, 'b') === '2');
|
|
7488
|
+
|
|
7489
|
+
/**
|
|
7490
|
+
* @type {any}
|
|
7491
|
+
*/
|
|
7492
|
+
const m = c._map;
|
|
7493
|
+
const aTimestamp1 = m.get('a').created;
|
|
7494
|
+
const bTimestamp1 = m.get('b').created;
|
|
7495
|
+
|
|
7496
|
+
// write new values and check later if the creation-timestamp was updated
|
|
7497
|
+
set(c, 'a', '11');
|
|
7498
|
+
await setIfUndefined(c, 'b', () => resolveWith('22')); // this shouldn't override, but update the timestamp
|
|
7499
|
+
|
|
7500
|
+
await wait(5); // keys should be updated and not timed out. Hence the creation time should be updated
|
|
7501
|
+
assert(get(c, 'a') === '11');
|
|
7502
|
+
assert(get(c, 'b') === '2');
|
|
7503
|
+
// timestamps should be updated
|
|
7504
|
+
assert(aTimestamp1 !== m.get('a').created);
|
|
7505
|
+
assert(bTimestamp1 !== m.get('b').created);
|
|
7506
|
+
|
|
7507
|
+
await wait(60); // now the keys should be timed-out
|
|
7508
|
+
|
|
7509
|
+
assert(get(c, 'a') == null);
|
|
7510
|
+
assert(getAsync(c, 'b') == null);
|
|
7511
|
+
|
|
7512
|
+
assert(c._map.size === 0);
|
|
7513
|
+
assert(c._q.start === null && c._q.end === null);
|
|
7514
|
+
|
|
7515
|
+
// test edge case of setIfUndefined
|
|
7516
|
+
const xp = setIfUndefined(c, 'a', () => resolve('x'));
|
|
7517
|
+
set(c, 'a', 'y');
|
|
7518
|
+
await xp;
|
|
7519
|
+
// we override the Entry.val property in cache when p resolves. However, we must prevent that when the value is overriden before p is resolved.
|
|
7520
|
+
assert(get(c, 'a') === 'y');
|
|
7521
|
+
|
|
7522
|
+
// test that we can remove properties
|
|
7523
|
+
remove(c, 'a');
|
|
7524
|
+
remove(c, 'does not exist'); // remove a non-existent property to achieve full test-coverage
|
|
7525
|
+
assert(get(c, 'a') === undefined);
|
|
7526
|
+
|
|
7527
|
+
// test that the optional property in setifUndefined works
|
|
7528
|
+
const yp = setIfUndefined(c, 'a', () => resolveWith(null), true);
|
|
7529
|
+
assert(await yp === null);
|
|
7530
|
+
assert(get(c, 'a') === undefined);
|
|
7531
|
+
};
|
|
7532
|
+
|
|
7533
|
+
var cache = /*#__PURE__*/Object.freeze({
|
|
7534
|
+
__proto__: null,
|
|
7535
|
+
testCache: testCache
|
|
7536
|
+
});
|
|
7537
|
+
|
|
6887
7538
|
/* istanbul ignore if */
|
|
6888
7539
|
if (isBrowser) {
|
|
6889
7540
|
createVConsole(document.body);
|
|
@@ -6903,7 +7554,7 @@
|
|
|
6903
7554
|
random,
|
|
6904
7555
|
promise,
|
|
6905
7556
|
queue,
|
|
6906
|
-
map,
|
|
7557
|
+
map: map$1,
|
|
6907
7558
|
eventloop,
|
|
6908
7559
|
time,
|
|
6909
7560
|
pair,
|
|
@@ -6911,11 +7562,14 @@
|
|
|
6911
7562
|
math,
|
|
6912
7563
|
number,
|
|
6913
7564
|
buffer,
|
|
7565
|
+
set: set$1,
|
|
6914
7566
|
sort,
|
|
6915
7567
|
url,
|
|
6916
7568
|
metric,
|
|
6917
7569
|
func,
|
|
6918
|
-
storage
|
|
7570
|
+
storage,
|
|
7571
|
+
list,
|
|
7572
|
+
cache
|
|
6919
7573
|
}).then(success => {
|
|
6920
7574
|
/* istanbul ignore next */
|
|
6921
7575
|
if (isNode) {
|
|
@@ -6923,5 +7577,5 @@
|
|
|
6923
7577
|
}
|
|
6924
7578
|
});
|
|
6925
7579
|
|
|
6926
|
-
}()
|
|
7580
|
+
})();
|
|
6927
7581
|
//# sourceMappingURL=test.js.map
|