@quokkaquery/graph 0.1.0 → 0.1.1
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.
- package/API.md +100 -100
- package/dist/graph.d.ts +35 -2
- package/dist/graph.js +31 -3
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/package.json +1 -1
package/API.md
CHANGED
|
@@ -1,100 +1,100 @@
|
|
|
1
|
-
# @quokkaquery/graph — API Reference
|
|
2
|
-
|
|
3
|
-
Distilled API surface for agent prompts and quick reference. 7 exports from `src/index.ts`.
|
|
4
|
-
|
|
5
|
-
## Types
|
|
6
|
-
|
|
7
|
-
```typescript
|
|
8
|
-
export type NodeId = string | number
|
|
9
|
-
|
|
10
|
-
export interface GraphNode<T = unknown> {
|
|
11
|
-
id: NodeId
|
|
12
|
-
data: T
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface Edge<E = unknown> {
|
|
16
|
-
from: NodeId
|
|
17
|
-
to: NodeId
|
|
18
|
-
weight: number
|
|
19
|
-
data: E
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export interface GraphOptions {
|
|
23
|
-
directed?: boolean // default: true
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export type Visitor<T> = (node: GraphNode<T>, depth: number) => void | false
|
|
27
|
-
export type NodePredicate<T> = (node: GraphNode<T>) => boolean
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## Class
|
|
31
|
-
|
|
32
|
-
```typescript
|
|
33
|
-
export class Graph<T = unknown, E = unknown> {
|
|
34
|
-
readonly directed: boolean
|
|
35
|
-
|
|
36
|
-
constructor(opts?: GraphOptions)
|
|
37
|
-
|
|
38
|
-
// ── Nodes ──────────────────────────────────────────
|
|
39
|
-
addNode(id: NodeId, data: T): this
|
|
40
|
-
getNode(id: NodeId): GraphNode<T> | undefined
|
|
41
|
-
hasNode(id: NodeId): boolean
|
|
42
|
-
removeNode(id: NodeId): boolean
|
|
43
|
-
get nodeCount(): number
|
|
44
|
-
nodeIds(): NodeId[]
|
|
45
|
-
nodeEntries(): GraphNode<T>[]
|
|
46
|
-
|
|
47
|
-
// ── Edges ──────────────────────────────────────────
|
|
48
|
-
addEdge(from: NodeId, to: NodeId, weight?: number, data?: E): this
|
|
49
|
-
getEdge(from: NodeId, to: NodeId): Edge<E> | undefined
|
|
50
|
-
hasEdge(from: NodeId, to: NodeId): boolean
|
|
51
|
-
removeEdge(from: NodeId, to: NodeId): boolean
|
|
52
|
-
get edgeCount(): number
|
|
53
|
-
edges(): Edge<E>[]
|
|
54
|
-
neighbors(id: NodeId): NodeId[]
|
|
55
|
-
outEdges(id: NodeId): Edge<E>[]
|
|
56
|
-
inEdges(id: NodeId): Edge<E>[]
|
|
57
|
-
outDegree(id: NodeId): number
|
|
58
|
-
inDegree(id: NodeId): number
|
|
59
|
-
degree(id: NodeId): number
|
|
60
|
-
|
|
61
|
-
// ── Node helpers ───────────────────────────────────
|
|
62
|
-
predecessors(id: NodeId): NodeId[]
|
|
63
|
-
successors(id: NodeId): NodeId[]
|
|
64
|
-
connectedNodes(id: NodeId): NodeId[]
|
|
65
|
-
isSource(id: NodeId): boolean // directed only
|
|
66
|
-
isSink(id: NodeId): boolean // directed only
|
|
67
|
-
isIsolated(id: NodeId): boolean
|
|
68
|
-
sources(): NodeId[] // directed only
|
|
69
|
-
sinks(): NodeId[] // directed only
|
|
70
|
-
isolatedNodes(): NodeId[]
|
|
71
|
-
|
|
72
|
-
// ── Reachability ───────────────────────────────────
|
|
73
|
-
reachableFrom(id: NodeId): Set<NodeId>
|
|
74
|
-
reachableTo(id: NodeId): Set<NodeId>
|
|
75
|
-
|
|
76
|
-
// ── Traversals ─────────────────────────────────────
|
|
77
|
-
bfs(start: NodeId, visitor: Visitor<T>): void
|
|
78
|
-
dfs(start: NodeId, visitor: Visitor<T>): void
|
|
79
|
-
findBfs(start: NodeId, predicate: NodePredicate<T>): GraphNode<T> | undefined
|
|
80
|
-
findDfs(start: NodeId, predicate: NodePredicate<T>): GraphNode<T> | undefined
|
|
81
|
-
|
|
82
|
-
// ── Algorithms ─────────────────────────────────────
|
|
83
|
-
topologicalSort(): NodeId[] // directed only, throws on cycle
|
|
84
|
-
hasCycle(): boolean
|
|
85
|
-
dijkstra(start: NodeId, end: NodeId): { distance: number; path: NodeId[] } | undefined
|
|
86
|
-
connectedComponents(): NodeId[][] // weakly-connected for directed
|
|
87
|
-
|
|
88
|
-
// ── Transforms ─────────────────────────────────────
|
|
89
|
-
mapNodes<U>(fn: (node: GraphNode<T>) => U): Graph<U, E>
|
|
90
|
-
subgraph(ids: Set<NodeId>): Graph<T, E>
|
|
91
|
-
}
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
## Notes
|
|
95
|
-
|
|
96
|
-
- Adjacency-list representation. Directed by default.
|
|
97
|
-
- `addEdge` auto-creates missing nodes. For undirected, both directions are stored internally.
|
|
98
|
-
- `edges()` deduplicates for undirected graphs.
|
|
99
|
-
- `reachableFrom` includes the start node only if a cycle leads back to it.
|
|
100
|
-
- Visitor callbacks can return `false` to stop traversal early.
|
|
1
|
+
# @quokkaquery/graph — API Reference
|
|
2
|
+
|
|
3
|
+
Distilled API surface for agent prompts and quick reference. 7 exports from `src/index.ts`.
|
|
4
|
+
|
|
5
|
+
## Types
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
export type NodeId = string | number
|
|
9
|
+
|
|
10
|
+
export interface GraphNode<T = unknown> {
|
|
11
|
+
id: NodeId
|
|
12
|
+
data: T
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface Edge<E = unknown> {
|
|
16
|
+
from: NodeId
|
|
17
|
+
to: NodeId
|
|
18
|
+
weight: number
|
|
19
|
+
data: E
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface GraphOptions {
|
|
23
|
+
directed?: boolean // default: true
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export type Visitor<T> = (node: GraphNode<T>, depth: number) => void | false
|
|
27
|
+
export type NodePredicate<T> = (node: GraphNode<T>) => boolean
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Class
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
export class Graph<T = unknown, E = unknown> {
|
|
34
|
+
readonly directed: boolean
|
|
35
|
+
|
|
36
|
+
constructor(opts?: GraphOptions)
|
|
37
|
+
|
|
38
|
+
// ── Nodes ──────────────────────────────────────────
|
|
39
|
+
addNode(id: NodeId, data: T): this
|
|
40
|
+
getNode(id: NodeId): GraphNode<T> | undefined
|
|
41
|
+
hasNode(id: NodeId): boolean
|
|
42
|
+
removeNode(id: NodeId): boolean
|
|
43
|
+
get nodeCount(): number
|
|
44
|
+
nodeIds(): NodeId[]
|
|
45
|
+
nodeEntries(): GraphNode<T>[]
|
|
46
|
+
|
|
47
|
+
// ── Edges ──────────────────────────────────────────
|
|
48
|
+
addEdge(from: NodeId, to: NodeId, weight?: number, data?: E): this
|
|
49
|
+
getEdge(from: NodeId, to: NodeId): Edge<E> | undefined
|
|
50
|
+
hasEdge(from: NodeId, to: NodeId): boolean
|
|
51
|
+
removeEdge(from: NodeId, to: NodeId): boolean
|
|
52
|
+
get edgeCount(): number
|
|
53
|
+
edges(): Edge<E>[]
|
|
54
|
+
neighbors(id: NodeId): NodeId[]
|
|
55
|
+
outEdges(id: NodeId): Edge<E>[]
|
|
56
|
+
inEdges(id: NodeId): Edge<E>[]
|
|
57
|
+
outDegree(id: NodeId): number
|
|
58
|
+
inDegree(id: NodeId): number
|
|
59
|
+
degree(id: NodeId): number
|
|
60
|
+
|
|
61
|
+
// ── Node helpers ───────────────────────────────────
|
|
62
|
+
predecessors(id: NodeId): NodeId[]
|
|
63
|
+
successors(id: NodeId): NodeId[]
|
|
64
|
+
connectedNodes(id: NodeId): NodeId[]
|
|
65
|
+
isSource(id: NodeId): boolean // directed only
|
|
66
|
+
isSink(id: NodeId): boolean // directed only
|
|
67
|
+
isIsolated(id: NodeId): boolean
|
|
68
|
+
sources(): NodeId[] // directed only
|
|
69
|
+
sinks(): NodeId[] // directed only
|
|
70
|
+
isolatedNodes(): NodeId[]
|
|
71
|
+
|
|
72
|
+
// ── Reachability ───────────────────────────────────
|
|
73
|
+
reachableFrom(id: NodeId): Set<NodeId>
|
|
74
|
+
reachableTo(id: NodeId): Set<NodeId>
|
|
75
|
+
|
|
76
|
+
// ── Traversals ─────────────────────────────────────
|
|
77
|
+
bfs(start: NodeId, visitor: Visitor<T>): void
|
|
78
|
+
dfs(start: NodeId, visitor: Visitor<T>): void
|
|
79
|
+
findBfs(start: NodeId, predicate: NodePredicate<T>): GraphNode<T> | undefined
|
|
80
|
+
findDfs(start: NodeId, predicate: NodePredicate<T>): GraphNode<T> | undefined
|
|
81
|
+
|
|
82
|
+
// ── Algorithms ─────────────────────────────────────
|
|
83
|
+
topologicalSort(): NodeId[] // directed only, throws on cycle
|
|
84
|
+
hasCycle(): boolean
|
|
85
|
+
dijkstra(start: NodeId, end: NodeId): { distance: number; path: NodeId[] } | undefined
|
|
86
|
+
connectedComponents(): NodeId[][] // weakly-connected for directed
|
|
87
|
+
|
|
88
|
+
// ── Transforms ─────────────────────────────────────
|
|
89
|
+
mapNodes<U>(fn: (node: GraphNode<T>) => U): Graph<U, E>
|
|
90
|
+
subgraph(ids: Set<NodeId>): Graph<T, E>
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Notes
|
|
95
|
+
|
|
96
|
+
- Adjacency-list representation. Directed by default.
|
|
97
|
+
- `addEdge` auto-creates missing nodes. For undirected, both directions are stored internally.
|
|
98
|
+
- `edges()` deduplicates for undirected graphs.
|
|
99
|
+
- `reachableFrom` includes the start node only if a cycle leads back to it.
|
|
100
|
+
- Visitor callbacks can return `false` to stop traversal early.
|
package/dist/graph.d.ts
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory `Graph` class: node and edge storage, degree and reachability
|
|
3
|
+
* queries, BFS/DFS traversal, and topological sort, cycle detection,
|
|
4
|
+
* Dijkstra, connected components, mapping and subgraph extraction.
|
|
5
|
+
*/
|
|
1
6
|
import type { NodeId, GraphNode, Edge, GraphOptions, Visitor, NodePredicate } from "./types.js";
|
|
2
7
|
/**
|
|
3
8
|
* Generic graph with adjacency-list representation.
|
|
4
9
|
* Supports directed and undirected graphs, weighted edges, and common traversals.
|
|
10
|
+
* Undirected edges are stored as a pair of mirrored directed edges, so
|
|
11
|
+
* per-node edge lists contain both directions.
|
|
5
12
|
*
|
|
6
13
|
* @typeParam T - Node data type
|
|
7
14
|
* @typeParam E - Edge data type
|
|
@@ -11,19 +18,43 @@ export declare class Graph<T = unknown, E = unknown> {
|
|
|
11
18
|
private nodes;
|
|
12
19
|
private adjOut;
|
|
13
20
|
private adjIn;
|
|
21
|
+
/** Graphs are directed unless `opts.directed` is explicitly `false`. */
|
|
14
22
|
constructor(opts?: GraphOptions);
|
|
23
|
+
/** Adds or replaces a node's data; existing edges on `id` are kept. Chainable. */
|
|
15
24
|
addNode(id: NodeId, data: T): this;
|
|
16
25
|
getNode(id: NodeId): GraphNode<T> | undefined;
|
|
17
26
|
hasNode(id: NodeId): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Deletes a node and its edges; returns false if `id` was not a registered node.
|
|
29
|
+
* Only the first edge between `id` and each other node is removed from that
|
|
30
|
+
* node's lists, so parallel edges leave dangling entries behind.
|
|
31
|
+
*/
|
|
18
32
|
removeNode(id: NodeId): boolean;
|
|
19
33
|
get nodeCount(): number;
|
|
20
34
|
nodeIds(): NodeId[];
|
|
21
35
|
nodeEntries(): GraphNode<T>[];
|
|
36
|
+
/**
|
|
37
|
+
* Appends an edge (weight defaults to 1); parallel edges are allowed. Endpoints
|
|
38
|
+
* not added via `addNode` get adjacency lists but are not registered nodes:
|
|
39
|
+
* they are absent from `nodeIds`/`getNode` and skipped by traversal visitors
|
|
40
|
+
* and `dijkstra`. Chainable.
|
|
41
|
+
*/
|
|
22
42
|
addEdge(from: NodeId, to: NodeId, weight?: number, data?: E): this;
|
|
43
|
+
/** First stored edge from `from` to `to`; with parallel edges the others are not returned. */
|
|
23
44
|
getEdge(from: NodeId, to: NodeId): Edge<E> | undefined;
|
|
24
45
|
hasEdge(from: NodeId, to: NodeId): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Removes one `from`→`to` edge (and its mirror when undirected); returns false
|
|
48
|
+
* if none exists. Parallel edges must be removed one call at a time.
|
|
49
|
+
*/
|
|
25
50
|
removeEdge(from: NodeId, to: NodeId): boolean;
|
|
51
|
+
/** Number of edges; undirected edges count once despite being stored twice. */
|
|
26
52
|
get edgeCount(): number;
|
|
53
|
+
/**
|
|
54
|
+
* All edges. For undirected graphs, one edge per node pair is returned in
|
|
55
|
+
* whichever direction was seen first, which also collapses parallel edges —
|
|
56
|
+
* so `mapNodes` and `subgraph` drop undirected parallel edges.
|
|
57
|
+
*/
|
|
27
58
|
edges(): Edge<E>[];
|
|
28
59
|
/** Outgoing neighbors of a node. */
|
|
29
60
|
neighbors(id: NodeId): NodeId[];
|
|
@@ -79,7 +110,7 @@ export declare class Graph<T = unknown, E = unknown> {
|
|
|
79
110
|
findDfs(start: NodeId, predicate: NodePredicate<T>): GraphNode<T> | undefined;
|
|
80
111
|
/**
|
|
81
112
|
* Topological sort (Kahn's algorithm). Returns node ids in topological order.
|
|
82
|
-
* Throws if the graph has a cycle.
|
|
113
|
+
* Throws if the graph is undirected or has a cycle.
|
|
83
114
|
*/
|
|
84
115
|
topologicalSort(): NodeId[];
|
|
85
116
|
/** Detect whether the graph contains a cycle. */
|
|
@@ -87,7 +118,9 @@ export declare class Graph<T = unknown, E = unknown> {
|
|
|
87
118
|
/**
|
|
88
119
|
* Dijkstra's shortest path from `start` to `end`.
|
|
89
120
|
* Returns `{ distance, path }` or `undefined` if unreachable.
|
|
90
|
-
* Edges must have non-negative weights.
|
|
121
|
+
* Edges must have non-negative weights. `end` must be a registered node;
|
|
122
|
+
* otherwise the result is a one-element path with an undefined distance
|
|
123
|
+
* rather than `undefined`.
|
|
91
124
|
*/
|
|
92
125
|
dijkstra(start: NodeId, end: NodeId): {
|
|
93
126
|
distance: number;
|
package/dist/graph.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Generic graph with adjacency-list representation.
|
|
3
3
|
* Supports directed and undirected graphs, weighted edges, and common traversals.
|
|
4
|
+
* Undirected edges are stored as a pair of mirrored directed edges, so
|
|
5
|
+
* per-node edge lists contain both directions.
|
|
4
6
|
*
|
|
5
7
|
* @typeParam T - Node data type
|
|
6
8
|
* @typeParam E - Edge data type
|
|
@@ -10,10 +12,12 @@ export class Graph {
|
|
|
10
12
|
nodes = new Map();
|
|
11
13
|
adjOut = new Map(); // outgoing edges
|
|
12
14
|
adjIn = new Map(); // incoming edges (directed only, for convenience)
|
|
15
|
+
/** Graphs are directed unless `opts.directed` is explicitly `false`. */
|
|
13
16
|
constructor(opts = {}) {
|
|
14
17
|
this.directed = opts.directed ?? true;
|
|
15
18
|
}
|
|
16
19
|
// ── Node operations ──────────────────────────────────────────────
|
|
20
|
+
/** Adds or replaces a node's data; existing edges on `id` are kept. Chainable. */
|
|
17
21
|
addNode(id, data) {
|
|
18
22
|
this.nodes.set(id, { id, data });
|
|
19
23
|
if (!this.adjOut.has(id))
|
|
@@ -28,6 +32,11 @@ export class Graph {
|
|
|
28
32
|
hasNode(id) {
|
|
29
33
|
return this.nodes.has(id);
|
|
30
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* Deletes a node and its edges; returns false if `id` was not a registered node.
|
|
37
|
+
* Only the first edge between `id` and each other node is removed from that
|
|
38
|
+
* node's lists, so parallel edges leave dangling entries behind.
|
|
39
|
+
*/
|
|
31
40
|
removeNode(id) {
|
|
32
41
|
if (!this.nodes.has(id))
|
|
33
42
|
return false;
|
|
@@ -57,6 +66,12 @@ export class Graph {
|
|
|
57
66
|
return [...this.nodes.values()];
|
|
58
67
|
}
|
|
59
68
|
// ── Edge operations ──────────────────────────────────────────────
|
|
69
|
+
/**
|
|
70
|
+
* Appends an edge (weight defaults to 1); parallel edges are allowed. Endpoints
|
|
71
|
+
* not added via `addNode` get adjacency lists but are not registered nodes:
|
|
72
|
+
* they are absent from `nodeIds`/`getNode` and skipped by traversal visitors
|
|
73
|
+
* and `dijkstra`. Chainable.
|
|
74
|
+
*/
|
|
60
75
|
addEdge(from, to, weight = 1, data) {
|
|
61
76
|
this.ensureNode(from);
|
|
62
77
|
this.ensureNode(to);
|
|
@@ -70,12 +85,17 @@ export class Graph {
|
|
|
70
85
|
}
|
|
71
86
|
return this;
|
|
72
87
|
}
|
|
88
|
+
/** First stored edge from `from` to `to`; with parallel edges the others are not returned. */
|
|
73
89
|
getEdge(from, to) {
|
|
74
90
|
return this.adjOut.get(from)?.find((e) => e.to === to);
|
|
75
91
|
}
|
|
76
92
|
hasEdge(from, to) {
|
|
77
93
|
return this.getEdge(from, to) !== undefined;
|
|
78
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* Removes one `from`→`to` edge (and its mirror when undirected); returns false
|
|
97
|
+
* if none exists. Parallel edges must be removed one call at a time.
|
|
98
|
+
*/
|
|
79
99
|
removeEdge(from, to) {
|
|
80
100
|
const out = this.adjOut.get(from);
|
|
81
101
|
if (!out)
|
|
@@ -106,18 +126,24 @@ export class Graph {
|
|
|
106
126
|
}
|
|
107
127
|
return true;
|
|
108
128
|
}
|
|
129
|
+
/** Number of edges; undirected edges count once despite being stored twice. */
|
|
109
130
|
get edgeCount() {
|
|
110
131
|
let count = 0;
|
|
111
132
|
for (const [, edges] of this.adjOut)
|
|
112
133
|
count += edges.length;
|
|
113
134
|
return this.directed ? count : count / 2;
|
|
114
135
|
}
|
|
136
|
+
/**
|
|
137
|
+
* All edges. For undirected graphs, one edge per node pair is returned in
|
|
138
|
+
* whichever direction was seen first, which also collapses parallel edges —
|
|
139
|
+
* so `mapNodes` and `subgraph` drop undirected parallel edges.
|
|
140
|
+
*/
|
|
115
141
|
edges() {
|
|
116
142
|
const all = [];
|
|
117
143
|
for (const [, edges] of this.adjOut)
|
|
118
144
|
all.push(...edges);
|
|
119
145
|
if (!this.directed) {
|
|
120
|
-
// Deduplicate: keep
|
|
146
|
+
// Deduplicate: keep the first-seen direction of each node pair
|
|
121
147
|
const seen = new Set();
|
|
122
148
|
return all.filter((e) => {
|
|
123
149
|
const key = `${e.from}->${e.to}`;
|
|
@@ -314,7 +340,7 @@ export class Graph {
|
|
|
314
340
|
// ── Algorithms ───────────────────────────────────────────────────
|
|
315
341
|
/**
|
|
316
342
|
* Topological sort (Kahn's algorithm). Returns node ids in topological order.
|
|
317
|
-
* Throws if the graph has a cycle.
|
|
343
|
+
* Throws if the graph is undirected or has a cycle.
|
|
318
344
|
*/
|
|
319
345
|
topologicalSort() {
|
|
320
346
|
if (!this.directed)
|
|
@@ -394,7 +420,9 @@ export class Graph {
|
|
|
394
420
|
/**
|
|
395
421
|
* Dijkstra's shortest path from `start` to `end`.
|
|
396
422
|
* Returns `{ distance, path }` or `undefined` if unreachable.
|
|
397
|
-
* Edges must have non-negative weights.
|
|
423
|
+
* Edges must have non-negative weights. `end` must be a registered node;
|
|
424
|
+
* otherwise the result is a one-element path with an undefined distance
|
|
425
|
+
* rather than `undefined`.
|
|
398
426
|
*/
|
|
399
427
|
dijkstra(start, end) {
|
|
400
428
|
const dist = new Map();
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public entry point for the graph package: re-exports the `Graph` class and
|
|
3
|
+
* its supporting types, so consumers never import from internal module paths.
|
|
4
|
+
* The types are exported with `export type`, so they disappear at compile time
|
|
5
|
+
* and only `Graph` remains as a runtime export.
|
|
6
|
+
*/
|
|
1
7
|
export { Graph } from "./graph.js";
|
|
2
8
|
export type { NodeId, GraphNode, Edge, GraphOptions, Visitor, NodePredicate, } from "./types.js";
|
package/dist/index.js
CHANGED
|
@@ -1 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public entry point for the graph package: re-exports the `Graph` class and
|
|
3
|
+
* its supporting types, so consumers never import from internal module paths.
|
|
4
|
+
* The types are exported with `export type`, so they disappear at compile time
|
|
5
|
+
* and only `Graph` remains as a runtime export.
|
|
6
|
+
*/
|
|
1
7
|
export { Graph } from "./graph.js";
|