@dxos/app-graph 0.8.4-main.a4bbb77 → 0.8.4-main.ae835ea

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.
@@ -1,31 +1,20 @@
1
1
  // src/graph.ts
2
2
  import { Registry, Rx } from "@effect-rx/rx-react";
3
- import { Option, Record, pipe } from "effect";
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";
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
- }
22
11
  var __dxlog_file = "/__w/dxos/dxos/packages/sdk/app-graph/src/graph.ts";
23
12
  var graphSymbol = Symbol("graph");
24
13
  var getGraph = (node) => {
25
14
  const graph = node[graphSymbol];
26
15
  invariant(graph, "Node is not associated with a graph.", {
27
16
  F: __dxlog_file,
28
- L: 25,
17
+ L: 27,
29
18
  S: void 0,
30
19
  A: [
31
20
  "graph",
@@ -39,6 +28,108 @@ var ROOT_TYPE = "dxos.org/type/GraphRoot";
39
28
  var ACTION_TYPE = "dxos.org/type/GraphAction";
40
29
  var ACTION_GROUP_TYPE = "dxos.org/type/GraphActionGroup";
41
30
  var Graph = class {
31
+ onNodeChanged = new Event();
32
+ _onExpand;
33
+ _onInitialize;
34
+ _onRemoveNode;
35
+ _registry;
36
+ _expanded = Record.empty();
37
+ _initialized = Record.empty();
38
+ _initialEdges = Record.empty();
39
+ _initialNodes = Record.fromEntries([
40
+ [
41
+ ROOT_ID,
42
+ this._constructNode({
43
+ id: ROOT_ID,
44
+ type: ROOT_TYPE,
45
+ data: null,
46
+ properties: {}
47
+ })
48
+ ]
49
+ ]);
50
+ /** @internal */
51
+ _node = Rx.family((id) => {
52
+ const initial = Option.flatten(Record.get(this._initialNodes, id));
53
+ return Rx.make(initial).pipe(Rx.keepAlive, Rx.withLabel(`graph:node:${id}`));
54
+ });
55
+ _nodeOrThrow = Rx.family((id) => {
56
+ return Rx.make((get2) => {
57
+ const node = get2(this._node(id));
58
+ invariant(Option.isSome(node), `Node not available: ${id}`, {
59
+ F: __dxlog_file,
60
+ L: 254,
61
+ S: this,
62
+ A: [
63
+ "Option.isSome(node)",
64
+ "`Node not available: ${id}`"
65
+ ]
66
+ });
67
+ return node.value;
68
+ });
69
+ });
70
+ _edges = Rx.family((id) => {
71
+ const initial = Record.get(this._initialEdges, id).pipe(Option.getOrElse(() => ({
72
+ inbound: [],
73
+ outbound: []
74
+ })));
75
+ return Rx.make(initial).pipe(Rx.keepAlive, Rx.withLabel(`graph:edges:${id}`));
76
+ });
77
+ // NOTE: Currently the argument to the family needs to be referentially stable for the rx to be referentially stable.
78
+ // TODO(wittjosiah): Rx feature request, support for something akin to `ComplexMap` to allow for complex arguments.
79
+ _connections = Rx.family((key) => {
80
+ return Rx.make((get2) => {
81
+ const [id, relation] = key.split("$");
82
+ const edges = get2(this._edges(id));
83
+ return edges[relation].map((id2) => get2(this._node(id2))).filter(Option.isSome).map((o) => o.value);
84
+ }).pipe(Rx.withLabel(`graph:connections:${key}`));
85
+ });
86
+ _actions = Rx.family((id) => {
87
+ return Rx.make((get2) => {
88
+ return get2(this._connections(`${id}$outbound`)).filter((node) => node.type === ACTION_TYPE || node.type === ACTION_GROUP_TYPE);
89
+ }).pipe(Rx.withLabel(`graph:actions:${id}`));
90
+ });
91
+ _json = Rx.family((id) => {
92
+ return Rx.make((get2) => {
93
+ const toJSON = (node, seen = []) => {
94
+ const nodes = get2(this.connections(node.id));
95
+ const obj = {
96
+ id: node.id,
97
+ type: node.type
98
+ };
99
+ if (node.properties.label) {
100
+ obj.label = node.properties.label;
101
+ }
102
+ if (nodes.length) {
103
+ obj.nodes = nodes.map((n) => {
104
+ const nextSeen = [
105
+ ...seen,
106
+ node.id
107
+ ];
108
+ return nextSeen.includes(n.id) ? void 0 : toJSON(n, nextSeen);
109
+ }).filter(isNonNullable);
110
+ }
111
+ return obj;
112
+ };
113
+ const root = get2(this.nodeOrThrow(id));
114
+ return toJSON(root);
115
+ }).pipe(Rx.withLabel(`graph:json:${id}`));
116
+ });
117
+ constructor({ registry, nodes, edges, onInitialize, onExpand, onRemoveNode } = {}) {
118
+ this._registry = registry ?? Registry.make();
119
+ this._onInitialize = onInitialize;
120
+ this._onExpand = onExpand;
121
+ this._onRemoveNode = onRemoveNode;
122
+ if (nodes) {
123
+ nodes.forEach((node) => {
124
+ Record.set(this._initialNodes, node.id, this._constructNode(node));
125
+ });
126
+ }
127
+ if (edges) {
128
+ Object.entries(edges).forEach(([source, edges2]) => {
129
+ Record.set(this._initialEdges, source, edges2);
130
+ });
131
+ }
132
+ }
42
133
  toJSON(id = ROOT_ID) {
43
134
  return this._registry.get(this._json(id));
44
135
  }
@@ -85,7 +176,7 @@ var Graph = class {
85
176
  initialized
86
177
  }, {
87
178
  F: __dxlog_file,
88
- L: 384,
179
+ L: 386,
89
180
  S: this,
90
181
  C: (f, a) => f(...a)
91
182
  });
@@ -102,7 +193,7 @@ var Graph = class {
102
193
  expanded
103
194
  }, {
104
195
  F: __dxlog_file,
105
- L: 394,
196
+ L: 396,
106
197
  S: this,
107
198
  C: (f, a) => f(...a)
108
199
  });
@@ -132,7 +223,7 @@ var Graph = class {
132
223
  propertiesChanged
133
224
  }, {
134
225
  F: __dxlog_file,
135
- L: 416,
226
+ L: 418,
136
227
  S: this,
137
228
  C: (f, a) => f(...a)
138
229
  });
@@ -144,7 +235,7 @@ var Graph = class {
144
235
  properties
145
236
  }, {
146
237
  F: __dxlog_file,
147
- L: 418,
238
+ L: 420,
148
239
  S: this,
149
240
  C: (f, a) => f(...a)
150
241
  });
@@ -172,7 +263,7 @@ var Graph = class {
172
263
  properties
173
264
  }, {
174
265
  F: __dxlog_file,
175
- L: 425,
266
+ L: 427,
176
267
  S: this,
177
268
  C: (f, a) => f(...a)
178
269
  });
