directed-graph-typed 2.4.3 → 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 (65) hide show
  1. package/dist/cjs/index.cjs +150 -43
  2. package/dist/cjs/index.cjs.map +1 -1
  3. package/dist/cjs-legacy/index.cjs +151 -42
  4. package/dist/cjs-legacy/index.cjs.map +1 -1
  5. package/dist/esm/index.mjs +150 -44
  6. package/dist/esm/index.mjs.map +1 -1
  7. package/dist/esm-legacy/index.mjs +151 -43
  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/base/iterable-element-base.d.ts +1 -1
  12. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +15 -5
  13. package/dist/types/data-structures/binary-tree/bst.d.ts +1 -1
  14. package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +7 -1
  15. package/dist/types/data-structures/graph/abstract-graph.d.ts +44 -0
  16. package/dist/types/data-structures/graph/directed-graph.d.ts +3 -2
  17. package/dist/types/data-structures/graph/undirected-graph.d.ts +16 -2
  18. package/dist/types/data-structures/hash/hash-map.d.ts +2 -2
  19. package/dist/types/data-structures/heap/heap.d.ts +3 -7
  20. package/dist/types/data-structures/queue/deque.d.ts +41 -1
  21. package/dist/types/types/data-structures/binary-tree/avl-tree.d.ts +1 -1
  22. package/dist/types/types/data-structures/binary-tree/red-black-tree.d.ts +1 -1
  23. package/dist/types/types/data-structures/linked-list/doubly-linked-list.d.ts +1 -1
  24. package/dist/types/types/data-structures/linked-list/singly-linked-list.d.ts +1 -1
  25. package/dist/types/types/data-structures/priority-queue/priority-queue.d.ts +1 -1
  26. package/dist/types/types/data-structures/queue/deque.d.ts +6 -0
  27. package/dist/types/types/data-structures/stack/stack.d.ts +1 -1
  28. package/dist/umd/directed-graph-typed.js +149 -40
  29. package/dist/umd/directed-graph-typed.js.map +1 -1
  30. package/dist/umd/directed-graph-typed.min.js +3 -1
  31. package/dist/umd/directed-graph-typed.min.js.map +1 -1
  32. package/package.json +2 -2
  33. package/src/common/error.ts +60 -0
  34. package/src/common/index.ts +2 -0
  35. package/src/data-structures/base/iterable-element-base.ts +5 -4
  36. package/src/data-structures/binary-tree/binary-indexed-tree.ts +6 -5
  37. package/src/data-structures/binary-tree/binary-tree.ts +121 -49
  38. package/src/data-structures/binary-tree/bst.ts +12 -4
  39. package/src/data-structures/binary-tree/red-black-tree.ts +20 -0
  40. package/src/data-structures/binary-tree/tree-map.ts +8 -7
  41. package/src/data-structures/binary-tree/tree-multi-map.ts +4 -4
  42. package/src/data-structures/binary-tree/tree-multi-set.ts +10 -9
  43. package/src/data-structures/binary-tree/tree-set.ts +7 -6
  44. package/src/data-structures/graph/abstract-graph.ts +124 -19
  45. package/src/data-structures/graph/directed-graph.ts +8 -4
  46. package/src/data-structures/graph/map-graph.ts +1 -1
  47. package/src/data-structures/graph/undirected-graph.ts +99 -4
  48. package/src/data-structures/hash/hash-map.ts +19 -6
  49. package/src/data-structures/heap/heap.ts +21 -17
  50. package/src/data-structures/heap/max-heap.ts +2 -3
  51. package/src/data-structures/linked-list/doubly-linked-list.ts +4 -4
  52. package/src/data-structures/linked-list/singly-linked-list.ts +15 -9
  53. package/src/data-structures/matrix/matrix.ts +9 -10
  54. package/src/data-structures/priority-queue/max-priority-queue.ts +2 -3
  55. package/src/data-structures/queue/deque.ts +72 -4
  56. package/src/data-structures/stack/stack.ts +1 -1
  57. package/src/data-structures/trie/trie.ts +12 -6
  58. package/src/types/data-structures/binary-tree/avl-tree.ts +1 -1
  59. package/src/types/data-structures/binary-tree/red-black-tree.ts +1 -1
  60. package/src/types/data-structures/linked-list/doubly-linked-list.ts +1 -1
  61. package/src/types/data-structures/linked-list/singly-linked-list.ts +1 -1
  62. package/src/types/data-structures/priority-queue/priority-queue.ts +1 -1
  63. package/src/types/data-structures/queue/deque.ts +7 -0
  64. package/src/types/data-structures/stack/stack.ts +1 -1
  65. package/src/utils/utils.ts +4 -2
