@dxos/plugin-explorer 0.8.4-main.3c1ae3b → 0.8.4-main.3fbcb4aa9b

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 (186) hide show
  1. package/dist/lib/neutral/ExplorerContainer-5TOK2ZEY.mjs +40 -0
  2. package/dist/lib/neutral/ExplorerContainer-5TOK2ZEY.mjs.map +7 -0
  3. package/dist/lib/neutral/ExplorerPlugin.mjs +26 -0
  4. package/dist/lib/neutral/ExplorerPlugin.mjs.map +7 -0
  5. package/dist/lib/neutral/capabilities/index.mjs +11 -0
  6. package/dist/lib/neutral/capabilities/index.mjs.map +7 -0
  7. package/dist/lib/neutral/chunk-5X5ATGCS.mjs +73 -0
  8. package/dist/lib/neutral/chunk-5X5ATGCS.mjs.map +7 -0
  9. package/dist/lib/{browser/chunk-UBHZGWZQ.mjs → neutral/chunk-HPIS2WXY.mjs} +2 -2
  10. package/dist/lib/neutral/chunk-HPIS2WXY.mjs.map +7 -0
  11. package/dist/lib/{browser/chunk-ARBGXQFH.mjs → neutral/components/index.mjs} +341 -156
  12. package/dist/lib/{browser/chunk-ARBGXQFH.mjs.map → neutral/components/index.mjs.map} +4 -4
  13. package/dist/lib/neutral/containers/index.mjs +9 -0
  14. package/dist/lib/neutral/containers/index.mjs.map +7 -0
  15. package/dist/lib/neutral/create-object-F6TKVAGV.mjs +39 -0
  16. package/dist/lib/neutral/create-object-F6TKVAGV.mjs.map +7 -0
  17. package/dist/lib/neutral/hooks/index.mjs +40 -0
  18. package/dist/lib/neutral/hooks/index.mjs.map +7 -0
  19. package/dist/lib/neutral/index.mjs +14 -0
  20. package/dist/lib/neutral/meta.json +1 -0
  21. package/dist/lib/{browser → neutral}/meta.mjs +1 -1
  22. package/dist/lib/neutral/plugin.mjs +12 -0
  23. package/dist/lib/neutral/plugin.mjs.map +7 -0
  24. package/dist/lib/neutral/react-surface-U3JEY7V7.mjs +26 -0
  25. package/dist/lib/neutral/react-surface-U3JEY7V7.mjs.map +7 -0
  26. package/dist/lib/neutral/translations.mjs +33 -0
  27. package/dist/lib/neutral/translations.mjs.map +7 -0
  28. package/dist/lib/{browser → neutral}/types/index.mjs +1 -2
  29. package/dist/types/data/cities.d.ts +4 -4
  30. package/dist/types/data/cities.d.ts.map +1 -1
  31. package/dist/types/data/countries-110m.d.ts +19 -22
  32. package/dist/types/data/countries-110m.d.ts.map +1 -1
  33. package/dist/types/src/ExplorerPlugin.d.ts +3 -1
  34. package/dist/types/src/ExplorerPlugin.d.ts.map +1 -1
  35. package/dist/types/src/ExplorerPlugin.test.d.ts +2 -0
  36. package/dist/types/src/ExplorerPlugin.test.d.ts.map +1 -0
  37. package/dist/types/src/capabilities/create-object.d.ts +11 -0
  38. package/dist/types/src/capabilities/create-object.d.ts.map +1 -0
  39. package/dist/types/src/capabilities/index.d.ts +8 -2
  40. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  41. package/dist/types/src/capabilities/react-surface.d.ts +3 -2
  42. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  43. package/dist/types/src/components/Chart/Chart.d.ts.map +1 -1
  44. package/dist/types/src/components/Chart/Chart.stories.d.ts +4 -1
  45. package/dist/types/src/components/Chart/Chart.stories.d.ts.map +1 -1
  46. package/dist/types/src/components/Globe/Globe.d.ts.map +1 -1
  47. package/dist/types/src/components/Globe/Globe.stories.d.ts +5 -2
  48. package/dist/types/src/components/Globe/Globe.stories.d.ts.map +1 -1
  49. package/dist/types/src/components/Graph/CanvasForceGraph.d.ts +13 -0
  50. package/dist/types/src/components/Graph/CanvasForceGraph.d.ts.map +1 -0
  51. package/dist/types/src/components/Graph/CanvasForceGraph.stories.d.ts +17 -0
  52. package/dist/types/src/components/Graph/CanvasForceGraph.stories.d.ts.map +1 -0
  53. package/dist/types/src/components/Graph/ForceGraph.d.ts +12 -5
  54. package/dist/types/src/components/Graph/ForceGraph.d.ts.map +1 -1
  55. package/dist/types/src/components/Graph/ForceGraph.stories.d.ts +4 -2
  56. package/dist/types/src/components/Graph/ForceGraph.stories.d.ts.map +1 -1
  57. package/dist/types/src/components/Graph/{adapter.d.ts → graph-adapter.d.ts} +2 -2
  58. package/dist/types/src/components/Graph/graph-adapter.d.ts.map +1 -0
  59. package/dist/types/src/components/Graph/index.d.ts +1 -1
  60. package/dist/types/src/components/Graph/index.d.ts.map +1 -1
  61. package/dist/types/src/components/Graph/testing.d.ts.map +1 -1
  62. package/dist/types/src/components/Tree/Tree.d.ts.map +1 -1
  63. package/dist/types/src/components/Tree/Tree.stories.d.ts +5 -1
  64. package/dist/types/src/components/Tree/Tree.stories.d.ts.map +1 -1
  65. package/dist/types/src/components/Tree/layout/HierarchicalEdgeBundling.d.ts.map +1 -1
  66. package/dist/types/src/components/Tree/layout/RadialTree.d.ts.map +1 -1
  67. package/dist/types/src/components/Tree/layout/TidyTree.d.ts.map +1 -1
  68. package/dist/types/src/components/Tree/testing/generator.d.ts.map +1 -1
  69. package/dist/types/src/components/Tree/types/tree.d.ts +18 -16
  70. package/dist/types/src/components/Tree/types/tree.d.ts.map +1 -1
  71. package/dist/types/src/components/Tree/types/types.d.ts +1 -1
  72. package/dist/types/src/components/Tree/types/types.d.ts.map +1 -1
  73. package/dist/types/src/components/index.d.ts +0 -2
  74. package/dist/types/src/components/index.d.ts.map +1 -1
  75. package/dist/types/src/components/plot.d.ts.map +1 -1
  76. package/dist/types/src/containers/ExplorerContainer/ExplorerContainer.d.ts +6 -0
  77. package/dist/types/src/containers/ExplorerContainer/ExplorerContainer.d.ts.map +1 -0
  78. package/dist/types/src/containers/ExplorerContainer/index.d.ts +2 -0
  79. package/dist/types/src/containers/ExplorerContainer/index.d.ts.map +1 -0
  80. package/dist/types/src/containers/index.d.ts +3 -0
  81. package/dist/types/src/containers/index.d.ts.map +1 -0
  82. package/dist/types/src/hooks/useGraphModel.d.ts.map +1 -1
  83. package/dist/types/src/index.d.ts +1 -3
  84. package/dist/types/src/index.d.ts.map +1 -1
  85. package/dist/types/src/meta.d.ts +2 -2
  86. package/dist/types/src/meta.d.ts.map +1 -1
  87. package/dist/types/src/plugin.d.ts +3 -0
  88. package/dist/types/src/plugin.d.ts.map +1 -0
  89. package/dist/types/src/translations.d.ts +29 -27
  90. package/dist/types/src/translations.d.ts.map +1 -1
  91. package/dist/types/src/types/ExplorerAction.d.ts +0 -17
  92. package/dist/types/src/types/ExplorerAction.d.ts.map +1 -1
  93. package/dist/types/src/types/Graph.d.ts +10 -19
  94. package/dist/types/src/types/Graph.d.ts.map +1 -1
  95. package/dist/types/tsconfig.tsbuildinfo +1 -1
  96. package/package.json +107 -61
  97. package/src/ExplorerPlugin.test.ts +26 -0
  98. package/src/ExplorerPlugin.tsx +15 -45
  99. package/src/capabilities/create-object.ts +36 -0
  100. package/src/capabilities/index.ts +3 -3
  101. package/src/capabilities/react-surface.tsx +24 -18
  102. package/src/components/Chart/Chart.stories.tsx +16 -23
  103. package/src/components/Globe/Globe.stories.tsx +19 -22
  104. package/src/components/Graph/CanvasForceGraph.stories.tsx +83 -0
  105. package/src/components/Graph/CanvasForceGraph.tsx +124 -0
  106. package/src/components/Graph/ForceGraph.stories.tsx +78 -43
  107. package/src/components/Graph/ForceGraph.tsx +104 -85
  108. package/src/components/Graph/{adapter.ts → graph-adapter.ts} +14 -8
  109. package/src/components/Graph/index.ts +1 -1
  110. package/src/components/Graph/testing.ts +3 -3
  111. package/src/components/Tree/Tree.stories.tsx +44 -36
  112. package/src/components/Tree/Tree.tsx +8 -3
  113. package/src/components/Tree/testing/generator.ts +4 -2
  114. package/src/components/Tree/types/tree.test.ts +5 -4
  115. package/src/components/Tree/types/tree.ts +41 -20
  116. package/src/components/Tree/types/types.ts +1 -1
  117. package/src/components/index.ts +0 -4
  118. package/src/containers/ExplorerContainer/ExplorerContainer.tsx +51 -0
  119. package/src/containers/ExplorerContainer/index.ts +5 -0
  120. package/src/containers/index.ts +7 -0
  121. package/src/hooks/useGraphModel.ts +17 -10
  122. package/src/index.ts +1 -4
  123. package/src/meta.ts +3 -3
  124. package/src/plugin.ts +9 -0
  125. package/src/translations.ts +14 -13
  126. package/src/types/ExplorerAction.ts +1 -18
  127. package/src/types/Graph.ts +14 -28
  128. package/src/typings.d.ts +8 -0
  129. package/dist/lib/browser/ExplorerContainer-NOLLVUTE.mjs +0 -50
  130. package/dist/lib/browser/ExplorerContainer-NOLLVUTE.mjs.map +0 -7
  131. package/dist/lib/browser/chunk-2MKBRIUT.mjs +0 -31
  132. package/dist/lib/browser/chunk-2MKBRIUT.mjs.map +0 -7
  133. package/dist/lib/browser/chunk-6BVXZQPP.mjs +0 -188
  134. package/dist/lib/browser/chunk-6BVXZQPP.mjs.map +0 -7
  135. package/dist/lib/browser/chunk-P6FFFVPM.mjs +0 -100
  136. package/dist/lib/browser/chunk-P6FFFVPM.mjs.map +0 -7
  137. package/dist/lib/browser/chunk-UBHZGWZQ.mjs.map +0 -7
  138. package/dist/lib/browser/index.mjs +0 -112
  139. package/dist/lib/browser/index.mjs.map +0 -7
  140. package/dist/lib/browser/intent-resolver-XAMO4BLV.mjs +0 -32
  141. package/dist/lib/browser/intent-resolver-XAMO4BLV.mjs.map +0 -7
  142. package/dist/lib/browser/meta.json +0 -1
  143. package/dist/lib/browser/react-surface-BY2DYCTH.mjs +0 -34
  144. package/dist/lib/browser/react-surface-BY2DYCTH.mjs.map +0 -7
  145. package/dist/lib/node-esm/ExplorerContainer-N3S5KSUX.mjs +0 -51
  146. package/dist/lib/node-esm/ExplorerContainer-N3S5KSUX.mjs.map +0 -7
  147. package/dist/lib/node-esm/chunk-3ODK27PU.mjs +0 -33
  148. package/dist/lib/node-esm/chunk-3ODK27PU.mjs.map +0 -7
  149. package/dist/lib/node-esm/chunk-4BY2XZET.mjs +0 -101
  150. package/dist/lib/node-esm/chunk-4BY2XZET.mjs.map +0 -7
  151. package/dist/lib/node-esm/chunk-CRSVAZNA.mjs +0 -190
  152. package/dist/lib/node-esm/chunk-CRSVAZNA.mjs.map +0 -7
  153. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +0 -11
  154. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +0 -7
  155. package/dist/lib/node-esm/chunk-NPIP4VEH.mjs +0 -11091
  156. package/dist/lib/node-esm/chunk-NPIP4VEH.mjs.map +0 -7
  157. package/dist/lib/node-esm/chunk-UXZM5VJB.mjs +0 -26
  158. package/dist/lib/node-esm/chunk-UXZM5VJB.mjs.map +0 -7
  159. package/dist/lib/node-esm/index.mjs +0 -113
  160. package/dist/lib/node-esm/index.mjs.map +0 -7
  161. package/dist/lib/node-esm/intent-resolver-YNS4MM2C.mjs +0 -33
  162. package/dist/lib/node-esm/intent-resolver-YNS4MM2C.mjs.map +0 -7
  163. package/dist/lib/node-esm/meta.json +0 -1
  164. package/dist/lib/node-esm/meta.mjs +0 -9
  165. package/dist/lib/node-esm/meta.mjs.map +0 -7
  166. package/dist/lib/node-esm/react-surface-7AAV7GBG.mjs +0 -35
  167. package/dist/lib/node-esm/react-surface-7AAV7GBG.mjs.map +0 -7
  168. package/dist/lib/node-esm/types/index.mjs +0 -12
  169. package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
  170. package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
  171. package/dist/types/src/components/ExplorerContainer.d.ts +0 -9
  172. package/dist/types/src/components/ExplorerContainer.d.ts.map +0 -1
  173. package/dist/types/src/components/Graph/D3ForceGraph.d.ts +0 -14
  174. package/dist/types/src/components/Graph/D3ForceGraph.d.ts.map +0 -1
  175. package/dist/types/src/components/Graph/D3ForceGraph.stories.d.ts +0 -15
  176. package/dist/types/src/components/Graph/D3ForceGraph.stories.d.ts.map +0 -1
  177. package/dist/types/src/components/Graph/adapter.d.ts.map +0 -1
  178. package/src/capabilities/intent-resolver.ts +0 -21
  179. package/src/components/ExplorerContainer.tsx +0 -54
  180. package/src/components/Graph/D3ForceGraph.stories.tsx +0 -80
  181. package/src/components/Graph/D3ForceGraph.tsx +0 -101
  182. /package/dist/lib/{browser → neutral}/chunk-J5LGTIGS.mjs +0 -0
  183. /package/dist/lib/{browser → neutral}/chunk-J5LGTIGS.mjs.map +0 -0
  184. /package/dist/lib/{browser/types → neutral}/index.mjs.map +0 -0
  185. /package/dist/lib/{browser → neutral}/meta.mjs.map +0 -0
  186. /package/dist/lib/{node-esm → neutral}/types/index.mjs.map +0 -0
