@graphty/algorithms 1.3.1 → 1.5.0

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 (314) hide show
  1. package/README.md +368 -422
  2. package/dist/algorithms.js +567 -264
  3. package/dist/algorithms.js.map +1 -1
  4. package/dist/src/algorithms/centrality/betweenness.d.ts +10 -0
  5. package/dist/src/algorithms/centrality/betweenness.d.ts.map +1 -1
  6. package/dist/src/algorithms/centrality/betweenness.js +27 -6
  7. package/dist/src/algorithms/centrality/betweenness.js.map +1 -1
  8. package/dist/src/algorithms/centrality/closeness.d.ts +11 -2
  9. package/dist/src/algorithms/centrality/closeness.d.ts.map +1 -1
  10. package/dist/src/algorithms/centrality/closeness.js +17 -3
  11. package/dist/src/algorithms/centrality/closeness.js.map +1 -1
  12. package/dist/src/algorithms/centrality/degree.d.ts +7 -0
  13. package/dist/src/algorithms/centrality/degree.d.ts.map +1 -1
  14. package/dist/src/algorithms/centrality/degree.js +9 -6
  15. package/dist/src/algorithms/centrality/degree.js.map +1 -1
  16. package/dist/src/algorithms/centrality/delta-pagerank-simple.d.ts +21 -3
  17. package/dist/src/algorithms/centrality/delta-pagerank-simple.d.ts.map +1 -1
  18. package/dist/src/algorithms/centrality/delta-pagerank-simple.js +25 -7
  19. package/dist/src/algorithms/centrality/delta-pagerank-simple.js.map +1 -1
  20. package/dist/src/algorithms/centrality/delta-pagerank.d.ts +28 -2
  21. package/dist/src/algorithms/centrality/delta-pagerank.d.ts.map +1 -1
  22. package/dist/src/algorithms/centrality/delta-pagerank.js +30 -4
  23. package/dist/src/algorithms/centrality/delta-pagerank.js.map +1 -1
  24. package/dist/src/algorithms/centrality/eigenvector.d.ts +10 -3
  25. package/dist/src/algorithms/centrality/eigenvector.d.ts.map +1 -1
  26. package/dist/src/algorithms/centrality/eigenvector.js +11 -4
  27. package/dist/src/algorithms/centrality/eigenvector.js.map +1 -1
  28. package/dist/src/algorithms/centrality/hits.d.ts +10 -3
  29. package/dist/src/algorithms/centrality/hits.d.ts.map +1 -1
  30. package/dist/src/algorithms/centrality/hits.js +11 -4
  31. package/dist/src/algorithms/centrality/hits.js.map +1 -1
  32. package/dist/src/algorithms/centrality/index.d.ts +1 -1
  33. package/dist/src/algorithms/centrality/index.d.ts.map +1 -1
  34. package/dist/src/algorithms/centrality/index.js +1 -1
  35. package/dist/src/algorithms/centrality/index.js.map +1 -1
  36. package/dist/src/algorithms/centrality/katz.d.ts +10 -3
  37. package/dist/src/algorithms/centrality/katz.d.ts.map +1 -1
  38. package/dist/src/algorithms/centrality/katz.js +13 -8
  39. package/dist/src/algorithms/centrality/katz.js.map +1 -1
  40. package/dist/src/algorithms/centrality/pagerank.d.ts +14 -0
  41. package/dist/src/algorithms/centrality/pagerank.d.ts.map +1 -1
  42. package/dist/src/algorithms/centrality/pagerank.js +16 -1
  43. package/dist/src/algorithms/centrality/pagerank.js.map +1 -1
  44. package/dist/src/algorithms/community/girvan-newman.d.ts +2 -3
  45. package/dist/src/algorithms/community/girvan-newman.d.ts.map +1 -1
  46. package/dist/src/algorithms/community/girvan-newman.js +21 -4
  47. package/dist/src/algorithms/community/girvan-newman.js.map +1 -1
  48. package/dist/src/algorithms/community/index.d.ts.map +1 -1
  49. package/dist/src/algorithms/community/index.js.map +1 -1
  50. package/dist/src/algorithms/community/label-propagation.d.ts +0 -3
  51. package/dist/src/algorithms/community/label-propagation.d.ts.map +1 -1
  52. package/dist/src/algorithms/community/label-propagation.js +13 -6
  53. package/dist/src/algorithms/community/label-propagation.js.map +1 -1
  54. package/dist/src/algorithms/community/leiden.d.ts +0 -1
  55. package/dist/src/algorithms/community/leiden.d.ts.map +1 -1
  56. package/dist/src/algorithms/community/leiden.js +37 -6
  57. package/dist/src/algorithms/community/leiden.js.map +1 -1
  58. package/dist/src/algorithms/community/louvain-optimized.d.ts +37 -0
  59. package/dist/src/algorithms/community/louvain-optimized.d.ts.map +1 -1
  60. package/dist/src/algorithms/community/louvain-optimized.js +42 -7
  61. package/dist/src/algorithms/community/louvain-optimized.js.map +1 -1
  62. package/dist/src/algorithms/community/louvain.d.ts +2 -3
  63. package/dist/src/algorithms/community/louvain.d.ts.map +1 -1
  64. package/dist/src/algorithms/community/louvain.js +19 -6
  65. package/dist/src/algorithms/community/louvain.js.map +1 -1
  66. package/dist/src/algorithms/community/modularity-utils.d.ts +0 -4
  67. package/dist/src/algorithms/community/modularity-utils.d.ts.map +1 -1
  68. package/dist/src/algorithms/community/modularity-utils.js +1 -5
  69. package/dist/src/algorithms/community/modularity-utils.js.map +1 -1
  70. package/dist/src/algorithms/components/connected.d.ts +23 -0
  71. package/dist/src/algorithms/components/connected.d.ts.map +1 -1
  72. package/dist/src/algorithms/components/connected.js +29 -3
  73. package/dist/src/algorithms/components/connected.js.map +1 -1
  74. package/dist/src/algorithms/matching/bipartite.d.ts +10 -0
  75. package/dist/src/algorithms/matching/bipartite.d.ts.map +1 -1
  76. package/dist/src/algorithms/matching/bipartite.js +10 -0
  77. package/dist/src/algorithms/matching/bipartite.js.map +1 -1
  78. package/dist/src/algorithms/matching/index.d.ts.map +1 -1
  79. package/dist/src/algorithms/matching/index.js.map +1 -1
  80. package/dist/src/algorithms/matching/isomorphism.d.ts +8 -0
  81. package/dist/src/algorithms/matching/isomorphism.d.ts.map +1 -1
  82. package/dist/src/algorithms/matching/isomorphism.js +36 -2
  83. package/dist/src/algorithms/matching/isomorphism.js.map +1 -1
  84. package/dist/src/algorithms/mst/index.d.ts.map +1 -1
  85. package/dist/src/algorithms/mst/index.js.map +1 -1
  86. package/dist/src/algorithms/mst/kruskal.d.ts +14 -0
  87. package/dist/src/algorithms/mst/kruskal.d.ts.map +1 -1
  88. package/dist/src/algorithms/mst/kruskal.js +17 -3
  89. package/dist/src/algorithms/mst/kruskal.js.map +1 -1
  90. package/dist/src/algorithms/mst/prim.d.ts +9 -0
  91. package/dist/src/algorithms/mst/prim.d.ts.map +1 -1
  92. package/dist/src/algorithms/mst/prim.js +9 -0
  93. package/dist/src/algorithms/mst/prim.js.map +1 -1
  94. package/dist/src/algorithms/shortest-path/bellman-ford.d.ts +10 -0
  95. package/dist/src/algorithms/shortest-path/bellman-ford.d.ts.map +1 -1
  96. package/dist/src/algorithms/shortest-path/bellman-ford.js +10 -0
  97. package/dist/src/algorithms/shortest-path/bellman-ford.js.map +1 -1
  98. package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.d.ts +12 -5
  99. package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.d.ts.map +1 -1
  100. package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.js +19 -17
  101. package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.js.map +1 -1
  102. package/dist/src/algorithms/shortest-path/dijkstra.d.ts +15 -0
  103. package/dist/src/algorithms/shortest-path/dijkstra.d.ts.map +1 -1
  104. package/dist/src/algorithms/shortest-path/dijkstra.js +15 -0
  105. package/dist/src/algorithms/shortest-path/dijkstra.js.map +1 -1
  106. package/dist/src/algorithms/shortest-path/floyd-warshall.d.ts +17 -0
  107. package/dist/src/algorithms/shortest-path/floyd-warshall.d.ts.map +1 -1
  108. package/dist/src/algorithms/shortest-path/floyd-warshall.js +17 -0
  109. package/dist/src/algorithms/shortest-path/floyd-warshall.js.map +1 -1
  110. package/dist/src/algorithms/shortest-path/index.d.ts.map +1 -1
  111. package/dist/src/algorithms/shortest-path/index.js.map +1 -1
  112. package/dist/src/algorithms/traversal/bfs-unified.d.ts +13 -0
  113. package/dist/src/algorithms/traversal/bfs-unified.d.ts.map +1 -1
  114. package/dist/src/algorithms/traversal/bfs-unified.js +37 -0
  115. package/dist/src/algorithms/traversal/bfs-unified.js.map +1 -1
  116. package/dist/src/algorithms/traversal/bfs-variants.d.ts +23 -0
  117. package/dist/src/algorithms/traversal/bfs-variants.d.ts.map +1 -1
  118. package/dist/src/algorithms/traversal/bfs-variants.js +34 -0
  119. package/dist/src/algorithms/traversal/bfs-variants.js.map +1 -1
  120. package/dist/src/algorithms/traversal/bfs.d.ts +1 -1
  121. package/dist/src/algorithms/traversal/bfs.d.ts.map +1 -1
  122. package/dist/src/algorithms/traversal/bfs.js +1 -1
  123. package/dist/src/algorithms/traversal/bfs.js.map +1 -1
  124. package/dist/src/algorithms/traversal/dfs.d.ts +10 -0
  125. package/dist/src/algorithms/traversal/dfs.d.ts.map +1 -1
  126. package/dist/src/algorithms/traversal/dfs.js +48 -0
  127. package/dist/src/algorithms/traversal/dfs.js.map +1 -1
  128. package/dist/src/algorithms/traversal/index.d.ts.map +1 -1
  129. package/dist/src/algorithms/traversal/index.js.map +1 -1
  130. package/dist/src/benchmark-all-algorithms.d.ts +2 -0
  131. package/dist/src/benchmark-all-algorithms.d.ts.map +1 -1
  132. package/dist/src/benchmark-all-algorithms.js +32 -3
  133. package/dist/src/benchmark-all-algorithms.js.map +1 -1
  134. package/dist/src/clustering/hierarchical.d.ts +8 -1
  135. package/dist/src/clustering/hierarchical.d.ts.map +1 -1
  136. package/dist/src/clustering/hierarchical.js +22 -6
  137. package/dist/src/clustering/hierarchical.js.map +1 -1
  138. package/dist/src/clustering/index.d.ts.map +1 -1
  139. package/dist/src/clustering/index.js.map +1 -1
  140. package/dist/src/clustering/k-core.d.ts +2 -5
  141. package/dist/src/clustering/k-core.d.ts.map +1 -1
  142. package/dist/src/clustering/k-core.js +14 -12
  143. package/dist/src/clustering/k-core.js.map +1 -1
  144. package/dist/src/clustering/mcl.d.ts +6 -0
  145. package/dist/src/clustering/mcl.d.ts.map +1 -1
  146. package/dist/src/clustering/mcl.js +34 -3
  147. package/dist/src/clustering/mcl.js.map +1 -1
  148. package/dist/src/clustering/spectral.d.ts +4 -1
  149. package/dist/src/clustering/spectral.d.ts.map +1 -1
  150. package/dist/src/clustering/spectral.js +61 -28
  151. package/dist/src/clustering/spectral.js.map +1 -1
  152. package/dist/src/core/graph.d.ts +45 -0
  153. package/dist/src/core/graph.d.ts.map +1 -1
  154. package/dist/src/core/graph.js +45 -1
  155. package/dist/src/core/graph.js.map +1 -1
  156. package/dist/src/data-structures/index.d.ts.map +1 -1
  157. package/dist/src/data-structures/index.js.map +1 -1
  158. package/dist/src/data-structures/priority-queue.d.ts +18 -1
  159. package/dist/src/data-structures/priority-queue.d.ts.map +1 -1
  160. package/dist/src/data-structures/priority-queue.js +26 -5
  161. package/dist/src/data-structures/priority-queue.js.map +1 -1
  162. package/dist/src/data-structures/union-find.d.ts +21 -0
  163. package/dist/src/data-structures/union-find.d.ts.map +1 -1
  164. package/dist/src/data-structures/union-find.js +21 -0
  165. package/dist/src/data-structures/union-find.js.map +1 -1
  166. package/dist/src/flow/ford-fulkerson.d.ts +4 -2
  167. package/dist/src/flow/ford-fulkerson.d.ts.map +1 -1
  168. package/dist/src/flow/ford-fulkerson.js +31 -2
  169. package/dist/src/flow/ford-fulkerson.js.map +1 -1
  170. package/dist/src/flow/min-cut.d.ts +0 -3
  171. package/dist/src/flow/min-cut.d.ts.map +1 -1
  172. package/dist/src/flow/min-cut.js +17 -4
  173. package/dist/src/flow/min-cut.js.map +1 -1
  174. package/dist/src/index.d.ts +2 -1
  175. package/dist/src/index.d.ts.map +1 -1
  176. package/dist/src/index.js +2 -1
  177. package/dist/src/index.js.map +1 -1
  178. package/dist/src/link-prediction/adamic-adar.d.ts +26 -0
  179. package/dist/src/link-prediction/adamic-adar.d.ts.map +1 -1
  180. package/dist/src/link-prediction/adamic-adar.js +36 -10
  181. package/dist/src/link-prediction/adamic-adar.js.map +1 -1
  182. package/dist/src/link-prediction/common-neighbors.d.ts +21 -0
  183. package/dist/src/link-prediction/common-neighbors.d.ts.map +1 -1
  184. package/dist/src/link-prediction/common-neighbors.js +27 -6
  185. package/dist/src/link-prediction/common-neighbors.js.map +1 -1
  186. package/dist/src/link-prediction/index.d.ts.map +1 -1
  187. package/dist/src/optimized/bit-packed.d.ts +103 -53
  188. package/dist/src/optimized/bit-packed.d.ts.map +1 -1
  189. package/dist/src/optimized/bit-packed.js +104 -54
  190. package/dist/src/optimized/bit-packed.js.map +1 -1
  191. package/dist/src/optimized/csr-graph.d.ts +87 -24
  192. package/dist/src/optimized/csr-graph.d.ts.map +1 -1
  193. package/dist/src/optimized/csr-graph.js +87 -24
  194. package/dist/src/optimized/csr-graph.js.map +1 -1
  195. package/dist/src/optimized/direction-optimized-bfs.d.ts +37 -16
  196. package/dist/src/optimized/direction-optimized-bfs.d.ts.map +1 -1
  197. package/dist/src/optimized/direction-optimized-bfs.js +39 -20
  198. package/dist/src/optimized/direction-optimized-bfs.js.map +1 -1
  199. package/dist/src/optimized/graph-adapter.d.ts +58 -9
  200. package/dist/src/optimized/graph-adapter.d.ts.map +1 -1
  201. package/dist/src/optimized/graph-adapter.js +58 -10
  202. package/dist/src/optimized/graph-adapter.js.map +1 -1
  203. package/dist/src/optimized/index.d.ts +1 -1
  204. package/dist/src/optimized/index.d.ts.map +1 -1
  205. package/dist/src/optimized/index.js +3 -1
  206. package/dist/src/optimized/index.js.map +1 -1
  207. package/dist/src/pathfinding/astar.d.ts +25 -9
  208. package/dist/src/pathfinding/astar.d.ts.map +1 -1
  209. package/dist/src/pathfinding/astar.js +25 -10
  210. package/dist/src/pathfinding/astar.js.map +1 -1
  211. package/dist/src/pathfinding/utils.d.ts +15 -6
  212. package/dist/src/pathfinding/utils.d.ts.map +1 -1
  213. package/dist/src/pathfinding/utils.js +19 -7
  214. package/dist/src/pathfinding/utils.js.map +1 -1
  215. package/dist/src/research/grsbm.d.ts +0 -1
  216. package/dist/src/research/grsbm.d.ts.map +1 -1
  217. package/dist/src/research/grsbm.js +23 -10
  218. package/dist/src/research/grsbm.js.map +1 -1
  219. package/dist/src/research/index.d.ts.map +1 -1
  220. package/dist/src/research/index.js.map +1 -1
  221. package/dist/src/research/sync.d.ts +0 -1
  222. package/dist/src/research/sync.d.ts.map +1 -1
  223. package/dist/src/research/sync.js +29 -8
  224. package/dist/src/research/sync.js.map +1 -1
  225. package/dist/src/research/terahac.d.ts +0 -1
  226. package/dist/src/research/terahac.d.ts.map +1 -1
  227. package/dist/src/research/terahac.js +32 -4
  228. package/dist/src/research/terahac.js.map +1 -1
  229. package/dist/src/utils/graph-converters.d.ts +31 -0
  230. package/dist/src/utils/graph-converters.d.ts.map +1 -1
  231. package/dist/src/utils/graph-converters.js +31 -0
  232. package/dist/src/utils/graph-converters.js.map +1 -1
  233. package/dist/src/utils/graph-utilities.d.ts.map +1 -1
  234. package/dist/src/utils/graph-utilities.js.map +1 -1
  235. package/dist/src/utils/math-utilities.d.ts +11 -0
  236. package/dist/src/utils/math-utilities.d.ts.map +1 -1
  237. package/dist/src/utils/math-utilities.js +14 -5
  238. package/dist/src/utils/math-utilities.js.map +1 -1
  239. package/dist/src/utils/optimization-helpers.d.ts +9 -0
  240. package/dist/src/utils/optimization-helpers.d.ts.map +1 -1
  241. package/dist/src/utils/optimization-helpers.js +12 -0
  242. package/dist/src/utils/optimization-helpers.js.map +1 -1
  243. package/dist/src/utils/priorityQueue.d.ts +24 -0
  244. package/dist/src/utils/priorityQueue.d.ts.map +1 -1
  245. package/dist/src/utils/priorityQueue.js +34 -4
  246. package/dist/src/utils/priorityQueue.js.map +1 -1
  247. package/dist/tsconfig.tsbuildinfo +1 -0
  248. package/package.json +56 -65
  249. package/src/algorithms/centrality/betweenness.ts +34 -17
  250. package/src/algorithms/centrality/closeness.ts +34 -17
  251. package/src/algorithms/centrality/degree.ts +15 -19
  252. package/src/algorithms/centrality/delta-pagerank-simple.ts +36 -28
  253. package/src/algorithms/centrality/delta-pagerank.ts +34 -11
  254. package/src/algorithms/centrality/eigenvector.ts +14 -15
  255. package/src/algorithms/centrality/hits.ts +17 -17
  256. package/src/algorithms/centrality/index.ts +20 -15
  257. package/src/algorithms/centrality/katz.ts +17 -25
  258. package/src/algorithms/centrality/pagerank.ts +26 -17
  259. package/src/algorithms/community/girvan-newman.ts +39 -28
  260. package/src/algorithms/community/index.ts +6 -7
  261. package/src/algorithms/community/label-propagation.ts +20 -28
  262. package/src/algorithms/community/leiden.ts +61 -37
  263. package/src/algorithms/community/louvain-optimized.ts +49 -20
  264. package/src/algorithms/community/louvain.ts +35 -25
  265. package/src/algorithms/community/modularity-utils.ts +5 -17
  266. package/src/algorithms/components/connected.ts +40 -17
  267. package/src/algorithms/matching/bipartite.ts +17 -10
  268. package/src/algorithms/matching/index.ts +4 -4
  269. package/src/algorithms/matching/isomorphism.ts +53 -23
  270. package/src/algorithms/mst/index.ts +3 -4
  271. package/src/algorithms/mst/kruskal.ts +21 -6
  272. package/src/algorithms/mst/prim.ts +13 -4
  273. package/src/algorithms/shortest-path/bellman-ford.ts +16 -15
  274. package/src/algorithms/shortest-path/bidirectional-dijkstra.ts +29 -29
  275. package/src/algorithms/shortest-path/dijkstra.ts +23 -17
  276. package/src/algorithms/shortest-path/floyd-warshall.ts +21 -4
  277. package/src/algorithms/shortest-path/index.ts +5 -5
  278. package/src/algorithms/traversal/bfs-unified.ts +64 -60
  279. package/src/algorithms/traversal/bfs-variants.ts +61 -37
  280. package/src/algorithms/traversal/bfs.ts +1 -7
  281. package/src/algorithms/traversal/dfs.ts +61 -42
  282. package/src/algorithms/traversal/index.ts +3 -3
  283. package/src/benchmark-all-algorithms.ts +57 -25
  284. package/src/clustering/hierarchical.ts +40 -34
  285. package/src/clustering/index.ts +8 -8
  286. package/src/clustering/k-core.ts +26 -42
  287. package/src/clustering/mcl.ts +53 -23
  288. package/src/clustering/spectral.ts +91 -57
  289. package/src/core/graph.ts +54 -14
  290. package/src/data-structures/index.ts +2 -2
  291. package/src/data-structures/priority-queue.ts +36 -11
  292. package/src/data-structures/union-find.ts +22 -1
  293. package/src/flow/ford-fulkerson.ts +62 -35
  294. package/src/flow/min-cut.ts +43 -45
  295. package/src/index.ts +3 -2
  296. package/src/link-prediction/adamic-adar.ts +65 -51
  297. package/src/link-prediction/common-neighbors.ts +45 -36
  298. package/src/link-prediction/index.ts +1 -1
  299. package/src/optimized/bit-packed.ts +106 -56
  300. package/src/optimized/csr-graph.ts +93 -30
  301. package/src/optimized/direction-optimized-bfs.ts +44 -25
  302. package/src/optimized/graph-adapter.ts +64 -16
  303. package/src/optimized/index.ts +7 -9
  304. package/src/pathfinding/astar.ts +40 -25
  305. package/src/pathfinding/utils.ts +20 -13
  306. package/src/research/grsbm.ts +31 -25
  307. package/src/research/index.ts +4 -4
  308. package/src/research/sync.ts +40 -24
  309. package/src/research/terahac.ts +54 -20
  310. package/src/utils/graph-converters.ts +42 -14
  311. package/src/utils/graph-utilities.ts +11 -37
  312. package/src/utils/math-utilities.ts +17 -8
  313. package/src/utils/optimization-helpers.ts +27 -21
  314. package/src/utils/priorityQueue.ts +40 -6
