@dxos/app-graph 0.8.4-main.c1de068 → 0.8.4-main.dedc0f3
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 +234 -159
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +234 -159
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/graph-builder.d.ts +15 -4
- package/dist/types/src/graph-builder.d.ts.map +1 -1
- package/dist/types/src/graph.d.ts +6 -2
- package/dist/types/src/graph.d.ts.map +1 -1
- package/dist/types/src/node.d.ts +1 -1
- package/dist/types/src/stories/EchoGraph.stories.d.ts +8 -9
- package/dist/types/src/stories/EchoGraph.stories.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +24 -23
- package/src/graph-builder.test.ts +59 -2
- package/src/graph-builder.ts +65 -21
- package/src/graph.test.ts +1 -1
- package/src/graph.ts +16 -17
- package/src/node.ts +1 -1
- package/src/signals-integration.test.ts +1 -1
- package/src/stories/EchoGraph.stories.tsx +15 -12
|
@@ -1,11 +1,24 @@
|
|
|
1
1
|
// src/graph.ts
|
|
2
2
|
import { Registry, Rx } from "@effect-rx/rx-react";
|
|
3
|
-
import { Option,
|
|
3
|
+
import { Option, Record, pipe } from "effect";
|
|
4
4
|
import { Event, Trigger } from "@dxos/async";
|
|
5
5
|
import { todo } from "@dxos/debug";
|
|
6
6
|
import { invariant } from "@dxos/invariant";
|
|
7
7
|
import { log } from "@dxos/log";
|
|
8
8
|
import { isNonNullable } from "@dxos/util";
|
|
9
|
+
function _define_property(obj, key, value) {
|
|
10
|
+
if (key in obj) {
|
|
11
|
+
Object.defineProperty(obj, key, {
|
|
12
|
+
value,
|
|
13
|
+
enumerable: true,
|
|
14
|
+
configurable: true,
|
|
15
|
+
writable: true
|
|
16
|
+
});
|
|
17
|
+
} else {
|
|
18
|
+
obj[key] = value;
|
|
19
|
+
}
|
|
20
|
+
return obj;
|
|
21
|
+
}
|
|
9
22
|
var __dxlog_file = "/__w/dxos/dxos/packages/sdk/app-graph/src/graph.ts";
|
|
10
23
|
var graphSymbol = Symbol("graph");
|
|
11
24
|
var getGraph = (node) => {
|
|
@@ -26,103 +39,6 @@ var ROOT_TYPE = "dxos.org/type/GraphRoot";
|
|
|
26
39
|
var ACTION_TYPE = "dxos.org/type/GraphAction";
|
|
27
40
|
var ACTION_GROUP_TYPE = "dxos.org/type/GraphActionGroup";
|
|
28
41
|
var Graph = class {
|
|
29
|
-
constructor({ registry, nodes, edges, onExpand, onRemoveNode } = {}) {
|
|
30
|
-
this.onNodeChanged = new Event();
|
|
31
|
-
this._expanded = Record.empty();
|
|
32
|
-
this._initialized = Record.empty();
|
|
33
|
-
this._initialEdges = Record.empty();
|
|
34
|
-
this._initialNodes = Record.fromEntries([
|
|
35
|
-
[
|
|
36
|
-
ROOT_ID,
|
|
37
|
-
this._constructNode({
|
|
38
|
-
id: ROOT_ID,
|
|
39
|
-
type: ROOT_TYPE,
|
|
40
|
-
data: null,
|
|
41
|
-
properties: {}
|
|
42
|
-
})
|
|
43
|
-
]
|
|
44
|
-
]);
|
|
45
|
-
/** @internal */
|
|
46
|
-
this._node = Rx.family((id) => {
|
|
47
|
-
const initial = Option.flatten(Record.get(this._initialNodes, id));
|
|
48
|
-
return Rx.make(initial).pipe(Rx.keepAlive, Rx.withLabel(`graph:node:${id}`));
|
|
49
|
-
});
|
|
50
|
-
this._nodeOrThrow = Rx.family((id) => {
|
|
51
|
-
return Rx.make((get) => {
|
|
52
|
-
const node = get(this._node(id));
|
|
53
|
-
invariant(Option.isSome(node), `Node not available: ${id}`, {
|
|
54
|
-
F: __dxlog_file,
|
|
55
|
-
L: 253,
|
|
56
|
-
S: this,
|
|
57
|
-
A: [
|
|
58
|
-
"Option.isSome(node)",
|
|
59
|
-
"`Node not available: ${id}`"
|
|
60
|
-
]
|
|
61
|
-
});
|
|
62
|
-
return node.value;
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
this._edges = Rx.family((id) => {
|
|
66
|
-
const initial = Record.get(this._initialEdges, id).pipe(Option.getOrElse(() => ({
|
|
67
|
-
inbound: [],
|
|
68
|
-
outbound: []
|
|
69
|
-
})));
|
|
70
|
-
return Rx.make(initial).pipe(Rx.keepAlive, Rx.withLabel(`graph:edges:${id}`));
|
|
71
|
-
});
|
|
72
|
-
// NOTE: Currently the argument to the family needs to be referentially stable for the rx to be referentially stable.
|
|
73
|
-
// TODO(wittjosiah): Rx feature request, support for something akin to `ComplexMap` to allow for complex arguments.
|
|
74
|
-
this._connections = Rx.family((key) => {
|
|
75
|
-
return Rx.make((get) => {
|
|
76
|
-
const [id, relation] = key.split("$");
|
|
77
|
-
const edges = get(this._edges(id));
|
|
78
|
-
return edges[relation].map((id2) => get(this._node(id2))).filter(Option.isSome).map((o) => o.value);
|
|
79
|
-
}).pipe(Rx.withLabel(`graph:connections:${key}`));
|
|
80
|
-
});
|
|
81
|
-
this._actions = Rx.family((id) => {
|
|
82
|
-
return Rx.make((get) => {
|
|
83
|
-
return get(this._connections(`${id}$outbound`)).filter((node) => node.type === ACTION_TYPE || node.type === ACTION_GROUP_TYPE);
|
|
84
|
-
}).pipe(Rx.withLabel(`graph:actions:${id}`));
|
|
85
|
-
});
|
|
86
|
-
this._json = Rx.family((id) => {
|
|
87
|
-
return Rx.make((get) => {
|
|
88
|
-
const toJSON = (node, seen = []) => {
|
|
89
|
-
const nodes = get(this.connections(node.id));
|
|
90
|
-
const obj = {
|
|
91
|
-
id: node.id.length > 32 ? `${node.id.slice(0, 32)}...` : node.id,
|
|
92
|
-
type: node.type
|
|
93
|
-
};
|
|
94
|
-
if (node.properties.label) {
|
|
95
|
-
obj.label = node.properties.label;
|
|
96
|
-
}
|
|
97
|
-
if (nodes.length) {
|
|
98
|
-
obj.nodes = nodes.map((n) => {
|
|
99
|
-
const nextSeen = [
|
|
100
|
-
...seen,
|
|
101
|
-
node.id
|
|
102
|
-
];
|
|
103
|
-
return nextSeen.includes(n.id) ? void 0 : toJSON(n, nextSeen);
|
|
104
|
-
}).filter(isNonNullable);
|
|
105
|
-
}
|
|
106
|
-
return obj;
|
|
107
|
-
};
|
|
108
|
-
const root = get(this.nodeOrThrow(id));
|
|
109
|
-
return toJSON(root);
|
|
110
|
-
}).pipe(Rx.withLabel(`graph:json:${id}`));
|
|
111
|
-
});
|
|
112
|
-
this._registry = registry ?? Registry.make();
|
|
113
|
-
this._onExpand = onExpand;
|
|
114
|
-
this._onRemoveNode = onRemoveNode;
|
|
115
|
-
if (nodes) {
|
|
116
|
-
nodes.forEach((node) => {
|
|
117
|
-
Record.set(this._initialNodes, node.id, this._constructNode(node));
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
if (edges) {
|
|
121
|
-
Object.entries(edges).forEach(([source, edges2]) => {
|
|
122
|
-
Record.set(this._initialEdges, source, edges2);
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
42
|
toJSON(id = ROOT_ID) {
|
|
127
43
|
return this._registry.get(this._json(id));
|
|
128
44
|
}
|
|
@@ -162,15 +78,22 @@ var Graph = class {
|
|
|
162
78
|
getEdges(id) {
|
|
163
79
|
return this._registry.get(this.edges(id));
|
|
164
80
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
81
|
+
async initialize(id) {
|
|
82
|
+
const initialized = Record.get(this._initialized, id).pipe(Option.getOrElse(() => false));
|
|
83
|
+
log("initialize", {
|
|
84
|
+
id,
|
|
85
|
+
initialized
|
|
86
|
+
}, {
|
|
87
|
+
F: __dxlog_file,
|
|
88
|
+
L: 384,
|
|
89
|
+
S: this,
|
|
90
|
+
C: (f, a) => f(...a)
|
|
91
|
+
});
|
|
92
|
+
if (!initialized) {
|
|
93
|
+
await this._onInitialize?.(id);
|
|
94
|
+
Record.set(this._initialized, id, true);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
174
97
|
expand(id, relation = "outbound") {
|
|
175
98
|
const key = `${id}$${relation}`;
|
|
176
99
|
const expanded = Record.get(this._expanded, key).pipe(Option.getOrElse(() => false));
|
|
@@ -179,7 +102,7 @@ var Graph = class {
|
|
|
179
102
|
expanded
|
|
180
103
|
}, {
|
|
181
104
|
F: __dxlog_file,
|
|
182
|
-
L:
|
|
105
|
+
L: 394,
|
|
183
106
|
S: this,
|
|
184
107
|
C: (f, a) => f(...a)
|
|
185
108
|
});
|
|
@@ -209,7 +132,7 @@ var Graph = class {
|
|
|
209
132
|
propertiesChanged
|
|
210
133
|
}, {
|
|
211
134
|
F: __dxlog_file,
|
|
212
|
-
L:
|
|
135
|
+
L: 416,
|
|
213
136
|
S: this,
|
|
214
137
|
C: (f, a) => f(...a)
|
|
215
138
|
});
|
|
@@ -221,7 +144,7 @@ var Graph = class {
|
|
|
221
144
|
properties
|
|
222
145
|
}, {
|
|
223
146
|
F: __dxlog_file,
|
|
224
|
-
L:
|
|
147
|
+
L: 418,
|
|
225
148
|
S: this,
|
|
226
149
|
C: (f, a) => f(...a)
|
|
227
150
|
});
|
|
@@ -249,7 +172,7 @@ var Graph = class {
|
|
|
249
172
|
properties
|
|
250
173
|
}, {
|
|
251
174
|
F: __dxlog_file,
|
|
252
|
-
L:
|
|
175
|
+
L: 425,
|
|
253
176
|
S: this,
|
|
254
177
|
C: (f, a) => f(...a)
|
|
255
178
|
});
|
|
@@ -320,7 +243,7 @@ var Graph = class {
|
|
|
320
243
|
target: edgeArg.target
|
|
321
244
|
}, {
|
|
322
245
|
F: __dxlog_file,
|
|
323
|
-
L:
|
|
246
|
+
L: 480,
|
|
324
247
|
S: this,
|
|
325
248
|
C: (f, a) => f(...a)
|
|
326
249
|
});
|
|
@@ -340,7 +263,7 @@ var Graph = class {
|
|
|
340
263
|
target: edgeArg.target
|
|
341
264
|
}, {
|
|
342
265
|
F: __dxlog_file,
|
|
343
|
-
L:
|
|
266
|
+
L: 487,
|
|
344
267
|
S: this,
|
|
345
268
|
C: (f, a) => f(...a)
|
|
346
269
|
});
|
|
@@ -464,12 +387,111 @@ var Graph = class {
|
|
|
464
387
|
...node
|
|
465
388
|
});
|
|
466
389
|
}
|
|
390
|
+
constructor({ registry, nodes, edges, onInitialize, onExpand, onRemoveNode } = {}) {
|
|
391
|
+
_define_property(this, "onNodeChanged", new Event());
|
|
392
|
+
_define_property(this, "_onExpand", void 0);
|
|
393
|
+
_define_property(this, "_onInitialize", void 0);
|
|
394
|
+
_define_property(this, "_onRemoveNode", void 0);
|
|
395
|
+
_define_property(this, "_registry", void 0);
|
|
396
|
+
_define_property(this, "_expanded", Record.empty());
|
|
397
|
+
_define_property(this, "_initialized", Record.empty());
|
|
398
|
+
_define_property(this, "_initialEdges", Record.empty());
|
|
399
|
+
_define_property(this, "_initialNodes", Record.fromEntries([
|
|
400
|
+
[
|
|
401
|
+
ROOT_ID,
|
|
402
|
+
this._constructNode({
|
|
403
|
+
id: ROOT_ID,
|
|
404
|
+
type: ROOT_TYPE,
|
|
405
|
+
data: null,
|
|
406
|
+
properties: {}
|
|
407
|
+
})
|
|
408
|
+
]
|
|
409
|
+
]));
|
|
410
|
+
_define_property(this, "_node", Rx.family((id) => {
|
|
411
|
+
const initial = Option.flatten(Record.get(this._initialNodes, id));
|
|
412
|
+
return Rx.make(initial).pipe(Rx.keepAlive, Rx.withLabel(`graph:node:${id}`));
|
|
413
|
+
}));
|
|
414
|
+
_define_property(this, "_nodeOrThrow", Rx.family((id) => {
|
|
415
|
+
return Rx.make((get) => {
|
|
416
|
+
const node = get(this._node(id));
|
|
417
|
+
invariant(Option.isSome(node), `Node not available: ${id}`, {
|
|
418
|
+
F: __dxlog_file,
|
|
419
|
+
L: 252,
|
|
420
|
+
S: this,
|
|
421
|
+
A: [
|
|
422
|
+
"Option.isSome(node)",
|
|
423
|
+
"`Node not available: ${id}`"
|
|
424
|
+
]
|
|
425
|
+
});
|
|
426
|
+
return node.value;
|
|
427
|
+
});
|
|
428
|
+
}));
|
|
429
|
+
_define_property(this, "_edges", Rx.family((id) => {
|
|
430
|
+
const initial = Record.get(this._initialEdges, id).pipe(Option.getOrElse(() => ({
|
|
431
|
+
inbound: [],
|
|
432
|
+
outbound: []
|
|
433
|
+
})));
|
|
434
|
+
return Rx.make(initial).pipe(Rx.keepAlive, Rx.withLabel(`graph:edges:${id}`));
|
|
435
|
+
}));
|
|
436
|
+
_define_property(this, "_connections", Rx.family((key) => {
|
|
437
|
+
return Rx.make((get) => {
|
|
438
|
+
const [id, relation] = key.split("$");
|
|
439
|
+
const edges2 = get(this._edges(id));
|
|
440
|
+
return edges2[relation].map((id2) => get(this._node(id2))).filter(Option.isSome).map((o) => o.value);
|
|
441
|
+
}).pipe(Rx.withLabel(`graph:connections:${key}`));
|
|
442
|
+
}));
|
|
443
|
+
_define_property(this, "_actions", Rx.family((id) => {
|
|
444
|
+
return Rx.make((get) => {
|
|
445
|
+
return get(this._connections(`${id}$outbound`)).filter((node) => node.type === ACTION_TYPE || node.type === ACTION_GROUP_TYPE);
|
|
446
|
+
}).pipe(Rx.withLabel(`graph:actions:${id}`));
|
|
447
|
+
}));
|
|
448
|
+
_define_property(this, "_json", Rx.family((id) => {
|
|
449
|
+
return Rx.make((get) => {
|
|
450
|
+
const toJSON = (node, seen = []) => {
|
|
451
|
+
const nodes2 = get(this.connections(node.id));
|
|
452
|
+
const obj = {
|
|
453
|
+
id: node.id.length > 32 ? `${node.id.slice(0, 32)}...` : node.id,
|
|
454
|
+
type: node.type
|
|
455
|
+
};
|
|
456
|
+
if (node.properties.label) {
|
|
457
|
+
obj.label = node.properties.label;
|
|
458
|
+
}
|
|
459
|
+
if (nodes2.length) {
|
|
460
|
+
obj.nodes = nodes2.map((n) => {
|
|
461
|
+
const nextSeen = [
|
|
462
|
+
...seen,
|
|
463
|
+
node.id
|
|
464
|
+
];
|
|
465
|
+
return nextSeen.includes(n.id) ? void 0 : toJSON(n, nextSeen);
|
|
466
|
+
}).filter(isNonNullable);
|
|
467
|
+
}
|
|
468
|
+
return obj;
|
|
469
|
+
};
|
|
470
|
+
const root = get(this.nodeOrThrow(id));
|
|
471
|
+
return toJSON(root);
|
|
472
|
+
}).pipe(Rx.withLabel(`graph:json:${id}`));
|
|
473
|
+
}));
|
|
474
|
+
this._registry = registry ?? Registry.make();
|
|
475
|
+
this._onInitialize = onInitialize;
|
|
476
|
+
this._onExpand = onExpand;
|
|
477
|
+
this._onRemoveNode = onRemoveNode;
|
|
478
|
+
if (nodes) {
|
|
479
|
+
nodes.forEach((node) => {
|
|
480
|
+
Record.set(this._initialNodes, node.id, this._constructNode(node));
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
if (edges) {
|
|
484
|
+
Object.entries(edges).forEach(([source, edges2]) => {
|
|
485
|
+
Record.set(this._initialEdges, source, edges2);
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
}
|
|
467
489
|
};
|
|
468
490
|
|
|
469
491
|
// src/graph-builder.ts
|
|
470
492
|
import { Registry as Registry2, Rx as Rx2 } from "@effect-rx/rx-react";
|
|
471
493
|
import { effect } from "@preact/signals-core";
|
|
472
|
-
import { Array,
|
|
494
|
+
import { Array, Option as Option2, Record as Record2, pipe as pipe2 } from "effect";
|
|
473
495
|
import { log as log2 } from "@dxos/log";
|
|
474
496
|
import { byPosition, getDebugName, isNode, isNonNullable as isNonNullable2 } from "@dxos/util";
|
|
475
497
|
|
|
@@ -481,15 +503,33 @@ var isActionGroup = (data) => isGraphNode(data) ? data.data === actionGroupSymbo
|
|
|
481
503
|
var isActionLike = (data) => isAction(data) || isActionGroup(data);
|
|
482
504
|
|
|
483
505
|
// src/graph-builder.ts
|
|
506
|
+
function _define_property2(obj, key, value) {
|
|
507
|
+
if (key in obj) {
|
|
508
|
+
Object.defineProperty(obj, key, {
|
|
509
|
+
value,
|
|
510
|
+
enumerable: true,
|
|
511
|
+
configurable: true,
|
|
512
|
+
writable: true
|
|
513
|
+
});
|
|
514
|
+
} else {
|
|
515
|
+
obj[key] = value;
|
|
516
|
+
}
|
|
517
|
+
return obj;
|
|
518
|
+
}
|
|
484
519
|
var __dxlog_file2 = "/__w/dxos/dxos/packages/sdk/app-graph/src/graph-builder.ts";
|
|
485
520
|
var createExtension = (extension) => {
|
|
486
|
-
const { id, position = "static", relation = "outbound", connector: _connector, actions: _actions, actionGroups: _actionGroups } = extension;
|
|
521
|
+
const { id, position = "static", relation = "outbound", resolver: _resolver, connector: _connector, actions: _actions, actionGroups: _actionGroups } = extension;
|
|
487
522
|
const getId = (key) => `${id}/${key}`;
|
|
523
|
+
const resolver = _resolver && Rx2.family((id2) => _resolver(id2).pipe(Rx2.withLabel(`graph-builder:_resolver:${id2}`)));
|
|
488
524
|
const connector = _connector && Rx2.family((node) => _connector(node).pipe(Rx2.withLabel(`graph-builder:_connector:${id}`)));
|
|
489
525
|
const actionGroups = _actionGroups && Rx2.family((node) => _actionGroups(node).pipe(Rx2.withLabel(`graph-builder:_actionGroups:${id}`)));
|
|
490
526
|
const actions = _actions && Rx2.family((node) => _actions(node).pipe(Rx2.withLabel(`graph-builder:_actions:${id}`)));
|
|
491
527
|
return [
|
|
492
|
-
|
|
528
|
+
resolver ? {
|
|
529
|
+
id: getId("resolver"),
|
|
530
|
+
position,
|
|
531
|
+
resolver
|
|
532
|
+
} : void 0,
|
|
493
533
|
connector ? {
|
|
494
534
|
id: getId("connector"),
|
|
495
535
|
position,
|
|
@@ -503,7 +543,7 @@ var createExtension = (extension) => {
|
|
|
503
543
|
node
|
|
504
544
|
}, {
|
|
505
545
|
F: __dxlog_file2,
|
|
506
|
-
L:
|
|
546
|
+
L: 109,
|
|
507
547
|
S: void 0,
|
|
508
548
|
C: (f, a) => f(...a)
|
|
509
549
|
});
|
|
@@ -528,7 +568,7 @@ var createExtension = (extension) => {
|
|
|
528
568
|
node
|
|
529
569
|
}, {
|
|
530
570
|
F: __dxlog_file2,
|
|
531
|
-
L:
|
|
571
|
+
L: 130,
|
|
532
572
|
S: void 0,
|
|
533
573
|
C: (f, a) => f(...a)
|
|
534
574
|
});
|
|
@@ -552,7 +592,7 @@ var createExtension = (extension) => {
|
|
|
552
592
|
node
|
|
553
593
|
}, {
|
|
554
594
|
F: __dxlog_file2,
|
|
555
|
-
L:
|
|
595
|
+
L: 147,
|
|
556
596
|
S: void 0,
|
|
557
597
|
C: (f, a) => f(...a)
|
|
558
598
|
});
|
|
@@ -576,35 +616,6 @@ var flattenExtensions = (extension, acc = []) => {
|
|
|
576
616
|
}
|
|
577
617
|
};
|
|
578
618
|
var GraphBuilder = class _GraphBuilder {
|
|
579
|
-
constructor({ registry, ...params } = {}) {
|
|
580
|
-
// TODO(wittjosiah): Use Context.
|
|
581
|
-
this._connectorSubscriptions = /* @__PURE__ */ new Map();
|
|
582
|
-
this._extensions = Rx2.make(Record2.empty()).pipe(Rx2.keepAlive, Rx2.withLabel("graph-builder:extensions"));
|
|
583
|
-
this._connectors = Rx2.family((key) => {
|
|
584
|
-
return Rx2.make((get) => {
|
|
585
|
-
const [id, relation] = key.split("+");
|
|
586
|
-
const node = this._graph.node(id);
|
|
587
|
-
return pipe2(
|
|
588
|
-
get(this._extensions),
|
|
589
|
-
Record2.values,
|
|
590
|
-
// TODO(wittjosiah): Sort on write rather than read.
|
|
591
|
-
Array.sortBy(byPosition),
|
|
592
|
-
Array.filter(({ relation: _relation = "outbound" }) => _relation === relation),
|
|
593
|
-
Array.map(({ connector }) => connector?.(node)),
|
|
594
|
-
Array.filter(isNonNullable2),
|
|
595
|
-
Array.flatMap((result) => get(result))
|
|
596
|
-
);
|
|
597
|
-
}).pipe(Rx2.withLabel(`graph-builder:connectors:${key}`));
|
|
598
|
-
});
|
|
599
|
-
this._registry = registry ?? Registry2.make();
|
|
600
|
-
this._graph = new Graph({
|
|
601
|
-
...params,
|
|
602
|
-
registry: this._registry,
|
|
603
|
-
onExpand: (id, relation) => this._onExpand(id, relation),
|
|
604
|
-
// onInitialize: (id) => this._onInitialize(id),
|
|
605
|
-
onRemoveNode: (id) => this._onRemoveNode(id)
|
|
606
|
-
});
|
|
607
|
-
}
|
|
608
619
|
static from(pickle, registry) {
|
|
609
620
|
if (!pickle) {
|
|
610
621
|
return new _GraphBuilder({
|
|
@@ -671,8 +682,8 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
671
682
|
}
|
|
672
683
|
}
|
|
673
684
|
destroy() {
|
|
674
|
-
this.
|
|
675
|
-
this.
|
|
685
|
+
this._subscriptions.forEach((unsubscribe) => unsubscribe());
|
|
686
|
+
this._subscriptions.clear();
|
|
676
687
|
}
|
|
677
688
|
_onExpand(id, relation) {
|
|
678
689
|
log2("onExpand", {
|
|
@@ -681,7 +692,7 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
681
692
|
registry: getDebugName(this._registry)
|
|
682
693
|
}, {
|
|
683
694
|
F: __dxlog_file2,
|
|
684
|
-
L:
|
|
695
|
+
L: 324,
|
|
685
696
|
S: this,
|
|
686
697
|
C: (f, a) => f(...a)
|
|
687
698
|
});
|
|
@@ -698,7 +709,7 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
698
709
|
removed
|
|
699
710
|
}, {
|
|
700
711
|
F: __dxlog_file2,
|
|
701
|
-
L:
|
|
712
|
+
L: 335,
|
|
702
713
|
S: this,
|
|
703
714
|
C: (f, a) => f(...a)
|
|
704
715
|
});
|
|
@@ -727,15 +738,79 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
727
738
|
}, {
|
|
728
739
|
immediate: true
|
|
729
740
|
});
|
|
730
|
-
this.
|
|
741
|
+
this._subscriptions.set(id, cancel);
|
|
742
|
+
}
|
|
743
|
+
// TODO(wittjosiah): If the same node is added by a connector, the resolver should probably cancel itself?
|
|
744
|
+
async _onInitialize(id) {
|
|
745
|
+
log2("onInitialize", {
|
|
746
|
+
id
|
|
747
|
+
}, {
|
|
748
|
+
F: __dxlog_file2,
|
|
749
|
+
L: 372,
|
|
750
|
+
S: this,
|
|
751
|
+
C: (f, a) => f(...a)
|
|
752
|
+
});
|
|
753
|
+
const resolver = this._resolvers(id);
|
|
754
|
+
const cancel = this._registry.subscribe(resolver, (node) => {
|
|
755
|
+
const trigger = this._initialized[id];
|
|
756
|
+
Option2.match(node, {
|
|
757
|
+
onSome: (node2) => {
|
|
758
|
+
this._graph.addNodes([
|
|
759
|
+
node2
|
|
760
|
+
]);
|
|
761
|
+
trigger?.wake();
|
|
762
|
+
},
|
|
763
|
+
onNone: () => {
|
|
764
|
+
trigger?.wake();
|
|
765
|
+
this._graph.removeNodes([
|
|
766
|
+
id
|
|
767
|
+
]);
|
|
768
|
+
}
|
|
769
|
+
});
|
|
770
|
+
}, {
|
|
771
|
+
immediate: true
|
|
772
|
+
});
|
|
773
|
+
this._subscriptions.set(id, cancel);
|
|
731
774
|
}
|
|
732
|
-
// TODO(wittjosiah): On initialize to restore state from cache.
|
|
733
|
-
// private async _onInitialize(id: string) {
|
|
734
|
-
// log('onInitialize', { id });
|
|
735
|
-
// }
|
|
736
775
|
_onRemoveNode(id) {
|
|
737
|
-
this.
|
|
738
|
-
this.
|
|
776
|
+
this._subscriptions.get(id)?.();
|
|
777
|
+
this._subscriptions.delete(id);
|
|
778
|
+
}
|
|
779
|
+
constructor({ registry, ...params } = {}) {
|
|
780
|
+
_define_property2(this, "_subscriptions", /* @__PURE__ */ new Map());
|
|
781
|
+
_define_property2(this, "_extensions", Rx2.make(Record2.empty()).pipe(Rx2.keepAlive, Rx2.withLabel("graph-builder:extensions")));
|
|
782
|
+
_define_property2(this, "_initialized", {});
|
|
783
|
+
_define_property2(this, "_registry", void 0);
|
|
784
|
+
_define_property2(this, "_graph", void 0);
|
|
785
|
+
_define_property2(this, "_resolvers", Rx2.family((id) => {
|
|
786
|
+
return Rx2.make((get) => {
|
|
787
|
+
return pipe2(get(this._extensions), Record2.values, Array.sortBy(byPosition), Array.map(({ resolver }) => resolver), Array.filter(isNonNullable2), Array.map((resolver) => get(resolver(id))), Array.filter(isNonNullable2), Array.head);
|
|
788
|
+
});
|
|
789
|
+
}));
|
|
790
|
+
_define_property2(this, "_connectors", Rx2.family((key) => {
|
|
791
|
+
return Rx2.make((get) => {
|
|
792
|
+
const [id, relation] = key.split("+");
|
|
793
|
+
const node = this._graph.node(id);
|
|
794
|
+
return pipe2(
|
|
795
|
+
get(this._extensions),
|
|
796
|
+
Record2.values,
|
|
797
|
+
// TODO(wittjosiah): Sort on write rather than read.
|
|
798
|
+
Array.sortBy(byPosition),
|
|
799
|
+
Array.filter(({ relation: _relation = "outbound" }) => _relation === relation),
|
|
800
|
+
Array.map(({ connector }) => connector?.(node)),
|
|
801
|
+
Array.filter(isNonNullable2),
|
|
802
|
+
Array.flatMap((result) => get(result))
|
|
803
|
+
);
|
|
804
|
+
}).pipe(Rx2.withLabel(`graph-builder:connectors:${key}`));
|
|
805
|
+
}));
|
|
806
|
+
this._registry = registry ?? Registry2.make();
|
|
807
|
+
this._graph = new Graph({
|
|
808
|
+
...params,
|
|
809
|
+
registry: this._registry,
|
|
810
|
+
onExpand: (id, relation) => this._onExpand(id, relation),
|
|
811
|
+
onInitialize: (id) => this._onInitialize(id),
|
|
812
|
+
onRemoveNode: (id) => this._onRemoveNode(id)
|
|
813
|
+
});
|
|
739
814
|
}
|
|
740
815
|
};
|
|
741
816
|
var rxFromSignal = (cb) => {
|