lib0 0.2.43 → 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 (104) hide show
  1. package/README.md +49 -0
  2. package/cache.d.ts +50 -0
  3. package/cache.d.ts.map +1 -0
  4. package/cache.js +178 -0
  5. package/cache.test.d.ts +3 -0
  6. package/cache.test.d.ts.map +1 -0
  7. package/diff.d.ts +5 -0
  8. package/diff.d.ts.map +1 -1
  9. package/diff.js +47 -10
  10. package/diff.test.d.ts +1 -0
  11. package/diff.test.d.ts.map +1 -1
  12. package/dist/{broadcastchannel-044f32d2.cjs → broadcastchannel-7da37795.cjs} +2 -2
  13. package/dist/{broadcastchannel-044f32d2.cjs.map → broadcastchannel-7da37795.cjs.map} +1 -1
  14. package/dist/broadcastchannel.cjs +4 -4
  15. package/dist/{buffer-49880125.cjs → buffer-b0dea3b0.cjs} +3 -3
  16. package/dist/{buffer-49880125.cjs.map → buffer-b0dea3b0.cjs.map} +1 -1
  17. package/dist/buffer.cjs +3 -3
  18. package/dist/cache.cjs +185 -0
  19. package/dist/cache.cjs.map +1 -0
  20. package/dist/cache.d.ts +50 -0
  21. package/dist/cache.d.ts.map +1 -0
  22. package/dist/cache.test.d.ts +3 -0
  23. package/dist/cache.test.d.ts.map +1 -0
  24. package/dist/component.cjs +2 -2
  25. package/dist/decoding.cjs +3 -3
  26. package/dist/{diff-75787d87.cjs → diff-233747fa.cjs} +51 -12
  27. package/dist/diff-233747fa.cjs.map +1 -0
  28. package/dist/diff.cjs +2 -1
  29. package/dist/diff.cjs.map +1 -1
  30. package/dist/diff.d.ts +5 -0
  31. package/dist/diff.d.ts.map +1 -1
  32. package/dist/diff.test.d.ts +1 -0
  33. package/dist/diff.test.d.ts.map +1 -1
  34. package/dist/dom.d.ts.map +1 -1
  35. package/dist/encoding.cjs +3 -3
  36. package/dist/{environment-7e2ffaea.cjs → environment-60b83194.cjs} +2 -2
  37. package/dist/{environment-7e2ffaea.cjs.map → environment-60b83194.cjs.map} +1 -1
  38. package/dist/environment.cjs +2 -2
  39. package/dist/index.cjs +9 -9
  40. package/dist/list.cjs +172 -0
  41. package/dist/list.cjs.map +1 -0
  42. package/dist/list.d.ts +33 -0
  43. package/dist/list.d.ts.map +1 -0
  44. package/dist/list.test.d.ts +4 -0
  45. package/dist/list.test.d.ts.map +1 -0
  46. package/dist/{logging-7cc36806.cjs → logging-f6d41f58.cjs} +2 -2
  47. package/dist/{logging-7cc36806.cjs.map → logging-f6d41f58.cjs.map} +1 -1
  48. package/dist/logging.cjs +3 -3
  49. package/dist/observable.cjs +1 -1
  50. package/dist/{prng-97174619.cjs → prng-25602bac.cjs} +3 -3
  51. package/dist/{prng-97174619.cjs.map → prng-25602bac.cjs.map} +1 -1
  52. package/dist/prng.cjs +4 -4
  53. package/dist/queue.cjs +3 -0
  54. package/dist/queue.cjs.map +1 -1
  55. package/dist/queue.d.ts.map +1 -1
  56. package/dist/queue.test.d.ts.map +1 -1
  57. package/dist/set-b596ef38.cjs +49 -0
  58. package/dist/set-b596ef38.cjs.map +1 -0
  59. package/dist/set.cjs +3 -1
  60. package/dist/set.cjs.map +1 -1
  61. package/dist/set.d.ts +2 -0
  62. package/dist/set.d.ts.map +1 -1
  63. package/dist/set.test.d.ts +2 -0
  64. package/dist/set.test.d.ts.map +1 -1
  65. package/dist/{string-f3c3d805.cjs → string-ad04f734.cjs} +12 -2
  66. package/dist/{string-f3c3d805.cjs.map → string-ad04f734.cjs.map} +1 -1
  67. package/dist/string.cjs +2 -1
  68. package/dist/string.cjs.map +1 -1
  69. package/dist/string.d.ts +1 -0
  70. package/dist/string.d.ts.map +1 -1
  71. package/dist/string.test.d.ts +1 -0
  72. package/dist/string.test.d.ts.map +1 -1
  73. package/dist/test.cjs +721 -101
  74. package/dist/test.cjs.map +1 -1
  75. package/dist/test.js +721 -101
  76. package/dist/test.js.map +1 -1
  77. package/dist/testing.cjs +6 -6
  78. package/dist/{websocket-bfe7f545.cjs → websocket-08bd4c7b.cjs} +1 -1
  79. package/dist/{websocket-bfe7f545.cjs.map → websocket-08bd4c7b.cjs.map} +1 -1
  80. package/dist/websocket.cjs +2 -2
  81. package/dom.d.ts.map +1 -1
  82. package/list.d.ts +33 -0
  83. package/list.d.ts.map +1 -0
  84. package/list.js +155 -0
  85. package/list.test.d.ts +4 -0
  86. package/list.test.d.ts.map +1 -0
  87. package/package.json +13 -1
  88. package/queue.d.ts.map +1 -1
  89. package/queue.js +3 -0
  90. package/queue.test.d.ts.map +1 -1
  91. package/set.d.ts +2 -0
  92. package/set.d.ts.map +1 -1
  93. package/set.js +18 -0
  94. package/set.test.d.ts +2 -0
  95. package/set.test.d.ts.map +1 -1
  96. package/string.d.ts +1 -0
  97. package/string.d.ts.map +1 -1
  98. package/string.js +8 -0
  99. package/string.test.d.ts +1 -0
  100. package/string.test.d.ts.map +1 -1
  101. package/test.js +7 -1
  102. package/dist/diff-75787d87.cjs.map +0 -1
  103. package/dist/set-7ae96d21.cjs +0 -27
  104. package/dist/set-7ae96d21.cjs.map +0 -1
