@dxos/graph 0.8.4-main.72ec0f3 → 0.8.4-main.765dc60934
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/LICENSE +102 -5
- package/dist/lib/browser/index.mjs +298 -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 +298 -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 +30 -8
- package/dist/types/src/selection.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +18 -19
- 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 +71 -22
- package/dist/types/src/model.d.ts +0 -102
- 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 { isTruthy, 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
|
+
_registry;
|
|
13
|
+
_selected;
|
|
14
|
+
_mode;
|
|
15
|
+
constructor({ mode = "multi" } = {}) {
|
|
16
|
+
this._registry = Registry.make();
|
|
17
|
+
this._selected = Atom.make(/* @__PURE__ */ new Set());
|
|
18
|
+
this._mode = mode;
|
|
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: 59, S: this, A: ["id", ""] });
|
|
66
|
+
const current = this._registry.get(this._selected);
|
|
67
|
+
this._registry.set(this._selected, new Set(this._mode === "single" ? [
|
|
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: 69, 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,34 +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 {
|
|
58
166
|
_graph;
|
|
59
167
|
/**
|
|
168
|
+
* Optional function to wrap mutations.
|
|
169
|
+
* When set, all graph mutations are wrapped in this function.
|
|
170
|
+
*/
|
|
171
|
+
_change;
|
|
172
|
+
/**
|
|
60
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).
|
|
61
176
|
*/
|
|
62
|
-
constructor(graph) {
|
|
177
|
+
constructor(graph, change) {
|
|
63
178
|
this._graph = graph ?? {
|
|
64
179
|
nodes: [],
|
|
65
180
|
edges: []
|
|
66
181
|
};
|
|
182
|
+
this._change = change;
|
|
67
183
|
}
|
|
68
184
|
[inspectCustom]() {
|
|
69
185
|
return this.toJSON();
|
|
@@ -131,9 +247,22 @@ var ReadonlyGraphModel = class {
|
|
|
131
247
|
}
|
|
132
248
|
};
|
|
133
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
|
+
}
|
|
134
261
|
clear() {
|
|
135
|
-
this.
|
|
136
|
-
|
|
262
|
+
this._mutate((graph) => {
|
|
263
|
+
graph.nodes.length = 0;
|
|
264
|
+
graph.edges.length = 0;
|
|
265
|
+
});
|
|
137
266
|
return this;
|
|
138
267
|
}
|
|
139
268
|
addGraph(graph) {
|
|
@@ -149,76 +278,44 @@ var AbstractGraphModel = class extends ReadonlyGraphModel {
|
|
|
149
278
|
return this;
|
|
150
279
|
}
|
|
151
280
|
addNode(node) {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
A: [
|
|
157
|
-
"node.id",
|
|
158
|
-
"'ID is required'"
|
|
159
|
-
]
|
|
160
|
-
});
|
|
161
|
-
invariant2(!this.findNode(node.id), `node already exists: ${node.id}`, {
|
|
162
|
-
F: __dxlog_file2,
|
|
163
|
-
L: 158,
|
|
164
|
-
S: this,
|
|
165
|
-
A: [
|
|
166
|
-
"!this.findNode(node.id)",
|
|
167
|
-
"`node already exists: ${node.id}`"
|
|
168
|
-
]
|
|
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);
|
|
169
285
|
});
|
|
170
|
-
this._graph.nodes.push(node);
|
|
171
286
|
return node;
|
|
172
287
|
}
|
|
173
288
|
addNodes(nodes) {
|
|
174
289
|
return nodes.map((node) => this.addNode(node));
|
|
175
290
|
}
|
|
176
291
|
addEdge(edge) {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
L: 168,
|
|
180
|
-
S: this,
|
|
181
|
-
A: [
|
|
182
|
-
"edge.source",
|
|
183
|
-
""
|
|
184
|
-
]
|
|
185
|
-
});
|
|
186
|
-
invariant2(edge.target, void 0, {
|
|
187
|
-
F: __dxlog_file2,
|
|
188
|
-
L: 169,
|
|
189
|
-
S: this,
|
|
190
|
-
A: [
|
|
191
|
-
"edge.target",
|
|
192
|
-
""
|
|
193
|
-
]
|
|
194
|
-
});
|
|
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", ""] });
|
|
195
294
|
if (!edge.id) {
|
|
196
295
|
edge = {
|
|
197
296
|
id: createEdgeId(edge),
|
|
198
297
|
...edge
|
|
199
298
|
};
|
|
200
299
|
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
S: this,
|
|
205
|
-
A: [
|
|
206
|
-
"!this.findNode(edge.id!)",
|
|
207
|
-
""
|
|
208
|
-
]
|
|
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);
|
|
209
303
|
});
|
|
210
|
-
this._graph.edges.push(edge);
|
|
211
304
|
return edge;
|
|
212
305
|
}
|
|
213
306
|
addEdges(edges) {
|
|
214
307
|
return edges.map((edge) => this.addEdge(edge));
|
|
215
308
|
}
|
|
216
309
|
removeNode(id) {
|
|
217
|
-
|
|
218
|
-
|
|
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
|
+
});
|
|
219
316
|
return this.copy({
|
|
220
|
-
nodes,
|
|
221
|
-
edges
|
|
317
|
+
nodes: removedNodes,
|
|
318
|
+
edges: removedEdges
|
|
222
319
|
});
|
|
223
320
|
}
|
|
224
321
|
removeNodes(ids) {
|
|
@@ -226,10 +323,13 @@ var AbstractGraphModel = class extends ReadonlyGraphModel {
|
|
|
226
323
|
return this.copy().addGraphs(graphs);
|
|
227
324
|
}
|
|
228
325
|
removeEdge(id) {
|
|
229
|
-
|
|
326
|
+
let removedEdges = [];
|
|
327
|
+
this._mutate((graph) => {
|
|
328
|
+
removedEdges = removeBy(graph.edges, (edge) => edge.id === id);
|
|
329
|
+
});
|
|
230
330
|
return this.copy({
|
|
231
331
|
nodes: [],
|
|
232
|
-
edges
|
|
332
|
+
edges: removedEdges
|
|
233
333
|
});
|
|
234
334
|
}
|
|
235
335
|
removeEdges(ids) {
|
|
@@ -237,7 +337,7 @@ var AbstractGraphModel = class extends ReadonlyGraphModel {
|
|
|
237
337
|
return this.copy().addGraphs(graphs);
|
|
238
338
|
}
|
|
239
339
|
};
|
|
240
|
-
var
|
|
340
|
+
var AbstractBuilder = class {
|
|
241
341
|
_model;
|
|
242
342
|
constructor(_model) {
|
|
243
343
|
this._model = _model;
|
|
@@ -271,153 +371,138 @@ var AbstractGraphBuilder = class {
|
|
|
271
371
|
};
|
|
272
372
|
var GraphModel = class _GraphModel extends AbstractGraphModel {
|
|
273
373
|
get builder() {
|
|
274
|
-
return new
|
|
374
|
+
return new Builder(this);
|
|
275
375
|
}
|
|
276
376
|
copy(graph) {
|
|
277
|
-
return new _GraphModel(
|
|
278
|
-
nodes: graph?.nodes ?? [],
|
|
279
|
-
edges: graph?.edges ?? []
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
};
|
|
283
|
-
var subscribe = (model, cb, fire = false) => {
|
|
284
|
-
if (fire) {
|
|
285
|
-
cb(model, model.graph);
|
|
377
|
+
return new _GraphModel(graph);
|
|
286
378
|
}
|
|
287
|
-
return effect(() => {
|
|
288
|
-
cb(model, model.graph);
|
|
289
|
-
});
|
|
290
379
|
};
|
|
291
380
|
var ReactiveGraphModel = class _ReactiveGraphModel extends GraphModel {
|
|
292
|
-
|
|
293
|
-
|
|
381
|
+
_registry;
|
|
382
|
+
_graphAtom;
|
|
383
|
+
constructor(_registry, graph) {
|
|
384
|
+
const initialGraph = {
|
|
294
385
|
nodes: graph?.nodes ?? [],
|
|
295
386
|
edges: graph?.edges ?? []
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
return new _ReactiveGraphModel(graph);
|
|
300
|
-
}
|
|
301
|
-
subscribe(cb, fire = false) {
|
|
302
|
-
return subscribe(this, cb, fire);
|
|
387
|
+
};
|
|
388
|
+
super(initialGraph), this._registry = _registry;
|
|
389
|
+
this._graphAtom = Atom2.make(initialGraph);
|
|
303
390
|
}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
call(cb) {
|
|
307
|
-
cb(this);
|
|
308
|
-
return this;
|
|
391
|
+
get registry() {
|
|
392
|
+
return this._registry;
|
|
309
393
|
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
var __dxlog_file3 = "/__w/dxos/dxos/packages/common/graph/src/selection.ts";
|
|
316
|
-
var SelectionModel = class {
|
|
317
|
-
_singleSelect;
|
|
318
|
-
_selected = signal(/* @__PURE__ */ new Set());
|
|
319
|
-
_selectedIds = computed(() => Array.from(this._selected.value.values()));
|
|
320
|
-
constructor(_singleSelect = false) {
|
|
321
|
-
this._singleSelect = _singleSelect;
|
|
394
|
+
/**
|
|
395
|
+
* Get the graph atom for reactive subscriptions.
|
|
396
|
+
*/
|
|
397
|
+
get graphAtom() {
|
|
398
|
+
return this._graphAtom;
|
|
322
399
|
}
|
|
323
|
-
|
|
324
|
-
return
|
|
325
|
-
selected: Array.from(this._selected.value.values())
|
|
326
|
-
};
|
|
400
|
+
get graph() {
|
|
401
|
+
return this._registry.get(this._graphAtom);
|
|
327
402
|
}
|
|
328
|
-
get
|
|
329
|
-
return this.
|
|
403
|
+
get nodes() {
|
|
404
|
+
return this.graph.nodes;
|
|
330
405
|
}
|
|
331
|
-
get
|
|
332
|
-
return this.
|
|
406
|
+
get edges() {
|
|
407
|
+
return this.graph.edges;
|
|
333
408
|
}
|
|
334
|
-
|
|
335
|
-
return this.
|
|
409
|
+
copy(graph) {
|
|
410
|
+
return new _ReactiveGraphModel(this._registry, graph);
|
|
336
411
|
}
|
|
337
412
|
clear() {
|
|
338
|
-
this.
|
|
413
|
+
this._registry.set(this._graphAtom, {
|
|
414
|
+
nodes: [],
|
|
415
|
+
edges: []
|
|
416
|
+
});
|
|
417
|
+
return this;
|
|
339
418
|
}
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
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
|
|
348
435
|
]
|
|
349
436
|
});
|
|
350
|
-
|
|
351
|
-
id
|
|
352
|
-
] : [
|
|
353
|
-
...Array.from(this._selected.value.values()),
|
|
354
|
-
id
|
|
355
|
-
]);
|
|
437
|
+
return node;
|
|
356
438
|
}
|
|
357
|
-
|
|
358
|
-
invariant3(
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
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
|
|
365
455
|
]
|
|
366
456
|
});
|
|
367
|
-
|
|
457
|
+
return edge;
|
|
368
458
|
}
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
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
|
+
});
|
|
375
471
|
}
|
|
376
|
-
|
|
377
|
-
const
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
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);
|
|
384
494
|
});
|
|
385
|
-
this._selected.value = set;
|
|
386
495
|
}
|
|
387
496
|
};
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
data: Schema.optional(Schema.Any)
|
|
395
|
-
});
|
|
396
|
-
var BaseGraphEdge = Schema.Struct({
|
|
397
|
-
id: Schema.String,
|
|
398
|
-
type: Schema.optional(Schema.String),
|
|
399
|
-
source: Schema.String,
|
|
400
|
-
target: Schema.String,
|
|
401
|
-
data: Schema.optional(Schema.Any)
|
|
402
|
-
});
|
|
403
|
-
var Graph = Schema.Struct({
|
|
404
|
-
id: Schema.optional(Schema.String),
|
|
405
|
-
nodes: Schema.mutable(Schema.Array(BaseGraphNode)),
|
|
406
|
-
edges: Schema.mutable(Schema.Array(BaseGraphEdge))
|
|
407
|
-
});
|
|
497
|
+
var Builder = class extends AbstractBuilder {
|
|
498
|
+
call(cb) {
|
|
499
|
+
cb(this);
|
|
500
|
+
return this;
|
|
501
|
+
}
|
|
502
|
+
};
|
|
408
503
|
export {
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
BaseGraphNode,
|
|
413
|
-
Graph,
|
|
414
|
-
GraphBuilder,
|
|
415
|
-
GraphModel,
|
|
416
|
-
ReactiveGraphModel,
|
|
417
|
-
ReadonlyGraphModel,
|
|
418
|
-
SelectionModel,
|
|
419
|
-
createEdgeId,
|
|
420
|
-
parseEdgeId,
|
|
421
|
-
subscribe
|
|
504
|
+
Graph_exports as Graph,
|
|
505
|
+
GraphModel_exports as GraphModel,
|
|
506
|
+
SelectionModel
|
|
422
507
|
};
|
|
423
508
|
//# sourceMappingURL=index.mjs.map
|