@dxos/graph 0.8.4-main.f9ba587 → 0.8.4-main.fcc0d83b33
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/dist/lib/browser/index.mjs +301 -213
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +301 -214
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/Graph.d.ts +64 -0
- package/dist/types/src/Graph.d.ts.map +1 -0
- package/dist/types/src/GraphModel.d.ts +135 -0
- package/dist/types/src/GraphModel.d.ts.map +1 -0
- package/dist/types/src/GraphModel.test.d.ts +2 -0
- package/dist/types/src/GraphModel.test.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +2 -3
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/selection.d.ts +24 -6
- package/dist/types/src/selection.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +18 -24
- package/src/Graph.ts +83 -0
- package/src/GraphModel.test.ts +265 -0
- package/src/GraphModel.ts +454 -0
- package/src/index.ts +3 -3
- package/src/selection.ts +62 -22
- package/dist/types/src/model.d.ts +0 -105
- package/dist/types/src/model.d.ts.map +0 -1
- package/dist/types/src/model.test.d.ts +0 -2
- package/dist/types/src/model.test.d.ts.map +0 -1
- package/dist/types/src/types.d.ts +0 -58
- package/dist/types/src/types.d.ts.map +0 -1
- package/dist/types/src/util.d.ts +0 -9
- package/dist/types/src/util.d.ts.map +0 -1
- package/src/model.test.ts +0 -188
- package/src/model.ts +0 -317
- package/src/types.ts +0 -72
- package/src/util.ts +0 -22
|
@@ -1,33 +1,131 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import { isNotFalsy, removeBy } from "@dxos/util";
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __export = (target, all) => {
|
|
3
|
+
for (var name in all)
|
|
4
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
5
|
+
};
|
|
7
6
|
|
|
8
|
-
// src/
|
|
7
|
+
// src/selection.ts
|
|
8
|
+
import { Atom, Registry } from "@effect-atom/atom-react";
|
|
9
9
|
import { invariant } from "@dxos/invariant";
|
|
10
|
-
var __dxlog_file = "/__w/dxos/dxos/packages/common/graph/src/
|
|
10
|
+
var __dxlog_file = "/__w/dxos/dxos/packages/common/graph/src/selection.ts";
|
|
11
|
+
var SelectionModel = class {
|
|
12
|
+
_singleSelect;
|
|
13
|
+
_registry;
|
|
14
|
+
_selected;
|
|
15
|
+
constructor(_singleSelect = false) {
|
|
16
|
+
this._singleSelect = _singleSelect;
|
|
17
|
+
this._registry = Registry.make();
|
|
18
|
+
this._selected = Atom.make(/* @__PURE__ */ new Set());
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Returns the selected IDs atom for subscription.
|
|
22
|
+
*/
|
|
23
|
+
get selected() {
|
|
24
|
+
return this._selected;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Gets the current selected IDs as a Set.
|
|
28
|
+
*/
|
|
29
|
+
getSelected() {
|
|
30
|
+
return this._registry.get(this._selected);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Gets the current selected IDs as an array.
|
|
34
|
+
*/
|
|
35
|
+
getSelectedIds() {
|
|
36
|
+
return Array.from(this._registry.get(this._selected).values());
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Subscribe to selection changes.
|
|
40
|
+
*/
|
|
41
|
+
subscribe(cb) {
|
|
42
|
+
this._registry.get(this._selected);
|
|
43
|
+
return this._registry.subscribe(this._selected, () => {
|
|
44
|
+
cb(this._registry.get(this._selected));
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
toJSON() {
|
|
48
|
+
return {
|
|
49
|
+
selected: this.getSelectedIds()
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Gets the current selection size.
|
|
54
|
+
*/
|
|
55
|
+
getSize() {
|
|
56
|
+
return this._registry.get(this._selected).size;
|
|
57
|
+
}
|
|
58
|
+
contains(id) {
|
|
59
|
+
return this._registry.get(this._selected).has(id);
|
|
60
|
+
}
|
|
61
|
+
clear() {
|
|
62
|
+
this._registry.set(this._selected, /* @__PURE__ */ new Set());
|
|
63
|
+
}
|
|
64
|
+
add(id) {
|
|
65
|
+
invariant(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 58, S: this, A: ["id", ""] });
|
|
66
|
+
const current = this._registry.get(this._selected);
|
|
67
|
+
this._registry.set(this._selected, new Set(this._singleSelect ? [
|
|
68
|
+
id
|
|
69
|
+
] : [
|
|
70
|
+
...Array.from(current.values()),
|
|
71
|
+
id
|
|
72
|
+
]));
|
|
73
|
+
}
|
|
74
|
+
remove(id) {
|
|
75
|
+
invariant(id, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 68, S: this, A: ["id", ""] });
|
|
76
|
+
const current = this._registry.get(this._selected);
|
|
77
|
+
this._registry.set(this._selected, new Set(Array.from(current.values()).filter((_id) => _id !== id)));
|
|
78
|
+
}
|
|
79
|
+
// TODO(burdon): Handle single select.
|
|
80
|
+
setSelected(ids, subtract = false) {
|
|
81
|
+
const current = this._registry.get(this._selected);
|
|
82
|
+
this._registry.set(this._selected, /* @__PURE__ */ new Set([
|
|
83
|
+
...subtract ? Array.from(current.values()) : [],
|
|
84
|
+
...ids
|
|
85
|
+
]));
|
|
86
|
+
}
|
|
87
|
+
toggleSelected(ids, subtract = false) {
|
|
88
|
+
const current = this._registry.get(this._selected);
|
|
89
|
+
const set = new Set(subtract ? Array.from(current.values()) : void 0);
|
|
90
|
+
ids.forEach((id) => {
|
|
91
|
+
if (current.has(id)) {
|
|
92
|
+
set.delete(id);
|
|
93
|
+
} else {
|
|
94
|
+
set.add(id);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
this._registry.set(this._selected, set);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
// src/Graph.ts
|
|
102
|
+
var Graph_exports = {};
|
|
103
|
+
__export(Graph_exports, {
|
|
104
|
+
Edge: () => Edge,
|
|
105
|
+
Graph: () => Graph,
|
|
106
|
+
Node: () => Node,
|
|
107
|
+
createEdgeId: () => createEdgeId,
|
|
108
|
+
parseEdgeId: () => parseEdgeId
|
|
109
|
+
});
|
|
110
|
+
import * as Schema from "effect/Schema";
|
|
111
|
+
import { invariant as invariant2 } from "@dxos/invariant";
|
|
112
|
+
var __dxlog_file2 = "/__w/dxos/dxos/packages/common/graph/src/Graph.ts";
|
|
113
|
+
var Node = Schema.Struct({
|
|
114
|
+
id: Schema.String,
|
|
115
|
+
type: Schema.optional(Schema.String),
|
|
116
|
+
data: Schema.optional(Schema.Any)
|
|
117
|
+
});
|
|
118
|
+
var Edge = Schema.Struct({
|
|
119
|
+
id: Schema.String,
|
|
120
|
+
type: Schema.optional(Schema.String),
|
|
121
|
+
source: Schema.String,
|
|
122
|
+
target: Schema.String,
|
|
123
|
+
data: Schema.optional(Schema.Any)
|
|
124
|
+
});
|
|
11
125
|
var KEY_REGEX = /\w+/;
|
|
12
126
|
var createEdgeId = ({ source, target, relation }) => {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
L: 13,
|
|
16
|
-
S: void 0,
|
|
17
|
-
A: [
|
|
18
|
-
"source.match(KEY_REGEX)",
|
|
19
|
-
"`invalid source: ${source}`"
|
|
20
|
-
]
|
|
21
|
-
});
|
|
22
|
-
invariant(target.match(KEY_REGEX), `invalid target: ${target}`, {
|
|
23
|
-
F: __dxlog_file,
|
|
24
|
-
L: 14,
|
|
25
|
-
S: void 0,
|
|
26
|
-
A: [
|
|
27
|
-
"target.match(KEY_REGEX)",
|
|
28
|
-
"`invalid target: ${target}`"
|
|
29
|
-
]
|
|
30
|
-
});
|
|
127
|
+
invariant2(source.match(KEY_REGEX), `invalid source: ${source}`, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 27, S: void 0, A: ["source.match(KEY_REGEX)", "`invalid source: ${source}`"] });
|
|
128
|
+
invariant2(target.match(KEY_REGEX), `invalid target: ${target}`, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 28, S: void 0, A: ["target.match(KEY_REGEX)", "`invalid target: ${target}`"] });
|
|
31
129
|
return [
|
|
32
130
|
source,
|
|
33
131
|
relation,
|
|
@@ -36,33 +134,52 @@ var createEdgeId = ({ source, target, relation }) => {
|
|
|
36
134
|
};
|
|
37
135
|
var parseEdgeId = (id) => {
|
|
38
136
|
const [source, relation, target] = id.split("_");
|
|
39
|
-
|
|
40
|
-
F: __dxlog_file,
|
|
41
|
-
L: 20,
|
|
42
|
-
S: void 0,
|
|
43
|
-
A: [
|
|
44
|
-
"source.length && target.length",
|
|
45
|
-
""
|
|
46
|
-
]
|
|
47
|
-
});
|
|
137
|
+
invariant2(source.length && target.length, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 37, S: void 0, A: ["source.length && target.length", ""] });
|
|
48
138
|
return {
|
|
49
139
|
source,
|
|
50
140
|
relation: relation.length ? relation : void 0,
|
|
51
141
|
target
|
|
52
142
|
};
|
|
53
143
|
};
|
|
144
|
+
var Graph = Schema.Struct({
|
|
145
|
+
id: Schema.optional(Schema.String),
|
|
146
|
+
nodes: Schema.mutable(Schema.Array(Node)),
|
|
147
|
+
edges: Schema.mutable(Schema.Array(Edge))
|
|
148
|
+
});
|
|
54
149
|
|
|
55
|
-
// src/
|
|
56
|
-
var
|
|
150
|
+
// src/GraphModel.ts
|
|
151
|
+
var GraphModel_exports = {};
|
|
152
|
+
__export(GraphModel_exports, {
|
|
153
|
+
AbstractBuilder: () => AbstractBuilder,
|
|
154
|
+
AbstractGraphModel: () => AbstractGraphModel,
|
|
155
|
+
Builder: () => Builder,
|
|
156
|
+
GraphModel: () => GraphModel,
|
|
157
|
+
ReactiveGraphModel: () => ReactiveGraphModel,
|
|
158
|
+
ReadonlyGraphModel: () => ReadonlyGraphModel
|
|
159
|
+
});
|
|
160
|
+
import { Atom as Atom2 } from "@effect-atom/atom-react";
|
|
161
|
+
import { inspectCustom } from "@dxos/debug";
|
|
162
|
+
import { failedInvariant, invariant as invariant3 } from "@dxos/invariant";
|
|
163
|
+
import { isTruthy, removeBy } from "@dxos/util";
|
|
164
|
+
var __dxlog_file3 = "/__w/dxos/dxos/packages/common/graph/src/GraphModel.ts";
|
|
57
165
|
var ReadonlyGraphModel = class {
|
|
166
|
+
_graph;
|
|
167
|
+
/**
|
|
168
|
+
* Optional function to wrap mutations.
|
|
169
|
+
* When set, all graph mutations are wrapped in this function.
|
|
170
|
+
*/
|
|
171
|
+
_change;
|
|
58
172
|
/**
|
|
59
173
|
* NOTE: Pass in simple Graph or Live.
|
|
174
|
+
* @param graph - The graph data.
|
|
175
|
+
* @param change - Optional function to wrap mutations (e.g., Obj.update for ECHO objects).
|
|
60
176
|
*/
|
|
61
|
-
constructor(graph) {
|
|
177
|
+
constructor(graph, change) {
|
|
62
178
|
this._graph = graph ?? {
|
|
63
179
|
nodes: [],
|
|
64
180
|
edges: []
|
|
65
181
|
};
|
|
182
|
+
this._change = change;
|
|
66
183
|
}
|
|
67
184
|
[inspectCustom]() {
|
|
68
185
|
return this.toJSON();
|
|
@@ -122,7 +239,7 @@ var ReadonlyGraphModel = class {
|
|
|
122
239
|
visited.add(root.id);
|
|
123
240
|
const targets = this.filterEdges({
|
|
124
241
|
source: root.id
|
|
125
|
-
}).map((edge) => this.getNode(edge.target)).filter(
|
|
242
|
+
}).map((edge) => this.getNode(edge.target)).filter(isTruthy);
|
|
126
243
|
return [
|
|
127
244
|
root,
|
|
128
245
|
...targets.flatMap((target) => this._traverse(target, visited))
|
|
@@ -130,9 +247,22 @@ var ReadonlyGraphModel = class {
|
|
|
130
247
|
}
|
|
131
248
|
};
|
|
132
249
|
var AbstractGraphModel = class extends ReadonlyGraphModel {
|
|
250
|
+
/**
|
|
251
|
+
* Execute a mutation on the graph.
|
|
252
|
+
* If a change function is set, wraps the mutation in it.
|
|
253
|
+
*/
|
|
254
|
+
_mutate(fn) {
|
|
255
|
+
if (this._change != null) {
|
|
256
|
+
this._change(() => fn(this._graph));
|
|
257
|
+
} else {
|
|
258
|
+
fn(this._graph);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
133
261
|
clear() {
|
|
134
|
-
this.
|
|
135
|
-
|
|
262
|
+
this._mutate((graph) => {
|
|
263
|
+
graph.nodes.length = 0;
|
|
264
|
+
graph.edges.length = 0;
|
|
265
|
+
});
|
|
136
266
|
return this;
|
|
137
267
|
}
|
|
138
268
|
addGraph(graph) {
|
|
@@ -148,76 +278,44 @@ var AbstractGraphModel = class extends ReadonlyGraphModel {
|
|
|
148
278
|
return this;
|
|
149
279
|
}
|
|
150
280
|
addNode(node) {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
A: [
|
|
156
|
-
"node.id",
|
|
157
|
-
"'ID is required'"
|
|
158
|
-
]
|
|
281
|
+
invariant3(node.id, "ID is required", { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 126, S: this, A: ["node.id", "'ID is required'"] });
|
|
282
|
+
invariant3(!this.findNode(node.id), `node already exists: ${node.id}`, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 127, S: this, A: ["!this.findNode(node.id)", "`node already exists: ${node.id}`"] });
|
|
283
|
+
this._mutate((graph) => {
|
|
284
|
+
graph.nodes.push(node);
|
|
159
285
|
});
|
|
160
|
-
invariant2(!this.findNode(node.id), `node already exists: ${node.id}`, {
|
|
161
|
-
F: __dxlog_file2,
|
|
162
|
-
L: 158,
|
|
163
|
-
S: this,
|
|
164
|
-
A: [
|
|
165
|
-
"!this.findNode(node.id)",
|
|
166
|
-
"`node already exists: ${node.id}`"
|
|
167
|
-
]
|
|
168
|
-
});
|
|
169
|
-
this._graph.nodes.push(node);
|
|
170
286
|
return node;
|
|
171
287
|
}
|
|
172
288
|
addNodes(nodes) {
|
|
173
289
|
return nodes.map((node) => this.addNode(node));
|
|
174
290
|
}
|
|
175
291
|
addEdge(edge) {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
L: 168,
|
|
179
|
-
S: this,
|
|
180
|
-
A: [
|
|
181
|
-
"edge.source",
|
|
182
|
-
""
|
|
183
|
-
]
|
|
184
|
-
});
|
|
185
|
-
invariant2(edge.target, void 0, {
|
|
186
|
-
F: __dxlog_file2,
|
|
187
|
-
L: 169,
|
|
188
|
-
S: this,
|
|
189
|
-
A: [
|
|
190
|
-
"edge.target",
|
|
191
|
-
""
|
|
192
|
-
]
|
|
193
|
-
});
|
|
292
|
+
invariant3(edge.source, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 137, S: this, A: ["edge.source", ""] });
|
|
293
|
+
invariant3(edge.target, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 138, S: this, A: ["edge.target", ""] });
|
|
194
294
|
if (!edge.id) {
|
|
195
295
|
edge = {
|
|
196
296
|
id: createEdgeId(edge),
|
|
197
297
|
...edge
|
|
198
298
|
};
|
|
199
299
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
S: this,
|
|
204
|
-
A: [
|
|
205
|
-
"!this.findNode(edge.id!)",
|
|
206
|
-
""
|
|
207
|
-
]
|
|
300
|
+
invariant3(!this.findNode(edge.id), void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 146, S: this, A: ["!this.findNode(edge.id)", ""] });
|
|
301
|
+
this._mutate((graph) => {
|
|
302
|
+
graph.edges.push(edge);
|
|
208
303
|
});
|
|
209
|
-
this._graph.edges.push(edge);
|
|
210
304
|
return edge;
|
|
211
305
|
}
|
|
212
306
|
addEdges(edges) {
|
|
213
307
|
return edges.map((edge) => this.addEdge(edge));
|
|
214
308
|
}
|
|
215
309
|
removeNode(id) {
|
|
216
|
-
|
|
217
|
-
|
|
310
|
+
let removedEdges = [];
|
|
311
|
+
let removedNodes = [];
|
|
312
|
+
this._mutate((graph) => {
|
|
313
|
+
removedEdges = removeBy(graph.edges, (edge) => edge.source === id || edge.target === id);
|
|
314
|
+
removedNodes = removeBy(graph.nodes, (node) => node.id === id);
|
|
315
|
+
});
|
|
218
316
|
return this.copy({
|
|
219
|
-
nodes,
|
|
220
|
-
edges
|
|
317
|
+
nodes: removedNodes,
|
|
318
|
+
edges: removedEdges
|
|
221
319
|
});
|
|
222
320
|
}
|
|
223
321
|
removeNodes(ids) {
|
|
@@ -225,10 +323,13 @@ var AbstractGraphModel = class extends ReadonlyGraphModel {
|
|
|
225
323
|
return this.copy().addGraphs(graphs);
|
|
226
324
|
}
|
|
227
325
|
removeEdge(id) {
|
|
228
|
-
|
|
326
|
+
let removedEdges = [];
|
|
327
|
+
this._mutate((graph) => {
|
|
328
|
+
removedEdges = removeBy(graph.edges, (edge) => edge.id === id);
|
|
329
|
+
});
|
|
229
330
|
return this.copy({
|
|
230
331
|
nodes: [],
|
|
231
|
-
edges
|
|
332
|
+
edges: removedEdges
|
|
232
333
|
});
|
|
233
334
|
}
|
|
234
335
|
removeEdges(ids) {
|
|
@@ -236,7 +337,8 @@ var AbstractGraphModel = class extends ReadonlyGraphModel {
|
|
|
236
337
|
return this.copy().addGraphs(graphs);
|
|
237
338
|
}
|
|
238
339
|
};
|
|
239
|
-
var
|
|
340
|
+
var AbstractBuilder = class {
|
|
341
|
+
_model;
|
|
240
342
|
constructor(_model) {
|
|
241
343
|
this._model = _model;
|
|
242
344
|
}
|
|
@@ -269,152 +371,138 @@ var AbstractGraphBuilder = class {
|
|
|
269
371
|
};
|
|
270
372
|
var GraphModel = class _GraphModel extends AbstractGraphModel {
|
|
271
373
|
get builder() {
|
|
272
|
-
return new
|
|
374
|
+
return new Builder(this);
|
|
273
375
|
}
|
|
274
376
|
copy(graph) {
|
|
275
|
-
return new _GraphModel(
|
|
276
|
-
nodes: graph?.nodes ?? [],
|
|
277
|
-
edges: graph?.edges ?? []
|
|
278
|
-
});
|
|
279
|
-
}
|
|
280
|
-
};
|
|
281
|
-
var subscribe = (model, cb, fire = false) => {
|
|
282
|
-
if (fire) {
|
|
283
|
-
cb(model, model.graph);
|
|
377
|
+
return new _GraphModel(graph);
|
|
284
378
|
}
|
|
285
|
-
return effect(() => {
|
|
286
|
-
cb(model, model.graph);
|
|
287
|
-
});
|
|
288
379
|
};
|
|
289
380
|
var ReactiveGraphModel = class _ReactiveGraphModel extends GraphModel {
|
|
290
|
-
|
|
291
|
-
|
|
381
|
+
_registry;
|
|
382
|
+
_graphAtom;
|
|
383
|
+
constructor(_registry, graph) {
|
|
384
|
+
const initialGraph = {
|
|
292
385
|
nodes: graph?.nodes ?? [],
|
|
293
386
|
edges: graph?.edges ?? []
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
return new _ReactiveGraphModel(graph);
|
|
298
|
-
}
|
|
299
|
-
subscribe(cb, fire = false) {
|
|
300
|
-
return subscribe(this, cb, fire);
|
|
387
|
+
};
|
|
388
|
+
super(initialGraph), this._registry = _registry;
|
|
389
|
+
this._graphAtom = Atom2.make(initialGraph);
|
|
301
390
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
call(cb) {
|
|
305
|
-
cb(this);
|
|
306
|
-
return this;
|
|
391
|
+
get registry() {
|
|
392
|
+
return this._registry;
|
|
307
393
|
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
var __dxlog_file3 = "/__w/dxos/dxos/packages/common/graph/src/selection.ts";
|
|
314
|
-
var SelectionModel = class {
|
|
315
|
-
constructor(_singleSelect = false) {
|
|
316
|
-
this._singleSelect = _singleSelect;
|
|
317
|
-
this._selected = signal(/* @__PURE__ */ new Set());
|
|
318
|
-
this._selectedIds = computed(() => Array.from(this._selected.value.values()));
|
|
394
|
+
/**
|
|
395
|
+
* Get the graph atom for reactive subscriptions.
|
|
396
|
+
*/
|
|
397
|
+
get graphAtom() {
|
|
398
|
+
return this._graphAtom;
|
|
319
399
|
}
|
|
320
|
-
|
|
321
|
-
return
|
|
322
|
-
selected: Array.from(this._selected.value.values())
|
|
323
|
-
};
|
|
400
|
+
get graph() {
|
|
401
|
+
return this._registry.get(this._graphAtom);
|
|
324
402
|
}
|
|
325
|
-
get
|
|
326
|
-
return this.
|
|
403
|
+
get nodes() {
|
|
404
|
+
return this.graph.nodes;
|
|
327
405
|
}
|
|
328
|
-
get
|
|
329
|
-
return this.
|
|
406
|
+
get edges() {
|
|
407
|
+
return this.graph.edges;
|
|
330
408
|
}
|
|
331
|
-
|
|
332
|
-
return this.
|
|
409
|
+
copy(graph) {
|
|
410
|
+
return new _ReactiveGraphModel(this._registry, graph);
|
|
333
411
|
}
|
|
334
412
|
clear() {
|
|
335
|
-
this.
|
|
413
|
+
this._registry.set(this._graphAtom, {
|
|
414
|
+
nodes: [],
|
|
415
|
+
edges: []
|
|
416
|
+
});
|
|
417
|
+
return this;
|
|
336
418
|
}
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
419
|
+
/**
|
|
420
|
+
* Set the entire graph at once, triggering a single notification.
|
|
421
|
+
*/
|
|
422
|
+
setGraph(graph) {
|
|
423
|
+
this._registry.set(this._graphAtom, graph);
|
|
424
|
+
return this;
|
|
425
|
+
}
|
|
426
|
+
addNode(node) {
|
|
427
|
+
invariant3(node.id, "ID is required", { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 280, S: this, A: ["node.id", "'ID is required'"] });
|
|
428
|
+
invariant3(!this.findNode(node.id), `node already exists: ${node.id}`, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 281, S: this, A: ["!this.findNode(node.id)", "`node already exists: ${node.id}`"] });
|
|
429
|
+
const current = this._registry.get(this._graphAtom);
|
|
430
|
+
this._registry.set(this._graphAtom, {
|
|
431
|
+
...current,
|
|
432
|
+
nodes: [
|
|
433
|
+
...current.nodes,
|
|
434
|
+
node
|
|
345
435
|
]
|
|
346
436
|
});
|
|
347
|
-
|
|
348
|
-
id
|
|
349
|
-
] : [
|
|
350
|
-
...Array.from(this._selected.value.values()),
|
|
351
|
-
id
|
|
352
|
-
]);
|
|
437
|
+
return node;
|
|
353
438
|
}
|
|
354
|
-
|
|
355
|
-
invariant3(
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
439
|
+
addEdge(edge) {
|
|
440
|
+
invariant3(edge.source, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 293, S: this, A: ["edge.source", ""] });
|
|
441
|
+
invariant3(edge.target, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 294, S: this, A: ["edge.target", ""] });
|
|
442
|
+
if (!edge.id) {
|
|
443
|
+
edge = {
|
|
444
|
+
id: createEdgeId(edge),
|
|
445
|
+
...edge
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
invariant3(!this.findNode(edge.id), void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 301, S: this, A: ["!this.findNode(edge.id)", ""] });
|
|
449
|
+
const current = this._registry.get(this._graphAtom);
|
|
450
|
+
this._registry.set(this._graphAtom, {
|
|
451
|
+
...current,
|
|
452
|
+
edges: [
|
|
453
|
+
...current.edges,
|
|
454
|
+
edge
|
|
362
455
|
]
|
|
363
456
|
});
|
|
364
|
-
|
|
457
|
+
return edge;
|
|
365
458
|
}
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
459
|
+
removeNode(id) {
|
|
460
|
+
const current = this._registry.get(this._graphAtom);
|
|
461
|
+
const removedEdges = current.edges.filter((edge) => edge.source === id || edge.target === id);
|
|
462
|
+
const removedNodes = current.nodes.filter((node) => node.id === id);
|
|
463
|
+
this._registry.set(this._graphAtom, {
|
|
464
|
+
nodes: current.nodes.filter((node) => node.id !== id),
|
|
465
|
+
edges: current.edges.filter((edge) => edge.source !== id && edge.target !== id)
|
|
466
|
+
});
|
|
467
|
+
return this.copy({
|
|
468
|
+
nodes: removedNodes,
|
|
469
|
+
edges: removedEdges
|
|
470
|
+
});
|
|
372
471
|
}
|
|
373
|
-
|
|
374
|
-
const
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
472
|
+
removeEdge(id) {
|
|
473
|
+
const current = this._registry.get(this._graphAtom);
|
|
474
|
+
const removedEdges = current.edges.filter((edge) => edge.id === id);
|
|
475
|
+
this._registry.set(this._graphAtom, {
|
|
476
|
+
...current,
|
|
477
|
+
edges: current.edges.filter((edge) => edge.id !== id)
|
|
478
|
+
});
|
|
479
|
+
return this.copy({
|
|
480
|
+
nodes: [],
|
|
481
|
+
edges: removedEdges
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* Subscribe to graph changes.
|
|
486
|
+
*/
|
|
487
|
+
subscribe(cb, fire = false) {
|
|
488
|
+
if (fire) {
|
|
489
|
+
cb(this, this.graph);
|
|
490
|
+
}
|
|
491
|
+
this._registry.get(this._graphAtom);
|
|
492
|
+
return this._registry.subscribe(this._graphAtom, () => {
|
|
493
|
+
cb(this, this.graph);
|
|
381
494
|
});
|
|
382
|
-
this._selected.value = set;
|
|
383
495
|
}
|
|
384
496
|
};
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
data: Schema.optional(Schema.Any)
|
|
392
|
-
});
|
|
393
|
-
var BaseGraphEdge = Schema.Struct({
|
|
394
|
-
id: Schema.String,
|
|
395
|
-
type: Schema.optional(Schema.String),
|
|
396
|
-
source: Schema.String,
|
|
397
|
-
target: Schema.String,
|
|
398
|
-
data: Schema.optional(Schema.Any)
|
|
399
|
-
});
|
|
400
|
-
var Graph = Schema.Struct({
|
|
401
|
-
id: Schema.optional(Schema.String),
|
|
402
|
-
nodes: Schema.mutable(Schema.Array(BaseGraphNode)),
|
|
403
|
-
edges: Schema.mutable(Schema.Array(BaseGraphEdge))
|
|
404
|
-
});
|
|
497
|
+
var Builder = class extends AbstractBuilder {
|
|
498
|
+
call(cb) {
|
|
499
|
+
cb(this);
|
|
500
|
+
return this;
|
|
501
|
+
}
|
|
502
|
+
};
|
|
405
503
|
export {
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
BaseGraphNode,
|
|
410
|
-
Graph,
|
|
411
|
-
GraphBuilder,
|
|
412
|
-
GraphModel,
|
|
413
|
-
ReactiveGraphModel,
|
|
414
|
-
ReadonlyGraphModel,
|
|
415
|
-
SelectionModel,
|
|
416
|
-
createEdgeId,
|
|
417
|
-
parseEdgeId,
|
|
418
|
-
subscribe
|
|
504
|
+
Graph_exports as Graph,
|
|
505
|
+
GraphModel_exports as GraphModel,
|
|
506
|
+
SelectionModel
|
|
419
507
|
};
|
|
420
508
|
//# sourceMappingURL=index.mjs.map
|