@parcel/graph 2.0.2-nightly.2534 → 2.0.2-nightly.2548
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/lib/AdjacencyList.js +1165 -0
- package/lib/ContentGraph.js +1 -0
- package/lib/Graph.js +40 -213
- package/lib/index.js +3 -13
- package/package.json +2 -2
- package/src/AdjacencyList.js +1211 -0
- package/src/ContentGraph.js +9 -4
- package/src/Graph.js +77 -197
- package/src/index.js +4 -2
- package/test/AdjacencyList.test.js +280 -0
- package/test/Graph.test.js +9 -6
- package/test/integration/adjacency-list-shared-array.js +20 -0
package/src/ContentGraph.js
CHANGED
@@ -1,14 +1,18 @@
|
|
1
1
|
// @flow strict-local
|
2
2
|
import type {ContentKey, NodeId} from './types';
|
3
3
|
|
4
|
-
import Graph, {type GraphOpts} from './Graph';
|
4
|
+
import Graph, {type SerializedGraph, type GraphOpts} from './Graph';
|
5
5
|
import nullthrows from 'nullthrows';
|
6
6
|
|
7
|
-
export type
|
7
|
+
export type ContentGraphOpts<TNode, TEdgeType: number = 1> = {|
|
8
8
|
...GraphOpts<TNode, TEdgeType>,
|
9
9
|
_contentKeyToNodeId: Map<ContentKey, NodeId>,
|
10
10
|
_nodeIdToContentKey: Map<NodeId, ContentKey>,
|
11
11
|
|};
|
12
|
+
export type SerializedContentGraph<TNode, TEdgeType: number = 1> = {|
|
13
|
+
...SerializedGraph<TNode, TEdgeType>,
|
14
|
+
_contentKeyToNodeId: Map<ContentKey, NodeId>,
|
15
|
+
|};
|
12
16
|
|
13
17
|
export default class ContentGraph<TNode, TEdgeType: number = 1> extends Graph<
|
14
18
|
TNode,
|
@@ -17,7 +21,7 @@ export default class ContentGraph<TNode, TEdgeType: number = 1> extends Graph<
|
|
17
21
|
_contentKeyToNodeId: Map<ContentKey, NodeId>;
|
18
22
|
_nodeIdToContentKey: Map<NodeId, ContentKey>;
|
19
23
|
|
20
|
-
constructor(opts: ?
|
24
|
+
constructor(opts: ?ContentGraphOpts<TNode, TEdgeType>) {
|
21
25
|
if (opts) {
|
22
26
|
let {_contentKeyToNodeId, _nodeIdToContentKey, ...rest} = opts;
|
23
27
|
super(rest);
|
@@ -32,13 +36,14 @@ export default class ContentGraph<TNode, TEdgeType: number = 1> extends Graph<
|
|
32
36
|
|
33
37
|
// $FlowFixMe[prop-missing]
|
34
38
|
static deserialize(
|
35
|
-
opts:
|
39
|
+
opts: ContentGraphOpts<TNode, TEdgeType>,
|
36
40
|
): ContentGraph<TNode, TEdgeType> {
|
37
41
|
return new ContentGraph(opts);
|
38
42
|
}
|
39
43
|
|
40
44
|
// $FlowFixMe[prop-missing]
|
41
45
|
serialize(): SerializedContentGraph<TNode, TEdgeType> {
|
46
|
+
// $FlowFixMe[prop-missing]
|
42
47
|
return {
|
43
48
|
...super.serialize(),
|
44
49
|
_contentKeyToNodeId: this._contentKeyToNodeId,
|
package/src/Graph.js
CHANGED
@@ -1,49 +1,42 @@
|
|
1
1
|
// @flow strict-local
|
2
2
|
|
3
|
-
import {
|
3
|
+
import {fromNodeId} from './types';
|
4
|
+
import AdjacencyList, {type SerializedAdjacencyList} from './AdjacencyList';
|
4
5
|
import type {Edge, NodeId} from './types';
|
5
6
|
import type {TraversalActions, GraphVisitor} from '@parcel/types';
|
6
7
|
|
7
8
|
import assert from 'assert';
|
8
9
|
import nullthrows from 'nullthrows';
|
9
10
|
|
10
|
-
type NullEdgeType = 1;
|
11
|
+
export type NullEdgeType = 1;
|
11
12
|
export type GraphOpts<TNode, TEdgeType: number = 1> = {|
|
12
13
|
nodes?: Map<NodeId, TNode>,
|
13
|
-
|
14
|
+
adjacencyList?: SerializedAdjacencyList<TEdgeType>,
|
14
15
|
rootNodeId?: ?NodeId,
|
15
|
-
nextNodeId?: ?number,
|
16
16
|
|};
|
17
17
|
|
18
|
-
export
|
18
|
+
export type SerializedGraph<TNode, TEdgeType: number = 1> = {|
|
19
|
+
nodes: Map<NodeId, TNode>,
|
20
|
+
adjacencyList: SerializedAdjacencyList<TEdgeType>,
|
21
|
+
rootNodeId: ?NodeId,
|
22
|
+
|};
|
23
|
+
|
24
|
+
export type AllEdgeTypes = -1;
|
25
|
+
export const ALL_EDGE_TYPES: AllEdgeTypes = -1;
|
19
26
|
|
20
27
|
export default class Graph<TNode, TEdgeType: number = 1> {
|
21
28
|
nodes: Map<NodeId, TNode>;
|
22
|
-
|
23
|
-
outboundEdges: AdjacencyList<TEdgeType | NullEdgeType>;
|
29
|
+
adjacencyList: AdjacencyList<TEdgeType>;
|
24
30
|
rootNodeId: ?NodeId;
|
25
|
-
nextNodeId: number = 1;
|
26
31
|
|
27
32
|
constructor(opts: ?GraphOpts<TNode, TEdgeType>) {
|
28
33
|
this.nodes = opts?.nodes || new Map();
|
29
34
|
this.setRootNodeId(opts?.rootNodeId);
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
this.outboundEdges = new AdjacencyList(edges);
|
36
|
-
for (let [from, edgeList] of edges) {
|
37
|
-
for (let [type, toNodes] of edgeList) {
|
38
|
-
for (let to of toNodes) {
|
39
|
-
this.inboundEdges.addEdge(to, from, type);
|
40
|
-
}
|
41
|
-
}
|
42
|
-
}
|
43
|
-
} else {
|
44
|
-
this.inboundEdges = new AdjacencyList();
|
45
|
-
this.outboundEdges = new AdjacencyList();
|
46
|
-
}
|
35
|
+
|
36
|
+
let adjacencyList = opts?.adjacencyList;
|
37
|
+
this.adjacencyList = adjacencyList
|
38
|
+
? AdjacencyList.deserialize(adjacencyList)
|
39
|
+
: new AdjacencyList<TEdgeType>();
|
47
40
|
}
|
48
41
|
|
49
42
|
setRootNodeId(id: ?NodeId) {
|
@@ -55,37 +48,27 @@ export default class Graph<TNode, TEdgeType: number = 1> {
|
|
55
48
|
): Graph<TNode, TEdgeType> {
|
56
49
|
return new this({
|
57
50
|
nodes: opts.nodes,
|
58
|
-
|
51
|
+
adjacencyList: opts.adjacencyList,
|
59
52
|
rootNodeId: opts.rootNodeId,
|
60
|
-
nextNodeId: opts.nextNodeId,
|
61
53
|
});
|
62
54
|
}
|
63
55
|
|
64
|
-
serialize():
|
56
|
+
serialize(): SerializedGraph<TNode, TEdgeType> {
|
65
57
|
return {
|
66
58
|
nodes: this.nodes,
|
67
|
-
|
59
|
+
adjacencyList: this.adjacencyList.serialize(),
|
68
60
|
rootNodeId: this.rootNodeId,
|
69
|
-
nextNodeId: this.nextNodeId,
|
70
61
|
};
|
71
62
|
}
|
72
63
|
|
73
|
-
// Returns
|
64
|
+
// Returns an iterator of all edges in the graph. This can be large, so iterating
|
74
65
|
// the complete list can be costly in large graphs. Used when merging graphs.
|
75
|
-
getAllEdges():
|
76
|
-
|
77
|
-
for (let [from, edgeList] of this.outboundEdges.getListMap()) {
|
78
|
-
for (let [type, toNodes] of edgeList) {
|
79
|
-
for (let to of toNodes) {
|
80
|
-
edges.push({from, to, type});
|
81
|
-
}
|
82
|
-
}
|
83
|
-
}
|
84
|
-
return edges;
|
66
|
+
getAllEdges(): Iterator<Edge<TEdgeType | NullEdgeType>> {
|
67
|
+
return this.adjacencyList.getAllEdges();
|
85
68
|
}
|
86
69
|
|
87
70
|
addNode(node: TNode): NodeId {
|
88
|
-
let id =
|
71
|
+
let id = this.adjacencyList.addNode();
|
89
72
|
this.nodes.set(id, node);
|
90
73
|
return id;
|
91
74
|
}
|
@@ -98,7 +81,15 @@ export default class Graph<TNode, TEdgeType: number = 1> {
|
|
98
81
|
return this.nodes.get(id);
|
99
82
|
}
|
100
83
|
|
101
|
-
addEdge(
|
84
|
+
addEdge(
|
85
|
+
from: NodeId,
|
86
|
+
to: NodeId,
|
87
|
+
type: TEdgeType | NullEdgeType = 1,
|
88
|
+
): boolean {
|
89
|
+
if (Number(type) === 0) {
|
90
|
+
throw new Error(`Edge type "${type}" not allowed`);
|
91
|
+
}
|
92
|
+
|
102
93
|
if (!this.getNode(from)) {
|
103
94
|
throw new Error(`"from" node '${fromNodeId(from)}' not found`);
|
104
95
|
}
|
@@ -107,8 +98,7 @@ export default class Graph<TNode, TEdgeType: number = 1> {
|
|
107
98
|
throw new Error(`"to" node '${fromNodeId(to)}' not found`);
|
108
99
|
}
|
109
100
|
|
110
|
-
this.
|
111
|
-
this.inboundEdges.addEdge(to, from, type);
|
101
|
+
return this.adjacencyList.addEdge(from, to, type);
|
112
102
|
}
|
113
103
|
|
114
104
|
hasEdge(
|
@@ -116,95 +106,52 @@ export default class Graph<TNode, TEdgeType: number = 1> {
|
|
116
106
|
to: NodeId,
|
117
107
|
type?: TEdgeType | NullEdgeType = 1,
|
118
108
|
): boolean {
|
119
|
-
return this.
|
109
|
+
return this.adjacencyList.hasEdge(from, to, type);
|
120
110
|
}
|
121
111
|
|
122
112
|
getNodeIdsConnectedTo(
|
123
113
|
nodeId: NodeId,
|
124
|
-
type:
|
114
|
+
type:
|
115
|
+
| TEdgeType
|
116
|
+
| NullEdgeType
|
117
|
+
| Array<TEdgeType | NullEdgeType>
|
118
|
+
| AllEdgeTypes = 1,
|
125
119
|
): Array<NodeId> {
|
126
120
|
this._assertHasNodeId(nodeId);
|
127
121
|
|
128
|
-
|
129
|
-
if (inboundByType == null) {
|
130
|
-
return [];
|
131
|
-
}
|
132
|
-
|
133
|
-
let nodes;
|
134
|
-
if (type === ALL_EDGE_TYPES) {
|
135
|
-
nodes = new Set();
|
136
|
-
for (let [, typeNodes] of inboundByType) {
|
137
|
-
for (let node of typeNodes) {
|
138
|
-
nodes.add(node);
|
139
|
-
}
|
140
|
-
}
|
141
|
-
} else if (Array.isArray(type)) {
|
142
|
-
nodes = new Set();
|
143
|
-
for (let typeName of type) {
|
144
|
-
for (let node of inboundByType.get(typeName)?.values() ?? []) {
|
145
|
-
nodes.add(node);
|
146
|
-
}
|
147
|
-
}
|
148
|
-
} else {
|
149
|
-
nodes = new Set(inboundByType.get(type)?.values() ?? []);
|
150
|
-
}
|
151
|
-
|
152
|
-
return [...nodes];
|
122
|
+
return this.adjacencyList.getNodeIdsConnectedTo(nodeId, type);
|
153
123
|
}
|
154
124
|
|
155
125
|
getNodeIdsConnectedFrom(
|
156
126
|
nodeId: NodeId,
|
157
|
-
type:
|
127
|
+
type:
|
128
|
+
| TEdgeType
|
129
|
+
| NullEdgeType
|
130
|
+
| Array<TEdgeType | NullEdgeType>
|
131
|
+
| AllEdgeTypes = 1,
|
158
132
|
): Array<NodeId> {
|
159
133
|
this._assertHasNodeId(nodeId);
|
160
|
-
let outboundByType = this.outboundEdges.getEdgesByType(nodeId);
|
161
|
-
if (outboundByType == null) {
|
162
|
-
return [];
|
163
|
-
}
|
164
134
|
|
165
|
-
|
166
|
-
if (type === ALL_EDGE_TYPES) {
|
167
|
-
nodes = new Set();
|
168
|
-
for (let [, typeNodes] of outboundByType) {
|
169
|
-
for (let node of typeNodes) {
|
170
|
-
nodes.add(node);
|
171
|
-
}
|
172
|
-
}
|
173
|
-
} else if (Array.isArray(type)) {
|
174
|
-
nodes = new Set();
|
175
|
-
for (let typeName of type) {
|
176
|
-
for (let node of outboundByType.get(typeName)?.values() ?? []) {
|
177
|
-
nodes.add(node);
|
178
|
-
}
|
179
|
-
}
|
180
|
-
} else {
|
181
|
-
nodes = new Set(outboundByType.get(type)?.values() ?? []);
|
182
|
-
}
|
183
|
-
|
184
|
-
return [...nodes];
|
135
|
+
return this.adjacencyList.getNodeIdsConnectedFrom(nodeId, type);
|
185
136
|
}
|
186
137
|
|
187
138
|
// Removes node and any edges coming from or to that node
|
188
139
|
removeNode(nodeId: NodeId) {
|
189
140
|
this._assertHasNodeId(nodeId);
|
190
141
|
|
191
|
-
for (let
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
);
|
201
|
-
}
|
142
|
+
for (let {type, from} of this.adjacencyList.getInboundEdgesByType(nodeId)) {
|
143
|
+
this.removeEdge(
|
144
|
+
from,
|
145
|
+
nodeId,
|
146
|
+
type,
|
147
|
+
// Do not allow orphans to be removed as this node could be one
|
148
|
+
// and is already being removed.
|
149
|
+
false,
|
150
|
+
);
|
202
151
|
}
|
203
152
|
|
204
|
-
for (let
|
205
|
-
|
206
|
-
this.removeEdge(nodeId, to, type);
|
207
|
-
}
|
153
|
+
for (let {type, to} of this.adjacencyList.getOutboundEdgesByType(nodeId)) {
|
154
|
+
this.removeEdge(nodeId, to, type);
|
208
155
|
}
|
209
156
|
|
210
157
|
let wasRemoved = this.nodes.delete(nodeId);
|
@@ -214,7 +161,7 @@ export default class Graph<TNode, TEdgeType: number = 1> {
|
|
214
161
|
removeEdges(nodeId: NodeId, type: TEdgeType | NullEdgeType = 1) {
|
215
162
|
this._assertHasNodeId(nodeId);
|
216
163
|
|
217
|
-
for (let to of this.
|
164
|
+
for (let to of this.getNodeIdsConnectedFrom(nodeId, type)) {
|
218
165
|
this.removeEdge(nodeId, to, type);
|
219
166
|
}
|
220
167
|
}
|
@@ -226,23 +173,13 @@ export default class Graph<TNode, TEdgeType: number = 1> {
|
|
226
173
|
type: TEdgeType | NullEdgeType = 1,
|
227
174
|
removeOrphans: boolean = true,
|
228
175
|
) {
|
229
|
-
if (!this.
|
176
|
+
if (!this.adjacencyList.hasEdge(from, to, type)) {
|
230
177
|
throw new Error(
|
231
|
-
`
|
232
|
-
to,
|
233
|
-
)} not found!`,
|
178
|
+
`Edge from ${fromNodeId(from)} to ${fromNodeId(to)} not found!`,
|
234
179
|
);
|
235
180
|
}
|
236
181
|
|
237
|
-
|
238
|
-
throw new Error(
|
239
|
-
`Inbound edge from ${fromNodeId(to)} to ${fromNodeId(from)} not found!`,
|
240
|
-
);
|
241
|
-
}
|
242
|
-
|
243
|
-
this.outboundEdges.removeEdge(from, to, type);
|
244
|
-
this.inboundEdges.removeEdge(to, from, type);
|
245
|
-
|
182
|
+
this.adjacencyList.removeEdge(from, to, type);
|
246
183
|
if (removeOrphans && this.isOrphanedNode(to)) {
|
247
184
|
this.removeNode(to);
|
248
185
|
}
|
@@ -254,14 +191,7 @@ export default class Graph<TNode, TEdgeType: number = 1> {
|
|
254
191
|
if (this.rootNodeId == null) {
|
255
192
|
// If the graph does not have a root, and there are inbound edges,
|
256
193
|
// this node should not be considered orphaned.
|
257
|
-
|
258
|
-
for (let [, inboundNodeIds] of this.inboundEdges.getEdgesByType(nodeId)) {
|
259
|
-
if (inboundNodeIds.size > 0) {
|
260
|
-
return false;
|
261
|
-
}
|
262
|
-
}
|
263
|
-
|
264
|
-
return true;
|
194
|
+
return !this.adjacencyList.hasInboundEdges(nodeId);
|
265
195
|
}
|
266
196
|
|
267
197
|
// Otherwise, attempt to traverse backwards to the root. If there is a path,
|
@@ -276,7 +206,6 @@ export default class Graph<TNode, TEdgeType: number = 1> {
|
|
276
206
|
actions.stop();
|
277
207
|
}
|
278
208
|
},
|
279
|
-
// $FlowFixMe
|
280
209
|
ALL_EDGE_TYPES,
|
281
210
|
);
|
282
211
|
|
@@ -292,19 +221,6 @@ export default class Graph<TNode, TEdgeType: number = 1> {
|
|
292
221
|
this.nodes.set(nodeId, node);
|
293
222
|
}
|
294
223
|
|
295
|
-
replaceNode(
|
296
|
-
fromNodeId: NodeId,
|
297
|
-
toNodeId: NodeId,
|
298
|
-
type: TEdgeType | NullEdgeType = 1,
|
299
|
-
): void {
|
300
|
-
this._assertHasNodeId(fromNodeId);
|
301
|
-
for (let parent of this.inboundEdges.getEdges(fromNodeId, type)) {
|
302
|
-
this.addEdge(parent, toNodeId, type);
|
303
|
-
this.removeEdge(parent, fromNodeId, type);
|
304
|
-
}
|
305
|
-
this.removeNode(fromNodeId);
|
306
|
-
}
|
307
|
-
|
308
224
|
// Update a node's downstream nodes making sure to prune any orphaned branches
|
309
225
|
replaceNodeIdsConnectedTo(
|
310
226
|
fromNodeId: NodeId,
|
@@ -314,10 +230,10 @@ export default class Graph<TNode, TEdgeType: number = 1> {
|
|
314
230
|
): void {
|
315
231
|
this._assertHasNodeId(fromNodeId);
|
316
232
|
|
317
|
-
let outboundEdges = this.
|
233
|
+
let outboundEdges = this.getNodeIdsConnectedFrom(fromNodeId, type);
|
318
234
|
let childrenToRemove = new Set(
|
319
235
|
replaceFilter
|
320
|
-
?
|
236
|
+
? outboundEdges.filter(toNodeId => replaceFilter(toNodeId))
|
321
237
|
: outboundEdges,
|
322
238
|
);
|
323
239
|
for (let toNodeId of toNodeIds) {
|
@@ -336,7 +252,11 @@ export default class Graph<TNode, TEdgeType: number = 1> {
|
|
336
252
|
traverse<TContext>(
|
337
253
|
visit: GraphVisitor<NodeId, TContext>,
|
338
254
|
startNodeId: ?NodeId,
|
339
|
-
type:
|
255
|
+
type:
|
256
|
+
| TEdgeType
|
257
|
+
| NullEdgeType
|
258
|
+
| Array<TEdgeType | NullEdgeType>
|
259
|
+
| AllEdgeTypes = 1,
|
340
260
|
): ?TContext {
|
341
261
|
return this.dfs({
|
342
262
|
visit,
|
@@ -349,7 +269,7 @@ export default class Graph<TNode, TEdgeType: number = 1> {
|
|
349
269
|
filter: (NodeId, TraversalActions) => ?TValue,
|
350
270
|
visit: GraphVisitor<TValue, TContext>,
|
351
271
|
startNodeId: ?NodeId,
|
352
|
-
type?: TEdgeType | Array<TEdgeType | NullEdgeType
|
272
|
+
type?: TEdgeType | Array<TEdgeType | NullEdgeType> | AllEdgeTypes,
|
353
273
|
): ?TContext {
|
354
274
|
return this.traverse(mapVisitor(filter, visit), startNodeId, type);
|
355
275
|
}
|
@@ -357,7 +277,11 @@ export default class Graph<TNode, TEdgeType: number = 1> {
|
|
357
277
|
traverseAncestors<TContext>(
|
358
278
|
startNodeId: ?NodeId,
|
359
279
|
visit: GraphVisitor<NodeId, TContext>,
|
360
|
-
type:
|
280
|
+
type:
|
281
|
+
| TEdgeType
|
282
|
+
| NullEdgeType
|
283
|
+
| Array<TEdgeType | NullEdgeType>
|
284
|
+
| AllEdgeTypes = 1,
|
361
285
|
): ?TContext {
|
362
286
|
return this.dfs({
|
363
287
|
visit,
|
@@ -574,47 +498,3 @@ export function mapVisitor<NodeId, TValue, TContext>(
|
|
574
498
|
|
575
499
|
return mapped;
|
576
500
|
}
|
577
|
-
|
578
|
-
type AdjacencyListMap<TEdgeType> = Map<NodeId, Map<TEdgeType, Set<NodeId>>>;
|
579
|
-
class AdjacencyList<TEdgeType> {
|
580
|
-
_listMap: AdjacencyListMap<TEdgeType>;
|
581
|
-
|
582
|
-
constructor(listMap?: AdjacencyListMap<TEdgeType>) {
|
583
|
-
this._listMap = listMap ?? new Map();
|
584
|
-
}
|
585
|
-
|
586
|
-
getListMap(): AdjacencyListMap<TEdgeType> {
|
587
|
-
return this._listMap;
|
588
|
-
}
|
589
|
-
|
590
|
-
getEdges(from: NodeId, type: TEdgeType): $ReadOnlySet<NodeId> {
|
591
|
-
return this._listMap.get(from)?.get(type) ?? new Set();
|
592
|
-
}
|
593
|
-
|
594
|
-
getEdgesByType(from: NodeId): $ReadOnlyMap<TEdgeType, $ReadOnlySet<NodeId>> {
|
595
|
-
return this._listMap.get(from) ?? new Map();
|
596
|
-
}
|
597
|
-
|
598
|
-
hasEdge(from: NodeId, to: NodeId, type: TEdgeType): boolean {
|
599
|
-
return Boolean(this._listMap.get(from)?.get(type)?.has(to));
|
600
|
-
}
|
601
|
-
|
602
|
-
addEdge(from: NodeId, to: NodeId, type: TEdgeType): void {
|
603
|
-
let types = this._listMap.get(from);
|
604
|
-
if (types == null) {
|
605
|
-
types = new Map<TEdgeType, Set<NodeId>>();
|
606
|
-
this._listMap.set(from, types);
|
607
|
-
}
|
608
|
-
|
609
|
-
let adjacent = types.get(type);
|
610
|
-
if (adjacent == null) {
|
611
|
-
adjacent = new Set<NodeId>();
|
612
|
-
types.set(type, adjacent);
|
613
|
-
}
|
614
|
-
adjacent.add(to);
|
615
|
-
}
|
616
|
-
|
617
|
-
removeEdge(from: NodeId, to: NodeId, type: TEdgeType): void {
|
618
|
-
this._listMap.get(from)?.get(type)?.delete(to);
|
619
|
-
}
|
620
|
-
}
|
package/src/index.js
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
// @flow strict-local
|
2
2
|
|
3
3
|
export type {NodeId, ContentKey, Edge} from './types';
|
4
|
+
export type {GraphOpts} from './Graph';
|
5
|
+
export type {ContentGraphOpts, SerializedContentGraph} from './ContentGraph';
|
4
6
|
export {toNodeId, fromNodeId} from './types';
|
5
|
-
export {default as Graph, ALL_EDGE_TYPES,
|
6
|
-
export {default as ContentGraph
|
7
|
+
export {default as Graph, ALL_EDGE_TYPES, mapVisitor} from './Graph';
|
8
|
+
export {default as ContentGraph} from './ContentGraph';
|