@dxos/plugin-explorer 0.8.4-main.5ad4a44 → 0.8.4-main.66e292d

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 (101) hide show
  1. package/dist/lib/browser/{ExplorerContainer-S66JDOAF.mjs → ExplorerContainer-NOLLVUTE.mjs} +8 -7
  2. package/dist/lib/browser/ExplorerContainer-NOLLVUTE.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-NXGP6NTP.mjs → chunk-6BVXZQPP.mjs} +10 -25
  4. package/dist/lib/browser/{chunk-NXGP6NTP.mjs.map → chunk-6BVXZQPP.mjs.map} +2 -2
  5. package/dist/lib/browser/{chunk-UCDNCIRV.mjs → chunk-ARBGXQFH.mjs} +4 -256
  6. package/dist/lib/browser/{chunk-UCDNCIRV.mjs.map → chunk-ARBGXQFH.mjs.map} +3 -3
  7. package/dist/lib/browser/chunk-J5LGTIGS.mjs +10 -0
  8. package/dist/lib/browser/chunk-J5LGTIGS.mjs.map +7 -0
  9. package/dist/lib/browser/chunk-P6FFFVPM.mjs +100 -0
  10. package/dist/lib/browser/chunk-P6FFFVPM.mjs.map +7 -0
  11. package/dist/lib/browser/{chunk-2DGFNLRO.mjs → chunk-UBHZGWZQ.mjs} +7 -2
  12. package/dist/lib/browser/chunk-UBHZGWZQ.mjs.map +7 -0
  13. package/dist/lib/browser/index.mjs +23 -23
  14. package/dist/lib/browser/index.mjs.map +3 -3
  15. package/dist/lib/browser/intent-resolver-EWB3H5KH.mjs +35 -0
  16. package/dist/lib/browser/intent-resolver-EWB3H5KH.mjs.map +7 -0
  17. package/dist/lib/browser/meta.json +1 -1
  18. package/dist/lib/browser/meta.mjs +2 -1
  19. package/dist/lib/browser/{react-surface-C4EC6ZDZ.mjs → react-surface-BY2DYCTH.mjs} +14 -11
  20. package/dist/lib/browser/react-surface-BY2DYCTH.mjs.map +7 -0
  21. package/dist/lib/browser/types/index.mjs +7 -6
  22. package/dist/lib/node-esm/{ExplorerContainer-GIJN67DO.mjs → ExplorerContainer-N3S5KSUX.mjs} +8 -7
  23. package/dist/lib/node-esm/ExplorerContainer-N3S5KSUX.mjs.map +7 -0
  24. package/dist/lib/node-esm/chunk-4BY2XZET.mjs +101 -0
  25. package/dist/lib/node-esm/chunk-4BY2XZET.mjs.map +7 -0
  26. package/dist/lib/node-esm/{chunk-6JACZE7E.mjs → chunk-CRSVAZNA.mjs} +10 -25
  27. package/dist/lib/node-esm/{chunk-6JACZE7E.mjs.map → chunk-CRSVAZNA.mjs.map} +2 -2
  28. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
  29. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +7 -0
  30. package/dist/lib/node-esm/{chunk-WHKUQG5M.mjs → chunk-NPIP4VEH.mjs} +4 -256
  31. package/dist/lib/node-esm/{chunk-WHKUQG5M.mjs.map → chunk-NPIP4VEH.mjs.map} +3 -3
  32. package/dist/lib/node-esm/{chunk-PX6LHR2N.mjs → chunk-UXZM5VJB.mjs} +7 -2
  33. package/dist/lib/node-esm/chunk-UXZM5VJB.mjs.map +7 -0
  34. package/dist/lib/node-esm/index.mjs +23 -23
  35. package/dist/lib/node-esm/index.mjs.map +3 -3
  36. package/dist/lib/node-esm/intent-resolver-SH6PW7VF.mjs +36 -0
  37. package/dist/lib/node-esm/intent-resolver-SH6PW7VF.mjs.map +7 -0
  38. package/dist/lib/node-esm/meta.json +1 -1
  39. package/dist/lib/node-esm/meta.mjs +2 -1
  40. package/dist/lib/node-esm/{react-surface-YGGLTBF3.mjs → react-surface-7AAV7GBG.mjs} +14 -11
  41. package/dist/lib/node-esm/react-surface-7AAV7GBG.mjs.map +7 -0
  42. package/dist/lib/node-esm/types/index.mjs +7 -6
  43. package/dist/types/src/ExplorerPlugin.d.ts.map +1 -1
  44. package/dist/types/src/capabilities/index.d.ts +1 -1
  45. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  46. package/dist/types/src/capabilities/intent-resolver.d.ts +2 -2
  47. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
  48. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  49. package/dist/types/src/components/ExplorerContainer.d.ts +2 -2
  50. package/dist/types/src/components/ExplorerContainer.d.ts.map +1 -1
  51. package/dist/types/src/components/Graph/D3ForceGraph.stories.d.ts.map +1 -1
  52. package/dist/types/src/components/Graph/ForceGraph.stories.d.ts.map +1 -1
  53. package/dist/types/src/components/Graph/testing.d.ts.map +1 -1
  54. package/dist/types/src/components/Tree/types/tree.d.ts +6 -6
  55. package/dist/types/src/components/index.d.ts +2 -4
  56. package/dist/types/src/components/index.d.ts.map +1 -1
  57. package/dist/types/src/meta.d.ts.map +1 -1
  58. package/dist/types/src/translations.d.ts +14 -6
  59. package/dist/types/src/translations.d.ts.map +1 -1
  60. package/dist/types/src/types/ExplorerAction.d.ts +23 -0
  61. package/dist/types/src/types/ExplorerAction.d.ts.map +1 -0
  62. package/dist/types/src/types/Graph.d.ts +32 -0
  63. package/dist/types/src/types/Graph.d.ts.map +1 -0
  64. package/dist/types/src/types/index.d.ts +2 -2
  65. package/dist/types/src/types/index.d.ts.map +1 -1
  66. package/dist/types/tsconfig.tsbuildinfo +1 -1
  67. package/package.json +30 -29
  68. package/src/ExplorerPlugin.tsx +9 -17
  69. package/src/capabilities/intent-resolver.ts +12 -8
  70. package/src/capabilities/react-surface.tsx +6 -3
  71. package/src/components/ExplorerContainer.tsx +11 -7
  72. package/src/components/Graph/D3ForceGraph.stories.tsx +22 -10
  73. package/src/components/Graph/ForceGraph.stories.tsx +22 -10
  74. package/src/components/Graph/testing.ts +6 -6
  75. package/src/components/Tree/types/tree.test.ts +2 -2
  76. package/src/components/index.ts +3 -3
  77. package/src/meta.ts +6 -1
  78. package/src/translations.ts +4 -2
  79. package/src/types/ExplorerAction.ts +37 -0
  80. package/src/types/Graph.ts +63 -0
  81. package/src/types/index.ts +2 -2
  82. package/dist/lib/browser/ExplorerContainer-S66JDOAF.mjs.map +0 -7
  83. package/dist/lib/browser/chunk-2DGFNLRO.mjs.map +0 -7
  84. package/dist/lib/browser/chunk-4ETQJYX4.mjs +0 -38
  85. package/dist/lib/browser/chunk-4ETQJYX4.mjs.map +0 -7
  86. package/dist/lib/browser/intent-resolver-OXJJ3PII.mjs +0 -24
  87. package/dist/lib/browser/intent-resolver-OXJJ3PII.mjs.map +0 -7
  88. package/dist/lib/browser/react-surface-C4EC6ZDZ.mjs.map +0 -7
  89. package/dist/lib/node-esm/ExplorerContainer-GIJN67DO.mjs.map +0 -7
  90. package/dist/lib/node-esm/chunk-AGHU3KVI.mjs +0 -39
  91. package/dist/lib/node-esm/chunk-AGHU3KVI.mjs.map +0 -7
  92. package/dist/lib/node-esm/chunk-PX6LHR2N.mjs.map +0 -7
  93. package/dist/lib/node-esm/intent-resolver-GVM36TJX.mjs +0 -25
  94. package/dist/lib/node-esm/intent-resolver-GVM36TJX.mjs.map +0 -7
  95. package/dist/lib/node-esm/react-surface-YGGLTBF3.mjs.map +0 -7
  96. package/dist/types/src/types/schema.d.ts +0 -12
  97. package/dist/types/src/types/schema.d.ts.map +0 -1
  98. package/dist/types/src/types/types.d.ts +0 -18
  99. package/dist/types/src/types/types.d.ts.map +0 -1
  100. package/src/types/schema.ts +0 -16
  101. package/src/types/types.ts +0 -22
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/plugin-explorer",
3
- "version": "0.8.4-main.5ad4a44",
3
+ "version": "0.8.4-main.66e292d",
4
4
  "description": "Braneframe data visualization plugin",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -55,50 +55,51 @@