@@ -24,6 +24,55 @@ var arrayRemove = /* @__PURE__ */ __name(function(array, predicate) {
24
24
  return result;
25
25
  }, "arrayRemove");
26
26
 
27
+ // src/common/error.ts
28
+ var ERR = {
29
+ // Range / index
30
+ indexOutOfRange: /* @__PURE__ */ __name((index, min, max, ctx) => `${ctx ? ctx + ": " : ""}Index ${index} is out of range [${min}, ${max}].`, "indexOutOfRange"),
31
+ invalidIndex: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Index must be an integer.`, "invalidIndex"),
32
+ // Type / argument
33
+ invalidArgument: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidArgument"),
34
+ comparatorRequired: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Comparator is required for non-number/non-string/non-Date keys.`, "comparatorRequired"),
35
+ invalidKey: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidKey"),
36
+ notAFunction: /* @__PURE__ */ __name((name, ctx) => `${ctx ? ctx + ": " : ""}${name} must be a function.`, "notAFunction"),
37
+ invalidEntry: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Each entry must be a [key, value] tuple.`, "invalidEntry"),
38
+ invalidNaN: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}NaN is not a valid key.`, "invalidNaN"),
39
+ invalidDate: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Invalid Date key.`, "invalidDate"),
40
+ reduceEmpty: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Reduce of empty structure with no initial value.`, "reduceEmpty"),
41
+ callbackReturnType: /* @__PURE__ */ __name((expected, got, ctx) => `${ctx ? ctx + ": " : ""}Callback must return ${expected}; got ${got}.`, "callbackReturnType"),
42
+ // State / operation
43
+ invalidOperation: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidOperation"),
44
+ // Matrix
45
+ matrixDimensionMismatch: /* @__PURE__ */ __name((op) => `Matrix: Dimensions must be compatible for ${op}.`, "matrixDimensionMismatch"),
46
+ matrixSingular: /* @__PURE__ */ __name(() => "Matrix: Singular matrix, inverse does not exist.", "matrixSingular"),
47
+ matrixNotSquare: /* @__PURE__ */ __name(() => "Matrix: Must be square for inversion.", "matrixNotSquare"),
48
+ matrixNotRectangular: /* @__PURE__ */ __name(() => "Matrix: Must be rectangular for transposition.", "matrixNotRectangular"),
49
+ matrixRowMismatch: /* @__PURE__ */ __name((expected, got) => `Matrix: Expected row length ${expected}, but got ${got}.`, "matrixRowMismatch")
50
+ };
51
+
52
+ // src/common/index.ts
53
+ var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
54
+ DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
55
+ DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
56
+ return DFSOperation2;
57
+ })(DFSOperation || {});
58
+ var Range = class {
59
+ constructor(low, high, includeLow = true, includeHigh = true) {
60
+ this.low = low;
61
+ this.high = high;
62
+ this.includeLow = includeLow;
63
+ this.includeHigh = includeHigh;
64
+ }
65
+ static {
66
+ __name(this, "Range");
67
+ }
68
+ // Determine whether a key is within the range
69
+ isInRange(key, comparator) {
70
+ const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
71
+ const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
72
+ return lowCheck && highCheck;
73
+ }
74
+ };
75
+
27
76
  // src/data-structures/base/iterable-entry-base.ts
