@statelyai/graph 1.0.0 → 2.0.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 (53) hide show
  1. package/README.md +55 -26
  2. package/dist/{adjacency-list-VsUaH9SJ.mjs → adjacency-list-GeL1Cu-L.mjs} +3 -1
  3. package/dist/{algorithms-fTqmvhzP.d.mts → algorithms-CsGNehct.d.mts} +137 -2
  4. package/dist/{algorithms-Ba7o7niK.mjs → algorithms-DF1pSQGv.mjs} +1476 -343
  5. package/dist/algorithms.d.mts +2 -2
  6. package/dist/algorithms.mjs +2 -2
  7. package/dist/{converter-udLITX36.mjs → converter-DyCJJfTe.mjs} +2 -2
  8. package/dist/format-support.mjs +38 -11
  9. package/dist/formats/adjacency-list/index.d.mts +1 -1
  10. package/dist/formats/adjacency-list/index.mjs +1 -1
  11. package/dist/formats/converter/index.d.mts +1 -1
  12. package/dist/formats/converter/index.mjs +1 -1
  13. package/dist/formats/cytoscape/index.d.mts +1 -1
  14. package/dist/formats/cytoscape/index.mjs +3 -1
  15. package/dist/formats/d2/index.d.mts +1 -1
  16. package/dist/formats/d2/index.mjs +26 -12
  17. package/dist/formats/d3/index.d.mts +1 -1
  18. package/dist/formats/d3/index.mjs +3 -1
  19. package/dist/formats/dot/index.d.mts +1 -1
  20. package/dist/formats/dot/index.mjs +22 -6
  21. package/dist/formats/edge-list/index.d.mts +1 -1
  22. package/dist/formats/edge-list/index.mjs +1 -1
  23. package/dist/formats/elk/index.d.mts +1 -1
  24. package/dist/formats/elk/index.mjs +21 -14
  25. package/dist/formats/gexf/index.d.mts +1 -1
  26. package/dist/formats/gexf/index.mjs +22 -15
  27. package/dist/formats/gml/index.d.mts +1 -1
  28. package/dist/formats/gml/index.mjs +21 -12
  29. package/dist/formats/graphml/index.d.mts +1 -1
  30. package/dist/formats/graphml/index.mjs +73 -22
  31. package/dist/formats/jgf/index.d.mts +1 -1
  32. package/dist/formats/jgf/index.mjs +5 -2
  33. package/dist/formats/mermaid/index.d.mts +1 -1
  34. package/dist/formats/mermaid/index.mjs +49 -12
  35. package/dist/formats/tgf/index.d.mts +1 -1
  36. package/dist/formats/tgf/index.mjs +1 -1
  37. package/dist/formats/xyflow/index.d.mts +1 -1
  38. package/dist/formats/xyflow/index.mjs +31 -4
  39. package/dist/{index-D9Kj6Fe3.d.mts → index-D51lJnt2.d.mts} +1 -1
  40. package/dist/{index-CHoriXZD.d.mts → index-DWmo1mIp.d.mts} +77 -18
  41. package/dist/index.d.mts +6 -6
  42. package/dist/index.mjs +143 -295
  43. package/dist/{queries-BlkA1HAN.d.mts → queries-BfXeTXRf.d.mts} +43 -12
  44. package/dist/queries-KirMDR7e.mjs +980 -0
  45. package/dist/queries.d.mts +1 -1
  46. package/dist/queries.mjs +1 -768
  47. package/dist/schemas.d.mts +1 -1
  48. package/dist/schemas.mjs +23 -84
  49. package/dist/{types-3-FS9NV2.d.mts → types-DNYdIU21.d.mts} +54 -5
  50. package/dist/validate-TtH-x3JV.mjs +190 -0
  51. package/package.json +13 -3
  52. package/dist/indexing-DR8M1vBy.mjs +0 -137
  53. /package/dist/{edge-list-DP4otyPU.mjs → edge-list-BcZ0h6zz.mjs} +0 -0
