@dxos/app-graph 0.8.4-main.8360d9e660 → 0.8.4-main.8baae0fced

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.
Files changed (53) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +1 -1
  3. package/dist/lib/{browser/index.mjs → neutral/chunk-32XXJE6M.mjs} +247 -349
  4. package/dist/lib/neutral/chunk-32XXJE6M.mjs.map +7 -0
  5. package/dist/lib/neutral/chunk-J5LGTIGS.mjs +10 -0
  6. package/dist/lib/neutral/chunk-J5LGTIGS.mjs.map +7 -0
  7. package/dist/lib/neutral/index.mjs +40 -0
  8. package/dist/lib/neutral/index.mjs.map +7 -0
  9. package/dist/lib/neutral/meta.json +1 -0
  10. package/dist/lib/neutral/scheduler.mjs +15 -0
  11. package/dist/lib/neutral/scheduler.mjs.map +7 -0
  12. package/dist/lib/neutral/testing/index.mjs +40 -0
  13. package/dist/lib/neutral/testing/index.mjs.map +7 -0
  14. package/dist/types/src/atoms.d.ts.map +1 -1
  15. package/dist/types/src/graph-builder.d.ts +2 -2
  16. package/dist/types/src/graph-builder.d.ts.map +1 -1
  17. package/dist/types/src/graph.d.ts.map +1 -1
  18. package/dist/types/src/index.d.ts +1 -0
  19. package/dist/types/src/index.d.ts.map +1 -1
  20. package/dist/types/src/node-matcher.d.ts +42 -16
  21. package/dist/types/src/node-matcher.d.ts.map +1 -1
  22. package/dist/types/src/node.d.ts +9 -3
  23. package/dist/types/src/node.d.ts.map +1 -1
  24. package/dist/types/src/scheduler.browser.d.ts +2 -0
  25. package/dist/types/src/scheduler.browser.d.ts.map +1 -0
  26. package/dist/types/src/scheduler.d.ts +8 -0
  27. package/dist/types/src/scheduler.d.ts.map +1 -0
  28. package/dist/types/src/stories/EchoGraph.stories.d.ts.map +1 -1
  29. package/dist/types/src/testing/index.d.ts +2 -0
  30. package/dist/types/src/testing/index.d.ts.map +1 -0
  31. package/dist/types/src/testing/setup-graph-builder.d.ts +31 -0
  32. package/dist/types/src/testing/setup-graph-builder.d.ts.map +1 -0
  33. package/dist/types/src/util.d.ts +20 -14
  34. package/dist/types/src/util.d.ts.map +1 -1
  35. package/dist/types/tsconfig.tsbuildinfo +1 -1
  36. package/package.json +38 -27
  37. package/src/graph-builder.test.ts +276 -25
  38. package/src/graph-builder.ts +45 -17
  39. package/src/graph.ts +15 -17
  40. package/src/index.ts +1 -0
  41. package/src/node-matcher.ts +57 -25
  42. package/src/node.ts +29 -3
  43. package/src/scheduler.browser.ts +5 -0
  44. package/src/scheduler.ts +17 -0
  45. package/src/stories/EchoGraph.stories.tsx +10 -12
  46. package/src/testing/index.ts +5 -0
  47. package/src/testing/setup-graph-builder.ts +41 -0
  48. package/src/util.ts +48 -18
  49. package/dist/lib/browser/index.mjs.map +0 -7
  50. package/dist/lib/browser/meta.json +0 -1
  51. package/dist/lib/node-esm/index.mjs +0 -1580
  52. package/dist/lib/node-esm/index.mjs.map +0 -7
  53. package/dist/lib/node-esm/meta.json +0 -1
@@ -1,67 +1,6 @@
1
- var __defProp = Object.defineProperty;
2
- var __export = (target, all) => {
3
- for (var name in all)
4
- __defProp(target, name, { get: all[name], enumerable: true });
5
- };
6
-
7
- // src/atoms.ts
8
- var atoms_exports = {};
9
- __export(atoms_exports, {
10
- fromObservable: () => fromObservable
11
- });
12
- import { Atom } from "@effect-atom/atom-react";
13
- var observableFamily = Atom.family((observable) => {
14
- return Atom.make((get2) => {
15
- const subscription = observable.subscribe((value) => get2.setSelf(value));
16
- get2.addFinalizer(() => subscription.unsubscribe());
17
- return observable.get();
18
- });
19
- });
20
- var fromObservable = (observable) => {
21
- return observableFamily(observable);
22
- };
23
-
24
- // src/graph.ts
25
- var graph_exports = {};
26
- __export(graph_exports, {
27
- GraphKind: () => GraphKind,
28
- GraphTypeId: () => GraphTypeId,
29
- addEdge: () => addEdge,
30
- addEdges: () => addEdges,
31
- addNode: () => addNode,
32
- addNodes: () => addNodes,
33
- expand: () => expand,
34
- getActions: () => getActions,
35
- getConnections: () => getConnections,
36
- getEdges: () => getEdges,
37
- getGraph: () => getGraph,
38
- getNode: () => getNode,
39
- getNodeOrThrow: () => getNodeOrThrow,
40
- getPath: () => getPath,
41
- getRoot: () => getRoot,
42
- initialize: () => initialize,
43
- make: () => make,
44
- relationFromKey: () => relationFromKey,
45
- relationKey: () => relationKey,
46
- removeEdge: () => removeEdge,
47
- removeEdges: () => removeEdges,
48
- removeNode: () => removeNode,
49
- removeNodes: () => removeNodes,
50
- sortEdges: () => sortEdges,
51
- toJSON: () => toJSON,
52
- traverse: () => traverse,
53
- waitForPath: () => waitForPath
54
- });
55
- import { Atom as Atom2, Registry } from "@effect-atom/atom-react";
56
- import * as Function from "effect/Function";
57
- import * as Option from "effect/Option";
58
- import * as Pipeable from "effect/Pipeable";
59
- import * as Record from "effect/Record";
60
- import { Event, Trigger } from "@dxos/async";
61
- import { todo } from "@dxos/debug";
62
- import { invariant as invariant2 } from "@dxos/invariant";
63
- import { log } from "@dxos/log";
64
- import { isNonNullable } from "@dxos/util";
1
+ import {
2
+ __export
3
+ } from "./chunk-J5LGTIGS.mjs";
65
4
 
66
5
  // src/node.ts
67
6
  var node_exports = {};
@@ -77,12 +16,15 @@ __export(node_exports, {
77
16
  isActionGroup: () => isActionGroup,
78
17
  isActionLike: () => isActionLike,
79
18
  isGraphNode: () => isGraphNode,
19
+ make: () => make,
20
+ makeAction: () => makeAction,
21
+ makeActionGroup: () => makeActionGroup,
80
22
  relation: () => relation
81
23
  });
82
24
  var RootId = "root";
