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

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 (43) hide show
  1. package/dist/lib/browser/index.mjs +1014 -553
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node-esm/index.mjs +1013 -553
  5. package/dist/lib/node-esm/index.mjs.map +4 -4
  6. package/dist/lib/node-esm/meta.json +1 -1
  7. package/dist/types/src/atoms.d.ts +8 -0
  8. package/dist/types/src/atoms.d.ts.map +1 -0
  9. package/dist/types/src/graph-builder.d.ts +108 -66
  10. package/dist/types/src/graph-builder.d.ts.map +1 -1
  11. package/dist/types/src/graph.d.ts +182 -212
  12. package/dist/types/src/graph.d.ts.map +1 -1
  13. package/dist/types/src/index.d.ts +6 -3
  14. package/dist/types/src/index.d.ts.map +1 -1
  15. package/dist/types/src/node-matcher.d.ts +218 -0
  16. package/dist/types/src/node-matcher.d.ts.map +1 -0
  17. package/dist/types/src/node-matcher.test.d.ts +2 -0
  18. package/dist/types/src/node-matcher.test.d.ts.map +1 -0
  19. package/dist/types/src/node.d.ts +32 -3
  20. package/dist/types/src/node.d.ts.map +1 -1
  21. package/dist/types/src/stories/EchoGraph.stories.d.ts.map +1 -1
  22. package/dist/types/tsconfig.tsbuildinfo +1 -1
  23. package/package.json +35 -33
  24. package/src/atoms.ts +25 -0
  25. package/src/graph-builder.test.ts +520 -104
  26. package/src/graph-builder.ts +550 -255
  27. package/src/graph.test.ts +299 -106
  28. package/src/graph.ts +964 -394
  29. package/src/index.ts +9 -3
  30. package/src/node-matcher.test.ts +301 -0
  31. package/src/node-matcher.ts +284 -0
  32. package/src/node.ts +39 -6
  33. package/src/stories/EchoGraph.stories.tsx +104 -95
  34. package/src/stories/Tree.tsx +2 -2
  35. package/dist/types/src/experimental/graph-projections.test.d.ts +0 -25
  36. package/dist/types/src/experimental/graph-projections.test.d.ts.map +0 -1
  37. package/dist/types/src/signals-integration.test.d.ts +0 -2
  38. package/dist/types/src/signals-integration.test.d.ts.map +0 -1
  39. package/dist/types/src/testing.d.ts +0 -5
  40. package/dist/types/src/testing.d.ts.map +0 -1
  41. package/src/experimental/graph-projections.test.ts +0 -56
  42. package/src/signals-integration.test.ts +0 -218
  43. package/src/testing.ts +0 -20
@@ -1,20 +1,97 @@
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
+
1
24
  // src/graph.ts
2
- import { Registry, Rx } from "@effect-rx/rx-react";
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
+ removeEdge: () => removeEdge,
45
+ removeEdges: () => removeEdges,
46
+ removeNode: () => removeNode,
47
+ removeNodes: () => removeNodes,
48
+ sortEdges: () => sortEdges,
49
+ toJSON: () => toJSON,
50
+ traverse: () => traverse,
51
+ waitForPath: () => waitForPath
52
+ });
53
+ import { Atom as Atom2, Registry } from "@effect-atom/atom-react";
3
54
  import * as Function from "effect/Function";
4
55
  import * as Option from "effect/Option";
56
+ import * as Pipeable from "effect/Pipeable";
5
57
  import * as Record from "effect/Record";
6
58
  import { Event, Trigger } from "@dxos/async";
7
59
  import { todo } from "@dxos/debug";
8
60
  import { invariant } from "@dxos/invariant";
9
61
  import { log } from "@dxos/log";
10
62
  import { isNonNullable } from "@dxos/util";
63
+
64
+ // src/node.ts
65
+ var node_exports = {};
66
+ __export(node_exports, {
67
+ ActionGroupType: () => ActionGroupType,
68
+ ActionType: () => ActionType,
69
+ RootId: () => RootId,
70
+ RootType: () => RootType,
71
+ actionGroupSymbol: () => actionGroupSymbol,
72
+ isAction: () => isAction,
73
+ isActionGroup: () => isActionGroup,
74
+ isActionLike: () => isActionLike,
75
+ isGraphNode: () => isGraphNode
76
+ });
77
+ var RootId = "root";
78
+ var RootType = "dxos.org/type/GraphRoot";
79
+ var ActionType = "dxos.org/type/GraphAction";
80
+ var ActionGroupType = "dxos.org/type/GraphActionGroup";
81
+ var isGraphNode = (data) => data && typeof data === "object" && "id" in data && "properties" in data && data.properties ? typeof data.properties === "object" && "data" in data : false;
82
+ var isAction = (data) => isGraphNode(data) ? typeof data.data === "function" && data.type === ActionType : false;
83
+ var actionGroupSymbol = Symbol("ActionGroup");
84
+ var isActionGroup = (data) => isGraphNode(data) ? data.data === actionGroupSymbol && data.type === ActionGroupType : false;
85
+ var isActionLike = (data) => isAction(data) || isActionGroup(data);
86
+
87
+ // src/graph.ts
11
88
  var __dxlog_file = "/__w/dxos/dxos/packages/sdk/app-graph/src/graph.ts";
12
89
  var graphSymbol = Symbol("graph");