package/README.md CHANGED
@@ -86,6 +86,14 @@ const roots = getSources(graph); // nodes with no incoming edges
86
86
 
87
87
  Batch operations (`addEntities`, `deleteEntities`, `updateEntities`) let you apply multiple changes at once.
88
88
 
89
+ `updateNode`/`updateEdge` accept any config field. Optional fields (position, size, `shape`, `color`, `style`, edge `weight`/`mode`/ports) can be **unset** by passing `null`; `undefined` leaves them unchanged:
90
+
91
+ ```ts
92
+ updateNode(graph, 'a', { x: 100, color: 'red' }); // set
93
+ updateEdge(graph, 'e1', { weight: 2, mode: 'undirected' });
94
+ updateNode(graph, 'a', { color: null }); // unset
95
+ ```
96
+
89
97
  ## Hierarchy
90
98
 
91
99
  Nodes support parent-child relationships for compound/nested graphs. Query children, ancestors, descendants, depth, and least common ancestor. Use `flatten()` to decompose into a flat leaf-node graph.
@@ -149,7 +157,18 @@ getEdgesByPort(graph, 'render', 'input'); // [e1]
149
157
 
150
158
  <!-- validation helpers exported from src/schemas.ts -->
151
159
 
152
- Use the `@statelyai/graph/schemas` subpath when you want runtime validation or JSON Schema generation. `validateGraph()` combines shape checks with graph invariants such as duplicate ids, dangling edges, missing parents, missing initial nodes, duplicate ports, invalid port references, and parent cycles.
160
+ For structural invariant checking without zod, the core export `getGraphIssues(graph)` returns machine-readable issues (duplicate ids, dangling edge endpoints, missing parents, parent cycles, missing initial nodes, duplicate or invalid port references) the recommended gate for untrusted or imported graphs:
161
+
162
+ ```ts
163
+ import { getGraphIssues } from '@statelyai/graph';
164
+
165
+ const issues = getGraphIssues(importedGraph);
166
+ if (issues.length > 0) {
167
+ console.error(issues.map((issue) => issue.message));
168
+ }
169
+ ```
170
+
171
+ Use the `@statelyai/graph/schemas` subpath when you want full runtime shape validation or JSON Schema generation. `validateGraph()` combines zod shape checks with the same graph invariants.
153
172
 
154
173
  ```ts
155
174
  import { GraphSchema, isGraph, validateGraph } from '@statelyai/graph/schemas';
@@ -169,7 +188,9 @@ const parsed = GraphSchema.parse(unknownValue);
169
188
 
170
189
  <!-- algorithm functions exported from src/algorithms.ts -->
171
190
 
172
- Includes traversal (BFS, DFS, preorder/postorder), pathfinding (shortest path, simple paths, all-pairs shortest paths, A*), centrality/link analysis (degree, closeness, betweenness, PageRank, HITS, eigenvector), community detection (label propagation, Girvan-Newman, greedy modularity, modularity scoring), cycle detection, connected/strongly-connected components, bridges, articulation points, biconnected components, isomorphism, topological sort, minimum spanning tree, and more. Many algorithms have lazy generator variants (`gen*`) for early exit.
191
+ Includes traversal (BFS, DFS, preorder/postorder), pathfinding (shortest path, simple paths, all-pairs shortest paths, A*), centrality/link analysis (degree, closeness, betweenness, PageRank, HITS, eigenvector), community detection (Louvain, label propagation, Girvan-Newman, greedy modularity, modularity scoring), flow (max-flow/min-cut), cycle detection, connected/strongly-connected components, bridges, articulation points, biconnected components, dominator trees, transitive reduction, isomorphism, topological sort, minimum spanning tree, and more. Many algorithms have lazy generator variants (`gen*`) for early exit.
192
+
193
+ Hot algorithm loops (centrality, components) run on an internal compressed-sparse-row snapshot — cached and invalidated transparently like the rest of the index — so they stay fast on large graphs without changing the plain-JSON model. Algorithm results are differential-tested against graphology on seeded random graphs.
173
194
 
174
195
  ```ts