package/README.md CHANGED
@@ -203,6 +203,20 @@ See encoding.writeAny for more information.</p></dd>
203
203
  <dd><p>Decode an any-encoded value.</p></dd>
204
204
  </dl>
205
205
  </details>
206
+ <details><summary><b>[lib0/cached-map]</b> An implementation of a map which has keys that expire.</summary>
207
+ <pre>import * as cached-map from 'lib0/cache'</pre>
208
+ <dl>
209
+ <b><code>new cached-map.Cache(timeout: number)</code></b><br>
210
+ <b><code>cached-map.removeStale(cache: module:cache.Cache&lt;K, V&gt;): number</code></b><br>
211
+ <b><code>cached-map.set(cache: module:cache.Cache&lt;K, V&gt;, key: K, value: V)</code></b><br>
212
+ <b><code>cached-map.get(cache: module:cache.Cache&lt;K, V&gt;, key: K): V | undefined</code></b><br>
213
+ <b><code>cached-map.getAsync(cache: module:cache.Cache&lt;K, V&gt;, key: K): V | Promise&lt;V&gt; | undefined</code></b><br>
214
+ <dd><p>Works well in conjunktion with setIfUndefined which has an async init function.
215
+ Using getAsync &amp; setIfUndefined ensures that the init function is only called once.</p></dd>
216
+ <b><code>cached-map.setIfUndefined(cache: module:cache.Cache&lt;K, V&gt;, key: K, init: function():Promise&lt;V&gt;): Promise&lt;V&gt; | V</code></b><br>
217
+ <b><code>cached-map.create(timeout: number)</code></b><br>
218
+ </dl>
219
+ </details>
206
220
  <details><summary><b>[lib0/component]</b> Web components.</summary>
207
221
  <pre>import * as component from 'lib0/component'</pre>
208
222
  <dl>
@@ -387,6 +401,8 @@ efficient, but not very sophisticated.</p></dd>
387
401
  efficient, but not very sophisticated.</p>
388
402
  <p>Note: This is basically the same function as above. Another function was created so that the runtime
389
403
  can better optimize these function calls.</p></dd>
404
+ <b><code>diff.simpleDiffStringWithCursor(a: string, b: string, cursor: number)</code></b><br>
405
+ <dd><p>Diff text and try to diff at the current cursor position.</p></dd>
390
406
  </dl>
391
407
  </details>
392
408
  <details><summary><b>[lib0/dom]</b> Utility module to work with the DOM.</summary>
@@ -787,6 +803,36 @@ In practice, when decoding several million small strings, the GC will kick in mo
787
803
  <dd><p>Parse JSON object.</p></dd>
788
804
  </dl>
789
805
  </details>
