@dxos/plugin-explorer 0.8.2-main.f11618f → 0.8.2-staging.42af850

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 (161) hide show
  1. package/dist/lib/browser/ExplorerContainer-BBZ54DJS.mjs +37 -0
  2. package/dist/lib/browser/ExplorerContainer-BBZ54DJS.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-RRXH3JYB.mjs → chunk-73GQ46YO.mjs} +415 -155
  4. package/dist/lib/{node-esm/chunk-VNMYGDGZ.mjs.map → browser/chunk-73GQ46YO.mjs.map} +4 -4
  5. package/dist/lib/browser/{chunk-QLQLPZNI.mjs → chunk-73YTQHOT.mjs} +12 -11
  6. package/dist/lib/browser/chunk-73YTQHOT.mjs.map +7 -0
  7. package/dist/lib/browser/chunk-M2BGAY6H.mjs +177 -0
  8. package/dist/lib/browser/chunk-M2BGAY6H.mjs.map +7 -0
  9. package/dist/lib/browser/{chunk-Z2SDLMQM.mjs → chunk-OBAFAA5V.mjs} +3 -3
  10. package/dist/lib/browser/{chunk-Z2SDLMQM.mjs.map → chunk-OBAFAA5V.mjs.map} +1 -1
  11. package/dist/lib/browser/chunk-SLB2F5AO.mjs +30 -0
  12. package/dist/lib/browser/chunk-SLB2F5AO.mjs.map +7 -0
  13. package/dist/lib/browser/index.mjs +15 -11
  14. package/dist/lib/browser/index.mjs.map +1 -1
  15. package/dist/lib/browser/{intent-resolver-P4YLQHXF.mjs → intent-resolver-FJDVBDE3.mjs} +3 -3
  16. package/dist/lib/browser/meta.json +1 -1
  17. package/dist/lib/browser/meta.mjs +1 -1
  18. package/dist/lib/browser/{react-surface-TPR4VUPE.mjs → react-surface-H3YDMXAQ.mjs} +5 -5
  19. package/dist/lib/browser/types/index.mjs +2 -2
  20. package/dist/lib/node/{ExplorerContainer-73AHSBAG.cjs → ExplorerContainer-MVP2AM7R.cjs} +24 -16
  21. package/dist/lib/node/ExplorerContainer-MVP2AM7R.cjs.map +7 -0
  22. package/dist/lib/node/chunk-4T4LCT5R.cjs +52 -0
  23. package/dist/lib/node/chunk-4T4LCT5R.cjs.map +7 -0
  24. package/dist/lib/node/{chunk-4QUNUHKB.cjs → chunk-72H5HBTK.cjs} +414 -153
  25. package/dist/lib/node/{chunk-4QUNUHKB.cjs.map → chunk-72H5HBTK.cjs.map} +4 -4
  26. package/dist/lib/node/{chunk-VB3QE6XY.cjs → chunk-BCDVG2CH.cjs} +6 -6
  27. package/dist/lib/node/{chunk-VB3QE6XY.cjs.map → chunk-BCDVG2CH.cjs.map} +1 -1
  28. package/dist/lib/node/{chunk-YLL7H7CZ.cjs → chunk-MLRYW4WQ.cjs} +15 -14
  29. package/dist/lib/node/chunk-MLRYW4WQ.cjs.map +7 -0
  30. package/dist/lib/node/chunk-NELWWGBU.cjs +204 -0
  31. package/dist/lib/node/chunk-NELWWGBU.cjs.map +7 -0
  32. package/dist/lib/node/index.cjs +34 -31
  33. package/dist/lib/node/index.cjs.map +1 -1
  34. package/dist/lib/node/{intent-resolver-T2R4PJVP.cjs → intent-resolver-DRT67ZU4.cjs} +8 -8
  35. package/dist/lib/node/meta.cjs +3 -3
  36. package/dist/lib/node/meta.cjs.map +1 -1
  37. package/dist/lib/node/meta.json +1 -1
  38. package/dist/lib/node/{react-surface-OLIOGYOK.cjs → react-surface-6ESLSM33.cjs} +11 -11
  39. package/dist/lib/node/types/index.cjs +4 -4
  40. package/dist/lib/node/types/index.cjs.map +1 -1
  41. package/dist/lib/node-esm/ExplorerContainer-APGUQI4M.mjs +38 -0
  42. package/dist/lib/node-esm/ExplorerContainer-APGUQI4M.mjs.map +7 -0
  43. package/dist/lib/node-esm/{chunk-VNMYGDGZ.mjs → chunk-34X2VFQN.mjs} +415 -154
  44. package/dist/lib/{browser/chunk-RRXH3JYB.mjs.map → node-esm/chunk-34X2VFQN.mjs.map} +4 -4
  45. package/dist/lib/node-esm/{chunk-PUFSCMN4.mjs → chunk-3CMBLK6W.mjs} +3 -3
  46. package/dist/lib/node-esm/{chunk-PUFSCMN4.mjs.map → chunk-3CMBLK6W.mjs.map} +1 -1
  47. package/dist/lib/node-esm/{chunk-QZH2GDN5.mjs → chunk-N6VEANUZ.mjs} +12 -11
  48. package/dist/lib/node-esm/chunk-N6VEANUZ.mjs.map +7 -0
  49. package/dist/lib/node-esm/chunk-PVII2K2B.mjs +179 -0
  50. package/dist/lib/node-esm/chunk-PVII2K2B.mjs.map +7 -0
  51. package/dist/lib/node-esm/chunk-VSORIAHH.mjs +32 -0
  52. package/dist/lib/node-esm/chunk-VSORIAHH.mjs.map +7 -0
  53. package/dist/lib/node-esm/index.mjs +15 -11
  54. package/dist/lib/node-esm/index.mjs.map +1 -1
  55. package/dist/lib/node-esm/{intent-resolver-OMUHLTGU.mjs → intent-resolver-4RBV644N.mjs} +3 -3
  56. package/dist/lib/node-esm/meta.json +1 -1
  57. package/dist/lib/node-esm/meta.mjs +1 -1
  58. package/dist/lib/node-esm/{react-surface-QLB55AWT.mjs → react-surface-ZEVL3FXG.mjs} +5 -5
  59. package/dist/lib/node-esm/types/index.mjs +2 -2
  60. package/dist/types/src/components/Chart/Chart.d.ts.map +1 -1
  61. package/dist/types/src/components/ExplorerContainer.d.ts +4 -3
  62. package/dist/types/src/components/ExplorerContainer.d.ts.map +1 -1
  63. package/dist/types/src/components/Globe/Globe.d.ts.map +1 -1
  64. package/dist/types/src/components/Graph/D3ForceGraph.d.ts +14 -0
  65. package/dist/types/src/components/Graph/D3ForceGraph.d.ts.map +1 -0
  66. package/dist/types/src/components/Graph/D3ForceGraph.stories.d.ts +6 -0
  67. package/dist/types/src/components/Graph/D3ForceGraph.stories.d.ts.map +1 -0
  68. package/dist/types/src/components/Graph/ForceGraph.d.ts +8 -0
  69. package/dist/types/src/components/Graph/ForceGraph.d.ts.map +1 -0
  70. package/dist/types/src/components/Graph/{Graph.stories.d.ts → ForceGraph.stories.d.ts} +1 -1
  71. package/dist/types/src/components/Graph/ForceGraph.stories.d.ts.map +1 -0
  72. package/dist/types/src/components/Graph/adapter.d.ts +21 -0
  73. package/dist/types/src/components/Graph/adapter.d.ts.map +1 -0
  74. package/dist/types/src/components/Graph/index.d.ts +2 -2
  75. package/dist/types/src/components/Graph/index.d.ts.map +1 -1
  76. package/dist/types/src/components/Graph/testing.d.ts +14 -0
  77. package/dist/types/src/components/Graph/testing.d.ts.map +1 -0
  78. package/dist/types/src/components/Tree/Tree.d.ts.map +1 -1
  79. package/dist/types/src/components/Tree/layout/HierarchicalEdgeBundling.d.ts.map +1 -1
  80. package/dist/types/src/components/Tree/layout/RadialTree.d.ts.map +1 -1
  81. package/dist/types/src/components/Tree/layout/TidyTree.d.ts.map +1 -1
  82. package/dist/types/src/components/Tree/testing/generator.d.ts +8 -0
  83. package/dist/types/src/components/Tree/testing/generator.d.ts.map +1 -0
  84. package/dist/types/src/components/Tree/testing/index.d.ts +2 -0
  85. package/dist/types/src/components/Tree/testing/index.d.ts.map +1 -0
  86. package/dist/types/src/components/Tree/types/index.d.ts +3 -0
  87. package/dist/types/src/components/Tree/types/index.d.ts.map +1 -0
  88. package/dist/types/src/components/Tree/types/tree.d.ts +83 -0
  89. package/dist/types/src/components/Tree/types/tree.d.ts.map +1 -0
  90. package/dist/types/src/components/Tree/types/tree.test.d.ts +2 -0
  91. package/dist/types/src/components/Tree/types/tree.test.d.ts.map +1 -0
  92. package/dist/types/src/components/Tree/types/types.d.ts +8 -0
  93. package/dist/types/src/components/Tree/types/types.d.ts.map +1 -0
  94. package/dist/types/src/components/index.d.ts +2 -2
  95. package/dist/types/src/components/plot.d.ts.map +1 -1
  96. package/dist/types/src/hooks/index.d.ts +2 -0
  97. package/dist/types/src/hooks/index.d.ts.map +1 -0
  98. package/dist/types/src/hooks/useGraphModel.d.ts +4 -0
  99. package/dist/types/src/hooks/useGraphModel.d.ts.map +1 -0
  100. package/dist/types/src/index.d.ts +2 -1
  101. package/dist/types/src/index.d.ts.map +1 -1
  102. package/dist/types/src/translations.d.ts +2 -8
  103. package/dist/types/src/translations.d.ts.map +1 -1
  104. package/dist/types/src/types/schema.d.ts +6 -6
  105. package/dist/types/src/types/schema.d.ts.map +1 -1
  106. package/dist/types/src/types/types.d.ts +6 -6
  107. package/dist/types/src/types/types.d.ts.map +1 -1
  108. package/dist/types/tsconfig.tsbuildinfo +1 -1
  109. package/package.json +30 -27
  110. package/src/components/ExplorerContainer.tsx +11 -4
  111. package/src/components/Graph/D3ForceGraph.stories.tsx +64 -0
  112. package/src/components/Graph/D3ForceGraph.tsx +101 -0
  113. package/src/components/Graph/ForceGraph.stories.tsx +64 -0
  114. package/src/components/Graph/{Graph.tsx → ForceGraph.tsx} +19 -26
  115. package/src/components/Graph/adapter.ts +47 -0
  116. package/src/components/Graph/index.ts +2 -3
  117. package/src/components/Graph/testing.ts +57 -0
  118. package/src/components/Tree/Tree.stories.tsx +1 -1
  119. package/src/components/Tree/Tree.tsx +11 -18
  120. package/src/components/Tree/testing/generator.ts +46 -0
  121. package/src/components/Tree/testing/index.ts +5 -0
  122. package/src/components/Tree/types/index.ts +6 -0
  123. package/src/components/Tree/types/tree.test.ts +133 -0
  124. package/src/components/Tree/types/tree.ts +287 -0
  125. package/src/components/Tree/types/types.ts +41 -0
  126. package/src/hooks/index.ts +5 -0
  127. package/src/hooks/useGraphModel.ts +35 -0
  128. package/src/index.ts +2 -2
  129. package/src/meta.ts +2 -2
  130. package/src/types/schema.ts +5 -3
  131. package/src/types/types.ts +5 -5
  132. package/dist/lib/browser/ExplorerContainer-HL532ODG.mjs +0 -27
  133. package/dist/lib/browser/ExplorerContainer-HL532ODG.mjs.map +0 -7
  134. package/dist/lib/browser/chunk-QLQLPZNI.mjs.map +0 -7
  135. package/dist/lib/browser/chunk-SBLNE7FL.mjs +0 -205
  136. package/dist/lib/browser/chunk-SBLNE7FL.mjs.map +0 -7
  137. package/dist/lib/node/ExplorerContainer-73AHSBAG.cjs.map +0 -7
  138. package/dist/lib/node/chunk-OIHH6TVE.cjs +0 -236
  139. package/dist/lib/node/chunk-OIHH6TVE.cjs.map +0 -7
  140. package/dist/lib/node/chunk-YLL7H7CZ.cjs.map +0 -7
  141. package/dist/lib/node-esm/ExplorerContainer-NMI55PYM.mjs +0 -28
  142. package/dist/lib/node-esm/ExplorerContainer-NMI55PYM.mjs.map +0 -7
  143. package/dist/lib/node-esm/chunk-QZH2GDN5.mjs.map +0 -7
  144. package/dist/lib/node-esm/chunk-SZRRNWYT.mjs +0 -207
  145. package/dist/lib/node-esm/chunk-SZRRNWYT.mjs.map +0 -7
  146. package/dist/types/src/components/Graph/Graph.d.ts +0 -8
  147. package/dist/types/src/components/Graph/Graph.d.ts.map +0 -1
  148. package/dist/types/src/components/Graph/Graph.stories.d.ts.map +0 -1
  149. package/dist/types/src/components/Graph/graph-model.d.ts +0 -39
  150. package/dist/types/src/components/Graph/graph-model.d.ts.map +0 -1
  151. package/dist/types/src/components/Tree/types.d.ts +0 -8
  152. package/dist/types/src/components/Tree/types.d.ts.map +0 -1
  153. package/src/components/Graph/Graph.stories.tsx +0 -62
  154. package/src/components/Graph/graph-model.ts +0 -193
  155. package/src/components/Tree/types.ts +0 -40
  156. /package/dist/lib/browser/{intent-resolver-P4YLQHXF.mjs.map → intent-resolver-FJDVBDE3.mjs.map} +0 -0
  157. /package/dist/lib/browser/{react-surface-TPR4VUPE.mjs.map → react-surface-H3YDMXAQ.mjs.map} +0 -0
  158. /package/dist/lib/node/{intent-resolver-T2R4PJVP.cjs.map → intent-resolver-DRT67ZU4.cjs.map} +0 -0
  159. /package/dist/lib/node/{react-surface-OLIOGYOK.cjs.map → react-surface-6ESLSM33.cjs.map} +0 -0
  160. /package/dist/lib/node-esm/{intent-resolver-OMUHLTGU.mjs.map → intent-resolver-4RBV644N.mjs.map} +0 -0
  161. /package/dist/lib/node-esm/{react-surface-QLB55AWT.mjs.map → react-surface-ZEVL3FXG.mjs.map} +0 -0
