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