@@ -243,7 +334,7 @@ var Graph = class {
243
334
  target: edgeArg.target
244
335
  }, {
245
336
  F: __dxlog_file,
246
- L: 480,
337
+ L: 482,
247
338
  S: this,
248
339
  C: (f, a) => f(...a)
249
340
  });
@@ -263,7 +354,7 @@ var Graph = class {
263
354
  target: edgeArg.target
264
355
  }, {
265
356
  F: __dxlog_file,
266
- L: 487,
357
+ L: 489,
267
358
  S: this,
268
359
  C: (f, a) => f(...a)
269
360
  });
@@ -346,7 +437,7 @@ var Graph = class {
346
437
  ]));
347
438
  }
348
439
  getPath({ source = "root", target }) {
349
- return pipe(this.getNode(source), Option.flatMap((node) => {
440
+ return Function.pipe(this.getNode(source), Option.flatMap((node) => {
350
441
  let found = Option.none();
351
442
  this.traverse({
352
443
  source: node.id,
@@ -387,111 +478,15 @@ var Graph = class {
387
478
  ...node
388
479
  });
389
480
  }
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
- }
489
481
  };
490
482
 
491
483
  // src/graph-builder.ts
492
484
  import { Registry as Registry2, Rx as Rx2 } from "@effect-rx/rx-react";
493
485
  import { effect } from "@preact/signals-core";
494
- import { Array, Option as Option2, Record as Record2, pipe as pipe2 } from "effect";
486
+ import * as Array from "effect/Array";
487
+ import * as Function2 from "effect/Function";
488
+ import * as Option2 from "effect/Option";
489
+ import * as Record2 from "effect/Record";
495
490
  import { log as log2 } from "@dxos/log";
496
491
  import { byPosition, getDebugName, isNode, isNonNullable as isNonNullable2 } from "@dxos/util";
497
492
 
@@ -503,19 +498,6 @@ var isActionGroup = (data) => isGraphNode(data) ? data.data === actionGroupSymbo
503
498
  var isActionLike = (data) => isAction(data) || isActionGroup(data);
504
499
 
505
500
  // 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
- }
519
501
  var __dxlog_file2 = "/__w/dxos/dxos/packages/sdk/app-graph/src/graph-builder.ts";
520
502
  var createExtension = (extension) => {
521
503
  const { id, position = "static", relation = "outbound", resolver: _resolver, connector: _connector, actions: _actions, actionGroups: _actionGroups } = extension;
@@ -534,16 +516,16 @@ var createExtension = (extension) => {
534
516
  id: getId("connector"),
535
517
  position,
536
518
  relation,
537
- connector: Rx2.family((node) => Rx2.make((get) => {
519
+ connector: Rx2.family((node) => Rx2.make((get2) => {
538
520
  try {
539
- return get(connector(node));
521
+ return get2(connector(node));
540
522
  } catch {
541
523
  log2.warn("Error in connector", {
542
524
  id: getId("connector"),
543
525
  node
544
526
  }, {
545
527
  F: __dxlog_file2,
546
- L: 109,
528
+ L: 112,
547
529
  S: void 0,
548
530
  C: (f, a) => f(...a)
549
531
  });
@@ -555,9 +537,9 @@ var createExtension = (extension) => {
555
537
  id: getId("actionGroups"),
556
538
  position,
557
539
  relation: "outbound",
558
- connector: Rx2.family((node) => Rx2.make((get) => {
540
+ connector: Rx2.family((node) => Rx2.make((get2) => {
559
541
  try {
560
- return get(actionGroups(node)).map((arg) => ({
542
+ return get2(actionGroups(node)).map((arg) => ({
561
543
  ...arg,
562
544
  data: actionGroupSymbol,
563
545
  type: ACTION_GROUP_TYPE
@@ -568,7 +550,7 @@ var createExtension = (extension) => {
568
550
  node
569
551
  }, {
570
552
  F: __dxlog_file2,
571
- L: 130,
553
+ L: 133,
572
554
  S: void 0,
573
555
  C: (f, a) => f(...a)
574
556
  });
@@ -580,9 +562,9 @@ var createExtension = (extension) => {
580
562
  id: getId("actions"),
581
563
  position,
582
564
  relation: "outbound",
583
- connector: Rx2.family((node) => Rx2.make((get) => {
565
+ connector: Rx2.family((node) => Rx2.make((get2) => {
584
566
  try {
585
- return get(actions(node)).map((arg) => ({
567
+ return get2(actions(node)).map((arg) => ({
586
568
  ...arg,
587
569
  type: ACTION_TYPE
588
570
  }));
@@ -592,7 +574,7 @@ var createExtension = (extension) => {
592
574
  node
593
575
  }, {
594
576
  F: __dxlog_file2,
595
- L: 147,
577
+ L: 150,
596
578
  S: void 0,
597
579
  C: (f, a) => f(...a)
598
580
  });
@@ -616,6 +598,22 @@ var flattenExtensions = (extension, acc = []) => {
616
598
  }
617
599
  };
618
600
  var GraphBuilder = class _GraphBuilder {
601
+ // TODO(wittjosiah): Use Context.
602
+ _subscriptions = /* @__PURE__ */ new Map();
603
+ _extensions = Rx2.make(Record2.empty()).pipe(Rx2.keepAlive, Rx2.withLabel("graph-builder:extensions"));
604
+ _initialized = {};
605
+ _registry;
606
+ _graph;
607
+ constructor({ registry, ...params } = {}) {
608
+ this._registry = registry ?? Registry2.make();
609
+ this._graph = new Graph({
610
+ ...params,
611
+ registry: this._registry,
612
+ onExpand: (id, relation) => this._onExpand(id, relation),
613
+ onInitialize: (id) => this._onInitialize(id),
614
+ onRemoveNode: (id) => this._onRemoveNode(id)
615
+ });
616
+ }
619
617
  static from(pickle, registry) {
620
618
  if (!pickle) {
621
619
  return new _GraphBuilder({
@@ -685,6 +683,27 @@ var GraphBuilder = class _GraphBuilder {
685
683
  this._subscriptions.forEach((unsubscribe) => unsubscribe());
686
684
  this._subscriptions.clear();
687
685
  }
686
+ _resolvers = Rx2.family((id) => {
687
+ return Rx2.make((get2) => {
688
+ 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);
689
+ });
690
+ });
691
+ _connectors = Rx2.family((key) => {
692
+ return Rx2.make((get2) => {
693
+ const [id, relation] = key.split("+");
694
+ const node = this._graph.node(id);
695
+ return Function2.pipe(
696
+ get2(this._extensions),
697
+ Record2.values,
698
+ // TODO(wittjosiah): Sort on write rather than read.
699
+ Array.sortBy(byPosition),
700
+ Array.filter(({ relation: _relation = "outbound" }) => _relation === relation),
701
+ Array.map(({ connector }) => connector?.(node)),
702
+ Array.filter(isNonNullable2),
703
+ Array.flatMap((result) => get2(result))
704
+ );
705
+ }).pipe(Rx2.withLabel(`graph-builder:connectors:${key}`));
706
+ });
688
707
  _onExpand(id, relation) {
689
708
  log2("onExpand", {
690
709
  id,
@@ -692,7 +711,7 @@ var GraphBuilder = class _GraphBuilder {
692
711
  registry: getDebugName(this._registry)
693
712
  }, {
694
713
  F: __dxlog_file2,
695
- L: 324,
714
+ L: 327,
696
715
  S: this,
697
716
  C: (f, a) => f(...a)
698
717
  });
@@ -709,7 +728,7 @@ var GraphBuilder = class _GraphBuilder {
709
728
  removed
710
729
  }, {
711
730
  F: __dxlog_file2,
712
- L: 335,
731
+ L: 338,
713
732
  S: this,
714
733
  C: (f, a) => f(...a)
715
734
  });
@@ -746,7 +765,7 @@ var GraphBuilder = class _GraphBuilder {
746
765
  id
747
766
  }, {
748
767
  F: __dxlog_file2,
749
- L: 372,
768
+ L: 375,
750
769
  S: this,
751
770
  C: (f, a) => f(...a)
752
771
  });
@@ -776,56 +795,20 @@ var GraphBuilder = class _GraphBuilder {
776
795
  this._subscriptions.get(id)?.();
777
796
  this._subscriptions.delete(id);
778
797
  }
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
- });
814
- }
815
798
  };
816
799
  var rxFromSignal = (cb) => {
817
- return Rx2.make((get) => {
800
+ return Rx2.make((get2) => {
818
801
  const dispose = effect(() => {
819
- get.setSelf(cb());
802
+ get2.setSelf(cb());
820
803
  });
821
- get.addFinalizer(() => dispose());
804
+ get2.addFinalizer(() => dispose());
822
805
  return cb();
823
806
  });
824
807
  };
825
808
  var observableFamily = Rx2.family((observable) => {
826
- return Rx2.make((get) => {
827
- const subscription = observable.subscribe((value) => get.setSelf(value));
828
- get.addFinalizer(() => subscription.unsubscribe());
809
+ return Rx2.make((get2) => {
810
+ const subscription = observable.subscribe((value) => get2.setSelf(value));
811
+ get2.addFinalizer(() => subscription.unsubscribe());
829
812
  return observable.get();
830
813
  });
831
814
  });