55
55
  "react-resize-detector": "^11.0.1",
56
56
  "three": "^0.178.0",
57
57
  "topojson-client": "^3.1.0",
58
- "@dxos/app-framework": "0.8.4-main.5ad4a44",
59
- "@dxos/async": "0.8.4-main.5ad4a44",
60
- "@dxos/echo": "0.8.4-main.5ad4a44",
61
- "@dxos/client": "0.8.4-main.5ad4a44",
62
- "@dxos/echo-query": "0.8.4-main.5ad4a44",
63
- "@dxos/graph": "0.8.4-main.5ad4a44",
64
- "@dxos/invariant": "0.8.4-main.5ad4a44",
65
- "@dxos/log": "0.8.4-main.5ad4a44",
66
- "@dxos/live-object": "0.8.4-main.5ad4a44",
67
- "@dxos/plugin-client": "0.8.4-main.5ad4a44",
68
- "@dxos/plugin-search": "0.8.4-main.5ad4a44",
69
- "@dxos/plugin-graph": "0.8.4-main.5ad4a44",
70
- "@dxos/plugin-space": "0.8.4-main.5ad4a44",
71
- "@dxos/react-client": "0.8.4-main.5ad4a44",
72
- "@dxos/react-ui-attention": "0.8.4-main.5ad4a44",
73
- "@dxos/react-ui-graph": "0.8.4-main.5ad4a44",
74
- "@dxos/react-ui-stack": "0.8.4-main.5ad4a44",
75
- "@dxos/react-ui-components": "0.8.4-main.5ad4a44",
76
- "@dxos/schema": "0.8.4-main.5ad4a44",
77
- "@dxos/util": "0.8.4-main.5ad4a44"
58
+ "@dxos/app-framework": "0.8.4-main.66e292d",
59
+ "@dxos/async": "0.8.4-main.66e292d",
60
+ "@dxos/client": "0.8.4-main.66e292d",
61
+ "@dxos/invariant": "0.8.4-main.66e292d",
62
+ "@dxos/graph": "0.8.4-main.66e292d",
63
+ "@dxos/echo-query": "0.8.4-main.66e292d",
64
+ "@dxos/echo": "0.8.4-main.66e292d",
65
+ "@dxos/live-object": "0.8.4-main.66e292d",
66
+ "@dxos/log": "0.8.4-main.66e292d",
67
+ "@dxos/plugin-client": "0.8.4-main.66e292d",
68
+ "@dxos/plugin-search": "0.8.4-main.66e292d",
69
+ "@dxos/plugin-graph": "0.8.4-main.66e292d",
70
+ "@dxos/plugin-space": "0.8.4-main.66e292d",
71
+ "@dxos/react-client": "0.8.4-main.66e292d",
72
+ "@dxos/react-ui-attention": "0.8.4-main.66e292d",
73
+ "@dxos/react-ui-graph": "0.8.4-main.66e292d",
74
+ "@dxos/react-ui-components": "0.8.4-main.66e292d",
75
+ "@dxos/react-ui-stack": "0.8.4-main.66e292d",
76
+ "@dxos/schema": "0.8.4-main.66e292d",
77
+ "@dxos/util": "0.8.4-main.66e292d",
78
+ "@dxos/types": "0.8.4-main.66e292d"
78
79
  },
