data-structure-typed 2.4.2 → 2.4.4

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 (48) hide show
  1. package/.github/workflows/release.yml +27 -0
  2. package/CHANGELOG.md +3 -1
  3. package/README.md +46 -50
  4. package/dist/cjs/index.cjs +57 -35
  5. package/dist/cjs-legacy/index.cjs +58 -35
  6. package/dist/esm/index.mjs +57 -35
  7. package/dist/esm-legacy/index.mjs +58 -35
  8. package/dist/types/data-structures/base/iterable-element-base.d.ts +1 -1
  9. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +5 -5
  10. package/dist/types/data-structures/binary-tree/bst.d.ts +1 -1
  11. package/dist/types/data-structures/binary-tree/tree-map.d.ts +10 -0
  12. package/dist/types/data-structures/binary-tree/tree-set.d.ts +10 -0
  13. package/dist/types/data-structures/graph/directed-graph.d.ts +2 -2
  14. package/dist/types/data-structures/graph/undirected-graph.d.ts +2 -2
  15. package/dist/types/data-structures/hash/hash-map.d.ts +2 -2
  16. package/dist/types/data-structures/heap/heap.d.ts +3 -7
  17. package/dist/types/types/data-structures/binary-tree/avl-tree.d.ts +1 -1
  18. package/dist/types/types/data-structures/binary-tree/red-black-tree.d.ts +1 -1
  19. package/dist/types/types/data-structures/linked-list/doubly-linked-list.d.ts +1 -1
  20. package/dist/types/types/data-structures/linked-list/singly-linked-list.d.ts +1 -1
  21. package/dist/types/types/data-structures/priority-queue/priority-queue.d.ts +1 -1
  22. package/dist/types/types/data-structures/stack/stack.d.ts +1 -1
  23. package/dist/umd/data-structure-typed.js +58 -35
  24. package/dist/umd/data-structure-typed.min.js +4 -4
  25. package/package.json +2 -2
  26. package/src/data-structures/base/iterable-element-base.ts +2 -2
  27. package/src/data-structures/binary-tree/binary-tree.ts +8 -7
  28. package/src/data-structures/binary-tree/bst.ts +1 -1
  29. package/src/data-structures/binary-tree/tree-map.ts +16 -0
  30. package/src/data-structures/binary-tree/tree-multi-set.ts +5 -5
  31. package/src/data-structures/binary-tree/tree-set.ts +16 -0
  32. package/src/data-structures/graph/abstract-graph.ts +18 -18
  33. package/src/data-structures/graph/directed-graph.ts +4 -4
  34. package/src/data-structures/graph/map-graph.ts +1 -1
  35. package/src/data-structures/graph/undirected-graph.ts +4 -4
  36. package/src/data-structures/hash/hash-map.ts +6 -4
  37. package/src/data-structures/heap/heap.ts +17 -14
  38. package/src/data-structures/linked-list/doubly-linked-list.ts +4 -4
  39. package/src/data-structures/linked-list/singly-linked-list.ts +15 -9
  40. package/src/data-structures/queue/deque.ts +1 -1
  41. package/src/data-structures/stack/stack.ts +1 -1
  42. package/src/data-structures/trie/trie.ts +10 -5
  43. package/src/types/data-structures/binary-tree/avl-tree.ts +1 -1
  44. package/src/types/data-structures/binary-tree/red-black-tree.ts +1 -1
  45. package/src/types/data-structures/linked-list/doubly-linked-list.ts +1 -1
  46. package/src/types/data-structures/linked-list/singly-linked-list.ts +1 -1
  47. package/src/types/data-structures/priority-queue/priority-queue.ts +1 -1
  48. package/src/types/data-structures/stack/stack.ts +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "data-structure-typed",
3
- "version": "2.4.2",
3
+ "version": "2.4.4",
4
4
  "description": "Standard data structure",
5
5
  "browser": "dist/umd/data-structure-typed.min.js",
6
6
  "umd:main": "dist/umd/data-structure-typed.min.js",
@@ -105,7 +105,7 @@
105
105
  "benchmark": "^2.1.4",
106
106
  "binary-tree-typed": "^1.54.3",
107
107
  "bst-typed": "^1.54.3",
108
- "data-structure-typed": "^2.4.1",
108
+ "data-structure-typed": "^2.4.3",
109
109
  "dependency-cruiser": "^16.5.0",
