lib0 0.2.41 → 0.2.44

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.
Files changed (156) hide show
  1. package/README.md +127 -72
  2. package/bin/gendocs.js +1 -1
  3. package/cache.d.ts +50 -0
  4. package/cache.d.ts.map +1 -0
  5. package/cache.js +178 -0
  6. package/cache.test.d.ts +3 -0
  7. package/cache.test.d.ts.map +1 -0
  8. package/component.d.ts +4 -1
  9. package/component.d.ts.map +1 -1
  10. package/component.js +4 -1
  11. package/diff.d.ts +5 -0
  12. package/diff.d.ts.map +1 -1
  13. package/diff.js +47 -10
  14. package/diff.test.d.ts +1 -0
  15. package/diff.test.d.ts.map +1 -1
  16. package/dist/{broadcastchannel-8a61b21a.cjs → broadcastchannel-7da37795.cjs} +2 -2
  17. package/dist/{broadcastchannel-8a61b21a.cjs.map → broadcastchannel-7da37795.cjs.map} +1 -1
  18. package/dist/broadcastchannel.cjs +5 -5
  19. package/dist/{buffer-ac2cdedf.cjs → buffer-b0dea3b0.cjs} +4 -4
  20. package/dist/{buffer-ac2cdedf.cjs.map → buffer-b0dea3b0.cjs.map} +1 -1
  21. package/dist/buffer.cjs +4 -4
  22. package/dist/cache.cjs +185 -0
  23. package/dist/cache.cjs.map +1 -0
  24. package/dist/cache.d.ts +50 -0
  25. package/dist/cache.d.ts.map +1 -0
  26. package/dist/cache.test.d.ts +3 -0
  27. package/dist/cache.test.d.ts.map +1 -0
  28. package/dist/component.cjs +7 -4
  29. package/dist/component.cjs.map +1 -1
  30. package/dist/component.d.ts +4 -1
  31. package/dist/component.d.ts.map +1 -1
  32. package/dist/decoding.cjs +4 -4
  33. package/dist/{diff-75787d87.cjs → diff-233747fa.cjs} +51 -12
  34. package/dist/diff-233747fa.cjs.map +1 -0
  35. package/dist/diff.cjs +2 -1
  36. package/dist/diff.cjs.map +1 -1
  37. package/dist/diff.d.ts +5 -0
  38. package/dist/diff.d.ts.map +1 -1
  39. package/dist/diff.test.d.ts +1 -0
  40. package/dist/diff.test.d.ts.map +1 -1
  41. package/dist/dom.d.ts.map +1 -1
  42. package/dist/encoding.cjs +4 -4
  43. package/dist/{environment-7e2ffaea.cjs → environment-60b83194.cjs} +2 -2
  44. package/dist/{environment-7e2ffaea.cjs.map → environment-60b83194.cjs.map} +1 -1
  45. package/dist/environment.cjs +2 -2
  46. package/dist/{error-55a9a8c8.cjs → error-873c9cbf.cjs} +4 -4
  47. package/dist/error-873c9cbf.cjs.map +1 -0
  48. package/dist/error.cjs +1 -1
  49. package/dist/error.d.ts.map +1 -1
  50. package/dist/index.cjs +13 -13
  51. package/dist/{indexeddb-44227700.cjs → indexeddb-5b4b0e13.cjs} +27 -25
  52. package/dist/indexeddb-5b4b0e13.cjs.map +1 -0
  53. package/dist/indexeddb.cjs +3 -3
  54. package/dist/indexeddb.d.ts +2 -2
  55. package/dist/indexeddb.d.ts.map +1 -1
  56. package/dist/isomorphic.cjs +2 -6
  57. package/dist/isomorphic.cjs.map +1 -1
  58. package/dist/list.cjs +172 -0
  59. package/dist/list.cjs.map +1 -0
  60. package/dist/list.d.ts +33 -0
  61. package/dist/list.d.ts.map +1 -0
  62. package/dist/list.test.d.ts +4 -0
  63. package/dist/list.test.d.ts.map +1 -0
  64. package/dist/{logging-7cc36806.cjs → logging-f6d41f58.cjs} +2 -2
  65. package/dist/{logging-7cc36806.cjs.map → logging-f6d41f58.cjs.map} +1 -1
  66. package/dist/logging.cjs +3 -3
  67. package/dist/{number-24f1eabe.cjs → number-e62129bc.cjs} +5 -2
  68. package/dist/number-e62129bc.cjs.map +1 -0
  69. package/dist/number.cjs +2 -1
  70. package/dist/number.cjs.map +1 -1
  71. package/dist/number.d.ts +1 -0
  72. package/dist/number.d.ts.map +1 -1
  73. package/dist/observable.cjs +1 -1
  74. package/dist/{prng-695120cc.cjs → prng-25602bac.cjs} +3 -3
  75. package/dist/{prng-695120cc.cjs.map → prng-25602bac.cjs.map} +1 -1
  76. package/dist/prng.cjs +5 -5
  77. package/dist/{promise-f0a086b2.cjs → promise-1a9fe712.cjs} +10 -1
  78. package/dist/{promise-f0a086b2.cjs.map → promise-1a9fe712.cjs.map} +1 -1
  79. package/dist/promise.cjs +2 -1
  80. package/dist/promise.cjs.map +1 -1
  81. package/dist/promise.d.ts +1 -0
  82. package/dist/promise.d.ts.map +1 -1
  83. package/dist/queue.cjs +3 -0
  84. package/dist/queue.cjs.map +1 -1
  85. package/dist/queue.d.ts.map +1 -1
  86. package/dist/queue.test.d.ts.map +1 -1
  87. package/dist/set-b596ef38.cjs +49 -0
  88. package/dist/set-b596ef38.cjs.map +1 -0
  89. package/dist/set.cjs +3 -1
  90. package/dist/set.cjs.map +1 -1
  91. package/dist/set.d.ts +2 -0
  92. package/dist/set.d.ts.map +1 -1
  93. package/dist/set.test.d.ts +2 -0
  94. package/dist/set.test.d.ts.map +1 -1
  95. package/dist/{string-f3c3d805.cjs → string-ad04f734.cjs} +12 -2
  96. package/dist/{string-f3c3d805.cjs.map → string-ad04f734.cjs.map} +1 -1
  97. package/dist/string.cjs +3 -4
  98. package/dist/string.cjs.map +1 -1
  99. package/dist/string.d.ts +1 -0
  100. package/dist/string.d.ts.map +1 -1
  101. package/dist/string.test.d.ts +1 -0
  102. package/dist/string.test.d.ts.map +1 -1
  103. package/dist/test.cjs +750 -125
  104. package/dist/test.cjs.map +1 -1
  105. package/dist/test.js +751 -126
  106. package/dist/test.js.map +1 -1
  107. package/dist/testing.cjs +12 -9
  108. package/dist/testing.cjs.map +1 -1
  109. package/dist/testing.d.ts.map +1 -1
  110. package/dist/{websocket-bfe7f545.cjs → websocket-08bd4c7b.cjs} +1 -1
  111. package/dist/{websocket-bfe7f545.cjs.map → websocket-08bd4c7b.cjs.map} +1 -1
  112. package/dist/websocket.cjs +2 -2
  113. package/dist/websocket.d.ts +1 -1
  114. package/dist/websocket.d.ts.map +1 -1
  115. package/dom.d.ts.map +1 -1
  116. package/error.d.ts.map +1 -1
  117. package/error.js +3 -3
  118. package/indexeddb.d.ts +2 -2
  119. package/indexeddb.d.ts.map +1 -1
  120. package/indexeddb.js +25 -23
  121. package/list.d.ts +33 -0
  122. package/list.d.ts.map +1 -0
  123. package/list.js +155 -0
  124. package/list.test.d.ts +4 -0
  125. package/list.test.d.ts.map +1 -0
  126. package/number.d.ts +1 -0
  127. package/number.d.ts.map +1 -1
  128. package/number.js +1 -0
  129. package/package.json +16 -4
  130. package/promise.d.ts +1 -0
  131. package/promise.d.ts.map +1 -1
  132. package/promise.js +7 -0
  133. package/queue.d.ts.map +1 -1
  134. package/queue.js +3 -0
  135. package/queue.test.d.ts.map +1 -1
  136. package/set.d.ts +2 -0
  137. package/set.d.ts.map +1 -1
  138. package/set.js +18 -0
  139. package/set.test.d.ts +2 -0
  140. package/set.test.d.ts.map +1 -1
  141. package/string.d.ts +1 -0
  142. package/string.d.ts.map +1 -1
  143. package/string.js +8 -0
  144. package/string.test.d.ts +1 -0
  145. package/string.test.d.ts.map +1 -1
  146. package/test.js +7 -1
  147. package/testing.d.ts.map +1 -1
  148. package/testing.js +5 -2
  149. package/websocket.d.ts +1 -1
  150. package/websocket.d.ts.map +1 -1
  151. package/dist/diff-75787d87.cjs.map +0 -1
  152. package/dist/error-55a9a8c8.cjs.map +0 -1
  153. package/dist/indexeddb-44227700.cjs.map +0 -1
  154. package/dist/number-24f1eabe.cjs.map +0 -1
  155. package/dist/set-7ae96d21.cjs +0 -27
  156. package/dist/set-7ae96d21.cjs.map +0 -1
package/dist/test.cjs CHANGED
@@ -16,7 +16,7 @@ var isomorphic_js = require('isomorphic.js');
16
16
  *
17
17
  * @function
18
18
  */