175
196
  import {
@@ -183,9 +204,13 @@ import {
183
204
  getConnectedComponents,
184
205
  getMinimumSpanningTree,
185
206
  getPageRank,
207
+ getLouvainCommunities,
186
208
  getLabelPropagationCommunities,
187
209
  genGirvanNewmanCommunities,
188
210
  getBridges,
211
+ getMaxFlow,
212
+ getDominatorTree,
213
+ getTransitiveReduction,
189
214
  isIsomorphic,
190
215
  } from '@statelyai/graph';
191
216
 
@@ -201,11 +226,15 @@ isAcyclic(graph); // cycle check
201
226
  getShortestPath(graph, { from: 'a', to: 'c' }); // single shortest path
202
227
  getTopologicalSort(graph); // topological order (or null)
203
228
  getConnectedComponents(graph); // connected components
204
- getMinimumSpanningTree(graph, { weight: (e) => e.data?.weight ?? 1 }); // MST
229
+ getMinimumSpanningTree(graph, { getWeight: (e) => e.weight ?? 1 }); // MST
205
230
  getPageRank(graph); // link analysis scores
231
+ getLouvainCommunities(graph); // community detection (Louvain)
206
232
  getLabelPropagationCommunities(graph); // community detection
207
233
  [...genGirvanNewmanCommunities(graph)]; // lazy community splits
208
234
  getBridges(graph); // bridge edges
235
+ getMaxFlow(graph, { from: 'a', to: 'c' }); // max flow + min cut
236
+ getDominatorTree(graph, { from: 'a' }); // immediate dominators
237
+ getTransitiveReduction(graph); // minimal equivalent DAG
209
238
  isIsomorphic(graph, otherGraph); // structural equivalence
210
239
  ```
211
240
 
@@ -272,29 +301,29 @@ source information instead of preserving it as metadata.
272
301
 
273
302
  <!-- format support matrix derived from src/formats/support.ts -->
274
303
 
275
- | Format | Hierarchy | Ports | Visual | Round-trip | Notes |
276
- | ------------------- | --------- | ------- | ------- | ---------- | -------------------------------------------------------------------------- |
277
- | `adjacency-list` | none | none | none | partial | Connectivity only; edge metadata is lost. |
278
- | `cytoscape` | full | full | full | full | Graph, node, and edge metadata round-trip through element data. |
279
- | `d3` | full | full | full | full | Graph, node, and edge metadata round-trip through the loose JSON shape. |
280
- | `d2` | full | full | full | full | D2 syntax, hierarchy, ports, styles, and connector modes round-trip. |
281
- | `dot` | partial | partial | partial | partial | Edge port ids round-trip, but `:port:compass` mapping is still incomplete. |
282
- | `edge-list` | none | none | none | partial | Endpoints only. |
283
- | `elk` | full | full | full | full | Metadata round-trips through reserved layout options. |
284
- | `gexf` | full | full | full | full | Custom attributes preserve metadata beyond the standard viz module. |
285
- | `gml` | full | full | full | full | Graph, node, and edge metadata round-trip through direct and JSON fields. |
286
- | `graphml` | full | full | partial | partial | Ports round-trip through `<data>` fields. |
287
- | `jgf` | full | full | full | full | Graph, node, and edge metadata round-trip through `metadata` objects. |
288
- | `tgf` | none | none | none | partial | Minimal ids and labels only. |
289
- | `xyflow` | full | full | full | full | Metadata round-trips through reserved data fields. |
290
- | `mermaid/block` | partial | none | partial | partial | Syntax-driven, not port-aware. |
291
- | `mermaid/class` | none | none | none | partial | Class syntax is stored conservatively. |
292
- | `mermaid/er` | none | none | none | partial | Focuses on entities and cardinality. |
293
- | `mermaid/flowchart` | partial | none | partial | partial | `linkStyle` indices are fragile. |
294
- | `mermaid/ishikawa` | full | none | none | partial | Preserves hierarchy, not fishbone layout. |
295
- | `mermaid/mindmap` | full | none | partial | partial | Icon syntax is not fully re-emitted. |
296
- | `mermaid/sequence` | partial | none | none | partial | Actor links and menu syntax are incomplete. |
297
- | `mermaid/state` | full | none | partial | full | State syntax round-trips through graph and node data. |
304
+ | Format | Hierarchy | Ports | Visual | Round-trip | Notes |
305
+ | ------------------- | --------- | ------- | ------- | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
306
+ | `adjacency-list` | none | none | none | partial | Connectivity only; edge metadata is lost. |
307
+ | `cytoscape` | full | full | full | full | Graph/node/edge metadata (incl. per-edge `mode`) round-trips through element data. |
308
+ | `d3` | full | full | full | full | Graph/node/edge metadata (incl. per-edge `mode`) round-trips through the loose JSON shape. |
309
+ | `d2` | full | full | full | full | Hierarchy, ports, styles, and connector modes round-trip; nested `vars` sub-blocks are dropped. |
310
+ | `dot` | partial | partial | partial | partial | Edge port ids round-trip, but `:port:compass` mapping is still incomplete. |
311
+ | `edge-list` | none | none | none | partial | Endpoints only. |
312
+ | `elk` | full | full | full | full | Metadata round-trips through reserved layout options; port ids are emitted as `nodeId__portName` (document-unique, as ELK requires). |
313
+ | `gexf` | full | full | full | full | Custom attributes preserve metadata; `bidirectional` maps to directed. |
314
+ | `gml` | full | full | full | full | Metadata round-trips through direct and JSON fields; per-edge/graph `mode` via a dialect key. |
315
+ | `graphml` | full | full | partial | full | Emit is own-dialect (`<data>` fields, flat); import handles both dialects incl. standard nested `<graph>`, native `<port>` elements, and `sourceport`/`targetport` attributes. Multi-graph files import the first graph. |
316
+ | `jgf` | full | full | full | full | Metadata (incl. per-edge/graph `mode`) round-trips through `metadata` objects. |
317
+ | `tgf` | none | none | none | partial | Minimal ids and labels only. |
318
+ | `xyflow` | full | full | full | full | Metadata (incl. weight, ports, per-edge `mode`) round-trips through reserved data fields; parents are ordered before children for React Flow. |
319
+ | `mermaid/block` | partial | none | partial | partial | Syntax-driven, not port-aware. |
320
+ | `mermaid/class` | none | none | none | partial | Class syntax is stored conservatively. |
321
+ | `mermaid/er` | none | none | none | partial | Focuses on entities and cardinality. |
322
+ | `mermaid/flowchart` | partial | none | partial | partial | `linkStyle` indices are fragile. |
323
+ | `mermaid/ishikawa` | full | none | none | partial | Preserves hierarchy, not fishbone layout. |
324
+ | `mermaid/mindmap` | full | none | partial | partial | Icon syntax is not fully re-emitted. |
325
+ | `mermaid/sequence` | partial | none | none | partial | Actor links and menu syntax are incomplete. |
326
+ | `mermaid/state` | full | none | partial | partial | Isolated states and labels now emit (labels via the description form); `initialNodeId` round-trips as `[*] -->`. |
298
327
 
299
328
  Some formats have optional peer dependencies: `fast-xml-parser` (GEXF, GraphML) and `dotparser` (DOT). All other formats are dependency-free.
300
329
 
@@ -44,7 +44,9 @@ function toAdjacencyList(graph) {
44
44
  function fromAdjacencyList(adj, options) {
45
45
  const directed = options?.directed ?? true;
46
46
  const seen = /* @__PURE__ */ new Set();
47
- const nodes = Object.keys(adj).map((id) => ({
47
+ const nodeIds = new Set(Object.keys(adj));
48
+ for (const targets of Object.values(adj)) for (const targetId of targets) nodeIds.add(targetId);
49
+ const nodes = [...nodeIds].map((id) => ({
48
50
  type: "node",
49
51
  id,
50
52
  parentId: null,
@@ -1,13 +1,26 @@
1
- import { A as TraversalOptions, O as SinglePathOptions, S as MSTOptions, T as PathOptions, _ as GraphNode, n as AllPairsShortestPathsOptions, p as GraphEdge, t as AStarOptions, u as Graph, y as GraphPath } from "./types-3-FS9NV2.mjs";
1
+ import { A as SinglePathOptions, C as MSTOptions, D as PathOptions, M as TraversalOptions, b as GraphPath, d as Graph, m as GraphEdge, n as AllPairsShortestPathsOptions, t as AStarOptions, v as GraphNode } from "./types-DNYdIU21.mjs";
2
2
 
3
3
  //#region src/algorithms/traversal.d.ts
4
4
  declare function bfs<N>(graph: Graph<N>, startId: string): Generator<GraphNode<N>>;
5
5
  declare function dfs<N>(graph: Graph<N>, startId: string): Generator<GraphNode<N>>;
6
6
  declare function isAcyclic(graph: Graph): boolean;
7
7
  declare function getConnectedComponents<N>(graph: Graph<N>): GraphNode<N>[][];
8
+ /**
9
+ * Returns a topological ordering of the graph's nodes, or `null` if no such
10
+ * ordering exists.
11
+ *
12
+ * Any edge whose effective mode (per {@link getEdgeMode}) is not `'directed'`
13
+ * makes ordering impossible — an undirected/bidirectional edge is mutual
14
+ * precedence, i.e. a 2-cycle — so the function returns `null`.
15
+ */
8
16
  declare function getTopologicalSort<N>(graph: Graph<N>): GraphNode<N>[] | null;
9
17
  declare function hasPath(graph: Graph, sourceId: string, targetId: string): boolean;
10
18
  declare function isConnected(graph: Graph): boolean;
19
+ /**
20
+ * Returns whether the graph is a tree: connected, acyclic, and with exactly
21
+ * `nodes.length - 1` edges (so directed diamonds and parallel edges are not
22
+ * trees). Empty and single-node graphs are considered trees.
23
+ */
11
24
  declare function isTree(graph: Graph): boolean;
12
25
  //#endregion
13
26
  //#region src/algorithms/paths.d.ts
@@ -175,4 +188,126 @@ interface IsomorphismOptions<N = any, E = any> {
175
188
  */
176
189
  declare function isIsomorphic<N, E>(graphA: Graph<N, E>, graphB: Graph<N, E>, options?: IsomorphismOptions<N, E>): boolean;
177
190
  //#endregion
178
- export { genCycles as A, getStronglyConnectedComponents as B, getMinimumSpanningTree as C, getPostorders as D, getPostorder as E, getCycles as F, getTopologicalSort as G, bfs as H, getShortestPath as I, isConnected as J, hasPath as K, getShortestPaths as L, genSimplePaths as M, getAStarPath as N, getPreorder as O, getAllPairsShortestPaths as P, getSimplePath as R, getPageRank as S, genPreorders as T, dfs as U, joinPaths as V, getConnectedComponents as W, isTree as Y, getDegreeCentrality as _, getBridges as a, getInDegreeCentrality as b, genGirvanNewmanCommunities as c, getLabelPropagationCommunities as d, getModularity as f, getClosenessCentrality as g, getBetweennessCentrality as h, getBiconnectedComponents as i, genShortestPaths as j, getPreorders as k, getGirvanNewmanCommunities as l, IterativeCentralityOptions as m, isIsomorphic as n, GirvanNewmanOptions as o, HITSResult as p, isAcyclic as q, getArticulationPoints as r, LabelPropagationOptions as s, IsomorphismOptions as t, getGreedyModularityCommunities as u, getEigenvectorCentrality as v, genPostorders as w, getOutDegreeCentrality as x, getHITS as y, getSimplePaths as z };
191
+ //#region src/algorithms/louvain.d.ts
192
+ interface LouvainOptions<E = any> {
193
+ /** Edge weight accessor. Defaults to `edge.weight ?? 1`. */
194
+ getWeight?: (edge: GraphEdge<E>) => number;
195
+ /** Resolution parameter γ. Values > 1 favor smaller communities. Default 1. */
196
+ resolution?: number;
197
+ /** Maximum number of two-phase (local move + aggregation) passes. Default 10. */
198
+ maxPasses?: number;
199
+ }
200
+ /**
201
+ * Returns communities found by the classic two-phase Louvain modularity
202
+ * optimization (local moving + community aggregation).
203
+ *
204
+ * Like the other community algorithms in this library, the graph is treated
205
+ * as undirected regardless of `graph.mode` or per-edge modes. Parallel edges
206
+ * have their weights summed; self-loops contribute to a community's internal
207
+ * weight.
208
+ *
209
+ * The implementation is deterministic: nodes are visited in `graph.nodes`
210
+ * array order and there is no random shuffling, so tie-breaking is
211
+ * order-dependent but stable across runs.
212
+ *
213
+ * Returns communities of node ids, each community sorted lexicographically
214
+ * and communities sorted by their first id.
215
+ *
216
+ * @example
217
+ * ```ts
218
+ * const communities = getLouvainCommunities(graph);
219
+ * // [['a', 'b', 'c'], ['d', 'e', 'f']]
220
+ * ```
221
+ */
222
+ declare function getLouvainCommunities<N, E>(graph: Graph<N, E>, options?: LouvainOptions<E>): string[][];
223
+ //#endregion
224
+ //#region src/algorithms/flow.d.ts
225
+ interface MaxFlowOptions<E = any> {
226
+ /** Source node id. */
227
+ from: string;
228
+ /** Sink node id. */
229
+ to: string;
230
+ /** Edge capacity accessor. Defaults to `edge.weight ?? 1`. */
231
+ getCapacity?: (edge: GraphEdge<E>) => number;
232
+ }
233
+ interface MaxFlowResult<E = any> {
234
+ /** Maximum flow value from source to sink. */
235
+ value: number;
236
+ /** Net flow per edge id (positive means source→target direction). */
237
+ flows: Record<string, number>;
238
+ /** Edges in the minimum cut (max-flow-min-cut theorem). */
239
+ cutEdges: GraphEdge<E>[];
240
+ }
241
+ /**
242
+ * Returns the maximum flow from `from` to `to` using the Edmonds-Karp
243
+ * algorithm (BFS augmenting paths).
244
+ *
245
+ * Directed edges carry capacity from source to target only. Edges whose
246
+ * effective mode is not `'directed'` (undirected/bidirectional) are modeled
247
+ * as two independent opposite arcs, each with the edge's full capacity.
248
+ *
249
+ * The returned `flows` record maps every edge id to its net flow (positive
250
+ * in the source→target direction). `cutEdges` is a minimum s-t cut: the
251
+ * edges crossing from the source side to the sink side of the final
252
+ * residual graph; the sum of their capacities equals `value`.
253
+ *
254
+ * @example
255
+ * ```ts
256
+ * const { value, cutEdges } = getMaxFlow(graph, { from: 's', to: 't' });
257
+ * ```
258
+ */
259
+ declare function getMaxFlow<N, E>(graph: Graph<N, E>, options: MaxFlowOptions<E>): MaxFlowResult<E>;
260
+ //#endregion
261
+ //#region src/algorithms/dominators.d.ts
262
+ interface DominatorTreeOptions {
263
+ /**
264
+ * Root node id. Defaults to `graph.initialNodeId`, then to the unique
265
+ * zero-in-degree node.
266
+ */
267
+ from?: string;
268
+ }
269
+ /**
270
+ * Returns the dominator tree of the graph rooted at `from`, computed with
271
+ * the Cooper–Harvey–Kennedy iterative algorithm.
272
+ *
273
+ * Each reachable node maps to its immediate dominator's id; the root maps
274
+ * to `null`. Unreachable nodes are omitted. Traversal is mode-aware:
275
+ * undirected/bidirectional edges are traversable both ways.
276
+ *
277
+ * For statecharts this answers "which states must every path from the
278
+ * initial state pass through to reach this state?" — node `d` dominates
279
+ * node `n` when every path from the initial state to `n` goes through `d`.
280
+ *
281
+ * @example
282
+ * ```ts
283
+ * // a→b, a→c, b→d, c→d (diamond)
284
+ * getDominatorTree(graph, { from: 'a' });
285
+ * // { a: null, b: 'a', c: 'a', d: 'a' }
286
+ * ```
287
+ */
288
+ declare function getDominatorTree(graph: Graph, options?: DominatorTreeOptions): Record<string, string | null>;
289
+ //#endregion
290
+ //#region src/algorithms/reduction.d.ts
291
+ /**
292
+ * Returns a new graph with all transitively-redundant edges removed (the
293
+ * transitive reduction). The input graph is not mutated; nodes and surviving
294
+ * edges keep all of their fields.
295
+ *
296
+ * An edge u→v is removed when v is also reachable from u via a path of
297
+ * length ≥ 2. Exact-duplicate parallel edges u→v collapse to the first one
298
+ * in `graph.edges` order (a duplicate adds no reachability, so at most one
299
+ * edge per (u, v) pair survives).
300
+ *
301
+ * DAG-only: throws when the graph contains a cycle or any edge whose
302
+ * effective mode is not `'directed'`.
303
+ *
304
+ * @example
305
+ * ```ts
306
+ * // a→b, b→c, a→c
307
+ * const reduced = getTransitiveReduction(graph);
308
+ * // a→c removed; edges: a→b, b→c
309
+ * ```
310
+ */
311
+ declare function getTransitiveReduction<N, E, G, P>(graph: Graph<N, E, G, P>): Graph<N, E, G, P>;
312
+ //#endregion
313
+ export { getTopologicalSort as $, getPageRank as A, genSimplePaths as B, getBetweennessCentrality as C, getHITS as D, getEigenvectorCentrality as E, getPostorders as F, getShortestPaths as G, getAllPairsShortestPaths as H, getPreorder as I, getStronglyConnectedComponents as J, getSimplePath as K, getPreorders as L, genPostorders as M, genPreorders as N, getInDegreeCentrality as O, getPostorder as P, getConnectedComponents as Q, genCycles as R, IterativeCentralityOptions as S, getDegreeCentrality as T, getCycles as U, getAStarPath as V, getShortestPath as W, bfs as X, joinPaths as Y, dfs as Z, getGirvanNewmanCommunities as _, MaxFlowResult as a, getModularity as b, getLouvainCommunities as c, getArticulationPoints as d, hasPath as et, getBiconnectedComponents as f, genGirvanNewmanCommunities as g, LabelPropagationOptions as h, MaxFlowOptions as i, getMinimumSpanningTree as j, getOutDegreeCentrality as k, IsomorphismOptions as l, GirvanNewmanOptions as m, DominatorTreeOptions as n, isConnected as nt, getMaxFlow as o, getBridges as p, getSimplePaths as q, getDominatorTree as r, isTree as rt, LouvainOptions as s, getTransitiveReduction as t, isAcyclic as tt, isIsomorphic as u, getGreedyModularityCommunities as v, getClosenessCentrality as w, HITSResult as x, getLabelPropagationCommunities as y, genShortestPaths as z };