deque-typed 2.4.4 → 2.4.5

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 (45) hide show
  1. package/dist/cjs/index.cjs +117 -38
  2. package/dist/cjs/index.cjs.map +1 -1
  3. package/dist/cjs-legacy/index.cjs +116 -37
  4. package/dist/cjs-legacy/index.cjs.map +1 -1
  5. package/dist/esm/index.mjs +117 -39
  6. package/dist/esm/index.mjs.map +1 -1
  7. package/dist/esm-legacy/index.mjs +116 -38
  8. package/dist/esm-legacy/index.mjs.map +1 -1
  9. package/dist/types/common/error.d.ts +23 -0
  10. package/dist/types/common/index.d.ts +1 -0
  11. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +10 -0
  12. package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +7 -1
  13. package/dist/types/data-structures/graph/abstract-graph.d.ts +44 -0
  14. package/dist/types/data-structures/graph/directed-graph.d.ts +1 -0
  15. package/dist/types/data-structures/graph/undirected-graph.d.ts +14 -0
  16. package/dist/types/data-structures/queue/deque.d.ts +41 -1
  17. package/dist/types/types/data-structures/queue/deque.d.ts +6 -0
  18. package/dist/umd/deque-typed.js +114 -35
  19. package/dist/umd/deque-typed.js.map +1 -1
  20. package/dist/umd/deque-typed.min.js +1 -1
  21. package/dist/umd/deque-typed.min.js.map +1 -1
  22. package/package.json +2 -2
  23. package/src/common/error.ts +60 -0
  24. package/src/common/index.ts +2 -0
  25. package/src/data-structures/base/iterable-element-base.ts +3 -2
  26. package/src/data-structures/binary-tree/binary-indexed-tree.ts +6 -5
  27. package/src/data-structures/binary-tree/binary-tree.ts +113 -42
  28. package/src/data-structures/binary-tree/bst.ts +11 -3
  29. package/src/data-structures/binary-tree/red-black-tree.ts +20 -0
  30. package/src/data-structures/binary-tree/tree-map.ts +8 -7
  31. package/src/data-structures/binary-tree/tree-multi-map.ts +4 -4
  32. package/src/data-structures/binary-tree/tree-multi-set.ts +5 -4
  33. package/src/data-structures/binary-tree/tree-set.ts +7 -6
  34. package/src/data-structures/graph/abstract-graph.ts +106 -1
  35. package/src/data-structures/graph/directed-graph.ts +4 -0
  36. package/src/data-structures/graph/undirected-graph.ts +95 -0
  37. package/src/data-structures/hash/hash-map.ts +13 -2
  38. package/src/data-structures/heap/heap.ts +4 -3
  39. package/src/data-structures/heap/max-heap.ts +2 -3
  40. package/src/data-structures/matrix/matrix.ts +9 -10
  41. package/src/data-structures/priority-queue/max-priority-queue.ts +2 -3
  42. package/src/data-structures/queue/deque.ts +71 -3
  43. package/src/data-structures/trie/trie.ts +2 -1
  44. package/src/types/data-structures/queue/deque.ts +7 -0
  45. package/src/utils/utils.ts +4 -2
@@ -6,11 +6,61 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
6
6
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
7
7
 
8
8
  // src/utils/utils.ts