@@ -2,7 +2,8 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import React, { useEffect, useRef, useState } from 'react';
5
+ import { RegistryContext } from '@effect-atom/atom-react';
6
+ import React, { useContext, useEffect, useRef, useState } from 'react';
6
7
 
7
8
  import { type Space } from '@dxos/client/echo';
8
9
  import { useAsyncState } from '@dxos/react-ui';
@@ -62,7 +63,11 @@ export type TreeComponentProps<N = unknown> = {
62
63
 
63
64
  // TODO(burdon): Label accessor.
64
65
  export const Tree = <N,>({ space, selected, variant = 'tidy', onNodeClick }: TreeComponentProps<N>) => {
65
- const [model] = useAsyncState(async () => (space ? new SpaceGraphModel().open(space) : undefined), [space, selected]);
66
+ const registry = useContext(RegistryContext);
67
+ const [model] = useAsyncState(
68
+ async () => (space ? new SpaceGraphModel(registry).open(space.db) : undefined),
69
+ [space, selected, registry],
70
+ );
66
71
 
67
72
  const [tree, setTree] = useState<TreeNode>();
68
73
  useEffect(() => {
@@ -100,7 +105,7 @@ export const Tree = <N,>({ space, selected, variant = 'tidy', onNodeClick }: Tre
100
105
  }, [context.current, tree]);
101
106
 
102
107
  return (
103
- <div onClick={() => onNodeClick?.()}>
108
+ <div className='grow' onClick={() => onNodeClick?.()}>
104
109
  <SVG.Root ref={context} />
105
110
  </div>
106
111
  );
@@ -2,7 +2,7 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Key } from '@dxos/echo';
5
+ import { Key, Obj } from '@dxos/echo';
6
6
  import { range } from '@dxos/util';
7
7
 
8
8
  import { Tree, type TreeNodeType } from '../types';
@@ -16,7 +16,9 @@ const random = (min: number, max: number) => Math.floor(Math.random() * (max - m
16
16
  */
17
17
  export const createTree = (spec: NumberOrNumberArray[] = [], createText?: () => string): Tree => {
18
18
  const tree = new Tree();
19
- tree.root.data = { text: 'root' };
19
+ Obj.update(tree.tree, () => {
20
+ tree.root.data = { text: 'root' };
21
+ });
20
22
 
21
23
  const createNodes = (parent: TreeNodeType, spec: NumberOrNumberArray = 0): TreeNodeType[] => {
22
24
  const count = Array.isArray(spec) ? random(spec[0], spec[1]) : spec;
@@ -5,14 +5,13 @@
5
5
  import { describe, test } from 'vitest';
6
6
 
7
7
  import { Obj, Ref } from '@dxos/echo';
8
- import { faker } from '@dxos/random';
8
+ import { random } from '@dxos/random';
9
9
  import { Task } from '@dxos/types';
10
10
 
11
11
  import { createTree } from '../testing';
12
-
13
12
  import { type Tree } from './tree';
14
13
 
15
- faker.seed(0);
14
+ random.seed(0);
16
15
 
17
16
  const print = (tree: Tree) => {
18
17
  let count = 0;
@@ -129,6 +128,8 @@ describe('tree', () => {
129
128
 
130
129
  const tree = createTree();
131
130
  const node = tree.addNode(tree.root);
132
- node.ref = Ref.make(task);
131
+ Obj.update(tree.tree, () => {
132
+ node.ref = Ref.make(task);
133
+ });
133
134
  });
134
135
  });
@@ -4,7 +4,8 @@
4
4
 
5
5
  import * as Schema from 'effect/Schema';
6
6
 
7
- import { Key, Obj, Type } from '@dxos/echo';
7
+ import { Key, Obj, Ref, Type } from '@dxos/echo';
8
+ import { TestSchema } from '@dxos/echo/testing';
8
9
  import { invariant } from '@dxos/invariant';
9
10
 
10
11
  // TODO(burdon): Reconcile with @dxos/graph (i.e., common types).
@@ -13,7 +14,7 @@ export const TreeNodeType = Schema.Struct({
13
14
  id: Key.ObjectId,
14
15
  children: Schema.mutable(Schema.Array(Key.ObjectId)),
15
16
  data: Schema.mutable(Schema.Record({ key: Schema.String, value: Schema.Any })),
16
- ref: Schema.optional(Type.Ref(Type.Expando)),
17
+ ref: Schema.optional(Ref.Ref(TestSchema.Expando)),
17
18
  }).pipe(Schema.mutable);
18
19
 
19
20
  export interface TreeNodeType extends Schema.Schema.Type<typeof TreeNodeType> {}
@@ -22,8 +23,8 @@ export const TreeType = Schema.Struct({
22
23
  root: Key.ObjectId,
23
24
  nodes: Schema.mutable(Schema.Record({ key: Key.ObjectId, value: TreeNodeType })),
24
25
  }).pipe(
25
- Type.Obj({
26
- typename: 'dxos.org/type/Tree',
26
+ Type.object({
27
+ typename: 'org.dxos.type.tree',
27
28
  version: '0.1.0',
28
29
  }),
29
30
  );
@@ -184,9 +185,11 @@ export class Tree {
184
185
  clear(): void {
185
186
  const root = this._tree.nodes[this._tree.root];
186
187
  root.children.length = 0;
187
- this._tree.nodes = {
188
- [root.id]: root,
189
- };
188
+ Obj.update(this._tree, (obj) => {
189
+ obj.nodes = {
190
+ [root.id]: root,
191
+ };
192
+ });
190
193
  }
191
194
 
192
195
  /**
@@ -198,8 +201,11 @@ export class Tree {
198
201
  node = { id, children: [], data: { text: '' } }; // TODO(burdon): Generic.
199
202
  }
200
203
 
201
- this._tree.nodes[node.id] = node;
202
- parent.children.splice(index ?? parent.children.length, 0, node.id);
204
+ const nodeToAdd = node;
205
+ Obj.update(this._tree, (obj) => {
206
+ obj.nodes[nodeToAdd.id] = nodeToAdd;
207
+ parent.children.splice(index ?? parent.children.length, 0, nodeToAdd.id);
208
+ });
203
209
  return node;
204
210
  }
205
211
 
@@ -212,10 +218,14 @@ export class Tree {
212
218
  return undefined;
213
219
  }
214
220
 
215
- delete this._tree.nodes[node.id];
221
+ Obj.update(this._tree, (obj) => {
222
+ delete obj.nodes[node.id];
223
+ });
216
224
  const idx = parent.children.findIndex((child) => child === id);
217
225
  if (idx !== -1) {
218
- parent.children.splice(idx, 1);
226
+ Obj.update(this._tree, () => {
227
+ parent.children.splice(idx, 1);
228
+ });
219
229
  }
220
230
 
221
231
  return node;
@@ -232,8 +242,10 @@ export class Tree {
232
242
  }
233
243
 
234
244
  const child = node.children[from];
235
- node.children.splice(from, 1);
236
- node.children.splice(to, 0, child);
245
+ Obj.update(this._tree, () => {
246
+ node.children.splice(from, 1);
247
+ node.children.splice(to, 0, child);
248
+ });
237
249
  return this.getNode(child);
238
250
  }
239
251
 
@@ -252,8 +264,10 @@ export class Tree {
252
264
  }
253
265
 
254
266
  const previous = this.getNode(parent.children[idx - 1]);
255
- parent.children.splice(idx, 1);
256
- previous.children.push(node.id);
267
+ Obj.update(this._tree, () => {
268
+ parent.children.splice(idx, 1);
269
+ previous.children.push(node.id);
270
+ });
257
271
  }
258
272
 
259
273
  /**
@@ -270,16 +284,23 @@ export class Tree {
270
284
  return;
271
285
  }
272
286
 
273
- // Remove node from parent.
287
+ // Remove node from parent and get following siblings.
274
288
  const nodeIdx = parent.children.findIndex((id) => id === node.id);
275
- const [_, ...rest] = parent.children.splice(nodeIdx, parent.children.length - nodeIdx);
276
- parent.children.splice(nodeIdx, parent.children.length - nodeIdx);
289
+ let rest: Key.ObjectId[] = [];
290
+ Obj.update(this._tree, () => {
291
+ const removed = parent.children.splice(nodeIdx, parent.children.length - nodeIdx);
292
+ rest = removed.slice(1); // Skip the node itself.
293
+ });
277
294
 
278
295
  // Add to ancestor.
279
296
  const parentIdx = this.getChildNodes(ancestor).findIndex((n) => n.id === parent.id);
280
- ancestor.children.splice(parentIdx + 1, 0, node.id);
297
+ Obj.update(this._tree, () => {
298
+ ancestor.children.splice(parentIdx + 1, 0, node.id);
299
+ });
281
300
 
282
301
  // Transplant following siblings to current node.
283
- node.children.push(...rest);
302
+ Obj.update(this._tree, () => {
303
+ node.children.push(...rest);
304
+ });
284
305
  }
285
306
  }
@@ -10,7 +10,7 @@ export type TreeNode = {
10
10
  children?: TreeNode[];
11
11
  };
12
12
 
13
- export const mapGraphToTreeData = (model: GraphModel, maxDepth = 8): TreeNode | undefined => {
13
+ export const mapGraphToTreeData = (model: GraphModel.GraphModel, maxDepth = 8): TreeNode | undefined => {
14
14
  // TODO(burdon): Convert to common/graph.
15
15
  // const mapNode = (node: N, depth = 0): TreeNode => {
16
16
  // const treeNode: TreeNode = {
@@ -2,11 +2,7 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { type ComponentType, lazy } from 'react';
6
-
7
5
  export * from './Chart';
8
6
  export * from './Globe';
9
7
  export * from './Graph';
10
8
  export * from './Tree';
11
-
12
- export const ExplorerContainer: ComponentType<any> = lazy(() => import('./ExplorerContainer'));
@@ -0,0 +1,51 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import React, { useCallback, useMemo, useState } from 'react';
6
+
7
+ import { type AppSurface } from '@dxos/app-toolkit/ui';
8
+ import { type Filter } from '@dxos/echo';
9
+ import { type View } from '@dxos/echo';
10
+ import { QueryBuilder } from '@dxos/echo-query';
11
+ import { getSpace, useObject } from '@dxos/react-client/echo';
12
+ import { Panel, Toolbar } from '@dxos/react-ui';
13
+ import { QueryEditor, type QueryEditorProps } from '@dxos/react-ui-components';
14
+
15
+ import { ForceGraph } from '#components';
16
+ import { useGraphModel } from '#hooks';
17
+
18
+ export type ExplorerContainerProps = AppSurface.ObjectArticleProps<View.View>;
19
+
20
+ export const ExplorerContainer = ({ role, subject, attendableId: _attendableId }: ExplorerContainerProps) => {
21
+ const [view] = useObject(subject);
22
+ const space = view && getSpace(view);
23
+ const [filter, setFilter] = useState<Filter.Any>();
24
+ const model = useGraphModel(space, filter);
25
+
26
+ const builder = useMemo(() => new QueryBuilder(), []);
27
+ const handleChange = useCallback<NonNullable<QueryEditorProps['onChange']>>((value) => {
28
+ setFilter(builder.build(value).filter);
29
+ }, []);
30
+
31
+ const showToolbar = role === 'article';
32
+
33
+ if (!space || !model) {
34
+ return null;
35
+ }
36
+
37
+ return (
38
+ <Panel.Root role={role}>
39
+ {showToolbar && (
40
+ <Panel.Toolbar asChild>
41
+ <Toolbar.Root>
42
+ <QueryEditor db={space.db} onChange={handleChange} />
43
+ </Toolbar.Root>
44
+ </Panel.Toolbar>
45
+ )}
46
+ <Panel.Content asChild>
47
+ <ForceGraph model={model} />
48
+ </Panel.Content>
49
+ </Panel.Root>
50
+ );
51
+ };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ export { ExplorerContainer as default } from './ExplorerContainer';
@@ -0,0 +1,7 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { type ComponentType, lazy } from 'react';
6
+
7
+ export const ExplorerContainer: ComponentType<any> = lazy(() => import('./ExplorerContainer'));
@@ -4,6 +4,8 @@
4
4
 
5
5
  import { useEffect, useState } from 'react';
6
6
 
7
+ import { Capabilities } from '@dxos/app-framework';
8
+ import { useCapability } from '@dxos/app-framework/ui';
7
9
  import { type Filter, type Queue, type Space } from '@dxos/client/echo';
8
10
  import { SpaceGraphModel, type SpaceGraphModelOptions } from '@dxos/schema';
9
11
 
@@ -14,23 +16,28 @@ export const useGraphModel = (
14
16
  options?: SpaceGraphModelOptions,
15
17
  queue?: Queue,
16
18
  ): SpaceGraphModel | undefined => {
19
+ const registry = useCapability(Capabilities.AtomRegistry);
17
20
  const [model, setModel] = useState<SpaceGraphModel | undefined>(undefined);
21
+
18
22
  useEffect(() => {
19
23
  if (!space) {
20
- void model?.close();
21
24
  setModel(undefined);
22
25
  return;
23
26
  }
24
27
 
25
- // TODO(burdon): Does this need to be a dependency?
26
- if (!model || model.queue !== queue) {
27
- const model = new SpaceGraphModel().setFilter(filter).setOptions(options);
28
- void model.open(space, queue);
29
- setModel(model);
30
- } else {
31
- model.setFilter(filter).setOptions(options);
32
- }
33
- }, [space, filter, options, queue]);
28
+ const newModel = new SpaceGraphModel(registry);
29
+ void newModel.open(space.db, queue);
30
+ setModel(newModel);
31
+
32
+ return () => {
33
+ setModel(undefined);
34
+ void newModel.close();
35
+ };
36
+ }, [space, registry, queue]);
37
+
38
+ useEffect(() => {
39
+ model?.setFilter(filter).setOptions(options);
40
+ }, [model, filter, options]);
34
41
 
35
42
  return model;
36
43
  };
package/src/index.ts CHANGED
@@ -2,8 +2,5 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- export * from './components';
6
- export * from './hooks';
7
5
  export * from './meta';
8
-
9
- export * from './ExplorerPlugin';
6
+ export * from './types';
package/src/meta.ts CHANGED
@@ -2,11 +2,11 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { type PluginMeta } from '@dxos/app-framework';
5
+ import { type Plugin } from '@dxos/app-framework';
6
6
  import { trim } from '@dxos/util';
7
7
 
8
- export const meta: PluginMeta = {
9
- id: 'dxos.org/plugin/explorer',
8
+ export const meta: Plugin.Meta = {
9
+ id: 'org.dxos.plugin.explorer',
10
10
  name: 'Explorer',
11
11
  description: trim`
12
12
  Interactive hypergraph visualization that reveals relationships between objects in your workspace.
package/src/plugin.ts ADDED
@@ -0,0 +1,9 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { Plugin } from '@dxos/app-framework';
6
+
7
+ import { meta } from './meta';
8
+
9
+ export const ExplorerPlugin = Plugin.lazy(meta, () => import('#plugin'));
@@ -4,27 +4,28 @@
4
4
 
5
5
  import { Type } from '@dxos/echo';
6
6
  import { type Resource } from '@dxos/react-ui';
7
- import { translations as componentsTranslations } from '@dxos/react-ui-components';
7
+ import { translations as componentsTranslations } from '@dxos/react-ui-components/translations';
8
8
 
9
- import { meta } from './meta';
10
- import { Graph } from './types';
9
+ import { meta } from '#meta';
10
+ import { Graph } from '#types';
11
11
 
12
12
  export const translations = [
13
13
  {
14
14
  'en-US': {
15
15
  [Type.getTypename(Graph.Graph)]: {
16
- 'typename label': 'Explorer',
17
- 'typename label_zero': 'Explorers',
18
- 'typename label_one': 'Explorer',
19
- 'typename label_other': 'Explorers',
20
- 'object name placeholder': 'New explorer',
21
- 'rename object label': 'Rename explorer',
22
- 'delete object label': 'Delete explorer',
23
- 'object deleted label': 'Explorer deleted',
16
+ 'typename.label': 'Explorer',
17
+ 'typename.label_zero': 'Explorers',
18
+ 'typename.label_one': 'Explorer',
19
+ 'typename.label_other': 'Explorers',
20
+ 'object-name.placeholder': 'New explorer',
21
+ 'add-object.label': 'Add explorer',
22
+ 'rename-object.label': 'Rename explorer',
23
+ 'delete-object.label': 'Delete explorer',
24
+ 'object-deleted.label': 'Explorer deleted',
24
25
  },
25
26
  [meta.id]: {
26
- 'plugin name': 'Explorer',
27
- 'object title label': 'Title',
27
+ 'plugin.name': 'Explorer',
28
+ 'object-title.label': 'Title',
28
29
  },
29
30
  },
30
31
  },
@@ -4,14 +4,7 @@
4
4
 
5
5
  import * as Schema from 'effect/Schema';
6
6
 
7
- import { TypeInputOptionsAnnotation } from '@dxos/plugin-space/types';
8
- import { SpaceSchema } from '@dxos/react-client/echo';
9
-
10
- import { meta } from '../meta';
11
-
12
- import * as Graph from './Graph';
13
-
14
- const EXPLORER_ACTION = `${meta.id}/action`;
7
+ import { TypeInputOptionsAnnotation } from '@dxos/plugin-space';
15
8
 
16
9
  export const GraphProps = Schema.Struct({
17
10
  name: Schema.optional(Schema.String),
@@ -21,17 +14,7 @@ export const GraphProps = Schema.Struct({
21
14
  TypeInputOptionsAnnotation.set({
22
15
  location: ['database', 'runtime'],
23
16
  kind: ['user'],
24
- registered: ['registered'],
25
17
  }),
26
18
  Schema.optional,
27
19
  ),
28
20
  });
29
-
30
- export class CreateGraph extends Schema.TaggedClass<CreateGraph>()(`${EXPLORER_ACTION}/create-graph`, {
31
- input: Schema.Struct({
32
- space: SpaceSchema,
33
- }).pipe(Schema.extend(GraphProps)),
34
- output: Schema.Struct({
35
- object: Graph.Graph,
36
- }),
37
- }) {}
@@ -4,30 +4,34 @@
4
4
 
5
5
  import * as Schema from 'effect/Schema';
6
6
 
7
- import { Filter, Obj, Query, QueryAST, Ref, Type } from '@dxos/echo';
7
+ import { Annotation, Filter, Obj, Query, QueryAST, Ref, Type } from '@dxos/echo';
8
+ import { View } from '@dxos/echo';
8
9
  import { FormInputAnnotation, LabelAnnotation } from '@dxos/echo/internal';
9
- import { View, ViewAnnotation } from '@dxos/schema';
10
+ import { ViewAnnotation } from '@dxos/schema';
10
11
 
11
12
  const GraphSchema = Schema.Struct({
12
13
  name: Schema.optional(Schema.String),
13
14
 
14
- view: Type.Ref(View.View).pipe(FormInputAnnotation.set(false)),
15
+ view: Ref.Ref(View.View).pipe(FormInputAnnotation.set(false)),
15
16
 
16
17
  query: Schema.Struct({
17
18
  raw: Schema.optional(Schema.String),
18
19
  ast: QueryAST.Query,
19
- }).pipe(Schema.mutable, FormInputAnnotation.set(false)),
20
+ }).pipe(FormInputAnnotation.set(false)),
20
21
  }).pipe(
21
- Type.Obj({
22
- typename: 'dxos.org/type/Graph',
23
- version: '0.2.0',
22
+ Type.object({
23
+ typename: 'org.dxos.type.graph',
24
+ version: '0.1.0',
24
25
  }),
25
26
  LabelAnnotation.set(['name']),
26
- ViewAnnotation.set(true),
27
+ ViewAnnotation.set(['view']),
28
+ Annotation.IconAnnotation.set({
29
+ icon: 'ph--graph--regular',
30
+ hue: 'green',
31
+ }),
27
32
  );
28
33
  export interface Graph extends Schema.Schema.Type<typeof GraphSchema> {}
29
- export interface GraphEncoded extends Schema.Schema.Encoded<typeof GraphSchema> {}
30
- export const Graph: Schema.Schema<Graph, GraphEncoded> = GraphSchema;
34
+ export const Graph: Type.Obj<Graph> = GraphSchema as any;
31
35
 
32
36
  type MakeProps = Omit<Partial<Obj.MakeProps<typeof Graph>>, 'view'> & {
33
37
  view: View.View;
@@ -43,21 +47,3 @@ export const make = ({
43
47
  }: MakeProps): Graph => {
44
48
  return Obj.make(Graph, { name, view: Ref.make(view), query });
45
49
  };
46
-
47
- //
48
- // V1
49
- //
50
-
51
- export const GraphV1 = Schema.Struct({
52
- name: Schema.optional(Schema.String),
53
- query: Schema.Struct({
54
- raw: Schema.optional(Schema.String),
55
- ast: QueryAST.Query,
56
- }).pipe(Schema.mutable),
57
- }).pipe(
58
- Type.Obj({
59
- typename: 'dxos.org/type/Graph',
60
- version: '0.1.0',
61
- }),
62
- LabelAnnotation.set(['name']),
63
- );
@@ -0,0 +1,8 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ declare module '*.css' {
6
+ const content: undefined;
7
+ export default content;
8
+ }
@@ -1,50 +0,0 @@
1
- import {
2
- useGraphModel
3
- } from "./chunk-2MKBRIUT.mjs";
4
- import {
5
- D3ForceGraph
6
- } from "./chunk-6BVXZQPP.mjs";
7
- import "./chunk-J5LGTIGS.mjs";
8
-
9
- // src/components/ExplorerContainer.tsx
10
- import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
11
- import React, { useCallback, useMemo, useState } from "react";
12
- import { QueryBuilder } from "@dxos/echo-query";
13
- import { useGlobalSearch } from "@dxos/plugin-search";
14
- import { getSpace } from "@dxos/react-client/echo";
15
- import { Toolbar } from "@dxos/react-ui";
16
- import { QueryEditor } from "@dxos/react-ui-components";
17
- import { StackItem } from "@dxos/react-ui-stack";
18
- var ExplorerContainer = ({ role, view }) => {
19
- var _effect = _useSignals();
20
- try {
21
- const space = getSpace(view);
22
- const [filter, setFilter] = useState();
23
- const model = useGraphModel(space, filter);
24
- const { match } = useGlobalSearch();
25
- const builder = useMemo(() => new QueryBuilder(), []);
26
- const handleChange = useCallback((value) => {
27
- setFilter(builder.build(value).filter);
28
- }, []);
29
- const showToolbar = role === "article";
30
- if (!space || !model) {
31
- return null;
32
- }
33
- return /* @__PURE__ */ React.createElement(StackItem.Content, {
34
- toolbar: showToolbar
35
- }, showToolbar && /* @__PURE__ */ React.createElement(Toolbar.Root, null, /* @__PURE__ */ React.createElement(QueryEditor, {
36
- db: space.db,
37
- onChange: handleChange
38
- })), /* @__PURE__ */ React.createElement(D3ForceGraph, {
39
- model,
40
- match
41
- }));
42
- } finally {
43
- _effect.f();
44
- }
45
- };
46
- var ExplorerContainer_default = ExplorerContainer;
47
- export {
48
- ExplorerContainer_default as default
49
- };
50
- //# sourceMappingURL=ExplorerContainer-NOLLVUTE.mjs.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/components/ExplorerContainer.tsx"],
4
- "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport React, { useCallback, useMemo, useState } from 'react';\n\nimport { type Filter } from '@dxos/echo';\nimport { QueryBuilder } from '@dxos/echo-query';\nimport { useGlobalSearch } from '@dxos/plugin-search';\nimport { getSpace } from '@dxos/react-client/echo';\nimport { Toolbar } from '@dxos/react-ui';\nimport { QueryEditor, type QueryEditorProps } from '@dxos/react-ui-components';\nimport { StackItem } from '@dxos/react-ui-stack';\nimport { type View } from '@dxos/schema';\n\nimport { useGraphModel } from '../hooks';\n\nimport { D3ForceGraph } from './Graph';\n\ntype ExplorerContainerProps = {\n role: string;\n view: View.View;\n};\n\nconst ExplorerContainer = ({ role, view }: ExplorerContainerProps) => {\n const space = getSpace(view);\n const [filter, setFilter] = useState<Filter.Any>();\n const model = useGraphModel(space, filter);\n const { match } = useGlobalSearch();\n\n const builder = useMemo(() => new QueryBuilder(), []);\n const handleChange = useCallback<NonNullable<QueryEditorProps['onChange']>>((value) => {\n setFilter(builder.build(value).filter);\n }, []);\n\n const showToolbar = role === 'article';\n\n if (!space || !model) {\n return null;\n }\n\n return (\n <StackItem.Content toolbar={showToolbar}>\n {showToolbar && (\n <Toolbar.Root>\n <QueryEditor db={space.db} onChange={handleChange} />\n </Toolbar.Root>\n )}\n <D3ForceGraph model={model} match={match} />\n </StackItem.Content>\n );\n};\n\nexport default ExplorerContainer;\n"],
5
- "mappings": ";;;;;;;;;;AAIA,OAAOA,SAASC,aAAaC,SAASC,gBAAgB;AAGtD,SAASC,oBAAoB;AAC7B,SAASC,uBAAuB;AAChC,SAASC,gBAAgB;AACzB,SAASC,eAAe;AACxB,SAASC,mBAA0C;AACnD,SAASC,iBAAiB;AAY1B,IAAMC,oBAAoB,CAAC,EAAEC,MAAMC,KAAI,MAA0B;;;AAC/D,UAAMC,QAAQC,SAASF,IAAAA;AACvB,UAAM,CAACG,QAAQC,SAAAA,IAAaC,SAAAA;AAC5B,UAAMC,QAAQC,cAAcN,OAAOE,MAAAA;AACnC,UAAM,EAAEK,MAAK,IAAKC,gBAAAA;AAElB,UAAMC,UAAUC,QAAQ,MAAM,IAAIC,aAAAA,GAAgB,CAAA,CAAE;AACpD,UAAMC,eAAeC,YAAuD,CAACC,UAAAA;AAC3EX,gBAAUM,QAAQM,MAAMD,KAAAA,EAAOZ,MAAM;IACvC,GAAG,CAAA,CAAE;AAEL,UAAMc,cAAclB,SAAS;AAE7B,QAAI,CAACE,SAAS,CAACK,OAAO;AACpB,aAAO;IACT;AAEA,WACE,sBAAA,cAACY,UAAUC,SAAO;MAACC,SAASH;OACzBA,eACC,sBAAA,cAACI,QAAQC,MAAI,MACX,sBAAA,cAACC,aAAAA;MAAYC,IAAIvB,MAAMuB;MAAIC,UAAUZ;SAGzC,sBAAA,cAACa,cAAAA;MAAapB;MAAcE;;;;;AAGlC;AAEA,IAAA,4BAAeV;",
6
- "names": ["React", "useCallback", "useMemo", "useState", "QueryBuilder", "useGlobalSearch", "getSpace", "Toolbar", "QueryEditor", "StackItem", "ExplorerContainer", "role", "view", "space", "getSpace", "filter", "setFilter", "useState", "model", "useGraphModel", "match", "useGlobalSearch", "builder", "useMemo", "QueryBuilder", "handleChange", "useCallback", "value", "build", "showToolbar", "StackItem", "Content", "toolbar", "Toolbar", "Root", "QueryEditor", "db", "onChange", "D3ForceGraph"]
7
- }
@@ -1,31 +0,0 @@
1
- // src/hooks/useGraphModel.ts
2
- import { useEffect, useState } from "react";
3
- import { SpaceGraphModel } from "@dxos/schema";
4
- var useGraphModel = (space, filter, options, queue) => {
5
- const [model, setModel] = useState(void 0);
6
- useEffect(() => {
7
- if (!space) {
8
- void model?.close();
9
- setModel(void 0);
10
- return;
11
- }
12
- if (!model || model.queue !== queue) {
13
- const model2 = new SpaceGraphModel().setFilter(filter).setOptions(options);
14
- void model2.open(space, queue);
15
- setModel(model2);
16
- } else {
17
- model.setFilter(filter).setOptions(options);
18
- }
19
- }, [
20
- space,
21
- filter,
22
- options,
23
- queue
24
- ]);
25
- return model;
26
- };
27
-
28
- export {
29
- useGraphModel
30
- };
31
- //# sourceMappingURL=chunk-2MKBRIUT.mjs.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/hooks/useGraphModel.ts"],
4
- "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { useEffect, useState } from 'react';\n\nimport { type Filter, type Queue, type Space } from '@dxos/client/echo';\nimport { SpaceGraphModel, type SpaceGraphModelOptions } from '@dxos/schema';\n\n// TODO(burdon): Factor out.\nexport const useGraphModel = (\n space: Space | undefined,\n filter?: Filter.Any | undefined,\n options?: SpaceGraphModelOptions,\n queue?: Queue,\n): SpaceGraphModel | undefined => {\n const [model, setModel] = useState<SpaceGraphModel | undefined>(undefined);\n useEffect(() => {\n if (!space) {\n void model?.close();\n setModel(undefined);\n return;\n }\n\n // TODO(burdon): Does this need to be a dependency?\n if (!model || model.queue !== queue) {\n const model = new SpaceGraphModel().setFilter(filter).setOptions(options);\n void model.open(space, queue);\n setModel(model);\n } else {\n model.setFilter(filter).setOptions(options);\n }\n }, [space, filter, options, queue]);\n\n return model;\n};\n"],
5
- "mappings": ";AAIA,SAASA,WAAWC,gBAAgB;AAGpC,SAASC,uBAAoD;AAGtD,IAAMC,gBAAgB,CAC3BC,OACAC,QACAC,SACAC,UAAAA;AAEA,QAAM,CAACC,OAAOC,QAAAA,IAAYC,SAAsCC,MAAAA;AAChEC,YAAU,MAAA;AACR,QAAI,CAACR,OAAO;AACV,WAAKI,OAAOK,MAAAA;AACZJ,eAASE,MAAAA;AACT;IACF;AAGA,QAAI,CAACH,SAASA,MAAMD,UAAUA,OAAO;AACnC,YAAMC,SAAQ,IAAIM,gBAAAA,EAAkBC,UAAUV,MAAAA,EAAQW,WAAWV,OAAAA;AACjE,WAAKE,OAAMS,KAAKb,OAAOG,KAAAA;AACvBE,eAASD,MAAAA;IACX,OAAO;AACLA,YAAMO,UAAUV,MAAAA,EAAQW,WAAWV,OAAAA;IACrC;EACF,GAAG;IAACF;IAAOC;IAAQC;IAASC;GAAM;AAElC,SAAOC;AACT;",
6
- "names": ["useEffect", "useState", "SpaceGraphModel", "useGraphModel", "space", "filter", "options", "queue", "model", "setModel", "useState", "undefined", "useEffect", "close", "SpaceGraphModel", "setFilter", "setOptions", "open"]
7
- }