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