9
- var rangeCheck = /* @__PURE__ */ __name((index, min, max, message = "Index out of bounds.") => {
10
- if (index < min || index > max) throw new RangeError(message);
9
+ var rangeCheck = /* @__PURE__ */ __name((index, min, max, message) => {
10
+ if (index < min || index > max) {
11
+ throw new RangeError(message != null ? message : `Index ${index} is out of range [${min}, ${max}].`);
12
+ }
11
13
  }, "rangeCheck");
12
14
  var calcMinUnitsRequired = /* @__PURE__ */ __name((totalQuantity, unitSize) => Math.floor((totalQuantity + unitSize - 1) / unitSize), "calcMinUnitsRequired");
13
15
 
16
+ // src/common/error.ts
17
+ var ERR = {
18
+ // Range / index
19
+ indexOutOfRange: /* @__PURE__ */ __name((index, min, max, ctx) => `${ctx ? ctx + ": " : ""}Index ${index} is out of range [${min}, ${max}].`, "indexOutOfRange"),
20
+ invalidIndex: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Index must be an integer.`, "invalidIndex"),
21
+ // Type / argument
22
+ invalidArgument: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidArgument"),
23
+ comparatorRequired: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Comparator is required for non-number/non-string/non-Date keys.`, "comparatorRequired"),
24
+ invalidKey: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidKey"),
25
+ notAFunction: /* @__PURE__ */ __name((name, ctx) => `${ctx ? ctx + ": " : ""}${name} must be a function.`, "notAFunction"),
26
+ invalidEntry: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Each entry must be a [key, value] tuple.`, "invalidEntry"),
27
+ invalidNaN: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}NaN is not a valid key.`, "invalidNaN"),
28
+ invalidDate: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Invalid Date key.`, "invalidDate"),
29
+ reduceEmpty: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Reduce of empty structure with no initial value.`, "reduceEmpty"),
30
+ callbackReturnType: /* @__PURE__ */ __name((expected, got, ctx) => `${ctx ? ctx + ": " : ""}Callback must return ${expected}; got ${got}.`, "callbackReturnType"),
31
+ // State / operation
32
+ invalidOperation: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidOperation"),
33
+ // Matrix
34
+ matrixDimensionMismatch: /* @__PURE__ */ __name((op) => `Matrix: Dimensions must be compatible for ${op}.`, "matrixDimensionMismatch"),
35
+ matrixSingular: /* @__PURE__ */ __name(() => "Matrix: Singular matrix, inverse does not exist.", "matrixSingular"),
36
+ matrixNotSquare: /* @__PURE__ */ __name(() => "Matrix: Must be square for inversion.", "matrixNotSquare"),
37
+ matrixNotRectangular: /* @__PURE__ */ __name(() => "Matrix: Must be rectangular for transposition.", "matrixNotRectangular"),
38
+ matrixRowMismatch: /* @__PURE__ */ __name((expected, got) => `Matrix: Expected row length ${expected}, but got ${got}.`, "matrixRowMismatch")
39
+ };
40
+
41
+ // src/common/index.ts
42
+ var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
43
+ DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
44
+ DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
45
+ return DFSOperation2;
46
+ })(DFSOperation || {});
47
+ var _Range = class _Range {
48
+ constructor(low, high, includeLow = true, includeHigh = true) {
49
+ this.low = low;
50
+ this.high = high;
51
+ this.includeLow = includeLow;
52
+ this.includeHigh = includeHigh;
53
+ }
54
+ // Determine whether a key is within the range
55
+ isInRange(key, comparator) {
56
+ const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
57
+ const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
58
+ return lowCheck && highCheck;
59
+ }
60
+ };
61
+ __name(_Range, "Range");
62
+ var Range = _Range;
63
+
14
64
  // src/data-structures/base/iterable-element-base.ts