@@ -1,4 +1,4 @@
1
- import {TypedFastBitSet} from "typedfastbitset";
1
+ import { TypedFastBitSet } from "typedfastbitset";
2
2
 
3
3
  /**
4
4
  * Wrapper around TypedFastBitSet with graph-specific optimizations
@@ -10,6 +10,10 @@ export class GraphBitSet {
10
10
  private bitset: TypedFastBitSet;
11
11
  private _cardinality = 0;
12
12
 
13
+ /**
14
+ * Creates a new GraphBitSet with optional pre-allocated capacity.
15
+ * @param capacity - The initial capacity to pre-allocate for the bitset
16
+ */
13
17
  constructor(capacity?: number) {
14
18
  this.bitset = new TypedFastBitSet();
15
19
  if (capacity) {
@@ -19,8 +23,9 @@ export class GraphBitSet {
19
23
  }
20
24
 
21
25
  /**
22
- * Add a single element
23
- */
26
+ * Add a single element to the set.
27
+ * @param index - The element index to add
28
+ */
24
29
  add(index: number): void {
25
30
  if (!this.bitset.has(index)) {
26
31
  this.bitset.add(index);
@@ -29,8 +34,9 @@ export class GraphBitSet {
29
34
  }
30
35
 
31
36
  /**
32
- * Remove a single element
33
- */
37
+ * Remove a single element from the set.
38
+ * @param index - The element index to remove
39
+ */
34
40
  remove(index: number): void {
35
41
  if (this.bitset.has(index)) {
36
42
  this.bitset.remove(index);
@@ -39,30 +45,35 @@ export class GraphBitSet {
39
45
  }
40
46
 
41
47
  /**
42
- * Check if element exists
43
- */
48
+ * Check if an element exists in the set.
49
+ * @param index - The element index to check
50
+ * @returns True if the element exists, false otherwise
51
+ */
44
52
  has(index: number): boolean {
45
53
  return this.bitset.has(index);
46
54
  }
47
55
 
48
56
  /**
49
- * Clear all elements
50
- */
57
+ * Clear all elements
58
+ */
51
59
  clear(): void {
52
60
  this.bitset.clear();
53
61
  this._cardinality = 0;
54
62
  }
55
63
 
56
64
  /**
57
- * Check if empty
58
- */
65
+ * Check if the set is empty.
66
+ * @returns True if the set contains no elements, false otherwise
67
+ */
59
68
  isEmpty(): boolean {
60
69
  return this._cardinality === 0;
61
70
  }
62
71
 
63
72
  /**
64
- * Optimized for graph algorithms - add range of indices
65
- */
73
+ * Optimized for graph algorithms - add a range of indices.
74
+ * @param start - The starting index (inclusive)
75
+ * @param end - The ending index (exclusive)
76
+ */
66
77
  addRange(start: number, end: number): void {
67
78
  for (let i = start; i < end; i++) {
68
79
  if (!this.bitset.has(i)) {
@@ -73,31 +84,35 @@ export class GraphBitSet {
73
84
  }
74
85
 
75
86
  /**
76
- * Fast cardinality tracking
77
- */
87
+ * Fast cardinality tracking - get the number of elements in the set.
88
+ * @returns The number of elements in the set
89
+ */
78
90
  size(): number {
79
91
  return this._cardinality;
80
92
  }
81
93
 
82
94
  /**
83
- * Batch operations for frontier management - swap contents
84
- */
95
+ * Batch operations for frontier management - swap contents with another GraphBitSet.
96
+ * @param other - The GraphBitSet to swap contents with
97
+ */
85
98
  swap(other: GraphBitSet): void {
86
99
  [this.bitset, other.bitset] = [other.bitset, this.bitset];
87
100
  [this._cardinality, other._cardinality] = [other._cardinality, this._cardinality];
88
101
  }
89
102
 
90
103
  /**
91
- * Efficient iteration
92
- */
104
+ * Efficient iteration over all elements in the set.
105
+ * @yields The indices of elements in the set
106
+ */
93
107
  *[Symbol.iterator](): Generator<number> {
94
- // Use TypedFastBitSet's optimized iteration
108
+ // Use TypedFastBitSet's optimized iteration
95
109
  yield* this.bitset;
96
110
  }
97
111
 
98
112
  /**
99
- * Set operations with cardinality tracking
100
- */
113
+ * Perform union operation with another GraphBitSet, updating this set in place.
114
+ * @param other - The GraphBitSet to union with
115
+ */
101
116
  union(other: GraphBitSet): void {
102
117
  const result = this.bitset.union(other.bitset);
103
118
  this.bitset = result;
@@ -106,6 +121,10 @@ export class GraphBitSet {
106
121
  this._cardinality = size;
107
122
  }
108
123
 
124
+ /**
125
+ * Perform intersection operation with another GraphBitSet, updating this set in place.
126
+ * @param other - The GraphBitSet to intersect with
127
+ */
109
128
  intersection(other: GraphBitSet): void {
110
129
  const result = this.bitset.intersection(other.bitset);
111
130
  this.bitset = result;
@@ -114,6 +133,10 @@ export class GraphBitSet {
114
133
  this._cardinality = size;
115
134
  }
116
135
 
136
+ /**
137
+ * Perform difference operation with another GraphBitSet, updating this set in place.
138
+ * @param other - The GraphBitSet to subtract from this set
139
+ */
117
140
  difference(other: GraphBitSet): void {
118
141
  const result = this.bitset.difference(other.bitset);
119
142
  this.bitset = result;
@@ -123,8 +146,9 @@ export class GraphBitSet {
123
146
  }
124
147
 
125
148
  /**
126
- * Clone the bitset
127
- */
149
+ * Clone the bitset.
150
+ * @returns A new GraphBitSet with the same elements
151
+ */
128
152
  clone(): GraphBitSet {
129
153
  const cloned = new GraphBitSet();
130
154
  cloned.bitset = this.bitset.clone();
@@ -145,6 +169,10 @@ export class VisitedBitArray {
145
169
  private wordCount: number;
146
170
  private _size: number;
147
171
 
172
+ /**
173
+ * Creates a new VisitedBitArray with the specified size.
174
+ * @param size - The number of bits to allocate
175
+ */
148
176
  constructor(size: number) {
149
177
  this._size = size;
150
178
  this.wordCount = Math.ceil(size / 32);
@@ -152,8 +180,9 @@ export class VisitedBitArray {
152
180
  }
153
181
 
154
182
  /**
155
- * Set bit at index
156
- */
183
+ * Set bit at the specified index.
184
+ * @param index - The bit index to set
185
+ */
157
186
  set(index: number): void {
158
187
  if (index < 0 || index >= this._size) {
159
188
  throw new Error(`Index ${String(index)} out of bounds [0, ${String(this._size)})`);
@@ -168,8 +197,10 @@ export class VisitedBitArray {
168
197
  }
169
198
 
170
199
  /**
171
- * Get bit at index
172
- */
200
+ * Get bit value at the specified index.
201
+ * @param index - The bit index to get
202
+ * @returns True if the bit is set, false otherwise
203
+ */
173
204
  get(index: number): boolean {
174
205
  if (index < 0 || index >= this._size) {
175
206
  return false;
@@ -182,15 +213,16 @@ export class VisitedBitArray {
182
213
  }
183
214
 
184
215
  /**
185
- * Clear all bits
186
- */
216
+ * Clear all bits
217
+ */
187
218
  clear(): void {
188
219
  this.words.fill(0);
189
220
  }
190
221
 
191
222
  /**
192
- * Toggle bit at index
193
- */
223
+ * Toggle bit at the specified index.
224
+ * @param index - The bit index to toggle
225
+ */
194
226
  toggle(index: number): void {
195
227
  if (index < 0 || index >= this._size) {
196
228
  throw new Error(`Index ${String(index)} out of bounds [0, ${String(this._size)})`);
@@ -205,8 +237,9 @@ export class VisitedBitArray {
205
237
  }
206
238
 
207
239
  /**
208
- * Population count for statistics
209
- */
240
+ * Population count for statistics - count the number of set bits.
241
+ * @returns The number of bits set to 1
242
+ */
210
243
  popcount(): number {
211
244
  let count = 0;
212
245
  for (let i = 0; i < this.wordCount; i++) {
@@ -219,26 +252,30 @@ export class VisitedBitArray {
219
252
  }
220
253
 
221
254
  /**
222
- * Efficient population count for a single word
223
- * Uses bit manipulation tricks for fast counting
224
- */
255
+ * Efficient population count for a single word.
256
+ * Uses bit manipulation tricks for fast counting.
257
+ * @param n - The 32-bit word to count
258
+ * @returns The number of bits set to 1 in the word
259
+ */
225
260
  private popcountWord(n: number): number {
226
261
  let x = n;
227
262
  x = x - ((x >>> 1) & 0x55555555);
228
263
  x = (x & 0x33333333) + ((x >>> 2) & 0x33333333);
229
- return (((x + (x >>> 4)) & 0xF0F0F0F) * 0x1010101) >>> 24;
264
+ return (((x + (x >>> 4)) & 0xf0f0f0f) * 0x1010101) >>> 24;
230
265
  }
231
266
 
232
267
  /**
233
- * Get size of the bit array
234
- */
268
+ * Get size of the bit array.
269
+ * @returns The total number of bits in the array
270
+ */
235
271
  size(): number {
236
272
  return this._size;
237
273
  }
238
274
 
239
275
  /**
240
- * Check if all bits are zero
241
- */
276
+ * Check if all bits are zero.
277
+ * @returns True if no bits are set, false otherwise
278
+ */
242
279
  isEmpty(): boolean {
243
280
  for (let i = 0; i < this.wordCount; i++) {
244
281
  if (this.words[i] !== 0) {
@@ -249,8 +286,9 @@ export class VisitedBitArray {
249
286
  }
250
287
 
251
288
  /**
252
- * Set multiple bits from array
253
- */
289
+ * Set multiple bits from an array of indices.
290
+ * @param indices - Array of bit indices to set
291
+ */
254
292
  setMultiple(indices: number[]): void {
255
293
  for (const index of indices) {
256
294
  this.set(index);
@@ -258,8 +296,9 @@ export class VisitedBitArray {
258
296
  }
259
297
 
260
298
  /**
261
- * Get indices of all set bits
262
- */
299
+ * Get indices of all set bits.
300
+ * @returns Array containing the indices of all bits that are set to 1
301
+ */
263
302
  getSetIndices(): number[] {
264
303
  const indices: number[] = [];
265
304
  for (let wordIndex = 0; wordIndex < this.wordCount; wordIndex++) {
@@ -292,6 +331,10 @@ export class CompactDistanceArray {
292
331
  private _size: number;
293
332
  private static readonly INFINITY = 65535;
294
333
 
334
+ /**
335
+ * Creates a new CompactDistanceArray with the specified size.
336
+ * @param size - The number of distance values to store
337
+ */
295
338
  constructor(size: number) {
296
339
  this._size = size;
297
340
  this.data = new Uint16Array(size);
@@ -299,8 +342,10 @@ export class CompactDistanceArray {
299
342
  }
300
343
 
301
344
  /**
302
- * Set distance at index
303
- */
345
+ * Set distance at the specified index.
346
+ * @param index - The node index to set the distance for
347
+ * @param distance - The distance value to set
348
+ */
304
349
  set(index: number, distance: number): void {
305
350
  if (distance >= CompactDistanceArray.INFINITY) {
306
351
  throw new Error(`Distance exceeds maximum value (${String(CompactDistanceArray.INFINITY - 1)})`);
@@ -310,30 +355,35 @@ export class CompactDistanceArray {
310
355
  }
311
356
 
312
357
  /**
313
- * Get distance at index
314
- */
358
+ * Get distance at the specified index.
359
+ * @param index - The node index to get the distance for
360
+ * @returns The distance value, or INFINITY if not set
361
+ */
315
362
  get(index: number): number {
316
363
  const value = this.data[index];
317
364
  return value ?? CompactDistanceArray.INFINITY; // Default to unvisited
318
365
  }
319
366
 
320
367
  /**
321
- * Check if node has been visited
322
- */
368
+ * Check if a node has been visited (has a valid distance).
369
+ * @param index - The node index to check
370
+ * @returns True if the node has been visited, false otherwise
371
+ */
323
372
  isVisited(index: number): boolean {
324
373
  return this.data[index] !== CompactDistanceArray.INFINITY;
325
374
  }
326
375
 
327
376
  /**
328
- * Reset all distances
329
- */
377
+ * Reset all distances to unvisited state.
378
+ */
330
379
  clear(): void {
331
380
  this.data.fill(CompactDistanceArray.INFINITY);
332
381
  }
333
382
 
334
383
  /**
335
- * Get size
336
- */
384
+ * Get the size of the distance array.
385
+ * @returns The number of elements in the array
386
+ */
337
387
  size(): number {
338
388
  return this._size;
339
389
  }
@@ -1,4 +1,4 @@
1
- import type {NodeId} from "../types/index.js";
1
+ import type { NodeId } from "../types/index.js";
2
2
 
3
3
  /**
4
4
  * Interface for read-only graph operations
@@ -44,19 +44,29 @@ interface CSRGraphData<TNodeId> {
44
44
  export class CSRGraph<TNodeId = NodeId> implements ReadonlyGraph<TNodeId> {
45
45
  private data: CSRGraphData<TNodeId>;
46
46
 
47
+ /**
48
+ * Creates a new CSRGraph from an adjacency list representation.
49
+ * @param adjacencyList - Map of node IDs to arrays of neighbor node IDs
50
+ * @param weights - Optional map of edge weights keyed by "source-target" strings
51
+ * @param buildReverse - Whether to build reverse edges for bottom-up BFS (default true)
52
+ */
47
53
  constructor(adjacencyList: Map<TNodeId, TNodeId[]>, weights?: Map<string, number>, buildReverse = true) {
48
54
  this.data = this.buildCSR(adjacencyList, weights, buildReverse);
49
55
  }
50
56
 
51
57
  /**
52
- * Build CSR structure from adjacency list
53
- */
58
+ * Build CSR structure from adjacency list.
59
+ * @param adjacencyList - Map of node IDs to arrays of neighbor node IDs
60
+ * @param weights - Optional map of edge weights keyed by "source-target" strings
61
+ * @param buildReverse - Whether to build reverse edges for bottom-up BFS
62
+ * @returns The constructed CSR graph data structure
63
+ */
54
64
  private buildCSR(
55
65
  adjacencyList: Map<TNodeId, TNodeId[]>,
56
66
  weights?: Map<string, number>,
57
67
  buildReverse = true,
58
68
  ): CSRGraphData<TNodeId> {
59
- // Collect all unique nodes (both sources and targets)
69
+ // Collect all unique nodes (both sources and targets)
60
70
  const allNodes = new Set<TNodeId>();
61
71
  for (const [source, neighbors] of adjacencyList) {
62
72
  allNodes.add(source);
@@ -115,7 +125,7 @@ export class CSRGraph<TNodeId = NodeId> implements ReadonlyGraph<TNodeId> {
115
125
  throw new Error(`Node ${String(n)} not found in nodeIdToIndex map`);
116
126
  }
117
127
 
118
- return {id: n, index};
128
+ return { id: n, index };
119
129
  })
120
130
  .sort((a, b) => a.index - b.index);
121
131
 
@@ -193,18 +203,37 @@ export class CSRGraph<TNodeId = NodeId> implements ReadonlyGraph<TNodeId> {
193
203
  }
194
204
 
195
205
  // Core API methods
206
+ /**
207
+ * Get the total number of nodes in the graph.
208
+ * @returns The number of nodes
209
+ */
196
210
  nodeCount(): number {
197
211
  return this.data.indexToNodeId.length;
198
212
  }
199
213
 
214
+ /**
215
+ * Get the total number of edges in the graph.
216
+ * @returns The number of edges
217
+ */
200
218
  edgeCount(): number {
201
219
  return this.data.columnIndices.length;
202
220
  }
203
221
 
222
+ /**
223
+ * Check if a node exists in the graph.
224
+ * @param nodeId - The node ID to check
225
+ * @returns True if the node exists, false otherwise
226
+ */
204
227
  hasNode(nodeId: TNodeId): boolean {
205
228
  return this.data.nodeIdToIndex.has(nodeId);
206
229
  }
207
230
 
231
+ /**
232
+ * Check if an edge exists between two nodes.
233
+ * @param source - The source node ID
234
+ * @param target - The target node ID
235
+ * @returns True if the edge exists, false otherwise
236
+ */
208
237
  hasEdge(source: TNodeId, target: TNodeId): boolean {
209
238
  const sourceIndex = this.data.nodeIdToIndex.get(source);
210
239
  const targetIndex = this.data.nodeIdToIndex.get(target);
@@ -225,8 +254,10 @@ export class CSRGraph<TNodeId = NodeId> implements ReadonlyGraph<TNodeId> {
225
254
  }
226
255
 
227
256
  /**
228
- * Get neighbors as node IDs
229
- */
257
+ * Get neighbors of a node as node IDs.
258
+ * @param nodeId - The node ID to get neighbors for
259
+ * @returns An iterator over neighbor node IDs
260
+ */
230
261
  neighbors(nodeId: TNodeId): IterableIterator<TNodeId> {
231
262
  const nodeIndex = this.data.nodeIdToIndex.get(nodeId);
232
263
  if (nodeIndex === undefined) {
@@ -236,7 +267,7 @@ export class CSRGraph<TNodeId = NodeId> implements ReadonlyGraph<TNodeId> {
236
267
  const start = this.data.rowPointers[nodeIndex];
237
268
  const end = this.data.rowPointers[nodeIndex + 1];
238
269
 
239
- const {columnIndices, indexToNodeId} = this.data;
270
+ const { columnIndices, indexToNodeId } = this.data;
240
271
  function* generateNeighbors(): Generator<TNodeId> {
241
272
  if (start !== undefined && end !== undefined) {
242
273
  for (let i = start; i < end; i++) {
@@ -255,15 +286,18 @@ export class CSRGraph<TNodeId = NodeId> implements ReadonlyGraph<TNodeId> {
255
286
  }
256
287
 
257
288
  /**
258
- * Get all nodes
259
- */
289
+ * Get all nodes in the graph.
290
+ * @returns An iterator over all node IDs
291
+ */
260
292
  nodes(): IterableIterator<TNodeId> {
261
293
  return this.data.indexToNodeId.values();
262
294
  }
263
295
 
264
296
  /**
265
- * Get neighbors as indices (internal use)
266
- */
297
+ * Get neighbors as indices (internal use).
298
+ * @param nodeIndex - The internal index of the node
299
+ * @returns Array of neighbor indices
300
+ */
267
301
  getNeighborIndices(nodeIndex: number): number[] {
268
302
  if (nodeIndex < 0 || nodeIndex >= this.data.indexToNodeId.length) {
269
303
  return [];
@@ -278,6 +312,11 @@ export class CSRGraph<TNodeId = NodeId> implements ReadonlyGraph<TNodeId> {
278
312
  return Array.from(this.data.columnIndices.subarray(start, end));
279
313
  }
280
314
 
315
+ /**
316
+ * Get the out-degree (number of outgoing edges) of a node.
317
+ * @param nodeId - The node ID to get the out-degree for
318
+ * @returns The number of outgoing edges from the node
319
+ */
281
320
  outDegree(nodeId: TNodeId): number {
282
321
  const nodeIndex = this.data.nodeIdToIndex.get(nodeId);
283
322
  if (nodeIndex === undefined) {
@@ -288,8 +327,10 @@ export class CSRGraph<TNodeId = NodeId> implements ReadonlyGraph<TNodeId> {
288
327
  }
289
328
 
290
329
  /**
291
- * Get out-degree by index (internal use)
292
- */
330
+ * Get out-degree by index (internal use).
331
+ * @param nodeIndex - The internal index of the node
332
+ * @returns The number of outgoing edges from the node
333
+ */
293
334
  outDegreeByIndex(nodeIndex: number): number {
294
335
  const start = this.data.rowPointers[nodeIndex];
295
336
  const end = this.data.rowPointers[nodeIndex + 1];
@@ -301,8 +342,10 @@ export class CSRGraph<TNodeId = NodeId> implements ReadonlyGraph<TNodeId> {
301
342
  }
302
343
 
303
344
  /**
304
- * Iterator support for neighbor indices
305
- */
345
+ * Iterator support for neighbor indices.
346
+ * @param nodeIndex - The internal index of the node
347
+ * @yields The indices of neighboring nodes
348
+ */
306
349
  *iterateNeighborIndices(nodeIndex: number): Generator<number> {
307
350
  const start = this.data.rowPointers[nodeIndex];
308
351
  const end = this.data.rowPointers[nodeIndex + 1];
@@ -318,8 +361,10 @@ export class CSRGraph<TNodeId = NodeId> implements ReadonlyGraph<TNodeId> {
318
361
  }
319
362
 
320
363
  /**
321
- * Iterator support for incoming neighbor indices (for bottom-up BFS)
322
- */
364
+ * Iterator support for incoming neighbor indices (for bottom-up BFS).
365
+ * @param nodeIndex - The internal index of the node
366
+ * @yields The indices of nodes with edges pointing to this node
367
+ */
323
368
  *iterateIncomingNeighborIndices(nodeIndex: number): Generator<number> {
324
369
  if (!this.data.reverseRowPointers || !this.data.reverseColumnIndices) {
325
370
  return;
@@ -339,8 +384,10 @@ export class CSRGraph<TNodeId = NodeId> implements ReadonlyGraph<TNodeId> {
339
384
  }
340
385
 
341
386
  /**
342
- * Convert node ID to index
343
- */
387
+ * Convert node ID to internal index.
388
+ * @param nodeId - The node ID to convert
389
+ * @returns The internal index for the node
390
+ */
344
391
  nodeToIndex(nodeId: TNodeId): number {
345
392
  const index = this.data.nodeIdToIndex.get(nodeId);
346
393
  if (index === undefined) {
@@ -351,8 +398,10 @@ export class CSRGraph<TNodeId = NodeId> implements ReadonlyGraph<TNodeId> {
351
398
  }
352
399
 
353
400
  /**
354
- * Convert index to node ID
355
- */
401
+ * Convert internal index to node ID.
402
+ * @param index - The internal index to convert
403
+ * @returns The node ID for the given index
404
+ */
356
405
  indexToNodeId(index: number): TNodeId {
357
406
  const nodeId = this.data.indexToNodeId[index];
358
407
  if (nodeId === undefined) {
@@ -363,8 +412,11 @@ export class CSRGraph<TNodeId = NodeId> implements ReadonlyGraph<TNodeId> {
363
412
  }
364
413
 
365
414
  /**
366
- * Get edge weight
367
- */
415
+ * Get edge weight between two nodes.
416
+ * @param source - The source node ID
417
+ * @param target - The target node ID
418
+ * @returns The edge weight, or undefined if the edge doesn't exist or has no weight
419
+ */
368
420
  getEdgeWeight(source: TNodeId, target: TNodeId): number | undefined {
369
421
  if (!this.data.edgeWeights) {
370
422
  return undefined;
@@ -393,8 +445,13 @@ export class CSRGraph<TNodeId = NodeId> implements ReadonlyGraph<TNodeId> {
393
445
  }
394
446
 
395
447
  /**
396
- * Binary search for target in sorted array
397
- */
448
+ * Binary search for target in sorted array.
449
+ * @param arr - The typed array to search in
450
+ * @param target - The value to search for
451
+ * @param start - The starting index (inclusive)
452
+ * @param end - The ending index (exclusive)
453
+ * @returns The index of the target, or -1 if not found
454
+ */
398
455
  private binarySearch(arr: Uint32Array, target: number, start: number, end: number): number {
399
456
  let left = start;
400
457
  let right = end - 1;
@@ -422,13 +479,19 @@ export class CSRGraph<TNodeId = NodeId> implements ReadonlyGraph<TNodeId> {
422
479
  }
423
480
 
424
481
  /**
425
- * Create CSR graph from standard Graph
426
- */
482
+ * Create CSR graph from standard Graph interface.
483
+ * @param graph - The graph object to convert, must implement nodes, neighbors, hasNode, and optionally getEdge
484
+ * @param graph.nodes - Function that returns an iterator over node objects with id property
485
+ * @param graph.neighbors - Function that returns an iterator over neighbor node IDs
486
+ * @param graph.hasNode - Function that checks if a node exists in the graph
487
+ * @param graph.getEdge - Optional function that returns edge data including weight
488
+ * @returns A new CSRGraph instance
489
+ */
427
490
  static fromGraph<TNodeId = NodeId>(graph: {
428
- nodes(): IterableIterator<{id: TNodeId}>;
491
+ nodes(): IterableIterator<{ id: TNodeId }>;
429
492
  neighbors(nodeId: TNodeId): IterableIterator<TNodeId>;
430
493
  hasNode(nodeId: TNodeId): boolean;
431
- getEdge?(source: TNodeId, target: TNodeId): {weight?: number} | undefined;
494
+ getEdge?(source: TNodeId, target: TNodeId): { weight?: number } | undefined;
432
495
  }): CSRGraph<TNodeId> {
433
496
  const adjacencyList = new Map<TNodeId, TNodeId[]>();
434
497
  const weights = new Map<string, number>();