110
110
  "doctoc": "^2.2.1",
111
111
  "eslint": "^9.13.0",
@@ -35,7 +35,7 @@ export abstract class IterableElementBase<E, R> implements Iterable<E> {
35
35
  * @remarks
36
36
  * Time O(1), Space O(1).
37
37
  */
38
- protected _toElementFn?: (rawElement: R) => E;
38
+ protected readonly _toElementFn?: (rawElement: R) => E;
39
39
 
40
40
  /**
41
41
  * Exposes the current `toElementFn`, if configured.
@@ -229,7 +229,7 @@ export abstract class IterableElementBase<E, R> implements Iterable<E> {
229
229
  index = 1;
230
230
  }
231
231
 
232
- for (const value of iter as unknown as Iterable<E>) {
232
+ for (const value of iter) {
233
233
  acc = callbackfn(acc, value, index++, this);
234
234
  }
235
235
  return acc;
@@ -377,7 +377,7 @@ export class BinaryTree<K = any, V = any, R = any>
377
377
  if (keysNodesEntriesOrRaws) this.setMany(keysNodesEntriesOrRaws);
378
378
  }
379
379
 
380
- protected _isMapMode = true;
380
+ protected readonly _isMapMode: boolean = true;
381
381
 
382
382
  /**
383
383
  * Gets whether the tree is in Map mode.
@@ -389,7 +389,7 @@ export class BinaryTree<K = any, V = any, R = any>
389
389
  return this._isMapMode;
390
390
  }
391
391
 
392
- protected _isDuplicate = false;
392
+ protected readonly _isDuplicate: boolean = false;
393
393
 
394
394
  /**
395
395
  * Gets whether the tree allows duplicate keys.
@@ -440,7 +440,7 @@ export class BinaryTree<K = any, V = any, R = any>
440
440
  return this._size;
441
441
  }
442
442
 
443
- protected _NIL: BinaryTreeNode<K, V> = new BinaryTreeNode<K, V>(NaN as K) as unknown as BinaryTreeNode<K, V>;
443
+ protected readonly _NIL = new BinaryTreeNode<K, V>(NaN as K);
444
444
 
445
445
  /**
446
446
  * Gets the sentinel NIL node (used in self-balancing trees like Red-Black Tree).
@@ -452,7 +452,7 @@ export class BinaryTree<K = any, V = any, R = any>
452
452
  return this._NIL;
453
453
  }
454
454
 
455
- protected _toEntryFn?: ToEntryFn<K, V, R>;
455
+ protected readonly _toEntryFn?: ToEntryFn<K, V, R>;
456
456
 
457
457
  /**
458
458
  * Gets the function used to convert raw data objects (R) into [key, value] entries.
@@ -1014,7 +1014,7 @@ export class BinaryTree<K = any, V = any, R = any>
1014
1014
  ): BinaryTreeNode<K, V> | null | undefined {
1015
1015
  if (this._isMapMode && keyNodeEntryOrPredicate !== null && keyNodeEntryOrPredicate !== undefined) {
1016
1016
  if (!this._isPredicate(keyNodeEntryOrPredicate)) {
1017
- const key = this._extractKey(keyNodeEntryOrPredicate as any);
1017
+ const key = this._extractKey(keyNodeEntryOrPredicate);
1018
1018
  if (key === null || key === undefined) return;
1019
1019
  return this._store.get(key);
1020
1020
  }
@@ -1078,7 +1078,7 @@ export class BinaryTree<K = any, V = any, R = any>
1078
1078
  ): boolean {
1079
1079
  if (this._isMapMode && keyNodeEntryOrPredicate !== undefined && keyNodeEntryOrPredicate !== null) {
1080
1080
  if (!this._isPredicate(keyNodeEntryOrPredicate)) {
1081
- const key = this._extractKey(keyNodeEntryOrPredicate as any);
1081
+ const key = this._extractKey(keyNodeEntryOrPredicate);
1082
1082
  if (key === null || key === undefined) return false;
1083
1083
  return this._store.has(key);
1084
1084
  }
@@ -2136,7 +2136,8 @@ export class BinaryTree<K = any, V = any, R = any>
2136
2136
  * @param node - The node.
2137
2137
  * @returns The node's key or undefined.
2138
2138
  */
2139
- protected _DEFAULT_NODE_CALLBACK = (node: BinaryTreeNode<K, V> | null | undefined) => (node ? node.key : undefined);
2139
+ protected readonly _DEFAULT_NODE_CALLBACK: NodeCallback<BinaryTreeNode<K, V> | null | undefined, K | undefined> =
2140
+ (node): K | undefined => node?.key;
2140
2141
 
2141
2142
  /**
2142
2143
  * (Protected) Snapshots the current tree's configuration options.
@@ -391,7 +391,7 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
391
391
 
392
392
  * @remarks Time O(1) Space O(1)
393
393
  */
394
- protected _comparator: Comparator<K>;
394
+ protected readonly _comparator: Comparator<K>;
395
395
 
396
396
  /**
397
397
  * Gets the comparator function used by the tree.
@@ -436,4 +436,20 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
436
436
 
437
437
  return out;
438
438
  }
439
+
440
+ /**
441
+ * Creates a shallow clone of this map.
442
+ * @remarks Time O(n log n), Space O(n)
443
+ * @example
444
+ * const original = new TreeMap([['a', 1], ['b', 2]]);
445
+ * const copy = original.clone();
446
+ * copy.set('c', 3);
447
+ * original.has('c'); // false (original unchanged)
448
+ */
449
+ clone(): TreeMap<K, V> {
450
+ return new TreeMap<K, V>(this, {
451
+ comparator: this.#isDefaultComparator ? undefined : this.#userComparator,
452
+ isMapMode: this.#core.isMapMode
453
+ });
454
+ }
439
455
  }