15
65
  var _IterableElementBase = class _IterableElementBase {
16
66
  /**
@@ -33,7 +83,7 @@ var _IterableElementBase = class _IterableElementBase {
33
83
  if (options) {
34
84
  const { toElementFn } = options;
35
85
  if (typeof toElementFn === "function") this._toElementFn = toElementFn;
36
- else if (toElementFn) throw new TypeError("toElementFn must be a function type");
86
+ else if (toElementFn) throw new TypeError(ERR.notAFunction("toElementFn"));
37
87
  }
38
88
  }
39
89
  /**
@@ -189,7 +239,7 @@ var _IterableElementBase = class _IterableElementBase {
189
239
  acc = initialValue;
190
240
  } else {
191
241
  const first = iter.next();
192
- if (first.done) throw new TypeError("Reduce of empty structure with no initial value");
242
+ if (first.done) throw new TypeError(ERR.reduceEmpty());
193
243
  acc = first.value;
194
244
  index = 1;
195
245
  }
@@ -427,17 +477,16 @@ var LinearBase = _LinearBase;
427
477
 
428
478
  // src/data-structures/queue/deque.ts
429
479
  var _Deque = class _Deque extends LinearBase {
430
- /**
431
- * Create a Deque and optionally bulk-insert elements.
432
- * @remarks Time O(N), Space O(N)
433
- * @param [elements] - Iterable (or iterable-like) of elements/records to insert.
434
- * @param [options] - Options such as bucketSize, toElementFn, and maxLen.
435
- * @returns New Deque instance.
436
- */
437
480
  constructor(elements = [], options) {
438
481
  super(options);
439
482
  __publicField(this, "_equals", /* @__PURE__ */ __name((a, b) => Object.is(a, b), "_equals"));
440
483
  __publicField(this, "_bucketSize", 1 << 12);
484
+ __publicField(this, "_autoCompactRatio", 0.5);
485
+ /**
486
+ * Counter for shift/pop operations since last compaction check.
487
+ * Only checks ratio every `_bucketSize` operations to minimize overhead.
488
+ */
489
+ __publicField(this, "_compactCounter", 0);
441
490
  __publicField(this, "_bucketFirst", 0);
442
491
  __publicField(this, "_firstInBucket", 0);
443
492
  __publicField(this, "_bucketLast", 0);
@@ -446,8 +495,9 @@ var _Deque = class _Deque extends LinearBase {
446
495
  __publicField(this, "_buckets", []);
447
496
  __publicField(this, "_length", 0);
448
497
  if (options) {
449
- const { bucketSize } = options;
498
+ const { bucketSize, autoCompactRatio } = options;
450
499
  if (typeof bucketSize === "number") this._bucketSize = bucketSize;
500
+ if (typeof autoCompactRatio === "number") this._autoCompactRatio = autoCompactRatio;
451
501
  }
452
502
  let _size;
453
503
  if ("length" in elements) {
@@ -472,6 +522,24 @@ var _Deque = class _Deque extends LinearBase {
472
522
  get bucketSize() {
473
523
  return this._bucketSize;
474
524
  }
525
+ /**
526
+ * Get the auto-compaction ratio.
527
+ * When `elements / (bucketCount * bucketSize)` drops below this ratio after
528
+ * enough shift/pop operations, the deque auto-compacts.
529
+ * @remarks Time O(1), Space O(1)
530
+ * @returns Current ratio threshold. 0 means auto-compact is disabled.
531
+ */
532
+ get autoCompactRatio() {
533
+ return this._autoCompactRatio;
534
+ }
535
+ /**
536
+ * Set the auto-compaction ratio.
537
+ * @remarks Time O(1), Space O(1)
538
+ * @param value - Ratio in [0,1]. 0 disables auto-compact.
539
+ */
540
+ set autoCompactRatio(value) {
541
+ this._autoCompactRatio = value;
542
+ }
475
543
  /**
476
544
  * Get the index of the first bucket in use.
477
545
  * @remarks Time O(1), Space O(1)
@@ -603,6 +671,7 @@ var _Deque = class _Deque extends LinearBase {
603
671
  }
604
672
  }
605
673
  this._length -= 1;
674
+ this._autoCompact();
606
675
  return element;
607
676
  }
608
677
  /**
@@ -625,6 +694,7 @@ var _Deque = class _Deque extends LinearBase {
625
694
  }
626
695
  }
627
696
  this._length -= 1;
697
+ this._autoCompact();
628
698
  return element;
629
699
  }
630
700
  /**
@@ -957,11 +1027,40 @@ var _Deque = class _Deque extends LinearBase {
957
1027
  * @remarks Time O(N), Space O(1)
958
1028
  * @returns void
959
1029
  */
1030
+ /**
1031
+ * (Protected) Trigger auto-compaction if space utilization drops below threshold.
1032
+ * Only checks every `_bucketSize` operations to minimize hot-path overhead.
1033
+ * Uses element-based ratio: `elements / (bucketCount * bucketSize)`.
1034
+ */
1035
+ _autoCompact() {
1036
+ if (this._autoCompactRatio <= 0 || this._bucketCount <= 1) return;
1037
+ this._compactCounter++;
1038
+ if (this._compactCounter < this._bucketSize) return;
1039
+ this._compactCounter = 0;
1040
+ const utilization = this._length / (this._bucketCount * this._bucketSize);
1041
+ if (utilization < this._autoCompactRatio) {
1042
+ this.shrinkToFit();
1043
+ }
1044
+ }
1045
+ /**
1046
+ * Compact the deque by removing unused buckets.
1047
+ * @remarks Time O(N), Space O(1)
1048
+ * @returns True if compaction was performed (bucket count reduced).
1049
+ */
1050
+ /**
1051
+ * Compact the deque by removing unused buckets.
1052
+ * @remarks Time O(N), Space O(1)
1053
+ * @returns True if compaction was performed (bucket count reduced).
1054
+ */
1055
+ compact() {
1056
+ const before = this._bucketCount;
1057
+ this.shrinkToFit();
1058
+ return this._bucketCount < before;
1059
+ }
960
1060
  shrinkToFit() {
961
1061
  if (this._length === 0) return;
962
1062
  const newBuckets = [];
963
- if (this._bucketFirst === this._bucketLast) return;
964
- else if (this._bucketFirst < this._bucketLast) {
1063
+ if (this._bucketFirst <= this._bucketLast) {
965
1064
  for (let i = this._bucketFirst; i <= this._bucketLast; ++i) {
966
1065
  newBuckets.push(this._buckets[i]);
967
1066
  }
@@ -976,6 +1075,8 @@ var _Deque = class _Deque extends LinearBase {
976
1075
  this._bucketFirst = 0;
977
1076
  this._bucketLast = newBuckets.length - 1;
978
1077
  this._buckets = newBuckets;
1078
+ this._bucketCount = newBuckets.length;
1079
+ this._compactCounter = 0;
979
1080
  }
980
1081
  /**
981
1082
  * Deep clone this deque, preserving options.
@@ -1157,29 +1258,6 @@ var _Deque = class _Deque extends LinearBase {
1157
1258
  };
1158
1259
  __name(_Deque, "Deque");
1159
1260
  var Deque = _Deque;
1160
-
1161
- // src/common/index.ts
1162
- var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
1163
- DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
1164
- DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
1165
- return DFSOperation2;
1166
- })(DFSOperation || {});
1167
- var _Range = class _Range {
1168
- constructor(low, high, includeLow = true, includeHigh = true) {
1169
- this.low = low;
1170
- this.high = high;
1171
- this.includeLow = includeLow;
1172
- this.includeHigh = includeHigh;
1173
- }
1174
- // Determine whether a key is within the range
1175
- isInRange(key, comparator) {
1176
- const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
1177
- const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
1178
- return lowCheck && highCheck;
1179
- }
1180
- };
1181
- __name(_Range, "Range");
1182
- var Range = _Range;
1183
1261
  /**
1184
1262
  * data-structure-typed
1185
1263
  *
@@ -1190,6 +1268,7 @@ var Range = _Range;
1190
1268
 
1191
1269
  exports.DFSOperation = DFSOperation;
1192
1270
  exports.Deque = Deque;
1271
+ exports.ERR = ERR;
1193
1272
  exports.Range = Range;
1194
1273
  //# sourceMappingURL=index.cjs.map
1195
1274
  //# sourceMappingURL=index.cjs.map