806
+ <details><summary><b>[lib0/list]</b> </summary>
807
+ <pre>import * as list from 'lib0/list'</pre>
808
+ <dl>
809
+ <b><code>new e#ListNode()</code></b><br>
810
+ <b><code>e#next: this|null</code></b><br>
811
+ <b><code>e#prev: this|null</code></b><br>
812
+ <b><code>new st()</code></b><br>
813
+ <b><code>art: N | null</code></b><br>
814
+ <b><code>d: N | null</code></b><br>
815
+ <b><code>(): module:list.List&lt;N&gt;</code></b><br>
816
+ <b><code>()</code></b><br>
817
+ <b><code>(queue: module:list.List&lt;N&gt;)</code></b><br>
818
+ <b><code>()</code></b><br>
819
+ <b><code>ode(queue: module:list.List&lt;N&gt;, node: N)</code></b><br>
820
+ <dd><p>Remove a single node from the queue. Only works with Queues that operate on Doubly-linked lists of nodes.</p></dd>
821
+ <b><code>ode()</code></b><br>
822
+ <b><code>etween(queue: module:list.List&lt;N&gt;, left: N| null, right: N| null, node: N)</code></b><br>
823
+ <b><code>etween()</code></b><br>
824
+ <b><code>(queue: module:list.List&lt;N&gt;, n: N)</code></b><br>
825
+ <b><code>()</code></b><br>
826
+ <b><code>nt(queue: module:list.List&lt;N&gt;, n: N)</code></b><br>
827
+ <b><code>nt()</code></b><br>
828
+ <b><code>t(list: module:list.List&lt;N&gt;): N| null</code></b><br>
829
+ <b><code>t()</code></b><br>
830
+ <b><code>(list: module:list.List&lt;N&gt;): N| null</code></b><br>
831
+ <b><code>()</code></b><br>
832
+ <b><code>(list: module:list.List&lt;N&gt;, f: function(N):M): Array&lt;M&gt;</code></b><br>
833
+ <b><code>()</code></b><br>
834
+ </dl>
835
+ </details>
790
836
  <details><summary><b>[lib0/logging]</b> Isomorphic logging module with support for colors!</summary>
791
837
  <pre>import * as logging from 'lib0/logging'</pre>
792
838
  <dl>
@@ -1058,6 +1104,8 @@ library has some insane environment where global Promise objects are overwritten
1058
1104
  <dl>
1059
1105
  <b><code>set.create</code></b><br>
1060
1106
  <b><code>set.toArray(set: Set&lt;T&gt;): Array&lt;T&gt;</code></b><br>
1107
+ <b><code>set.first(set: Set&lt;T&gt;): T</code></b><br>
1108
+ <b><code>set.from(entries: Iterable&lt;T&gt;): Set&lt;T&gt;</code></b><br>
1061
1109
  </dl>
1062
1110
  </details>
1063
1111
  <details><summary><b>[lib0/sort]</b> Efficient sort implementations.</summary>
@@ -1104,6 +1152,7 @@ integrate this algorithm.</p>
1104
1152
  <b><code>string.utf8TextEncoder</code></b><br>
1105
1153
  <b><code>string.encodeUtf8</code></b><br>
1106
1154
  <b><code>string.decodeUtf8</code></b><br>
1155
+ <b><code>string.splice(str: string, index: number, remove: number, insert: string)</code></b><br>
1107
1156
  </dl>
1108
1157
  </details>
1109
1158
  <details><summary><b>[lib0/symbol]</b> Utility module to work with EcmaScript Symbols.</summary>
