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