@dxos/app-graph 0.6.3-main.cc41ccb → 0.6.3-main.d16c079

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.
@@ -7,7 +7,7 @@ export declare const ACTION_GROUP_TYPE = "dxos.org/type/GraphActionGroup";
7
7
  export type NodesOptions<T = any, U extends Record<string, any> = Record<string, any>> = {
8
8
  relation?: Relation;
9
9
  filter?: NodeFilter<T, U>;
10
- onlyLoaded?: boolean;
10
+ expansion?: boolean;
11
11
  type?: string;
12
12
  };
13
13
  export type GraphTraversalOptions = {
@@ -30,9 +30,9 @@ export type GraphTraversalOptions = {
30
30
  */
31
31
  relation?: Relation;
32
32
  /**
33
- * Only traverse nodes that are already loaded.
33
+ * Allow traversal to trigger expansion of the graph via `onInitialNodes`.
34
34
  */
35
- onlyLoaded?: boolean;
35
+ expansion?: boolean;
36
36
  };
37
37
  /**
38
38
  * The Graph represents the structure of the application constructed via plugins.
@@ -60,10 +60,9 @@ export declare class Graph {
60
60
  /**
61
61
  * Convert the graph to a JSON object.
62
62
  */
63
- toJSON({ id, maxLength, onlyLoaded, }?: {
63
+ toJSON({ id, maxLength }?: {
64
64
  id?: string;
65
65
  maxLength?: number;
66
- onlyLoaded?: boolean;
67
66
  }): any;
68
67
  /**
69
68
  * Find the node with the given id in the graph.
@@ -71,7 +70,7 @@ export declare class Graph {
71
70
  * If a node is not found within the graph and an `onInitialNode` callback is provided,
72
71
  * it is called with the id and type of the node, potentially initializing the node.
73
72
  */
74
- findNode(id: string, type?: string): Node | undefined;
73
+ findNode(id: string): Node | undefined;
75
74
  /**
76
75
  * Wait for a node to be added to the graph.
77
76
  *
@@ -99,14 +98,15 @@ export declare class Graph {
99
98
  /**
100
99
  * Actions or action groups that this node is connected to in default order.
101
100
  */
102
- actions(node: Node, { onlyLoaded }?: {
103
- onlyLoaded?: boolean;
101
+ actions(node: Node, { expansion }?: {
102
+ expansion?: boolean;
104
103
  }): Readonly<{
105
104
  id: string;
106
105
  type: string;
107
106
  properties: Readonly<Record<string, any>>;
108
107
  data: any;
109
108
  }>[];
109
+ expand(node: Node, relation?: Relation, type?: string): Promise<void>;
110
110
  /**
111
111
  * Recursive depth-first traversal of the graph.
112
112
  *
@@ -114,7 +114,7 @@ export declare class Graph {
114
114
  * @param options.relation The relation to traverse graph edges.
115
115
  * @param options.visitor A callback which is called for each node visited during traversal.
116
116
  */
117
- traverse({ visitor, node, relation, onlyLoaded }: GraphTraversalOptions, path?: string[]): void;
117
+ traverse({ visitor, node, relation, expansion }: GraphTraversalOptions, path?: string[]): void;
118
118
  /**
119
119
  * Recursive depth-first traversal of the graph wrapping each visitor call in an effect.
120
120
  *
@@ -122,7 +122,7 @@ export declare class Graph {
122
122
  * @param options.relation The relation to traverse graph edges.
123
123
  * @param options.visitor A callback which is called for each node visited during traversal.
124
124
  */
125
- subscribeTraverse({ visitor, node, relation, onlyLoaded }: GraphTraversalOptions, currentPath?: string[]): () => void;
125
+ subscribeTraverse({ visitor, node, relation, expansion }: GraphTraversalOptions, currentPath?: string[]): () => void;
126
126
  /**
127
127
  * Get the path between two nodes in the graph.
128
128
  */
@@ -1 +1 @@
1
- {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../../src/graph.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../../src/graph.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"EchoGraph.stories.d.ts","sourceRoot":"","sources":["../../../../src/stories/EchoGraph.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,YAAY,CAAC;;;;;AA4BpB,wBAGE;AAuNF,eAAO,MAAM,OAAO;;CAEnB,CAAC"}
1
+ {"version":3,"file":"EchoGraph.stories.d.ts","sourceRoot":"","sources":["../../../../src/stories/EchoGraph.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,YAAY,CAAC;;;;;AA4BpB,wBAGE;AA6NF,eAAO,MAAM,OAAO;;CAEnB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/app-graph",
3
- "version": "0.6.3-main.cc41ccb",
3
+ "version": "0.6.3-main.d16c079",
4
4
  "description": "Constructs knowledge graphs for the purpose of building applications on top of",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -22,13 +22,13 @@
22
22
  "dependencies": {
23
23
  "@preact/signals-core": "^1.6.0",
24
24
  "main-thread-scheduling": "^14.1.1",
25
- "@dxos/debug": "0.6.3-main.cc41ccb",
26
- "@dxos/invariant": "0.6.3-main.cc41ccb",
27
- "@dxos/async": "0.6.3-main.cc41ccb",
28
- "@dxos/echo-schema": "0.6.3-main.cc41ccb",
29
- "@dxos/log": "0.6.3-main.cc41ccb",
30
- "@dxos/util": "0.6.3-main.cc41ccb",
31
- "@dxos/echo-signals": "0.6.3-main.cc41ccb"
25
+ "@dxos/debug": "0.6.3-main.d16c079",
26
+ "@dxos/echo-schema": "0.6.3-main.d16c079",
27
+ "@dxos/async": "0.6.3-main.d16c079",
28
+ "@dxos/echo-signals": "0.6.3-main.d16c079",
29
+ "@dxos/invariant": "0.6.3-main.d16c079",
30
+ "@dxos/log": "0.6.3-main.d16c079",
31
+ "@dxos/util": "0.6.3-main.d16c079"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@phosphor-icons/react": "^2.1.5",
@@ -37,11 +37,11 @@
37
37
  "react": "^18.2.0",
38
38
  "react-dom": "^18.2.0",
39
39
  "vite": "^5.2.9",
40
- "@dxos/random": "0.6.3-main.cc41ccb",
41
- "@dxos/react-client": "0.6.3-main.cc41ccb",
42
- "@dxos/react-ui": "0.6.3-main.cc41ccb",
43
- "@dxos/react-ui-theme": "0.6.3-main.cc41ccb",
44
- "@dxos/storybook-utils": "0.6.3-main.cc41ccb"
40
+ "@dxos/random": "0.6.3-main.d16c079",
41
+ "@dxos/react-client": "0.6.3-main.d16c079",
42
+ "@dxos/react-ui-theme": "0.6.3-main.d16c079",
43
+ "@dxos/react-ui": "0.6.3-main.d16c079",
44
+ "@dxos/storybook-utils": "0.6.3-main.d16c079"
45
45
  },
46
46
  "peerDependencies": {
47
47
  "react": "^18.2.0",
@@ -3,7 +3,8 @@
3
3
  //
4
4
 
5
5
  import { signal } from '@preact/signals-core';
6
- import { expect } from 'chai';
6
+ import chai, { expect } from 'chai';
7
+ import chaiAsPromised from 'chai-as-promised';
7
8
 
8
9
  import { describe, test } from '@dxos/test';
9
10
 
@@ -11,13 +12,15 @@ import { ACTION_TYPE } from './graph';
11
12
  import { GraphBuilder, createExtension, memoize } from './graph-builder';
12
13
  import { type Node } from './node';
13
14
 
15
+ chai.use(chaiAsPromised);
16
+
14
17
  const exampleId = (id: number) => `dx:test:${id}`;
15
18
  const EXAMPLE_ID = exampleId(1);
16
19
  const EXAMPLE_TYPE = 'dxos.org/type/example';
17
20
 
18
21
  describe('GraphBuilder', () => {
19
22
  describe('resolver', () => {
20
- test('works', () => {
23
+ test('works', async () => {
21
24
  const builder = new GraphBuilder();
22
25
  const graph = builder.graph;
23
26
 
@@ -31,14 +34,14 @@ describe('GraphBuilder', () => {
31
34
  );
32
35
 
33
36
  {
34
- const node = graph.findNode(EXAMPLE_ID);
37
+ const node = await graph.waitForNode(EXAMPLE_ID);
35
38
  expect(node?.id).to.equal(EXAMPLE_ID);
36
39
  expect(node?.type).to.equal(EXAMPLE_TYPE);
37
40
  expect(node?.data).to.equal(1);
38
41
  }
39
42
  });
40
43
 
41
- test('updates', () => {
44
+ test('updates', async () => {
42
45
  const builder = new GraphBuilder();
43
46
  const name = signal('default');
44
47
  builder.addExtension(
@@ -46,14 +49,14 @@ describe('GraphBuilder', () => {
46
49
  );
47
50
  const graph = builder.graph;
48
51
 
49
- const node = graph.findNode(EXAMPLE_ID);
52
+ const node = await graph.waitForNode(EXAMPLE_ID);
50
53
  expect(node?.data).to.equal('default');
51
54
 
52
55
  name.value = 'updated';
53
56
  expect(node?.data).to.equal('updated');
54
57
  });
55
58
 
56
- test('memoize', () => {
59
+ test('memoize', async () => {
57
60
  const builder = new GraphBuilder();
58
61
  const name = signal('default');
59
62
  let count = 0;
@@ -73,7 +76,7 @@ describe('GraphBuilder', () => {
73
76
  );
74
77
  const graph = builder.graph;
75
78
 
76
- const node = graph.findNode(EXAMPLE_ID);
79
+ const node = await graph.waitForNode(EXAMPLE_ID);
77
80
  expect(node?.data).to.equal('default');
78
81
  expect(count).to.equal(1);
79
82
  expect(memoizedCount).to.equal(1);
@@ -89,9 +92,8 @@ describe('GraphBuilder', () => {
89
92
  });
90
93
 
91
94
  describe('connector', () => {
92
- test('works', () => {
95
+ test('works', async () => {
93
96
  const builder = new GraphBuilder();
94
- const graph = builder.graph;
95
97
  builder.addExtension(
96
98
  createExtension({
97
99
  id: 'outbound-connector',
@@ -106,6 +108,10 @@ describe('GraphBuilder', () => {
106
108
  }),
107
109
  );
108
110
 
111
+ const graph = builder.graph;
112
+ await graph.expand(graph.root);
113
+ await graph.expand(graph.root, 'inbound');
114
+
109
115
  const outbound = graph.nodes(graph.root);
110
116
  const inbound = graph.nodes(graph.root, { relation: 'inbound' });
111
117
 
@@ -117,7 +123,7 @@ describe('GraphBuilder', () => {
117
123
  expect(inbound?.[0].data).to.equal(0);
118
124
  });
119
125
 
120
- test('updates', () => {
126
+ test('updates', async () => {
121
127
  const name = signal('default');
122
128
  const builder = new GraphBuilder();
123
129
  builder.addExtension(
@@ -127,6 +133,7 @@ describe('GraphBuilder', () => {
127
133
  }),
128
134
  );
129
135
  const graph = builder.graph;
136
+ await graph.expand(graph.root);
130
137
 
131
138
  const [node] = graph.nodes(graph.root);
132
139
  expect(node.properties.label).to.equal('default');
@@ -135,7 +142,7 @@ describe('GraphBuilder', () => {
135
142
  expect(node.properties.label).to.equal('updated');
136
143
  });
137
144
 
138
- test('removes', () => {
145
+ test('removes', async () => {
139
146
  const nodes = signal([
140
147
  { id: exampleId(1), type: EXAMPLE_TYPE, data: 1 },
141
148
  { id: exampleId(2), type: EXAMPLE_TYPE, data: 2 },
@@ -149,6 +156,7 @@ describe('GraphBuilder', () => {
149
156
  }),
150
157
  );
151
158
  const graph = builder.graph;
159
+ await graph.expand(graph.root);
152
160
 
153
161
  {
154
162
  const nodes = graph.nodes(graph.root);
@@ -166,7 +174,7 @@ describe('GraphBuilder', () => {
166
174
  }
167
175
  });
168
176
 
169
- test('filters by type', () => {
177
+ test('filters by type', async () => {
170
178
  const builder = new GraphBuilder();
171
179
  builder.addExtension(
172
180
  createExtension({
@@ -177,21 +185,22 @@ describe('GraphBuilder', () => {
177
185
  );
178
186
  const graph = builder.graph;
179
187
 
188
+ await graph.expand(graph.root, 'outbound', ACTION_TYPE);
180
189
  const actions = graph.actions(graph.root);
181
190
  expect(actions).has.length(1);
182
191
  expect(actions?.[0].id).to.equal('action');
183
192
  expect(actions?.[0].type).to.equal(ACTION_TYPE);
184
193
 
185
- const node = graph.findNode('not-action', EXAMPLE_TYPE);
186
- expect(node).to.be.undefined;
194
+ await expect(graph.waitForNode('not-action', 10)).to.be.rejected;
187
195
 
196
+ await graph.expand(graph.root);
188
197
  const nodes = graph.nodes(graph.root);
189
198
  expect(nodes).has.length(1);
190
199
  expect(nodes?.[0].id).to.equal('not-action');
191
200
  expect(nodes?.[0].data).to.equal(1);
192
201
  });
193
202
 
194
- test('filters by callback', () => {
203
+ test('filters by callback', async () => {
195
204
  const builder = new GraphBuilder();
196
205
  builder.addExtension(
197
206
  createExtension({
@@ -201,6 +210,7 @@ describe('GraphBuilder', () => {
201
210
  }),
202
211
  );
203
212
  const graph = builder.graph;
213
+ await graph.expand(graph.root);
204
214
 
205
215
  const [node1] = graph.nodes(graph.root);
206
216
  expect(node1?.id).to.equal(EXAMPLE_ID);
@@ -209,7 +219,7 @@ describe('GraphBuilder', () => {
209
219
  expect(nodes).has.length(0);
210
220
  });
211
221
 
212
- test('memoize', () => {
222
+ test('memoize', async () => {
213
223
  const builder = new GraphBuilder();
214
224
  const name = signal('default');
215
225
  let count = 0;
@@ -228,6 +238,7 @@ describe('GraphBuilder', () => {
228
238
  }),
229
239
  );
230
240
  const graph = builder.graph;
241
+ await graph.expand(graph.root);
231
242
 
232
243
  const [node] = graph.nodes(graph.root);
233
244
  expect(node.properties.label).to.equal('default');
@@ -271,7 +282,7 @@ describe('GraphBuilder', () => {
271
282
  });
272
283
 
273
284
  describe('multiples', () => {
274
- test('one of each with multiple memos', () => {
285
+ test('one of each with multiple memos', async () => {
275
286
  const name = signal('default');
276
287
  const builder = new GraphBuilder();
277
288
  builder.addExtension(
@@ -291,8 +302,9 @@ describe('GraphBuilder', () => {
291
302
  );
292
303
  const graph = builder.graph;
293
304
 
294
- const one = graph.findNode(EXAMPLE_ID);
305
+ const one = await graph.waitForNode(EXAMPLE_ID);
295
306
  const initialData = one!.data;
307
+ await graph.expand(one!);
296
308
  const two = graph.nodes(one!)[0];
297
309
  const initialA = two?.data.a;
298
310
  const initialB = two?.data.b;
@@ -194,7 +194,7 @@ export class GraphBuilder {
194
194
 
195
195
  constructor() {
196
196
  this._graph = new Graph({
197
- onInitialNode: (id, type) => this._onInitialNode(id, type),
197
+ onInitialNode: (id) => this._onInitialNode(id),
198
198
  onInitialNodes: (node, relation, type) => this._onInitialNodes(node, relation, type),
199
199
  onRemoveNode: (id) => this._onRemoveNode(id),
200
200
  });
@@ -263,11 +263,11 @@ export class GraphBuilder {
263
263
  await Promise.all(nodes.map((n) => this.traverse({ node: n, relation, visitor }, [...path, node.id])));
264
264
  }
265
265
 
266
- private _onInitialNode(nodeId: string, nodeType?: string) {
266
+ private async _onInitialNode(nodeId: string) {
267
267
  this._nodeChanged[nodeId] = this._nodeChanged[nodeId] ?? signal({});
268
- let initialized: NodeArg<any> | undefined;
269
- for (const { id, type, resolver } of Object.values(this._extensions)) {
270
- if (!resolver || (nodeType && type !== nodeType)) {
268
+ let resolved = false;
269
+ for (const { id, resolver } of Object.values(this._extensions)) {
270
+ if (resolved || !resolver) {
271
271
  continue;
272
272
  }
273
273
 
@@ -277,30 +277,27 @@ export class GraphBuilder {
277
277
  BuilderInternal.currentDispatcher = this._dispatcher;
278
278
  const node = resolver({ id: nodeId });
279
279
  BuilderInternal.currentDispatcher = undefined;
280
- if (node && initialized) {
280
+ if (node) {
281
+ resolved = true;
281
282
  this.graph._addNodes([node]);
282
- if (this._nodeChanged[initialized.id]) {
283
- this._nodeChanged[initialized.id].value = {};
283
+ if (this._nodeChanged[node.id]) {
284
+ this._nodeChanged[node.id].value = {};
284
285
  }
285
- } else if (node) {
286
- initialized = node;
287
286
  }
288
287
  });
289
288
 
290
- if (initialized) {
289
+ if (resolved) {
290
+ this._resolverSubscriptions.get(nodeId)?.();
291
291
  this._resolverSubscriptions.set(nodeId, unsubscribe);
292
292
  break;
293
293
  } else {
294
294
  unsubscribe();
295
295
  }
296
296
  }
297
-
298
- return initialized;
299
297
  }
300
298
 
301
- private _onInitialNodes(node: Node, nodesRelation: Relation, nodesType?: string) {
299
+ private async _onInitialNodes(node: Node, nodesRelation: Relation, nodesType?: string) {
302
300
  this._nodeChanged[node.id] = this._nodeChanged[node.id] ?? signal({});
303
- let initialized: NodeArg<any>[] | undefined;
304
301
  let previous: string[] = [];
305
302
  this._connectorSubscriptions.set(
306
303
  node.id,
@@ -332,30 +329,28 @@ export class GraphBuilder {
332
329
  const removed = previous.filter((id) => !ids.includes(id));
333
330
  previous = ids;
334
331
 
335
- if (initialized) {
336
- this.graph._removeNodes(removed, true);
337
- this.graph._addNodes(nodes);
338
- this.graph._addEdges(nodes.map(({ id }) => ({ source: node.id, target: id })));
339
- this.graph._sortEdges(
340
- node.id,
341
- 'outbound',
342
- nodes.map(({ id }) => id),
343
- );
344
- nodes.forEach((n) => {
345
- if (this._nodeChanged[n.id]) {
346
- this._nodeChanged[n.id].value = {};
347
- }
348
- });
349
- } else {
350
- initialized = nodes;
351
- }
332
+ this.graph._removeNodes(removed, true);
333
+ this.graph._addNodes(nodes);
334
+ this.graph._addEdges(
335
+ nodes.map(({ id }) =>
336
+ nodesRelation === 'outbound' ? { source: node.id, target: id } : { source: id, target: node.id },
337
+ ),
338
+ );
339
+ this.graph._sortEdges(
340
+ node.id,
341
+ nodesRelation,
342
+ nodes.map(({ id }) => id),
343
+ );
344
+ nodes.forEach((n) => {
345
+ if (this._nodeChanged[n.id]) {
346
+ this._nodeChanged[n.id].value = {};
347
+ }
348
+ });
352
349
  }),
353
350
  );
354
-
355
- return initialized;
356
351
  }
357
352
 
358
- private _onRemoveNode(nodeId: string) {
353
+ private async _onRemoveNode(nodeId: string) {
359
354
  this._resolverSubscriptions.get(nodeId)?.();
360
355
  this._connectorSubscriptions.get(nodeId)?.();
361
356
  this._resolverSubscriptions.delete(nodeId);