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