dubc-ds-tmap 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,3 +1,271 @@
1
1
  # dubc-ds-tmap
2
2
 
3
- Observable sorted map based on a weighted binary search tree.
3
+ A map (dictionary) of key/value pairs that is sorted using a weighted
4
+ binary search tree.
5
+
6
+ Note that this data structure maps _arbitrary_ keys to _arbitrary_
7
+ values. When doing front-end development, that's usually not what
8
+ you actually need. Consider using `dubc-ds-tindex` instead, which
9
+ provides a dictionary where the keys are a function of the values.
10
+
11
+ ## Constructor
12
+
13
+ ```TypeScript
14
+ constructor(conf:Conf<K,V>, pairs:Pairs<K,V>)
15
+ ```
16
+
17
+ To construct a `TMap`, you need a configuration object that supplies
18
+ three things:
19
+
20
+ 1. A `compare` function that determines how to sort the keys in the map.
21
+ 2. A `unique` flag that determines whether the map can contain duplicate keys.
22
+ 3. A `valueEq` function that determines how values should be compared.
23
+
24
+ You also can supply initial key/value pairs to populate the map. The
25
+ pairs can be specified in three ways:
26
+
27
+ 1. You can specify an iterable of objects with `key` and `value` fields;
28
+ 2. Or an iterable of key/value tuples, where the first part of the tuple
29
+ is the key and the second part of the tuplie is the value;
30
+ 3. Or, if the keys are strings, you can use a plain JavaScript object.
31
+
32
+ If you want unique keys and can use `Object.is` for your `valueEq` function,
33
+ you can use the static `of` method to construct a `TMap` with variadic
34
+ key/value pairs.
35
+
36
+ Example:
37
+
38
+ ```TypeScript
39
+ import { Conf, TMap } from "dubc-ds-tmap"
40
+
41
+ const compare = (a:string, b:string) => a.localeCompare(b)
42
+
43
+ const conf:Conf<string,number> = {
44
+ compare, unique:false, valueEq:Object.is,
45
+ }
46
+
47
+ // These five statements all do the same thing.
48
+ const map1 = new TMap(conf, [{key:"1", value:1}, {key:"2", value:2}])
49
+ const map2 = new TMap(conf, [["1", 1], ["2", 2]])
50
+ const map3 = new TMap(conf, {"1":1, "2":2})
51
+ const map4 = TMap.of(compare, {key:"1", value:1}, {key:"2", value:2})
52
+ const map5 = TMap.of(compare, ["1", 1], ["2", 2])
53
+ ```
54
+
55
+ ## Properties
56
+
57
+ ### `.compare` O(1)
58
+
59
+ Returns the current function used to compare keys. This property is
60
+ mutable: If you change it, the map will re-sort (and fire a notification
61
+ to any listeners that the map has changed.)
62
+
63
+ ### `.first` O(log n)
64
+
65
+ Returns the first key/value pair in the map, or `undefined` if the map
66
+ is empty.
67
+
68
+ ### `.i` O(1)
69
+
70
+ Returns an iterator over the key/value pairs in the map. Each value
71
+ returned by the iterator will be an immutable object in the form `{key:k, value:v}`. (This property is inherited from `Base`.)
72
+
73
+ ### `.last` O(log n)
74
+
75
+ Returns the last key/value pair in the map, or `undefined` if the map
76
+ is empty.
77
+
78
+ ### `.only` O(1)
79
+
80
+ Returns the only key/value pair in the map. If the map doesn't have
81
+ exactly one element, throws an `Error`.
82
+
83
+ ### `.size` O(1)
84
+
85
+ Returns the number of key/value pairs in the map.
86
+
87
+ ## Methods
88
+
89
+ ### `.after(k:K)` O(log n)
90
+
91
+ Returns the key/value pair whose key is strictly greater than the provided
92
+ key, or `undefined` if no such pair exists in the map.
93
+
94
+ ### `.at(index:number)` O(log n)
95
+
96
+ Returns the key/value pair at the specified index in the sort order.
97
+ Throws a `TypeError` if the index is out of bounds.
98
+
99
+ ### `.before(k:K)` O(log n)
100
+
101
+ Returns the key/value pair whose key is strictly less than the provided
102
+ key, or `undefined` if no such pair exists in the map.
103
+
104
+ ### `.delete(k:K)` O(log n)
105
+
106
+ Removes the given key from the map. Returns the value that was mapped
107
+ to the key, or `undefined` if the key was not in the map.
108
+
109
+ ### `.deleteAll(i:Iterable<K>)` O(k * log n)
110
+
111
+ Removes every key provided by the given iterable from the map.
112
+ Returns the number of pairs that were deleted.
113
+
114
+ ### `.drop(f:(pair:Pair<K,V>)=>boolean)` O(n)
115
+
116
+ Safely removes all key/value pairs that match the provided predicate
117
+ function from the map. Use this instead of calling `delete` from within
118
+ an iteration. Returns the number of pairs that were dropped.
119
+
120
+ ### `.from(k:K)` O(log n)
121
+
122
+ Returns the key/value pair whose key is greater than or equal to the provided
123
+ key, or `undefined` if no such pair exists in the map.
124
+
125
+ ### `.get(k:K)` O(log n)
126
+
127
+ Returns the value for the given key, or `undefined` if no such key exists
128
+ in the map.
129
+
130
+ ### `.has(k:K)` O(log n)
131
+
132
+ Returns true if the map contains the given key, or false if it doesn't.
133
+
134
+ ### `.hasAll(i:Iterable<K>)` O(k * log n)
135
+
136
+ Returns true if the map contains every key produced by the given iterable,
137
+ or false if it doesn't.
138
+
139
+ ### `.hear(f:(event:DSEvent<Pair<K,V>>))` O(1)
140
+
141
+ Adds a listener to the map. Any time the map changes (and _only_ when
142
+ the map actually changes), the listener function will be called.
143
+
144
+ Returns a number that can be sent to `unhear` to stop receiving events.
145
+
146
+ ### `.keys()` O(1)
147
+
148
+ Returns an iterable iterator over the keys in the map.
149
+
150
+ ### `.range(start:K, end:K, include?:Include)` O(1)
151
+
152
+ Returns an iterable over a range of keys in the map. The
153
+ iterator will produce key/value pairs.
154
+
155
+ The optional third parameter specifies whether the range is inclusive
156
+ or exclusive, and must be one of the following four constants:
157
+
158
+ 1. `IN_EX`: Start is inclusive, end is exclusive. This is the default.
159
+ 2. `IN_IN`: Both start and end are inclusive.
160
+ 3. `EX_IN`: Start is exclusive, end is inclusive.
161
+ 4. `EX_EX`: Both start and end are exclusive.
162
+
163
+ ### `.rank(k:K)` O(log n)
164
+
165
+ Returns the index of the given key in the map's sort order, or
166
+ `undefined` if the key is not in the map.
167
+
168
+ ### `.replace(pairs:Pairs<K,V>)` O(k * log n)
169
+
170
+ Replaces the content of this map with new key/value pairs.
171
+
172
+ The provided pairs can be in one of the three forms accepted by
173
+ `TMap`'s constructor (objects with key and value fields, tuples of
174
+ keys and values, or, for string keys, a JavaScript object.)
175
+
176
+ ### `.reversed()` O(1)
177
+
178
+ Returns an iterable iterator over the pairs in the map, in reverse
179
+ sort order.
180
+
181
+ ### `.set(key:K, value:V)` O(log n)
182
+
183
+ Adds a pair to the map.
184
+
185
+ If the map uses unique keys and the key already exists in the map,
186
+ then `set` will replace the value for that key and return the old key.
187
+
188
+ Otherwise, `set` will add a new pair to the map and return `undefined`.
189
+
190
+ ### `.setAll(pairs:Pairs<K,V>)` O(k * log n)
191
+
192
+ Adds many pairs to the map. Returns the number of pairs that were newly
193
+ added. (The number returned does not include any keys that were
194
+ already in a unique map.)
195
+
196
+ The provided pairs can be in one of the three forms accepted by
197
+ `TMap`'s constructor (objects with key and value fields, tuples of
198
+ keys and values, or, for string keys, a JavaScript object.)
199
+
200
+ ### `.slice(start:number, end:number)`
201
+
202
+ Returns an iterable over a range of indices. `end` is always exclusive.
203
+
204
+ ### `.to(k:K)` O(log n)
205
+
206
+ Returns the key/value pair whose key is less than or equal to the provided
207
+ key, or `undefined` if no such pair exists in the map.
208
+
209
+ ### `.unhear(n:number)` O(1)
210
+
211
+ Removes the listener registered with the specified number.
212
+
213
+ ### `.values()` O(1)
214
+
215
+ Returns an iterable iterator over the values in the map.
216
+
217
+ ## Operations by Kind
218
+
219
+ ### Listeners
220
+
221
+ * `hear(eventHandler)` to get events when the map changes
222
+ * `unhear(n)` to stop listening for changes
223
+
224
+ ### Iterators
225
+
226
+ * `TMap` itself is an iterable, so you can use it directly in `for...of`
227
+ * `i` to get an iterator
228
+ * `keys()` if you just want the keys
229
+ * `range(start,end,include)` for partial iteration over a range of keys
230
+ * `reversed()` to iterate backwards
231
+ * `slice(start,end)` for partial iteration over a range of indices
232
+ * `values()` if you just want the values
233
+
234
+ ### Keys
235
+
236
+ * `get(key)` to get the value for a key
237
+ * `has(key)` to determine if the key exists
238
+ * `hasAll(iterable)` to determin if all the keys exist
239
+ * `only` to get the only pair
240
+
241
+ ### Ordering
242
+
243
+ * `get compare` for the sort function
244
+
245
+ * `first` to get the first pair
246
+ * `last` to get the last pair
247
+
248
+ * `after(key)` to get the pair > key
249
+ * `before(key)` to get the pair < key
250
+ * `from(key)` to get the pair >= key
251
+ * `to(key)` to get the pair <= key
252
+
253
+ ### Indices
254
+
255
+ * `at(index)` to get the key at an index
256
+ * `rank(key)` to get the index of a key
257
+ * `size` to get the number of pairs
258
+
259
+ ### Adding/Changing
260
+
261
+ * `set compare` to re-sort the map
262
+ * `set(key,value)` add a pair to the map
263
+ * `setAll(pairs)` add many pairs to the map
264
+ * `replace(pairs)` clear the map then add many pairs
265
+
266
+ ### Deleting
267
+
268
+ * `clear()` delete everything
269
+ * `delete(key)` delete a specific key
270
+ * `deleteAll(iterable)` delete many keys
271
+ * `drop(predicate)` delete pairs that match a predicate
package/dist/index.d.ts CHANGED
@@ -21,7 +21,7 @@ export declare const EX_EX: {
21
21
  end: boolean;
22
22
  };