19
- const create$7 = () => new Map();
19
+ const create$a = () => new Map();
20
20
 
21
21
  /**
22
22
  * Copy a Map object into a fresh Map object.
@@ -27,7 +27,7 @@ const create$7 = () => new Map();
27
27
  * @return {Map<X,Y>}
28
28
  */
29
29
  const copy = m => {
30
- const r = create$7();
30
+ const r = create$a();
31
31
  m.forEach((v, k) => { r.set(k, v); });
32
32
  return r
33
33
  };
@@ -47,7 +47,7 @@ const copy = m => {
47
47
  * @param {function():T} createT
48
48
  * @return {T}
49
49
  */
50
- const setIfUndefined = (map, key, createT) => {
50
+ const setIfUndefined$1 = (map, key, createT) => {
51
51
  let set = map.get(key);
52
52
  if (set === undefined) {
53
53
  map.set(key, set = createT());
@@ -66,7 +66,7 @@ const setIfUndefined = (map, key, createT) => {
66
66
  * @param {function(V,K):R} f
67
67
  * @return {Array<R>}
68
68
  */
69
- const map$3 = (m, f) => {
69
+ const map$4 = (m, f) => {
70
70
  const res = [];
71
71
  for (const [key, value] of m) {
72
72
  res.push(f(value, key));
@@ -189,6 +189,14 @@ const _decodeUtf8Native = buf => /** @type {TextDecoder} */ (utf8TextDecoder).de
189
189
  /* istanbul ignore next */
190
190
  const decodeUtf8 = utf8TextDecoder ? _decodeUtf8Native : _decodeUtf8Polyfill;
191
191
 
192
+ /**
193
+ * @param {string} str The initial string
194
+ * @param {number} index Starting position
195
+ * @param {number} remove Number of characters to remove
196
+ * @param {string} insert New content to insert
197
+ */
198
+ const splice = (str, index, remove, insert = '') => str.slice(0, index) + insert + str.slice(index + remove);
199
+
192
200
  /**
193
201
  * Often used conditions.
194
202
  *
@@ -289,7 +297,7 @@ let params;
289
297
  const computeParams = () => {
290
298
  if (params === undefined) {
291
299
  if (isNode) {
292
- params = create$7();
300
+ params = create$a();
293
301
  const pargs = process.argv;
294
302
  let currParamName = null;
295
303
  /* istanbul ignore next */
@@ -312,7 +320,7 @@ const computeParams = () => {
312
320
  }
313
321
  // in ReactNative for example this would not be true (unless connected to the Remote Debugger)
314
322
  } else if (typeof location === 'object') {
315
- params = create$7()
323
+ params = create$a()
316
324
  // eslint-disable-next-line no-undef
317
325
  ;(location.search || '?').slice(1).split('&').forEach(kv => {
318
326
  if (kv.length !== 0) {
@@ -322,7 +330,7 @@ const computeParams = () => {
322
330
  }
323
331
  });
324
332
  } else {
325
- params = create$7();
333
+ params = create$a();
326
334
  }
327
335
  }
328
336
  return params
@@ -372,7 +380,7 @@ const production = hasConf('production');
372
380
  *
373
381
  * @return {Symbol}
374
382
  */
375
- const create$6 = Symbol;
383
+ const create$9 = Symbol;
376
384
 
377
385
  /**
378
386
  * Working with value pairs.
@@ -400,7 +408,7 @@ class Pair {
400
408
  * @param {R} right
401
409
  * @return {Pair<L,R>}
402
410
  */
403
- const create$5 = (left, right) => new Pair(left, right);
411
+ const create$8 = (left, right) => new Pair(left, right);
404
412
 
405
413
  /**
406
414
  * @template L,R
@@ -423,7 +431,7 @@ const forEach$1 = (arr, f) => arr.forEach(p => f(p.left, p.right));
423
431
  * @param {function(L, R):X} f
424
432
  * @return {Array<X>}
425
433
  */
426
- const map$2 = (arr, f) => arr.map(p => f(p.left, p.right));
434
+ const map$3 = (arr, f) => arr.map(p => f(p.left, p.right));
427
435
 
428
436
  /* eslint-env browser */
429
437
 
@@ -542,7 +550,7 @@ const text = createTextNode;
542
550
  * @return {string}
543
551
  */
544
552
  /* istanbul ignore next */
545
- const mapToStyleString = m => map$3(m, (value, key) => `${key}:${value};`).join('');
553
+ const mapToStyleString = m => map$4(m, (value, key) => `${key}:${value};`).join('');
546
554
 
547
555
  /**
548
556
  * @param {Node} parent
@@ -552,6 +560,14 @@ const mapToStyleString = m => map$3(m, (value, key) => `${key}:${value};`).join(
552
560
  /* istanbul ignore next */
553
561
  const appendChild = (parent, child) => parent.appendChild(child);
554
562
 
563
+ doc.ELEMENT_NODE;
564
+ doc.TEXT_NODE;
565
+ doc.CDATA_SECTION_NODE;
566
+ doc.COMMENT_NODE;
567
+ doc.DOCUMENT_NODE;
568
+ doc.DOCUMENT_TYPE_NODE;
569
+ doc.DOCUMENT_FRAGMENT_NODE;
570
+
555
571
  /**
556
572
  * JSON utility functions.
557
573
  *
@@ -856,7 +872,7 @@ const flatten = arr => arr.reduce((acc, val) => acc.concat(val), []);
856
872
  /**
857
873
  * @return {Object<string,any>} obj
858
874
  */
859
- const create$4 = () => Object.create(null);
875
+ const create$7 = () => Object.create(null);
860
876
 
861
877
  /**
862
878
  * Object.assign
@@ -884,7 +900,7 @@ const forEach = (obj, f) => {
884
900
  * @param {function(any,string):R} f
885
901
  * @return {Array<R>}
886
902
  */
887
- const map$1 = (obj, f) => {
903
+ const map$2 = (obj, f) => {
888
904
  const results = [];
889
905
  for (const key in obj) {
890
906
  results.push(f(obj[key], key));
@@ -1051,29 +1067,29 @@ const equalityDeep = (a, b) => {
1051
1067
  * @module logging
1052
1068
  */
1053
1069
 
1054
- const BOLD = create$6();
1055
- const UNBOLD = create$6();
1056
- const BLUE = create$6();
1057
- const GREY = create$6();
1058
- const GREEN = create$6();
1059
- const RED = create$6();
1060
- const PURPLE = create$6();
1061
- const ORANGE = create$6();
1062
- const UNCOLOR = create$6();
1070
+ const BOLD = create$9();
1071
+ const UNBOLD = create$9();
1072
+ const BLUE = create$9();
1073
+ const GREY = create$9();
1074
+ const GREEN = create$9();
1075
+ const RED = create$9();
1076
+ const PURPLE = create$9();
1077
+ const ORANGE = create$9();
1078
+ const UNCOLOR = create$9();
1063
1079
 
1064
1080
  /**
1065
1081
  * @type {Object<Symbol,pair.Pair<string,string>>}
1066
1082
  */
1067
1083
  const _browserStyleMap = {
1068
- [BOLD]: create$5('font-weight', 'bold'),
1069
- [UNBOLD]: create$5('font-weight', 'normal'),
1070
- [BLUE]: create$5('color', 'blue'),
1071
- [GREEN]: create$5('color', 'green'),
1072
- [GREY]: create$5('color', 'grey'),
1073
- [RED]: create$5('color', 'red'),
1074
- [PURPLE]: create$5('color', 'purple'),
1075
- [ORANGE]: create$5('color', 'orange'), // not well supported in chrome when debugging node with inspector - TODO: deprecate
1076
- [UNCOLOR]: create$5('color', 'black')
1084
+ [BOLD]: create$8('font-weight', 'bold'),
1085
+ [UNBOLD]: create$8('font-weight', 'normal'),
1086
+ [BLUE]: create$8('color', 'blue'),
1087
+ [GREEN]: create$8('color', 'green'),
1088
+ [GREY]: create$8('color', 'grey'),
1089
+ [RED]: create$8('color', 'red'),
1090
+ [PURPLE]: create$8('color', 'purple'),
1091
+ [ORANGE]: create$8('color', 'orange'), // not well supported in chrome when debugging node with inspector - TODO: deprecate
1092
+ [UNCOLOR]: create$8('color', 'black')
1077
1093
  };
1078
1094
 
1079
1095
  const _nodeStyleMap = {
@@ -1096,7 +1112,7 @@ const _nodeStyleMap = {
1096
1112
  const computeBrowserLoggingArgs = args => {
1097
1113
  const strBuilder = [];
1098
1114
  const styles = [];
1099
- const currentStyle = create$7();
1115
+ const currentStyle = create$a();
1100
1116
  /**
1101
1117
  * @type {Array<string|Object|number>}
1102
1118
  */
@@ -1274,7 +1290,7 @@ const _computeLineSpans = args => {
1274
1290
  } else {
1275
1291
  if (arg.constructor === String || arg.constructor === Number) {
1276
1292
  // @ts-ignore
1277
- const span = element('span', [create$5('style', mapToStyleString(currentStyle))], [text(arg)]);
1293
+ const span = element('span', [create$8('style', mapToStyleString(currentStyle))], [text(arg)]);
1278
1294
  if (span.innerHTML === '') {
1279
1295
  span.innerHTML = '&nbsp;';
1280
1296
  }
@@ -1320,10 +1336,10 @@ class VConsole {
1320
1336
  */
1321
1337
  group (args, collapsed = false) {
1322
1338
  enqueue$1(() => {
1323
- const triangleDown = element('span', [create$5('hidden', collapsed), create$5('style', 'color:grey;font-size:120%;')], [text('▼')]);
1324
- const triangleRight = element('span', [create$5('hidden', !collapsed), create$5('style', 'color:grey;font-size:125%;')], [text('▶')]);
1325
- const content = element('div', [create$5('style', `${lineStyle};padding-left:${this.depth * 10}px`)], [triangleDown, triangleRight, text(' ')].concat(_computeLineSpans(args)));
1326
- const nextContainer = element('div', [create$5('hidden', collapsed)]);
1339
+ const triangleDown = element('span', [create$8('hidden', collapsed), create$8('style', 'color:grey;font-size:120%;')], [text('▼')]);
1340
+ const triangleRight = element('span', [create$8('hidden', !collapsed), create$8('style', 'color:grey;font-size:125%;')], [text('▶')]);
1341
+ const content = element('div', [create$8('style', `${lineStyle};padding-left:${this.depth * 10}px`)], [triangleDown, triangleRight, text(' ')].concat(_computeLineSpans(args)));
1342
+ const nextContainer = element('div', [create$8('hidden', collapsed)]);
1327
1343
  const nextLine = element('div', [], [content, nextContainer]);
1328
1344
  append(this.ccontainer, [nextLine]);
1329
1345
  this.ccontainer = nextContainer;
@@ -1359,7 +1375,7 @@ class VConsole {
1359
1375
  */
1360
1376
  print (args) {
1361
1377
  enqueue$1(() => {
1362
- append(this.ccontainer, [element('div', [create$5('style', `${lineStyle};padding-left:${this.depth * 10}px`)], _computeLineSpans(args))]);
1378
+ append(this.ccontainer, [element('div', [create$8('style', `${lineStyle};padding-left:${this.depth * 10}px`)], _computeLineSpans(args))]);
1363
1379
  });
1364
1380
  }
1365
1381
 
@@ -1376,7 +1392,7 @@ class VConsole {
1376
1392
  */
1377
1393
  printImg (url, height) {
1378
1394
  enqueue$1(() => {
1379
- append(this.ccontainer, [element('img', [create$5('src', url), create$5('height', `${round(height * 1.5)}px`)])]);
1395
+ append(this.ccontainer, [element('img', [create$8('src', url), create$8('height', `${round(height * 1.5)}px`)])]);
1380
1396
  });
1381
1397
  }
1382
1398
 
@@ -1446,11 +1462,8 @@ const simpleDiffString = (a, b) => {
1446
1462
  while (left < a.length && left < b.length && a[left] === b[left]) {
1447
1463
  left++;
1448
1464
  }
1449
- if (left !== a.length || left !== b.length) {
1450
- // Only check right if a !== b
1451
- while (right + left < a.length && right + left < b.length && a[a.length - right - 1] === b[b.length - right - 1]) {
1452
- right++;
1453
- }
1465
+ while (right + left < a.length && right + left < b.length && a[a.length - right - 1] === b[b.length - right - 1]) {
1466
+ right++;
1454
1467
  }
1455
1468
  return {
1456
1469
  index: left,
@@ -1459,12 +1472,6 @@ const simpleDiffString = (a, b) => {
1459
1472
  }
1460
1473
  };
1461
1474
 
1462
- /**
1463
- * @todo Remove in favor of simpleDiffString
1464
- * @deprecated
1465
- */
1466
- const simpleDiff = simpleDiffString;
1467
-
1468
1475
  /**
1469
1476
  * Create a diff between two arrays. This diff implementation is highly
1470
1477
  * efficient, but not very sophisticated.
@@ -1486,11 +1493,51 @@ const simpleDiffArray = (a, b, compare = equalityStrict) => {
1486
1493
  while (left < a.length && left < b.length && compare(a[left], b[left])) {
1487
1494
  left++;
1488
1495
  }
1489
- if (left !== a.length || left !== b.length) {
1490
- // Only check right if a !== b
1491
- while (right + left < a.length && right + left < b.length && compare(a[a.length - right - 1], b[b.length - right - 1])) {
1492
- right++;
1493
- }
1496
+ while (right + left < a.length && right + left < b.length && compare(a[a.length - right - 1], b[b.length - right - 1])) {
1497
+ right++;
1498
+ }
1499
+ return {
1500
+ index: left,
1501
+ remove: a.length - left - right,
1502
+ insert: b.slice(left, b.length - right)
1503
+ }
1504
+ };
1505
+
1506
+ /**
1507
+ * Diff text and try to diff at the current cursor position.
1508
+ *
1509
+ * @param {string} a
1510
+ * @param {string} b
1511
+ * @param {number} cursor This should refer to the current left cursor-range position
1512
+ */
1513
+ const simpleDiffStringWithCursor = (a, b, cursor) => {
1514
+ let left = 0; // number of same characters counting from left
1515
+ let right = 0; // number of same characters counting from right
1516
+ // Iterate left to the right until we find a changed character
1517
+ // First iteration considers the current cursor position
1518
+ while (
1519
+ left < a.length &&
1520
+ left < b.length &&
1521
+ a[left] === b[left] &&
1522
+ left < cursor
1523
+ ) {
1524
+ left++;
1525
+ }
1526
+ // Iterate right to the left until we find a changed character
1527
+ while (
1528
+ right + left < a.length &&
1529
+ right + left < b.length &&
1530
+ a[a.length - right - 1] === b[b.length - right - 1]
1531
+ ) {
1532
+ right++;
1533
+ }
1534
+ // Try to iterate left further to the right without caring about the current cursor position
1535
+ while (
1536
+ right + left < a.length &&
1537
+ right + left < b.length &&
1538
+ a[left] === b[left]
1539
+ ) {
1540
+ left++;
1494
1541
  }
1495
1542
  return {
1496
1543
  index: left,
@@ -1958,7 +2005,7 @@ const write = (encoder, num) => {
1958
2005
  * @param {number} pos Position to which to write data
1959
2006
  * @param {number} num Unsigned 8-bit integer
1960
2007
  */
1961
- const set = (encoder, pos, num) => {
2008
+ const set$2 = (encoder, pos, num) => {
1962
2009
  let buffer = null;
1963
2010
  // iterate all buffers and adjust position
1964
2011
  for (let i = 0; i < encoder.bufs.length && buffer === null; i++) {
@@ -1993,7 +2040,7 @@ const writeUint8 = write;
1993
2040
  * @param {number} pos The location where the data will be written.
1994
2041
  * @param {number} num The number that is to be encoded.
1995
2042
  */
1996
- const setUint8 = set;
2043
+ const setUint8 = set$2;
1997
2044
 
1998
2045
  /**
1999
2046
  * Write two bytes as an unsigned integer.
@@ -2015,8 +2062,8 @@ const writeUint16 = (encoder, num) => {
2015
2062
  * @param {number} num The number that is to be encoded.
2016
2063
  */
2017
2064
  const setUint16 = (encoder, pos, num) => {
2018
- set(encoder, pos, num & BITS8);
2019
- set(encoder, pos + 1, (num >>> 8) & BITS8);
2065
+ set$2(encoder, pos, num & BITS8);
2066
+ set$2(encoder, pos + 1, (num >>> 8) & BITS8);
2020
2067
  };
2021
2068
 
2022
2069
  /**
@@ -2057,7 +2104,7 @@ const writeUint32BigEndian = (encoder, num) => {
2057
2104
  */
2058
2105
  const setUint32 = (encoder, pos, num) => {
2059
2106
  for (let i = 0; i < 4; i++) {
2060
- set(encoder, pos + i, num & BITS8);
2107
+ set$2(encoder, pos + i, num & BITS8);
2061
2108
  num >>>= 8;
2062
2109
  }
2063
2110
  };
@@ -3360,7 +3407,7 @@ const DefaultPRNG = Xoroshiro128plus;
3360
3407
  * @param {number} seed A positive 32bit integer. Do not use negative numbers.
3361
3408
  * @return {PRNG}
3362
3409
  */
3363
- const create$3 = seed => new DefaultPRNG(seed);
3410
+ const create$6 = seed => new DefaultPRNG(seed);
3364
3411
 
3365
3412
  /**
3366
3413
  * Generates a single random bool.
@@ -3550,7 +3597,7 @@ const average = arr => arr.reduce(add$1, 0) / arr.length;
3550
3597
  * @param {function(PromiseResolve<T>,function(Error):void):any} f
3551
3598
  * @return {Promise<T>}
3552
3599
  */
3553
- const create$2 = f => /** @type {Promise<T>} */ (new Promise(f));
3600
+ const create$5 = f => /** @type {Promise<T>} */ (new Promise(f));
3554
3601
 
3555
3602
  /**
3556
3603
  * @param {function(function():void,function(Error):void):void} f
@@ -3579,6 +3626,13 @@ const reject = reason => Promise.reject(reason);
3579
3626
  */
3580
3627
  const resolve = res => Promise.resolve(res);
3581
3628
 
3629
+ /**
3630
+ * @template T
3631
+ * @param {T} res
3632
+ * @return {Promise<T>}
3633
+ */
3634
+ const resolveWith = res => Promise.resolve(res);
3635
+
3582
3636
  /**
3583
3637
  * @todo Next version, reorder parameters: check, [timeout, [intervalResolution]]
3584
3638
  *
@@ -3587,7 +3641,7 @@ const resolve = res => Promise.resolve(res);
3587
3641
  * @param {number} [intervalResolution]
3588
3642
  * @return {Promise<void>}
3589
3643
  */
3590
- const until = (timeout, check, intervalResolution = 10) => create$2((resolve, reject) => {
3644
+ const until = (timeout, check, intervalResolution = 10) => create$5((resolve, reject) => {
3591
3645
  const startTime = getUnixTime();
3592
3646
  const hasTimeout = timeout > 0;
3593
3647
  const untilInterval = () => {
@@ -3609,7 +3663,7 @@ const until = (timeout, check, intervalResolution = 10) => create$2((resolve, re
3609
3663
  * @param {number} timeout
3610
3664
  * @return {Promise<undefined>}
3611
3665
  */
3612
- const wait = timeout => create$2((resolve, reject) => setTimeout(resolve, timeout));
3666
+ const wait = timeout => create$5((resolve, reject) => setTimeout(resolve, timeout));
3613
3667
 
3614
3668
  /**
3615
3669
  * Checks if an object is a promise using ducktyping.
@@ -3716,7 +3770,7 @@ class TestCase {
3716
3770
  get prng () {
3717
3771
  /* istanbul ignore else */
3718
3772
  if (this._prng === null) {
3719
- this._prng = create$3(this.seed);
3773
+ this._prng = create$6(this.seed);
3720
3774
  }
3721
3775
  return this._prng
3722
3776
  }
@@ -3757,6 +3811,9 @@ const run = async (moduleName, name, f, i, numberOfTests) => {
3757
3811
  const times = [];
3758
3812
  const start = isomorphic_js.performance.now();
3759
3813
  let lastTime = start;
3814
+ /**
3815
+ * @type {any}
3816
+ */
3760
3817
  let err = null;
3761
3818
  isomorphic_js.performance.mark(`${name}-start`);
3762
3819
  do {
@@ -3977,7 +4034,7 @@ const compareArrays = (as, bs, m = 'Arrays match') => {
3977
4034
  */
3978
4035
  const compareStrings = (a, b, m = 'Strings match') => {
3979
4036
  if (a !== b) {
3980
- const diff = simpleDiff(a, b);
4037
+ const diff = simpleDiffString(a, b);
3981
4038
  print(GREY, a.slice(0, diff.index), RED, a.slice(diff.index, diff.remove), GREEN, diff.insert, GREY, a.slice(diff.index + diff.remove));
3982
4039
  fail(m);
3983
4040
  }
@@ -4140,7 +4197,7 @@ const fails = f => {
4140
4197
  * @param {Object<string, Object<string, function(TestCase):void|Promise<any>>>} tests
4141
4198
  */
4142
4199
  const runTests = async tests => {
4143
- const numberOfTests = map$1(tests, mod => map$1(mod, f => /* istanbul ignore next */ f ? 1 : 0).reduce(add$1, 0)).reduce(add$1, 0);
4200
+ const numberOfTests = map$2(tests, mod => map$2(mod, f => /* istanbul ignore next */ f ? 1 : 0).reduce(add$1, 0)).reduce(add$1, 0);
4144
4201
  let successfulTests = 0;
4145
4202
  let testnumber = 0;
4146
4203
  const start = isomorphic_js.performance.now();
@@ -4306,12 +4363,22 @@ const testBomEncodingDecoding = tc => {
4306
4363
  }
4307
4364
  };
4308
4365
 
4366
+ /**
4367
+ * @param {t.TestCase} tc
4368
+ */
4369
+ const testSplice = tc => {
4370
+ const initial = 'xyz';
4371
+ compareStrings(splice(initial, 0, 2), 'z');
4372
+ compareStrings(splice(initial, 0, 2, 'u'), 'uz');
4373
+ };
4374
+
4309
4375
  var string = /*#__PURE__*/Object.freeze({
4310
4376
  __proto__: null,
4311
4377
  testLowercaseTransformation: testLowercaseTransformation,
4312
4378
  testRepeatStringUtf8Encoding: testRepeatStringUtf8Encoding,
4313
4379
  testRepeatStringUtf8Decoding: testRepeatStringUtf8Decoding,
4314
- testBomEncodingDecoding: testBomEncodingDecoding
4380
+ testBomEncodingDecoding: testBomEncodingDecoding,
4381
+ testSplice: testSplice
4315
4382
  });
4316
4383
 
4317
4384
  /* global BigInt */
@@ -5021,6 +5088,7 @@ var encoding = /*#__PURE__*/Object.freeze({
5021
5088
  function runDiffTest (a, b, expected) {
5022
5089
  const result = simpleDiffString(a, b);
5023
5090
  compare(result, expected);
5091
+ compare(result, simpleDiffStringWithCursor(a, b, a.length)); // check that the withCursor approach returns the same result
5024
5092
  const arrResult = simpleDiffArray(a.split(''), b.split(''));
5025
5093
  compare(arrResult, assign({}, result, { insert: result.insert.split('') }));
5026
5094
  }
@@ -5046,10 +5114,43 @@ const testRepeatDiffing = tc => {
5046
5114
  const a = word(tc.prng);
5047
5115
  const b = word(tc.prng);
5048
5116
  const change = simpleDiffString(a, b);
5049
- const recomposed = `${a.slice(0, change.index)}${change.insert}${a.slice(change.index + change.remove)}`;
5117
+ const recomposed = splice(a, change.index, change.remove, change.insert);
5050
5118
  compareStrings(recomposed, b);
5051
5119
  };
5052
5120
 
5121
+ /**
5122
+ * @param {t.TestCase} tc
5123
+ */
5124
+ const testSimpleDiffWithCursor = tc => {
5125
+ const initial = 'Hello WorldHello World';
5126
+ const expected = 'Hello World';
5127
+ {
5128
+ const change = simpleDiffStringWithCursor(initial, 'Hello World', 0); // should delete the first hello world
5129
+ compare(change, { insert: '', remove: 11, index: 0 });
5130
+ const recomposed = splice(initial, change.index, change.remove, change.insert);
5131
+ compareStrings(expected, recomposed);
5132
+ }
5133
+ {
5134
+ const change = simpleDiffStringWithCursor(initial, 'Hello World', 11); // should delete the second hello world
5135
+ compare(change, { insert: '', remove: 11, index: 11 });
5136
+ const recomposedSecond = splice(initial, change.index, change.remove, change.insert);
5137
+ compareStrings(recomposedSecond, expected);
5138
+ }
5139
+ {
5140
+ const change = simpleDiffStringWithCursor(initial, 'Hello World', 5); // should delete in the midst of Hello World
5141
+ compare(change, { insert: '', remove: 11, index: 5 });
5142
+ const recomposed = splice(initial, change.index, change.remove, change.insert);
5143
+ compareStrings(expected, recomposed);
5144
+ }
5145
+ {
5146
+ const initial = 'Hello my World';
5147
+ const change = simpleDiffStringWithCursor(initial, 'Hello World', 0); // Should delete after the current cursor position
5148
+ compare(change, { insert: '', remove: 3, index: 5 });
5149
+ const recomposed = splice(initial, change.index, change.remove, change.insert);
5150
+ compareStrings(expected, recomposed);
5151
+ }
5152
+ };
5153
+
5053
5154
  /**
5054
5155
  * @param {t.TestCase} tc
5055
5156
  */
@@ -5065,6 +5166,7 @@ var diff = /*#__PURE__*/Object.freeze({
5065
5166
  __proto__: null,
5066
5167
  testDiffing: testDiffing,
5067
5168
  testRepeatDiffing: testRepeatDiffing,
5169
+ testSimpleDiffWithCursor: testSimpleDiffWithCursor,
5068
5170
  testArrayDiffing: testArrayDiffing
5069
5171
  });
5070
5172
 
@@ -5077,7 +5179,7 @@ const testComparing = tc => {
5077
5179
  compare([1, 2], [1, 2], 'simple compare (array)');
5078
5180
  compare({ a: [1, 2] }, { a: [1, 2] }, 'simple compare nested');
5079
5181
  compare(new Set(['3', 1234]), new Set(['3', 1234]), 'compare Sets');
5080
- const map1 = create$7();
5182
+ const map1 = create$a();
5081
5183
  map1.set(1, 2);
5082
5184
  map1.set('x', {});
5083
5185
  map1.set(98, 'tst');
@@ -5181,7 +5283,7 @@ const testSkipping = () => {
5181
5283
  };
5182
5284
 
5183
5285
  const testAsync = async () => {
5184
- await measureTimeAsync('time', () => create$2(r => setTimeout(r)));
5286
+ await measureTimeAsync('time', () => create$5(r => setTimeout(r)));
5185
5287
  await groupAsync('some description', () => wait(1));
5186
5288
  };
5187
5289
 
@@ -5209,23 +5311,32 @@ var testing = /*#__PURE__*/Object.freeze({
5209
5311
  * @module error
5210
5312
  */
5211
5313
 
5314
+ /* istanbul ignore next */
5212
5315
  /**
5213
5316
  * @param {string} s
5214
5317
  * @return {Error}
5215
5318
  */
5319
+ const create$4 = s => new Error(s);
5320
+
5216
5321
  /* istanbul ignore next */
5217
- const create$1 = s => new Error(s);
5322
+ /**
5323
+ * @throws {Error}
5324
+ * @return {never}
5325
+ */
5326
+ const unexpectedCase = () => {
5327
+ throw create$4('Unexpected case')
5328
+ };
5218
5329
 
5219
5330
  /* eslint-env browser */
5220
5331
 
5332
+ /* istanbul ignore next */
5221
5333
  /**
5222
5334
  * IDB Request to Promise transformer
5223
5335
  *
5224
5336
  * @param {IDBRequest} request
5225
5337
  * @return {Promise<any>}
5226
5338
  */
5227
- /* istanbul ignore next */
5228
- const rtop = request => create$2((resolve, reject) => {
5339
+ const rtop = request => create$5((resolve, reject) => {
5229
5340
  /* istanbul ignore next */
5230
5341
  // @ts-ignore
5231
5342
  request.onerror = event => reject(new Error(event.target.error));
@@ -5236,13 +5347,13 @@ const rtop = request => create$2((resolve, reject) => {
5236
5347
  request.onsuccess = event => resolve(event.target.result);
5237
5348
  });
5238
5349
 
5350
+ /* istanbul ignore next */
5239
5351
  /**
5240
5352
  * @param {string} name
5241
5353
  * @param {function(IDBDatabase):any} initDB Called when the database is first created
5242
5354
  * @return {Promise<IDBDatabase>}
5243
5355
  */
5244
- /* istanbul ignore next */
5245
- const openDB = (name, initDB) => create$2((resolve, reject) => {
5356
+ const openDB = (name, initDB) => create$5((resolve, reject) => {
5246
5357
  const request = indexedDB.open(name);
5247
5358
  /**
5248
5359
  * @param {any} event
@@ -5252,7 +5363,7 @@ const openDB = (name, initDB) => create$2((resolve, reject) => {
5252
5363
  /**
5253
5364
  * @param {any} event
5254
5365
  */
5255
- request.onerror = event => reject(create$1(event.target.error));
5366
+ request.onerror = event => reject(create$4(event.target.error));
5256
5367
  /* istanbul ignore next */
5257
5368
  request.onblocked = () => location.reload();
5258
5369
  /**
@@ -5273,82 +5384,82 @@ const openDB = (name, initDB) => create$2((resolve, reject) => {
5273
5384
  };
5274
5385
  });
5275
5386
 
5387
+ /* istanbul ignore next */
5276
5388
  /**
5277
5389
  * @param {string} name
5278
5390
  */
5279
- /* istanbul ignore next */
5280
5391
  const deleteDB = name => rtop(indexedDB.deleteDatabase(name));
5281
5392
 
5393
+ /* istanbul ignore next */
5282
5394
  /**
5283
5395
  * @param {IDBDatabase} db
5284
5396
  * @param {Array<Array<string>|Array<string|IDBObjectStoreParameters|undefined>>} definitions
5285
5397
  */
5286
- /* istanbul ignore next */
5287
5398
  const createStores = (db, definitions) => definitions.forEach(d =>
5288
5399
  // @ts-ignore
5289
5400
  db.createObjectStore.apply(db, d)
5290
5401
  );
5291
5402
 
5403
+ /* istanbul ignore next */
5292
5404
  /**
5293
5405
  * @param {IDBObjectStore} store
5294
5406
  * @param {String | number | ArrayBuffer | Date | Array<any> } key
5295
5407
  * @return {Promise<String | number | ArrayBuffer | Date | Array<any>>}
5296
5408
  */
5297
- /* istanbul ignore next */
5298
- const get = (store, key) =>
5409
+ const get$1 = (store, key) =>
5299
5410
  rtop(store.get(key));
5300
5411
 
5412
+ /* istanbul ignore next */
5301
5413
  /**
5302
5414
  * @param {IDBObjectStore} store
5303
5415
  * @param {String | number | ArrayBuffer | Date | IDBKeyRange | Array<any> } key
5304
5416
  */
5305
- /* istanbul ignore next */
5306
5417
  const del = (store, key) =>
5307
5418
  rtop(store.delete(key));
5308
5419
 
5420
+ /* istanbul ignore next */
5309
5421
  /**
5310
5422
  * @param {IDBObjectStore} store
5311
5423
  * @param {String | number | ArrayBuffer | Date | boolean} item
5312
5424
  * @param {String | number | ArrayBuffer | Date | Array<any>} [key]
5313
5425
  */
5314
- /* istanbul ignore next */
5315
5426
  const put = (store, item, key) =>
5316
5427
  rtop(store.put(item, key));
5317
5428
 
5429
+ /* istanbul ignore next */
5318
5430
  /**
5319
5431
  * @param {IDBObjectStore} store
5320
5432
  * @param {String | number | ArrayBuffer | Date | boolean} item
5321
5433
  * @param {String | number | ArrayBuffer | Date | Array<any>} key
5322
5434
  * @return {Promise<any>}
5323
5435
  */
5324
- /* istanbul ignore next */
5325
5436
  const add = (store, item, key) =>
5326
5437
  rtop(store.add(item, key));
5327
5438
 
5439
+ /* istanbul ignore next */
5328
5440
  /**
5329
5441
  * @param {IDBObjectStore} store
5330
5442
  * @param {String | number | ArrayBuffer | Date} item
5331
5443
  * @return {Promise<number>} Returns the generated key
5332
5444
  */
5333
- /* istanbul ignore next */
5334
5445
  const addAutoKey = (store, item) =>
5335
5446
  rtop(store.add(item));
5336
5447
 
5448
+ /* istanbul ignore next */
5337
5449
  /**
5338
5450
  * @param {IDBObjectStore} store
5339
5451
  * @param {IDBKeyRange} [range]
5340
5452
  * @return {Promise<Array<any>>}
5341
5453
  */
5342
- /* istanbul ignore next */
5343
5454
  const getAll = (store, range) =>
5344
5455
  rtop(store.getAll(range));
5345
5456
 
5457
+ /* istanbul ignore next */
5346
5458
  /**
5347
5459
  * @param {IDBObjectStore} store
5348
5460
  * @param {IDBKeyRange} [range]
5349
5461
  * @return {Promise<Array<any>>}
5350
5462
  */
5351
- /* istanbul ignore next */
5352
5463
  const getAllKeys = (store, range) =>
5353
5464
  rtop(store.getAllKeys(range));
5354
5465
 
@@ -5359,23 +5470,23 @@ const getAllKeys = (store, range) =>
5359
5470
  * @property {any} v Value
5360
5471
  */
5361
5472
 
5473
+ /* istanbul ignore next */
5362
5474
  /**
5363
5475
  * @param {IDBObjectStore} store
5364
5476
  * @param {IDBKeyRange} [range]
5365
5477
  * @return {Promise<Array<KeyValuePair>>}
5366
5478
  */
5367
- /* istanbul ignore next */
5368
5479
  const getAllKeysValues = (store, range) =>
5369
5480
  // @ts-ignore
5370
5481
  all([getAllKeys(store, range), getAll(store, range)]).then(([ks, vs]) => ks.map((k, i) => ({ k, v: vs[i] })));
5371
5482
 
5483
+ /* istanbul ignore next */
5372
5484
  /**
5373
5485
  * @param {any} request
5374
5486
  * @param {function(IDBCursorWithValue):void|boolean} f
5375
5487
  * @return {Promise<void>}
5376
5488
  */
5377
- /* istanbul ignore next */
5378
- const iterateOnRequest = (request, f) => create$2((resolve, reject) => {
5489
+ const iterateOnRequest = (request, f) => create$5((resolve, reject) => {
5379
5490
  /* istanbul ignore next */
5380
5491
  request.onerror = reject;
5381
5492
  /**
@@ -5390,6 +5501,7 @@ const iterateOnRequest = (request, f) => create$2((resolve, reject) => {
5390
5501
  };
5391
5502
  });
5392
5503
 
5504
+ /* istanbul ignore next */
5393
5505
  /**
5394
5506
  * Iterate on keys and values
5395
5507
  * @param {IDBObjectStore} store
@@ -5397,10 +5509,10 @@ const iterateOnRequest = (request, f) => create$2((resolve, reject) => {
5397
5509
  * @param {function(any,any):void|boolean} f Callback that receives (value, key)
5398
5510
  * @param {'next'|'prev'|'nextunique'|'prevunique'} direction
5399
5511
  */
5400
- /* istanbul ignore next */
5401
5512
  const iterate = (store, keyrange, f, direction = 'next') =>
5402
5513
  iterateOnRequest(store.openCursor(keyrange, direction), cursor => f(cursor.value, cursor.key));
5403
5514
 
5515
+ /* istanbul ignore next */
5404
5516
  /**
5405
5517
  * Iterate on the keys (no values)
5406
5518
  *
@@ -5409,26 +5521,25 @@ const iterate = (store, keyrange, f, direction = 'next') =>
5409
5521
  * @param {function(any):void|boolean} f callback that receives the key
5410
5522
  * @param {'next'|'prev'|'nextunique'|'prevunique'} direction
5411
5523
  */
5412
- /* istanbul ignore next */
5413
5524
  const iterateKeys = (store, keyrange, f, direction = 'next') =>
5414
5525
  iterateOnRequest(store.openKeyCursor(keyrange, direction), cursor => f(cursor.key));
5415
5526
 
5527
+ /* istanbul ignore next */
5416
5528
  /**
5417
5529
  * Open store from transaction
5418
5530
  * @param {IDBTransaction} t
5419
5531
  * @param {String} store
5420
5532
  * @returns {IDBObjectStore}
5421
5533
  */
5422
- /* istanbul ignore next */
5423
5534
  const getStore$1 = (t, store) => t.objectStore(store);
5424
5535
 
5536
+ /* istanbul ignore next */
5425
5537
  /**
5426
5538
  * @param {any} lower
5427
5539
  * @param {any} upper
5428
5540
  * @param {boolean} lowerOpen
5429
5541
  * @param {boolean} upperOpen
5430
5542
  */
5431
- /* istanbul ignore next */
5432
5543
  const createIDBKeyRangeBound = (lower, upper, lowerOpen, upperOpen) => IDBKeyRange.bound(lower, upper, lowerOpen, upperOpen);
5433
5544
 
5434
5545
  /* istanbul ignore next */
@@ -5506,19 +5617,19 @@ const testRetrieveElements = async () => {
5506
5617
  await iterateTests('range!=null', range);
5507
5618
 
5508
5619
  describe('idb.get');
5509
- const getV = await get(store, ['t', 1]);
5620
+ const getV = await get$1(store, ['t', 1]);
5510
5621
  assert(getV === 0);
5511
5622
  describe('idb.del');
5512
5623
  await del(store, ['t', 0]);
5513
- const getVDel = await get(store, ['t', 0]);
5624
+ const getVDel = await get$1(store, ['t', 0]);
5514
5625
  assert(getVDel === undefined);
5515
5626
  describe('idb.add');
5516
5627
  await add(store, 99, 42);
5517
- const idbVAdd = await get(store, 42);
5628
+ const idbVAdd = await get$1(store, 42);
5518
5629
  assert(idbVAdd === 99);
5519
5630
  describe('idb.addAutoKey');
5520
5631
  const key = await addAutoKey(store, 1234);
5521
- const retrieved = await get(store, key);
5632
+ const retrieved = await get$1(store, key);
5522
5633
  assert(retrieved === 1234);
5523
5634
  };
5524
5635
 
@@ -5968,7 +6079,7 @@ const measureP = (p, min, max) => {
5968
6079
  * @param {Promise<T>} p
5969
6080
  * @return {Promise<T>}
5970
6081
  */
5971
- const failsP = p => create$2((resolve, reject) => p.then(() => reject(create$1('Promise should fail')), resolve));
6082
+ const failsP = p => create$5((resolve, reject) => p.then(() => reject(create$4('Promise should fail')), resolve));
5972
6083
 
5973
6084
  /**
5974
6085
  * @param {t.TestCase} tc
@@ -5994,7 +6105,7 @@ const testRepeatPromise = async tc => {
5994
6105
  */
5995
6106
  const testispromise = tc => {
5996
6107
  assert(isPromise(new Promise(() => {})));
5997
- assert(isPromise(create$2(() => {})));
6108
+ assert(isPromise(create$5(() => {})));
5998
6109
  const rej = reject();
5999
6110
  assert(isPromise(rej));
6000
6111
  rej.catch(() => {});
@@ -6039,12 +6150,12 @@ class Queue {
6039
6150
  *
6040
6151
  * @return {Queue}
6041
6152
  */
6042
- const create = () => new Queue();
6153
+ const create$3 = () => new Queue();
6043
6154
 
6044
6155
  /**
6045
6156
  * @param {Queue} queue
6046
6157
  */
6047
- const isEmpty = queue => queue.start === null;
6158
+ const isEmpty$1 = queue => queue.start === null;
6048
6159
 
6049
6160
  /**
6050
6161
  * @param {Queue} queue
@@ -6069,12 +6180,15 @@ const dequeue = queue => {
6069
6180
  if (n !== null) {
6070
6181
  // @ts-ignore
6071
6182
  queue.start = n.next;
6183
+ if (queue.start === null) {
6184
+ queue.end = null;
6185
+ }
6072
6186
  return n
6073
6187
  }
6074
6188
  return null
6075
6189
  };
6076
6190
 
6077
- class QueueItem extends QueueNode {
6191
+ class QueueItem$1 extends QueueNode {
6078
6192
  /**
6079
6193
  * @param {number} v
6080
6194
  */
@@ -6087,51 +6201,62 @@ class QueueItem extends QueueNode {
6087
6201
  /**
6088
6202
  * @param {t.TestCase} tc
6089
6203
  */
6090
- const testEnqueueDequeue = tc => {
6204
+ const testEnqueueDequeue$1 = tc => {
6091
6205
  const N = 30;
6092
6206
  /**
6093
6207
  * @type {queue.Queue}
6094
6208
  */
6095
- const q = create();
6096
- assert(isEmpty(q));
6209
+ const q = create$3();
6210
+ assert(isEmpty$1(q));
6097
6211
  assert(dequeue(q) === null);
6098
6212
  for (let i = 0; i < N; i++) {
6099
- enqueue(q, new QueueItem(i));
6100
- assert(!isEmpty(q));
6213
+ enqueue(q, new QueueItem$1(i));
6214
+ assert(!isEmpty$1(q));
6101
6215
  }
6102
6216
  for (let i = 0; i < N; i++) {
6103
6217
  const item = /** @type {QueueItem} */ (dequeue(q));
6104
6218
  assert(item !== null && item.v === i);
6105
6219
  }
6220
+ assert(isEmpty$1(q));
6221
+ assert(dequeue(q) === null);
6222
+ for (let i = 0; i < N; i++) {
6223
+ enqueue(q, new QueueItem$1(i));
6224
+ assert(!isEmpty$1(q));
6225
+ }
6226
+ for (let i = 0; i < N; i++) {
6227
+ const item = /** @type {QueueItem} */ (dequeue(q));
6228
+ assert(item !== null && item.v === i);
6229
+ }
6230
+ assert(isEmpty$1(q));
6106
6231
  assert(dequeue(q) === null);
6107
6232
  };
6108
6233
 
6109
6234
  var queue = /*#__PURE__*/Object.freeze({
6110
6235
  __proto__: null,
6111
- testEnqueueDequeue: testEnqueueDequeue
6236
+ testEnqueueDequeue: testEnqueueDequeue$1
6112
6237
  });
6113
6238
 
6114
6239
  /**
6115
6240
  * @param {t.TestCase} tc
6116
6241
  */
6117
6242
  const testMap = tc => {
6118
- const m = create$7();
6243
+ const m = create$a();
6119
6244
  m.set(1, 2);
6120
6245
  m.set(2, 3);
6121
- assert(map$3(m, (value, key) => value * 2 + key).reduce(add$1) === 13);
6246
+ assert(map$4(m, (value, key) => value * 2 + key).reduce(add$1) === 13);
6122
6247
  let numberOfWrites = 0;
6123
6248
  const createT = () => {
6124
6249
  numberOfWrites++;
6125
6250
  return {}
6126
6251
  };
6127
- setIfUndefined(m, 3, createT);
6128
- setIfUndefined(m, 3, createT);
6129
- setIfUndefined(m, 3, createT);
6252
+ setIfUndefined$1(m, 3, createT);
6253
+ setIfUndefined$1(m, 3, createT);
6254
+ setIfUndefined$1(m, 3, createT);
6130
6255
  compare(copy(m), m);
6131
6256
  assert(numberOfWrites === 1);
6132
6257
  };
6133
6258
 
6134
- var map = /*#__PURE__*/Object.freeze({
6259
+ var map$1 = /*#__PURE__*/Object.freeze({
6135
6260
  __proto__: null,
6136
6261
  testMap: testMap
6137
6262
  });
@@ -6166,7 +6291,7 @@ const testTimeout = async tc => {
6166
6291
  set = true;
6167
6292
  });
6168
6293
  timeout$1.destroy();
6169
- await create$2(resolve => {
6294
+ await create$5(resolve => {
6170
6295
  timeout(10, resolve);
6171
6296
  });
6172
6297
  assert(set === false);
@@ -6204,7 +6329,7 @@ const testAnimationFrame = async tc => {
6204
6329
  * @param {t.TestCase} tc
6205
6330
  */
6206
6331
  const testIdleCallback = async tc => {
6207
- await create$2(resolve => {
6332
+ await create$5(resolve => {
6208
6333
  idleCallback(resolve);
6209
6334
  });
6210
6335
  };
@@ -6259,7 +6384,7 @@ var time = /*#__PURE__*/Object.freeze({
6259
6384
  * @param {t.TestCase} tc
6260
6385
  */
6261
6386
  const testPair = tc => {
6262
- const ps = [create$5(1, 2), create$5(3, 4), createReversed(6, 5)];
6387
+ const ps = [create$8(1, 2), create$8(3, 4), createReversed(6, 5)];
6263
6388
  describe('Counting elements in pair list');
6264
6389
  let countLeft = 0;
6265
6390
  let countRight = 0;
@@ -6269,8 +6394,8 @@ const testPair = tc => {
6269
6394
  });
6270
6395
  assert(countLeft === 9);
6271
6396
  assert(countRight === 12);
6272
- assert(countLeft === map$2(ps, left => left).reduce(add$1));
6273
- assert(countRight === map$2(ps, (left, right) => right).reduce(add$1));
6397
+ assert(countLeft === map$3(ps, left => left).reduce(add$1));
6398
+ assert(countRight === map$3(ps, (left, right) => right).reduce(add$1));
6274
6399
  };
6275
6400
 
6276
6401
  var pair = /*#__PURE__*/Object.freeze({
@@ -6282,7 +6407,7 @@ var pair = /*#__PURE__*/Object.freeze({
6282
6407
  * @param {t.TestCase} tc
6283
6408
  */
6284
6409
  const testObject = tc => {
6285
- assert(create$4().constructor === undefined, 'object.create creates an empty object without constructor');
6410
+ assert(create$7().constructor === undefined, 'object.create creates an empty object without constructor');
6286
6411
  describe('object.equalFlat');
6287
6412
  assert(equalFlat({}, {}), 'comparing equal objects');
6288
6413
  assert(equalFlat({ x: 1 }, { x: 1 }), 'comparing equal objects');
@@ -6303,7 +6428,7 @@ const testObject = tc => {
6303
6428
  forEach({ x: 1, y: 3 }, (v, k) => { forEachSum += v; });
6304
6429
  assert(forEachSum === 4);
6305
6430
  describe('object.map');
6306
- assert(map$1({ x: 1, z: 5 }, (v, k) => v).reduce(add$1) === 6);
6431
+ assert(map$2({ x: 1, z: 5 }, (v, k) => v).reduce(add$1) === 6);
6307
6432
  describe('object.length');
6308
6433
  assert(length$1({}) === 0);
6309
6434
  assert(length$1({ x: 1 }) === 1);
@@ -6403,6 +6528,50 @@ var buffer = /*#__PURE__*/Object.freeze({
6403
6528
  testAnyEncoding: testAnyEncoding
6404
6529
  });
6405
6530
 
6531
+ /**
6532
+ * Utility module to work with sets.
6533
+ *
6534
+ * @module set
6535
+ */
6536
+
6537
+ const create$2 = () => new Set();
6538
+
6539
+ /**
6540
+ * @template T
6541
+ * @param {Set<T>} set
6542
+ * @return {T}
6543
+ */
6544
+ const first = set => {
6545
+ return set.values().next().value || undefined
6546
+ };
6547
+
6548
+ /**
6549
+ * @template T
6550
+ * @param {Iterable<T>} entries
6551
+ * @return {Set<T>}
6552
+ */
6553
+ const from = entries => {
6554
+ return new Set(entries)
6555
+ };
6556
+
6557
+ /**
6558
+ * @template T
6559
+ * @param {t.TestCase} tc
6560
+ */
6561
+ const testFirst = tc => {
6562
+ const two = from(['a', 'b']);
6563
+ const one = from(['b']);
6564
+ const zero = create$2();
6565
+ assert(first(two) === 'a');
6566
+ assert(first(one) === 'b');
6567
+ assert(first(zero) === undefined);
6568
+ };
6569
+
6570
+ var set$1 = /*#__PURE__*/Object.freeze({
6571
+ __proto__: null,
6572
+ testFirst: testFirst
6573
+ });
6574
+
6406
6575
  /**
6407
6576
  * Efficient sort implementations.
6408
6577
  *
@@ -6695,7 +6864,7 @@ const decodeQueryParams = url => {
6695
6864
  * @return {string}
6696
6865
  */
6697
6866
  const encodeQueryParams = params =>
6698
- map$1(params, (val, key) => `${encodeURIComponent(key)}=${encodeURIComponent(val)}`).join('&');
6867
+ map$2(params, (val, key) => `${encodeURIComponent(key)}=${encodeURIComponent(val)}`).join('&');
6699
6868
 
6700
6869
  /**
6701
6870
  * @param {Object<string,any>} params
@@ -6859,6 +7028,459 @@ var storage = /*#__PURE__*/Object.freeze({
6859
7028
  testStorageModule: testStorageModule
6860
7029
  });
6861
7030
 
7031
+ class ListNode {
7032
+ constructor () {
7033
+ /**
7034
+ * @type {this|null}
7035
+ */
7036
+ this.next = null;
7037
+ /**
7038
+ * @type {this|null}
7039
+ */
7040
+ this.prev = null;
7041
+ }
7042
+ }
7043
+
7044
+ /**
7045
+ * @template {ListNode} N
7046
+ */
7047
+ class List {
7048
+ constructor () {
7049
+ /**
7050
+ * @type {N | null}
7051
+ */
7052
+ this.start = null;
7053
+ /**
7054
+ * @type {N | null}
7055
+ */
7056
+ this.end = null;
7057
+ }
7058
+ }
7059
+
7060
+ /**
7061
+ * @note The queue implementation is experimental and unfinished.
7062
+ * Don't use this in production yet.
7063
+ *
7064
+ * @template {ListNode} N
7065
+ *
7066
+ * @return {List<N>}
7067
+ */
7068
+ const create$1 = () => new List();
7069
+
7070
+ /**
7071
+ * @template {ListNode} N
7072
+ *
7073
+ * @param {List<N>} queue
7074
+ */
7075
+ const isEmpty = queue => queue.start === null;
7076
+
7077
+ /**
7078
+ * Remove a single node from the queue. Only works with Queues that operate on Doubly-linked lists of nodes.
7079
+ *
7080
+ * @template {ListNode} N
7081
+ *
7082
+ * @param {List<N>} queue
7083
+ * @param {N} node
7084
+ */
7085
+ const removeNode = (queue, node) => {
7086
+ const prev = node.prev;
7087
+ const next = node.next;
7088
+ if (prev) {
7089
+ prev.next = next;
7090
+ } else {
7091
+ queue.start = next;
7092
+ }
7093
+ if (next) {
7094
+ next.prev = prev;
7095
+ } else {
7096
+ queue.end = prev;
7097
+ }
7098
+ return node
7099
+ };
7100
+
7101
+ /**
7102
+ * @template {ListNode} N
7103
+ *
7104
+ * @param {List<N>} queue
7105
+ * @param {N| null} left
7106
+ * @param {N| null} right
7107
+ * @param {N} node
7108
+ */
7109
+ const insertBetween = (queue, left, right, node) => {
7110
+ /* istanbul ignore if */
7111
+ if (left != null && left.next !== right) {
7112
+ throw unexpectedCase()
7113
+ }
7114
+ if (left) {
7115
+ left.next = node;
7116
+ } else {
7117
+ queue.start = node;
7118
+ }
7119
+ if (right) {
7120
+ right.prev = node;
7121
+ } else {
7122
+ queue.end = node;
7123
+ }
7124
+ node.prev = left;
7125
+ node.next = right;
7126
+ };
7127
+
7128
+ /**
7129
+ * @template {ListNode} N
7130
+ *
7131
+ * @param {List<N>} queue
7132
+ * @param {N} n
7133
+ */
7134
+ const pushEnd = (queue, n) =>
7135
+ insertBetween(queue, queue.end, null, n);
7136
+
7137
+ /**
7138
+ * @template {ListNode} N
7139
+ *
7140
+ * @param {List<N>} queue
7141
+ * @param {N} n
7142
+ */
7143
+ const pushFront = (queue, n) =>
7144
+ insertBetween(queue, null, queue.start, n);
7145
+
7146
+ /**
7147
+ * @template {ListNode} N
7148
+ *
7149
+ * @param {List<N>} list
7150
+ * @return {N| null}
7151
+ */
7152
+ const popFront = list =>
7153
+ list.start ? removeNode(list, list.start) : null;
7154
+
7155
+ /**
7156
+ * @template {ListNode} N
7157
+ *
7158
+ * @param {List<N>} list
7159
+ * @return {N| null}
7160
+ */
7161
+ const popEnd = list =>
7162
+ list.end ? removeNode(list, list.end) : null;
7163
+
7164
+ /**
7165
+ * @template {ListNode} N
7166
+ * @template M
7167
+ *
7168
+ * @param {List<N>} list
7169
+ * @param {function(N):M} f
7170
+ * @return {Array<M>}
7171
+ */
7172
+ const map = (list, f) => {
7173
+ /**
7174
+ * @type {Array<M>}
7175
+ */
7176
+ const arr = [];
7177
+ let n = list.start;
7178
+ while (n) {
7179
+ arr.push(f(n));
7180
+ n = n.next;
7181
+ }
7182
+ return arr
7183
+ };
7184
+
7185
+ class QueueItem extends ListNode {
7186
+ /**
7187
+ * @param {number} v
7188
+ */
7189
+ constructor (v) {
7190
+ super();
7191
+ this.v = v;
7192
+ }
7193
+ }
7194
+
7195
+ /**
7196
+ * @param {t.TestCase} tc
7197
+ */
7198
+ const testEnqueueDequeue = tc => {
7199
+ const N = 30;
7200
+ /**
7201
+ * @type {list.List<QueueItem>}
7202
+ */
7203
+ const q = create$1();
7204
+ assert(isEmpty(q));
7205
+ assert(popFront(q) === null);
7206
+ for (let i = 0; i < N; i++) {
7207
+ pushEnd(q, new QueueItem(i));
7208
+ assert(!isEmpty(q));
7209
+ }
7210
+ for (let i = 0; i < N; i++) {
7211
+ const item = /** @type {QueueItem} */ (popFront(q));
7212
+ assert(item !== null && item.v === i);
7213
+ }
7214
+ assert(isEmpty(q));
7215
+ assert(popFront(q) === null);
7216
+ for (let i = 0; i < N; i++) {
7217
+ pushEnd(q, new QueueItem(i));
7218
+ assert(!isEmpty(q));
7219
+ }
7220
+ for (let i = 0; i < N; i++) {
7221
+ const item = /** @type {QueueItem} */ (popFront(q));
7222
+ assert(item !== null && item.v === i);
7223
+ }
7224
+ assert(isEmpty(q));
7225
+ assert(popFront(q) === null);
7226
+ };
7227
+
7228
+ /**
7229
+ * @param {t.TestCase} tc
7230
+ */
7231
+ const testSelectivePop = tc => {
7232
+ /**
7233
+ * @type {list.List<QueueItem>}
7234
+ */
7235
+ const l = create$1();
7236
+ pushFront(l, new QueueItem(1));
7237
+ pushEnd(l, new QueueItem(3));
7238
+ const middleNode = new QueueItem(2);
7239
+ insertBetween(l, l.start, l.end, middleNode);
7240
+ compare(map(l, n => n.v), [1, 2, 3]);
7241
+ assert(removeNode(l, middleNode) === middleNode);
7242
+ compare(/** @type {QueueItem} */ (popEnd(l)).v, 3);
7243
+ compare(/** @type {QueueItem} */ (popEnd(l)).v, 1);
7244
+ compare(popEnd(l), null);
7245
+ assert(l.start === null);
7246
+ assert(l.end === null);
7247
+ };
7248
+
7249
+ var list = /*#__PURE__*/Object.freeze({
7250
+ __proto__: null,
7251
+ testEnqueueDequeue: testEnqueueDequeue,
7252
+ testSelectivePop: testSelectivePop
7253
+ });
7254
+
7255
+ /**
7256
+ * @template K, V
7257
+ *
7258
+ * @implements {list.ListNode}
7259
+ */
7260
+ class Entry {
7261
+ /**
7262
+ * @param {K} key
7263
+ * @param {V | Promise<V>} val
7264
+ */
7265
+ constructor (key, val) {
7266
+ /**
7267
+ * @type {this | null}
7268
+ */
7269
+ this.prev = null;
7270
+ /**
7271
+ * @type {this | null}
7272
+ */
7273
+ this.next = null;
7274
+ this.created = getUnixTime();
7275
+ this.val = val;
7276
+ this.key = key;
7277
+ }
7278
+ }
7279
+
7280
+ /**
7281
+ * @template K, V
7282
+ */
7283
+ class Cache {
7284
+ /**
7285
+ * @param {number} timeout
7286
+ */
7287
+ constructor (timeout) {
7288
+ this.timeout = timeout;
7289
+ /**
7290
+ * @type list.List<Entry<K, V>>
7291
+ */
7292
+ this._q = create$1();
7293
+ /**
7294
+ * @type {Map<K, Entry<K, V>>}
7295
+ */
7296
+ this._map = create$a();
7297
+ }
7298
+ }
7299
+
7300
+ /**
7301
+ * @template K, V
7302
+ *
7303
+ * @param {Cache<K, V>} cache
7304
+ * @return {number} Returns the current timestamp
7305
+ */
7306
+ const removeStale = cache => {
7307
+ const now = getUnixTime();
7308
+ const q = cache._q;
7309
+ while (q.start && now - q.start.created > cache.timeout) {
7310
+ cache._map.delete(q.start.key);
7311
+ popFront(q);
7312
+ }
7313
+ return now
7314
+ };
7315
+
7316
+ /**
7317
+ * @template K, V
7318
+ *
7319
+ * @param {Cache<K, V>} cache
7320
+ * @param {K} key
7321
+ * @param {V} value
7322
+ */
7323
+ const set = (cache, key, value) => {
7324
+ const now = removeStale(cache);
7325
+ const q = cache._q;
7326
+ const n = cache._map.get(key);
7327
+ if (n) {
7328
+ removeNode(q, n);
7329
+ pushEnd(q, n);
7330
+ n.created = now;
7331
+ n.val = value;
7332
+ } else {
7333
+ const node = new Entry(key, value);
7334
+ pushEnd(q, node);
7335
+ cache._map.set(key, node);
7336
+ }
7337
+ };
7338
+
7339
+ /**
7340
+ * @template K, V
7341
+ *
7342
+ * @param {Cache<K, V>} cache
7343
+ * @param {K} key
7344
+ * @return {Entry<K, V> | undefined}
7345
+ */
7346
+ const getNode = (cache, key) => {
7347
+ const now = removeStale(cache);
7348
+ const q = cache._q;
7349
+ const n = cache._map.get(key);
7350
+ if (n) {
7351
+ removeNode(q, n);
7352
+ pushEnd(q, n);
7353
+ n.created = now;
7354
+ return n
7355
+ }
7356
+ };
7357
+
7358
+ /**
7359
+ * @template K, V
7360
+ *
7361
+ * @param {Cache<K, V>} cache
7362
+ * @param {K} key
7363
+ * @return {V | undefined}
7364
+ */
7365
+ const get = (cache, key) => {
7366
+ const n = getNode(cache, key);
7367
+ return n && !(n.val instanceof Promise) ? n.val : undefined
7368
+ };
7369
+
7370
+ /**
7371
+ * Works well in conjunktion with setIfUndefined which has an async init function.
7372
+ * Using getAsync & setIfUndefined ensures that the init function is only called once.
7373
+ *
7374
+ * @template K, V
7375
+ *
7376
+ * @param {Cache<K, V>} cache
7377
+ * @param {K} key
7378
+ * @return {V | Promise<V> | undefined}
7379
+ */
7380
+ const getAsync = (cache, key) => {
7381
+ const n = getNode(cache, key);
7382
+ return n ? n.val : undefined
7383
+ };
7384
+
7385
+ /**
7386
+ * @template K, V
7387
+ *
7388
+ * @param {Cache<K, V>} cache
7389
+ * @param {K} key
7390
+ * @param {function():Promise<V>} init
7391
+ * @return {Promise<V> | V}
7392
+ */
7393
+ const setIfUndefined = (cache, key, init) => {
7394
+ const now = removeStale(cache);
7395
+ const q = cache._q;
7396
+ const n = cache._map.get(key);
7397
+ if (n) {
7398
+ removeNode(q, n);
7399
+ pushEnd(q, n);
7400
+ n.created = now;
7401
+ return n.val
7402
+ } else {
7403
+ const p = init();
7404
+ const node = new Entry(key, p);
7405
+ pushEnd(q, node);
7406
+ cache._map.set(key, node);
7407
+ p.then(v => {
7408
+ if (p === node.val) {
7409
+ node.val = v;
7410
+ }
7411
+ });
7412
+ return p
7413
+ }
7414
+ };
7415
+
7416
+ /**
7417
+ * @param {number} timeout
7418
+ */
7419
+ const create = timeout => new Cache(timeout);
7420
+
7421
+ /**
7422
+ * @param {t.TestCase} tc
7423
+ */
7424
+ const testCache = async tc => {
7425
+ /**
7426
+ * @type {cache.Cache<string, string>}
7427
+ */
7428
+ const c = create(50);
7429
+ set(c, 'a', '1');
7430
+ assert(get(c, 'a') === '1');
7431
+ assert(await getAsync(c, 'a') === '1');
7432
+ const p = setIfUndefined(c, 'b', () => resolveWith('2'));
7433
+ const q = setIfUndefined(c, 'b', () => resolveWith('3'));
7434
+ assert(p === q);
7435
+ assert(get(c, 'b') == null);
7436
+ assert(getAsync(c, 'b') === p);
7437
+ assert(await p === '2');
7438
+ assert(get(c, 'b') === '2');
7439
+ assert(getAsync(c, 'b') === '2');
7440
+
7441
+ await wait(5); // keys shouldn't be timed out yet
7442
+ assert(get(c, 'a') === '1');
7443
+ assert(get(c, 'b') === '2');
7444
+
7445
+ /**
7446
+ * @type {any}
7447
+ */
7448
+ const m = c._map;
7449
+ const aTimestamp1 = m.get('a').created;
7450
+ const bTimestamp1 = m.get('b').created;
7451
+
7452
+ // write new values and check later if the creation-timestamp was updated
7453
+ set(c, 'a', '11');
7454
+ await setIfUndefined(c, 'b', () => resolveWith('22')); // this shouldn't override, but update the timestamp
7455
+
7456
+ await wait(5); // keys should be updated and not timed out. Hence the creation time should be updated
7457
+ assert(get(c, 'a') === '11');
7458
+ assert(get(c, 'b') === '2');
7459
+ // timestamps should be updated
7460
+ assert(aTimestamp1 !== m.get('a').created);
7461
+ assert(bTimestamp1 !== m.get('b').created);
7462
+
7463
+ await wait(60); // now the keys should be timed-out
7464
+
7465
+ assert(get(c, 'a') == null);
7466
+ assert(getAsync(c, 'b') == null);
7467
+
7468
+ assert(c._map.size === 0);
7469
+ assert(c._q.start === null && c._q.end === null);
7470
+
7471
+ // test edge case of setIfUndefined
7472
+ const xp = setIfUndefined(c, 'a', () => resolve('x'));
7473
+ set(c, 'a', 'y');
7474
+ await xp;
7475
+ // 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.
7476
+ assert(get(c, 'a') === 'y');
7477
+ };
7478
+
7479
+ var cache = /*#__PURE__*/Object.freeze({
7480
+ __proto__: null,
7481
+ testCache: testCache
7482
+ });
7483
+
6862
7484
  /* istanbul ignore if */
6863
7485
  if (isBrowser) {
6864
7486
  createVConsole(document.body);
@@ -6878,7 +7500,7 @@ runTests({
6878
7500
  random,
6879
7501
  promise,
6880
7502
  queue,
6881
- map,
7503
+ map: map$1,
6882
7504
  eventloop,
6883
7505
  time,
6884
7506
  pair,
@@ -6886,11 +7508,14 @@ runTests({
6886
7508
  math,
6887
7509
  number,
6888
7510
  buffer,
7511
+ set: set$1,
6889
7512
  sort,
6890
7513
  url,
6891
7514
  metric,
6892
7515
  func,
6893
- storage
7516
+ storage,
7517
+ list,
7518
+ cache
6894
7519
  }).then(success => {
6895
7520
  /* istanbul ignore next */
6896
7521
  if (isNode) {