79
80
  "devDependencies": {
80
81
  "@types/d3": "^7.4.3",
81
82
  "@types/d3-hierarchy": "^3.1.6",
82
83
  "@types/lodash.defaultsdeep": "^4.6.6",
83
84
  "@types/react": "~19.2.2",
84
- "@types/react-dom": "~19.2.1",
85
+ "@types/react-dom": "~19.2.2",
85
86
  "@types/topojson-client": "^3.1.4",
86
87
  "@types/topojson-specification": "^1.0.5",
87
88
  "react": "~19.2.0",
88
89
  "react-dom": "~19.2.0",
89
90
  "vite": "7.1.9",
90
- "@dxos/echo-generator": "0.8.4-main.5ad4a44",
91
- "@dxos/random": "0.8.4-main.5ad4a44",
92
- "@dxos/react-ui": "0.8.4-main.5ad4a44",
93
- "@dxos/react-ui-theme": "0.8.4-main.5ad4a44",
94
- "@dxos/storybook-utils": "0.8.4-main.5ad4a44"
91
+ "@dxos/echo-generator": "0.8.4-main.66e292d",
92
+ "@dxos/random": "0.8.4-main.66e292d",
93
+ "@dxos/react-ui": "0.8.4-main.66e292d",
94
+ "@dxos/react-ui-theme": "0.8.4-main.66e292d",
95
+ "@dxos/storybook-utils": "0.8.4-main.66e292d"
95
96
  },
