@dxos/app-graph 0.8.4-main.b97322e → 0.8.4-main.c4373fc
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 +253 -173
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +253 -173
- 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 +7 -3
- 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 -10
- package/dist/types/src/stories/EchoGraph.stories.d.ts.map +1 -1
- package/dist/types/src/testing.d.ts +1 -1
- package/dist/types/src/testing.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +31 -31
- package/src/graph-builder.test.ts +67 -9
- package/src/graph-builder.ts +69 -22
- package/src/graph.test.ts +2 -2
- package/src/graph.ts +19 -18
- package/src/node.ts +1 -1
- package/src/signals-integration.test.ts +7 -7
- package/src/stories/EchoGraph.stories.tsx +22 -20
- package/src/testing.ts +1 -1
|
@@ -1,18 +1,33 @@
|
|
|
1
1
|
// src/graph.ts
|
|
2
2
|
import { Registry, Rx } from "@effect-rx/rx-react";
|
|
3
|
-
import
|
|
3
|
+
import * as Function from "effect/Function";
|
|
4
|
+
import * as Option from "effect/Option";
|
|
5
|
+
import * as Record from "effect/Record";
|
|
4
6
|
import { Event, Trigger } from "@dxos/async";
|
|
5
7
|
import { todo } from "@dxos/debug";
|
|
6
8
|
import { invariant } from "@dxos/invariant";
|
|
7
9
|
import { log } from "@dxos/log";
|
|
8
10
|
import { isNonNullable } from "@dxos/util";
|
|
11
|
+
function _define_property(obj, key, value) {
|
|
12
|
+
if (key in obj) {
|
|
13
|
+
Object.defineProperty(obj, key, {
|
|
14
|
+
value,
|
|
15
|
+
enumerable: true,
|
|
16
|
+
configurable: true,
|
|
17
|
+
writable: true
|
|
18
|
+
});
|
|
19
|
+
} else {
|
|
20
|
+
obj[key] = value;
|
|
21
|
+
}
|
|
22
|
+
return obj;
|
|
23
|
+
}
|
|
9
24
|
var __dxlog_file = "/__w/dxos/dxos/packages/sdk/app-graph/src/graph.ts";
|
|
10
25
|
var graphSymbol = Symbol("graph");
|
|
11
26
|
var getGraph = (node) => {
|
|
12
27
|
const graph = node[graphSymbol];
|
|
13
28
|
invariant(graph, "Node is not associated with a graph.", {
|
|
14
29
|
F: __dxlog_file,
|
|
15
|
-
L:
|
|
30
|
+
L: 27,
|
|
16
31
|
S: void 0,
|
|
17
32
|
A: [
|
|
18
33
|
"graph",
|
|
@@ -26,103 +41,6 @@ var ROOT_TYPE = "dxos.org/type/GraphRoot";
|
|
|
26
41
|
var ACTION_TYPE = "dxos.org/type/GraphAction";
|
|
27
42
|
var ACTION_GROUP_TYPE = "dxos.org/type/GraphActionGroup";
|
|
28
43
|
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
44
|
toJSON(id = ROOT_ID) {
|
|
127
45
|
return this._registry.get(this._json(id));
|
|
128
46
|
}
|
|
@@ -162,15 +80,22 @@ var Graph = class {
|
|
|
162
80
|
getEdges(id) {
|
|
163
81
|
return this._registry.get(this.edges(id));
|
|
164
82
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
83
|
+
async initialize(id) {
|
|
84
|
+
const initialized = Record.get(this._initialized, id).pipe(Option.getOrElse(() => false));
|
|
85
|
+
log("initialize", {
|
|
86
|
+
id,
|
|
87
|
+
initialized
|
|
88
|
+
}, {
|
|
89
|
+
F: __dxlog_file,
|
|
90
|
+
L: 386,
|
|
91
|
+
S: this,
|
|
92
|
+
C: (f, a) => f(...a)
|
|
93
|
+
});
|
|
94
|
+
if (!initialized) {
|
|
95
|
+
await this._onInitialize?.(id);
|
|
96
|
+
Record.set(this._initialized, id, true);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
174
99
|
expand(id, relation = "outbound") {
|
|
175
100
|
const key = `${id}$${relation}`;
|
|
176
101
|
const expanded = Record.get(this._expanded, key).pipe(Option.getOrElse(() => false));
|
|
@@ -179,7 +104,7 @@ var Graph = class {
|
|
|
179
104
|
expanded
|
|
180
105
|
}, {
|
|
181
106
|
F: __dxlog_file,
|
|
182
|
-
L:
|
|
107
|
+
L: 396,
|
|
183
108
|
S: this,
|
|
184
109
|
C: (f, a) => f(...a)
|
|
185
110
|
});
|
|
@@ -209,7 +134,7 @@ var Graph = class {
|
|
|
209
134
|
propertiesChanged
|
|
210
135
|
}, {
|
|
211
136
|
F: __dxlog_file,
|
|
212
|
-
L:
|
|
137
|
+
L: 418,
|
|
213
138
|
S: this,
|
|
214
139
|
C: (f, a) => f(...a)
|
|
215
140
|
});
|
|
@@ -221,7 +146,7 @@ var Graph = class {
|
|
|
221
146
|
properties
|
|
222
147
|
}, {
|
|
223
148
|
F: __dxlog_file,
|
|
224
|
-
L:
|
|
149
|
+
L: 420,
|
|
225
150
|
S: this,
|
|
226
151
|
C: (f, a) => f(...a)
|
|
227
152
|
});
|
|
@@ -249,7 +174,7 @@ var Graph = class {
|
|
|
249
174
|
properties
|
|
250
175
|
}, {
|
|
251
176
|
F: __dxlog_file,
|
|
252
|
-
L:
|
|
177
|
+
L: 427,
|
|
253
178
|
S: this,
|
|
254
179
|
C: (f, a) => f(...a)
|
|
255
180
|
});
|
|
@@ -320,7 +245,7 @@ var Graph = class {
|
|
|
320
245
|
target: edgeArg.target
|
|
321
246
|
}, {
|
|
322
247
|
F: __dxlog_file,
|
|
323
|
-
L:
|
|
248
|
+
L: 482,
|
|
324
249
|
S: this,
|
|
325
250
|
C: (f, a) => f(...a)
|
|
326
251
|
});
|
|
@@ -340,7 +265,7 @@ var Graph = class {
|
|
|
340
265
|
target: edgeArg.target
|
|
341
266
|
}, {
|
|
342
267
|
F: __dxlog_file,
|
|
343
|
-
L:
|
|
268
|
+
L: 489,
|
|
344
269
|
S: this,
|
|
345
270
|
C: (f, a) => f(...a)
|
|
346
271
|
});
|
|
@@ -423,7 +348,7 @@ var Graph = class {
|
|
|
423
348
|
]));
|
|
424
349
|
}
|
|
425
350
|
getPath({ source = "root", target }) {
|
|
426
|
-
return pipe(this.getNode(source), Option.flatMap((node) => {
|
|
351
|
+
return Function.pipe(this.getNode(source), Option.flatMap((node) => {
|
|
427
352
|
let found = Option.none();
|
|
428
353
|
this.traverse({
|
|
429
354
|
source: node.id,
|
|
@@ -464,12 +389,114 @@ var Graph = class {
|
|
|
464
389
|
...node
|
|
465
390
|
});
|
|
466
391
|
}
|
|
392
|
+
constructor({ registry, nodes, edges, onInitialize, onExpand, onRemoveNode } = {}) {
|
|
393
|
+
_define_property(this, "onNodeChanged", new Event());
|
|
394
|
+
_define_property(this, "_onExpand", void 0);
|
|
395
|
+
_define_property(this, "_onInitialize", void 0);
|
|
396
|
+
_define_property(this, "_onRemoveNode", void 0);
|
|
397
|
+
_define_property(this, "_registry", void 0);
|
|
398
|
+
_define_property(this, "_expanded", Record.empty());
|
|
399
|
+
_define_property(this, "_initialized", Record.empty());
|
|
400
|
+
_define_property(this, "_initialEdges", Record.empty());
|
|
401
|
+
_define_property(this, "_initialNodes", Record.fromEntries([
|
|
402
|
+
[
|
|
403
|
+
ROOT_ID,
|
|
404
|
+
this._constructNode({
|
|
405
|
+
id: ROOT_ID,
|
|
406
|
+
type: ROOT_TYPE,
|
|
407
|
+
data: null,
|
|
408
|
+
properties: {}
|
|
409
|
+
})
|
|
410
|
+
]
|
|
411
|
+
]));
|
|
412
|
+
_define_property(this, "_node", Rx.family((id) => {
|
|
413
|
+
const initial = Option.flatten(Record.get(this._initialNodes, id));
|
|
414
|
+
return Rx.make(initial).pipe(Rx.keepAlive, Rx.withLabel(`graph:node:${id}`));
|
|
415
|
+
}));
|
|
416
|
+
_define_property(this, "_nodeOrThrow", Rx.family((id) => {
|
|
417
|
+
return Rx.make((get2) => {
|
|
418
|
+
const node = get2(this._node(id));
|
|
419
|
+
invariant(Option.isSome(node), `Node not available: ${id}`, {
|
|
420
|
+
F: __dxlog_file,
|
|
421
|
+
L: 254,
|
|
422
|
+
S: this,
|
|
423
|
+
A: [
|
|
424
|
+
"Option.isSome(node)",
|
|
425
|
+
"`Node not available: ${id}`"
|
|
426
|
+
]
|
|
427
|
+
});
|
|
428
|
+
return node.value;
|
|
429
|
+
});
|
|
430
|
+
}));
|
|
431
|
+
_define_property(this, "_edges", Rx.family((id) => {
|
|
432
|
+
const initial = Record.get(this._initialEdges, id).pipe(Option.getOrElse(() => ({
|
|
433
|
+
inbound: [],
|
|
434
|
+
outbound: []
|
|
435
|
+
})));
|
|
436
|
+
return Rx.make(initial).pipe(Rx.keepAlive, Rx.withLabel(`graph:edges:${id}`));
|
|
437
|
+
}));
|
|
438
|
+
_define_property(this, "_connections", Rx.family((key) => {
|
|
439
|
+
return Rx.make((get2) => {
|
|
440
|
+
const [id, relation] = key.split("$");
|
|
441
|
+
const edges2 = get2(this._edges(id));
|
|
442
|
+
return edges2[relation].map((id2) => get2(this._node(id2))).filter(Option.isSome).map((o) => o.value);
|
|
443
|
+
}).pipe(Rx.withLabel(`graph:connections:${key}`));
|
|
444
|
+
}));
|
|
445
|
+
_define_property(this, "_actions", Rx.family((id) => {
|
|
446
|
+
return Rx.make((get2) => {
|
|
447
|
+
return get2(this._connections(`${id}$outbound`)).filter((node) => node.type === ACTION_TYPE || node.type === ACTION_GROUP_TYPE);
|
|
448
|
+
}).pipe(Rx.withLabel(`graph:actions:${id}`));
|
|
449
|
+
}));
|
|
450
|
+
_define_property(this, "_json", Rx.family((id) => {
|
|
451
|
+
return Rx.make((get2) => {
|
|
452
|
+
const toJSON = (node, seen = []) => {
|
|
453
|
+
const nodes2 = get2(this.connections(node.id));
|
|
454
|
+
const obj = {
|
|
455
|
+
id: node.id.length > 32 ? `${node.id.slice(0, 32)}...` : node.id,
|
|
456
|
+
type: node.type
|
|
457
|
+
};
|
|
458
|
+
if (node.properties.label) {
|
|
459
|
+
obj.label = node.properties.label;
|
|
460
|
+
}
|
|
461
|
+
if (nodes2.length) {
|
|
462
|
+
obj.nodes = nodes2.map((n) => {
|
|
463
|
+
const nextSeen = [
|
|
464
|
+
...seen,
|
|
465
|
+
node.id
|
|
466
|
+
];
|
|
467
|
+
return nextSeen.includes(n.id) ? void 0 : toJSON(n, nextSeen);
|
|
468
|
+
}).filter(isNonNullable);
|
|
469
|
+
}
|
|
470
|
+
return obj;
|
|
471
|
+
};
|
|
472
|
+
const root = get2(this.nodeOrThrow(id));
|
|
473
|
+
return toJSON(root);
|
|
474
|
+
}).pipe(Rx.withLabel(`graph:json:${id}`));
|
|
475
|
+
}));
|
|
476
|
+
this._registry = registry ?? Registry.make();
|
|
477
|
+
this._onInitialize = onInitialize;
|
|
478
|
+
this._onExpand = onExpand;
|
|
479
|
+
this._onRemoveNode = onRemoveNode;
|
|
480
|
+
if (nodes) {
|
|
481
|
+
nodes.forEach((node) => {
|
|
482
|
+
Record.set(this._initialNodes, node.id, this._constructNode(node));
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
if (edges) {
|
|
486
|
+
Object.entries(edges).forEach(([source, edges2]) => {
|
|
487
|
+
Record.set(this._initialEdges, source, edges2);
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
}
|
|
467
491
|
};
|
|
468
492
|
|
|
469
493
|
// src/graph-builder.ts
|
|
470
494
|
import { Registry as Registry2, Rx as Rx2 } from "@effect-rx/rx-react";
|
|
471
495
|
import { effect } from "@preact/signals-core";
|
|
472
|
-
import
|
|
496
|
+
import * as Array from "effect/Array";
|
|
497
|
+
import * as Function2 from "effect/Function";
|
|
498
|
+
import * as Option2 from "effect/Option";
|
|
499
|
+
import * as Record2 from "effect/Record";
|
|
473
500
|
import { log as log2 } from "@dxos/log";
|
|
474
501
|
import { byPosition, getDebugName, isNode, isNonNullable as isNonNullable2 } from "@dxos/util";
|
|
475
502
|
|
|
@@ -481,29 +508,47 @@ var isActionGroup = (data) => isGraphNode(data) ? data.data === actionGroupSymbo
|
|
|
481
508
|
var isActionLike = (data) => isAction(data) || isActionGroup(data);
|
|
482
509
|
|
|
483
510
|
// src/graph-builder.ts
|
|
511
|
+
function _define_property2(obj, key, value) {
|
|
512
|
+
if (key in obj) {
|
|
513
|
+
Object.defineProperty(obj, key, {
|
|
514
|
+
value,
|
|
515
|
+
enumerable: true,
|
|
516
|
+
configurable: true,
|
|
517
|
+
writable: true
|
|
518
|
+
});
|
|
519
|
+
} else {
|
|
520
|
+
obj[key] = value;
|
|
521
|
+
}
|
|
522
|
+
return obj;
|
|
523
|
+
}
|
|
484
524
|
var __dxlog_file2 = "/__w/dxos/dxos/packages/sdk/app-graph/src/graph-builder.ts";
|
|
485
525
|
var createExtension = (extension) => {
|
|
486
|
-
const { id, position = "static", relation = "outbound", connector: _connector, actions: _actions, actionGroups: _actionGroups } = extension;
|
|
526
|
+
const { id, position = "static", relation = "outbound", resolver: _resolver, connector: _connector, actions: _actions, actionGroups: _actionGroups } = extension;
|
|
487
527
|
const getId = (key) => `${id}/${key}`;
|
|
528
|
+
const resolver = _resolver && Rx2.family((id2) => _resolver(id2).pipe(Rx2.withLabel(`graph-builder:_resolver:${id2}`)));
|
|
488
529
|
const connector = _connector && Rx2.family((node) => _connector(node).pipe(Rx2.withLabel(`graph-builder:_connector:${id}`)));
|
|
489
530
|
const actionGroups = _actionGroups && Rx2.family((node) => _actionGroups(node).pipe(Rx2.withLabel(`graph-builder:_actionGroups:${id}`)));
|
|
490
531
|
const actions = _actions && Rx2.family((node) => _actions(node).pipe(Rx2.withLabel(`graph-builder:_actions:${id}`)));
|
|
491
532
|
return [
|
|
492
|
-
|
|
533
|
+
resolver ? {
|
|
534
|
+
id: getId("resolver"),
|
|
535
|
+
position,
|
|
536
|
+
resolver
|
|
537
|
+
} : void 0,
|
|
493
538
|
connector ? {
|
|
494
539
|
id: getId("connector"),
|
|
495
540
|
position,
|
|
496
541
|
relation,
|
|
497
|
-
connector: Rx2.family((node) => Rx2.make((
|
|
542
|
+
connector: Rx2.family((node) => Rx2.make((get2) => {
|
|
498
543
|
try {
|
|
499
|
-
return
|
|
544
|
+
return get2(connector(node));
|
|
500
545
|
} catch {
|
|
501
546
|
log2.warn("Error in connector", {
|
|
502
547
|
id: getId("connector"),
|
|
503
548
|
node
|
|
504
549
|
}, {
|
|
505
550
|
F: __dxlog_file2,
|
|
506
|
-
L:
|
|
551
|
+
L: 112,
|
|
507
552
|
S: void 0,
|
|
508
553
|
C: (f, a) => f(...a)
|
|
509
554
|
});
|
|
@@ -515,9 +560,9 @@ var createExtension = (extension) => {
|
|
|
515
560
|
id: getId("actionGroups"),
|
|
516
561
|
position,
|
|
517
562
|
relation: "outbound",
|
|
518
|
-
connector: Rx2.family((node) => Rx2.make((
|
|
563
|
+
connector: Rx2.family((node) => Rx2.make((get2) => {
|
|
519
564
|
try {
|
|
520
|
-
return
|
|
565
|
+
return get2(actionGroups(node)).map((arg) => ({
|
|
521
566
|
...arg,
|
|
522
567
|
data: actionGroupSymbol,
|
|
523
568
|
type: ACTION_GROUP_TYPE
|
|
@@ -528,7 +573,7 @@ var createExtension = (extension) => {
|
|
|
528
573
|
node
|
|
529
574
|
}, {
|
|
530
575
|
F: __dxlog_file2,
|
|
531
|
-
L:
|
|
576
|
+
L: 133,
|
|
532
577
|
S: void 0,
|
|
533
578
|
C: (f, a) => f(...a)
|
|
534
579
|
});
|
|
@@ -540,9 +585,9 @@ var createExtension = (extension) => {
|
|
|
540
585
|
id: getId("actions"),
|
|
541
586
|
position,
|
|
542
587
|
relation: "outbound",
|
|
543
|
-
connector: Rx2.family((node) => Rx2.make((
|
|
588
|
+
connector: Rx2.family((node) => Rx2.make((get2) => {
|
|
544
589
|
try {
|
|
545
|
-
return
|
|
590
|
+
return get2(actions(node)).map((arg) => ({
|
|
546
591
|
...arg,
|
|
547
592
|
type: ACTION_TYPE
|
|
548
593
|
}));
|
|
@@ -552,7 +597,7 @@ var createExtension = (extension) => {
|
|
|
552
597
|
node
|
|
553
598
|
}, {
|
|
554
599
|
F: __dxlog_file2,
|
|
555
|
-
L:
|
|
600
|
+
L: 150,
|
|
556
601
|
S: void 0,
|
|
557
602
|
C: (f, a) => f(...a)
|
|
558
603
|
});
|
|
@@ -576,35 +621,6 @@ var flattenExtensions = (extension, acc = []) => {
|
|
|
576
621
|
}
|
|
577
622
|
};
|
|
578
623
|
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
624
|
static from(pickle, registry) {
|
|
609
625
|
if (!pickle) {
|
|
610
626
|
return new _GraphBuilder({
|
|
@@ -671,8 +687,8 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
671
687
|
}
|
|
672
688
|
}
|
|
673
689
|
destroy() {
|
|
674
|
-
this.
|
|
675
|
-
this.
|
|
690
|
+
this._subscriptions.forEach((unsubscribe) => unsubscribe());
|
|
691
|
+
this._subscriptions.clear();
|
|
676
692
|
}
|
|
677
693
|
_onExpand(id, relation) {
|
|
678
694
|
log2("onExpand", {
|
|
@@ -681,7 +697,7 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
681
697
|
registry: getDebugName(this._registry)
|
|
682
698
|
}, {
|
|
683
699
|
F: __dxlog_file2,
|
|
684
|
-
L:
|
|
700
|
+
L: 327,
|
|
685
701
|
S: this,
|
|
686
702
|
C: (f, a) => f(...a)
|
|
687
703
|
});
|
|
@@ -698,7 +714,7 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
698
714
|
removed
|
|
699
715
|
}, {
|
|
700
716
|
F: __dxlog_file2,
|
|
701
|
-
L:
|
|
717
|
+
L: 338,
|
|
702
718
|
S: this,
|
|
703
719
|
C: (f, a) => f(...a)
|
|
704
720
|
});
|
|
@@ -727,30 +743,94 @@ var GraphBuilder = class _GraphBuilder {
|
|
|
727
743
|
}, {
|
|
728
744
|
immediate: true
|
|
729
745
|
});
|
|
730
|
-
this.
|
|
746
|
+
this._subscriptions.set(id, cancel);
|
|
747
|
+
}
|
|
748
|
+
// TODO(wittjosiah): If the same node is added by a connector, the resolver should probably cancel itself?
|
|
749
|
+
async _onInitialize(id) {
|
|
750
|
+
log2("onInitialize", {
|
|
751
|
+
id
|
|
752
|
+
}, {
|
|
753
|
+
F: __dxlog_file2,
|
|
754
|
+
L: 375,
|
|
755
|
+
S: this,
|
|
756
|
+
C: (f, a) => f(...a)
|
|
757
|
+
});
|
|
758
|
+
const resolver = this._resolvers(id);
|
|
759
|
+
const cancel = this._registry.subscribe(resolver, (node) => {
|
|
760
|
+
const trigger = this._initialized[id];
|
|
761
|
+
Option2.match(node, {
|
|
762
|
+
onSome: (node2) => {
|
|
763
|
+
this._graph.addNodes([
|
|
764
|
+
node2
|
|
765
|
+
]);
|
|
766
|
+
trigger?.wake();
|
|
767
|
+
},
|
|
768
|
+
onNone: () => {
|
|
769
|
+
trigger?.wake();
|
|
770
|
+
this._graph.removeNodes([
|
|
771
|
+
id
|
|
772
|
+
]);
|
|
773
|
+
}
|
|
774
|
+
});
|
|
775
|
+
}, {
|
|
776
|
+
immediate: true
|
|
777
|
+
});
|
|
778
|
+
this._subscriptions.set(id, cancel);
|
|
731
779
|
}
|
|
732
|
-
// TODO(wittjosiah): On initialize to restore state from cache.
|
|
733
|
-
// private async _onInitialize(id: string) {
|
|
734
|
-
// log('onInitialize', { id });
|
|
735
|
-
// }
|
|
736
780
|
_onRemoveNode(id) {
|
|
737
|
-
this.
|
|
738
|
-
this.
|
|
781
|
+
this._subscriptions.get(id)?.();
|
|
782
|
+
this._subscriptions.delete(id);
|
|
783
|
+
}
|
|
784
|
+
constructor({ registry, ...params } = {}) {
|
|
785
|
+
_define_property2(this, "_subscriptions", /* @__PURE__ */ new Map());
|
|
786
|
+
_define_property2(this, "_extensions", Rx2.make(Record2.empty()).pipe(Rx2.keepAlive, Rx2.withLabel("graph-builder:extensions")));
|
|
787
|
+
_define_property2(this, "_initialized", {});
|
|
788
|
+
_define_property2(this, "_registry", void 0);
|
|
789
|
+
_define_property2(this, "_graph", void 0);
|
|
790
|
+
_define_property2(this, "_resolvers", Rx2.family((id) => {
|
|
791
|
+
return Rx2.make((get2) => {
|
|
792
|
+
return Function2.pipe(get2(this._extensions), Record2.values, Array.sortBy(byPosition), Array.map(({ resolver }) => resolver), Array.filter(isNonNullable2), Array.map((resolver) => get2(resolver(id))), Array.filter(isNonNullable2), Array.head);
|
|
793
|
+
});
|
|
794
|
+
}));
|
|
795
|
+
_define_property2(this, "_connectors", Rx2.family((key) => {
|
|
796
|
+
return Rx2.make((get2) => {
|
|
797
|
+
const [id, relation] = key.split("+");
|
|
798
|
+
const node = this._graph.node(id);
|
|
799
|
+
return Function2.pipe(
|
|
800
|
+
get2(this._extensions),
|
|
801
|
+
Record2.values,
|
|
802
|
+
// TODO(wittjosiah): Sort on write rather than read.
|
|
803
|
+
Array.sortBy(byPosition),
|
|
804
|
+
Array.filter(({ relation: _relation = "outbound" }) => _relation === relation),
|
|
805
|
+
Array.map(({ connector }) => connector?.(node)),
|
|
806
|
+
Array.filter(isNonNullable2),
|
|
807
|
+
Array.flatMap((result) => get2(result))
|
|
808
|
+
);
|
|
809
|
+
}).pipe(Rx2.withLabel(`graph-builder:connectors:${key}`));
|
|
810
|
+
}));
|
|
811
|
+
this._registry = registry ?? Registry2.make();
|
|
812
|
+
this._graph = new Graph({
|
|
813
|
+
...params,
|
|
814
|
+
registry: this._registry,
|
|
815
|
+
onExpand: (id, relation) => this._onExpand(id, relation),
|
|
816
|
+
onInitialize: (id) => this._onInitialize(id),
|
|
817
|
+
onRemoveNode: (id) => this._onRemoveNode(id)
|
|
818
|
+
});
|
|
739
819
|
}
|
|
740
820
|
};
|
|
741
821
|
var rxFromSignal = (cb) => {
|
|
742
|
-
return Rx2.make((
|
|
822
|
+
return Rx2.make((get2) => {
|
|
743
823
|
const dispose = effect(() => {
|
|
744
|
-
|
|
824
|
+
get2.setSelf(cb());
|
|
745
825
|
});
|
|
746
|
-
|
|
826
|
+
get2.addFinalizer(() => dispose());
|
|
747
827
|
return cb();
|
|
748
828
|
});
|
|
749
829
|
};
|
|
750
830
|
var observableFamily = Rx2.family((observable) => {
|
|
751
|
-
return Rx2.make((
|
|
752
|
-
const subscription = observable.subscribe((value) =>
|
|
753
|
-
|
|
831
|
+
return Rx2.make((get2) => {
|
|
832
|
+
const subscription = observable.subscribe((value) => get2.setSelf(value));
|
|
833
|
+
get2.addFinalizer(() => subscription.unsubscribe());
|
|
754
834
|
return observable.get();
|
|
755
835
|
});
|
|
756
836
|
});
|