@@ -1,15 +1,9 @@
1
+ import { ViewType } from './types';
1
2
  declare const _default: {
2
3
  'en-US': {
3
- [x: string]: {
4
+ [ViewType.typename]: {
4
5
  'typename label': string;
5
6
  'object name placeholder': string;
6
- 'plugin name'?: undefined;
7
- 'object title label'?: undefined;
8
- } | {
9
- 'plugin name': string;
10
- 'object title label': string;
11
- 'typename label'?: undefined;
12
- 'object name placeholder'?: undefined;
13
7
  };
14
8
  "dxos.org/plugin/explorer": {
15
9
  'plugin name': string;
@@ -1 +1 @@
1
- {"version":3,"file":"translations.d.ts","sourceRoot":"","sources":["../../../src/translations.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAOA,wBAaE"}
1
+ {"version":3,"file":"translations.d.ts","sourceRoot":"","sources":["../../../src/translations.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;;;QAK7B,CAAC,QAAQ,CAAC,QAAQ,CAAC;;;UAGlB;;;;;;;AANP,wBAaE"}
@@ -1,10 +1,10 @@
1
- import { S } from '@dxos/echo-schema';
1
+ import { Schema } from 'effect';
2
2
  declare const ViewType_base: import("@dxos/echo-schema").TypedObjectPrototype<import("@dxos/echo-schema").TypedObjectFields<{
3
- name: S.optional<typeof S.String>;
4
- type: typeof S.String;
5
- }, import("@dxos/echo-schema").TypedObjectOptions>, S.Struct.Encoded<{
6
- name: S.optional<typeof S.String>;
7
- type: typeof S.String;
3
+ name: Schema.optional<typeof Schema.String>;
4
+ type: typeof Schema.String;
5
+ }, import("@dxos/echo-schema").TypedObjectOptions>, Schema.Struct.Encoded<{
6
+ name: Schema.optional<typeof Schema.String>;
7
+ type: typeof Schema.String;
8
8
  }>>;
9
9
  export declare class ViewType extends ViewType_base {
10
10
  }
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../../src/types/schema.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAe,MAAM,mBAAmB,CAAC;;;;;;;;AAGnD,qBAAa,QAAS,SAAQ,aAM5B;CAAG"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../../src/types/schema.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;;;;;;;;AAKhC,qBAAa,QAAS,SAAQ,aAM5B;CAAG"}
@@ -1,13 +1,13 @@
1
- import { S } from '@dxos/echo-schema';
1
+ import { Schema } from 'effect';
2
2
  import { ViewType } from './schema';
3
3
  export declare namespace ExplorerAction {
4
- const Create_base: S.TaggedClass<Create, "dxos.org/plugin/explorer/action/create", {
5
- readonly _tag: S.tag<"dxos.org/plugin/explorer/action/create">;
4
+ const Create_base: Schema.TaggedClass<Create, "dxos.org/plugin/explorer/action/create", {
5
+ readonly _tag: Schema.tag<"dxos.org/plugin/explorer/action/create">;
6
6
  } & {
7
- input: S.Struct<{
8
- name: S.optional<typeof S.String>;
7
+ input: Schema.Struct<{
8
+ name: Schema.optional<typeof Schema.String>;
9
9
  }>;
10
- output: S.Struct<{
10
+ output: Schema.Struct<{
11
11
  object: typeof ViewType;
12
12
  }>;
13
13
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/types/types.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAEtC,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAGpC,yBAAiB,cAAc,CAAC;;;;;;;;;;;IAG9B,MAAM,OAAO,MAAO,SAAQ,WAO1B;KAAG;;CACN"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/types/types.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAGpC,yBAAiB,cAAc,CAAC;;;;;;;;;;;IAG9B,MAAM,OAAO,MAAO,SAAQ,WAO1B;KAAG;;CACN"}
@@ -1 +1 @@
1
- {"version":"5.7.3"}
1
+ {"version":"5.8.3"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/plugin-explorer",
3
- "version": "0.8.2-main.f11618f",
3
+ "version": "0.8.2-staging.42af850",
4
4
  "description": "Braneframe data visualization plugin",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -35,28 +35,32 @@
35
35
  "dependencies": {
36
36
  "3d-force-graph": "^1.76.1",
37
37
  "@observablehq/plot": "^0.6.11",
38
- "@preact/signals-core": "^1.6.0",
38
+ "@preact-signals/safe-react": "^0.9.0",
39
+ "@preact/signals-core": "^1.9.0",
39
40
  "d3": "^7.9.0",
41
+ "effect": "^3.13.3",
40
42
  "force-graph": "^1.49.4",
41
43
  "lodash.defaultsdeep": "^4.6.1",
42
- "lodash.get": "^4.4.2",
43
44
  "react-resize-detector": "^11.0.1",
44
45
  "topojson-client": "^3.1.0",
45
- "@dxos/app-framework": "0.8.2-main.f11618f",
46
- "@dxos/async": "0.8.2-main.f11618f",
47
- "@dxos/client": "0.8.2-main.f11618f",
48
- "@dxos/echo-schema": "0.8.2-main.f11618f",
49
- "@dxos/gem-core": "0.8.2-main.f11618f",
50
- "@dxos/gem-spore": "0.8.2-main.f11618f",
51
- "@dxos/live-object": "0.8.2-main.f11618f",
52
- "@dxos/log": "0.8.2-main.f11618f",
53
- "@dxos/plugin-client": "0.8.2-main.f11618f",
54
- "@dxos/plugin-graph": "0.8.2-main.f11618f",
55
- "@dxos/plugin-search": "0.8.2-main.f11618f",
56
- "@dxos/plugin-space": "0.8.2-main.f11618f",
57
- "@dxos/react-client": "0.8.2-main.f11618f",
58
- "@dxos/react-ui-stack": "0.8.2-main.f11618f",
59
- "@dxos/util": "0.8.2-main.f11618f"
46
+ "@dxos/app-framework": "0.8.2-staging.42af850",
47
+ "@dxos/async": "0.8.2-staging.42af850",
48
+ "@dxos/client": "0.8.2-staging.42af850",
49
+ "@dxos/echo": "0.8.2-staging.42af850",
50
+ "@dxos/echo-schema": "0.8.2-staging.42af850",
51
+ "@dxos/invariant": "0.8.2-staging.42af850",
52
+ "@dxos/graph": "0.8.2-staging.42af850",
53
+ "@dxos/log": "0.8.2-staging.42af850",
54
+ "@dxos/live-object": "0.8.2-staging.42af850",
55
+ "@dxos/plugin-client": "0.8.2-staging.42af850",
56
+ "@dxos/plugin-graph": "0.8.2-staging.42af850",
57
+ "@dxos/plugin-space": "0.8.2-staging.42af850",
58
+ "@dxos/plugin-search": "0.8.2-staging.42af850",
59
+ "@dxos/react-ui-graph": "0.8.2-staging.42af850",
60
+ "@dxos/react-client": "0.8.2-staging.42af850",
61
+ "@dxos/react-ui-stack": "0.8.2-staging.42af850",
62
+ "@dxos/schema": "0.8.2-staging.42af850",
63
+ "@dxos/util": "0.8.2-staging.42af850"
60
64
  },
61
65
  "devDependencies": {
62
66
  "@phosphor-icons/react": "^2.1.5",
@@ -67,23 +71,22 @@
67
71
  "@types/react-dom": "~18.2.0",
68
72
  "@types/topojson-client": "^3.1.4",
69
73
  "@types/topojson-specification": "^1.0.5",
70
- "lodash.get": "^4.4.2",
71
74
  "react": "~18.2.0",
72
75
  "react-dom": "~18.2.0",
73
76
  "vite": "5.4.7",
74
- "@dxos/echo-generator": "0.8.2-main.f11618f",
75
- "@dxos/plugin-outliner": "0.8.2-main.f11618f",
76
- "@dxos/random": "0.8.2-main.f11618f",
77
- "@dxos/react-ui": "0.8.2-main.f11618f",
78
- "@dxos/react-ui-theme": "0.8.2-main.f11618f",
79
- "@dxos/storybook-utils": "0.8.2-main.f11618f"
77
+ "@dxos/react-ui-theme": "0.8.2-staging.42af850",
78
+ "@dxos/random": "0.8.2-staging.42af850",
79
+ "@dxos/storybook-utils": "0.8.2-staging.42af850",
80
+ "@dxos/react-ui": "0.8.2-staging.42af850",
81
+ "@dxos/echo-generator": "0.8.2-staging.42af850"
80
82
  },
81
83
  "peerDependencies": {
82
84
  "@phosphor-icons/react": "^2.1.5",
85
+ "effect": "^3.13.3",
83
86
  "react": "~18.2.0",
84
87
  "react-dom": "~18.2.0",
85
- "@dxos/react-ui": "0.8.2-main.f11618f",
86
- "@dxos/react-ui-theme": "0.8.2-main.f11618f"
88
+ "@dxos/react-ui": "0.8.2-staging.42af850",
89
+ "@dxos/react-ui-theme": "0.8.2-staging.42af850"
87
90
  },
88
91
  "publishConfig": {
89
92
  "access": "public"
@@ -8,20 +8,27 @@ import { useGlobalSearch } from '@dxos/plugin-search';
8
8
  import { getSpace } from '@dxos/react-client/echo';
9
9
  import { StackItem } from '@dxos/react-ui-stack';
10
10
 
11
- import { Graph } from './Graph';
11
+ import { ForceGraph } from './Graph';
12
+ import { useGraphModel } from '../hooks';
12
13
  import { type ViewType } from '../types';
13
14
 
14
- const ExplorerContainer = ({ view, role }: { view: ViewType; role: string }) => {
15
+ type ExplorerContainerProps = {
16
+ role: string;
17
+ view: ViewType;
18
+ };
19
+
20
+ const ExplorerContainer = ({ role, view }: ExplorerContainerProps) => {
15
21
  const space = getSpace(view);
16
22
  const { match } = useGlobalSearch();
23
+ const model = useGraphModel(space);
17
24
 
18
- if (!space) {
25
+ if (!model || !space) {
19
26
  return null;
20
27
  }
21
28
 
22
29
  return (
23
30
  <StackItem.Content size={role === 'section' ? 'square' : 'intrinsic'}>
24
- <Graph space={space} match={match} />
31
+ <ForceGraph model={model} match={match} />
25
32
  </StackItem.Content>
26
33
  );
27
34
  };
@@ -0,0 +1,64 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import '@dxos-theme';
6
+
7
+ import { type Meta } from '@storybook/react';
8
+ import React, { useEffect, useState } from 'react';
9
+
10
+ import { faker } from '@dxos/random';
11
+ import { useClient } from '@dxos/react-client';
12
+ import { live } from '@dxos/react-client/echo';
13
+ import { type Space } from '@dxos/react-client/echo';
14
+ import { withClientProvider } from '@dxos/react-client/testing';
15
+ import { DataType } from '@dxos/schema';
16
+ import { type ValueGenerator } from '@dxos/schema/testing';
17
+ import { withLayout, withTheme, render } from '@dxos/storybook-utils';
18
+
19
+ import { D3ForceGraph } from './D3ForceGraph';
20
+ import { generate } from './testing';
21
+ import { useGraphModel } from '../../hooks';
22
+ import { ViewType } from '../../types';
23
+
24
+ const generator = faker as any as ValueGenerator;
25
+
26
+ faker.seed(1);
27
+
28
+ const DefaultStory = () => {
29
+ const client = useClient();
30
+ const [space, setSpace] = useState<Space>();
31
+ const [view, setView] = useState<ViewType>();
32
+ useEffect(() => {
33
+ const space = client.spaces.default;
34
+ void generate(space, generator);
35
+ const view = space.db.add(live(ViewType, { name: '', type: '' }));
36
+ setSpace(space);
37
+ setView(view);
38
+ }, []);
39
+
40
+ const model = useGraphModel(space);
41
+ if (!model || !space || !view) {
42
+ return null;
43
+ }
44
+
45
+ return <D3ForceGraph model={model} />;
46
+ };
47
+
48
+ const meta: Meta = {
49
+ title: 'plugins/plugin-explorer/D3ForceGraph',
50
+ component: D3ForceGraph,
51
+ render: render(DefaultStory),
52
+ decorators: [
53
+ withClientProvider({
54
+ createSpace: true,
55
+ types: [ViewType, DataType.Organization, DataType.Project, DataType.Person, DataType.HasRelationship],
56
+ }),
57
+ withTheme,
58
+ withLayout({ fullscreen: true }),
59
+ ],
60
+ };
61
+
62
+ export default meta;
63
+
64
+ export const Default = {};
@@ -0,0 +1,101 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import React, { type FC, useCallback, useEffect, useMemo, useRef } from 'react';
6
+
7
+ import { getTypename } from '@dxos/echo-schema';
8
+ import { SelectionModel } from '@dxos/graph';
9
+ import { type ThemedClassName } from '@dxos/react-ui';
10
+ import {
11
+ type GraphController,
12
+ GraphForceProjector,
13
+ type GraphLayoutNode,
14
+ type GraphProps,
15
+ SVG,
16
+ type SVGContext,
17
+ } from '@dxos/react-ui-graph';
18
+ import { getHashColor } from '@dxos/react-ui-theme';
19
+ import { type SpaceGraphNode, type SpaceGraphModel, type SpaceGraphEdge } from '@dxos/schema';
20
+
21
+ import '@dxos/react-ui-graph/styles/graph.css';
22
+
23
+ export type D3ForceGraphProps = ThemedClassName<
24
+ {
25
+ model?: SpaceGraphModel;
26
+ match?: RegExp;
27
+ selection?: SelectionModel;
28
+ grid?: boolean;
29
+ } & Pick<GraphProps, 'drag'>
30
+ >;
31
+
32
+ export const D3ForceGraph: FC<D3ForceGraphProps> = ({ classNames, model, selection: _selection, grid, ...props }) => {
33
+ const context = useRef<SVGContext>(null);
34
+ const projector = useMemo<GraphForceProjector | undefined>(() => {
35
+ if (context.current) {
36
+ return new GraphForceProjector(context.current, {
37
+ attributes: {
38
+ linkForce: (edge) => {
39
+ // TODO(burdon): Check type (currently assumes Employee property).
40
+ // Edge shouldn't contribute to force if it's not active.
41
+ return edge.data?.object?.active !== false;
42
+ },
43
+ },
44
+ forces: {
45
+ point: {
46
+ strength: 0.01,
47
+ },
48
+ },
49
+ });
50
+ }
51
+ }, [context.current]);
52
+
53
+ const graph = useRef<GraphController>(null);
54
+ const selection = useMemo(() => _selection ?? new SelectionModel(), [_selection]);
55
+ useEffect(() => graph.current?.repaint(), [selection.selected.value]);
56
+
57
+ const handleSelect = useCallback<NonNullable<GraphProps['onSelect']>>(
58
+ (node) => {
59
+ if (selection.contains(node.id)) {
60
+ selection.remove(node.id);
61
+ } else {
62
+ selection.add(node.id);
63
+ }
64
+ },
65
+ [selection],
66
+ );
67
+
68
+ return (
69
+ <SVG.Root ref={context} classNames={classNames}>
70
+ <SVG.Markers />
71
+ {grid && <SVG.Grid axis />}
72
+ <SVG.Zoom extent={[1 / 2, 2]}>
73
+ <SVG.Graph<SpaceGraphNode, SpaceGraphEdge>
74
+ {...props}
75
+ ref={graph}
76
+ model={model}
77
+ projector={projector}
78
+ labels={{
79
+ text: (node) => {
80
+ return node.data?.data.label ?? node.id;
81
+ },
82
+ }}
83
+ attributes={{
84
+ node: (node: GraphLayoutNode<SpaceGraphNode>) => {
85
+ const obj = node.data?.data.object;
86
+ return {
87
+ data: {
88
+ color: getHashColor(obj && getTypename(obj))?.color,
89
+ },
90
+ classes: {
91
+ 'dx-selected': selection.contains(node.id),
92
+ },
93
+ };
94
+ },
95
+ }}
96
+ onSelect={handleSelect}
97
+ />
98
+ </SVG.Zoom>
99
+ </SVG.Root>
100
+ );
101
+ };
@@ -0,0 +1,64 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import '@dxos-theme';
6
+
7
+ import { type Meta } from '@storybook/react';
8
+ import React, { useEffect, useState } from 'react';
9
+
10
+ import { faker } from '@dxos/random';
11
+ import { useClient } from '@dxos/react-client';
12
+ import { live } from '@dxos/react-client/echo';
13
+ import { type Space } from '@dxos/react-client/echo';
14
+ import { withClientProvider } from '@dxos/react-client/testing';
15
+ import { DataType } from '@dxos/schema';
16
+ import { type ValueGenerator } from '@dxos/schema/testing';
17
+ import { withLayout, withTheme, render } from '@dxos/storybook-utils';
18
+
19
+ import { ForceGraph } from './ForceGraph';
20
+ import { generate } from './testing';
21
+ import { useGraphModel } from '../../hooks';
22
+ import { ViewType } from '../../types';
23
+
24
+ const generator = faker as any as ValueGenerator;
25
+
26
+ faker.seed(1);
27
+
28
+ const DefaultStory = () => {
29
+ const client = useClient();
30
+ const [space, setSpace] = useState<Space>();
31
+ const [view, setView] = useState<ViewType>();
32
+ useEffect(() => {
33
+ const space = client.spaces.default;
34
+ void generate(space, generator);
35
+ const view = space.db.add(live(ViewType, { name: '', type: '' }));
36
+ setSpace(space);
37
+ setView(view);
38
+ }, []);
39
+
40
+ const model = useGraphModel(space);
41
+ if (!model || !space || !view) {
42
+ return null;
43
+ }
44
+
45
+ return <ForceGraph model={model} />;
46
+ };
47
+
48
+ const meta: Meta = {
49
+ title: 'plugins/plugin-explorer/ForceGraph',
50
+ component: ForceGraph,
51
+ render: render(DefaultStory),
52
+ decorators: [
53
+ withClientProvider({
54
+ createSpace: true,
55
+ types: [ViewType, DataType.HasRelationship, DataType.Organization, DataType.Project, DataType.Person],
56
+ }),
57
+ withTheme,
58
+ withLayout({ fullscreen: true }),
59
+ ],
60
+ };
61
+
62
+ export default meta;
63
+
64
+ export const Default = {};
@@ -3,30 +3,24 @@
3
3
  //
4
4
 
5
5
  import { forceLink, forceManyBody } from 'd3';
6
- import ForceGraph from 'force-graph';
6
+ import NativeForceGraph from 'force-graph';
7
7
  import React, { type FC, useEffect, useRef } from 'react';
8
8
  import { useResizeDetector } from 'react-resize-detector';
9
9
 
10
- import { type Space } from '@dxos/client/echo';
11
10
  import { filterObjectsSync, type SearchResult } from '@dxos/plugin-search';
12
- import { useAsyncState } from '@dxos/react-ui';
11
+ import { type SpaceGraphModel } from '@dxos/schema';
13
12
 
14
- import { SpaceGraphModel } from './graph-model';
13
+ import { GraphAdapter } from './adapter';
15
14
 
16
- export type GraphProps = {
17
- space: Space;
15
+ export type ForceGraphProps = {
16
+ model?: SpaceGraphModel;
18
17
  match?: RegExp;
19
18
  };
20
19
 
21
- export const Graph: FC<GraphProps> = ({ space, match }) => {
20
+ export const ForceGraph: FC<ForceGraphProps> = ({ model, match }) => {
22
21
  const { ref, width, height } = useResizeDetector({ refreshRate: 200 });
23
22
  const rootRef = useRef<HTMLDivElement>(null);
24
- const forceGraph = useRef<ForceGraph>();
25
-
26
- const [model] = useAsyncState(
27
- async () => (space ? new SpaceGraphModel({ schema: true }).open(space) : undefined),
28
- [space],
29
- );
23
+ const forceGraph = useRef<NativeForceGraph>();
30
24
 
31
25
  const filteredRef = useRef<SearchResult[]>();
32
26
  filteredRef.current = filterObjectsSync(model?.objects ?? [], match);
@@ -35,17 +29,14 @@ export const Graph: FC<GraphProps> = ({ space, match }) => {
35
29
  if (rootRef.current) {
36
30
  // https://github.com/vasturiano/force-graph
37
31
  // https://github.com/vasturiano/3d-force-graph
38
- forceGraph.current = new ForceGraph(rootRef.current)
32
+ forceGraph.current = new NativeForceGraph(rootRef.current)
33
+ // https://github.com/vasturiano/force-graph?tab=readme-ov-file#node-styling
39
34
  .nodeRelSize(6)
40
- .nodeLabel((node: any) => {
41
- if (node.type === 'schema') {
42
- return node.data.typename;
43
- }
44
-
45
- return node.id;
46
- })
35
+ .nodeLabel((node: any) => (node.type === 'schema' ? node.data.typename : node.data.label ?? node.id))
47
36
  .nodeAutoColorBy((node: any) => (node.type === 'schema' ? 'schema' : node.data.typename))
48
- .linkColor(() => 'rgba(255,255,255,0.25)');
37
+
38
+ // https://github.com/vasturiano/force-graph?tab=readme-ov-file#link-styling
39
+ .linkAutoColorBy((link: any) => link.type);
49
40
  }
50
41
 
51
42
  return () => {
@@ -56,6 +47,7 @@ export const Graph: FC<GraphProps> = ({ space, match }) => {
56
47
 
57
48
  useEffect(() => {
58
49
  if (forceGraph.current && width && height && model) {
50
+ // https://github.com/vasturiano/force-graph?tab=readme-ov-file#container-layout
59
51
  forceGraph.current
60
52
  .pauseAnimation()
61
53
  .width(width)
@@ -63,17 +55,18 @@ export const Graph: FC<GraphProps> = ({ space, match }) => {
63
55
  .onEngineStop(() => {
64
56
  handleZoomToFit();
65
57
  })
58
+ .onNodeClick((node: any) => {
59
+ forceGraph.current?.emitParticle(node);
60
+ })
66
61
 
67
62
  // https://github.com/vasturiano/force-graph?tab=readme-ov-file#force-engine-d3-force-configuration
68
63
  // .d3Force('center', forceCenter().strength(0.9))
69
64
  .d3Force('link', forceLink().distance(160).strength(0.5))
70
65
  .d3Force('charge', forceManyBody().strength(-30))
71
- // .d3AlphaDecay(0.0228)
72
- // .d3VelocityDecay(0.4)
73
66
 
74
- .graphData(model.graph)
67
+ .graphData(new GraphAdapter(model))
75
68
  .warmupTicks(100)
76
- .cooldownTime(1000)
69
+ .cooldownTime(1_000)
77
70
  .resumeAnimation();
78
71
  }
79
72
  }, [model, width, height]);
@@ -0,0 +1,47 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { type Graph } from '@dxos/graph';
6
+
7
+ export type GraphNode = {
8
+ id?: string;
9
+ };
10
+
11
+ export type GraphLink = {
12
+ source?: string;
13
+ target?: string;
14
+ };
15
+
16
+ export type GraphData = {
17
+ nodes: GraphNode[];
18
+ links: GraphLink[];
19
+ };
20
+
21
+ export class GraphAdapter implements GraphData {
22
+ private readonly _nodes: GraphNode[] = [];
23
+ private readonly _links: GraphLink[] = [];
24
+
25
+ constructor(private readonly graph: Graph) {
26
+ this._nodes = graph.nodes.map((node) => ({
27
+ id: node.id,
28
+ type: node.type,
29
+ data: node.data,
30
+ }));
31
+
32
+ this._links = graph.edges.map((edge) => ({
33
+ type: edge.type,
34
+ source: edge.source,
35
+ target: edge.target,
36
+ data: edge.data,
37
+ }));
38
+ }
39
+
40
+ get nodes() {
41
+ return this._nodes;
42
+ }
43
+
44
+ get links() {
45
+ return this._links;
46
+ }
47
+ }
@@ -2,6 +2,5 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- export * from './graph-model';
6
-
7
- export * from './Graph';
5
+ export * from './D3ForceGraph';
6
+ export * from './ForceGraph';
@@ -0,0 +1,57 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { type AnyLiveObject, live, type Space } from '@dxos/client/echo';
6
+ import { Query, RelationSourceId, RelationTargetId } from '@dxos/echo-schema';
7
+ import { DataType } from '@dxos/schema';
8
+ import { createObjectFactory, type ValueGenerator, type TypeSpec } from '@dxos/schema/testing';
9
+ import { range } from '@dxos/util';
10
+
11
+ const getObject = (objects: AnyLiveObject[]) => objects[Math.floor(Math.random() * objects.length)];
12
+
13
+ const defaultTypes: TypeSpec[] = [
14
+ { type: DataType.Organization, count: 5 },
15
+ { type: DataType.Project, count: 5 },
16
+ { type: DataType.Person, count: 10 },
17
+ ];
18
+
19
+ export type GenerateOptions = {
20
+ spec?: TypeSpec[];
21
+ relations?: {
22
+ count: number;
23
+ kind: string;
24
+ };
25
+ };
26
+
27
+ const defaultRelations: GenerateOptions['relations'] = { count: 10, kind: 'friend' };
28
+
29
+ /**
30
+ * @deprecated Use @dxos/schema.
31
+ */
32
+ export const generate = async (
33
+ space: Space,
34
+ generator: ValueGenerator,
35
+ { spec = defaultTypes, relations = defaultRelations }: GenerateOptions = {},
36
+ ) => {
37
+ const createObjects = createObjectFactory(space.db, generator);
38
+ await createObjects(spec);
39
+
40
+ // Add relations between objects.
41
+ const { objects: contacts } = await space.db.query(Query.type(DataType.Person)).run();
42
+ for (const _ of range(relations.count)) {
43
+ const source = getObject(contacts);
44
+ const target = getObject(contacts);
45
+ if (source.id === target.id) {
46
+ continue;
47
+ }
48
+
49
+ space.db.add(
50
+ live(DataType.HasRelationship, {
51
+ kind: relations.kind,
52
+ [RelationSourceId]: source,
53
+ [RelationTargetId]: target,
54
+ }),
55
+ );
56
+ }
57
+ };
@@ -7,13 +7,13 @@ import '@dxos-theme';
7
7
  import { type Meta } from '@storybook/react';
8
8
  import React, { type FC, useEffect, useState } from 'react';
9
9
 
10
- import { TreeType, Tree as TreeModel } from '@dxos/plugin-outliner/types';
11
10
  import { faker } from '@dxos/random';
12
11
  import { useClient } from '@dxos/react-client';
13
12
  import { type ClientRepeatedComponentProps, ClientRepeater } from '@dxos/react-client/testing';
14
13
  import { withLayout, withTheme } from '@dxos/storybook-utils';
15
14
 
16
15
  import { Tree, type TreeComponentProps } from './Tree';
16
+ import { TreeType, Tree as TreeModel } from './types';
17
17
 
18
18
  // TODO(burdon): Storybook for Graph/Tree/Plot (generics); incl. GraphModel.
19
19
  // TODO(burdon): Type for all Explorer components (Space, Object, Query, etc.) incl.