96
97
  "peerDependencies": {
97
98
  "effect": "^3.13.3",
98
99
  "react": "^19.0.0",
99
100
  "react-dom": "^19.0.0",
100
- "@dxos/react-ui": "0.8.4-main.5ad4a44",
101
- "@dxos/react-ui-theme": "0.8.4-main.5ad4a44"
101
+ "@dxos/react-ui": "0.8.4-main.66e292d",
102
+ "@dxos/react-ui-theme": "0.8.4-main.66e292d"
102
103
  },
103
104
  "publishConfig": {
104
105
  "access": "public"
@@ -3,14 +3,14 @@
3
3
  //
4
4
 
5
5
  import { Capabilities, Events, contributes, createIntent, defineModule, definePlugin } from '@dxos/app-framework';
6
+ import { Type } from '@dxos/echo';
6
7
  import { ClientCapabilities, ClientEvents } from '@dxos/plugin-client';
7
- import { SpaceCapabilities } from '@dxos/plugin-space';
8
- import { defineObjectForm } from '@dxos/plugin-space/types';
8
+ import { type CreateObjectIntent } from '@dxos/plugin-space/types';
9
9
 
10
10
  import { IntentResolver, ReactSurface } from './capabilities';
11
11
  import { meta } from './meta';
12
12
  import { translations } from './translations';
13
- import { ExplorerAction, ViewType } from './types';
13
+ import { ExplorerAction, Graph } from './types';
14
14
 
15
15
  export const ExplorerPlugin = definePlugin(meta, () => [
16
16
  defineModule({
@@ -23,28 +23,20 @@ export const ExplorerPlugin = definePlugin(meta, () => [
23
23
  activatesOn: Events.SetupMetadata,
24
24
  activate: () =>
25
25
  contributes(Capabilities.Metadata, {
26
- id: ViewType.typename,
26
+ id: Type.getTypename(Graph.Graph),
27
27
  metadata: {
28
28
  icon: 'ph--graph--regular',
29
+ iconHue: 'green',
30
+ inputSchema: ExplorerAction.GraphProps,
31
+ createObjectIntent: ((props, options) =>
32
+ createIntent(ExplorerAction.CreateGraph, { ...props, space: options.space })) satisfies CreateObjectIntent,
29
33
  },
30
34
  }),
31
35
  }),
32
- defineModule({
33
- id: `${meta.id}/module/object-form`,
34
- activatesOn: ClientEvents.SetupSchema,
35
- activate: () =>
36
- contributes(
37
- SpaceCapabilities.ObjectForm,
38
- defineObjectForm({
39
- objectSchema: ViewType,
40
- getIntent: () => createIntent(ExplorerAction.Create),
41
- }),
42
- ),
43
- }),
44
36
  defineModule({
45
37
  id: `${meta.id}/module/schema`,
46
38
  activatesOn: ClientEvents.SetupSchema,
47
- activate: () => contributes(ClientCapabilities.Schema, [ViewType]),
39
+ activate: () => contributes(ClientCapabilities.Schema, [Graph.Graph]),
48
40
  }),
49
41
  defineModule({
50
42
  id: `${meta.id}/module/react-surface`,
@@ -2,18 +2,22 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Capabilities, contributes, createResolver } from '@dxos/app-framework';
6
- import { Obj } from '@dxos/echo';
5
+ import { Capabilities, type PluginContext, contributes, createResolver } from '@dxos/app-framework';
6
+ import { ClientCapabilities } from '@dxos/plugin-client';
7
+ import { View } from '@dxos/schema';
7
8
 
8
- import { ExplorerAction, ViewType } from '../types';
9
+ import { ExplorerAction, Graph } from '../types';
9
10
 
10
- export default () =>
11
+ export default (context: PluginContext) =>
11
12
  contributes(
12
13
  Capabilities.IntentResolver,
13
14
  createResolver({
14
- intent: ExplorerAction.Create,
15
- resolve: ({ name }) => ({
16
- data: { object: Obj.make(ViewType, { name, type: '' }) },
17
- }),
15
+ intent: ExplorerAction.CreateGraph,
16
+ resolve: async ({ space, name, typename }) => {
17
+ const client = context.getCapability(ClientCapabilities.Client);
18
+ const { view } = await View.makeFromSpace({ client, space, typename });
19
+ const graph = Graph.make({ name, view });
20
+ return { data: { object: graph } };
21
+ },
18
22
  }),
19
23
  );
@@ -6,10 +6,11 @@ import React from 'react';
6
6
 
7
7
  import { Capabilities, contributes, createSurface } from '@dxos/app-framework';
8
8
  import { Obj } from '@dxos/echo';
9
+ import { type View } from '@dxos/schema';
9
10
 
10
11
  import { ExplorerContainer } from '../components';
11
12
  import { meta } from '../meta';
12
- import { ViewType } from '../types';
13
+ import { Graph } from '../types';
13
14
 
14
15
  export default () =>
15
16
  contributes(
@@ -17,7 +18,9 @@ export default () =>
17
18
  createSurface({
18
19
  id: `${meta.id}/article`,
19
20
  role: ['article', 'section'],
20
- filter: (data): data is { subject: ViewType } => Obj.instanceOf(ViewType, data.subject),
21
- component: ({ data, role }) => <ExplorerContainer view={data.subject} role={role} />,
21
+ filter: (data): data is { subject: View.View } => Obj.instanceOf(Graph.Graph, data.subject),
22
+ component: ({ data, role }) => {
23
+ return <ExplorerContainer view={data.subject} role={role} />;
24
+ },
22
25
  }),
23
26
  );
@@ -11,15 +11,15 @@ import { getSpace } from '@dxos/react-client/echo';
11
11
  import { Toolbar } from '@dxos/react-ui';
12
12
  import { QueryEditor, type QueryEditorProps } from '@dxos/react-ui-components';
13
13
  import { StackItem } from '@dxos/react-ui-stack';
14
+ import { type View } from '@dxos/schema';
14
15
 
15
16
  import { useGraphModel } from '../hooks';
16
- import { type ViewType } from '../types';
17
17
 
18
18
  import { D3ForceGraph } from './Graph';
19
19
 
20
20
  type ExplorerContainerProps = {
21
21
  role: string;
22
- view: ViewType;
22
+ view: View.View;
23
23
  };
24
24
 
25
25
  const ExplorerContainer = ({ role, view }: ExplorerContainerProps) => {
@@ -30,18 +30,22 @@ const ExplorerContainer = ({ role, view }: ExplorerContainerProps) => {
30
30
 
31
31
  const builder = useMemo(() => new QueryBuilder(), []);
32
32
  const handleChange = useCallback<NonNullable<QueryEditorProps['onChange']>>((value) => {
33
- setFilter(builder.build(value));
33
+ setFilter(builder.build(value).filter);
34
34
  }, []);
35
35
 
36
+ const showToolbar = role === 'article';
37
+
36
38
  if (!space || !model) {
37
39
  return null;
38
40
  }
39
41
 
40
42
  return (
41
- <StackItem.Content toolbar size={role === 'section' ? 'square' : 'intrinsic'}>
42
- <Toolbar.Root>
43
- <QueryEditor space={space} onChange={handleChange} />
44
- </Toolbar.Root>
43
+ <StackItem.Content toolbar={showToolbar}>
44
+ {showToolbar && (
45
+ <Toolbar.Root>
46
+ <QueryEditor db={space.db} onChange={handleChange} />
47
+ </Toolbar.Root>
48
+ )}
45
49
  <D3ForceGraph model={model} match={match} />
46
50
  </StackItem.Content>
47
51
  );
@@ -3,20 +3,22 @@
3
3
  //
4
4
 
5
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
6
- import React, { useEffect, useState } from 'react';
6
+ import React, { useState } from 'react';
7
7
 
8
- import { Obj } from '@dxos/echo';
8
+ import { Type } from '@dxos/echo';
9
9
  import { faker } from '@dxos/random';
10
10
  import { useClient } from '@dxos/react-client';
11
11
  import { type Space } from '@dxos/react-client/echo';
12
12
  import { withClientProvider } from '@dxos/react-client/testing';
13
+ import { useAsyncEffect } from '@dxos/react-ui';
13
14
  import { withTheme } from '@dxos/react-ui/testing';
14
- import { DataType } from '@dxos/schema';
15
+ import { View } from '@dxos/schema';
15
16
  import { type ValueGenerator } from '@dxos/schema/testing';
16
17
  import { render } from '@dxos/storybook-utils';
18
+ import { HasRelationship, Organization, Person, Project } from '@dxos/types';
17
19
 
18
20
  import { useGraphModel } from '../../hooks';
19
- import { ViewType } from '../../types';
21
+ import { Graph } from '../../types';
20
22
 
21
23
  import { D3ForceGraph } from './D3ForceGraph';
22
24
  import { generate } from './testing';
@@ -28,17 +30,20 @@ faker.seed(1);
28
30
  const DefaultStory = () => {
29
31
  const client = useClient();
30
32
  const [space, setSpace] = useState<Space>();
31
- const [view, setView] = useState<ViewType>();
32
- useEffect(() => {
33
+ const [graph, setGraph] = useState<Graph.Graph>();
34
+
35
+ useAsyncEffect(async () => {
33
36
  const space = client.spaces.default;
34
37
  void generate(space, generator);
35
- const view = space.db.add(Obj.make(ViewType, { name: '', type: '' }));
38
+ const { view } = await View.makeFromSpace({ client, space, typename: Type.getTypename(Graph.Graph) });
39
+ const graph = Graph.make({ name: 'Test', view });
40
+ space.db.add(graph);
36
41
  setSpace(space);
37
- setView(view);
42
+ setGraph(graph);
38
43
  }, []);
39
44
 
40
45
  const model = useGraphModel(space);
41
- if (!model || !space || !view) {
46
+ if (!model || !space || !graph) {
42
47
  return null;
43
48
  }
44
49
 
@@ -53,7 +58,14 @@ const meta = {
53
58
  withTheme,
54
59
  withClientProvider({
55
60
  createSpace: true,
56
- types: [ViewType, DataType.Organization, DataType.Project, DataType.Person, DataType.HasRelationship],
61
+ types: [
62
+ Graph.Graph,
63
+ View.View,
64
+ Organization.Organization,
65
+ Project.Project,
66
+ Person.Person,
67
+ HasRelationship.HasRelationship,
68
+ ],
57
69
  }),
58
70
  ],
59
71
  parameters: {
@@ -3,20 +3,22 @@
3
3
  //
4
4
 
5
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
6
- import React, { useEffect, useState } from 'react';
6
+ import React, { useState } from 'react';
7
7
 
8
- import { Obj } from '@dxos/echo';
8
+ import { Type } from '@dxos/echo';
9
9
  import { faker } from '@dxos/random';
10
10
  import { useClient } from '@dxos/react-client';
11
11
  import { type Space } from '@dxos/react-client/echo';
12
12
  import { withClientProvider } from '@dxos/react-client/testing';
13
+ import { useAsyncEffect } from '@dxos/react-ui';
13
14
  import { withTheme } from '@dxos/react-ui/testing';
14
- import { DataType } from '@dxos/schema';
15
+ import { View } from '@dxos/schema';
15
16
  import { type ValueGenerator } from '@dxos/schema/testing';
16
17
  import { render } from '@dxos/storybook-utils';
18
+ import { HasRelationship, Organization, Person, Project } from '@dxos/types';
17
19
 
18
20
  import { useGraphModel } from '../../hooks';
19
- import { ViewType } from '../../types';
21
+ import { Graph } from '../../types';
20
22
 
21
23
  import { ForceGraph } from './ForceGraph';
22
24
  import { generate } from './testing';
@@ -28,17 +30,20 @@ faker.seed(1);
28
30
  const DefaultStory = () => {
29
31
  const client = useClient();
30
32
  const [space, setSpace] = useState<Space>();
31
- const [view, setView] = useState<ViewType>();
32
- useEffect(() => {
33
+ const [graph, setGraph] = useState<Graph.Graph>();
34
+
35
+ useAsyncEffect(async () => {
33
36
  const space = client.spaces.default;
34
37
  void generate(space, generator);
35
- const view = space.db.add(Obj.make(ViewType, { name: '', type: '' }));
38
+ const { view } = await View.makeFromSpace({ client, space, typename: Type.getTypename(Graph.Graph) });
39
+ const graph = Graph.make({ name: 'Test', view });
40
+ space.db.add(graph);
36
41
  setSpace(space);
37
- setView(view);
42
+ setGraph(graph);
38
43
  }, []);
39
44
 
40
45
  const model = useGraphModel(space);
41
- if (!model || !space || !view) {
46
+ if (!model || !space || !graph) {
42
47
  return null;
43
48
  }
44
49
 
@@ -53,7 +58,14 @@ const meta = {
53
58
  withTheme,
54
59
  withClientProvider({
55
60
  createSpace: true,
56
- types: [ViewType, DataType.HasRelationship, DataType.Organization, DataType.Project, DataType.Person],
61
+ types: [
62
+ Graph.Graph,
63
+ View.View,
64
+ HasRelationship.HasRelationship,
65
+ Organization.Organization,
66
+ Project.Project,
67
+ Person.Person,
68
+ ],
57
69
  }),
58
70
  ],
59
71
  parameters: {
@@ -4,16 +4,16 @@
4
4
 
5
5
  import { type Space } from '@dxos/client/echo';
6
6
  import { type Obj, Query, Relation } from '@dxos/echo';
7
- import { DataType } from '@dxos/schema';
8
7
  import { type TypeSpec, type ValueGenerator, createObjectFactory } from '@dxos/schema/testing';
8
+ import { HasRelationship, Organization, Person, Project } from '@dxos/types';
9
9
  import { range } from '@dxos/util';
10
10
 
11
11
  const getObject = (objects: Obj.Any[]) => objects[Math.floor(Math.random() * objects.length)];
12
12
 
13
13
  const defaultTypes: TypeSpec[] = [
14
- { type: DataType.Organization, count: 5 },
15
- { type: DataType.Project, count: 5 },
16
- { type: DataType.Person, count: 10 },
14
+ { type: Organization.Organization, count: 5 },
15
+ { type: Project.Project, count: 5 },
16
+ { type: Person.Person, count: 10 },
17
17
  ];
18
18
 
19
19
  export type GenerateOptions = {
@@ -38,13 +38,13 @@ export const generate = async (
38
38
  await createObjects(spec);
39
39
 
40
40
  // Add relations between objects.
41
- const { objects: contacts } = await space.db.query(Query.type(DataType.Person)).run();
41
+ const { objects: contacts } = await space.db.query(Query.type(Person.Person)).run();
42
42
  for (const _ of range(relations.count)) {
43
43
  const source = getObject(contacts);
44
44
  const target = getObject(contacts);
45
45
  if (source.id !== target.id) {
46
46
  space.db.add(
47
- Relation.make(DataType.HasRelationship, {
47
+ Relation.make(HasRelationship.HasRelationship, {
48
48
  [Relation.Source]: source,
49
49
  [Relation.Target]: target,
50
50
  kind: relations.kind,
@@ -6,7 +6,7 @@ import { describe, test } from 'vitest';
6
6
 
7
7
  import { Obj, Ref } from '@dxos/echo';
8
8
  import { faker } from '@dxos/random';
9
- import { DataType } from '@dxos/schema';
9
+ import { Task } from '@dxos/types';
10
10
 
11
11
  import { createTree } from '../testing';
12
12
 
@@ -124,7 +124,7 @@ describe('tree', () => {
124
124
  });
125
125
 
126
126
  test('task', ({ expect }) => {
127
- const task = Obj.make(DataType.Task, { title: 'Test task.' });
127
+ const task = Obj.make(Task.Task, { title: 'Test task.' });
128
128
  expect(task.title).to.eq('Test task.');
129
129
 
130
130
  const tree = createTree();
@@ -2,11 +2,11 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { lazy } from 'react';
6
-
7
- export const ExplorerContainer = lazy(() => import('./ExplorerContainer'));
5
+ import { type ComponentType, lazy } from 'react';
8
6
 
9
7
  export * from './Chart';
10
8
  export * from './Globe';
11
9
  export * from './Graph';
12
10
  export * from './Tree';
11
+
12
+ export const ExplorerContainer: ComponentType<any> = lazy(() => import('./ExplorerContainer'));
package/src/meta.ts CHANGED
@@ -3,12 +3,17 @@
3
3
  //
4
4
 
5
5
  import { type PluginMeta } from '@dxos/app-framework';
6
+ import { trim } from '@dxos/util';
6
7
 
7
8
  export const meta: PluginMeta = {
8
9
  id: 'dxos.org/plugin/explorer',
9
10
  name: 'Explorer',
10
- description: 'Install this plugin to view a hypergraph of all objects inside of your Space.',
11
+ description: trim`
12
+ Interactive hypergraph visualization that reveals relationships between objects in your workspace.
13
+ Navigate complex data structures and discover connections through a dynamic network view.
14
+ `,
11
15
  icon: 'ph--graph--regular',
16
+ iconHue: 'green',
12
17
  source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-explorer',
13
18
  tags: ['labs'],
14
19
  screenshots: ['https://dxos.network/plugin-details-explorer-dark.png'],
@@ -2,16 +2,17 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
+ import { Type } from '@dxos/echo';
5
6
  import { type Resource } from '@dxos/react-ui';
6
7
  import { translations as componentsTranslations } from '@dxos/react-ui-components';
7
8
 
8
9
  import { meta } from './meta';
9
- import { ViewType } from './types';
10
+ import { Graph } from './types';
10
11
 
11
12
  export const translations = [
12
13
  {
13
14
  'en-US': {
14
- [ViewType.typename]: {
15
+ [Type.getTypename(Graph.Graph)]: {
15
16
  'typename label': 'Explorer',
16
17
  'typename label_zero': 'Explorers',
17
18
  'typename label_one': 'Explorer',
@@ -19,6 +20,7 @@ export const translations = [
19
20
  'object name placeholder': 'New explorer',
20
21
  'rename object label': 'Rename explorer',
21
22
  'delete object label': 'Delete explorer',
23
+ 'object deleted label': 'Explorer deleted',
22
24
  },
23
25
  [meta.id]: {
24
26
  'plugin name': 'Explorer',
@@ -0,0 +1,37 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import * as Schema from 'effect/Schema';
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`;
15
+
16
+ export const GraphProps = Schema.Struct({
17
+ name: Schema.optional(Schema.String),
18
+ // TODO(wittjosiah): This should be a query input instead.
19
+ typename: Schema.String.pipe(
20
+ Schema.annotations({ title: 'Select type' }),
21
+ TypeInputOptionsAnnotation.set({
22
+ location: ['database', 'runtime'],
23
+ kind: ['user'],
24
+ registered: ['registered'],
25
+ }),
26
+ Schema.optional,
27
+ ),
28
+ });
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
+ }) {}
@@ -0,0 +1,63 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import * as Schema from 'effect/Schema';
6
+
7
+ import { Filter, Obj, Query, QueryAST, Ref, Type } from '@dxos/echo';
8
+ import { FormInputAnnotation, LabelAnnotation } from '@dxos/echo/internal';
9
+ import { View, ViewAnnotation } from '@dxos/schema';
10
+
11
+ const GraphSchema = Schema.Struct({
12
+ name: Schema.optional(Schema.String),
13
+
14
+ view: Type.Ref(View.View).pipe(FormInputAnnotation.set(false)),
15
+
16
+ query: Schema.Struct({
17
+ raw: Schema.optional(Schema.String),
18
+ ast: QueryAST.Query,
19
+ }).pipe(Schema.mutable, FormInputAnnotation.set(false)),
20
+ }).pipe(
21
+ Type.Obj({
22
+ typename: 'dxos.org/type/Graph',
23
+ version: '0.2.0',
24
+ }),
25
+ LabelAnnotation.set(['name']),
26
+ ViewAnnotation.set(true),
27
+ );
28
+ 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;
31
+
32
+ type MakeProps = Omit<Partial<Obj.MakeProps<typeof Graph>>, 'view'> & {
33
+ view: View.View;
34
+ };
35
+
36
+ /**
37
+ * Make a graph as a view of a data set.
38
+ */
39
+ export const make = ({
40
+ name,
41
+ query = { raw: '', ast: Query.select(Filter.nothing()).ast },
42
+ view,
43
+ }: MakeProps): Graph => {
44
+ return Obj.make(Graph, { name, view: Ref.make(view), query });
45
+ };
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
+ );
@@ -2,5 +2,5 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- export * from './schema';
6
- export * from './types';
5
+ export * as ExplorerAction from './ExplorerAction';
6
+ export * as Graph from './Graph';
@@ -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';\n\nimport { useGraphModel } from '../hooks';\nimport { type ViewType } from '../types';\n\nimport { D3ForceGraph } from './Graph';\n\ntype ExplorerContainerProps = {\n role: string;\n view: ViewType;\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));\n }, []);\n\n if (!space || !model) {\n return null;\n }\n\n return (\n <StackItem.Content toolbar size={role === 'section' ? 'square' : 'intrinsic'}>\n <Toolbar.Root>\n <QueryEditor space={space} onChange={handleChange} />\n </Toolbar.Root>\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,CAAAA;IAC1B,GAAG,CAAA,CAAE;AAEL,QAAI,CAACd,SAAS,CAACK,OAAO;AACpB,aAAO;IACT;AAEA,WACE,sBAAA,cAACW,UAAUC,SAAO;MAACC,SAAAA;MAAQC,MAAMrB,SAAS,YAAY,WAAW;OAC/D,sBAAA,cAACsB,QAAQC,MAAI,MACX,sBAAA,cAACC,aAAAA;MAAYtB;MAAcuB,UAAUX;SAEvC,sBAAA,cAACY,cAAAA;MAAanB;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", "StackItem", "Content", "toolbar", "size", "Toolbar", "Root", "QueryEditor", "onChange", "D3ForceGraph"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/meta.ts"],
4
- "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { type PluginMeta } from '@dxos/app-framework';\n\nexport const meta: PluginMeta = {\n id: 'dxos.org/plugin/explorer',\n name: 'Explorer',\n description: 'Install this plugin to view a hypergraph of all objects inside of your Space.',\n icon: 'ph--graph--regular',\n source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-explorer',\n tags: ['labs'],\n screenshots: ['https://dxos.network/plugin-details-explorer-dark.png'],\n};\n"],
5
- "mappings": ";AAMO,IAAMA,OAAmB;EAC9BC,IAAI;EACJC,MAAM;EACNC,aAAa;EACbC,MAAM;EACNC,QAAQ;EACRC,MAAM;IAAC;;EACPC,aAAa;IAAC;;AAChB;",
6
- "names": ["meta", "id", "name", "description", "icon", "source", "tags", "screenshots"]
7
- }