13
90
  var getGraph = (node) => {
14
91
  const graph = node[graphSymbol];
15
92
  invariant(graph, "Node is not associated with a graph.", {
16
93
  F: __dxlog_file,
17
- L: 27,
94
+ L: 32,
18
95
  S: void 0,
19
96
  A: [
20
97
  "graph",
@@ -23,11 +100,14 @@ var getGraph = (node) => {
23
100
  });
24
101
  return graph;
25
102
  };
26
- var ROOT_ID = "root";
27
- var ROOT_TYPE = "dxos.org/type/GraphRoot";
28
- var ACTION_TYPE = "dxos.org/type/GraphAction";
29
- var ACTION_GROUP_TYPE = "dxos.org/type/GraphActionGroup";
30
- var Graph = class {
103
+ var GraphTypeId = Symbol.for("@dxos/app-graph/Graph");
104
+ var GraphKind = Symbol.for("@dxos/app-graph/GraphKind");
105
+ var GraphImpl = class {
106
+ [GraphTypeId] = GraphTypeId;
107
+ [GraphKind] = "writable";
108
+ pipe() {
109
+ return Pipeable.pipeArguments(this, arguments);
110
+ }
31
111
  onNodeChanged = new Event();
32
112
  _onExpand;
33
113
  _onInitialize;
@@ -38,26 +118,26 @@ var Graph = class {
38
118
  _initialEdges = Record.empty();
39
119
  _initialNodes = Record.fromEntries([
40
120
  [
41
- ROOT_ID,
121
+ RootId,
42
122
  this._constructNode({
43
- id: ROOT_ID,
44
- type: ROOT_TYPE,
123
+ id: RootId,
124
+ type: RootType,
45
125
  data: null,
46
126
  properties: {}
47
127
  })
48
128
  ]
49
129
  ]);
50
130
  /** @internal */
51
- _node = Rx.family((id) => {
131
+ _node = Atom2.family((id) => {
52
132
  const initial = Option.flatten(Record.get(this._initialNodes, id));
53
- return Rx.make(initial).pipe(Rx.keepAlive, Rx.withLabel(`graph:node:${id}`));
133
+ return Atom2.make(initial).pipe(Atom2.keepAlive, Atom2.withLabel(`graph:node:${id}`));
54
134
  });
55
- _nodeOrThrow = Rx.family((id) => {
56
- return Rx.make((get2) => {
135
+ _nodeOrThrow = Atom2.family((id) => {
136
+ return Atom2.make((get2) => {
57
137
  const node = get2(this._node(id));
58
138
  invariant(Option.isSome(node), `Node not available: ${id}`, {
59
139
  F: __dxlog_file,
60
- L: 254,
140
+ L: 174,
61
141
  S: this,
62
142
  A: [
63
143
  "Option.isSome(node)",
@@ -67,31 +147,31 @@ var Graph = class {
67
147
  return node.value;
68
148
  });
69
149
  });
70
- _edges = Rx.family((id) => {
150
+ _edges = Atom2.family((id) => {
71
151
  const initial = Record.get(this._initialEdges, id).pipe(Option.getOrElse(() => ({
72
152
  inbound: [],
73
153
  outbound: []
74
154
  })));
75
- return Rx.make(initial).pipe(Rx.keepAlive, Rx.withLabel(`graph:edges:${id}`));
155
+ return Atom2.make(initial).pipe(Atom2.keepAlive, Atom2.withLabel(`graph:edges:${id}`));
76
156
  });
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) => {
157
+ // NOTE: Currently the argument to the family needs to be referentially stable for the atom to be referentially stable.
158
+ // TODO(wittjosiah): Atom feature request, support for something akin to `ComplexMap` to allow for complex arguments.
159
+ _connections = Atom2.family((key) => {
160
+ return Atom2.make((get2) => {
81
161
  const [id, relation] = key.split("$");
82
162
  const edges = get2(this._edges(id));
83
163
  return edges[relation].map((id2) => get2(this._node(id2))).filter(Option.isSome).map((o) => o.value);
84
- }).pipe(Rx.withLabel(`graph:connections:${key}`));
164
+ }).pipe(Atom2.withLabel(`graph:connections:${key}`));
85
165
  });
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}`));
166
+ _actions = Atom2.family((id) => {
167
+ return Atom2.make((get2) => {
168
+ return get2(this._connections(`${id}$outbound`)).filter((node) => node.type === ActionType || node.type === ActionGroupType);
169
+ }).pipe(Atom2.withLabel(`graph:actions:${id}`));
90
170
  });
91
- _json = Rx.family((id) => {
92
- return Rx.make((get2) => {
93
- const toJSON = (node, seen = []) => {
94
- const nodes = get2(this.connections(node.id));
171
+ _json = Atom2.family((id) => {
172
+ return Atom2.make((get2) => {
173
+ const toJSON2 = (node, seen = []) => {
174
+ const nodes = get2(this._connections(`${node.id}$outbound`));
95
175
  const obj = {
96
176
  id: node.id,
97
177
  type: node.type
@@ -105,14 +185,14 @@ var Graph = class {
105
185
  ...seen,
106
186
  node.id
107
187
  ];
108
- return nextSeen.includes(n.id) ? void 0 : toJSON(n, nextSeen);
188
+ return nextSeen.includes(n.id) ? void 0 : toJSON2(n, nextSeen);
109
189
  }).filter(isNonNullable);
110
190
  }
111
191
  return obj;
112
192
  };
113
- const root = get2(this.nodeOrThrow(id));
114
- return toJSON(root);
115
- }).pipe(Rx.withLabel(`graph:json:${id}`));
193
+ const root = get2(this._nodeOrThrow(id));
194
+ return toJSON2(root);
195
+ }).pipe(Atom2.withLabel(`graph:json:${id}`));
116
196
  });
117
197
  constructor({ registry, nodes, edges, onInitialize, onExpand, onRemoveNode } = {}) {
118
198
  this._registry = registry ?? Registry.make();
@@ -130,502 +210,705 @@ var Graph = class {
130
210
  });
131
211
  }
132
212
  }
133
- toJSON(id = ROOT_ID) {
134
- return this._registry.get(this._json(id));
135
- }
136
- json(id = ROOT_ID) {
137
- return this._json(id);
213
+ json(id = RootId) {
214
+ return jsonImpl(this, id);
138
215
  }
139
216
  node(id) {
140
- return this._node(id);
217
+ return nodeImpl(this, id);
141
218
  }
142
219
  nodeOrThrow(id) {
143
- return this._nodeOrThrow(id);
220
+ return nodeOrThrowImpl(this, id);
144
221
  }
145
222
  connections(id, relation = "outbound") {
146
- return this._connections(`${id}$${relation}`);
223
+ return connectionsImpl(this, id, relation);
147
224
  }
148
225
  actions(id) {
149
- return this._actions(id);
226
+ return actionsImpl(this, id);
150
227
  }
151
228
  edges(id) {
152
- return this._edges(id);
229
+ return edgesImpl(this, id);
153
230
  }
154
- get root() {
155
- return this.getNodeOrThrow(ROOT_ID);
231
+ /** @internal */
232
+ _constructNode(node) {
233
+ return Option.some({
234
+ [graphSymbol]: this,
235
+ data: null,
236
+ properties: {},
237
+ ...node
238
+ });
156
239
  }
157
- getNode(id) {
158
- return this._registry.get(this.node(id));
240
+ };
241
+ var getInternal = (graph) => {
242
+ return graph;
243
+ };
244
+ var toJSON = (graph, id = RootId) => {
245
+ const internal = getInternal(graph);
246
+ return internal._registry.get(internal._json(id));
247
+ };
248
+ var jsonImpl = (graph, id = RootId) => {
249
+ const internal = getInternal(graph);
250
+ return internal._json(id);
251
+ };
252
+ var nodeImpl = (graph, id) => {
253
+ const internal = getInternal(graph);
254
+ return internal._node(id);
255
+ };
256
+ var nodeOrThrowImpl = (graph, id) => {
257
+ const internal = getInternal(graph);
258
+ return internal._nodeOrThrow(id);
259
+ };
260
+ var connectionsImpl = (graph, id, relation = "outbound") => {
261
+ const internal = getInternal(graph);
262
+ return internal._connections(`${id}$${relation}`);
263
+ };
264
+ var actionsImpl = (graph, id) => {
265
+ const internal = getInternal(graph);
266
+ return internal._actions(id);
267
+ };
268
+ var edgesImpl = (graph, id) => {
269
+ const internal = getInternal(graph);
270
+ return internal._edges(id);
271
+ };
272
+ var getNodeImpl = (graph, id) => {
273
+ const internal = getInternal(graph);
274
+ return internal._registry.get(nodeImpl(graph, id));
275
+ };
276
+ function getNode(graphOrId, id) {
277
+ if (typeof graphOrId === "string") {
278
+ const id2 = graphOrId;
279
+ return (graph) => getNodeImpl(graph, id2);
280
+ } else {
281
+ const graph = graphOrId;
282
+ return getNodeImpl(graph, id);
159
283
  }
160
- getNodeOrThrow(id) {
161
- return this._registry.get(this.nodeOrThrow(id));
284
+ }
285
+ var getNodeOrThrowImpl = (graph, id) => {
286
+ const internal = getInternal(graph);
287
+ return internal._registry.get(nodeOrThrowImpl(graph, id));
288
+ };
289
+ function getNodeOrThrow(graphOrId, id) {
290
+ if (typeof graphOrId === "string") {
291
+ const id2 = graphOrId;
292
+ return (graph) => getNodeOrThrowImpl(graph, id2);
293
+ } else {
294
+ const graph = graphOrId;
295
+ return getNodeOrThrowImpl(graph, id);
162
296
  }
163
- getConnections(id, relation = "outbound") {
164
- return this._registry.get(this.connections(id, relation));
297
+ }
298
+ function getRoot(graph) {
299
+ return getNodeOrThrowImpl(graph, RootId);
300
+ }
301
+ var getConnectionsImpl = (graph, id, relation = "outbound") => {
302
+ const internal = getInternal(graph);
303
+ return internal._registry.get(connectionsImpl(graph, id, relation));
304
+ };
305
+ function getConnections(graphOrId, idOrRelation, relation) {
306
+ if (typeof graphOrId === "string") {
307
+ const id = graphOrId;
308
+ const rel = (typeof idOrRelation === "string" ? "outbound" : idOrRelation) ?? "outbound";
309
+ return (graph) => getConnectionsImpl(graph, id, rel);
310
+ } else {
311
+ const graph = graphOrId;
312
+ const id = idOrRelation;
313
+ const rel = relation ?? "outbound";
314
+ return getConnectionsImpl(graph, id, rel);
165
315
  }
166
- getActions(id) {
167
- return this._registry.get(this.actions(id));
316
+ }
317
+ var getActionsImpl = (graph, id) => {
318
+ const internal = getInternal(graph);
319
+ return internal._registry.get(actionsImpl(graph, id));
320
+ };
321
+ function getActions(graphOrId, id) {
322
+ if (typeof graphOrId === "string") {
323
+ const id2 = graphOrId;
324
+ return (graph) => getActionsImpl(graph, id2);
325
+ } else {
326
+ const graph = graphOrId;
327
+ return getActionsImpl(graph, id);
168
328
  }
169
- getEdges(id) {
170
- return this._registry.get(this.edges(id));
329
+ }
330
+ var getEdgesImpl = (graph, id) => {
331
+ const internal = getInternal(graph);
332
+ return internal._registry.get(edgesImpl(graph, id));
333
+ };
334
+ function getEdges(graphOrId, id) {
335
+ if (typeof graphOrId === "string") {
336
+ const id2 = graphOrId;
337
+ return (graph) => getEdgesImpl(graph, id2);
338
+ } else {
339
+ const graph = graphOrId;
340
+ return getEdgesImpl(graph, id);
171
341
  }
172
- async initialize(id) {
173
- const initialized = Record.get(this._initialized, id).pipe(Option.getOrElse(() => false));
174
- log("initialize", {
175
- id,
176
- initialized
177
- }, {
178
- F: __dxlog_file,
179
- L: 386,
180
- S: this,
181
- C: (f, a) => f(...a)
182
- });
183
- if (!initialized) {
184
- await this._onInitialize?.(id);
185
- Record.set(this._initialized, id, true);
186
- }
342
+ }
343
+ var traverseImpl = (graph, options, path = []) => {
344
+ const { visitor, source = RootId, relation = "outbound" } = options;
345
+ if (path.includes(source)) {
346
+ return;
187
347
  }
188
- expand(id, relation = "outbound") {
189
- const key = `${id}$${relation}`;
190
- const expanded = Record.get(this._expanded, key).pipe(Option.getOrElse(() => false));
191
- log("expand", {
192
- key,
193
- expanded
194
- }, {
195
- F: __dxlog_file,
196
- L: 396,
197
- S: this,
198
- C: (f, a) => f(...a)
348
+ const node = getNodeOrThrow(graph, source);
349
+ const shouldContinue = visitor(node, [
350
+ ...path,
351
+ source
352
+ ]);
353
+ if (shouldContinue === false) {
354
+ return;
355
+ }
356
+ Object.values(getConnections(graph, source, relation)).forEach((child) => traverseImpl(graph, {
357
+ source: child.id,
358
+ relation,
359
+ visitor
360
+ }, [
361
+ ...path,
362
+ source
363
+ ]));
364
+ };
365
+ function traverse(graphOrOptions, optionsOrPath, path) {
366
+ if (typeof graphOrOptions === "object" && "visitor" in graphOrOptions) {
367
+ const options = graphOrOptions;
368
+ const pathArg = Array.isArray(optionsOrPath) ? optionsOrPath : void 0;
369
+ return (graph) => traverseImpl(graph, options, pathArg);
370
+ } else {
371
+ const graph = graphOrOptions;
372
+ const options = optionsOrPath;
373
+ const pathArg = path ?? (Array.isArray(optionsOrPath) ? optionsOrPath : void 0);
374
+ return traverseImpl(graph, options, pathArg);
375
+ }
376
+ }
377
+ var getPathImpl = (graph, params) => {
378
+ return Function.pipe(getNode(graph, params.source ?? "root"), Option.flatMap((node) => {
379
+ let found = Option.none();
380
+ traverseImpl(graph, {
381
+ source: node.id,
382
+ visitor: (node2, path) => {
383
+ if (Option.isSome(found)) {
384
+ return false;
385
+ }
386
+ if (node2.id === params.target) {
387
+ found = Option.some(path);
388
+ }
389
+ }
199
390
  });
200
- if (!expanded) {
201
- this._onExpand?.(id, relation);
202
- Record.set(this._expanded, key, true);
391
+ return found;
392
+ }));
393
+ };
394
+ function getPath(graphOrParams, params) {
395
+ if (params === void 0 && typeof graphOrParams === "object" && "target" in graphOrParams) {
396
+ const params2 = graphOrParams;
397
+ return (graph) => getPathImpl(graph, params2);
398
+ } else {
399
+ const graph = graphOrParams;
400
+ return getPathImpl(graph, params);
401
+ }
402
+ }
403
+ var waitForPathImpl = (graph, params, options) => {
404
+ const { timeout = 5e3, interval = 500 } = options ?? {};
405
+ const path = getPathImpl(graph, params);
406
+ if (Option.isSome(path)) {
407
+ return Promise.resolve(path.value);
408
+ }
409
+ const trigger = new Trigger();
410
+ const i = setInterval(() => {
411
+ const path2 = getPathImpl(graph, params);
412
+ if (Option.isSome(path2)) {
413
+ trigger.wake(path2.value);
203
414
  }
415
+ }, interval);
416
+ return trigger.wait({
417
+ timeout
418
+ }).finally(() => clearInterval(i));
419
+ };
420
+ function waitForPath(graphOrParams, paramsOrOptions, options) {
421
+ if (typeof graphOrParams === "object" && "target" in graphOrParams) {
422
+ const params = graphOrParams;
423
+ const opts = typeof paramsOrOptions === "object" && !("target" in paramsOrOptions) ? paramsOrOptions : void 0;
424
+ return (graph) => waitForPathImpl(graph, params, opts);
425
+ } else {
426
+ const graph = graphOrParams;
427
+ const params = paramsOrOptions;
428
+ return waitForPathImpl(graph, params, options);
204
429
  }
205
- addNodes(nodes) {
206
- Rx.batch(() => {
207
- nodes.map((node) => this.addNode(node));
208
- });
430
+ }
431
+ var initializeImpl = async (graph, id) => {
432
+ const internal = getInternal(graph);
433
+ const initialized = Record.get(internal._initialized, id).pipe(Option.getOrElse(() => false));
434
+ log("initialize", {
435
+ id,
436
+ initialized
437
+ }, {
438
+ F: __dxlog_file,
439
+ L: 661,
440
+ S: void 0,
441
+ C: (f, a) => f(...a)
442
+ });
443
+ if (!initialized) {
444
+ await internal._onInitialize?.(id);
445
+ Record.set(internal._initialized, id, true);
209
446
  }
210
- addNode({ nodes, edges, ...nodeArg }) {
211
- const { id, type, data = null, properties = {} } = nodeArg;
212
- const nodeRx = this._node(id);
213
- const node = this._registry.get(nodeRx);
214
- Option.match(node, {
215
- onSome: (node2) => {
216
- const typeChanged = node2.type !== type;
217
- const dataChanged = node2.data !== data;
218
- const propertiesChanged = Object.keys(properties).some((key) => node2.properties[key] !== properties[key]);
219
- log("existing node", {
220
- id,
221
- typeChanged,
222
- dataChanged,
223
- propertiesChanged
224
- }, {
225
- F: __dxlog_file,
226
- L: 418,
227
- S: this,
228
- C: (f, a) => f(...a)
229
- });
230
- if (typeChanged || dataChanged || propertiesChanged) {
231
- log("updating node", {
232
- id,
233
- type,
234
- data,
235
- properties
236
- }, {
237
- F: __dxlog_file,
238
- L: 420,
239
- S: this,
240
- C: (f, a) => f(...a)
241
- });
242
- const newNode = Option.some({
243
- ...node2,
244
- type,
245
- data,
246
- properties: {
247
- ...node2.properties,
248
- ...properties
249
- }
250
- });
251
- this._registry.set(nodeRx, newNode);
252
- this.onNodeChanged.emit({
253
- id,
254
- node: newNode
255
- });
256
- }
257
- },
258
- onNone: () => {
259
- log("new node", {
447
+ return graph;
448
+ };
449
+ function initialize(graphOrId, id) {
450
+ if (typeof graphOrId === "string") {
451
+ const id2 = graphOrId;
452
+ return (graph) => initializeImpl(graph, id2);
453
+ } else {
454
+ const graph = graphOrId;
455
+ return initializeImpl(graph, id);
456
+ }
457
+ }
458
+ var expandImpl = (graph, id, relation = "outbound") => {
459
+ const internal = getInternal(graph);
460
+ const key = `${id}$${relation}`;
461
+ const expanded = Record.get(internal._expanded, key).pipe(Option.getOrElse(() => false));
462
+ log("expand", {
463
+ key,
464
+ expanded
465
+ }, {
466
+ F: __dxlog_file,
467
+ L: 702,
468
+ S: void 0,
469
+ C: (f, a) => f(...a)
470
+ });
471
+ if (!expanded) {
472
+ internal._onExpand?.(id, relation);
473
+ Record.set(internal._expanded, key, true);
474
+ }
475
+ return graph;
476
+ };
477
+ function expand(graphOrId, idOrRelation, relation) {
478
+ if (typeof graphOrId === "string") {
479
+ const id = graphOrId;
480
+ const rel = (typeof idOrRelation === "string" ? "outbound" : idOrRelation) ?? "outbound";
481
+ return (graph) => expandImpl(graph, id, rel);
482
+ } else {
483
+ const graph = graphOrId;
484
+ const id = idOrRelation;
485
+ const rel = relation ?? "outbound";
486
+ return expandImpl(graph, id, rel);
487
+ }
488
+ }
489
+ var sortEdgesImpl = (graph, id, relation, order) => {
490
+ const internal = getInternal(graph);
491
+ const edgesAtom = internal._edges(id);
492
+ const edges = internal._registry.get(edgesAtom);
493
+ const unsorted = edges[relation].filter((id2) => !order.includes(id2)) ?? [];
494
+ const sorted = order.filter((id2) => edges[relation].includes(id2)) ?? [];
495
+ edges[relation].splice(0, edges[relation].length, ...[
496
+ ...sorted,
497
+ ...unsorted
498
+ ]);
499
+ internal._registry.set(edgesAtom, edges);
500
+ return graph;
501
+ };
502
+ function sortEdges(graphOrId, idOrRelation, relationOrOrder, order) {
503
+ if (typeof graphOrId === "string") {
504
+ const id = graphOrId;
505
+ const relation = idOrRelation;
506
+ const order2 = relationOrOrder;
507
+ return (graph) => sortEdgesImpl(graph, id, relation, order2);
508
+ } else {
509
+ const graph = graphOrId;
510
+ const id = idOrRelation;
511
+ const relation = relationOrOrder;
512
+ return sortEdgesImpl(graph, id, relation, order);
513
+ }
514
+ }
515
+ var addNodesImpl = (graph, nodes) => {
516
+ Atom2.batch(() => {
517
+ nodes.map((node) => addNodeImpl(graph, node));
518
+ });
519
+ return graph;
520
+ };
521
+ function addNodes(graphOrNodes, nodes) {
522
+ if (nodes === void 0) {
523
+ const nodes2 = graphOrNodes;
524
+ return (graph) => addNodesImpl(graph, nodes2);
525
+ } else {
526
+ const graph = graphOrNodes;
527
+ return addNodesImpl(graph, nodes);
528
+ }
529
+ }
530
+ var addNodeImpl = (graph, nodeArg) => {
531
+ const internal = getInternal(graph);
532
+ const { nodes, edges, id, type, data = null, properties = {}, ...rest } = nodeArg;
533
+ const nodeAtom = internal._node(id);
534
+ const existingNode = internal._registry.get(nodeAtom);
535
+ Option.match(existingNode, {
536
+ onSome: (existing) => {
537
+ const typeChanged = existing.type !== type;
538
+ const dataChanged = existing.data !== data;
539
+ const propertiesChanged = Object.keys(properties).some((key) => existing.properties[key] !== properties[key]);
540
+ log("existing node", {
541
+ id,
542
+ typeChanged,
543
+ dataChanged,
544
+ propertiesChanged
545
+ }, {
546
+ F: __dxlog_file,
547
+ L: 847,
548
+ S: void 0,
549
+ C: (f, a) => f(...a)
550
+ });
551
+ if (typeChanged || dataChanged || propertiesChanged) {
552
+ log("updating node", {
260
553
  id,
261
554
  type,
262
555
  data,
263
556
  properties
264
557
  }, {
265
558
  F: __dxlog_file,
266
- L: 427,
267
- S: this,
559
+ L: 854,
560
+ S: void 0,
268
561
  C: (f, a) => f(...a)
269
562
  });
270
- const newNode = this._constructNode({
271
- id,
563
+ const newNode = Option.some({
564
+ ...existing,
565
+ ...rest,
272
566
  type,
273
567
  data,
274
- properties
568
+ properties: {
569
+ ...existing.properties,
570
+ ...properties
571
+ }
275
572
  });
276
- this._registry.set(nodeRx, newNode);
277
- this.onNodeChanged.emit({
573
+ internal._registry.set(nodeAtom, newNode);
574
+ graph.onNodeChanged.emit({
278
575
  id,
279
576
  node: newNode
280
577
  });
281
578
  }
282
- });
283
- if (nodes) {
284
- this.addNodes(nodes);
285
- const _edges = nodes.map((node2) => ({
286
- source: id,
287
- target: node2.id
288
- }));
289
- this.addEdges(_edges);
290
- }
291
- if (edges) {
292
- todo();
293
- }
294
- }
295
- removeNodes(ids, edges = false) {
296
- Rx.batch(() => {
297
- ids.map((id) => this.removeNode(id, edges));
298
- });
299
- }
300
- removeNode(id, edges = false) {
301
- const nodeRx = this._node(id);
302
- this._registry.set(nodeRx, Option.none());
303
- this.onNodeChanged.emit({
304
- id,
305
- node: Option.none()
306
- });
307
- if (edges) {
308
- const { inbound, outbound } = this._registry.get(this._edges(id));
309
- const edges2 = [
310
- ...inbound.map((source) => ({
311
- source,
312
- target: id
313
- })),
314
- ...outbound.map((target) => ({
315
- source: id,
316
- target
317
- }))
318
- ];
319
- this.removeEdges(edges2);
320
- }
321
- this._onRemoveNode?.(id);
322
- }
323
- addEdges(edges) {
324
- Rx.batch(() => {
325
- edges.map((edge) => this.addEdge(edge));
326
- });
327
- }
328
- addEdge(edgeArg) {
329
- const sourceRx = this._edges(edgeArg.source);
330
- const source = this._registry.get(sourceRx);
331
- if (!source.outbound.includes(edgeArg.target)) {
332
- log("add outbound edge", {
333
- source: edgeArg.source,
334
- target: edgeArg.target
579
+ },
580
+ onNone: () => {
581
+ log("new node", {
582
+ id,
583
+ type,
584
+ data,
585
+ properties
335
586
  }, {
336
587
  F: __dxlog_file,
337
- L: 482,
338
- S: this,
588
+ L: 867,
589
+ S: void 0,
339
590
  C: (f, a) => f(...a)
340
591
  });
341
- this._registry.set(sourceRx, {
342
- inbound: source.inbound,
343
- outbound: [
344
- ...source.outbound,
345
- edgeArg.target
346
- ]
347
- });
348
- }
349
- const targetRx = this._edges(edgeArg.target);
350
- const target = this._registry.get(targetRx);
351
- if (!target.inbound.includes(edgeArg.source)) {
352
- log("add inbound edge", {
353
- source: edgeArg.source,
354
- target: edgeArg.target
355
- }, {
356
- F: __dxlog_file,
357
- L: 489,
358
- S: this,
359
- C: (f, a) => f(...a)
592
+ const newNode = internal._constructNode({
593
+ id,
594
+ type,
595
+ data,
596
+ properties,
597
+ ...rest
360
598
  });
361
- this._registry.set(targetRx, {
362
- inbound: [
363
- ...target.inbound,
364
- edgeArg.source
365
- ],
366
- outbound: target.outbound
599
+ internal._registry.set(nodeAtom, newNode);
600
+ graph.onNodeChanged.emit({
601
+ id,
602
+ node: newNode
367
603
  });
368
604
  }
605
+ });
606
+ if (nodes) {
607
+ addNodesImpl(graph, nodes);
608
+ const _edges = nodes.map((node) => ({
609
+ source: id,
610
+ target: node.id
611
+ }));
612
+ addEdgesImpl(graph, _edges);
613
+ }
614
+ if (edges) {
615
+ todo();
616
+ }
617
+ return graph;
618
+ };
619
+ function addNode(graphOrNodeArg, nodeArg) {
620
+ if (nodeArg === void 0) {
621
+ const nodeArg2 = graphOrNodeArg;
622
+ return (graph) => addNodeImpl(graph, nodeArg2);
623
+ } else {
624
+ const graph = graphOrNodeArg;
625
+ return addNodeImpl(graph, nodeArg);
626
+ }
627
+ }
628
+ var removeNodesImpl = (graph, ids, edges = false) => {
629
+ Atom2.batch(() => {
630
+ ids.map((id) => removeNodeImpl(graph, id, edges));
631
+ });
632
+ return graph;
633
+ };
634
+ function removeNodes(graphOrIds, idsOrEdges, edges) {
635
+ if (Array.isArray(graphOrIds)) {
636
+ const ids = graphOrIds;
637
+ const edgesArg = typeof idsOrEdges === "boolean" ? idsOrEdges : false;
638
+ return (graph) => removeNodesImpl(graph, ids, edgesArg);
639
+ } else {
640
+ const graph = graphOrIds;
641
+ const ids = idsOrEdges;
642
+ const edgesArg = edges ?? false;
643
+ return removeNodesImpl(graph, ids, edgesArg);
644
+ }
645
+ }
646
+ var removeNodeImpl = (graph, id, edges = false) => {
647
+ const internal = getInternal(graph);
648
+ const nodeAtom = internal._node(id);
649
+ internal._registry.set(nodeAtom, Option.none());
650
+ graph.onNodeChanged.emit({
651
+ id,
652
+ node: Option.none()
653
+ });
654
+ if (edges) {
655
+ const { inbound, outbound } = internal._registry.get(internal._edges(id));
656
+ const edgesToRemove = [
657
+ ...inbound.map((source) => ({
658
+ source,
659
+ target: id
660
+ })),
661
+ ...outbound.map((target) => ({
662
+ source: id,
663
+ target
664
+ }))
665
+ ];
666
+ removeEdgesImpl(graph, edgesToRemove);
667
+ }
668
+ internal._onRemoveNode?.(id);
669
+ return graph;
670
+ };
671
+ function removeNode(graphOrId, idOrEdges, edges) {
672
+ if (typeof graphOrId === "string") {
673
+ const id = graphOrId;
674
+ const edgesArg = typeof idOrEdges === "boolean" ? idOrEdges : false;
675
+ return (graph) => removeNodeImpl(graph, id, edgesArg);
676
+ } else {
677
+ const graph = graphOrId;
678
+ const id = idOrEdges;
679
+ const edgesArg = edges ?? false;
680
+ return removeNodeImpl(graph, id, edgesArg);
681
+ }
682
+ }
683
+ var addEdgesImpl = (graph, edges) => {
684
+ Atom2.batch(() => {
685
+ edges.map((edge) => addEdgeImpl(graph, edge));
686
+ });
687
+ return graph;
688
+ };
689
+ function addEdges(graphOrEdges, edges) {
690
+ if (edges === void 0) {
691
+ const edges2 = graphOrEdges;
692
+ return (graph) => addEdgesImpl(graph, edges2);
693
+ } else {
694
+ const graph = graphOrEdges;
695
+ return addEdgesImpl(graph, edges);
369
696
  }
370
- removeEdges(edges, removeOrphans = false) {
371
- Rx.batch(() => {
372
- edges.map((edge) => this.removeEdge(edge, removeOrphans));
697
+ }
698
+ var addEdgeImpl = (graph, edgeArg) => {
699
+ const internal = getInternal(graph);
700
+ const sourceAtom = internal._edges(edgeArg.source);
701
+ const source = internal._registry.get(sourceAtom);
702
+ if (!source.outbound.includes(edgeArg.target)) {
703
+ log("add outbound edge", {
704
+ source: edgeArg.source,
705
+ target: edgeArg.target
706
+ }, {
707
+ F: __dxlog_file,
708
+ L: 1026,
709
+ S: void 0,
710
+ C: (f, a) => f(...a)
711
+ });
712
+ internal._registry.set(sourceAtom, {
713
+ inbound: source.inbound,
714
+ outbound: [
715
+ ...source.outbound,
716
+ edgeArg.target
717
+ ]
373
718
  });
374
719
  }
375
- removeEdge(edgeArg, removeOrphans = false) {
376
- const sourceRx = this._edges(edgeArg.source);
377
- const source = this._registry.get(sourceRx);
378
- if (source.outbound.includes(edgeArg.target)) {
379
- this._registry.set(sourceRx, {
380
- inbound: source.inbound,
381
- outbound: source.outbound.filter((id) => id !== edgeArg.target)
382
- });
383
- }
384
- const targetRx = this._edges(edgeArg.target);
385
- const target = this._registry.get(targetRx);
386
- if (target.inbound.includes(edgeArg.source)) {
387
- this._registry.set(targetRx, {
388
- inbound: target.inbound.filter((id) => id !== edgeArg.source),
389
- outbound: target.outbound
390
- });
391
- }
392
- if (removeOrphans) {
393
- const source2 = this._registry.get(sourceRx);
394
- const target2 = this._registry.get(targetRx);
395
- if (source2.outbound.length === 0 && source2.inbound.length === 0 && edgeArg.source !== ROOT_ID) {
396
- this.removeNodes([
397
- edgeArg.source
398
- ]);
399
- }
400
- if (target2.outbound.length === 0 && target2.inbound.length === 0 && edgeArg.target !== ROOT_ID) {
401
- this.removeNodes([
402
- edgeArg.target
403
- ]);
404
- }
405
- }
720
+ const targetAtom = internal._edges(edgeArg.target);
721
+ const target = internal._registry.get(targetAtom);
722
+ if (!target.inbound.includes(edgeArg.source)) {
723
+ log("add inbound edge", {
724
+ source: edgeArg.source,
725
+ target: edgeArg.target
726
+ }, {
727
+ F: __dxlog_file,
728
+ L: 1039,
729
+ S: void 0,
730
+ C: (f, a) => f(...a)
731
+ });
732
+ internal._registry.set(targetAtom, {
733
+ inbound: [
734
+ ...target.inbound,
735
+ edgeArg.source
736
+ ],
737
+ outbound: target.outbound
738
+ });
406
739
  }
407
- sortEdges(id, relation, order) {
408
- const edgesRx = this._edges(id);
409
- const edges = this._registry.get(edgesRx);
410
- const unsorted = edges[relation].filter((id2) => !order.includes(id2)) ?? [];
411
- const sorted = order.filter((id2) => edges[relation].includes(id2)) ?? [];
412
- edges[relation].splice(0, edges[relation].length, ...[
413
- ...sorted,
414
- ...unsorted
415
- ]);
416
- this._registry.set(edgesRx, edges);
740
+ return graph;
741
+ };
742
+ function addEdge(graphOrEdgeArg, edgeArg) {
743
+ if (edgeArg === void 0) {
744
+ const edgeArg2 = graphOrEdgeArg;
745
+ return (graph) => addEdgeImpl(graph, edgeArg2);
746
+ } else {
747
+ const graph = graphOrEdgeArg;
748
+ return addEdgeImpl(graph, edgeArg);
417
749
  }
418
- traverse({ visitor, source = ROOT_ID, relation = "outbound" }, path = []) {
419
- if (path.includes(source)) {
420
- return;
421
- }
422
- const node = this.getNodeOrThrow(source);
423
- const shouldContinue = visitor(node, [
424
- ...path,
425
- source
426
- ]);
427
- if (shouldContinue === false) {
428
- return;
429
- }
430
- Object.values(this.getConnections(source, relation)).forEach((child) => this.traverse({
431
- source: child.id,
432
- relation,
433
- visitor
434
- }, [
435
- ...path,
436
- source
437
- ]));
438
- }
439
- getPath({ source = "root", target }) {
440
- return Function.pipe(this.getNode(source), Option.flatMap((node) => {
441
- let found = Option.none();
442
- this.traverse({
443
- source: node.id,
444
- visitor: (node2, path) => {
445
- if (Option.isSome(found)) {
446
- return false;
447
- }
448
- if (node2.id === target) {
449
- found = Option.some(path);
450
- }
451
- }
452
- });
453
- return found;
454
- }));
750
+ }
751
+ var removeEdgesImpl = (graph, edges, removeOrphans = false) => {
752
+ Atom2.batch(() => {
753
+ edges.map((edge) => removeEdgeImpl(graph, edge, removeOrphans));
754
+ });
755
+ return graph;
756
+ };
757
+ function removeEdges(graphOrEdges, edgesOrRemoveOrphans, removeOrphans) {
758
+ if (Array.isArray(graphOrEdges)) {
759
+ const edges = graphOrEdges;
760
+ const removeOrphansArg = typeof edgesOrRemoveOrphans === "boolean" ? edgesOrRemoveOrphans : false;
761
+ return (graph) => removeEdgesImpl(graph, edges, removeOrphansArg);
762
+ } else {
763
+ const graph = graphOrEdges;
764
+ const edges = edgesOrRemoveOrphans;
765
+ const removeOrphansArg = removeOrphans ?? false;
766
+ return removeEdgesImpl(graph, edges, removeOrphansArg);
455
767
  }
456
- async waitForPath(params, { timeout = 5e3, interval = 500 } = {}) {
457
- const path = this.getPath(params);
458
- if (Option.isSome(path)) {
459
- return path.value;
460
- }
461
- const trigger = new Trigger();
462
- const i = setInterval(() => {
463
- const path2 = this.getPath(params);
464
- if (Option.isSome(path2)) {
465
- trigger.wake(path2.value);
466
- }
467
- }, interval);
468
- return trigger.wait({
469
- timeout
470
- }).finally(() => clearInterval(i));
768
+ }
769
+ var removeEdgeImpl = (graph, edgeArg, removeOrphans = false) => {
770
+ const internal = getInternal(graph);
771
+ const sourceAtom = internal._edges(edgeArg.source);
772
+ const source = internal._registry.get(sourceAtom);
773
+ if (source.outbound.includes(edgeArg.target)) {
774
+ internal._registry.set(sourceAtom, {
775
+ inbound: source.inbound,
776
+ outbound: source.outbound.filter((id) => id !== edgeArg.target)
777
+ });
471
778
  }
472
- /** @internal */
473
- _constructNode(node) {
474
- return Option.some({
475
- [graphSymbol]: this,
476
- data: null,
477
- properties: {},
478
- ...node
779
+ const targetAtom = internal._edges(edgeArg.target);
780
+ const target = internal._registry.get(targetAtom);
781
+ if (target.inbound.includes(edgeArg.source)) {
782
+ internal._registry.set(targetAtom, {
783
+ inbound: target.inbound.filter((id) => id !== edgeArg.source),
784
+ outbound: target.outbound
479
785
  });
480
786
  }
787
+ if (removeOrphans) {
788
+ const source2 = internal._registry.get(sourceAtom);
789
+ const target2 = internal._registry.get(targetAtom);
790
+ if (source2.outbound.length === 0 && source2.inbound.length === 0 && edgeArg.source !== RootId) {
791
+ removeNodesImpl(graph, [
792
+ edgeArg.source
793
+ ]);
794
+ }
795
+ if (target2.outbound.length === 0 && target2.inbound.length === 0 && edgeArg.target !== RootId) {
796
+ removeNodesImpl(graph, [
797
+ edgeArg.target
798
+ ]);
799
+ }
800
+ }
801
+ return graph;
802
+ };
803
+ function removeEdge(graphOrEdgeArg, edgeArgOrRemoveOrphans, removeOrphans) {
804
+ if (edgeArgOrRemoveOrphans === void 0 || typeof edgeArgOrRemoveOrphans === "boolean" || "source" in graphOrEdgeArg) {
805
+ const edgeArg = graphOrEdgeArg;
806
+ const removeOrphansArg = typeof edgeArgOrRemoveOrphans === "boolean" ? edgeArgOrRemoveOrphans : false;
807
+ return (graph) => removeEdgeImpl(graph, edgeArg, removeOrphansArg);
808
+ } else {
809
+ const graph = graphOrEdgeArg;
810
+ const edgeArg = edgeArgOrRemoveOrphans;
811
+ const removeOrphansArg = removeOrphans ?? false;
812
+ return removeEdgeImpl(graph, edgeArg, removeOrphansArg);
813
+ }
814
+ }
815
+ var make = (params) => {
816
+ return new GraphImpl(params);
481
817
  };
482
818
 
483
819
  // src/graph-builder.ts
484
- import { Registry as Registry2, Rx as Rx2 } from "@effect-rx/rx-react";
485
- import { effect } from "@preact/signals-core";
486
- import * as Array from "effect/Array";
820
+ var graph_builder_exports = {};
821
+ __export(graph_builder_exports, {
822
+ GraphBuilderTypeId: () => GraphBuilderTypeId,
823
+ addExtension: () => addExtension,
824
+ createConnector: () => createConnector,
825
+ createExtension: () => createExtension,
826
+ createExtensionRaw: () => createExtensionRaw,
827
+ createTypeExtension: () => createTypeExtension,
828
+ destroy: () => destroy,
829
+ explore: () => explore,
830
+ flattenExtensions: () => flattenExtensions,
831
+ from: () => from,
832
+ make: () => make2,
833
+ removeExtension: () => removeExtension
834
+ });
835
+ import { Atom as Atom3, Registry as Registry2 } from "@effect-atom/atom-react";
836
+ import * as Array2 from "effect/Array";
837
+ import * as Effect from "effect/Effect";
487
838
  import * as Function2 from "effect/Function";
488
- import * as Option2 from "effect/Option";
839
+ import * as Option3 from "effect/Option";
840
+ import * as Pipeable2 from "effect/Pipeable";
489
841
  import * as Record2 from "effect/Record";
490
842
  import { log as log2 } from "@dxos/log";
491
843
  import { byPosition, getDebugName, isNode, isNonNullable as isNonNullable2 } from "@dxos/util";
492
844
 
493
- // src/node.ts
494
- var isGraphNode = (data) => data && typeof data === "object" && "id" in data && "properties" in data && data.properties ? typeof data.properties === "object" && "data" in data : false;
495
- var isAction = (data) => isGraphNode(data) ? typeof data.data === "function" && data.type === ACTION_TYPE : false;
496
- var actionGroupSymbol = Symbol("ActionGroup");
497
- var isActionGroup = (data) => isGraphNode(data) ? data.data === actionGroupSymbol && data.type === ACTION_GROUP_TYPE : false;
498
- var isActionLike = (data) => isAction(data) || isActionGroup(data);
845
+ // src/node-matcher.ts
846
+ var node_matcher_exports = {};
847
+ __export(node_matcher_exports, {
848
+ whenAll: () => whenAll,
849
+ whenAny: () => whenAny,
850
+ whenEchoObject: () => whenEchoObject,
851
+ whenEchoObjectMatches: () => whenEchoObjectMatches,
852
+ whenEchoType: () => whenEchoType,
853
+ whenEchoTypeMatches: () => whenEchoTypeMatches,
854
+ whenId: () => whenId,
855
+ whenNodeType: () => whenNodeType,
856
+ whenNot: () => whenNot,
857
+ whenRoot: () => whenRoot
858
+ });
859
+ import * as Option2 from "effect/Option";
860
+ import { Obj } from "@dxos/echo";
861
+ var whenRoot = (node) => node.id === RootId ? Option2.some(node) : Option2.none();
862
+ var whenId = (id) => (node) => node.id === id ? Option2.some(node) : Option2.none();
863
+ var whenNodeType = (type) => (node) => node.type === type ? Option2.some(node) : Option2.none();
864
+ var whenEchoType = (type) => (node) => Obj.instanceOf(type, node.data) ? Option2.some(node.data) : Option2.none();
865
+ var whenEchoObject = (node) => Obj.isObject(node.data) ? Option2.some(node.data) : Option2.none();
866
+ var whenAll = (...matchers) => (node) => {
867
+ for (const matcher of matchers) {
868
+ const result = matcher(node);
869
+ if (Option2.isNone(result)) {
870
+ return Option2.none();
871
+ }
872
+ }
873
+ return Option2.some(node);
874
+ };
875
+ var whenAny = (...matchers) => (node) => {
876
+ for (const matcher of matchers) {
877
+ const result = matcher(node);
878
+ if (Option2.isSome(result)) {
879
+ return Option2.some(node);
880
+ }
881
+ }
882
+ return Option2.none();
883
+ };
884
+ var whenEchoTypeMatches = (type) => (node) => Obj.instanceOf(type, node.data) ? Option2.some(node) : Option2.none();
885
+ var whenEchoObjectMatches = (node) => Obj.isObject(node.data) ? Option2.some(node) : Option2.none();
886
+ var whenNot = (matcher) => (node) => Option2.isNone(matcher(node)) ? Option2.some(node) : Option2.none();
499
887
 
500
888
  // src/graph-builder.ts
501
889
  var __dxlog_file2 = "/__w/dxos/dxos/packages/sdk/app-graph/src/graph-builder.ts";
502
- var createExtension = (extension) => {
503
- const { id, position = "static", relation = "outbound", resolver: _resolver, connector: _connector, actions: _actions, actionGroups: _actionGroups } = extension;
504
- const getId = (key) => `${id}/${key}`;
505
- const resolver = _resolver && Rx2.family((id2) => _resolver(id2).pipe(Rx2.withLabel(`graph-builder:_resolver:${id2}`)));
506
- const connector = _connector && Rx2.family((node) => _connector(node).pipe(Rx2.withLabel(`graph-builder:_connector:${id}`)));
507
- const actionGroups = _actionGroups && Rx2.family((node) => _actionGroups(node).pipe(Rx2.withLabel(`graph-builder:_actionGroups:${id}`)));
508
- const actions = _actions && Rx2.family((node) => _actions(node).pipe(Rx2.withLabel(`graph-builder:_actions:${id}`)));
509
- return [
510
- resolver ? {
511
- id: getId("resolver"),
512
- position,
513
- resolver
514
- } : void 0,
515
- connector ? {
516
- id: getId("connector"),
517
- position,
518
- relation,
519
- connector: Rx2.family((node) => Rx2.make((get2) => {
520
- try {
521
- return get2(connector(node));
522
- } catch {
523
- log2.warn("Error in connector", {
524
- id: getId("connector"),
525
- node
526
- }, {
527
- F: __dxlog_file2,
528
- L: 112,
529
- S: void 0,
530
- C: (f, a) => f(...a)
531
- });
532
- return [];
533
- }
534
- }).pipe(Rx2.withLabel(`graph-builder:connector:${id}`)))
535
- } : void 0,
536
- actionGroups ? {
537
- id: getId("actionGroups"),
538
- position,
539
- relation: "outbound",
540
- connector: Rx2.family((node) => Rx2.make((get2) => {
541
- try {
542
- return get2(actionGroups(node)).map((arg) => ({
543
- ...arg,
544
- data: actionGroupSymbol,
545
- type: ACTION_GROUP_TYPE
546
- }));
547
- } catch {
548
- log2.warn("Error in actionGroups", {
549
- id: getId("actionGroups"),
550
- node
551
- }, {
552
- F: __dxlog_file2,
553
- L: 133,
554
- S: void 0,
555
- C: (f, a) => f(...a)
556
- });
557
- return [];
558
- }
559
- }).pipe(Rx2.withLabel(`graph-builder:connector:actionGroups:${id}`)))
560
- } : void 0,
561
- actions ? {
562
- id: getId("actions"),
563
- position,
564
- relation: "outbound",
565
- connector: Rx2.family((node) => Rx2.make((get2) => {
566
- try {
567
- return get2(actions(node)).map((arg) => ({
568
- ...arg,
569
- type: ACTION_TYPE
570
- }));
571
- } catch {
572
- log2.warn("Error in actions", {
573
- id: getId("actions"),
574
- node
575
- }, {
576
- F: __dxlog_file2,
577
- L: 150,
578
- S: void 0,
579
- C: (f, a) => f(...a)
580
- });
581
- return [];
582
- }
583
- }).pipe(Rx2.withLabel(`graph-builder:connector:actions:${id}`)))
584
- } : void 0
585
- ].filter(isNonNullable2);
586
- };
587
- var flattenExtensions = (extension, acc = []) => {
588
- if (Array.isArray(extension)) {
589
- return [
590
- ...acc,
591
- ...extension.flatMap((ext) => flattenExtensions(ext, acc))
592
- ];
593
- } else {
594
- return [
595
- ...acc,
596
- extension
597
- ];
890
+ var GraphBuilderTypeId = Symbol.for("@dxos/app-graph/GraphBuilder");
891
+ var GraphBuilderImpl = class {
892
+ [GraphBuilderTypeId] = GraphBuilderTypeId;
893
+ pipe() {
894
+ return Pipeable2.pipeArguments(this, arguments);
598
895
  }
599
- };
600
- var GraphBuilder = class _GraphBuilder {
601
896
  // TODO(wittjosiah): Use Context.
602
897
  _subscriptions = /* @__PURE__ */ new Map();
603
- _extensions = Rx2.make(Record2.empty()).pipe(Rx2.keepAlive, Rx2.withLabel("graph-builder:extensions"));
898
+ _extensions = Atom3.make(Record2.empty()).pipe(Atom3.keepAlive, Atom3.withLabel("graph-builder:extensions"));
604
899
  _initialized = {};
605
900
  _registry;
606
901
  _graph;
607
902
  constructor({ registry, ...params } = {}) {
608
903
  this._registry = registry ?? Registry2.make();
609
- this._graph = new Graph({
904
+ const graph = make({
610
905
  ...params,
611
906
  registry: this._registry,
612
907
  onExpand: (id, relation) => this._onExpand(id, relation),
613
908
  onInitialize: (id) => this._onInitialize(id),
614
909
  onRemoveNode: (id) => this._onRemoveNode(id)
615
910
  });
616
- }
617
- static from(pickle, registry) {
618
- if (!pickle) {
619
- return new _GraphBuilder({
620
- registry
621
- });
622
- }
623
- const { nodes, edges } = JSON.parse(pickle);
624
- return new _GraphBuilder({
625
- nodes,
626
- edges,
627
- registry
628
- });
911
+ this._graph = graph;
629
912
  }
630
913
  get graph() {
631
914
  return this._graph;
@@ -633,76 +916,26 @@ var GraphBuilder = class _GraphBuilder {
633
916
  get extensions() {
634
917
  return this._extensions;
635
918
  }
636
- addExtension(extensions) {
637
- flattenExtensions(extensions).forEach((extension) => {
638
- const extensions2 = this._registry.get(this._extensions);
639
- this._registry.set(this._extensions, Record2.set(extensions2, extension.id, extension));
640
- });
641
- return this;
642
- }
643
- removeExtension(id) {
644
- const extensions = this._registry.get(this._extensions);
645
- this._registry.set(this._extensions, Record2.remove(extensions, id));
646
- return this;
647
- }
648
- async explore({ registry = Registry2.make(), source = ROOT_ID, relation = "outbound", visitor }, path = []) {
649
- if (path.includes(source)) {
650
- return;
651
- }
652
- if (!isNode()) {
653
- const { yieldOrContinue } = await import("main-thread-scheduling");
654
- await yieldOrContinue("idle");
655
- }
656
- const node = registry.get(this._graph.nodeOrThrow(source));
657
- const shouldContinue = await visitor(node, [
658
- ...path,
659
- node.id
660
- ]);
661
- if (shouldContinue === false) {
662
- return;
663
- }
664
- const nodes = Object.values(this._registry.get(this._extensions)).filter((extension) => relation === (extension.relation ?? "outbound")).map((extension) => extension.connector).filter(isNonNullable2).flatMap((connector) => registry.get(connector(this._graph.node(source))));
665
- await Promise.all(nodes.map((nodeArg) => {
666
- registry.set(this._graph._node(nodeArg.id), this._graph._constructNode(nodeArg));
667
- return this.explore({
668
- registry,
669
- source: nodeArg.id,
670
- relation,
671
- visitor
672
- }, [
673
- ...path,
674
- node.id
675
- ]);
676
- }));
677
- if (registry !== this._registry) {
678
- registry.reset();
679
- registry.dispose();
680
- }
681
- }
682
- destroy() {
683
- this._subscriptions.forEach((unsubscribe) => unsubscribe());
684
- this._subscriptions.clear();
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);
919
+ _resolvers = Atom3.family((id) => {
920
+ return Atom3.make((get2) => {
921
+ 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);
689
922
  });
690
923
  });
691
- _connectors = Rx2.family((key) => {
692
- return Rx2.make((get2) => {
924
+ _connectors = Atom3.family((key) => {
925
+ return Atom3.make((get2) => {
693
926
  const [id, relation] = key.split("+");
694
927
  const node = this._graph.node(id);
695
928
  return Function2.pipe(
696
929
  get2(this._extensions),
697
930
  Record2.values,
698
931
  // 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))
932
+ Array2.sortBy(byPosition),
933
+ Array2.filter(({ relation: _relation = "outbound" }) => _relation === relation),
934
+ Array2.map(({ connector }) => connector?.(node)),
935
+ Array2.filter(isNonNullable2),
936
+ Array2.flatMap((result) => get2(result))
704
937
  );
705
- }).pipe(Rx2.withLabel(`graph-builder:connectors:${key}`));
938
+ }).pipe(Atom3.withLabel(`graph-builder:connectors:${key}`));
706
939
  });
707
940
  _onExpand(id, relation) {
708
941
  log2("onExpand", {
@@ -711,7 +944,7 @@ var GraphBuilder = class _GraphBuilder {
711
944
  registry: getDebugName(this._registry)
712
945
  }, {
713
946
  F: __dxlog_file2,
714
- L: 327,
947
+ L: 176,
715
948
  S: this,
716
949
  C: (f, a) => f(...a)
717
950
  });
@@ -728,25 +961,25 @@ var GraphBuilder = class _GraphBuilder {
728
961
  removed
729
962
  }, {
730
963
  F: __dxlog_file2,
731
- L: 338,
964
+ L: 187,
732
965
  S: this,
733
966
  C: (f, a) => f(...a)
734
967
  });
735
968
  const update = () => {
736
- Rx2.batch(() => {
737
- this._graph.removeEdges(removed.map((target) => ({
969
+ Atom3.batch(() => {
970
+ removeEdges(this._graph, removed.map((target) => ({
738
971
  source: id,
739
972
  target
740
973
  })), true);
741
- this._graph.addNodes(nodes);
742
- this._graph.addEdges(nodes.map((node) => relation === "outbound" ? {
974
+ addNodes(this._graph, nodes);
975
+ addEdges(this._graph, nodes.map((node) => relation === "outbound" ? {
743
976
  source: id,
744
977
  target: node.id
745
978
  } : {
746
979
  source: node.id,
747
980
  target: id
748
981
  }));
749
- this._graph.sortEdges(id, relation, nodes.map(({ id: id2 }) => id2));
982
+ sortEdges(this._graph, id, relation, nodes.map(({ id: id2 }) => id2));
750
983
  });
751
984
  };
752
985
  if (typeof requestAnimationFrame === "function") {
@@ -765,23 +998,23 @@ var GraphBuilder = class _GraphBuilder {
765
998
  id
766
999
  }, {
767
1000
  F: __dxlog_file2,
768
- L: 375,
1001
+ L: 227,
769
1002
  S: this,
770
1003
  C: (f, a) => f(...a)
771
1004
  });
772
1005
  const resolver = this._resolvers(id);
773
1006
  const cancel = this._registry.subscribe(resolver, (node) => {
774
1007
  const trigger = this._initialized[id];
775
- Option2.match(node, {
1008
+ Option3.match(node, {
776
1009
  onSome: (node2) => {
777
- this._graph.addNodes([
1010
+ addNodes(this._graph, [
778
1011
  node2
779
1012
  ]);
780
1013
  trigger?.wake();
781
1014
  },
782
1015
  onNone: () => {
783
1016
  trigger?.wake();
784
- this._graph.removeNodes([
1017
+ removeNodes(this._graph, [
785
1018
  id
786
1019
  ]);
787
1020
  }
@@ -796,41 +1029,269 @@ var GraphBuilder = class _GraphBuilder {
796
1029
  this._subscriptions.delete(id);
797
1030
  }
798
1031
  };
799
- var rxFromSignal = (cb) => {
800
- return Rx2.make((get2) => {
801
- const dispose = effect(() => {
802
- get2.setSelf(cb());
1032
+ var make2 = (params) => {
1033
+ return new GraphBuilderImpl(params);
1034
+ };
1035
+ var from = (pickle, registry) => {
1036
+ if (!pickle) {
1037
+ return make2({
1038
+ registry
803
1039
  });
804
- get2.addFinalizer(() => dispose());
805
- return cb();
1040
+ }
1041
+ const { nodes, edges } = JSON.parse(pickle);
1042
+ return make2({
1043
+ nodes,
1044
+ edges,
1045
+ registry
806
1046
  });
807
1047
  };
808
- var observableFamily = Rx2.family((observable) => {
809
- return Rx2.make((get2) => {
810
- const subscription = observable.subscribe((value) => get2.setSelf(value));
811
- get2.addFinalizer(() => subscription.unsubscribe());
812
- return observable.get();
1048
+ var addExtensionImpl = (builder, extensions) => {
1049
+ const internal = builder;
1050
+ flattenExtensions(extensions).forEach((extension) => {
1051
+ const extensions2 = internal._registry.get(internal._extensions);
1052
+ internal._registry.set(internal._extensions, Record2.set(extensions2, extension.id, extension));
1053
+ });
1054
+ return builder;
1055
+ };
1056
+ function addExtension(builderOrExtensions, extensions) {
1057
+ if (extensions === void 0) {
1058
+ const extensions2 = builderOrExtensions;
1059
+ return (builder) => addExtensionImpl(builder, extensions2);
1060
+ } else {
1061
+ const builder = builderOrExtensions;
1062
+ return addExtensionImpl(builder, extensions);
1063
+ }
1064
+ }
1065
+ var removeExtensionImpl = (builder, id) => {
1066
+ const internal = builder;
1067
+ const extensions = internal._registry.get(internal._extensions);
1068
+ internal._registry.set(internal._extensions, Record2.remove(extensions, id));
1069
+ return builder;
1070
+ };
1071
+ function removeExtension(builderOrId, id) {
1072
+ if (typeof builderOrId === "string") {
1073
+ const id2 = builderOrId;
1074
+ return (builder) => removeExtensionImpl(builder, id2);
1075
+ } else {
1076
+ const builder = builderOrId;
1077
+ return removeExtensionImpl(builder, id);
1078
+ }
1079
+ }
1080
+ var exploreImpl = async (builder, options, path = []) => {
1081
+ const internal = builder;
1082
+ const { registry = Registry2.make(), source = RootId, relation = "outbound", visitor } = options;
1083
+ if (path.includes(source)) {
1084
+ return;
1085
+ }
1086
+ if (!isNode()) {
1087
+ const { yieldOrContinue } = await import("main-thread-scheduling");
1088
+ await yieldOrContinue("idle");
1089
+ }
1090
+ const node = registry.get(internal._graph.nodeOrThrow(source));
1091
+ const shouldContinue = await visitor(node, [
1092
+ ...path,
1093
+ node.id
1094
+ ]);
1095
+ if (shouldContinue === false) {
1096
+ return;
1097
+ }
1098
+ const nodes = Object.values(internal._registry.get(internal._extensions)).filter((extension) => relation === (extension.relation ?? "outbound")).map((extension) => extension.connector).filter(isNonNullable2).flatMap((connector) => registry.get(connector(internal._graph.node(source))));
1099
+ await Promise.all(nodes.map((nodeArg) => {
1100
+ registry.set(internal._graph._node(nodeArg.id), internal._graph._constructNode(nodeArg));
1101
+ return exploreImpl(builder, {
1102
+ registry,
1103
+ source: nodeArg.id,
1104
+ relation,
1105
+ visitor
1106
+ }, [
1107
+ ...path,
1108
+ node.id
1109
+ ]);
1110
+ }));
1111
+ if (registry !== internal._registry) {
1112
+ registry.reset();
1113
+ registry.dispose();
1114
+ }
1115
+ };
1116
+ function explore(builderOrOptions, optionsOrPath, path) {
1117
+ if (typeof builderOrOptions === "object" && "visitor" in builderOrOptions) {
1118
+ const options = builderOrOptions;
1119
+ const path2 = Array2.isArray(optionsOrPath) ? optionsOrPath : void 0;
1120
+ return (builder) => exploreImpl(builder, options, path2);
1121
+ } else {
1122
+ const builder = builderOrOptions;
1123
+ const options = optionsOrPath;
1124
+ const pathArg = path ?? (Array2.isArray(optionsOrPath) ? optionsOrPath : void 0);
1125
+ return exploreImpl(builder, options, pathArg);
1126
+ }
1127
+ }
1128
+ var destroyImpl = (builder) => {
1129
+ const internal = builder;
1130
+ internal._subscriptions.forEach((unsubscribe) => unsubscribe());
1131
+ internal._subscriptions.clear();
1132
+ };
1133
+ function destroy(builder) {
1134
+ if (builder === void 0) {
1135
+ return (builder2) => destroyImpl(builder2);
1136
+ } else {
1137
+ return destroyImpl(builder);
1138
+ }
1139
+ }
1140
+ var createExtensionRaw = (extension) => {
1141
+ const { id, position = "static", relation = "outbound", resolver: _resolver, connector: _connector, actions: _actions, actionGroups: _actionGroups } = extension;
1142
+ const getId = (key) => `${id}/${key}`;
1143
+ const resolver = _resolver && Atom3.family((id2) => _resolver(id2).pipe(Atom3.withLabel(`graph-builder:_resolver:${id2}`)));
1144
+ const connector = _connector && Atom3.family((node) => _connector(node).pipe(Atom3.withLabel(`graph-builder:_connector:${id}`)));
1145
+ const actionGroups = _actionGroups && Atom3.family((node) => _actionGroups(node).pipe(Atom3.withLabel(`graph-builder:_actionGroups:${id}`)));
1146
+ const actions = _actions && Atom3.family((node) => _actions(node).pipe(Atom3.withLabel(`graph-builder:_actions:${id}`)));
1147
+ return [
1148
+ resolver ? {
1149
+ id: getId("resolver"),
1150
+ position,
1151
+ resolver
1152
+ } : void 0,
1153
+ connector ? {
1154
+ id: getId("connector"),
1155
+ position,
1156
+ relation,
1157
+ connector: Atom3.family((node) => Atom3.make((get2) => {
1158
+ try {
1159
+ return get2(connector(node));
1160
+ } catch (error) {
1161
+ log2.warn("Error in connector", {
1162
+ id: getId("connector"),
1163
+ node,
1164
+ error
1165
+ }, {
1166
+ F: __dxlog_file2,
1167
+ L: 509,
1168
+ S: void 0,
1169
+ C: (f, a) => f(...a)
1170
+ });
1171
+ return [];
1172
+ }
1173
+ }).pipe(Atom3.withLabel(`graph-builder:connector:${id}`)))
1174
+ } : void 0,
1175
+ actionGroups ? {
1176
+ id: getId("actionGroups"),
1177
+ position,
1178
+ relation: "outbound",
1179
+ connector: Atom3.family((node) => Atom3.make((get2) => {
1180
+ try {
1181
+ return get2(actionGroups(node)).map((arg) => ({
1182
+ ...arg,
1183
+ data: actionGroupSymbol,
1184
+ type: ActionGroupType
1185
+ }));
1186
+ } catch (error) {
1187
+ log2.warn("Error in actionGroups", {
1188
+ id: getId("actionGroups"),
1189
+ node,
1190
+ error
1191
+ }, {
1192
+ F: __dxlog_file2,
1193
+ L: 530,
1194
+ S: void 0,
1195
+ C: (f, a) => f(...a)
1196
+ });
1197
+ return [];
1198
+ }
1199
+ }).pipe(Atom3.withLabel(`graph-builder:connector:actionGroups:${id}`)))
1200
+ } : void 0,
1201
+ actions ? {
1202
+ id: getId("actions"),
1203
+ position,
1204
+ relation: "outbound",
1205
+ connector: Atom3.family((node) => Atom3.make((get2) => {
1206
+ try {
1207
+ return get2(actions(node)).map((arg) => ({
1208
+ ...arg,
1209
+ type: ActionType
1210
+ }));
1211
+ } catch (error) {
1212
+ log2.warn("Error in actions", {
1213
+ id: getId("actions"),
1214
+ node,
1215
+ error
1216
+ }, {
1217
+ F: __dxlog_file2,
1218
+ L: 547,
1219
+ S: void 0,
1220
+ C: (f, a) => f(...a)
1221
+ });
1222
+ return [];
1223
+ }
1224
+ }).pipe(Atom3.withLabel(`graph-builder:connector:actions:${id}`)))
1225
+ } : void 0
1226
+ ].filter(isNonNullable2);
1227
+ };
1228
+ var runEffectSyncWithFallback = (effect, context2, extensionId, fallback) => {
1229
+ return Effect.runSync(effect.pipe(Effect.provide(context2), Effect.catchAll((error) => {
1230
+ log2.warn("Extension failed", {
1231
+ extension: extensionId,
1232
+ error
1233
+ }, {
1234
+ F: __dxlog_file2,
1235
+ L: 590,
1236
+ S: void 0,
1237
+ C: (f, a) => f(...a)
1238
+ });
1239
+ return Effect.succeed(fallback);
1240
+ })));
1241
+ };
1242
+ var createExtension = (options) => Effect.map(Effect.context(), (context2) => {
1243
+ const { id, match: match3, actions, connector, resolver, relation, position } = options;
1244
+ const connectorExtension = connector ? createConnectorWithRuntime(id, match3, connector, context2) : void 0;
1245
+ 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) => ({
1246
+ ...action,
1247
+ // Attach captured context for action execution.
1248
+ _actionContext: context2
1249
+ }))), Option3.getOrElse(() => []))) : void 0;
1250
+ const resolverExtension = resolver ? (nodeId) => Atom3.make((get2) => runEffectSyncWithFallback(resolver(nodeId, get2), context2, id, null) ?? null) : void 0;
1251
+ return createExtensionRaw({
1252
+ id,
1253
+ relation,
1254
+ position,
1255
+ connector: connectorExtension,
1256
+ actions: actionsExtension,
1257
+ resolver: resolverExtension
813
1258
  });
814
1259
  });
815
- var rxFromObservable = (observable) => {
816
- return observableFamily(observable);
1260
+ var createConnector = (matcher, factory) => {
1261
+ return (node) => Atom3.make((get2) => Function2.pipe(get2(node), Option3.flatMap(matcher), Option3.map((data) => factory(data, get2)), Option3.getOrElse(() => [])));
1262
+ };
1263
+ var createConnectorWithRuntime = (extensionId, matcher, factory, context2) => {
1264
+ return (node) => Atom3.make((get2) => Function2.pipe(get2(node), Option3.flatMap(matcher), Option3.map((data) => runEffectSyncWithFallback(factory(data, get2), context2, extensionId, [])), Option3.getOrElse(() => [])));
1265
+ };
1266
+ var createTypeExtension = (options) => {
1267
+ const { id, type, actions, connector, relation, position } = options;
1268
+ return createExtension({
1269
+ id,
1270
+ match: whenEchoType(type),
1271
+ actions,
1272
+ connector,
1273
+ relation,
1274
+ position
1275
+ });
1276
+ };
1277
+ var flattenExtensions = (extension, acc = []) => {
1278
+ if (Array2.isArray(extension)) {
1279
+ return [
1280
+ ...acc,
1281
+ ...extension.flatMap((ext) => flattenExtensions(ext, acc))
1282
+ ];
1283
+ } else {
1284
+ return [
1285
+ ...acc,
1286
+ extension
1287
+ ];
1288
+ }
817
1289
  };
818
1290
  export {
819
- ACTION_GROUP_TYPE,
820
- ACTION_TYPE,
821
- Graph,
822
- GraphBuilder,
823
- ROOT_ID,
824
- ROOT_TYPE,
825
- actionGroupSymbol,
826
- createExtension,
827
- flattenExtensions,
828
- getGraph,
829
- isAction,
830
- isActionGroup,
831
- isActionLike,
832
- isGraphNode,
833
- rxFromObservable,
834
- rxFromSignal
1291
+ atoms_exports as CreateAtom,
1292
+ graph_exports as Graph,
1293
+ graph_builder_exports as GraphBuilder,
1294
+ node_exports as Node,
1295
+ node_matcher_exports as NodeMatcher
835
1296
  };
836
1297
  //# sourceMappingURL=index.mjs.map