28
77
  var IterableEntryBase = class {
29
78
  static {
@@ -224,7 +273,7 @@ var IterableElementBase = class {
224
273
  if (options) {
225
274
  const { toElementFn } = options;
226
275
  if (typeof toElementFn === "function") this._toElementFn = toElementFn;
227
- else if (toElementFn) throw new TypeError("toElementFn must be a function type");
276
+ else if (toElementFn) throw new TypeError(ERR.notAFunction("toElementFn"));
228
277
  }
229
278
  }
230
279
  /**
@@ -387,7 +436,7 @@ var IterableElementBase = class {
387
436
  acc = initialValue;
388
437
  } else {
389
438
  const first = iter.next();
390
- if (first.done) throw new TypeError("Reduce of empty structure with no initial value");
439
+ if (first.done) throw new TypeError(ERR.reduceEmpty());
391
440
  acc = first.value;
392
441
  index = 1;
393
442
  }
@@ -747,7 +796,7 @@ var Heap = class _Heap extends IterableElementBase {
747
796
  */
748
797
  map(callback, options, thisArg) {
749
798
  const { comparator, toElementFn, ...rest } = options ?? {};
750
- if (!comparator) throw new TypeError("Heap.map requires options.comparator for EM");
799
+ if (!comparator) throw new TypeError(ERR.comparatorRequired("Heap.map"));
751
800
  const out = this._createLike([], { ...rest, comparator, toElementFn });
752
801
  let i = 0;
753
802
  for (const x of this) {
@@ -774,18 +823,13 @@ var Heap = class _Heap extends IterableElementBase {
774
823
  }
775
824
  _DEFAULT_COMPARATOR = /* @__PURE__ */ __name((a, b) => {
776
825
  if (typeof a === "object" || typeof b === "object") {
777
- throw TypeError("When comparing object types, define a custom comparator in options.");
826
+ throw new TypeError(ERR.comparatorRequired("Heap"));
778
827
  }
779
828
  if (a > b) return 1;
780
829
  if (a < b) return -1;
781
830
  return 0;
782
831
  }, "_DEFAULT_COMPARATOR");
783
832
  _comparator = this._DEFAULT_COMPARATOR;
784
- /**
785
- * Get the comparator used to order elements.
786
- * @remarks Time O(1), Space O(1)
787
- * @returns Comparator function.
788
- */
789
833
  /**
790
834
  * Get the comparator used to order elements.
791
835
  * @remarks Time O(1), Space O(1)
@@ -834,8 +878,7 @@ var Heap = class _Heap extends IterableElementBase {
834
878
  */
835
879
  _createInstance(options) {
836
880
  const Ctor = this.constructor;
837
- const next = new Ctor([], { comparator: this.comparator, toElementFn: this.toElementFn, ...options ?? {} });
838
- return next;
881
+ return new Ctor([], { comparator: this.comparator, toElementFn: this.toElementFn, ...options ?? {} });
839
882
  }
840
883
  /**
841
884
  * (Protected) Create a like-kind instance seeded by elements.
@@ -1567,7 +1610,7 @@ var AbstractGraph = class extends IterableEntryBase {
1567
1610
  const newEdge = this.createEdge(srcOrEdge, dest, weight, value);
1568
1611
  return this._addEdge(newEdge);
1569
1612
  } else {
1570
- throw new Error("dest must be a Vertex or vertex key while srcOrEdge is an Edge");
1613
+ throw new TypeError(ERR.invalidArgument("dest must be a Vertex or vertex key when srcOrEdge is an Edge.", "Graph"));
1571
1614
  }
1572
1615
  }
1573
1616
  }
@@ -2172,8 +2215,8 @@ var AbstractGraph = class extends IterableEntryBase {
2172
2215
  const Ctor = this.constructor;
2173
2216
  const instance = new Ctor();
2174
2217
  const graph = _options?.graph;
2175
- if (graph) instance._options = { ...instance._options, ...graph };
2176
- else instance._options = { ...instance._options, ...this._options };
2218
+ if (graph) instance["_options"] = { ...instance["_options"], ...graph };
2219
+ else instance["_options"] = { ...instance["_options"], ...this._options };
2177
2220
  return instance;
2178
2221
  }
2179
2222
  /**
@@ -2206,12 +2249,10 @@ var AbstractGraph = class extends IterableEntryBase {
2206
2249
  const [va, vb] = ends;
2207
2250
  const ka = va.key;
2208
2251
  const kb = vb.key;
2209
- const hasA = g.hasVertex ? g.hasVertex(ka) : false;
2210
- const hasB = g.hasVertex ? g.hasVertex(kb) : false;
2252
+ const hasA = typeof g.hasVertex === "function" ? g.hasVertex(ka) : false;
2253
+ const hasB = typeof g.hasVertex === "function" ? g.hasVertex(kb) : false;
2211
2254
  if (hasA && hasB) {
2212
- const w = e.weight;
2213
- const val = e.value;
2214
- const newEdge = g.createEdge(ka, kb, w, val);
2255
+ const newEdge = g.createEdge(ka, kb, e.weight, e.value);
2215
2256
  g._addEdge(newEdge);
2216
2257
  }
2217
2258
  }
@@ -2249,6 +2290,92 @@ var AbstractGraph = class extends IterableEntryBase {
2249
2290
  _getVertexKey(vertexOrKey) {
2250
2291
  return vertexOrKey instanceof AbstractVertex ? vertexOrKey.key : vertexOrKey;
2251
2292
  }
2293
+ /**
2294
+ * The edge connector string used in visual output.
2295
+ * Override in subclasses (e.g., '--' for undirected, '->' for directed).
2296
+ */
2297
+ get _edgeConnector() {
2298
+ return "--";
2299
+ }
2300
+ /**
2301
+ * Generate a text-based visual representation of the graph.
2302
+ *
2303
+ * **Adjacency list format:**
2304
+ * ```
2305
+ * Graph (5 vertices, 6 edges):
2306
+ * A -> B (1), C (2)
2307
+ * B -> D (3)
2308
+ * C -> (no outgoing edges)
2309
+ * D -> A (1)
2310
+ * E (isolated)
2311
+ * ```
2312
+ *
2313
+ * @param options - Optional display settings.
2314
+ * @param options.showWeight - Whether to show edge weights (default: true).
2315
+ * @returns The visual string.
2316
+ */
2317
+ toVisual(options) {
2318
+ const showWeight = options?.showWeight ?? true;
2319
+ const vertices = [...this._vertexMap.values()];
2320
+ const vertexCount = vertices.length;
2321
+ const edgeCount = this.edgeSet().length;
2322
+ const lines = [`Graph (${vertexCount} vertices, ${edgeCount} edges):`];
2323
+ for (const vertex of vertices) {
2324
+ const neighbors = this.getNeighbors(vertex);
2325
+ if (neighbors.length === 0) {
2326
+ lines.push(` ${vertex.key} (isolated)`);
2327
+ } else {
2328
+ const edgeStrs = neighbors.map((neighbor) => {
2329
+ const edge = this.getEdge(vertex, neighbor);
2330
+ if (edge && showWeight && edge.weight !== void 0 && edge.weight !== 1) {
2331
+ return `${neighbor.key} (${edge.weight})`;
2332
+ }
2333
+ return `${neighbor.key}`;
2334
+ });
2335
+ lines.push(` ${vertex.key} ${this._edgeConnector} ${edgeStrs.join(", ")}`);
2336
+ }
2337
+ }
2338
+ return lines.join("\n");
2339
+ }
2340
+ /**
2341
+ * Generate DOT language representation for Graphviz.
2342
+ *
2343
+ * @param options - Optional display settings.
2344
+ * @param options.name - Graph name (default: 'G').
2345
+ * @param options.showWeight - Whether to label edges with weight (default: true).
2346
+ * @returns DOT format string.
2347
+ */
2348
+ toDot(options) {
2349
+ const name = options?.name ?? "G";
2350
+ const showWeight = options?.showWeight ?? true;
2351
+ const isDirected = this._edgeConnector === "->";
2352
+ const graphType = isDirected ? "digraph" : "graph";
2353
+ const edgeOp = isDirected ? "->" : "--";
2354
+ const lines = [`${graphType} ${name} {`];
2355
+ for (const vertex of this._vertexMap.values()) {
2356
+ lines.push(` "${vertex.key}";`);
2357
+ }
2358
+ const visited = /* @__PURE__ */ new Set();
2359
+ for (const vertex of this._vertexMap.values()) {
2360
+ for (const neighbor of this.getNeighbors(vertex)) {
2361
+ const edgeId = isDirected ? `${vertex.key}->${neighbor.key}` : [vertex.key, neighbor.key].sort().join("--");
2362
+ if (visited.has(edgeId)) continue;
2363
+ visited.add(edgeId);
2364
+ const edge = this.getEdge(vertex, neighbor);
2365
+ const label = edge && showWeight && edge.weight !== void 0 && edge.weight !== 1 ? ` [label="${edge.weight}"]` : "";
2366
+ lines.push(` "${vertex.key}" ${edgeOp} "${neighbor.key}"${label};`);
2367
+ }
2368
+ }
2369
+ lines.push("}");
2370
+ return lines.join("\n");
2371
+ }
2372
+ /**
2373
+ * Print the graph to console.
2374
+ * @param options - Display settings passed to `toVisual`.
2375
+ */
2376
+ print(options) {
2377
+ console.log(this.toVisual(options));
2378
+ }
2252
2379
  };
2253
2380
 
2254
2381
  // src/data-structures/graph/directed-graph.ts
@@ -2284,6 +2411,9 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
2284
2411
  constructor(options) {
2285
2412
  super(options);
2286
2413
  }
2414
+ get _edgeConnector() {
2415
+ return "->";
2416
+ }
2287
2417
  _outEdgeMap = /* @__PURE__ */ new Map();
2288
2418
  get outEdgeMap() {
2289
2419
  return this._outEdgeMap;
@@ -2730,30 +2860,6 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
2730
2860
  }
2731
2861
  }
2732
2862
  };
2733
-
2734
- // src/common/index.ts
2735
- var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
2736
- DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
2737
- DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
2738
- return DFSOperation2;
2739
- })(DFSOperation || {});
2740
- var Range = class {
2741
- constructor(low, high, includeLow = true, includeHigh = true) {
2742
- this.low = low;
2743
- this.high = high;
2744
- this.includeLow = includeLow;
2745
- this.includeHigh = includeHigh;
2746
- }
2747
- static {
2748
- __name(this, "Range");
2749
- }
2750
- // Determine whether a key is within the range
2751
- isInRange(key, comparator) {
2752
- const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
2753
- const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
2754
- return lowCheck && highCheck;
2755
- }
2756
- };
2757
2863
  /**
2758
2864
  * data-structure-typed
2759
2865
  *
@@ -2769,6 +2875,7 @@ exports.DFSOperation = DFSOperation;
2769
2875
  exports.DirectedEdge = DirectedEdge;
2770
2876
  exports.DirectedGraph = DirectedGraph;
2771
2877
  exports.DirectedVertex = DirectedVertex;
2878
+ exports.ERR = ERR;
2772
2879
  exports.Range = Range;
2773
2880
  //# sourceMappingURL=index.cjs.map
2774
2881
  //# sourceMappingURL=index.cjs.map