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.
Files changed (156) hide show
  1. package/README.md +128 -72
  2. package/bin/gendocs.js +1 -1
  3. package/cache.d.ts +51 -0
  4. package/cache.d.ts.map +1 -0
  5. package/cache.js +197 -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 +205 -0
  23. package/dist/cache.cjs.map +1 -0
  24. package/dist/cache.d.ts +51 -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 +779 -125
  104. package/dist/test.cjs.map +1 -1
  105. package/dist/test.js +780 -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 +15 -3
  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.js CHANGED
@@ -15,7 +15,7 @@
15
15
  *
16
16
  * @function
17
17
  */
18
- const create$7 = () => new Map();
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$7();
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$3 = (m, f) => {
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$7();
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$7()
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$7();
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$6 = Symbol;
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$5 = (left, right) => new Pair(left, right);
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$2 = (arr, f) => arr.map(p => f(p.left, p.right));
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$3(m, (value, key) => `${key}:${value};`).join('');
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$4 = () => Object.create(null);
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$1 = (obj, f) => {
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$6();
1054
- const UNBOLD = create$6();
1055
- const BLUE = create$6();
1056
- const GREY = create$6();
1057
- const GREEN = create$6();
1058
- const RED = create$6();
1059
- const PURPLE = create$6();
1060
- const ORANGE = create$6();
1061
- const UNCOLOR = create$6();
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$5('font-weight', 'bold'),
1068
- [UNBOLD]: create$5('font-weight', 'normal'),
1069
- [BLUE]: create$5('color', 'blue'),
1070
- [GREEN]: create$5('color', 'green'),
1071
- [GREY]: create$5('color', 'grey'),
1072
- [RED]: create$5('color', 'red'),
1073
- [PURPLE]: create$5('color', 'purple'),
1074
- [ORANGE]: create$5('color', 'orange'), // not well supported in chrome when debugging node with inspector - TODO: deprecate
1075
- [UNCOLOR]: create$5('color', 'black')
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$7();
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$5('style', mapToStyleString(currentStyle))], [text(arg)]);
1292
+ const span = element('span', [create$8('style', mapToStyleString(currentStyle))], [text(arg)]);
1277
1293
  if (span.innerHTML === '') {
1278
1294
  span.innerHTML = '&nbsp;';
1279
1295
  }
@@ -1319,10 +1335,10 @@
1319
1335
  */
1320
1336
  group (args, collapsed = false) {
1321
1337
  enqueue$1(() => {
1322
- const triangleDown = element('span', [create$5('hidden', collapsed), create$5('style', 'color:grey;font-size:120%;')], [text('▼')]);
1323
- const triangleRight = element('span', [create$5('hidden', !collapsed), create$5('style', 'color:grey;font-size:125%;')], [text('▶')]);
1324
- const content = element('div', [create$5('style', `${lineStyle};padding-left:${this.depth * 10}px`)], [triangleDown, triangleRight, text(' ')].concat(_computeLineSpans(args)));
1325
- const nextContainer = element('div', [create$5('hidden', collapsed)]);
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$5('style', `${lineStyle};padding-left:${this.depth * 10}px`)], _computeLineSpans(args))]);
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$5('src', url), create$5('height', `${round(height * 1.5)}px`)])]);
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
- if (left !== a.length || left !== b.length) {
1449
- // Only check right if a !== b
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
- if (left !== a.length || left !== b.length) {
1489
- // Only check right if a !== b
1490
- while (right + left < a.length && right + left < b.length && compare(a[a.length - right - 1], b[b.length - right - 1])) {
1491
- right++;
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$3 = seed => new DefaultPRNG(seed);
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$2 = f => /** @type {Promise<T>} */ (new Promise(f));
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$2((resolve, reject) => {
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$2((resolve, reject) => setTimeout(resolve, timeout));
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$3(this.seed);
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 = simpleDiff(a, b);
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$1(tests, mod => map$1(mod, f => /* istanbul ignore next */ f ? 1 : 0).reduce(add$1, 0)).reduce(add$1, 0);
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 = `${a.slice(0, change.index)}${change.insert}${a.slice(change.index + change.remove)}`;
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$7();
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$2(r => setTimeout(r)));
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
- const create$1 = s => new Error(s);
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
- /* istanbul ignore next */
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
- /* istanbul ignore next */
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$1(event.target.error));
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
- /* istanbul ignore next */
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
- /* istanbul ignore next */
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$2((resolve, reject) => p.then(() => reject(create$1('Promise should fail')), resolve));
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$2(() => {})));
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$7();
6268
+ const m = create$a();
6144
6269
  m.set(1, 2);
6145
6270
  m.set(2, 3);
6146
- assert(map$3(m, (value, key) => value * 2 + key).reduce(add$1) === 13);
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$2(resolve => {
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$2(resolve => {
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$5(1, 2), create$5(3, 4), createReversed(6, 5)];
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$2(ps, left => left).reduce(add$1));
6298
- assert(countRight === map$2(ps, (left, right) => right).reduce(add$1));
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$4().constructor === undefined, 'object.create creates an empty object without constructor');
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$1({ x: 1, z: 5 }, (v, k) => v).reduce(add$1) === 6);
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$1(params, (val, key) => `${encodeURIComponent(key)}=${encodeURIComponent(val)}`).join('&');
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