@@ -247,7 +247,7 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
247
247
  * @remarks Time O(1), Space O(1)
248
248
  */
249
249
  get comparator(): Comparator<K> {
250
- return (this.#core as any)._comparator;
250
+ return this.#core.comparator;
251
251
  }
252
252
 
253
253
  // ━━━ clear ━━━
@@ -398,7 +398,7 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
398
398
  filter(predicate: (key: K, count: number) => boolean): TreeMultiSet<K> {
399
399
  const result = new TreeMultiSet<K>([], {
400
400
  comparator: this.#isDefaultComparator ? undefined : this.comparator,
401
- isMapMode: (this.#core as any)._isMapMode
401
+ isMapMode: this.#core.isMapMode
402
402
  });
403
403
  for (const [k, c] of this.entries()) {
404
404
  if (predicate(k, c)) {
@@ -443,7 +443,7 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
443
443
  ): TreeMultiSet<K2> {
444
444
  const result = new TreeMultiSet<K2>([], {
445
445
  comparator: options?.comparator,
446
- isMapMode: (this.#core as any)._isMapMode
446
+ isMapMode: this.#core.isMapMode
447
447
  });
448
448
  for (const [k, c] of this.entries()) {
449
449
  const [newKey, newCount] = mapper(k, c);
@@ -464,7 +464,7 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
464
464
  clone(): TreeMultiSet<K> {
465
465
  const result = new TreeMultiSet<K>([], {
466
466
  comparator: this.#isDefaultComparator ? undefined : this.comparator,
467
- isMapMode: (this.#core as any)._isMapMode
467
+ isMapMode: this.#core.isMapMode
468
468
  });
469
469
  for (const [k, c] of this.entries()) {
470
470
  result.add(k, c);
@@ -486,7 +486,7 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
486
486
  callback?: C
487
487
  ): (C extends undefined ? K : ReturnType<C>)[] {
488
488
  const cb = callback ?? ((k: K) => k);
489
- return this.#core.rangeSearch(range, node => cb(node.key)) as any;
489
+ return this.#core.rangeSearch(range, node => cb(node.key));
490
490
  }
491
491
 
492
492
  /**
@@ -404,4 +404,20 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
404
404
 
405
405
  return out;
406
406
  }
407
+
408
+ /**
409
+ * Creates a shallow clone of this set.
410
+ * @remarks Time O(n log n), Space O(n)
411
+ * @example
412
+ * const original = new TreeSet([1, 2, 3]);
413
+ * const copy = original.clone();
414
+ * copy.add(4);
415
+ * original.has(4); // false (original unchanged)
416
+ */
417
+ clone(): TreeSet<K> {
418
+ return new TreeSet<K>(this, {
419
+ comparator: this.#isDefaultComparator ? undefined : this.#userComparator,
420
+ isMapMode: this.#core.isMapMode
421
+ });
422
+ }
407
423
  }
@@ -65,7 +65,7 @@ export abstract class AbstractGraph<
65
65
  */
66
66
  constructor(options?: Partial<Record<string, unknown>>) {
67
67
  super();
68
- const graph = (options as any)?.graph as GraphOptions<V> | undefined;
68
+ const graph = (options as { graph?: GraphOptions<V> })?.graph;
69
69
  this._options = { defaultEdgeWeight: 1, ...(graph ?? {}) };
70
70
  }
71
71
 
@@ -984,11 +984,12 @@ export abstract class AbstractGraph<
984
984
  * @remarks Time O(1), Space O(1)
985
985
  */
986
986
  protected _createInstance(_options?: Partial<Record<string, unknown>>): this {
987
- const Ctor: any = (this as any).constructor;
988
- const instance: this = new Ctor();
989
- const graph = (_options as any)?.graph as GraphOptions<V> | undefined;
990
- if (graph) (instance as any)._options = { ...(instance as any)._options, ...graph };
991
- else (instance as any)._options = { ...(instance as any)._options, ...(this as any)._options };
987
+ const Ctor = this.constructor as new () => this;
988
+ const instance = new Ctor();
989
+ const graph = (_options as { graph?: GraphOptions<V> })?.graph;
990
+ // Use bracket notation for protected field access on dynamically created instance
991
+ if (graph) instance['_options'] = { ...instance['_options'], ...graph };
992
+ else instance['_options'] = { ...instance['_options'], ...this._options };
992
993
  return instance;
993
994
  }
994
995
 
@@ -1009,28 +1010,27 @@ export abstract class AbstractGraph<
1009
1010
  // 1) Add vertices
1010
1011
  if (iter) {
1011
1012
  for (const [k, v] of iter) {
1012
- (g as any).addVertex(k as VertexKey, v as V | undefined);
1013
+ g.addVertex(k as VertexKey, v as V | undefined);
1013
1014
  }
1014
1015
  } else {
1015
1016
  for (const [k, v] of this) {
1016
- (g as any).addVertex(k as VertexKey, v as V | undefined);
1017
+ g.addVertex(k as VertexKey, v as V | undefined);
1017
1018
  }
1018
1019
  }
1019
1020
  // 2) Add edges whose endpoints exist in the new graph
1020
1021
  const edges = this.edgeSet();
1021
- for (const e of edges as any[]) {
1022
- const ends = this.getEndsOfEdge(e as any) as unknown as [any, any] | undefined;
1022
+ for (const e of edges) {
1023
+ const ends = this.getEndsOfEdge(e);
1023
1024
  if (!ends) continue;
1024
1025
  const [va, vb] = ends;
1025
- const ka = (va as any).key as VertexKey;
1026
- const kb = (vb as any).key as VertexKey;
1027
- const hasA = (g as any).hasVertex ? (g as any).hasVertex(ka) : false;
1028
- const hasB = (g as any).hasVertex ? (g as any).hasVertex(kb) : false;
1026
+ const ka = va.key;
1027
+ const kb = vb.key;
1028
+ // Defensive check for edge cases where hasVertex may be overridden/undefined
1029
+ const hasA = typeof g.hasVertex === 'function' ? g.hasVertex(ka) : false;
1030
+ const hasB = typeof g.hasVertex === 'function' ? g.hasVertex(kb) : false;
1029
1031
  if (hasA && hasB) {
1030
- const w = (e as any).weight;
1031
- const val = (e as any).value;
1032
- const newEdge = (g as any).createEdge(ka, kb, w, val);
1033
- (g as any)._addEdge(newEdge);
1032
+ const newEdge = g.createEdge(ka, kb, e.weight, e.value);
1033
+ (g as this & { _addEdge(edge: EO): boolean })._addEdge(newEdge);
1034
1034
  }
1035
1035
  }
1036
1036
  return g;
@@ -207,8 +207,8 @@ export class DirectedGraph<
207
207
  * @returns DirectedGraph with all keys added.
208
208
  * @remarks Time O(V), Space O(V)
209
209
  */
210
- static fromKeys<K extends VertexKey>(keys: Iterable<K>): DirectedGraph<K, any, DirectedVertex<K>, DirectedEdge<any>> {
211
- const g: DirectedGraph<K, any, DirectedVertex<K>, DirectedEdge<any>> = new DirectedGraph<K, any>({
210
+ static fromKeys<K extends VertexKey>(keys: Iterable<K>): DirectedGraph<K, undefined, DirectedVertex<K>, DirectedEdge<undefined>> {
211
+ const g: DirectedGraph<K, undefined, DirectedVertex<K>, DirectedEdge<undefined>> = new DirectedGraph<K, undefined>({
212
212
  vertexValueInitializer: (k: VertexKey) => k as K
213
213
  });
214
214
  for (const k of keys) g.addVertex(k);
@@ -224,8 +224,8 @@ export class DirectedGraph<
224
224
  */
225
225
  static fromEntries<V>(
226
226
  entries: Iterable<[VertexKey, V]>
227
- ): DirectedGraph<V, any, DirectedVertex<V>, DirectedEdge<any>> {
228
- const g: DirectedGraph<V, any, DirectedVertex<V>, DirectedEdge<any>> = new DirectedGraph<V, any>();
227
+ ): DirectedGraph<V, undefined, DirectedVertex<V>, DirectedEdge<undefined>> {
228
+ const g: DirectedGraph<V, undefined, DirectedVertex<V>, DirectedEdge<undefined>> = new DirectedGraph<V, undefined>();
229
229
  for (const [k, v] of entries) g.addVertex(k, v);
230
230
  return g;
231
231
  }
@@ -111,7 +111,7 @@ export class MapGraph<
111
111
  * @remarks Time O(1), Space O(1)
112
112
  */
113
113
  protected override _snapshotOptions(): Record<string, unknown> {
114
- return { ...(super._snapshotOptions() as any), originCoord: this.originCoord, bottomRight: this.bottomRight };
114
+ return { ...super._snapshotOptions(), originCoord: this.originCoord, bottomRight: this.bottomRight };
115
115
  }
116
116
 
117
117
  /**
@@ -232,8 +232,8 @@ export class UndirectedGraph<
232
232
  */
233
233
  static fromKeys<K extends VertexKey>(
234
234
  keys: Iterable<K>
235
- ): UndirectedGraph<K, any, UndirectedVertex<K>, UndirectedEdge<any>> {
236
- const g: UndirectedGraph<K, any, UndirectedVertex<K>, UndirectedEdge<any>> = new UndirectedGraph<K, any>({
235
+ ): UndirectedGraph<K, undefined, UndirectedVertex<K>, UndirectedEdge<undefined>> {
236
+ const g: UndirectedGraph<K, undefined, UndirectedVertex<K>, UndirectedEdge<undefined>> = new UndirectedGraph<K, undefined>({
237
237
  vertexValueInitializer: (k: VertexKey) => k as K
238
238
  });
239
239
  for (const k of keys) g.addVertex(k);
@@ -249,8 +249,8 @@ export class UndirectedGraph<
249
249
  */
250
250
  static fromEntries<V>(
251
251
  entries: Iterable<[VertexKey, V]>
252
- ): UndirectedGraph<V, any, UndirectedVertex<V>, UndirectedEdge<any>> {
253
- const g: UndirectedGraph<V, any, UndirectedVertex<V>, UndirectedEdge<any>> = new UndirectedGraph<V, any>();
252
+ ): UndirectedGraph<V, undefined, UndirectedVertex<V>, UndirectedEdge<undefined>> {
253
+ const g: UndirectedGraph<V, undefined, UndirectedVertex<V>, UndirectedEdge<undefined>> = new UndirectedGraph<V, undefined>();
254
254
  for (const [k, v] of entries) g.addVertex(k, v);
255
255
  return g;
256
256
  }
@@ -197,7 +197,7 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
197
197
  return this._objMap;
198
198
  }
199
199
 
200
- protected _toEntryFn?: (rawElement: R) => [K, V];
200
+ protected readonly _toEntryFn?: (rawElement: R) => [K, V];
201
201
 
202
202
  /**
203
203
  * Get the raw→entry converter function if present.
@@ -530,7 +530,7 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
530
530
  return this._tail;
531
531
  }
532
532
 
533
- protected _toEntryFn?: (rawElement: R) => [K, V] = (rawElement: R) => {
533
+ protected readonly _toEntryFn?: (rawElement: R) => [K, V] = (rawElement: R) => {
534
534
  if (this.isEntry(rawElement)) {
535
535
  return rawElement;
536
536
  }
@@ -538,6 +538,7 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
538
538
  'If `entryOrRawElements` does not adhere to [key,value], provide `options.toEntryFn` to transform raw records.'
539
539
  );
540
540
  };
541
+
541
542
  get toEntryFn() {
542
543
  return this._toEntryFn;
543
544
  }
@@ -712,8 +713,9 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
712
713
  const cur = node;
713
714
  node = node.next;
714
715
  if (predicate(cur.key as K, cur.value as V | undefined, i++, this)) {
715
- if (isWeakKey(cur.key as unknown as object)) {
716
- this._objMap.delete(cur.key as unknown as object);
716
+ const keyToCheck: unknown = cur.key;
717
+ if (isWeakKey(keyToCheck)) {
718
+ this._objMap.delete(keyToCheck);
717
719
  } else {
718
720
  const hash = this._hashFn(cur.key as K);
719
721
  delete this._noObjMap[hash];
@@ -639,20 +639,17 @@ export class Heap<E = any, R = any> extends IterableElementBase<E, R> {
639
639
  return out;
640
640
  }
641
641
 
642
- protected _DEFAULT_COMPARATOR = (a: E, b: E): number => {
642
+ protected readonly _DEFAULT_COMPARATOR: Comparator<E> = (a: E, b: E): number => {
643
643
  if (typeof a === 'object' || typeof b === 'object') {
644
644
  throw TypeError('When comparing object types, define a custom comparator in options.');
645
645
  }
646
- if ((a as unknown as number) > (b as unknown as number)) return 1;
647
- if ((a as unknown as number) < (b as unknown as number)) return -1;
646
+ if (a > b) return 1;
647
+ if (a < b) return -1;
648
648
  return 0;
649
649
  };
650
650
 
651
- protected _comparator: Comparator<E> = this._DEFAULT_COMPARATOR; /**
652
- * Get the comparator used to order elements.
653
- * @remarks Time O(1), Space O(1)
654
- * @returns Comparator function.
655
- */
651
+ protected readonly _comparator: Comparator<E> = this._DEFAULT_COMPARATOR;
652
+
656
653
  /**
657
654
  * Get the comparator used to order elements.
658
655
  * @remarks Time O(1), Space O(1)
@@ -706,9 +703,11 @@ export class Heap<E = any, R = any> extends IterableElementBase<E, R> {
706
703
  */
707
704
 
708
705
  protected _createInstance(options?: HeapOptions<E, R>): this {
709
- const Ctor: any = this.constructor;
710
- const next: any = new Ctor([], { comparator: this.comparator, toElementFn: this.toElementFn, ...(options ?? {}) });
711
- return next as this;
706
+ const Ctor = this.constructor as new (
707
+ elements?: Iterable<E> | Iterable<R>,
708
+ options?: HeapOptions<E, R>
709
+ ) => this;
710
+ return new Ctor([], { comparator: this.comparator, toElementFn: this.toElementFn, ...(options ?? {}) });
712
711
  }
713
712
 
714
713
  /**
@@ -725,8 +724,11 @@ export class Heap<E = any, R = any> extends IterableElementBase<E, R> {
725
724
  elements: Iterable<EM> | Iterable<RM> = [],
726
725
  options?: HeapOptions<EM, RM>
727
726
  ): Heap<EM, RM> {
728
- const Ctor: any = this.constructor;
729
- return new Ctor(elements, options) as Heap<EM, RM>;
727
+ const Ctor = this.constructor as new (
728
+ elements?: Iterable<EM> | Iterable<RM>,
729
+ options?: HeapOptions<EM, RM>
730
+ ) => Heap<EM, RM>;
731
+ return new Ctor(elements, options);
730
732
  }
731
733
 
732
734
  /**
@@ -813,7 +815,8 @@ export class FibonacciHeap<E> {
813
815
  return this._min;
814
816
  }
815
817
 
816
- protected _comparator: Comparator<E>;
818
+ protected readonly _comparator: Comparator<E>;
819
+
817
820
  get comparator(): Comparator<E> {
818
821
  return this._comparator;
819
822
  }
@@ -182,7 +182,7 @@ export class DoublyLinkedListNode<E = any> extends LinkedListNode<E> {
182
182
  * console.log(foundEntry?.value); // 'Bob';
183
183
  */
184
184
  export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, DoublyLinkedListNode<E>> {
185
- protected _equals: (a: E, b: E) => boolean = Object.is as unknown as (a: E, b: E) => boolean;
185
+ protected _equals: (a: E, b: E) => boolean = (a, b) => Object.is(a, b);
186
186
 
187
187
  /**
188
188
  * Create a DoublyLinkedList and optionally bulk-insert elements.
@@ -423,8 +423,8 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
423
423
  at(index: number): E | undefined {
424
424
  if (index < 0 || index >= this._length) return undefined;
425
425
  let current = this.head;
426
- for (let i = 0; i < index; i++) current = current!.next;
427
- return current!.value;
426
+ for (let i = 0; i < index && current; i++) current = current.next;
427
+ return current?.value;
428
428
  }
429
429
 
430
430
  /**
@@ -437,7 +437,7 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
437
437
  getNodeAt(index: number): DoublyLinkedListNode<E> | undefined {
438
438
  if (index < 0 || index >= this._length) return undefined;
439
439
  let current = this.head;
440
- for (let i = 0; i < index; i++) current = current!.next;
440
+ for (let i = 0; i < index && current; i++) current = current.next;
441
441
  return current;
442
442
  }
443
443
 
@@ -246,7 +246,7 @@ export class SinglyLinkedListNode<E = any> extends LinkedListNode<E> {
246
246
  * console.log(editor.getText()); // 'Haello';
247
247
  */
248
248
  export class SinglyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, SinglyLinkedListNode<E>> {
249
- protected _equals: (a: E, b: E) => boolean = Object.is as unknown as (a: E, b: E) => boolean;
249
+ protected _equals: (a: E, b: E) => boolean = (a, b) => Object.is(a, b);
250
250
 
251
251
  /**
252
252
  * Create a SinglyLinkedList and optionally bulk-insert elements.
@@ -381,8 +381,8 @@ export class SinglyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, S
381
381
  return value;
382
382
  }
383
383
  let current = this.head;
384
- while (current.next !== this.tail) current = current.next!;
385
- const value = this.tail!.value;
384
+ while (current.next && current.next !== this.tail) current = current.next;
385
+ const value = this.tail?.value;
386
386
  current.next = undefined;
387
387
  this._tail = current;
388
388
  this._length--;
@@ -484,8 +484,8 @@ export class SinglyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, S
484
484
  at(index: number): E | undefined {
485
485
  if (index < 0 || index >= this._length) return undefined;
486
486
  let current = this.head;
487
- for (let i = 0; i < index; i++) current = current!.next;
488
- return current!.value;
487
+ for (let i = 0; i < index && current; i++) current = current.next;
488
+ return current?.value;
489
489
  }
490
490
 
491
491
  /**
@@ -511,7 +511,7 @@ export class SinglyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, S
511
511
  getNodeAt(index: number): SinglyLinkedListNode<E> | undefined {
512
512
  if (index < 0 || index >= this._length) return undefined;
513
513
  let current = this.head;
514
- for (let i = 0; i < index; i++) current = current!.next;
514
+ for (let i = 0; i < index && current; i++) current = current.next;
515
515
  return current;
516
516
  }
517
517
 
@@ -1003,7 +1003,10 @@ export class SinglyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, S
1003
1003
  */
1004
1004
 
1005
1005
  protected _createInstance(options?: SinglyLinkedListOptions<E, R>): this {
1006
- const Ctor: any = this.constructor;
1006
+ const Ctor = this.constructor as new (
1007
+ elements?: Iterable<E> | Iterable<R> | Iterable<SinglyLinkedListNode<E>>,
1008
+ options?: SinglyLinkedListOptions<E, R>
1009
+ ) => this;
1007
1010
  return new Ctor([], options);
1008
1011
  }
1009
1012
 
@@ -1021,8 +1024,11 @@ export class SinglyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, S
1021
1024
  elements: Iterable<EM> | Iterable<RM> | Iterable<SinglyLinkedListNode<EM>> = [],
1022
1025
  options?: SinglyLinkedListOptions<EM, RM>
1023
1026
  ): SinglyLinkedList<EM, RM> {
1024
- const Ctor: any = this.constructor;
1025
- return new Ctor(elements, options) as SinglyLinkedList<EM, RM>;
1027
+ const Ctor = this.constructor as new (
1028
+ elements?: Iterable<EM> | Iterable<RM> | Iterable<SinglyLinkedListNode<EM>>,
1029
+ options?: SinglyLinkedListOptions<EM, RM>
1030
+ ) => SinglyLinkedList<EM, RM>;
1031
+ return new Ctor(elements, options);
1026
1032
  }
1027
1033
 
1028
1034
  /**
@@ -144,7 +144,7 @@ import { LinearBase } from '../base/linear-base';
144
144
  * console.log(dataWindow.length); // 3;
145
145
  */
146
146
  export class Deque<E = any, R = any> extends LinearBase<E, R> {
147
- protected _equals: (a: E, b: E) => boolean = Object.is as unknown as (a: E, b: E) => boolean;
147
+ protected _equals: (a: E, b: E) => boolean = (a, b) => Object.is(a, b);
148
148
 
149
149
  /**
150
150
  * Create a Deque and optionally bulk-insert elements.
@@ -161,7 +161,7 @@ import { IterableElementBase } from '../base';
161
161
  * console.log(stack.elements.join('/')); // 'c';
162
162
  */
163
163
  export class Stack<E = any, R = any> extends IterableElementBase<E, R> {
164
- protected _equals: (a: E, b: E) => boolean = Object.is as unknown as (a: E, b: E) => boolean;
164
+ protected _equals: (a: E, b: E) => boolean = (a, b) => Object.is(a, b);
165
165
 
166
166
  /**
167
167
  * Create a Stack and optionally bulk-push elements.
@@ -684,13 +684,15 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
684
684
  */
685
685
 
686
686
  protected _createInstance(options?: TrieOptions<R>): this {
687
- const Ctor: any = this.constructor;
688
- const next: any = new Ctor([], {
687
+ const Ctor = this.constructor as new (
688
+ elements?: Iterable<string> | Iterable<R>,
689
+ options?: TrieOptions<R>
690
+ ) => this;
691
+ return new Ctor([], {
689
692
  toElementFn: this.toElementFn,
690
693
  caseSensitive: this.caseSensitive,
691
694
  ...(options ?? {})
692
695
  });
693
- return next as this;
694
696
  }
695
697
 
696
698
  /**
@@ -703,8 +705,11 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
703
705
  */
704
706
 
705
707
  protected _createLike<RM>(elements: Iterable<string> | Iterable<RM> = [], options?: TrieOptions<RM>): Trie<RM> {
706
- const Ctor: any = this.constructor;
707
- return new Ctor(elements, options) as Trie<RM>;
708
+ const Ctor = this.constructor as new (
709
+ elements?: Iterable<string> | Iterable<RM>,
710
+ options?: TrieOptions<RM>
711
+ ) => Trie<RM>;
712
+ return new Ctor(elements, options);
708
713
  }
709
714
 
710
715
  /**
@@ -1,3 +1,3 @@
1
1
  import { BSTOptions } from './bst';
2
2
 
3
- export type AVLTreeOptions<K, V, R> = BSTOptions<K, V, R> & {};
3
+ export type AVLTreeOptions<K, V, R> = BSTOptions<K, V, R>;
@@ -2,4 +2,4 @@ import type { BSTOptions } from './bst';
2
2
 
3
3
  export type RBTNColor = 'RED' | 'BLACK';
4
4
 
5
- export type RedBlackTreeOptions<K, V, R> = BSTOptions<K, V, R> & {};
5
+ export type RedBlackTreeOptions<K, V, R> = BSTOptions<K, V, R>;
@@ -1,3 +1,3 @@
1
1
  import { LinearBaseOptions } from '../base';
2
2
 
3
- export type DoublyLinkedListOptions<E, R> = LinearBaseOptions<E, R> & {};
3
+ export type DoublyLinkedListOptions<E, R> = LinearBaseOptions<E, R>;
@@ -1,3 +1,3 @@
1
1
  import { LinearBaseOptions } from '../base';
2
2
 
3
- export type SinglyLinkedListOptions<E, R> = LinearBaseOptions<E, R> & {};
3
+ export type SinglyLinkedListOptions<E, R> = LinearBaseOptions<E, R>;
@@ -1,3 +1,3 @@
1
1
  import { HeapOptions } from '../heap';
2
2
 
3
- export type PriorityQueueOptions<E, R> = HeapOptions<E, R> & {};
3
+ export type PriorityQueueOptions<E, R> = HeapOptions<E, R>;
@@ -1,3 +1,3 @@
1
1
  import { IterableElementBaseOptions } from '../base';
2
2
 
3
- export type StackOptions<E, R> = IterableElementBaseOptions<E, R> & {};
3
+ export type StackOptions<E, R> = IterableElementBaseOptions<E, R>;