@dxos/graph 0.8.4-main.dedc0f3 → 0.8.4-main.e00bdcdb52
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 +311 -255
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +311 -256
- 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 -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,40 +134,54 @@ 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
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
69
|
-
var
|
|
70
|
-
var _inspectCustom = inspectCustom;
|
|
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";
|
|
71
165
|
var ReadonlyGraphModel = class {
|
|
72
|
-
|
|
166
|
+
_graph;
|
|
167
|
+
/**
|
|
168
|
+
* Optional function to wrap mutations.
|
|
169
|
+
* When set, all graph mutations are wrapped in this function.
|
|
170
|
+
*/
|
|
171
|
+
_change;
|
|
172
|
+
/**
|
|
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).
|
|
176
|
+
*/
|
|
177
|
+
constructor(graph, change) {
|
|
178
|
+
this._graph = graph ?? {
|
|
179
|
+
nodes: [],
|
|
180
|
+
edges: []
|
|
181
|
+
};
|
|
182
|
+
this._change = change;
|
|
183
|
+
}
|
|
184
|
+
[inspectCustom]() {
|
|
73
185
|
return this.toJSON();
|
|
74
186
|
}
|
|
75
187
|
/**
|
|
@@ -127,27 +239,30 @@ var ReadonlyGraphModel = class {
|
|
|
127
239
|
visited.add(root.id);
|
|
128
240
|
const targets = this.filterEdges({
|
|
129
241
|
source: root.id
|
|
130
|
-
}).map((edge) => this.getNode(edge.target)).filter(
|
|
242
|
+
}).map((edge) => this.getNode(edge.target)).filter(isTruthy);
|
|
131
243
|
return [
|
|
132
244
|
root,
|
|
133
245
|
...targets.flatMap((target) => this._traverse(target, visited))
|
|
134
246
|
];
|
|
135
247
|
}
|
|
248
|
+
};
|
|
249
|
+
var AbstractGraphModel = class extends ReadonlyGraphModel {
|
|
136
250
|
/**
|
|
137
|
-
*
|
|
251
|
+
* Execute a mutation on the graph.
|
|
252
|
+
* If a change function is set, wraps the mutation in it.
|
|
138
253
|
*/
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}
|
|
254
|
+
_mutate(fn) {
|
|
255
|
+
if (this._change != null) {
|
|
256
|
+
this._change(() => fn(this._graph));
|
|
257
|
+
} else {
|
|
258
|
+
fn(this._graph);
|
|
259
|
+
}
|
|
145
260
|
}
|
|
146
|
-
};
|
|
147
|
-
var AbstractGraphModel = class extends ReadonlyGraphModel {
|
|
148
261
|
clear() {
|
|
149
|
-
this.
|
|
150
|
-
|
|
262
|
+
this._mutate((graph) => {
|
|
263
|
+
graph.nodes.length = 0;
|
|
264
|
+
graph.edges.length = 0;
|
|
265
|
+
});
|
|
151
266
|
return this;
|
|
152
267
|
}
|
|
153
268
|
addGraph(graph) {
|
|
@@ -163,76 +278,44 @@ var AbstractGraphModel = class extends ReadonlyGraphModel {
|
|
|
163
278
|
return this;
|
|
164
279
|
}
|
|
165
280
|
addNode(node) {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
A: [
|
|
171
|
-
"node.id",
|
|
172
|
-
"'ID is required'"
|
|
173
|
-
]
|
|
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);
|
|
174
285
|
});
|
|
175
|
-
invariant2(!this.findNode(node.id), `node already exists: ${node.id}`, {
|
|
176
|
-
F: __dxlog_file2,
|
|
177
|
-
L: 158,
|
|
178
|
-
S: this,
|
|
179
|
-
A: [
|
|
180
|
-
"!this.findNode(node.id)",
|
|
181
|
-
"`node already exists: ${node.id}`"
|
|
182
|
-
]
|
|
183
|
-
});
|
|
184
|
-
this._graph.nodes.push(node);
|
|
185
286
|
return node;
|
|
186
287
|
}
|
|
187
288
|
addNodes(nodes) {
|
|
188
289
|
return nodes.map((node) => this.addNode(node));
|
|
189
290
|
}
|
|
190
291
|
addEdge(edge) {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
L: 168,
|
|
194
|
-
S: this,
|
|
195
|
-
A: [
|
|
196
|
-
"edge.source",
|
|
197
|
-
""
|
|
198
|
-
]
|
|
199
|
-
});
|
|
200
|
-
invariant2(edge.target, void 0, {
|
|
201
|
-
F: __dxlog_file2,
|
|
202
|
-
L: 169,
|
|
203
|
-
S: this,
|
|
204
|
-
A: [
|
|
205
|
-
"edge.target",
|
|
206
|
-
""
|
|
207
|
-
]
|
|
208
|
-
});
|
|
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", ""] });
|
|
209
294
|
if (!edge.id) {
|
|
210
295
|
edge = {
|
|
211
296
|
id: createEdgeId(edge),
|
|
212
297
|
...edge
|
|
213
298
|
};
|
|
214
299
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
S: this,
|
|
219
|
-
A: [
|
|
220
|
-
"!this.findNode(edge.id!)",
|
|
221
|
-
""
|
|
222
|
-
]
|
|
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);
|
|
223
303
|
});
|
|
224
|
-
this._graph.edges.push(edge);
|
|
225
304
|
return edge;
|
|
226
305
|
}
|
|
227
306
|
addEdges(edges) {
|
|
228
307
|
return edges.map((edge) => this.addEdge(edge));
|
|
229
308
|
}
|
|
230
309
|
removeNode(id) {
|
|
231
|
-
|
|
232
|
-
|
|
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
|
+
});
|
|
233
316
|
return this.copy({
|
|
234
|
-
nodes,
|
|
235
|
-
edges
|
|
317
|
+
nodes: removedNodes,
|
|
318
|
+
edges: removedEdges
|
|
236
319
|
});
|
|
237
320
|
}
|
|
238
321
|
removeNodes(ids) {
|
|
@@ -240,10 +323,13 @@ var AbstractGraphModel = class extends ReadonlyGraphModel {
|
|
|
240
323
|
return this.copy().addGraphs(graphs);
|
|
241
324
|
}
|
|
242
325
|
removeEdge(id) {
|
|
243
|
-
|
|
326
|
+
let removedEdges = [];
|
|
327
|
+
this._mutate((graph) => {
|
|
328
|
+
removedEdges = removeBy(graph.edges, (edge) => edge.id === id);
|
|
329
|
+
});
|
|
244
330
|
return this.copy({
|
|
245
331
|
nodes: [],
|
|
246
|
-
edges
|
|
332
|
+
edges: removedEdges
|
|
247
333
|
});
|
|
248
334
|
}
|
|
249
335
|
removeEdges(ids) {
|
|
@@ -251,7 +337,11 @@ var AbstractGraphModel = class extends ReadonlyGraphModel {
|
|
|
251
337
|
return this.copy().addGraphs(graphs);
|
|
252
338
|
}
|
|
253
339
|
};
|
|
254
|
-
var
|
|
340
|
+
var AbstractBuilder = class {
|
|
341
|
+
_model;
|
|
342
|
+
constructor(_model) {
|
|
343
|
+
this._model = _model;
|
|
344
|
+
}
|
|
255
345
|
get model() {
|
|
256
346
|
return this._model;
|
|
257
347
|
}
|
|
@@ -278,175 +368,141 @@ var AbstractGraphBuilder = class {
|
|
|
278
368
|
this._model.addEdges(edges);
|
|
279
369
|
return this;
|
|
280
370
|
}
|
|
281
|
-
constructor(_model) {
|
|
282
|
-
_define_property(this, "_model", void 0);
|
|
283
|
-
this._model = _model;
|
|
284
|
-
}
|
|
285
371
|
};
|
|
286
372
|
var GraphModel = class _GraphModel extends AbstractGraphModel {
|
|
287
373
|
get builder() {
|
|
288
|
-
return new
|
|
374
|
+
return new Builder(this);
|
|
289
375
|
}
|
|
290
376
|
copy(graph) {
|
|
291
|
-
return new _GraphModel(
|
|
292
|
-
nodes: graph?.nodes ?? [],
|
|
293
|
-
edges: graph?.edges ?? []
|
|
294
|
-
});
|
|
295
|
-
}
|
|
296
|
-
};
|
|
297
|
-
var subscribe = (model, cb, fire = false) => {
|
|
298
|
-
if (fire) {
|
|
299
|
-
cb(model, model.graph);
|
|
377
|
+
return new _GraphModel(graph);
|
|
300
378
|
}
|
|
301
|
-
return effect(() => {
|
|
302
|
-
cb(model, model.graph);
|
|
303
|
-
});
|
|
304
379
|
};
|
|
305
380
|
var ReactiveGraphModel = class _ReactiveGraphModel extends GraphModel {
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
return subscribe(this, cb, fire);
|
|
311
|
-
}
|
|
312
|
-
constructor(graph) {
|
|
313
|
-
super(live({
|
|
381
|
+
_registry;
|
|
382
|
+
_graphAtom;
|
|
383
|
+
constructor(_registry, graph) {
|
|
384
|
+
const initialGraph = {
|
|
314
385
|
nodes: graph?.nodes ?? [],
|
|
315
386
|
edges: graph?.edges ?? []
|
|
316
|
-
}
|
|
387
|
+
};
|
|
388
|
+
super(initialGraph), this._registry = _registry;
|
|
389
|
+
this._graphAtom = Atom2.make(initialGraph);
|
|
317
390
|
}
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
call(cb) {
|
|
321
|
-
cb(this);
|
|
322
|
-
return this;
|
|
391
|
+
get registry() {
|
|
392
|
+
return this._registry;
|
|
323
393
|
}
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
function _define_property2(obj, key, value) {
|
|
330
|
-
if (key in obj) {
|
|
331
|
-
Object.defineProperty(obj, key, {
|
|
332
|
-
value,
|
|
333
|
-
enumerable: true,
|
|
334
|
-
configurable: true,
|
|
335
|
-
writable: true
|
|
336
|
-
});
|
|
337
|
-
} else {
|
|
338
|
-
obj[key] = value;
|
|
394
|
+
/**
|
|
395
|
+
* Get the graph atom for reactive subscriptions.
|
|
396
|
+
*/
|
|
397
|
+
get graphAtom() {
|
|
398
|
+
return this._graphAtom;
|
|
339
399
|
}
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
var __dxlog_file3 = "/__w/dxos/dxos/packages/common/graph/src/selection.ts";
|
|
343
|
-
var SelectionModel = class {
|
|
344
|
-
toJSON() {
|
|
345
|
-
return {
|
|
346
|
-
selected: Array.from(this._selected.value.values())
|
|
347
|
-
};
|
|
400
|
+
get graph() {
|
|
401
|
+
return this._registry.get(this._graphAtom);
|
|
348
402
|
}
|
|
349
|
-
get
|
|
350
|
-
return this.
|
|
403
|
+
get nodes() {
|
|
404
|
+
return this.graph.nodes;
|
|
351
405
|
}
|
|
352
|
-
get
|
|
353
|
-
return this.
|
|
406
|
+
get edges() {
|
|
407
|
+
return this.graph.edges;
|
|
354
408
|
}
|
|
355
|
-
|
|
356
|
-
return this.
|
|
409
|
+
copy(graph) {
|
|
410
|
+
return new _ReactiveGraphModel(this._registry, graph);
|
|
357
411
|
}
|
|
358
412
|
clear() {
|
|
359
|
-
this.
|
|
413
|
+
this._registry.set(this._graphAtom, {
|
|
414
|
+
nodes: [],
|
|
415
|
+
edges: []
|
|
416
|
+
});
|
|
417
|
+
return this;
|
|
360
418
|
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
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
|
|
369
435
|
]
|
|
370
436
|
});
|
|
371
|
-
|
|
372
|
-
id
|
|
373
|
-
] : [
|
|
374
|
-
...Array.from(this._selected.value.values()),
|
|
375
|
-
id
|
|
376
|
-
]);
|
|
437
|
+
return node;
|
|
377
438
|
}
|
|
378
|
-
|
|
379
|
-
invariant3(
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
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
|
|
386
455
|
]
|
|
387
456
|
});
|
|
388
|
-
|
|
457
|
+
return edge;
|
|
389
458
|
}
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
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
|
+
});
|
|
396
471
|
}
|
|
397
|
-
|
|
398
|
-
const
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
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
|
|
405
482
|
});
|
|
406
|
-
this._selected.value = set;
|
|
407
483
|
}
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
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);
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
};
|
|
497
|
+
var Builder = class extends AbstractBuilder {
|
|
498
|
+
call(cb) {
|
|
499
|
+
cb(this);
|
|
500
|
+
return this;
|
|
415
501
|
}
|
|
416
502
|
};
|
|
417
|
-
|
|
418
|
-
// src/types.ts
|
|
419
|
-
import { Schema } from "effect";
|
|
420
|
-
var BaseGraphNode = Schema.Struct({
|
|
421
|
-
id: Schema.String,
|
|
422
|
-
type: Schema.optional(Schema.String),
|
|
423
|
-
data: Schema.optional(Schema.Any)
|
|
424
|
-
});
|
|
425
|
-
var BaseGraphEdge = Schema.Struct({
|
|
426
|
-
id: Schema.String,
|
|
427
|
-
type: Schema.optional(Schema.String),
|
|
428
|
-
source: Schema.String,
|
|
429
|
-
target: Schema.String,
|
|
430
|
-
data: Schema.optional(Schema.Any)
|
|
431
|
-
});
|
|
432
|
-
var Graph = Schema.Struct({
|
|
433
|
-
id: Schema.optional(Schema.String),
|
|
434
|
-
nodes: Schema.mutable(Schema.Array(BaseGraphNode)),
|
|
435
|
-
edges: Schema.mutable(Schema.Array(BaseGraphEdge))
|
|
436
|
-
});
|
|
437
503
|
export {
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
BaseGraphNode,
|
|
442
|
-
Graph,
|
|
443
|
-
GraphBuilder,
|
|
444
|
-
GraphModel,
|
|
445
|
-
ReactiveGraphModel,
|
|
446
|
-
ReadonlyGraphModel,
|
|
447
|
-
SelectionModel,
|
|
448
|
-
createEdgeId,
|
|
449
|
-
parseEdgeId,
|
|
450
|
-
subscribe
|
|
504
|
+
Graph_exports as Graph,
|
|
505
|
+
GraphModel_exports as GraphModel,
|
|
506
|
+
SelectionModel
|
|
451
507
|
};
|
|
452
508
|
//# sourceMappingURL=index.mjs.map
|