83
- var RootType = "org.dxos.type.graph-root";
84
- var ActionType = "org.dxos.type.graph-action";
85
- var ActionGroupType = "org.dxos.type.graph-action-group";
25
+ var RootType = "org.dxos.type.graphRoot";
26
+ var ActionType = "org.dxos.type.graphAction";
27
+ var ActionGroupType = "org.dxos.type.graphActionGroup";
86
28
  var relation = (kind, direction = "outbound") => ({
87
29
  kind,
88
30
  direction
@@ -94,19 +36,35 @@ var isAction = (data) => isGraphNode(data) ? typeof data.data === "function" &&
94
36
  var actionGroupSymbol = /* @__PURE__ */ Symbol("ActionGroup");
95
37
  var isActionGroup = (data) => isGraphNode(data) ? data.data === actionGroupSymbol && data.type === ActionGroupType : false;
96
38
  var isActionLike = (data) => isAction(data) || isActionGroup(data);
39
+ var make = (arg) => arg;
40
+ var makeAction = (arg) => ({
41
+ ...arg,
42
+ type: ActionType
43
+ });
44
+ var makeActionGroup = (arg) => ({
45
+ ...arg,
46
+ type: ActionGroupType,
47
+ data: actionGroupSymbol
48
+ });
97
49
 
98
50
  // src/util.ts
99
51
  import { invariant } from "@dxos/invariant";
100
52
  var __dxlog_file = "/__w/dxos/dxos/packages/sdk/app-graph/src/util.ts";
101
- var Separators = {
102
- primary: "",
103
- secondary: "",
104
- path: "/"
105
- };
53
+ var PRIMARY = "";
54
+ var SECONDARY = "";
55
+ var PATH = "/";
56
+ var primaryKey = (...parts) => parts.join(PRIMARY);
57
+ var primaryParts = (key) => key.split(PRIMARY);
58
+ var secondaryKey = (...parts) => parts.join(SECONDARY);
59
+ var secondaryParts = (key) => key.split(SECONDARY);
106
60
  var normalizeRelation = (relation2) => relation2 == null ? childRelation() : typeof relation2 === "string" ? relation(relation2) : relation2;
107
61
  var shallowEqual = (a, b) => {
108
- if (a === b) return true;
109
- if (a == null || b == null || typeof a !== "object" || typeof b !== "object") return false;
62
+ if (a === b) {
63
+ return true;
64
+ }
65
+ if (a == null || b == null || typeof a !== "object" || typeof b !== "object") {
66
+ return false;
67
+ }
110
68
  const keysA = Object.keys(a);
111
69
  const keysB = Object.keys(b);
112
70
  if (keysA.length !== keysB.length) {
@@ -120,36 +78,70 @@ var nodeArgsUnchanged = (prev, next) => {
120
78
  }
121
79
  return prev.every((prevNode, idx) => {
122
80
  const nextNode = next[idx];
123
- return prevNode.id === nextNode.id && prevNode.type === nextNode.type && shallowEqual(prevNode.data, nextNode.data) && shallowEqual(prevNode.properties, nextNode.properties);
81
+ return prevNode.id === nextNode.id && prevNode.type === nextNode.type && shallowEqual(prevNode.data, nextNode.data) && shallowEqual(prevNode.properties, nextNode.properties) && nodeArgsUnchanged(prevNode.nodes ?? [], nextNode.nodes ?? []);
124
82
  });
125
83
  };
126
- var qualifyId = (parentId, segmentId) => `${parentId}${Separators.path}${segmentId}`;
84
+ var qualifyId = (parentId, ...segmentIds) => [
85
+ parentId,
86
+ ...segmentIds
87
+ ].join(PATH);
127
88
  var validateSegmentId = (id) => {
128
- invariant(!id.includes(Separators.path), `Node segment ID must not contain '${Separators.path}': ${id}`, {
129
- F: __dxlog_file,
130
- L: 70,
131
- S: void 0,
132
- A: [
133
- "!id.includes(Separators.path)",
134
- "`Node segment ID must not contain '${Separators.path}': ${id}`"
135
- ]
136
- });
89
+ invariant(!id.includes(PATH), `Node segment ID must not contain '${PATH}': ${id}`, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 56, S: void 0, A: ["!id.includes(PATH)", "`Node segment ID must not contain '${PATH}': ${id}`"] });
90
+ };
91
+ var getParentId = (qualifiedId) => {
92
+ const lastSlash = qualifiedId.lastIndexOf(PATH);
93
+ return lastSlash > 0 ? qualifiedId.slice(0, lastSlash) : void 0;
94
+ };
95
+ var getSegmentId = (qualifiedId) => {
96
+ return qualifiedId.split(PATH).pop() ?? qualifiedId;
137
97
  };
138
98
 
139
99
  // src/graph.ts
100
+ var graph_exports = {};
101
+ __export(graph_exports, {
102
+ GraphKind: () => GraphKind,
103
+ GraphTypeId: () => GraphTypeId,
104
+ addEdge: () => addEdge,
105
+ addEdges: () => addEdges,
106
+ addNode: () => addNode,
107
+ addNodes: () => addNodes,
108
+ expand: () => expand,
109
+ getActions: () => getActions,
110
+ getConnections: () => getConnections,
111
+ getEdges: () => getEdges,
112
+ getGraph: () => getGraph,
113
+ getNode: () => getNode,
114
+ getNodeOrThrow: () => getNodeOrThrow,
115
+ getPath: () => getPath,
116
+ getRoot: () => getRoot,
117
+ initialize: () => initialize,
118
+ make: () => make2,
119
+ relationFromKey: () => relationFromKey,
120
+ relationKey: () => relationKey,
121
+ removeEdge: () => removeEdge,
122
+ removeEdges: () => removeEdges,
123
+ removeNode: () => removeNode,
124
+ removeNodes: () => removeNodes,
125
+ sortEdges: () => sortEdges,
126
+ toJSON: () => toJSON,
127
+ traverse: () => traverse,
128
+ waitForPath: () => waitForPath
129
+ });
130
+ import { Atom, Registry } from "@effect-atom/atom-react";
131
+ import * as Function from "effect/Function";
132
+ import * as Option from "effect/Option";
133
+ import * as Pipeable from "effect/Pipeable";
134
+ import * as Record from "effect/Record";
135
+ import { Event, Trigger } from "@dxos/async";
136
+ import { todo } from "@dxos/debug";
137
+ import { invariant as invariant2 } from "@dxos/invariant";
138
+ import { log } from "@dxos/log";
139
+ import { isNonNullable } from "@dxos/util";
140
140
  var __dxlog_file2 = "/__w/dxos/dxos/packages/sdk/app-graph/src/graph.ts";
141
141
  var graphSymbol = /* @__PURE__ */ Symbol("graph");
142
142
  var getGraph = (node) => {
143
143
  const graph = node[graphSymbol];
144
- invariant2(graph, "Node is not associated with a graph.", {
145
- F: __dxlog_file2,
146
- L: 33,
147
- S: void 0,
148
- A: [
149
- "graph",
150
- "'Node is not associated with a graph.'"
151
- ]
152
- });
144
+ invariant2(graph, "Node is not associated with a graph.", { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 21, S: void 0, A: ["graph", "'Node is not associated with a graph.'"] });
153
145
  return graph;
154
146
  };
155
147
  var GraphTypeId = /* @__PURE__ */ Symbol.for("@dxos/app-graph/Graph");
@@ -181,51 +173,44 @@ var GraphImpl = class {
181
173
  ]
182
174
  ]);