package/cache.d.ts ADDED
@@ -0,0 +1,50 @@
1
+ /**
2
+ * @template K, V
3
+ */
4
+ export class Cache<K, V> {
5
+ /**
6
+ * @param {number} timeout
7
+ */
8
+ constructor(timeout: number);
9
+ timeout: number;
10
+ /**
11
+ * @type list.List<Entry<K, V>>
12
+ */
13
+ _q: list.List<Entry<K, V>>;
14
+ /**
15
+ * @type {Map<K, Entry<K, V>>}
16
+ */
17
+ _map: Map<K, Entry<K, V>>;
18
+ }
19
+ export function removeStale<K, V>(cache: Cache<K, V>): number;
20
+ export function set<K, V>(cache: Cache<K, V>, key: K, value: V): void;
21
+ export function get<K, V>(cache: Cache<K, V>, key: K): V | undefined;
22
+ export function getAsync<K, V>(cache: Cache<K, V>, key: K): V | Promise<V> | undefined;
23
+ export function setIfUndefined<K, V>(cache: Cache<K, V>, key: K, init: () => Promise<V>): V | Promise<V>;
24
+ export function create(timeout: number): Cache<any, any>;
25
+ import * as list from "./list.js";
26
+ /**
27
+ * @template K, V
28
+ *
29
+ * @implements {list.ListNode}
30
+ */
31
+ declare class Entry<K, V> implements list.ListNode {
32
+ /**
33
+ * @param {K} key
34
+ * @param {V | Promise<V>} val
35
+ */
36
+ constructor(key: K, val: V | Promise<V>);
37
+ /**
38
+ * @type {this | null}
39
+ */
40
+ prev: Entry<K, V> | null;
41
+ /**
42
+ * @type {this | null}
43
+ */
44
+ next: Entry<K, V> | null;
45
+ created: number;
46
+ val: V | Promise<V>;
47
+ key: K;
48
+ }
49
+ export {};
50
+ //# sourceMappingURL=cache.d.ts.map
package/cache.d.ts.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["cache.js"],"names":[],"mappings":"AAsCA;;GAEG;AACH;IACE;;OAEG;IACH,qBAFW,MAAM,EAYhB;IATC,gBAAsB;IACtB;;OAEG;IACH,IAFS,KAAK,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAER;IACvB;;OAEG;IACH,MAFU,IAAI,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAEL;CAE3B;AAQM,uDAFK,MAAM,CAUjB;AASM,sEAcN;AA4BM,qEAGN;AAYM,uFAGN;AAUM,yGAqBN;AAKM,gCAFI,MAAM,mBAEkC;;AApKnD;;;;GAIG;AACH,qCAFgB,IAAI,CAAC,QAAQ;IAG3B;;;OAGG;IACH,iBAHW,CAAC,OACD,CAAC,GAAG,QAAQ,CAAC,CAAC,EAcxB;IAXC;;OAEG;IACH,yBAAgB;IAChB;;OAEG;IACH,yBAAgB;IAChB,gBAAiC;IACjC,oBAAc;IACd,OAAc;CAEjB"}
package/cache.js ADDED
@@ -0,0 +1,178 @@
1
+
2
+ /* eslint-env browser */
3
+
4
+ /**
5
+ * An implementation of a map which has keys that expire.
6
+ *
7
+ * @module cached-map
8
+ */
9
+
10
+ import * as list from './list.js'
11
+ import * as map from './map.js'
12
+ import * as time from './time.js'
13
+
14
+ /**
15
+ * @template K, V
16
+ *
17
+ * @implements {list.ListNode}
18
+ */
19
+ class Entry {
20
+ /**
21
+ * @param {K} key
22
+ * @param {V | Promise<V>} val
23
+ */
24
+ constructor (key, val) {
25
+ /**
26
+ * @type {this | null}
27
+ */
28
+ this.prev = null
29
+ /**
30
+ * @type {this | null}
31
+ */
32
+ this.next = null
33
+ this.created = time.getUnixTime()
34
+ this.val = val
35
+ this.key = key
36
+ }
37
+ }
38
+
39
+ /**
40
+ * @template K, V
41
+ */
42
+ export class Cache {
43
+ /**
44
+ * @param {number} timeout
45
+ */
46
+ constructor (timeout) {
47
+ this.timeout = timeout
48
+ /**
49
+ * @type list.List<Entry<K, V>>
50
+ */
51
+ this._q = list.create()
52
+ /**
53
+ * @type {Map<K, Entry<K, V>>}
54
+ */
55
+ this._map = map.create()
56
+ }
57
+ }
58
+
59
+ /**
60
+ * @template K, V
61
+ *
62
+ * @param {Cache<K, V>} cache
63
+ * @return {number} Returns the current timestamp
64
+ */
65
+ export const removeStale = cache => {
66
+ const now = time.getUnixTime()
67
+ const q = cache._q
68
+ while (q.start && now - q.start.created > cache.timeout) {
69
+ cache._map.delete(q.start.key)
70
+ list.popFront(q)
71
+ }
72
+ return now
73
+ }
74
+
75
+ /**
76
+ * @template K, V
77
+ *
78
+ * @param {Cache<K, V>} cache
79
+ * @param {K} key
80
+ * @param {V} value
81
+ */
82
+ export const set = (cache, key, value) => {
83
+ const now = removeStale(cache)
84
+ const q = cache._q
85
+ const n = cache._map.get(key)
86
+ if (n) {
87
+ list.removeNode(q, n)
88
+ list.pushEnd(q, n)
89
+ n.created = now
90
+ n.val = value
91
+ } else {
92
+ const node = new Entry(key, value)
93
+ list.pushEnd(q, node)
94
+ cache._map.set(key, node)
95
+ }
96
+ }
97
+
98
+ /**
99
+ * @template K, V
100
+ *
101
+ * @param {Cache<K, V>} cache
102
+ * @param {K} key
103
+ * @return {Entry<K, V> | undefined}
104
+ */
105
+ const getNode = (cache, key) => {
106
+ const now = removeStale(cache)
107
+ const q = cache._q
108
+ const n = cache._map.get(key)
109
+ if (n) {
110
+ list.removeNode(q, n)
111
+ list.pushEnd(q, n)
112
+ n.created = now
113
+ return n
114
+ }
115
+ }
116
+
117
+ /**
118
+ * @template K, V
119
+ *
120
+ * @param {Cache<K, V>} cache
121
+ * @param {K} key
122
+ * @return {V | undefined}
123
+ */
124
+ export const get = (cache, key) => {
125
+ const n = getNode(cache, key)
126
+ return n && !(n.val instanceof Promise) ? n.val : undefined
127
+ }
128
+
129
+ /**
130
+ * Works well in conjunktion with setIfUndefined which has an async init function.
131
+ * Using getAsync & setIfUndefined ensures that the init function is only called once.
132
+ *
133
+ * @template K, V
134
+ *
135
+ * @param {Cache<K, V>} cache
136
+ * @param {K} key
137
+ * @return {V | Promise<V> | undefined}
138
+ */
139
+ export const getAsync = (cache, key) => {
140
+ const n = getNode(cache, key)
141
+ return n ? n.val : undefined
142
+ }
143
+
144
+ /**
145
+ * @template K, V
146
+ *
147
+ * @param {Cache<K, V>} cache
148
+ * @param {K} key
149
+ * @param {function():Promise<V>} init
150
+ * @return {Promise<V> | V}
151
+ */
152
+ export const setIfUndefined = (cache, key, init) => {
153
+ const now = removeStale(cache)
154
+ const q = cache._q
155
+ const n = cache._map.get(key)
156
+ if (n) {
157
+ list.removeNode(q, n)
158
+ list.pushEnd(q, n)
159
+ n.created = now
160
+ return n.val
161
+ } else {
162
+ const p = init()
163
+ const node = new Entry(key, p)
164
+ list.pushEnd(q, node)
165
+ cache._map.set(key, node)
166
+ p.then(v => {
167
+ if (p === node.val) {
168
+ node.val = v
169
+ }
170
+ })
171
+ return p
172
+ }
173
+ }
174
+
175
+ /**
176
+ * @param {number} timeout
177
+ */
178
+ export const create = timeout => new Cache(timeout)
@@ -0,0 +1,3 @@
1
+ export function testCache(tc: t.TestCase): Promise<void>;
2
+ import * as t from "./testing.js";
3
+ //# sourceMappingURL=cache.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.test.d.ts","sourceRoot":"","sources":["cache.test.js"],"names":[],"mappings":"AAQO,8BAFI,EAAE,QAAQ,iBAuDpB"}
package/diff.d.ts CHANGED
@@ -1,6 +1,11 @@
1
1
  export function simpleDiffString(a: string, b: string): SimpleDiff<string>;