23
23
  type N<K extends {}, V> = Node<K, V> | undefined;
24
- declare class Node<K extends {}, V> {
24
+ declare class Node<K extends {}, V> implements Pair<K, V> {
25
25
  readonly key: K;
26
26
  value: V;
27
27
  weight: number;
@@ -42,6 +42,7 @@ export interface Conf<K extends {}, V> {
42
42
  readonly valueEq: (a: V, b: V) => boolean;
43
43
  }
44
44
  export declare class TMap<K extends {}, V> extends Base<Pair<K, V>> {
45
+ #private;
45
46
  private root;
46
47
  private _compare;
47
48
  protected conf: Conf<K, V>;
@@ -50,23 +51,20 @@ export declare class TMap<K extends {}, V> extends Base<Pair<K, V>> {
50
51
  toEmpty(): TMap<K, V>;
51
52
  get size(): number;
52
53
  clear(): void;
53
- replace(i: Pairs<K, V>): void;
54
- drop(f: (pair: Pair<K, V>) => boolean): void;
54
+ replace(i: Pairs<K, V>): boolean;
55
+ drop(f: (pair: Pair<K, V>) => boolean): number;
55
56
  get compare(): (a: K, b: K) => number;
56
57
  set compare(cmp: (a: K, b: K) => number);
57
- get keyEq(): (a: K, b: K) => boolean;
58
- get unique(): boolean;
59
58
  at(i: number): Pair<K, V>;
60
59
  get only(): Pair<K, V>;
61
60
  get first(): Pair<K, V> | undefined;
62
61
  get last(): Pair<K, V> | undefined;
63
- [Symbol.iterator](): Generator<Node<K, V>, void, unknown>;
64
- private keys2;
65
- get keys(): Iterable<K>;
66
- private values2;
67
- get values(): Iterable<V>;
68
- reversed(): Generator<Pair<K, V>, void, unknown>;
69
- range(startKey: K, endKey: K, inc?: Include): Generator<Pair<K, V>, void, unknown>;
62
+ [Symbol.iterator](): Generator<Pair<K, V>>;
63
+ keys(): Iterable<K>;
64
+ values(): Iterable<V>;
65
+ reversed(): Iterable<Pair<K, V>>;
66
+ range(startKey: K, endKey: K, inc?: Include): Iterable<Pair<K, V>>;
67
+ slice(start: number, end: number): Iterable<Pair<K, V>>;
70
68
  private find;
71
69
  get(key: K): V | undefined;
72
70
  has(key: K): boolean;
@@ -74,6 +72,7 @@ export declare class TMap<K extends {}, V> extends Base<Pair<K, V>> {
74
72
  to(key: K): Pair<K, V> | undefined;
75
73
  after(key: K): Pair<K, V> | undefined;
76
74
  before(key: K): Pair<K, V> | undefined;
75
+ hasAll(keys: Iterable<K>): boolean;
77
76
  rank(key: K): number | undefined;
78
77
  protected rawPut(key: K, value: V): {
79
78
  node: Node<K, V>;
@@ -82,7 +81,9 @@ export declare class TMap<K extends {}, V> extends Base<Pair<K, V>> {
82
81
  set(key: K, value: V): V | undefined;
83
82
  setAll(entries: Pairs<K, V>): number;
84
83
  delete(key: K): V | undefined;
85
- private remove;
84
+ private delete2;
85
+ deleteAll(i: Iterable<K>): number;
86
+ private rawDelete;
86
87
  private weigh;
87
88
  }
88
89
  export {};
package/dist/index.js CHANGED
@@ -1,18 +1,23 @@
1
1
  import { Base } from "dubc-ds-base";
2
+ import { iterable } from "dubc-ds-iterables";
2
3
  import { forEach } from "dubc-ds-pairs";
3
4
  export const IN_IN = { start: true, end: true };
4
5
  export const IN_EX = { start: true, end: false };
5
6
  export const EX_IN = { start: false, end: true };
6
7
  export const EX_EX = { start: false, end: false };
7
8
  class Node {
9
+ key;
10
+ value;
11
+ weight = 1;
12
+ parent;
13
+ left;
14
+ right;
8
15
  constructor(key, value) {
9
16
  this.key = key;
10
17
  this.value = value;
11
- this.weight = 1;
12
18
  }
13
19
  weigh() {
14
- var _a, _b, _c, _d;
15
- this.weight = 1 + ((_b = (_a = this.left) === null || _a === void 0 ? void 0 : _a.weight) !== null && _b !== void 0 ? _b : 0) + ((_d = (_c = this.right) === null || _c === void 0 ? void 0 : _c.weight) !== null && _d !== void 0 ? _d : 0);
20
+ this.weight = 1 + (this.left?.weight ?? 0) + (this.right?.weight ?? 0);
16
21
  }
17
22
  index() {
18
23
  let i = -1;
@@ -60,7 +65,7 @@ class Node {
60
65
  rotateLeft() {
61
66
  let a = this;
62
67
  let b = a.right;
63
- let r = b === null || b === void 0 ? void 0 : b.left;
68
+ let r = b?.left;
64
69
  b.parent = a.parent;
65
70
  b.left = a;
66
71
  a.parent = b;
@@ -68,13 +73,13 @@ class Node {
68
73
  if (r)
69
74
  r.parent = a;
70
75
  a.weigh();
71
- b === null || b === void 0 ? void 0 : b.weigh();
76
+ b?.weigh();
72
77
  return b;
73
78
  }
74
79
  rotateRight() {
75
80
  let a = this;
76
81
  let b = a.left;
77
- let l = b === null || b === void 0 ? void 0 : b.right;
82
+ let l = b?.right;
78
83
  b.parent = a.parent;
79
84
  b.right = a;
80
85
  a.parent = b;
@@ -82,7 +87,7 @@ class Node {
82
87
  if (l)
83
88
  l.parent = a;
84
89
  a.weigh();
85
- b === null || b === void 0 ? void 0 : b.weigh();
90
+ b?.weigh();
86
91
  return b;
87
92
  }
88
93
  }
@@ -93,6 +98,9 @@ const LE = { lset: true, rset: false, eset: true, eright: true };
93
98
  const GT = { lset: false, rset: true, eset: false, eright: true };
94
99
  const GE = { lset: false, rset: true, eset: true, eright: false };
95
100
  export class TMap extends Base {
101
+ root;
102
+ _compare;
103
+ conf;
96
104
  constructor(input, c) {
97
105
  super();
98
106
  this._compare = c.compare;
@@ -104,15 +112,9 @@ export class TMap extends Base {
104
112
  return new TMap(pairs, conf);
105
113
  }
106
114
  toEmpty() {
107
- const conf2 = {
108
- unique: this.conf.unique,
109
- valueEq: this.conf.valueEq,
110
- compare: this._compare,
111
- };
112
- const r = new TMap(this, conf2);
113
- return r;
114
- }
115
- get size() { var _a, _b; return (_b = (_a = this.root) === null || _a === void 0 ? void 0 : _a.weight) !== null && _b !== void 0 ? _b : 0; }
115
+ return new TMap([], this.conf);
116
+ }
117
+ get size() { return this.root?.weight ?? 0; }
116
118
  clear() {
117
119
  const sz = this.size;
118
120
  this.root = undefined;
@@ -128,23 +130,32 @@ export class TMap extends Base {
128
130
  this.fire({ cleared: sz });
129
131
  else
130
132
  this.fire({ cleared: sz, added: { items: this, at: 0 } });
133
+ return true;
131
134
  }
132
- else if (this.root !== undefined)
135
+ else if (this.root !== undefined) {
133
136
  this.fire({ added: { items: this, at: 0 } });
137
+ return true;
138
+ }
139
+ else {
140
+ return false;
141
+ }
134
142
  }
135
143
  drop(f) {
136
144
  let n = this.first;
137
145
  let at = 0;
146
+ let c = 0;
138
147
  while (n !== undefined) {
139
148
  const x = n;
140
149
  n = n.next();
141
150
  if (f(x)) {
142
- this.remove(x);
151
+ this.rawDelete(x);
143
152
  this.fire({ deleted: { items: [x], at: at } });
153
+ c++;
144
154
  }
145
155
  else
146
156
  at++;
147
157
  }
158
+ return c;
148
159
  }
149
160
  get compare() { return this._compare; }
150
161
  set compare(cmp) {
@@ -159,21 +170,19 @@ export class TMap extends Base {
159
170
  }
160
171
  this.fire({ cleared: this.size, added: { items: this, at: 0 } });
161
172
  }
162
- get keyEq() { return (a, b) => this._compare(a, b) === 0; }
163
- get unique() { return this.conf.unique; }
164
173
  at(i) {
165
- var _a;
166
174
  let node = this.root;
167
175
  let weight = this.size;
168
- // if (i < 0) i += weight // TODO
176
+ if (!Number.isSafeInteger(i))
177
+ throw new TypeError("index must be an integer");
169
178
  if (i < 0 || i >= weight)
170
179
  throw new TypeError("bounds");
171
180
  while (true) {
172
- const left = node === null || node === void 0 ? void 0 : node.left;
173
- const lw = (_a = left === null || left === void 0 ? void 0 : left.weight) !== null && _a !== void 0 ? _a : 0;
181
+ const left = node?.left;
182
+ const lw = left?.weight ?? 0;
174
183
  if (i > lw) {
175
184
  i -= lw + 1;
176
- node = node === null || node === void 0 ? void 0 : node.right;
185
+ node = node?.right;
177
186
  }
178
187
  else if (i < lw) {
179
188
  node = left;
@@ -213,28 +222,31 @@ export class TMap extends Base {
213
222
  n = n.next();
214
223
  }
215
224
  }
216
- *keys2() {
225
+ *#keys() {
217
226
  for (const x of this)
218
227
  yield x.key;
219
228
  }
220
- get keys() {
221
- return this.keys2();
229
+ keys() {
230
+ return iterable(() => this.#keys());
222
231
  }
223
- *values2() {
232
+ *#values() {
224
233
  for (const x of this)
225
234
  yield x.value;
226
235
  }
227
- get values() {
228
- return this.values2();
236
+ values() {
237
+ return iterable(() => this.#values());
229
238
  }
230
- *reversed() {
239
+ *#reversed() {
231
240
  let n = this.last;
232
241
  while (n) {
233
242
  yield n;
234
243
  n = n.prev();
235
244
  }
236
245
  }
237
- *range(startKey, endKey, inc = IN_EX) {
246
+ reversed() {
247
+ return iterable(() => this.#reversed());
248
+ }
249
+ *#range(startKey, endKey, inc) {
238
250
  const start = this.find(startKey, inc.start ? GE : GT);
239
251
  const cmp = this.compare;
240
252
  if (inc.end)
@@ -246,10 +258,25 @@ export class TMap extends Base {
246
258
  yield n;
247
259
  }
248
260
  }
261
+ range(startKey, endKey, inc = IN_EX) {
262
+ return iterable(() => this.#range(startKey, endKey, inc));
263
+ }
264
+ slice(start, end) {
265
+ if (end <= start)
266
+ throw new TypeError("end <= start");
267
+ const s = this.at(start);
268
+ if (end === this.size) {
269
+ return this.range(s.key, this.last.key, IN_IN);
270
+ }
271
+ else {
272
+ const e = this.at(end);
273
+ return this.range(s.key, e.key, IN_EX);
274
+ }
275
+ }
249
276
  find(key, op = EQ) {
250
277
  let node = this.root;
251
278
  let ret;
252
- const unique = this.unique;
279
+ const unique = this.conf.unique;
253
280
  const cmp = this.compare;
254
281
  while (node) {
255
282
  const c = cmp(node.key, key);
@@ -275,19 +302,24 @@ export class TMap extends Base {
275
302
  }
276
303
  return ret;
277
304
  }
278
- get(key) { var _a; return (_a = this.find(key, EQ)) === null || _a === void 0 ? void 0 : _a.value; }
305
+ get(key) { return this.find(key, EQ)?.value; }
279
306
  has(key) { return this.find(key, EQ) !== undefined; }
280
307
  from(key) { return this.find(key, GE); }
281
308
  to(key) { return this.find(key, LE); }
282
309
  after(key) { return this.find(key, GT); }
283
310
  before(key) { return this.find(key, LT); }
311
+ hasAll(keys) {
312
+ for (const x of keys)
313
+ if (!this.has(x))
314
+ return false;
315
+ return true;
316
+ }
284
317
  rank(key) {
285
- var _a;
286
- return (_a = this.find(key, EQ)) === null || _a === void 0 ? void 0 : _a.index();
318
+ return this.find(key, EQ)?.index();
287
319
  }
288
320
  rawPut(key, value) {
289
321
  let previous = undefined, node = this.root;
290
- let unique = this.unique ? 0 : undefined;
322
+ let unique = this.conf.unique ? 0 : undefined;
291
323
  let c = 0, cmp = this.compare;
292
324
  while (node) {
293
325
  c = cmp(node.key, key);
@@ -347,12 +379,26 @@ export class TMap extends Base {
347
379
  const node = this.find(key);
348
380
  if (node === undefined)
349
381
  return undefined;
382
+ return this.delete2(node);
383
+ }
384
+ delete2(node) {
350
385
  const at = node.index();
351
- this.remove(node);
386
+ this.rawDelete(node);
352
387
  this.fire({ deleted: { items: [node], at } });
353
388
  return node.value;
354
389
  }
355
- remove(node) {
390
+ deleteAll(i) {
391
+ let c = 0;
392
+ for (const x of i) {
393
+ const node = this.find(x);
394
+ if (node !== undefined) {
395
+ c++;
396
+ this.delete2(node);
397
+ }
398
+ }
399
+ return c;
400
+ }
401
+ rawDelete(node) {
356
402
  const p = node.parent;
357
403
  let left = node.left, right = node.right;
358
404
  let bal;
@@ -404,13 +450,13 @@ export class TMap extends Base {
404
450
  let lw = weight(left);
405
451
  let rw = weight(right);
406
452
  if (rw * 5 + 2 < lw * 2) {
407
- if (weight(left === null || left === void 0 ? void 0 : left.left) * 5 < lw * 2)
408
- node.left = left === null || left === void 0 ? void 0 : left.rotateLeft();
453
+ if (weight(left?.left) * 5 < lw * 2)
454
+ node.left = left?.rotateLeft();
409
455
  node = node.rotateRight();
410
456
  }
411
457
  else if (lw * 5 + 2 < rw * 2) {
412
- if (weight(right === null || right === void 0 ? void 0 : right.right) * 5 < rw * 2)
413
- node.right = right === null || right === void 0 ? void 0 : right.rotateRight();
458
+ if (weight(right?.right) * 5 < rw * 2)
459
+ node.right = right?.rotateRight();
414
460
  node = node.rotateLeft();
415
461
  }
416
462
  else {
@@ -427,7 +473,6 @@ export class TMap extends Base {
427
473
  }
428
474
  }
429
475
  function weight(n) {
430
- var _a;
431
- return (_a = n === null || n === void 0 ? void 0 : n.weight) !== null && _a !== void 0 ? _a : 0;
476
+ return n?.weight ?? 0;
432
477
  }
433
478
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dubc-ds-tmap",
3
3
  "type": "module",
4
- "version": "1.0.0",
4
+ "version": "1.0.2",
5
5
  "description": "Observable map based on a weighted binary search tree.",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -26,14 +26,15 @@
26
26
  },
27
27
  "homepage": "https://github.com/p-jack/dubc#readme",
28
28
  "dependencies": {
29
- "dubc-ds-base": "^1.0.2",
30
- "dubc-ds-pairs": "^1.0.0"
29
+ "@vitest/coverage-v8": "^4.1.8",
30
+ "dubc-ds-base": "^1.0.3",
31
+ "dubc-ds-iterables": "^1.0.0",
32
+ "dubc-ds-pairs": "^1.0.2",
33
+ "vitest": "^4.1.8"
31
34
  },
32
35
  "devDependencies": {
33
- "@vitest/coverage-v8": "^3.2.4",
34
- "dubc-ds-test": "^1.0.1",
36
+ "dubc-ds-test": "^1.0.2",
35
37
  "jsdom": "^27.0.1",
36
- "typescript": "^5.9.3",
37
- "vitest": "^3.2.4"
38
+ "typescript": "^5.9.3"
38
39
  }
39
40
  }