183
175
  /** @internal */
184
- _node = Atom2.family((id) => {
176
+ _node = Atom.family((id) => {
185
177
  const initial = Option.flatten(Record.get(this._initialNodes, id));
186
- return Atom2.make(initial).pipe(Atom2.keepAlive, Atom2.withLabel(`graph:node:${id}`));
178
+ return Atom.make(initial).pipe(Atom.keepAlive, Atom.withLabel(`graph:node:${id}`));
187
179
  });
188
- _nodeOrThrow = Atom2.family((id) => {
189
- return Atom2.make((get2) => {
180
+ _nodeOrThrow = Atom.family((id) => {
181
+ return Atom.make((get2) => {
190
182
  const node = get2(this._node(id));
191
- invariant2(Option.isSome(node), `Node not available: ${id}`, {
192
- F: __dxlog_file2,
193
- L: 172,
194
- S: this,
195
- A: [
196
- "Option.isSome(node)",
197
- "`Node not available: ${id}`"
198
- ]
199
- });
183
+ invariant2(Option.isSome(node), `Node not available: ${id}`, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 67, S: this, A: ["Option.isSome(node)", "`Node not available: ${id}`"] });
200
184
  return node.value;
201
185
  });
202
186
  });
203
- _edges = Atom2.family((id) => {
187
+ _edges = Atom.family((id) => {
204
188
  const initial = Record.get(this._initialEdges, id).pipe(Option.getOrElse(() => ({})));
205
- return Atom2.make(initial).pipe(Atom2.keepAlive, Atom2.withLabel(`graph:edges:${id}`));
189
+ return Atom.make(initial).pipe(Atom.keepAlive, Atom.withLabel(`graph:edges:${id}`));
206
190
  });
207
191
  // NOTE: Currently the argument to the family needs to be referentially stable for the atom to be referentially stable.
208
192
  // TODO(wittjosiah): Atom feature request, support for something akin to `ComplexMap` to allow for complex arguments.
209
- _connections = Atom2.family((key) => {
210
- return Atom2.make((get2) => {
211
- if (!key || key.indexOf(Separators.primary) <= 0) {
193
+ _connections = Atom.family((key) => {
194
+ return Atom.make((get2) => {
195
+ const parts = key ? primaryParts(key) : [];
196
+ if (parts.length < 2 || !parts[0]) {
212
197
  return [];
213
198
  }
214
199
  const { id, relation: relation2 } = relationFromConnectionKey(key);
215
200
  const edges = get2(this._edges(id));
216
201
  return (edges[relationKey(relation2)] ?? []).map((id2) => get2(this._node(id2))).filter(Option.isSome).map((o) => o.value);
217
- }).pipe(Atom2.withLabel(`graph:connections:${key}`));
202
+ }).pipe(Atom.withLabel(`graph:connections:${key}`));
218
203
  });
219
- _actions = Atom2.family((id) => {
220
- return Atom2.make((get2) => {
204
+ _actions = Atom.family((id) => {
205
+ return Atom.make((get2) => {
221
206
  if (!id) {
222
207
  return [];
223
208
  }
224
209
  return get2(this._connections(connectionKey(id, actionRelation())));
225
- }).pipe(Atom2.withLabel(`graph:actions:${id}`));
210
+ }).pipe(Atom.withLabel(`graph:actions:${id}`));
226
211
  });
227
- _json = Atom2.family((id) => {
228
- return Atom2.make((get2) => {
212
+ _json = Atom.family((id) => {
213
+ return Atom.make((get2) => {
229
214
  const toJSON2 = (node, seen = []) => {
230
215
  const nodes = get2(this._connections(connectionKey(node.id, "child")));
231
216
  const obj = {
@@ -248,7 +233,7 @@ var GraphImpl = class {
248
233
  };
249
234
  const root = get2(this._nodeOrThrow(id));
250
235
  return toJSON2(root);
251
- }).pipe(Atom2.withLabel(`graph:json:${id}`));
236
+ }).pipe(Atom.withLabel(`graph:json:${id}`));
252
237
  });
253
238
  constructor({ registry, nodes, edges, onInitialize, onExpand, onRemoveNode } = {}) {
254
239
  this._registry = registry ?? Registry.make();
@@ -366,15 +351,7 @@ function getConnections(graphOrId, idOrRelation, relation2) {
366
351
  } else {
367
352
  const graph = graphOrId;
368
353
  const id = idOrRelation;
369
- invariant2(relation2 !== void 0, "Relation is required.", {
370
- F: __dxlog_file2,
371
- L: 446,
372
- S: this,
373
- A: [
374
- "relation !== undefined",
375
- "'Relation is required.'"
376
- ]
377
- });
354
+ invariant2(relation2 !== void 0, "Relation is required.", { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 272, S: this, A: ["relation !== undefined", "'Relation is required.'"] });
378
355
  const rel = relation2;
379
356
  return getConnectionsImpl(graph, id, rel);
380
357
  }
@@ -511,12 +488,7 @@ var initializeImpl = async (graph, id) => {
511
488
  log("initialize", {
512
489
  id,
513
490
  initialized
514
- }, {
515
- F: __dxlog_file2,
516
- L: 668,
517
- S: void 0,
518
- C: (f, a) => f(...a)
519
- });
491
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 431, S: void 0 });
520
492
  if (!initialized) {
521
493
  Record.set(internal._initialized, id, true);
522
494
  await internal._onInitialize?.(id);
@@ -535,31 +507,21 @@ function initialize(graphOrId, id) {
535
507
  var expandImpl = (graph, id, relation2) => {
536
508
  const internal = getInternal(graph);
537
509
  const normalizedRelation = normalizeRelation(relation2);
538
- const key = `${id}${Separators.primary}${relationKey(normalizedRelation)}`;
510
+ const key = primaryKey(id, relationKey(normalizedRelation));
539
511
  const nodeOpt = internal._registry.get(internal._node(id));
540
512
  if (Option.isNone(nodeOpt)) {
541
513
  internal._pendingExpands.add(key);
542
514
  log("expand", {
543
515
  key,
544
516
  deferred: true
545
- }, {
546
- F: __dxlog_file2,
547
- L: 714,
548
- S: void 0,
549
- C: (f, a) => f(...a)
550
- });
517
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 463, S: void 0 });
551
518
  return graph;
552
519
  }
553
520
  const expanded = Record.get(internal._expanded, key).pipe(Option.getOrElse(() => false));
554
521
  log("expand", {
555
522
  key,
556
523
  expanded
557
- }, {
558
- F: __dxlog_file2,
559
- L: 719,
560
- S: void 0,
561
- C: (f, a) => f(...a)
562
- });
524
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 470, S: void 0 });
563
525
  if (!expanded) {
564
526
  Record.set(internal._expanded, key, true);
565
527
  internal._onExpand?.(id, normalizedRelation);
@@ -574,15 +536,7 @@ function expand(graphOrId, idOrRelation, relation2) {
574
536
  } else {
575
537
  const graph = graphOrId;
576
538
  const id = idOrRelation;
577
- invariant2(relation2 !== void 0, "Relation is required.", {
578
- F: __dxlog_file2,
579
- L: 755,
580
- S: this,
581
- A: [
582
- "relation !== undefined",
583
- "'Relation is required.'"
584
- ]
585
- });
539
+ invariant2(relation2 !== void 0, "Relation is required.", { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 490, S: this, A: ["relation !== undefined", "'Relation is required.'"] });
586
540
  const rel = relation2;
587
541
  return expandImpl(graph, id, rel);
588
542
  }
@@ -622,7 +576,7 @@ function sortEdges(graphOrId, idOrRelation, relationOrOrder, order) {
622
576
  }
623
577
  }
624
578
  var addNodesImpl = (graph, nodes) => {
625
- Atom2.batch(() => {
579
+ Atom.batch(() => {
626
580
  nodes.map((node) => addNodeImpl(graph, node));
627
581
  });
628
582
  return graph;
@@ -651,24 +605,14 @@ var addNodeImpl = (graph, nodeArg) => {
651
605
  typeChanged,
652
606
  dataChanged,
653
607
  propertiesChanged
654
- }, {
655
- F: __dxlog_file2,
656
- L: 877,
657
- S: void 0,
658
- C: (f, a) => f(...a)
659
- });
608
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 565, S: void 0 });
660
609
  if (typeChanged || dataChanged || propertiesChanged) {
661
610
  log("updating node", {
662
611
  id,
663
612
  type,
664
613
  data,
665
614
  properties
666
- }, {
667
- F: __dxlog_file2,
668
- L: 884,
669
- S: void 0,
670
- C: (f, a) => f(...a)
671
- });
615
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 572, S: void 0 });
672
616
  const newNode = Option.some({
673
617
  ...existing,
674
618
  ...rest,
@@ -692,12 +636,7 @@ var addNodeImpl = (graph, nodeArg) => {
692
636
  type,
693
637
  data,
694
638
  properties
695
- }, {
696
- F: __dxlog_file2,
697
- L: 897,
698
- S: void 0,
699
- C: (f, a) => f(...a)
700
- });
639
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 596, S: void 0 });
701
640
  const newNode = internal._constructNode({
702
641
  id,
703
642
  type,
@@ -710,13 +649,12 @@ var addNodeImpl = (graph, nodeArg) => {
710
649
  id,
711
650
  node: newNode
712
651
  });
713
- const prefix = `${id}${Separators.primary}`;
714
652
  const toApply = [
715
653
  ...internal._pendingExpands
716
- ].filter((k) => k.startsWith(prefix));
654
+ ].filter((k) => primaryParts(k)[0] === id);
717
655
  for (const pendingKey of toApply) {
718
656
  internal._pendingExpands.delete(pendingKey);
719
- const relation2 = relationFromKey(pendingKey.slice(prefix.length));
657
+ const relation2 = relationFromKey(primaryParts(pendingKey)[1]);
720
658
  Record.set(internal._expanded, pendingKey, true);
721
659
  internal._onExpand?.(id, relation2);
722
660
  }
@@ -746,7 +684,7 @@ function addNode(graphOrNodeArg, nodeArg) {
746
684
  }
747
685
  }
748
686
  var removeNodesImpl = (graph, ids, edges = false) => {
749
- Atom2.batch(() => {
687
+ Atom.batch(() => {
750
688
  ids.map((id) => removeNodeImpl(graph, id, edges));
751
689
  });
752
690
  return graph;
@@ -811,7 +749,7 @@ function removeNode(graphOrId, idOrEdges, edges) {
811
749
  }
812
750
  }
813
751
  var addEdgesImpl = (graph, edges) => {
814
- Atom2.batch(() => {
752
+ Atom.batch(() => {
815
753
  edges.map((edge) => addEdgeImpl(graph, edge));
816
754
  });
817
755
  return graph;
@@ -839,12 +777,7 @@ var addEdgeImpl = (graph, edgeArg) => {
839
777
  source: edgeArg.source,
840
778
  target: edgeArg.target,
841
779
  relation: relationId
842
- }, {
843
- F: __dxlog_file2,
844
- L: 1081,
845
- S: void 0,
846
- C: (f, a) => f(...a)
847
- });
780
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 758, S: void 0 });
848
781
  internal._registry.set(sourceAtom, {
849
782
  ...source,
850
783
  [relationId]: [
@@ -861,12 +794,7 @@ var addEdgeImpl = (graph, edgeArg) => {
861
794
  source: edgeArg.source,
862
795
  target: edgeArg.target,
863
796
  relation: inverseId
864
- }, {
865
- F: __dxlog_file2,
866
- L: 1089,
867
- S: void 0,
868
- C: (f, a) => f(...a)
869
- });
797
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 775, S: void 0 });
870
798
  internal._registry.set(targetAtom, {
871
799
  ...target,
872
800
  [inverseId]: [
@@ -887,7 +815,7 @@ function addEdge(graphOrEdgeArg, edgeArg) {
887
815
  }
888
816
  }
889
817
  var removeEdgesImpl = (graph, edges, removeOrphans = false) => {
890
- Atom2.batch(() => {
818
+ Atom.batch(() => {
891
819
  edges.map((edge) => removeEdgeImpl(graph, edge, removeOrphans));
892
820
  });
893
821
  return graph;
@@ -957,51 +885,24 @@ function removeEdge(graphOrEdgeArg, edgeArgOrRemoveOrphans, removeOrphans) {
957
885
  return removeEdgeImpl(graph, edgeArg, removeOrphansArg);
958
886
  }
959
887
  }
960
- var make = (params) => {
888
+ var make2 = (params) => {
961
889
  return new GraphImpl(params);
962
890
  };
963
891
  var relationKey = (relation2) => {
964
892
  const normalized = normalizeRelation(relation2);
965
- return `${normalized.kind}${Separators.secondary}${normalized.direction}`;
893
+ return secondaryKey(normalized.kind, normalized.direction);
966
894
  };
967
895
  var relationFromKey = (encoded) => {
968
- const separatorIndex = encoded.lastIndexOf(Separators.secondary);
969
- invariant2(separatorIndex > 0 && separatorIndex < encoded.length - 1, `Invalid relation key: ${encoded}`, {
970
- F: __dxlog_file2,
971
- L: 1234,
972
- S: void 0,
973
- A: [
974
- "separatorIndex > 0 && separatorIndex < encoded.length - 1",
975
- "`Invalid relation key: ${encoded}`"
976
- ]
977
- });
978
- const kind = encoded.slice(0, separatorIndex);
979
- const directionRaw = encoded.slice(separatorIndex + 1);
980
- invariant2(directionRaw === "outbound" || directionRaw === "inbound", `Invalid relation direction: ${directionRaw}`, {
981
- F: __dxlog_file2,
982
- L: 1237,
983
- S: void 0,
984
- A: [
985
- "directionRaw === 'outbound' || directionRaw === 'inbound'",
986
- "`Invalid relation direction: ${directionRaw}`"
987
- ]
988
- });
896
+ const parts = secondaryParts(encoded);
897
+ invariant2(parts.length === 2 && parts[0].length > 0 && parts[1].length > 0, `Invalid relation key: ${encoded}`, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 894, S: void 0, A: ["parts.length === 2 && parts[0].length > 0 && parts[1].length > 0", "`Invalid relation key: ${encoded}`"] });
898
+ const [kind, directionRaw] = parts;
899
+ invariant2(directionRaw === "outbound" || directionRaw === "inbound", `Invalid relation direction: ${directionRaw}`, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 896, S: void 0, A: ["directionRaw === 'outbound' || directionRaw === 'inbound'", "`Invalid relation direction: ${directionRaw}`"] });
989
900
  return relation(kind, directionRaw);
990
901
  };
991
- var connectionKey = (id, relation2) => `${id}${Separators.primary}${relationKey(relation2)}`;
902
+ var connectionKey = (id, relation2) => primaryKey(id, relationKey(relation2));
992
903
  var relationFromConnectionKey = (key) => {
993
- const separatorIndex = key.indexOf(Separators.primary);
994
- invariant2(separatorIndex > 0 && separatorIndex < key.length - 1, `Invalid connection key: ${key}`, {
995
- F: __dxlog_file2,
996
- L: 1246,
997
- S: void 0,
998
- A: [
999
- "separatorIndex > 0 && separatorIndex < key.length - 1",
1000
- "`Invalid connection key: ${key}`"
1001
- ]
1002
- });
1003
- const id = key.slice(0, separatorIndex);
1004
- const encodedRelation = key.slice(separatorIndex + 1);
904
+ const [id, encodedRelation] = primaryParts(key);
905
+ invariant2(id && encodedRelation, `Invalid connection key: ${key}`, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 902, S: void 0, A: ["id && encodedRelation", "`Invalid connection key: ${key}`"] });
1005
906
  return {
1006
907
  id,
1007
908
  relation: relationFromKey(encodedRelation)
@@ -1012,34 +913,6 @@ var inverseRelation = (relation2) => {
1012
913
  return relation(normalized.kind, normalized.direction === "outbound" ? "inbound" : "outbound");
1013
914
  };
1014
915
 
1015
- // src/graph-builder.ts
1016
- var graph_builder_exports = {};
1017
- __export(graph_builder_exports, {
1018
- GraphBuilderTypeId: () => GraphBuilderTypeId,
1019
- addExtension: () => addExtension,
1020
- createConnector: () => createConnector,
1021
- createExtension: () => createExtension,
1022
- createExtensionRaw: () => createExtensionRaw,
1023
- createTypeExtension: () => createTypeExtension,
1024
- destroy: () => destroy,
1025
- explore: () => explore,
1026
- flattenExtensions: () => flattenExtensions,
1027
- flush: () => flush,
1028
- from: () => from,
1029
- make: () => make2,
1030
- removeExtension: () => removeExtension
1031
- });
1032
- import { Atom as Atom3, Registry as Registry2 } from "@effect-atom/atom-react";
1033
- import * as Array2 from "effect/Array";
1034
- import * as Effect from "effect/Effect";
1035
- import * as Function2 from "effect/Function";
1036
- import * as Option3 from "effect/Option";
1037
- import * as Pipeable2 from "effect/Pipeable";
1038
- import * as Record2 from "effect/Record";
1039
- import { scheduleTask, yieldOrContinue } from "main-thread-scheduling";
1040
- import { log as log2 } from "@dxos/log";
1041
- import { byPosition, getDebugName, isNonNullable as isNonNullable2 } from "@dxos/util";
1042
-
1043
916
  // src/node-matcher.ts
1044
917
  var node_matcher_exports = {};
1045
918
  __export(node_matcher_exports, {
@@ -1062,17 +935,23 @@ var whenNodeType = (type) => (node) => node.type === type ? Option2.some(node) :
1062
935
  var whenEchoType = (type) => (node) => Obj.instanceOf(type, node.data) ? Option2.some(node.data) : Option2.none();
1063
936
  var whenEchoObject = (node) => Obj.isObject(node.data) ? Option2.some(node.data) : Option2.none();
1064
937
  var whenAll = (...matchers) => (node) => {
938
+ let first = Option2.none();
1065
939
  for (const candidate of matchers) {
1066
- if (Option2.isNone(candidate(node))) {
940
+ const result = candidate(node);
941
+ if (Option2.isNone(result)) {
1067
942
  return Option2.none();
1068
943
  }
944
+ if (Option2.isNone(first)) {
945
+ first = result;
946
+ }
1069
947
  }
1070
- return Option2.some(node);
948
+ return first;
1071
949
  };
1072
950
  var whenAny = (...matchers) => (node) => {
1073
951
  for (const candidate of matchers) {
1074
- if (Option2.isSome(candidate(node))) {
1075
- return Option2.some(node);
952
+ const result = candidate(node);
953
+ if (Option2.isSome(result)) {
954
+ return result;
1076
955
  }
1077
956
  }
1078
957
  return Option2.none();
@@ -1082,6 +961,32 @@ var whenEchoObjectMatches = (node) => Obj.isObject(node.data) ? Option2.some(nod
1082
961
  var whenNot = (matcher) => (node) => Option2.isNone(matcher(node)) ? Option2.some(node) : Option2.none();
1083
962
 
1084
963
  // src/graph-builder.ts
964
+ var graph_builder_exports = {};
965
+ __export(graph_builder_exports, {
966
+ GraphBuilderTypeId: () => GraphBuilderTypeId,
967
+ addExtension: () => addExtension,
968
+ createConnector: () => createConnector,
969
+ createExtension: () => createExtension,
970
+ createExtensionRaw: () => createExtensionRaw,
971
+ createTypeExtension: () => createTypeExtension,
972
+ destroy: () => destroy,
973
+ explore: () => explore,
974
+ flattenExtensions: () => flattenExtensions,
975
+ flush: () => flush,
976
+ from: () => from,
977
+ make: () => make3,
978
+ removeExtension: () => removeExtension
979
+ });
980
+ import { Atom as Atom2, Registry as Registry2 } from "@effect-atom/atom-react";
981
+ import * as Array2 from "effect/Array";
982
+ import * as Effect from "effect/Effect";
983
+ import * as Function2 from "effect/Function";
984
+ import * as Option3 from "effect/Option";
985
+ import * as Pipeable2 from "effect/Pipeable";
986
+ import * as Record2 from "effect/Record";
987
+ import { log as log2 } from "@dxos/log";
988
+ import { byPosition, getDebugName, isNonNullable as isNonNullable2 } from "@dxos/util";
989
+ import { scheduleTask, yieldOrContinue } from "#scheduler";
1085
990
  var __dxlog_file3 = "/__w/dxos/dxos/packages/sdk/app-graph/src/graph-builder.ts";
1086
991
  var GraphBuilderTypeId = /* @__PURE__ */ Symbol.for("@dxos/app-graph/GraphBuilder");
1087
992
  var GraphBuilderImpl = class {
@@ -1096,6 +1001,8 @@ var GraphBuilderImpl = class {
1096
1001
  _dirtyConnectors = /* @__PURE__ */ new Map();
1097
1002
  /** Last-flushed node IDs per connector key, used for edge removal on update. */
1098
1003
  _connectorPrevious = /* @__PURE__ */ new Map();
1004
+ /** All inline-descendant IDs per connector key, used to remove stale inline nodes on update. */
1005
+ _connectorPreviousInlineIds = /* @__PURE__ */ new Map();
1099
1006
  /** Last-flushed node args per connector key, used for change detection. */
1100
1007
  _connectorPreviousArgs = /* @__PURE__ */ new Map();
1101
1008
  /** Whether a dirty-flush task is already scheduled. */
@@ -1103,7 +1010,7 @@ var GraphBuilderImpl = class {
1103
1010
  /** Resolves when the current flush completes. */
1104
1011
  _flushPromise = Promise.resolve();
1105
1012
  /** Registered builder extensions keyed by extension ID. */
1106
- _extensions = Atom3.make(Record2.empty()).pipe(Atom3.keepAlive, Atom3.withLabel("graph-builder:extensions"));
1013
+ _extensions = Atom2.make(Record2.empty()).pipe(Atom2.keepAlive, Atom2.withLabel("graph-builder:extensions"));
1107
1014
  /** Triggers signalling that a node's resolver has fired at least once. */
1108
1015
  _initialized = {};
1109
1016
  /** Shared atom registry for reactive subscriptions. */
@@ -1112,7 +1019,7 @@ var GraphBuilderImpl = class {
1112
1019
  _graph;
1113
1020
  constructor({ registry, ...params } = {}) {
1114
1021
  this._registry = registry ?? Registry2.make();
1115
- const graph = make({
1022
+ const graph = make2({
1116
1023
  ...params,
1117
1024
  registry: this._registry,
1118
1025
  onExpand: (id, relation2) => this._onExpand(id, relation2),
@@ -1134,6 +1041,11 @@ var GraphBuilderImpl = class {
1134
1041
  const removed = previous.filter((pid) => !ids.includes(pid));
1135
1042
  this._connectorPrevious.set(key, ids);
1136
1043
  this._connectorPreviousArgs.set(key, nodes);
1044
+ const currentInlineIds = collectAllInlineIds(nodes);
1045
+ const previousInlineIds = this._connectorPreviousInlineIds.get(key) ?? [];
1046
+ const staleInlineIds = previousInlineIds.filter((pid) => !currentInlineIds.includes(pid));
1047
+ this._connectorPreviousInlineIds.set(key, currentInlineIds);
1048
+ removeNodes(this._graph, staleInlineIds, true);
1137
1049
  removeEdges(this._graph, removed.map((target) => ({
1138
1050
  source: id,
1139
1051
  target,
@@ -1162,7 +1074,7 @@ var GraphBuilderImpl = class {
1162
1074
  ...this._dirtyConnectors.entries()
1163
1075
  ];
1164
1076
  this._dirtyConnectors.clear();
1165
- Atom3.batch(() => {
1077
+ Atom2.batch(() => {
1166
1078
  for (const [key, { nodes, previous }] of entries) {
1167
1079
  this._applyConnectorUpdate(key, nodes, previous);
1168
1080
  }
@@ -1173,13 +1085,13 @@ var GraphBuilderImpl = class {
1173
1085
  });
1174
1086
  }
1175
1087
  }
1176
- _resolvers = Atom3.family((id) => {
1177
- return Atom3.make((get2) => {
1088
+ _resolvers = Atom2.family((id) => {
1089
+ return Atom2.make((get2) => {
1178
1090
  return Function2.pipe(get2(this._extensions), Record2.values, Array2.sortBy(byPosition), Array2.map(({ resolver }) => resolver), Array2.filter(isNonNullable2), Array2.map((resolver) => get2(resolver(id))), Array2.filter(isNonNullable2), Array2.head);
1179
1091
  });
1180
1092
  });
1181
- _connectors = Atom3.family((key) => {
1182
- return Atom3.make((get2) => {
1093
+ _connectors = Atom2.family((key) => {
1094
+ return Atom2.make((get2) => {
1183
1095
  const { id, relation: relation2 } = relationFromConnectorKey(key);
1184
1096
  const node = this._graph.node(id);
1185
1097
  const sourceNode = Option3.getOrElse(get2(node), () => void 0);
@@ -1193,19 +1105,14 @@ var GraphBuilderImpl = class {
1193
1105
  nodes.push(...result);
1194
1106
  }
1195
1107
  return nodes;
1196
- }).pipe(Atom3.withLabel(`graph-builder:connectors:${key}`));
1108
+ }).pipe(Atom2.withLabel(`graph-builder:connectors:${key}`));
1197
1109
  });
1198
1110
  _onExpand(id, relation2) {
1199
1111
  log2("onExpand", {
1200
1112
  id,
1201
1113
  relation: relation2,
1202
1114
  registry: getDebugName(this._registry)
1203
- }, {
1204
- F: __dxlog_file3,
1205
- L: 261,
1206
- S: this,
1207
- C: (f, a) => f(...a)
1208
- });
1115
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 136, S: this });
1209
1116
  this._expandRelation(id, relation2);
1210
1117
  if (relation2.kind === "child" && relation2.direction === "outbound") {
1211
1118
  expand(this._graph, id, "action");
@@ -1228,12 +1135,7 @@ var GraphBuilderImpl = class {
1228
1135
  id,
1229
1136
  relation: relation2,
1230
1137
  ids
1231
- }, {
1232
- F: __dxlog_file3,
1233
- L: 288,
1234
- S: this,
1235
- C: (f, a) => f(...a)
1236
- });
1138
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 160, S: this });
1237
1139
  this._dirtyConnectors.set(key, {
1238
1140
  nodes,
1239
1141
  previous
@@ -1244,36 +1146,42 @@ var GraphBuilderImpl = class {
1244
1146
  });
1245
1147
  this._subscriptions.set(subscriptionKey(id, "expand", key), cancel);
1246
1148
  }
1247
- // TODO(wittjosiah): If the same node is added by a connector, the resolver should probably cancel itself?
1248
1149
  async _onInitialize(id) {
1249
1150
  log2("onInitialize", {
1250
1151
  id
1251
- }, {
1252
- F: __dxlog_file3,
1253
- L: 300,
1254
- S: this,
1255
- C: (f, a) => f(...a)
1256
- });
1152
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 176, S: this });
1257
1153
  const resolver = this._resolvers(id);
1258
1154
  const cancel = this._registry.subscribe(resolver, (node) => {
1259
1155
  const trigger = this._initialized[id];
1156
+ const connectorOwned = [
1157
+ ...this._connectorPrevious.values()
1158
+ ].some((ids) => ids.includes(id));
1260
1159
  Option3.match(node, {
1261
1160
  onSome: (node2) => {
1262
- const connectorOwned = [
1263
- ...this._connectorPrevious.values()
1264
- ].some((ids) => ids.includes(id));
1265
1161
  if (!connectorOwned) {
1266
1162
  addNodes(this._graph, [
1267
1163
  node2
1268
1164
  ]);
1165
+ const parentId = getParentId(id);
1166
+ if (parentId) {
1167
+ addEdges(this._graph, [
1168
+ {
1169
+ source: parentId,
1170
+ target: id,
1171
+ relation: "child"
1172
+ }
1173
+ ]);
1174
+ }
1269
1175
  }
1270
1176
  trigger?.wake();
1271
1177
  },
1272
1178
  onNone: () => {
1273
1179
  trigger?.wake();
1274
- removeNodes(this._graph, [
1275
- id
1276
- ]);
1180
+ if (!connectorOwned) {
1181
+ removeNodes(this._graph, [
1182
+ id
1183
+ ]);
1184
+ }
1277
1185
  }
1278
1186
  });
1279
1187
  }, {
@@ -1282,26 +1190,25 @@ var GraphBuilderImpl = class {
1282
1190
  this._subscriptions.set(subscriptionKey(id, "init"), cancel);
1283
1191
  }
1284
1192
  _onRemoveNode(id) {
1285
- const prefix = `${id}${Separators.primary}`;
1286
1193
  for (const [key, cleanup] of this._subscriptions) {
1287
- if (key.startsWith(prefix)) {
1194
+ if (primaryParts(key)[0] === id) {
1288
1195
  cleanup();
1289
1196
  this._subscriptions.delete(key);
1290
1197
  }
1291
1198
  }
1292
1199
  }
1293
1200
  };
1294
- var make2 = (params) => {
1201
+ var make3 = (params) => {
1295
1202
  return new GraphBuilderImpl(params);
1296
1203
  };
1297
1204
  var from = (pickle, registry) => {
1298
1205
  if (!pickle) {
1299
- return make2({
1206
+ return make3({
1300
1207
  registry
1301
1208
  });
1302
1209
  }
1303
1210
  const { nodes, edges } = JSON.parse(pickle);
1304
- return make2({
1211
+ return make3({
1305
1212
  nodes,
1306
1213
  edges,
1307
1214
  registry
@@ -1400,13 +1307,13 @@ var flush = (builder) => {
1400
1307
  return builder._flushPromise;
1401
1308
  };
1402
1309
  var createExtensionRaw = (extension) => {
1403
- const { id, position = "static", relation: relation2 = "child", resolver: _resolver, connector: _connector, actions: _actions, actionGroups: _actionGroups } = extension;
1310
+ const { id, position, relation: relation2 = "child", resolver: _resolver, connector: _connector, actions: _actions, actionGroups: _actionGroups } = extension;
1404
1311
  const normalizedRelation = normalizeRelation(relation2);
1405
1312
  const getId = (key) => `${id}/${key}`;
1406
- const resolver = _resolver && Atom3.family((id2) => _resolver(id2).pipe(Atom3.withLabel(`graph-builder:_resolver:${id2}`)));
1407
- const connector = _connector && Atom3.family((node) => _connector(node).pipe(Atom3.withLabel(`graph-builder:_connector:${id}`)));
1408
- const actionGroups = _actionGroups && Atom3.family((node) => _actionGroups(node).pipe(Atom3.withLabel(`graph-builder:_actionGroups:${id}`)));
1409
- const actions = _actions && Atom3.family((node) => _actions(node).pipe(Atom3.withLabel(`graph-builder:_actions:${id}`)));
1313
+ const resolver = _resolver && Atom2.family((id2) => _resolver(id2).pipe(Atom2.withLabel(`graph-builder:_resolver:${id2}`)));
1314
+ const connector = _connector && Atom2.family((node) => _connector(node).pipe(Atom2.withLabel(`graph-builder:_connector:${id}`)));
1315
+ const actionGroups = _actionGroups && Atom2.family((node) => _actionGroups(node).pipe(Atom2.withLabel(`graph-builder:_actionGroups:${id}`)));
1316
+ const actions = _actions && Atom2.family((node) => _actions(node).pipe(Atom2.withLabel(`graph-builder:_actions:${id}`)));
1410
1317
  return [
1411
1318
  resolver ? {
1412
1319
  id: getId("resolver"),
@@ -1417,7 +1324,7 @@ var createExtensionRaw = (extension) => {
1417
1324
  id: getId("connector"),
1418
1325
  position,
1419
1326
  relation: normalizedRelation,
1420
- connector: Atom3.family((node) => Atom3.make((get2) => {
1327
+ connector: Atom2.family((node) => Atom2.make((get2) => {
1421
1328
  try {
1422
1329
  return get2(connector(node));
1423
1330
  } catch (error) {
@@ -1425,21 +1332,16 @@ var createExtensionRaw = (extension) => {
1425
1332
  id: getId("connector"),
1426
1333
  node,
1427
1334
  error
1428
- }, {
1429
- F: __dxlog_file3,
1430
- L: 596,
1431
- S: void 0,
1432
- C: (f, a) => f(...a)
1433
- });
1335
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 383, S: void 0 });
1434
1336
  return [];
1435
1337
  }
1436
- }).pipe(Atom3.withLabel(`graph-builder:connector:${id}`)))
1338
+ }).pipe(Atom2.withLabel(`graph-builder:connector:${id}`)))
1437
1339
  } : void 0,
1438
1340
  actionGroups ? {
1439
1341
  id: getId("actionGroups"),
1440
1342
  position,
1441
1343
  relation: actionRelation(),
1442
- connector: Atom3.family((node) => Atom3.make((get2) => {
1344
+ connector: Atom2.family((node) => Atom2.make((get2) => {
1443
1345
  try {
1444
1346
  return get2(actionGroups(node)).map((arg) => ({
1445
1347
  ...arg,
@@ -1451,21 +1353,16 @@ var createExtensionRaw = (extension) => {
1451
1353
  id: getId("actionGroups"),
1452
1354
  node,
1453
1355
  error
1454
- }, {
1455
- F: __dxlog_file3,
1456
- L: 617,
1457
- S: void 0,
1458
- C: (f, a) => f(...a)
1459
- });
1356
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 404, S: void 0 });
1460
1357
  return [];
1461
1358
  }
1462
- }).pipe(Atom3.withLabel(`graph-builder:connector:actionGroups:${id}`)))
1359
+ }).pipe(Atom2.withLabel(`graph-builder:connector:actionGroups:${id}`)))
1463
1360
  } : void 0,
1464
1361
  actions ? {
1465
1362
  id: getId("actions"),
1466
1363
  position,
1467
1364
  relation: actionRelation(),
1468
- connector: Atom3.family((node) => Atom3.make((get2) => {
1365
+ connector: Atom2.family((node) => Atom2.make((get2) => {
1469
1366
  try {
1470
1367
  return get2(actions(node)).map((arg) => ({
1471
1368
  ...arg,
@@ -1476,15 +1373,10 @@ var createExtensionRaw = (extension) => {
1476
1373
  id: getId("actions"),
1477
1374
  node,
1478
1375
  error
1479
- }, {
1480
- F: __dxlog_file3,
1481
- L: 634,
1482
- S: void 0,
1483
- C: (f, a) => f(...a)
1484
- });
1376
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 424, S: void 0 });
1485
1377
  return [];
1486
1378
  }
1487
- }).pipe(Atom3.withLabel(`graph-builder:connector:actions:${id}`)))
1379
+ }).pipe(Atom2.withLabel(`graph-builder:connector:actions:${id}`)))
1488
1380
  } : void 0
1489
1381
  ].filter(isNonNullable2);
1490
1382
  };
@@ -1493,24 +1385,19 @@ var runEffectSyncWithFallback = (effect, context2, extensionId, fallback) => {
1493
1385
  log2.warn("Extension failed", {
1494
1386
  extension: extensionId,
1495
1387
  error
1496
- }, {
1497
- F: __dxlog_file3,
1498
- L: 677,
1499
- S: void 0,
1500
- C: (f, a) => f(...a)
1501
- });
1388
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 441, S: void 0 });
1502
1389
  return Effect.succeed(fallback);
1503
1390
  })));
1504
1391
  };
1505
1392
  var createExtension = (options) => Effect.map(Effect.context(), (context2) => {
1506
1393
  const { id, match: match3, actions, connector, resolver, relation: relation2, position } = options;
1507
1394
  const connectorExtension = connector ? createConnectorWithRuntime(id, match3, connector, context2) : void 0;
1508
- const actionsExtension = actions ? (node) => Atom3.make((get2) => Function2.pipe(get2(node), Option3.flatMap(match3), Option3.map((matched) => runEffectSyncWithFallback(actions(matched, get2), context2, id, []).map((action) => ({
1395
+ const actionsExtension = actions ? (node) => Atom2.make((get2) => Function2.pipe(get2(node), Option3.flatMap(match3), Option3.map((matched) => runEffectSyncWithFallback(actions(matched, get2), context2, id, []).map((action) => ({
1509
1396
  ...action,
1510
1397
  // Attach captured context for action execution.
1511
1398
  _actionContext: context2
1512
1399
  }))), Option3.getOrElse(() => []))) : void 0;
1513
- const resolverExtension = resolver ? (nodeId) => Atom3.make((get2) => runEffectSyncWithFallback(resolver(nodeId, get2), context2, id, null) ?? null) : void 0;
1400
+ const resolverExtension = resolver ? (nodeId) => Atom2.make((get2) => runEffectSyncWithFallback(resolver(nodeId, get2), context2, id, null) ?? null) : void 0;
1514
1401
  return createExtensionRaw({
1515
1402
  id,
1516
1403
  relation: relation2,
@@ -1521,10 +1408,10 @@ var createExtension = (options) => Effect.map(Effect.context(), (context2) => {
1521
1408
  });
1522
1409
  });
1523
1410
  var createConnector = (matcher, factory) => {
1524
- return (node) => Atom3.make((get2) => Function2.pipe(get2(node), Option3.flatMap(matcher), Option3.map((data) => factory(data, get2)), Option3.getOrElse(() => [])));
1411
+ return (node) => Atom2.make((get2) => Function2.pipe(get2(node), Option3.flatMap(matcher), Option3.map((data) => factory(data, get2)), Option3.getOrElse(() => [])));
1525
1412
  };
1526
1413
  var createConnectorWithRuntime = (extensionId, matcher, factory, context2) => {
1527
- return (node) => Atom3.make((get2) => Function2.pipe(get2(node), Option3.flatMap(matcher), Option3.map((data) => runEffectSyncWithFallback(factory(data, get2), context2, extensionId, [])), Option3.getOrElse(() => [])));
1414
+ return (node) => Atom2.make((get2) => Function2.pipe(get2(node), Option3.flatMap(matcher), Option3.map((data) => runEffectSyncWithFallback(factory(data, get2), context2, extensionId, [])), Option3.getOrElse(() => [])));
1528
1415
  };
1529
1416
  var createTypeExtension = (options) => {
1530
1417
  const { id, type, actions, connector, relation: relation2, position } = options;
@@ -1546,16 +1433,19 @@ var qualifyNodeArgs = (parentId) => (nodes) => nodes.map((node) => {
1546
1433
  nodes: node.nodes ? qualifyNodeArgs(qualified)(node.nodes) : void 0
1547
1434
  };
1548
1435
  });
1549
- var connectorKey = (id, relation2) => `${id}${Separators.primary}${relationKey(relation2)}`;
1436
+ var collectAllInlineIds = (nodes) => nodes.flatMap((node) => node.nodes ? [
1437
+ ...node.nodes.map((child) => child.id),
1438
+ ...collectAllInlineIds(node.nodes)
1439
+ ] : []);
1440
+ var connectorKey = (id, relation2) => primaryKey(id, relationKey(relation2));
1550
1441
  var relationFromConnectorKey = (key) => {
1551
- const separatorIndex = key.indexOf(Separators.primary);
1552
- const id = key.slice(0, separatorIndex);
1442
+ const [id, encodedRelation] = primaryParts(key);
1553
1443
  return {
1554
1444
  id,
1555
- relation: relationFromKey(key.slice(separatorIndex + 1))
1445
+ relation: relationFromKey(encodedRelation)
1556
1446
  };
1557
1447
  };
1558
- var subscriptionKey = (id, kind, detail) => detail != null ? `${id}${Separators.primary}${kind}${Separators.primary}${detail}` : `${id}${Separators.primary}${kind}`;
1448
+ var subscriptionKey = (id, kind, detail) => detail != null ? primaryKey(id, kind, detail) : primaryKey(id, kind);
1559
1449
  var flattenExtensions = (extension, acc = []) => {
1560
1450
  if (Array2.isArray(extension)) {
1561
1451
  return [
@@ -1569,11 +1459,19 @@ var flattenExtensions = (extension, acc = []) => {
1569
1459
  ];
1570
1460
  }
1571
1461
  };
1462
+
1572
1463
  export {
1573
- atoms_exports as CreateAtom,
1574
- graph_exports as Graph,
1575
- graph_builder_exports as GraphBuilder,
1576
- node_exports as Node,
1577
- node_matcher_exports as NodeMatcher
1464
+ node_exports,
1465
+ qualifyId,
1466
+ getParentId,
1467
+ getSegmentId,
1468
+ getNode,
1469
+ expand,
1470
+ graph_exports,
1471
+ node_matcher_exports,
1472
+ make3 as make,
1473
+ addExtension,
1474
+ flush,
1475
+ graph_builder_exports
1578
1476
  };
1579
- //# sourceMappingURL=index.mjs.map
1477
+ //# sourceMappingURL=chunk-32XXJE6M.mjs.map