2
2
  export function simpleDiff(a: string, b: string): SimpleDiff<string>;
3
3
  export function simpleDiffArray<T>(a: T[], b: T[], compare?: ((arg0: T, arg1: T) => boolean) | undefined): SimpleDiff<T[]>;
4
+ export function simpleDiffStringWithCursor(a: string, b: string, cursor: number): {
5
+ index: number;
6
+ remove: number;
7
+ insert: string;
8
+ };
4
9
  /**
5
10
  * A SimpleDiff describes a change on a String.
6
11
  *
package/diff.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["diff.js"],"names":[],"mappings":"AAwCO,oCAJI,MAAM,KACN,MAAM,GACL,WAAW,MAAM,CAAC,CAmB7B;AAjBM,8BAJI,MAAM,KACN,MAAM,GACL,WAAW,MAAM,CAAC,CAmB7B;AAuBM,oFAHmB,OAAO,gCAoBhC;;;;;;;;;;;;;;;;;;;;;;;;;;;YAzEa,CAAC"}
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["diff.js"],"names":[],"mappings":"AAwCO,oCAJI,MAAM,KACN,MAAM,GACL,WAAW,MAAM,CAAC,CAgB7B;AAdM,8BAJI,MAAM,KACN,MAAM,GACL,WAAW,MAAM,CAAC,CAgB7B;AAuBM,oFAHmB,OAAO,gCAiBhC;AASM,8CAJI,MAAM,KACN,MAAM,UACN,MAAM;;;;EAoChB;;;;;;;;;;;;;;;;;;;;;;;;;;;YA9Ga,CAAC"}
package/diff.js CHANGED
@@ -44,11 +44,8 @@ export const simpleDiffString = (a, b) => {
44
44
  while (left < a.length && left < b.length && a[left] === b[left]) {
45
45
  left++
46
46
  }
47
- if (left !== a.length || left !== b.length) {
48
- // Only check right if a !== b
49
- while (right + left < a.length && right + left < b.length && a[a.length - right - 1] === b[b.length - right - 1]) {
50
- right++
51
- }
47
+ while (right + left < a.length && right + left < b.length && a[a.length - right - 1] === b[b.length - right - 1]) {
48
+ right++
52
49
  }
53
50
  return {
54
51
  index: left,
@@ -84,11 +81,51 @@ export const simpleDiffArray = (a, b, compare = equalityStrict) => {
84
81
  while (left < a.length && left < b.length && compare(a[left], b[left])) {
85
82
  left++
86
83
  }
87
- if (left !== a.length || left !== b.length) {
88
- // Only check right if a !== b
89
- while (right + left < a.length && right + left < b.length && compare(a[a.length - right - 1], b[b.length - right - 1])) {
90
- right++
91
- }
84
+ while (right + left < a.length && right + left < b.length && compare(a[a.length - right - 1], b[b.length - right - 1])) {
85
+ right++
86
+ }
87
+ return {
88
+ index: left,
89
+ remove: a.length - left - right,
90
+ insert: b.slice(left, b.length - right)
91
+ }
92
+ }
93
+
94
+ /**
95
+ * Diff text and try to diff at the current cursor position.
96
+ *
97
+ * @param {string} a
98
+ * @param {string} b
99
+ * @param {number} cursor This should refer to the current left cursor-range position
100
+ */
101
+ export const simpleDiffStringWithCursor = (a, b, cursor) => {
102
+ let left = 0 // number of same characters counting from left
103
+ let right = 0 // number of same characters counting from right
104
+ // Iterate left to the right until we find a changed character
105
+ // First iteration considers the current cursor position
106
+ while (
107
+ left < a.length &&
108
+ left < b.length &&
109
+ a[left] === b[left] &&
110
+ left < cursor
111
+ ) {
112
+ left++
113
+ }
114
+ // Iterate right to the left until we find a changed character
115
+ while (
116
+ right + left < a.length &&
117
+ right + left < b.length &&
118
+ a[a.length - right - 1] === b[b.length - right - 1]
119
+ ) {
120
+ right++
121
+ }
122
+ // Try to iterate left further to the right without caring about the current cursor position
123
+ while (
124
+ right + left < a.length &&
125
+ right + left < b.length &&
126
+ a[left] === b[left]
127
+ ) {
128
+ left++
92
129
  }
93
130
  return {
94
131
  index: left,
package/diff.test.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export function testDiffing(tc: t.TestCase): void;
2
2
  export function testRepeatDiffing(tc: t.TestCase): void;
3
+ export function testSimpleDiffWithCursor(tc: t.TestCase): void;
3
4
  export function testArrayDiffing(tc: t.TestCase): void;
4
5
  import * as t from "./testing.js";
5
6
  //# sourceMappingURL=diff.test.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"diff.test.d.ts","sourceRoot":"","sources":["diff.test.js"],"names":[],"mappings":"AAqBO,gCAFI,EAAE,QAAQ,QAWpB;AAKM,sCAFI,EAAE,QAAQ,QAQpB;AAKM,qCAFI,EAAE,QAAQ,QAQpB"}
1
+ {"version":3,"file":"diff.test.d.ts","sourceRoot":"","sources":["diff.test.js"],"names":[],"mappings":"AAuBO,gCAFI,EAAE,QAAQ,QAWpB;AAKM,sCAFI,EAAE,QAAQ,QAQpB;AAKM,6CAFI,EAAE,QAAQ,QA8BpB;AAKM,qCAFI,EAAE,QAAQ,QAQpB"}
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var map = require('./map-28a001c9.cjs');
4
- var encoding = require('./buffer-49880125.cjs');
4
+ var encoding = require('./buffer-b0dea3b0.cjs');
5
5
  var storage = require('./storage.cjs');
6
6
 
7
7
  /* eslint-env browser */
@@ -100,4 +100,4 @@ exports.broadcastchannel = broadcastchannel;
100
100
  exports.publish = publish;
101
101
  exports.subscribe = subscribe;
102
102
  exports.unsubscribe = unsubscribe;
103
- //# sourceMappingURL=broadcastchannel-044f32d2.cjs.map
103
+ //# sourceMappingURL=broadcastchannel-7da37795.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"broadcastchannel-044f32d2.cjs","sources":["../broadcastchannel.js"],"sourcesContent":["/* eslint-env browser */\n\n/**\n * Helpers for cross-tab communication using broadcastchannel with LocalStorage fallback.\n *\n * ```js\n * // In browser window A:\n * broadcastchannel.subscribe('my events', data => console.log(data))\n * broadcastchannel.publish('my events', 'Hello world!') // => A: 'Hello world!' fires synchronously in same tab\n *\n * // In browser window B:\n * broadcastchannel.publish('my events', 'hello from tab B') // => A: 'hello from tab B'\n * ```\n *\n * @module broadcastchannel\n */\n\n// @todo before next major: use Uint8Array instead as buffer object\n\nimport * as map from './map.js'\nimport * as buffer from './buffer.js'\nimport * as storage from './storage.js'\n\n/**\n * @typedef {Object} Channel\n * @property {Set<Function>} Channel.subs\n * @property {any} Channel.bc\n */\n\n/**\n * @type {Map<string, Channel>}\n */\nconst channels = new Map()\n\nclass LocalStoragePolyfill {\n /**\n * @param {string} room\n */\n constructor (room) {\n this.room = room\n /**\n * @type {null|function({data:ArrayBuffer}):void}\n */\n this.onmessage = null\n storage.onChange(e => e.key === room && this.onmessage !== null && this.onmessage({ data: buffer.fromBase64(e.newValue || '') }))\n }\n\n /**\n * @param {ArrayBuffer} buf\n */\n postMessage (buf) {\n storage.varStorage.setItem(this.room, buffer.toBase64(buffer.createUint8ArrayFromArrayBuffer(buf)))\n }\n}\n\n// Use BroadcastChannel or Polyfill\nconst BC = typeof BroadcastChannel === 'undefined' ? LocalStoragePolyfill : BroadcastChannel\n\n/**\n * @param {string} room\n * @return {Channel}\n */\nconst getChannel = room =>\n map.setIfUndefined(channels, room, () => {\n const subs = new Set()\n const bc = new BC(room)\n /**\n * @param {{data:ArrayBuffer}} e\n */\n bc.onmessage = e => subs.forEach(sub => sub(e.data))\n return {\n bc, subs\n }\n })\n\n/**\n * Subscribe to global `publish` events.\n *\n * @function\n * @param {string} room\n * @param {function(any):any} f\n */\nexport const subscribe = (room, f) => getChannel(room).subs.add(f)\n\n/**\n * Unsubscribe from `publish` global events.\n *\n * @function\n * @param {string} room\n * @param {function(any):any} f\n */\nexport const unsubscribe = (room, f) => getChannel(room).subs.delete(f)\n\n/**\n * Publish data to all subscribers (including subscribers on this tab)\n *\n * @function\n * @param {string} room\n * @param {any} data\n */\nexport const publish = (room, data) => {\n const c = getChannel(room)\n c.bc.postMessage(data)\n c.subs.forEach(sub => sub(data))\n}\n"],"names":["storage.onChange","buffer.fromBase64","storage.varStorage","buffer.toBase64","buffer.createUint8ArrayFromArrayBuffer","map.setIfUndefined"],"mappings":";;;;;;AAAA;AAsBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,QAAQ,GAAG,IAAI,GAAG,GAAE;AAC1B;AACA,MAAM,oBAAoB,CAAC;AAC3B;AACA;AACA;AACA,EAAE,WAAW,CAAC,CAAC,IAAI,EAAE;AACrB,IAAI,IAAI,CAAC,IAAI,GAAG,KAAI;AACpB;AACA;AACA;AACA,IAAI,IAAI,CAAC,SAAS,GAAG,KAAI;AACzB,IAAIA,gBAAgB,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,IAAI,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAEC,mBAAiB,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE,CAAC,EAAC;AACrI,GAAG;AACH;AACA;AACA;AACA;AACA,EAAE,WAAW,CAAC,CAAC,GAAG,EAAE;AACpB,IAAIC,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAEC,iBAAe,CAACC,wCAAsC,CAAC,GAAG,CAAC,CAAC,EAAC;AACvG,GAAG;AACH,CAAC;AACD;AACA;AACA,MAAM,EAAE,GAAG,OAAO,gBAAgB,KAAK,WAAW,GAAG,oBAAoB,GAAG,iBAAgB;AAC5F;AACA;AACA;AACA;AACA;AACA,MAAM,UAAU,GAAG,IAAI;AACvB,EAAEC,kBAAkB,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM;AAC3C,IAAI,MAAM,IAAI,GAAG,IAAI,GAAG,GAAE;AAC1B,IAAI,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC,IAAI,EAAC;AAC3B;AACA;AACA;AACA,IAAI,EAAE,CAAC,SAAS,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAC;AACxD,IAAI,OAAO;AACX,MAAM,EAAE,EAAE,IAAI;AACd,KAAK;AACL,GAAG,EAAC;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,SAAS,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAC;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,WAAW,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAC;AACvE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,OAAO,GAAG,CAAC,IAAI,EAAE,IAAI,KAAK;AACvC,EAAE,MAAM,CAAC,GAAG,UAAU,CAAC,IAAI,EAAC;AAC5B,EAAE,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,IAAI,EAAC;AACxB,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,EAAC;AAClC;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"broadcastchannel-7da37795.cjs","sources":["../broadcastchannel.js"],"sourcesContent":["/* eslint-env browser */\n\n/**\n * Helpers for cross-tab communication using broadcastchannel with LocalStorage fallback.\n *\n * ```js\n * // In browser window A:\n * broadcastchannel.subscribe('my events', data => console.log(data))\n * broadcastchannel.publish('my events', 'Hello world!') // => A: 'Hello world!' fires synchronously in same tab\n *\n * // In browser window B:\n * broadcastchannel.publish('my events', 'hello from tab B') // => A: 'hello from tab B'\n * ```\n *\n * @module broadcastchannel\n */\n\n// @todo before next major: use Uint8Array instead as buffer object\n\nimport * as map from './map.js'\nimport * as buffer from './buffer.js'\nimport * as storage from './storage.js'\n\n/**\n * @typedef {Object} Channel\n * @property {Set<Function>} Channel.subs\n * @property {any} Channel.bc\n */\n\n/**\n * @type {Map<string, Channel>}\n */\nconst channels = new Map()\n\nclass LocalStoragePolyfill {\n /**\n * @param {string} room\n */\n constructor (room) {\n this.room = room\n /**\n * @type {null|function({data:ArrayBuffer}):void}\n */\n this.onmessage = null\n storage.onChange(e => e.key === room && this.onmessage !== null && this.onmessage({ data: buffer.fromBase64(e.newValue || '') }))\n }\n\n /**\n * @param {ArrayBuffer} buf\n */\n postMessage (buf) {\n storage.varStorage.setItem(this.room, buffer.toBase64(buffer.createUint8ArrayFromArrayBuffer(buf)))\n }\n}\n\n// Use BroadcastChannel or Polyfill\nconst BC = typeof BroadcastChannel === 'undefined' ? LocalStoragePolyfill : BroadcastChannel\n\n/**\n * @param {string} room\n * @return {Channel}\n */\nconst getChannel = room =>\n map.setIfUndefined(channels, room, () => {\n const subs = new Set()\n const bc = new BC(room)\n /**\n * @param {{data:ArrayBuffer}} e\n */\n bc.onmessage = e => subs.forEach(sub => sub(e.data))\n return {\n bc, subs\n }\n })\n\n/**\n * Subscribe to global `publish` events.\n *\n * @function\n * @param {string} room\n * @param {function(any):any} f\n */\nexport const subscribe = (room, f) => getChannel(room).subs.add(f)\n\n/**\n * Unsubscribe from `publish` global events.\n *\n * @function\n * @param {string} room\n * @param {function(any):any} f\n */\nexport const unsubscribe = (room, f) => getChannel(room).subs.delete(f)\n\n/**\n * Publish data to all subscribers (including subscribers on this tab)\n *\n * @function\n * @param {string} room\n * @param {any} data\n */\nexport const publish = (room, data) => {\n const c = getChannel(room)\n c.bc.postMessage(data)\n c.subs.forEach(sub => sub(data))\n}\n"],"names":["storage.onChange","buffer.fromBase64","storage.varStorage","buffer.toBase64","buffer.createUint8ArrayFromArrayBuffer","map.setIfUndefined"],"mappings":";;;;;;AAAA;AAsBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,QAAQ,GAAG,IAAI,GAAG,GAAE;AAC1B;AACA,MAAM,oBAAoB,CAAC;AAC3B;AACA;AACA;AACA,EAAE,WAAW,CAAC,CAAC,IAAI,EAAE;AACrB,IAAI,IAAI,CAAC,IAAI,GAAG,KAAI;AACpB;AACA;AACA;AACA,IAAI,IAAI,CAAC,SAAS,GAAG,KAAI;AACzB,IAAIA,gBAAgB,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,IAAI,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAEC,mBAAiB,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE,CAAC,EAAC;AACrI,GAAG;AACH;AACA;AACA;AACA;AACA,EAAE,WAAW,CAAC,CAAC,GAAG,EAAE;AACpB,IAAIC,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAEC,iBAAe,CAACC,wCAAsC,CAAC,GAAG,CAAC,CAAC,EAAC;AACvG,GAAG;AACH,CAAC;AACD;AACA;AACA,MAAM,EAAE,GAAG,OAAO,gBAAgB,KAAK,WAAW,GAAG,oBAAoB,GAAG,iBAAgB;AAC5F;AACA;AACA;AACA;AACA;AACA,MAAM,UAAU,GAAG,IAAI;AACvB,EAAEC,kBAAkB,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM;AAC3C,IAAI,MAAM,IAAI,GAAG,IAAI,GAAG,GAAE;AAC1B,IAAI,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC,IAAI,EAAC;AAC3B;AACA;AACA;AACA,IAAI,EAAE,CAAC,SAAS,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAC;AACxD,IAAI,OAAO;AACX,MAAM,EAAE,EAAE,IAAI;AACd,KAAK;AACL,GAAG,EAAC;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,SAAS,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAC;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,WAAW,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAC;AACvE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,OAAO,GAAG,CAAC,IAAI,EAAE,IAAI,KAAK;AACvC,EAAE,MAAM,CAAC,GAAG,UAAU,CAAC,IAAI,EAAC;AAC5B,EAAE,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,IAAI,EAAC;AACxB,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,EAAC;AAClC;;;;;;;;;;;;;;"}
@@ -3,11 +3,11 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  require('./map-28a001c9.cjs');
6
- require('./buffer-49880125.cjs');
6
+ require('./buffer-b0dea3b0.cjs');
7
7
  require('./storage.cjs');
8
- var broadcastchannel = require('./broadcastchannel-044f32d2.cjs');
9
- require('./string-f3c3d805.cjs');
10
- require('./environment-7e2ffaea.cjs');
8
+ var broadcastchannel = require('./broadcastchannel-7da37795.cjs');
9
+ require('./string-ad04f734.cjs');
10
+ require('./environment-60b83194.cjs');
11
11
  require('./conditions-fb475c70.cjs');
12
12
  require('./binary-ac8e39e2.cjs');
13
13
  require('./math-08e068f9.cjs');
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var string = require('./string-f3c3d805.cjs');
4
- var environment = require('./environment-7e2ffaea.cjs');
3
+ var string = require('./string-ad04f734.cjs');
4
+ var environment = require('./environment-60b83194.cjs');
5
5
  var binary = require('./binary-ac8e39e2.cjs');
6
6
  var math = require('./math-08e068f9.cjs');
7
7
  var number = require('./number-e62129bc.cjs');
@@ -1740,4 +1740,4 @@ exports.writeVarInt = writeVarInt;
1740
1740
  exports.writeVarString = writeVarString;
1741
1741
  exports.writeVarUint = writeVarUint;
1742
1742
  exports.writeVarUint8Array = writeVarUint8Array;
1743
- //# sourceMappingURL=buffer-49880125.cjs.map
1743
+ //# sourceMappingURL=buffer-b0dea3b0.cjs.map