@dxos/plugin-explorer 0.8.4-main.ae835ea → 0.8.4-main.bc2380dfbc

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 (234) hide show
  1. package/LICENSE +102 -5
  2. package/dist/lib/neutral/ExplorerArticle-EW2MBCRK.mjs +141 -0
  3. package/dist/lib/neutral/ExplorerArticle-EW2MBCRK.mjs.map +7 -0
  4. package/dist/lib/neutral/ExplorerPlugin.mjs +10 -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-7SPMPHRS.mjs +72 -0
  8. package/dist/lib/neutral/chunk-7SPMPHRS.mjs.map +7 -0
  9. package/dist/lib/neutral/chunk-GRJXLL4Z.mjs +25 -0
  10. package/dist/lib/neutral/chunk-GRJXLL4Z.mjs.map +7 -0
  11. package/dist/lib/{browser/chunk-UBHZGWZQ.mjs → neutral/chunk-HPIS2WXY.mjs} +2 -2
  12. package/dist/lib/neutral/chunk-HPIS2WXY.mjs.map +7 -0
  13. package/dist/lib/{browser/chunk-CRN65FY3.mjs → neutral/components/index.mjs} +817 -288
  14. package/dist/lib/{node-esm/chunk-RSZFBKZM.mjs.map → neutral/components/index.mjs.map} +4 -4
  15. package/dist/lib/neutral/containers/index.mjs +9 -0
  16. package/dist/lib/neutral/containers/index.mjs.map +7 -0
  17. package/dist/lib/neutral/create-object-F6TKVAGV.mjs +39 -0
  18. package/dist/lib/neutral/create-object-F6TKVAGV.mjs.map +7 -0
  19. package/dist/lib/neutral/hooks/index.mjs +45 -0
  20. package/dist/lib/neutral/hooks/index.mjs.map +7 -0
  21. package/dist/lib/neutral/index.mjs +14 -0
  22. package/dist/lib/neutral/meta.json +1 -0
  23. package/dist/lib/{browser → neutral}/meta.mjs +1 -1
  24. package/dist/lib/neutral/plugin.mjs +12 -0
  25. package/dist/lib/neutral/plugin.mjs.map +7 -0
  26. package/dist/lib/neutral/react-surface-APBW2VQG.mjs +26 -0
  27. package/dist/lib/neutral/react-surface-APBW2VQG.mjs.map +7 -0
  28. package/dist/lib/neutral/testing.mjs +8 -0
  29. package/dist/lib/neutral/translations.mjs +33 -0
  30. package/dist/lib/neutral/translations.mjs.map +7 -0
  31. package/dist/lib/{browser → neutral}/types/index.mjs +1 -2
  32. package/dist/types/data/cities.d.ts +4 -4
  33. package/dist/types/data/cities.d.ts.map +1 -1
  34. package/dist/types/data/countries-110m.d.ts +19 -22
  35. package/dist/types/data/countries-110m.d.ts.map +1 -1
  36. package/dist/types/src/ExplorerPlugin.d.ts +3 -1
  37. package/dist/types/src/ExplorerPlugin.d.ts.map +1 -1
  38. package/dist/types/src/ExplorerPlugin.test.d.ts +2 -0
  39. package/dist/types/src/ExplorerPlugin.test.d.ts.map +1 -0
  40. package/dist/types/src/capabilities/create-object.d.ts +11 -0
  41. package/dist/types/src/capabilities/create-object.d.ts.map +1 -0
  42. package/dist/types/src/capabilities/index.d.ts +8 -2
  43. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  44. package/dist/types/src/capabilities/react-surface.d.ts +3 -2
  45. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  46. package/dist/types/src/components/Chart/Chart.d.ts.map +1 -1
  47. package/dist/types/src/components/Chart/Chart.stories.d.ts +4 -1
  48. package/dist/types/src/components/Chart/Chart.stories.d.ts.map +1 -1
  49. package/dist/types/src/components/Globe/Globe.d.ts.map +1 -1
  50. package/dist/types/src/components/Globe/Globe.stories.d.ts +5 -2
  51. package/dist/types/src/components/Globe/Globe.stories.d.ts.map +1 -1
  52. package/dist/types/src/components/Graph/CanvasForceGraph.d.ts +13 -0
  53. package/dist/types/src/components/Graph/CanvasForceGraph.d.ts.map +1 -0
  54. package/dist/types/src/components/Graph/CanvasForceGraph.stories.d.ts +17 -0
  55. package/dist/types/src/components/Graph/CanvasForceGraph.stories.d.ts.map +1 -0
  56. package/dist/types/src/components/Graph/ForceGraph.d.ts +12 -5
  57. package/dist/types/src/components/Graph/ForceGraph.d.ts.map +1 -1
  58. package/dist/types/src/components/Graph/ForceGraph.stories.d.ts +4 -2
  59. package/dist/types/src/components/Graph/ForceGraph.stories.d.ts.map +1 -1
  60. package/dist/types/src/components/Graph/{adapter.d.ts → graph-adapter.d.ts} +2 -2
  61. package/dist/types/src/components/Graph/graph-adapter.d.ts.map +1 -0
  62. package/dist/types/src/components/Graph/index.d.ts +1 -1
  63. package/dist/types/src/components/Graph/index.d.ts.map +1 -1
  64. package/dist/types/src/components/Tree/EdgeBundling.stories.d.ts +21 -0
  65. package/dist/types/src/components/Tree/EdgeBundling.stories.d.ts.map +1 -0
  66. package/dist/types/src/components/Tree/Tree.d.ts +20 -23
  67. package/dist/types/src/components/Tree/Tree.d.ts.map +1 -1
  68. package/dist/types/src/components/Tree/Tree.stories.d.ts +5 -12
  69. package/dist/types/src/components/Tree/Tree.stories.d.ts.map +1 -1
  70. package/dist/types/src/components/Tree/index.d.ts +3 -0
  71. package/dist/types/src/components/Tree/index.d.ts.map +1 -1
  72. package/dist/types/src/components/Tree/layout/HierarchicalEdgeBundling.d.ts +35 -2
  73. package/dist/types/src/components/Tree/layout/HierarchicalEdgeBundling.d.ts.map +1 -1
  74. package/dist/types/src/components/Tree/layout/RadialTree.d.ts +35 -2
  75. package/dist/types/src/components/Tree/layout/RadialTree.d.ts.map +1 -1
  76. package/dist/types/src/components/Tree/layout/TidyTree.d.ts +24 -2
  77. package/dist/types/src/components/Tree/layout/TidyTree.d.ts.map +1 -1
  78. package/dist/types/src/components/Tree/layout/hierarchy.d.ts +17 -0
  79. package/dist/types/src/components/Tree/layout/hierarchy.d.ts.map +1 -0
  80. package/dist/types/src/components/Tree/layout/index.d.ts +5 -4
  81. package/dist/types/src/components/Tree/layout/index.d.ts.map +1 -1
  82. package/dist/types/src/components/Tree/layout/slots.d.ts +7 -0
  83. package/dist/types/src/components/Tree/layout/slots.d.ts.map +1 -0
  84. package/dist/types/src/components/Tree/layout/useContainerSize.d.ts +15 -0
  85. package/dist/types/src/components/Tree/layout/useContainerSize.d.ts.map +1 -0
  86. package/dist/types/src/components/Tree/space-graph-adapter.d.ts +32 -0
  87. package/dist/types/src/components/Tree/space-graph-adapter.d.ts.map +1 -0
  88. package/dist/types/src/components/Tree/testing/generator.d.ts.map +1 -1
  89. package/dist/types/src/components/Tree/testing/index.d.ts +1 -0
  90. package/dist/types/src/components/Tree/testing/index.d.ts.map +1 -1
  91. package/dist/types/src/components/Tree/testing/relations.d.ts +47 -0
  92. package/dist/types/src/components/Tree/testing/relations.d.ts.map +1 -0
  93. package/dist/types/src/components/Tree/types/tree.d.ts +18 -16
  94. package/dist/types/src/components/Tree/types/tree.d.ts.map +1 -1
  95. package/dist/types/src/components/Tree/types/types.d.ts +14 -4
  96. package/dist/types/src/components/Tree/types/types.d.ts.map +1 -1
  97. package/dist/types/src/components/index.d.ts +0 -4
  98. package/dist/types/src/components/index.d.ts.map +1 -1
  99. package/dist/types/src/components/plot.d.ts.map +1 -1
  100. package/dist/types/src/containers/ExplorerArticle/ExplorerArticle.d.ts +8 -0
  101. package/dist/types/src/containers/ExplorerArticle/ExplorerArticle.d.ts.map +1 -0
  102. package/dist/types/src/containers/ExplorerArticle/ExplorerArticle.stories.d.ts +24 -0
  103. package/dist/types/src/containers/ExplorerArticle/ExplorerArticle.stories.d.ts.map +1 -0
  104. package/dist/types/src/containers/ExplorerArticle/index.d.ts +2 -0
  105. package/dist/types/src/containers/ExplorerArticle/index.d.ts.map +1 -0
  106. package/dist/types/src/containers/index.d.ts +3 -0
  107. package/dist/types/src/containers/index.d.ts.map +1 -0
  108. package/dist/types/src/hooks/useGraphModel.d.ts +2 -2
  109. package/dist/types/src/hooks/useGraphModel.d.ts.map +1 -1
  110. package/dist/types/src/index.d.ts +1 -3
  111. package/dist/types/src/index.d.ts.map +1 -1
  112. package/dist/types/src/meta.d.ts +2 -2
  113. package/dist/types/src/meta.d.ts.map +1 -1
  114. package/dist/types/src/plugin.d.ts +3 -0
  115. package/dist/types/src/plugin.d.ts.map +1 -0
  116. package/dist/types/src/testing.d.ts +2 -0
  117. package/dist/types/src/testing.d.ts.map +1 -0
  118. package/dist/types/src/translations.d.ts +31 -22
  119. package/dist/types/src/translations.d.ts.map +1 -1
  120. package/dist/types/src/types/ExplorerAction.d.ts +1 -18
  121. package/dist/types/src/types/ExplorerAction.d.ts.map +1 -1
  122. package/dist/types/src/types/Graph.d.ts +14 -25
  123. package/dist/types/src/types/Graph.d.ts.map +1 -1
  124. package/dist/types/tsconfig.tsbuildinfo +1 -1
  125. package/package.json +113 -61
  126. package/src/ExplorerPlugin.test.ts +26 -0
  127. package/src/ExplorerPlugin.tsx +15 -56
  128. package/src/capabilities/create-object.ts +36 -0
  129. package/src/capabilities/index.ts +3 -3
  130. package/src/capabilities/react-surface.tsx +24 -19
  131. package/src/components/Chart/Chart.stories.tsx +16 -23
  132. package/src/components/Globe/Globe.stories.tsx +19 -22
  133. package/src/components/Graph/CanvasForceGraph.stories.tsx +83 -0
  134. package/src/components/Graph/CanvasForceGraph.tsx +124 -0
  135. package/src/components/Graph/ForceGraph.stories.tsx +79 -41
  136. package/src/components/Graph/ForceGraph.tsx +104 -85
  137. package/src/components/Graph/{adapter.ts → graph-adapter.ts} +14 -8
  138. package/src/components/Graph/index.ts +1 -1
  139. package/src/components/Tree/EdgeBundling.stories.tsx +144 -0
  140. package/src/components/Tree/Tree.stories.tsx +20 -38
  141. package/src/components/Tree/Tree.tsx +69 -95
  142. package/src/components/Tree/index.ts +3 -0
  143. package/src/components/Tree/layout/HierarchicalEdgeBundling.tsx +277 -0
  144. package/src/components/Tree/layout/RadialTree.tsx +237 -0
  145. package/src/components/Tree/layout/TidyTree.tsx +246 -0
  146. package/src/components/Tree/layout/hierarchy.ts +32 -0
  147. package/src/components/Tree/layout/index.ts +5 -5
  148. package/src/components/Tree/layout/slots.ts +19 -0
  149. package/src/components/Tree/layout/useContainerSize.ts +43 -0
  150. package/src/components/Tree/space-graph-adapter.ts +96 -0
  151. package/src/components/Tree/testing/generator.ts +4 -2
  152. package/src/components/Tree/testing/index.ts +1 -0
  153. package/src/components/Tree/testing/relations.ts +182 -0
  154. package/src/components/Tree/types/tree.test.ts +7 -6
  155. package/src/components/Tree/types/tree.ts +41 -20
  156. package/src/components/Tree/types/types.ts +38 -29
  157. package/src/components/index.ts +0 -4
  158. package/src/containers/ExplorerArticle/ExplorerArticle.stories.tsx +119 -0
  159. package/src/containers/ExplorerArticle/ExplorerArticle.tsx +153 -0
  160. package/src/containers/ExplorerArticle/index.ts +5 -0
  161. package/src/containers/index.ts +7 -0
  162. package/src/hooks/useGraphModel.ts +25 -14
  163. package/src/index.ts +1 -4
  164. package/src/meta.ts +3 -3
  165. package/src/plugin.ts +9 -0
  166. package/src/testing.ts +7 -0
  167. package/src/translations.ts +16 -13
  168. package/src/types/ExplorerAction.ts +10 -19
  169. package/src/types/Graph.ts +25 -22
  170. package/src/typings.d.ts +8 -0
  171. package/dist/lib/browser/ExplorerContainer-L5RVUJRL.mjs +0 -50
  172. package/dist/lib/browser/ExplorerContainer-L5RVUJRL.mjs.map +0 -7
  173. package/dist/lib/browser/chunk-2MKBRIUT.mjs +0 -31
  174. package/dist/lib/browser/chunk-2MKBRIUT.mjs.map +0 -7
  175. package/dist/lib/browser/chunk-6BVXZQPP.mjs +0 -188
  176. package/dist/lib/browser/chunk-6BVXZQPP.mjs.map +0 -7
  177. package/dist/lib/browser/chunk-BGNRYZUN.mjs +0 -79
  178. package/dist/lib/browser/chunk-BGNRYZUN.mjs.map +0 -7
  179. package/dist/lib/browser/chunk-CRN65FY3.mjs.map +0 -7
  180. package/dist/lib/browser/chunk-UBHZGWZQ.mjs.map +0 -7
  181. package/dist/lib/browser/index.mjs +0 -119
  182. package/dist/lib/browser/index.mjs.map +0 -7
  183. package/dist/lib/browser/intent-resolver-FX5H52QN.mjs +0 -31
  184. package/dist/lib/browser/intent-resolver-FX5H52QN.mjs.map +0 -7
  185. package/dist/lib/browser/meta.json +0 -1
  186. package/dist/lib/browser/react-surface-VS3ZFL2Y.mjs +0 -35
  187. package/dist/lib/browser/react-surface-VS3ZFL2Y.mjs.map +0 -7
  188. package/dist/lib/node-esm/ExplorerContainer-BBLPHH7K.mjs +0 -51
  189. package/dist/lib/node-esm/ExplorerContainer-BBLPHH7K.mjs.map +0 -7
  190. package/dist/lib/node-esm/chunk-3ODK27PU.mjs +0 -33
  191. package/dist/lib/node-esm/chunk-3ODK27PU.mjs.map +0 -7
  192. package/dist/lib/node-esm/chunk-CRSVAZNA.mjs +0 -190
  193. package/dist/lib/node-esm/chunk-CRSVAZNA.mjs.map +0 -7
  194. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +0 -11
  195. package/dist/lib/node-esm/chunk-RSZFBKZM.mjs +0 -11091
  196. package/dist/lib/node-esm/chunk-TQESRBUJ.mjs +0 -80
  197. package/dist/lib/node-esm/chunk-TQESRBUJ.mjs.map +0 -7
  198. package/dist/lib/node-esm/chunk-UXZM5VJB.mjs +0 -26
  199. package/dist/lib/node-esm/chunk-UXZM5VJB.mjs.map +0 -7
  200. package/dist/lib/node-esm/index.mjs +0 -120
  201. package/dist/lib/node-esm/index.mjs.map +0 -7
  202. package/dist/lib/node-esm/intent-resolver-RGBBXXYM.mjs +0 -32
  203. package/dist/lib/node-esm/intent-resolver-RGBBXXYM.mjs.map +0 -7
  204. package/dist/lib/node-esm/meta.json +0 -1
  205. package/dist/lib/node-esm/meta.mjs +0 -9
  206. package/dist/lib/node-esm/react-surface-SXPT2T37.mjs +0 -36
  207. package/dist/lib/node-esm/react-surface-SXPT2T37.mjs.map +0 -7
  208. package/dist/lib/node-esm/types/index.mjs +0 -12
  209. package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
  210. package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
  211. package/dist/types/src/components/ExplorerContainer.d.ts +0 -9
  212. package/dist/types/src/components/ExplorerContainer.d.ts.map +0 -1
  213. package/dist/types/src/components/Graph/D3ForceGraph.d.ts +0 -14
  214. package/dist/types/src/components/Graph/D3ForceGraph.d.ts.map +0 -1
  215. package/dist/types/src/components/Graph/D3ForceGraph.stories.d.ts +0 -15
  216. package/dist/types/src/components/Graph/D3ForceGraph.stories.d.ts.map +0 -1
  217. package/dist/types/src/components/Graph/adapter.d.ts.map +0 -1
  218. package/dist/types/src/components/Graph/testing.d.ts +0 -14
  219. package/dist/types/src/components/Graph/testing.d.ts.map +0 -1
  220. package/src/capabilities/intent-resolver.ts +0 -21
  221. package/src/components/ExplorerContainer.tsx +0 -54
  222. package/src/components/Graph/D3ForceGraph.stories.tsx +0 -77
  223. package/src/components/Graph/D3ForceGraph.tsx +0 -101
  224. package/src/components/Graph/testing.ts +0 -55
  225. package/src/components/Tree/layout/HierarchicalEdgeBundling.ts +0 -162
  226. package/src/components/Tree/layout/RadialTree.ts +0 -94
  227. package/src/components/Tree/layout/TidyTree.ts +0 -101
  228. /package/dist/lib/{browser/chunk-J5LGTIGS.mjs.map → neutral/ExplorerPlugin.mjs.map} +0 -0
  229. /package/dist/lib/{browser → neutral}/chunk-J5LGTIGS.mjs +0 -0
  230. /package/dist/lib/{browser/meta.mjs.map → neutral/chunk-J5LGTIGS.mjs.map} +0 -0
  231. /package/dist/lib/{browser/types → neutral}/index.mjs.map +0 -0
  232. /package/dist/lib/{node-esm → neutral}/meta.mjs.map +0 -0
  233. /package/dist/lib/{node-esm/chunk-HSLMI22Q.mjs.map → neutral/testing.mjs.map} +0 -0
  234. /package/dist/lib/{node-esm → neutral}/types/index.mjs.map +0 -0
@@ -1,5 +1,6 @@
1
+ import "../chunk-J5LGTIGS.mjs";
2
+
1
3
  // src/components/Chart/Chart.tsx
2
- import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
3
4
  import * as Plot from "@observablehq/plot";
4
5
  import React, { useEffect } from "react";
5
6
  import { useResizeDetector } from "react-resize-detector";
@@ -17,49 +18,43 @@ var defaultOptions = {
17
18
  fillOpacity: 0.2
18
19
  };
19
20
  var Chart = ({ items = [], accessor, options = defaultOptions }) => {
20
- var _effect = _useSignals();
21
- try {
22
- const { ref: containerRef, width = 0, height = 0 } = useResizeDetector({
23
- refreshRate: 200
24
- });
25
- useEffect(() => {
26
- if (!width || !height) {
27
- return;
28
- }
29
- const plot3 = Plot.plot({
30
- grid: true,
31
- width,
32
- height,
33
- style: {
34
- background: "transparent"
35
- },
36
- marks: [
37
- Plot.frame(),
38
- Plot.dot(items, {
39
- x: createAdapter("x", accessor),
40
- y: createAdapter("y", accessor),
41
- ...options
42
- })
43
- ]
44
- });
45
- containerRef.current.append(plot3);
46
- return () => plot3?.remove();
47
- }, [
48
- items,
21
+ const { ref: containerRef, width = 0, height = 0 } = useResizeDetector({
22
+ refreshRate: 200
23
+ });
24
+ useEffect(() => {
25
+ if (!width || !height) {
26
+ return;
27
+ }
28
+ const plot3 = Plot.plot({
29
+ grid: true,
49
30
  width,
50
- height
51
- ]);
52
- return /* @__PURE__ */ React.createElement("div", {
53
- ref: containerRef,
54
- className: "grow"
31
+ height,
32
+ style: {
33
+ background: "transparent"
34
+ },
35
+ marks: [
36
+ Plot.frame(),
37
+ Plot.dot(items, {
38
+ x: createAdapter("x", accessor),
39
+ y: createAdapter("y", accessor),
40
+ ...options
41
+ })
42
+ ]
55
43
  });
56
- } finally {
57
- _effect.f();
58
- }
44
+ containerRef.current.append(plot3);
45
+ return () => plot3?.remove();
46
+ }, [
47
+ items,
48
+ width,
49
+ height
50
+ ]);
51
+ return /* @__PURE__ */ React.createElement("div", {
52
+ ref: containerRef,
53
+ className: "grow"
54
+ });
59
55
  };
60
56
 
61
57
  // src/components/Globe/Globe.tsx
62
- import { useSignals as _useSignals2 } from "@preact-signals/safe-react/tracking";
63
58
  import * as Plot2 from "@observablehq/plot";
64
59
  import React2, { useEffect as useEffect2 } from "react";
65
60
  import { useResizeDetector as useResizeDetector2 } from "react-resize-detector";
@@ -10773,180 +10768,651 @@ var defaultOptions2 = {
10773
10768
  fill: "#003300"
10774
10769
  };
10775
10770
  var Globe = ({ items = [], accessor, projection = "orthographic", options = defaultOptions2 }) => {
10776
- var _effect = _useSignals2();
10777
- try {
10778
- const { ref: containerRef, width = 0, height = 0 } = useResizeDetector2({
10779
- refreshRate: 200
10780
- });
10781
- const land = topojson.feature(countries_110m_default, countries_110m_default.objects.land);
10782
- useEffect2(() => {
10783
- if (!width || !height) {
10784
- return;
10785
- }
10786
- const plot3 = Plot2.plot({
10787
- // https://observablehq.com/plot/features/projections
10788
- projection: {
10789
- type: projection,
10790
- rotate: [
10791
- -100,
10792
- -20
10793
- ]
10794
- },
10795
- // projection: { type: 'equirectangular', rotate: [-140, -30] },
10796
- width,
10797
- height,
10798
- style: {
10799
- background: "transparent"
10800
- },
10801
- // TODO(burdon): Create simple wrapper for Plot with good defaults.
10802
- marks: [
10803
- Plot2.sphere({
10804
- fill: "lightblue",
10805
- fillOpacity: 0.5
10806
- }),
10807
- Plot2.geo(land, {
10808
- fill: "darkgreen",
10809
- fillOpacity: 0.5
10810
- }),
10811
- Plot2.graticule(),
10812
- Plot2.dot(items, {
10813
- x: createAdapter("lat", accessor),
10814
- y: createAdapter("lng", accessor),
10815
- ...options
10816
- })
10771
+ const { ref: containerRef, width = 0, height = 0 } = useResizeDetector2({
10772
+ refreshRate: 200
10773
+ });
10774
+ const land = topojson.feature(countries_110m_default, countries_110m_default.objects.land);
10775
+ useEffect2(() => {
10776
+ if (!width || !height) {
10777
+ return;
10778
+ }
10779
+ const plot3 = Plot2.plot({
10780
+ // https://observablehq.com/plot/features/projections
10781
+ projection: {
10782
+ type: projection,
10783
+ rotate: [
10784
+ -100,
10785
+ -20
10817
10786
  ]
10818
- });
10819
- containerRef.current.append(plot3);
10820
- return () => plot3?.remove();
10821
- }, [
10822
- items,
10787
+ },
10788
+ // projection: { type: 'equirectangular', rotate: [-140, -30] },
10823
10789
  width,
10824
- height
10825
- ]);
10826
- return /* @__PURE__ */ React2.createElement("div", {
10827
- ref: containerRef,
10828
- className: "grow p-4"
10790
+ height,
10791
+ style: {
10792
+ background: "transparent"
10793
+ },
10794
+ // TODO(burdon): Create simple wrapper for Plot with good defaults.
10795
+ marks: [
10796
+ Plot2.sphere({
10797
+ fill: "lightblue",
10798
+ fillOpacity: 0.5
10799
+ }),
10800
+ Plot2.geo(land, {
10801
+ fill: "darkgreen",
10802
+ fillOpacity: 0.5
10803
+ }),
10804
+ Plot2.graticule(),
10805
+ Plot2.dot(items, {
10806
+ x: createAdapter("lat", accessor),
10807
+ y: createAdapter("lng", accessor),
10808
+ ...options
10809
+ })
10810
+ ]
10829
10811
  });
10830
- } finally {
10831
- _effect.f();
10812
+ containerRef.current.append(plot3);
10813
+ return () => plot3?.remove();
10814
+ }, [
10815
+ items,
10816
+ width,
10817
+ height
10818
+ ]);
10819
+ return /* @__PURE__ */ React2.createElement("div", {
10820
+ ref: containerRef,
10821
+ className: "grow p-4"
10822
+ });
10823
+ };
10824
+
10825
+ // src/components/Graph/CanvasForceGraph.tsx
10826
+ import { forceLink, forceManyBody } from "d3";
10827
+ import NativeForceGraph from "force-graph";
10828
+ import React3, { useCallback, useEffect as useEffect3, useRef, useState } from "react";
10829
+ import { useResizeDetector as useResizeDetector3 } from "react-resize-detector";
10830
+ import { composable, composableProps } from "@dxos/ui-theme";
10831
+
10832
+ // src/components/Graph/graph-adapter.ts
10833
+ var GraphAdapter = class {
10834
+ graph;
10835
+ _nodes = [];
10836
+ _links = [];
10837
+ constructor(graph) {
10838
+ this.graph = graph;
10839
+ this._nodes = graph.nodes.map((node) => ({
10840
+ id: node.id,
10841
+ type: node.type,
10842
+ data: node.data
10843
+ }));
10844
+ const nodeIds = new Set(this._nodes.map((node) => node.id));
10845
+ this._links = graph.edges.filter((edge) => nodeIds.has(edge.source) && nodeIds.has(edge.target)).map((edge) => ({
10846
+ type: edge.type,
10847
+ source: edge.source,
10848
+ target: edge.target,
10849
+ data: edge.data
10850
+ }));
10851
+ }
10852
+ get nodes() {
10853
+ return this._nodes;
10854
+ }
10855
+ get links() {
10856
+ return this._links;
10857
+ }
10858
+ };
10859
+
10860
+ // src/components/Graph/CanvasForceGraph.tsx
10861
+ var CanvasForceGraph = composable(({ model, match, onClick, ...props }, forwardedRef) => {
10862
+ const { ref: resizeRef, width, height } = useResizeDetector3({
10863
+ refreshRate: 200
10864
+ });
10865
+ const setRef = useCallback((node) => {
10866
+ resizeRef(node);
10867
+ assignRef(forwardedRef, node);
10868
+ }, [
10869
+ resizeRef,
10870
+ forwardedRef
10871
+ ]);
10872
+ const rootRef = useRef(null);
10873
+ const forceGraph = useRef(null);
10874
+ const [data, setData] = useState();
10875
+ useEffect3(() => {
10876
+ return model?.subscribe((model2) => setData(new GraphAdapter(model2.graph)));
10877
+ }, [
10878
+ model
10879
+ ]);
10880
+ useEffect3(() => {
10881
+ if (rootRef.current) {
10882
+ forceGraph.current = new NativeForceGraph(rootRef.current).nodeRelSize(6).nodeLabel((node) => node.type === "schema" ? node.data.typename : node.data.label ?? node.id).nodeAutoColorBy((node) => node.type === "schema" ? "schema" : node.data.typename).linkAutoColorBy((link) => link.type);
10883
+ }
10884
+ return () => {
10885
+ forceGraph.current?.pauseAnimation().graphData({
10886
+ nodes: [],
10887
+ links: []
10888
+ });
10889
+ forceGraph.current = null;
10890
+ };
10891
+ }, []);
10892
+ useEffect3(() => {
10893
+ if (!data || !width || !height || !forceGraph.current) {
10894
+ return;
10895
+ }
10896
+ forceGraph.current.pauseAnimation().width(width).height(height).onEngineStop(() => handleZoomToFit()).onNodeClick((node) => {
10897
+ forceGraph.current?.emitParticle(node);
10898
+ }).d3Force("link", forceLink().distance(160).strength(0.5)).d3Force("charge", forceManyBody().strength(-30)).graphData(data).warmupTicks(100).cooldownTime(1e3).resumeAnimation();
10899
+ }, [
10900
+ data,
10901
+ width,
10902
+ height
10903
+ ]);
10904
+ const handleZoomToFit = () => {
10905
+ forceGraph.current?.zoomToFit(400, 40);
10906
+ };
10907
+ const handleClick = useCallback((event) => {
10908
+ onClick?.(event);
10909
+ if (!event.defaultPrevented) {
10910
+ handleZoomToFit();
10911
+ }
10912
+ }, [
10913
+ onClick
10914
+ ]);
10915
+ return /* @__PURE__ */ React3.createElement("div", {
10916
+ ...composableProps(props, {
10917
+ classNames: "relative grow"
10918
+ }),
10919
+ onClick: handleClick,
10920
+ ref: setRef
10921
+ }, /* @__PURE__ */ React3.createElement("div", {
10922
+ ref: rootRef,
10923
+ className: "absolute inset-0"
10924
+ }));
10925
+ });
10926
+ var assignRef = (ref, value) => {
10927
+ if (typeof ref === "function") {
10928
+ ref(value);
10929
+ } else if (ref) {
10930
+ ref.current = value;
10832
10931
  }
10833
10932
  };
10834
10933
 
10934
+ // src/components/Graph/ForceGraph.tsx
10935
+ import { Atom, useAtomValue } from "@effect-atom/atom-react";
10936
+ import React4, { useCallback as useCallback2, useEffect as useEffect4, useMemo, useRef as useRef2, useState as useState2 } from "react";
10937
+ import { Obj } from "@dxos/echo";
10938
+ import { SelectionModel } from "@dxos/graph";
10939
+ import { GraphForceProjector, SVG } from "@dxos/react-ui-graph";
10940
+ import { composable as composable2, composableProps as composableProps2, getHashStyles } from "@dxos/ui-theme";
10941
+ import "@dxos/react-ui-graph/styles/graph.css";
10942
+ var EMPTY_ATOM = Atom.make({
10943
+ nodes: [],
10944
+ edges: []
10945
+ });
10946
+ var ForceGraph = composable2(({ model, selection: selectionProp, grid, drag, onInspect, ...props }, forwardedRef) => {
10947
+ useAtomValue(model?.graphAtom ?? EMPTY_ATOM);
10948
+ const graph = useRef2(null);
10949
+ const selection = useMemo(() => selectionProp ?? new SelectionModel(), [
10950
+ selectionProp
10951
+ ]);
10952
+ useEffect4(() => {
10953
+ const unsubscribe = selection.subscribe(() => graph.current?.repaint());
10954
+ return unsubscribe;
10955
+ }, [
10956
+ selection
10957
+ ]);
10958
+ const svgRef = useRef2(null);
10959
+ const [projector, setProjector] = useState2();
10960
+ useEffect4(() => {
10961
+ if (svgRef.current) {
10962
+ setProjector(new GraphForceProjector(svgRef.current, {
10963
+ attributes: {
10964
+ // TODO(burdon): Check type (currently assumes Employee property).
10965
+ // Edge shouldn't contribute to force if it's not active.
10966
+ linkForce: (edge) => edge.data?.object?.active !== false
10967
+ },
10968
+ forces: {
10969
+ point: {
10970
+ strength: 0.01
10971
+ }
10972
+ }
10973
+ }));
10974
+ }
10975
+ }, []);
10976
+ const handleSelect = useCallback2((node) => {
10977
+ if (selection.contains(node.id)) {
10978
+ selection.remove(node.id);
10979
+ } else {
10980
+ selection.add(node.id);
10981
+ }
10982
+ }, [
10983
+ selection
10984
+ ]);
10985
+ return /* @__PURE__ */ React4.createElement("div", {
10986
+ ...composableProps2(props, {
10987
+ classNames: "dx-container"
10988
+ }),
10989
+ ref: forwardedRef
10990
+ }, /* @__PURE__ */ React4.createElement(SVG.Root, {
10991
+ ref: svgRef
10992
+ }, /* @__PURE__ */ React4.createElement(SVG.Markers, null), grid && /* @__PURE__ */ React4.createElement(SVG.Grid, {
10993
+ axis: true
10994
+ }), /* @__PURE__ */ React4.createElement(SVG.Zoom, {
10995
+ extent: [
10996
+ 1 / 2,
10997
+ 2
10998
+ ]
10999
+ }, /* @__PURE__ */ React4.createElement(SVG.Graph, {
11000
+ ref: graph,
11001
+ drag,
11002
+ model,
11003
+ projector,
11004
+ labels: {
11005
+ text: (node) => node.data?.data.label ?? node.id
11006
+ },
11007
+ attributes: {
11008
+ node: (node) => {
11009
+ const obj = node.data?.data.object;
11010
+ return {
11011
+ data: {
11012
+ color: getHashStyles(obj && Obj.getTypename(obj))?.hue
11013
+ },
11014
+ classes: {
11015
+ "dx-selected": selection.contains(node.id)
11016
+ }
11017
+ };
11018
+ }
11019
+ },
11020
+ onSelect: handleSelect,
11021
+ onInspect
11022
+ }))));
11023
+ });
11024
+
10835
11025
  // src/components/Tree/Tree.tsx
10836
- import { useSignals as _useSignals3 } from "@preact-signals/safe-react/tracking";
10837
- import React3, { useEffect as useEffect3, useRef, useState } from "react";
10838
- import { useAsyncState } from "@dxos/react-ui";
10839
- import { SVG } from "@dxos/react-ui-graph";
10840
- import { SpaceGraphModel } from "@dxos/schema";
11026
+ import React8, { useMemo as useMemo5 } from "react";
10841
11027
 
10842
- // src/components/Tree/layout/HierarchicalEdgeBundling.ts
11028
+ // src/components/Tree/layout/HierarchicalEdgeBundling.tsx
10843
11029
  import { cluster, curveBundle, hierarchy, lineRadial, select } from "d3";
10844
- var HierarchicalEdgeBundling = (s, data, options) => {
10845
- const svg = select(s);
10846
- svg.selectAll("*").remove();
10847
- const { radius = 600, padding = 100, slots } = options;
10848
- const root = hierarchy(flatten(data));
10849
- const tree3 = cluster().size([
10850
- 2 * Math.PI,
10851
- radius - padding
10852
- ]);
10853
- const layout = tree3(addLinks(root));
10854
- const node = svg.append("g").selectAll().data(layout.leaves()).join("g").attr("transform", (d) => `rotate(${d.x * (180 / Math.PI) - 90}) translate(${d.y},0)`).append("text").attr("class", slots?.text ?? "").attr("dy", "0.31em").attr("x", (d) => d.x < Math.PI ? 6 : -6).attr("text-anchor", (d) => d.x < Math.PI ? "start" : "end").attr("transform", (d) => d.x >= Math.PI ? "rotate(180)" : null).call((text) => text.text((d) => d.data.id.slice(0, 8)));
10855
- const line = lineRadial().curve(curveBundle.beta(0.85)).radius((d) => d.y).angle((d) => d.x);
10856
- const links = svg.append("g").selectAll().data(layout.leaves().flatMap((leaf) => leaf.outgoing)).join("path").style("mix-blend-mode", "multiply").attr("class", slots?.path ?? "").attr("d", ([i, o]) => {
10857
- return line(i.path(o));
10858
- }).each(function(d) {
10859
- d.path = this;
11030
+ import React5, { useEffect as useEffect6, useMemo as useMemo2, useRef as useRef3 } from "react";
11031
+ import { mx } from "@dxos/ui-theme";
11032
+
11033
+ // src/components/Tree/layout/slots.ts
11034
+ var defaultTreeLayoutSlots = {
11035
+ // Cursor + transition so the hover swap reads clearly; SVG circles support the `:hover` pseudo-class
11036
+ // via Tailwind variants exactly like HTML elements.
11037
+ node: "fill-blue-600 hover:fill-orange-500 cursor-pointer transition-colors",
11038
+ // 0.5px is fine on a white background, but on a dark Storybook background the lines disappear.
11039
+ // Use stroke-1 with opacity 50% so they read in both themes; dx-bundle-dim/out/in further tune on hover.
11040
+ path: "fill-none stroke-blue-500/50 stroke-[1px] dark:stroke-blue-400/60",
11041
+ text: "fill-neutral-700 dark:fill-neutral-300 text-xs hover:fill-orange-500 cursor-pointer transition-colors"
11042
+ };
11043
+
11044
+ // src/components/Tree/layout/useContainerSize.ts
11045
+ import { useEffect as useEffect5, useState as useState3 } from "react";
11046
+ var useContainerSize = () => {
11047
+ const [el, setEl] = useState3(null);
11048
+ const [size, setSize] = useState3({
11049
+ width: 0,
11050
+ height: 0
10860
11051
  });
11052
+ useEffect5(() => {
11053
+ if (!el) {
11054
+ return;
11055
+ }
11056
+ const rect = el.getBoundingClientRect();
11057
+ setSize({
11058
+ width: rect.width,
11059
+ height: rect.height
11060
+ });
11061
+ const observer = new ResizeObserver((entries) => {
11062
+ const entry = entries[0];
11063
+ if (!entry) {
11064
+ return;
11065
+ }
11066
+ const { width, height } = entry.contentRect;
11067
+ setSize((prev) => prev.width === width && prev.height === height ? prev : {
11068
+ width,
11069
+ height
11070
+ });
11071
+ });
11072
+ observer.observe(el);
11073
+ return () => observer.disconnect();
11074
+ }, [
11075
+ el
11076
+ ]);
11077
+ return {
11078
+ setRef: setEl,
11079
+ width: size.width,
11080
+ height: size.height
11081
+ };
10861
11082
  };
10862
- var addLinks = (root) => {
10863
- const nodes = new Map(root.descendants().map((d) => [
10864
- d.data.id,
10865
- d
10866
- ]));
10867
- const parents = root.descendants().reduce((map, d) => {
10868
- if (d.children?.length) {
10869
- map.set(d.data.id, d);
11083
+
11084
+ // src/components/Tree/layout/HierarchicalEdgeBundling.tsx
11085
+ var TRANSITION_MS = 350;
11086
+ var HierarchicalEdgeBundling = ({ classNames, data, edges = [], label = (d) => d.label ?? d.id, padding = 120, tension = 0.85, slots = defaultTreeLayoutSlots, onNodeHover }) => {
11087
+ const svgRef = useRef3(null);
11088
+ const { setRef, width, height } = useContainerSize();
11089
+ const root = useMemo2(() => buildBundleHierarchy(data, edges), [
11090
+ data,
11091
+ edges
11092
+ ]);
11093
+ const handleHoverRef = useRef3(() => {
11094
+ });
11095
+ handleHoverRef.current = (node, event) => onNodeHover?.(node, event);
11096
+ useEffect6(() => {
11097
+ if (!svgRef.current || !width || !height) {
11098
+ return;
10870
11099
  }
10871
- return map;
10872
- }, /* @__PURE__ */ new Map());
10873
- for (const d of root.leaves()) {
10874
- const parent = parents.get(d.data.id);
10875
- if (parent) {
10876
- d.outgoing = parent.data.children?.slice(1).map((child) => {
10877
- return [
10878
- d,
10879
- nodes.get(child.id)
10880
- ];
10881
- }) ?? [];
10882
- } else {
10883
- d.outgoing = [];
11100
+ const radius = Math.max(0, Math.min(width, height) / 2 - padding);
11101
+ renderBundling(svgRef.current, root, {
11102
+ radius,
11103
+ label,
11104
+ slots,
11105
+ tension,
11106
+ onNodeHover: (n, e) => handleHoverRef.current(n, e)
11107
+ });
11108
+ }, [
11109
+ root,
11110
+ width,
11111
+ height,
11112
+ padding,
11113
+ tension,
11114
+ label,
11115
+ slots
11116
+ ]);
11117
+ return /* @__PURE__ */ React5.createElement("div", {
11118
+ ref: setRef,
11119
+ className: mx("dx-expander relative", classNames)
11120
+ }, width > 0 && height > 0 && /* @__PURE__ */ React5.createElement("svg", {
11121
+ ref: svgRef,
11122
+ xmlns: "http://www.w3.org/2000/svg",
11123
+ width,
11124
+ height,
11125
+ viewBox: `${-width / 2} ${-height / 2} ${width} ${height}`
11126
+ }));
11127
+ };
11128
+ var buildBundleHierarchy = (data, edges) => {
11129
+ const root = hierarchy(data);
11130
+ const byId = /* @__PURE__ */ new Map();
11131
+ for (const node of root.descendants()) {
11132
+ byId.set(node.data.id, node);
11133
+ node.outgoing = [];
11134
+ node.incoming = [];
11135
+ }
11136
+ for (const edge of edges) {
11137
+ const source = byId.get(edge.source);
11138
+ const target = byId.get(edge.target);
11139
+ if (!source || !target || source === target) {
11140
+ continue;
10884
11141
  }
11142
+ source.outgoing.push([
11143
+ source,
11144
+ target,
11145
+ edge
11146
+ ]);
11147
+ target.incoming.push([
11148
+ source,
11149
+ target,
11150
+ edge
11151
+ ]);
10885
11152
  }
10886
11153
  return root;
10887
11154
  };
10888
- var flatten = (node) => {
10889
- const clone = {
10890
- id: node.id
10891
- };
10892
- if (node.children?.length) {
10893
- const children = node.children.map((child) => flatten(child));
10894
- clone.children = [
10895
- {
10896
- id: node.id
10897
- },
10898
- ...children
10899
- ];
11155
+ var renderBundling = (svgElement, root, options) => {
11156
+ const { radius, tension, label, slots, onNodeHover } = options;
11157
+ const svg = select(svgElement);
11158
+ if (!root.children?.length) {
11159
+ svg.selectAll("g.dx-bundle-root").remove();
11160
+ return;
10900
11161
  }
10901
- return clone;
11162
+ cluster().size([
11163
+ 2 * Math.PI,
11164
+ radius
11165
+ ])(root);
11166
+ const g = svg.selectAll("g.dx-bundle-root").data([
11167
+ null
11168
+ ]).join("g").classed("dx-bundle-root", true);
11169
+ const linksLayer = g.selectAll("g.dx-bundle-links").data([
11170
+ null
11171
+ ]).join("g").classed("dx-bundle-links", true);
11172
+ const nodesLayer = g.selectAll("g.dx-bundle-nodes").data([
11173
+ null
11174
+ ]).join("g").classed("dx-bundle-nodes", true);
11175
+ const line = lineRadial().curve(curveBundle.beta(tension)).radius((d) => d.y).angle((d) => d.x);
11176
+ const leaves = root.leaves();
11177
+ const flatEdges = leaves.flatMap((leaf) => leaf.outgoing ?? []);
11178
+ const paths = linksLayer.selectAll("path").data(flatEdges, (d) => `${d[0].data.id}->${d[1].data.id}`).join((enter) => enter.append("path").attr("class", slots.path ?? "").attr("fill", "none").attr("opacity", 0), (update) => update, (exit) => exit.each(function() {
11179
+ select(this).interrupt();
11180
+ }).transition().duration(TRANSITION_MS).attr("opacity", 0).remove());
11181
+ paths.each(function(d) {
11182
+ d[0].pathEl = this;
11183
+ }).transition().duration(TRANSITION_MS).attr("opacity", 1).attr("d", ([s, t]) => line(s.path(t)));
11184
+ const labels = nodesLayer.selectAll("g.dx-bundle-leaf").data(leaves, (d) => d.data.id).join((enter) => {
11185
+ const ge = enter.append("g").classed("dx-bundle-leaf", true).attr("opacity", 0);
11186
+ ge.append("text").attr("dy", "0.32em").attr("paint-order", "stroke").style("cursor", "pointer");
11187
+ return ge;
11188
+ }, (update) => update, (exit) => exit.each(function() {
11189
+ select(this).interrupt();
11190
+ }).transition().duration(TRANSITION_MS).attr("opacity", 0).remove());
11191
+ labels.transition().duration(TRANSITION_MS).attr("opacity", 1).attr("transform", (d) => `rotate(${d.x * 180 / Math.PI - 90}) translate(${d.y},0)`);
11192
+ labels.select("text").attr("class", slots.text ?? "").attr("x", (d) => d.x < Math.PI ? 6 : -6).attr("text-anchor", (d) => d.x < Math.PI ? "start" : "end").attr("transform", (d) => d.x >= Math.PI ? "rotate(180)" : null).each(function(d) {
11193
+ d.text = this;
11194
+ }).text((d) => label(d.data)).on("pointerenter", function(event, d) {
11195
+ onNodeHover(d.data, event);
11196
+ hover(linksLayer, leaves, d, true);
11197
+ }).on("pointerleave", function(event, d) {
11198
+ onNodeHover(null);
11199
+ hover(linksLayer, leaves, d, false);
11200
+ });
11201
+ };
11202
+ var hover = (linksLayer, leaves, focused, on) => {
11203
+ const outgoing = new Set((focused.outgoing ?? []).map(([, t]) => t));
11204
+ const incoming = new Set((focused.incoming ?? []).map(([s]) => s));
11205
+ linksLayer.selectAll("path").classed("dx-bundle-out", (d) => on && d[0] === focused).classed("dx-bundle-in", (d) => on && d[1] === focused).classed("dx-bundle-dim", (d) => on && d[0] !== focused && d[1] !== focused);
11206
+ for (const leaf of leaves) {
11207
+ if (!leaf.text) {
11208
+ continue;
11209
+ }
11210
+ select(leaf.text).classed("dx-bundle-focused", on && leaf === focused).classed("dx-bundle-out-text", on && outgoing.has(leaf)).classed("dx-bundle-in-text", on && incoming.has(leaf));
11211
+ }
11212
+ };
11213
+
11214
+ // src/components/Tree/layout/RadialTree.tsx
11215
+ import { cluster as d3Cluster, linkRadial, select as select2, tree as d3Tree } from "d3";
11216
+ import React6, { useCallback as useCallback3, useEffect as useEffect7, useMemo as useMemo3, useRef as useRef4, useState as useState4 } from "react";
11217
+ import { mx as mx2 } from "@dxos/ui-theme";
11218
+
11219
+ // src/components/Tree/layout/hierarchy.ts
11220
+ import { hierarchy as d3Hierarchy } from "d3";
11221
+ var buildHierarchy = (data, collapsed = /* @__PURE__ */ new Set()) => {
11222
+ return d3Hierarchy(data, (d) => {
11223
+ if (!d.children?.length) {
11224
+ return void 0;
11225
+ }
11226
+ return collapsed.has(d.id) ? void 0 : d.children;
11227
+ });
10902
11228
  };
10903
- var HierarchicalEdgeBundling_default = HierarchicalEdgeBundling;
11229
+ var isCollapsed = (data, collapsed) => Boolean(data.children?.length) && collapsed.has(data.id);
11230
+ var isLeaf = (data) => !data.children?.length;
10904
11231
 
10905
- // src/components/Tree/layout/RadialTree.ts
10906
- import { hierarchy as hierarchy2, linkRadial, select as select2, tree } from "d3";
10907
- var RadialTree = (s, data, options) => {
10908
- const svg = select2(s);
10909
- svg.selectAll("*").remove();
10910
- const { label, radius = 400, r = 4, slots } = options;
10911
- const arc = 2 * Math.PI;
10912
- const root = hierarchy2(data);
10913
- const descendants = root.descendants();
10914
- const getLabel = label === null ? null : descendants.map((d) => label(d.data));
10915
- const layout = tree().size([
10916
- arc,
11232
+ // src/components/Tree/layout/RadialTree.tsx
11233
+ var TRANSITION_MS2 = 350;
11234
+ var RadialTree = ({ classNames, data, label = (d) => d.label ?? d.id, slots = defaultTreeLayoutSlots, r = 4, padding = 80, initialCollapsed, cluster: cluster2 = false, onNodeClick, onNodeHover }) => {
11235
+ const svgRef = useRef4(null);
11236
+ const { setRef, width, height } = useContainerSize();
11237
+ const [collapsed, setCollapsed] = useState4(() => new Set(initialCollapsed ?? []));
11238
+ const toggle = useCallback3((id) => {
11239
+ setCollapsed((prev) => {
11240
+ const next = new Set(prev);
11241
+ if (next.has(id)) {
11242
+ next.delete(id);
11243
+ } else {
11244
+ next.add(id);
11245
+ }
11246
+ return next;
11247
+ });
11248
+ }, []);
11249
+ const handleClickRef = useRef4(() => {
11250
+ });
11251
+ handleClickRef.current = (node) => {
11252
+ onNodeClick?.(node);
11253
+ if (node.children?.length) {
11254
+ toggle(node.id);
11255
+ }
11256
+ };
11257
+ const handleHoverRef = useRef4(() => {
11258
+ });
11259
+ handleHoverRef.current = (node, event) => onNodeHover?.(node, event);
11260
+ const root = useMemo3(() => buildHierarchy(data, collapsed), [
11261
+ data,
11262
+ collapsed
11263
+ ]);
11264
+ useEffect7(() => {
11265
+ if (!svgRef.current || !width || !height) {
11266
+ return;
11267
+ }
11268
+ const radius = Math.max(0, Math.min(width, height) / 2 - padding);
11269
+ renderRadialTree(svgRef.current, root, {
11270
+ radius,
11271
+ r,
11272
+ label,
11273
+ slots,
11274
+ collapsed,
11275
+ cluster: cluster2,
11276
+ onNodeClick: (n) => handleClickRef.current(n),
11277
+ onNodeHover: (n, e) => handleHoverRef.current(n, e)
11278
+ });
11279
+ }, [
11280
+ root,
11281
+ width,
11282
+ height,
11283
+ r,
11284
+ padding,
11285
+ label,
11286
+ slots,
11287
+ collapsed,
11288
+ cluster2
11289
+ ]);
11290
+ return /* @__PURE__ */ React6.createElement("div", {
11291
+ ref: setRef,
11292
+ className: mx2("dx-expander relative", classNames)
11293
+ }, width > 0 && height > 0 && /* @__PURE__ */ React6.createElement("svg", {
11294
+ ref: svgRef,
11295
+ xmlns: "http://www.w3.org/2000/svg",
11296
+ width,
11297
+ height,
11298
+ viewBox: `${-width / 2} ${-height / 2} ${width} ${height}`
11299
+ }));
11300
+ };
11301
+ var renderRadialTree = (svgElement, root, options) => {
11302
+ const { radius, r, label, slots, collapsed, cluster: cluster2, onNodeClick, onNodeHover } = options;
11303
+ const svg = select2(svgElement);
11304
+ const layout = cluster2 ? d3Cluster() : d3Tree();
11305
+ layout.size([
11306
+ 2 * Math.PI,
10917
11307
  radius
10918
- ]).separation((a, b) => (a.parent === b.parent ? 1 : 2) / a.depth);
10919
- layout(root);
10920
- svg.append("g").selectAll("path").data(root.links()).join("path").attr("class", slots?.path ?? "").attr("d", linkRadial().angle((d) => d.x + Math.PI / 2).radius((d) => d.y));
10921
- const node = svg.append("g").selectAll("a").data(root.descendants()).join("a").attr("transform", (d) => `rotate(${d.x * 180 / Math.PI}) translate(${d.y},0)`);
10922
- node.append("circle").attr("class", slots?.node ?? "").attr("r", r);
10923
- if (getLabel) {
10924
- node.append("text").attr("transform", (d) => `rotate(${d.x >= Math.PI ? 180 : 0})`).attr("dy", "0.32em").attr("x", (d) => d.x < Math.PI === !d.children ? 6 : -6).attr("text-anchor", (d) => d.x < Math.PI === !d.children ? "start" : "end").attr("class", slots?.text ?? "").text((d, i) => getLabel[i]);
10925
- }
10926
- return svg.node();
11308
+ ]).separation((a, b) => (a.parent === b.parent ? 1 : 2) / Math.max(1, a.depth))(root);
11309
+ const g = svg.selectAll("g.dx-radial-root").data([
11310
+ null
11311
+ ]).join("g").classed("dx-radial-root", true);
11312
+ const linksLayer = g.selectAll("g.dx-radial-links").data([
11313
+ null
11314
+ ]).join("g").classed("dx-radial-links", true);
11315
+ const nodesLayer = g.selectAll("g.dx-radial-nodes").data([
11316
+ null
11317
+ ]).join("g").classed("dx-radial-nodes", true);
11318
+ const linkPath = linkRadial().angle((d) => d.x).radius((d) => d.y);
11319
+ linksLayer.selectAll("path").data(root.links(), (d) => `${d.source.data.id}->${d.target.data.id}`).join((enter) => enter.append("path").attr("class", slots.path ?? "").attr("fill", "none").attr("opacity", 0), (update) => update, (exit) => exit.transition().duration(TRANSITION_MS2).attr("opacity", 0).remove()).transition().duration(TRANSITION_MS2).attr("opacity", 1).attr("d", linkPath);
11320
+ const node = nodesLayer.selectAll("g.dx-radial-node").data(root.descendants(), (d) => d.data.id);
11321
+ const nodeEnter = node.enter().append("g").classed("dx-radial-node", true).attr("opacity", 0).attr("transform", (d) => `rotate(${d.x * 180 / Math.PI - 90}) translate(${d.y},0)`).style("cursor", (d) => d.data.children?.length ? "pointer" : "default").on("click", (_, d) => onNodeClick(d.data));
11322
+ nodeEnter.append("circle").attr("r", r).on("pointerenter", (event, d) => onNodeHover(d.data, event)).on("pointerleave", (event) => onNodeHover(null, event));
11323
+ nodeEnter.append("text").attr("dy", "0.32em").attr("paint-order", "stroke").text((d) => label(d.data));
11324
+ const nodeMerge = nodeEnter.merge(node);
11325
+ nodeMerge.transition().duration(TRANSITION_MS2).attr("opacity", 1).attr("transform", (d) => `rotate(${d.x * 180 / Math.PI - 90}) translate(${d.y},0)`);
11326
+ nodeMerge.select("circle").attr("class", (d) => {
11327
+ const collapsedHere = isCollapsed(d.data, collapsed);
11328
+ const leaf = isLeaf(d.data);
11329
+ return [
11330
+ slots.node ?? "",
11331
+ collapsedHere ? "dx-collapsed" : leaf ? "dx-leaf" : "dx-branch"
11332
+ ].filter(Boolean).join(" ");
11333
+ }).attr("r", r);
11334
+ nodeMerge.select("text").attr("class", slots.text ?? "").attr("transform", (d) => d.x >= Math.PI ? "rotate(180)" : null).attr("x", (d) => d.x < Math.PI === !d.children ? r + 4 : -(r + 4)).attr("text-anchor", (d) => d.x < Math.PI === !d.children ? "start" : "end").text((d) => label(d.data));
11335
+ node.exit().transition().duration(TRANSITION_MS2).attr("opacity", 0).remove();
10927
11336
  };
10928
- var RadialTree_default = RadialTree;
10929
11337
 
10930
- // src/components/Tree/layout/TidyTree.ts
10931
- import { curveBumpX, hierarchy as hierarchy3, link, select as select3, tree as tree2 } from "d3";
10932
- var TidyTree = (s, data, options) => {
10933
- const svg = select3(s);
10934
- svg.selectAll("*").remove();
10935
- const { label, width, height, r = 4, padding = 4, margin = 60, slots } = options;
10936
- const root = hierarchy3(data);
10937
- const descendants = root.descendants();
10938
- const getLabel = label == null ? null : descendants.map((d) => label(d.data));
10939
- const dx = 16;
10940
- const dy = width / (root.height + padding);
10941
- const layout = tree2().nodeSize([
11338
+ // src/components/Tree/layout/TidyTree.tsx
11339
+ import { curveBumpX, link as d3Link, select as select3, tree as d3Tree2 } from "d3";
11340
+ import React7, { useCallback as useCallback4, useEffect as useEffect8, useMemo as useMemo4, useRef as useRef5, useState as useState5 } from "react";
11341
+ import { mx as mx3 } from "@dxos/ui-theme";
11342
+ var TRANSITION_MS3 = 350;
11343
+ var TidyTree = ({ classNames, data, label = (d) => d.label ?? d.id, slots = defaultTreeLayoutSlots, r = 4, margin = 24, initialCollapsed, onNodeClick }) => {
11344
+ const svgRef = useRef5(null);
11345
+ const { setRef, width, height } = useContainerSize();
11346
+ const [collapsed, setCollapsed] = useState5(() => new Set(initialCollapsed ?? []));
11347
+ const toggle = useCallback4((id) => {
11348
+ setCollapsed((prev) => {
11349
+ const next = new Set(prev);
11350
+ if (next.has(id)) {
11351
+ next.delete(id);
11352
+ } else {
11353
+ next.add(id);
11354
+ }
11355
+ return next;
11356
+ });
11357
+ }, []);
11358
+ const handleClickRef = useRef5(() => {
11359
+ });
11360
+ handleClickRef.current = (node) => {
11361
+ onNodeClick?.(node);
11362
+ if (node.children?.length) {
11363
+ toggle(node.id);
11364
+ }
11365
+ };
11366
+ const root = useMemo4(() => buildHierarchy(data, collapsed), [
11367
+ data,
11368
+ collapsed
11369
+ ]);
11370
+ useEffect8(() => {
11371
+ if (!svgRef.current || !width || !height) {
11372
+ return;
11373
+ }
11374
+ renderTidyTree(svgRef.current, root, {
11375
+ width,
11376
+ height,
11377
+ r,
11378
+ margin,
11379
+ label,
11380
+ slots,
11381
+ collapsed,
11382
+ onNodeClick: (n) => handleClickRef.current(n)
11383
+ });
11384
+ }, [
11385
+ root,
11386
+ width,
11387
+ height,
11388
+ r,
11389
+ margin,
11390
+ label,
11391
+ slots,
11392
+ collapsed
11393
+ ]);
11394
+ return /* @__PURE__ */ React7.createElement("div", {
11395
+ ref: setRef,
11396
+ className: mx3("dx-expander relative", classNames)
11397
+ }, width > 0 && height > 0 && /* @__PURE__ */ React7.createElement("svg", {
11398
+ ref: svgRef,
11399
+ xmlns: "http://www.w3.org/2000/svg",
11400
+ width,
11401
+ height,
11402
+ viewBox: `${-width / 2} ${-height / 2} ${width} ${height}`
11403
+ }));
11404
+ };
11405
+ var renderTidyTree = (svgElement, root, options) => {
11406
+ const { width, height, r, margin, label, slots, collapsed, onNodeClick } = options;
11407
+ const svg = select3(svgElement);
11408
+ const dx = 18;
11409
+ const dy = Math.max(60, (width - margin * 2) / Math.max(1, root.height + 1));
11410
+ d3Tree2().nodeSize([
10942
11411
  dx,
10943
11412
  dy
10944
- ]);
10945
- layout(root);
11413
+ ])(root);
10946
11414
  let x0 = Infinity;
10947
11415
  let x1 = -x0;
10948
- let y0 = Infinity;
10949
- let y1 = -y0;
10950
11416
  root.each((d) => {
10951
11417
  if (d.x > x1) {
10952
11418
  x1 = d.x;
@@ -10954,27 +11420,140 @@ var TidyTree = (s, data, options) => {
10954
11420
  if (d.x < x0) {
10955
11421
  x0 = d.x;
10956
11422
  }
10957
- if (d.y > y1) {
10958
- y1 = d.y;
10959
- }
10960
- if (d.y < y0) {
10961
- y0 = d.y;
10962
- }
10963
11423
  });
10964
- const sx = Math.min(2, Math.max(1, (height - margin * 2) / (x1 - x0)));
10965
- const oy = -(width - (y1 - y0)) / 2;
10966
- svg.append("g").selectAll("path").data(root.links()).join("path").attr("class", slots?.path ?? "").attr("d", link(curveBumpX).x((d) => d.y + oy).y((d) => d.x * sx));
10967
- const node = svg.append("g").selectAll("a").data(root.descendants()).join("a").attr("transform", (d) => `translate(${d.y + oy},${d.x * sx})`);
10968
- node.append("circle").attr("class", slots?.node ?? "").attr("r", r);
10969
- if (getLabel) {
10970
- node.append("text").attr("dy", "0.32em").attr("x", (d) => d.children ? -6 : 6).attr("text-anchor", (d) => d.children ? "end" : "start").attr("class", slots?.text ?? "").text((d, i) => getLabel[i]);
11424
+ const treeWidth = width - margin * 2;
11425
+ const treeHeight = x1 - x0;
11426
+ const scaleY = treeHeight > 0 ? Math.min(1, (height - margin * 2) / treeHeight) : 1;
11427
+ const offsetX = -treeWidth / 2;
11428
+ const offsetY = -(x0 + x1) / 2;
11429
+ const g = svg.selectAll("g.dx-tidy-root").data([
11430
+ null
11431
+ ]).join("g").classed("dx-tidy-root", true);
11432
+ const linksLayer = g.selectAll("g.dx-tidy-links").data([
11433
+ null
11434
+ ]).join("g").classed("dx-tidy-links", true);
11435
+ const nodesLayer = g.selectAll("g.dx-tidy-nodes").data([
11436
+ null
11437
+ ]).join("g").classed("dx-tidy-nodes", true);
11438
+ const linkPath = d3Link(curveBumpX).x((d) => offsetX + d.y).y((d) => (d.x + offsetY) * scaleY);
11439
+ linksLayer.selectAll("path").data(root.links(), (d) => `${d.source.data.id}->${d.target.data.id}`).join((enter) => enter.append("path").attr("class", slots.path ?? "").attr("fill", "none").attr("opacity", 0), (update) => update, (exit) => exit.transition().duration(TRANSITION_MS3).attr("opacity", 0).remove()).transition().duration(TRANSITION_MS3).attr("opacity", 1).attr("d", linkPath);
11440
+ const node = nodesLayer.selectAll("g.dx-tidy-node").data(root.descendants(), (d) => d.data.id);
11441
+ const nodeEnter = node.enter().append("g").classed("dx-tidy-node", true).attr("transform", (d) => `translate(${offsetX + d.y},${(d.x + offsetY) * scaleY})`).attr("opacity", 0).style("cursor", (d) => d.data.children?.length ? "pointer" : "default").on("click", (_, d) => onNodeClick(d.data));
11442
+ nodeEnter.append("circle").attr("r", r);
11443
+ nodeEnter.append("text").attr("dy", "0.32em").attr("x", (d) => d.children ? -(r + 4) : r + 4).attr("text-anchor", (d) => d.children ? "end" : "start").text((d) => label(d.data));
11444
+ const nodeMerge = nodeEnter.merge(node);
11445
+ nodeMerge.transition().duration(TRANSITION_MS3).attr("opacity", 1).attr("transform", (d) => `translate(${offsetX + d.y},${(d.x + offsetY) * scaleY})`);
11446
+ nodeMerge.select("circle").attr("class", (d) => {
11447
+ const collapsedHere = isCollapsed(d.data, collapsed);
11448
+ const leaf = isLeaf(d.data);
11449
+ return [
11450
+ slots.node ?? "",
11451
+ collapsedHere ? "dx-collapsed" : leaf ? "dx-leaf" : "dx-branch"
11452
+ ].filter(Boolean).join(" ");
11453
+ }).attr("r", r);
11454
+ nodeMerge.select("text").attr("class", slots.text ?? "").attr("x", (d) => d.children ? -(r + 4) : r + 4).attr("text-anchor", (d) => d.children ? "end" : "start").text((d) => label(d.data));
11455
+ node.exit().each(function() {
11456
+ select3(this).interrupt();
11457
+ }).transition().duration(TRANSITION_MS3).attr("opacity", 0).remove();
11458
+ };
11459
+
11460
+ // src/components/Tree/Tree.tsx
11461
+ var Tree = ({ classNames, data, edges, variant = "tidy", label, slots, initialCollapsed, onNodeClick, onNodeHover }) => {
11462
+ return useMemo5(() => {
11463
+ switch (variant) {
11464
+ case "tidy":
11465
+ return /* @__PURE__ */ React8.createElement(TidyTree, {
11466
+ classNames,
11467
+ data,
11468
+ label,
11469
+ slots,
11470
+ initialCollapsed,
11471
+ onNodeClick
11472
+ });
11473
+ case "radial":
11474
+ return /* @__PURE__ */ React8.createElement(RadialTree, {
11475
+ classNames,
11476
+ data,
11477
+ label,
11478
+ slots,
11479
+ initialCollapsed,
11480
+ onNodeClick,
11481
+ onNodeHover
11482
+ });
11483
+ case "edge":
11484
+ return /* @__PURE__ */ React8.createElement(HierarchicalEdgeBundling, {
11485
+ classNames,
11486
+ data,
11487
+ edges: edges ?? [],
11488
+ label,
11489
+ slots,
11490
+ onNodeHover
11491
+ });
11492
+ }
11493
+ }, [
11494
+ variant,
11495
+ classNames,
11496
+ data,
11497
+ edges,
11498
+ label,
11499
+ slots,
11500
+ initialCollapsed,
11501
+ onNodeClick,
11502
+ onNodeHover
11503
+ ]);
11504
+ };
11505
+
11506
+ // src/components/Tree/space-graph-adapter.ts
11507
+ import { Obj as Obj2 } from "@dxos/echo";
11508
+ var ROOT_ID = "db:root";
11509
+ var SCHEMA_PREFIX = "schema:";
11510
+ var truncate = (id) => `${id.slice(0, 4)}\u2026${id.slice(-4)}`;
11511
+ var labelOf = (node) => node.data?.label ?? truncate(node.id);
11512
+ var spaceGraphToHierarchy = (model, { rootLabel = "Database", rootId = ROOT_ID } = {}) => {
11513
+ const graph = model.graph;
11514
+ const objectNodes = graph.nodes.filter((node) => node.type === "object");
11515
+ const byTypename = /* @__PURE__ */ new Map();
11516
+ for (const node of objectNodes) {
11517
+ const obj = node.data?.object;
11518
+ const typename = (obj && Obj2.getTypename(obj)) ?? "(untyped)";
11519
+ const bucket = byTypename.get(typename) ?? [];
11520
+ bucket.push(node);
11521
+ byTypename.set(typename, bucket);
10971
11522
  }
11523
+ const tree = {
11524
+ id: rootId,
11525
+ label: rootLabel,
11526
+ children: Array.from(byTypename.entries()).map(([typename, nodes]) => ({
11527
+ id: `${SCHEMA_PREFIX}${typename}`,
11528
+ label: shortTypename(typename),
11529
+ children: nodes.map((node) => ({
11530
+ id: node.id,
11531
+ label: labelOf(node),
11532
+ // Preserve the ECHO object on the leaf so layouts can fire hover/inspect callbacks with it.
11533
+ data: node.data?.object
11534
+ }))
11535
+ }))
11536
+ };
11537
+ const objectIds = new Set(objectNodes.map((n) => n.id));
11538
+ const edges = graph.edges.filter((edge) => objectIds.has(edge.source) && objectIds.has(edge.target)).filter((edge) => edge.source !== edge.target).map((edge) => ({
11539
+ source: edge.source,
11540
+ target: edge.target,
11541
+ kind: edge.type
11542
+ }));
11543
+ return {
11544
+ tree,
11545
+ edges
11546
+ };
11547
+ };
11548
+ var shortTypename = (typename) => {
11549
+ const last = typename.split(".").pop() ?? typename;
11550
+ return last.charAt(0).toUpperCase() + last.slice(1);
10972
11551
  };
10973
- var TidyTree_default = TidyTree;
10974
11552
 
10975
11553
  // src/components/Tree/types/tree.ts
10976
11554
  import * as Schema from "effect/Schema";
10977
- import { Key, Obj, Type } from "@dxos/echo";
11555
+ import { Key, Obj as Obj3, Ref, Type } from "@dxos/echo";
11556
+ import { TestSchema } from "@dxos/echo/testing";
10978
11557
  import { invariant } from "@dxos/invariant";
10979
11558
  var TreeNodeType = Schema.Struct({
10980
11559
  id: Key.ObjectId,
@@ -10983,7 +11562,7 @@ var TreeNodeType = Schema.Struct({
10983
11562
  key: Schema.String,
10984
11563
  value: Schema.Any
10985
11564
  })),
10986
- ref: Schema.optional(Type.Ref(Type.Expando))
11565
+ ref: Schema.optional(Ref.Ref(TestSchema.Expando))
10987
11566
  }).pipe(Schema.mutable);
10988
11567
  var TreeType = Schema.Struct({
10989
11568
  root: Key.ObjectId,
@@ -10991,99 +11570,49 @@ var TreeType = Schema.Struct({
10991
11570
  key: Key.ObjectId,
10992
11571
  value: TreeNodeType
10993
11572
  }))
10994
- }).pipe(Type.Obj({
10995
- typename: "dxos.org/type/Tree",
11573
+ }).pipe(Type.object({
11574
+ typename: "org.dxos.type.tree",
10996
11575
  version: "0.1.0"
10997
11576
  }));
10998
11577
 
10999
11578
  // src/components/Tree/types/types.ts
11000
- var mapGraphToTreeData = (model, maxDepth = 8) => {
11001
- let data;
11002
- return data;
11003
- };
11004
-
11005
- // src/components/Tree/Tree.tsx
11006
- var defaultTreeLayoutSlots = {
11007
- node: "fill-blue-600",
11008
- path: "fill-none stroke-blue-400 stroke-[0.5px]",
11009
- text: "stroke-[0.5px] stroke-neutral-700 text-xs"
11010
- };
11011
- var renderers = /* @__PURE__ */ new Map([
11012
- [
11013
- "tidy",
11014
- TidyTree_default
11015
- ],
11016
- [
11017
- "radial",
11018
- RadialTree_default
11019
- ],
11020
- [
11021
- "edge",
11022
- HierarchicalEdgeBundling_default
11023
- ]
11024
- ]);
11025
- var Tree = ({ space, selected, variant = "tidy", onNodeClick }) => {
11026
- var _effect = _useSignals3();
11027
- try {
11028
- const [model] = useAsyncState(async () => space ? new SpaceGraphModel().open(space) : void 0, [
11029
- space,
11030
- selected
11031
- ]);
11032
- const [tree3, setTree] = useState();
11033
- useEffect3(() => {
11034
- return model?.subscribe(() => {
11035
- const tree4 = mapGraphToTreeData(model);
11036
- setTree(tree4);
11037
- }, true);
11038
- }, [
11039
- model
11040
- ]);
11041
- const context = useRef(null);
11042
- useEffect3(() => {
11043
- if (context.current?.size) {
11044
- const { width, height } = context.current.size;
11045
- const size = Math.min(width, height);
11046
- const radius = size * 0.4;
11047
- const options = {
11048
- // TODO(burdon): Type.
11049
- label: (d) => d.label ?? d.id,
11050
- width,
11051
- height,
11052
- radius,
11053
- marginLeft: (width - radius * 2) / 2,
11054
- marginRight: (width - radius * 2) / 2,
11055
- marginTop: (height - radius * 2) / 2,
11056
- marginBottom: (height - radius * 2) / 2,
11057
- slots: defaultTreeLayoutSlots
11058
- };
11059
- if (tree3) {
11060
- const renderer = renderers.get(variant);
11061
- renderer?.(context.current.svg, tree3, options);
11062
- }
11063
- }
11064
- }, [
11065
- context.current,
11066
- tree3
11067
- ]);
11068
- return /* @__PURE__ */ React3.createElement("div", {
11069
- onClick: () => onNodeClick?.()
11070
- }, /* @__PURE__ */ React3.createElement(SVG.Root, {
11071
- ref: context
11072
- }));
11073
- } finally {
11074
- _effect.f();
11579
+ var treeTypeToTreeNode = (tree, rootId = tree.root, visited = /* @__PURE__ */ new Set()) => {
11580
+ const node = tree.nodes[rootId];
11581
+ if (!node) {
11582
+ return void 0;
11583
+ }
11584
+ if (visited.has(rootId)) {
11585
+ return {
11586
+ id: rootId,
11587
+ label: labelOf2(node),
11588
+ data: node.data
11589
+ };
11075
11590
  }
11591
+ visited.add(rootId);
11592
+ return {
11593
+ id: rootId,
11594
+ label: labelOf2(node),
11595
+ data: node.data,
11596
+ children: node.children.map((childId) => treeTypeToTreeNode(tree, childId, visited)).filter((c) => Boolean(c))
11597
+ };
11598
+ };
11599
+ var labelOf2 = (node) => {
11600
+ return typeof node.data?.text === "string" ? node.data.text : void 0;
11076
11601
  };
11077
-
11078
- // src/components/index.ts
11079
- import { lazy } from "react";
11080
- var ExplorerContainer = lazy(() => import("./ExplorerContainer-L5RVUJRL.mjs"));
11081
-
11082
11602
  export {
11603
+ CanvasForceGraph,
11083
11604
  Chart,
11605
+ ForceGraph,
11084
11606
  Globe,
11085
- defaultTreeLayoutSlots,
11607
+ HierarchicalEdgeBundling,
11608
+ RadialTree,
11609
+ TidyTree,
11086
11610
  Tree,
11087
- ExplorerContainer
11611
+ buildHierarchy,
11612
+ defaultTreeLayoutSlots,
11613
+ isCollapsed,
11614
+ isLeaf,
11615
+ spaceGraphToHierarchy,
11616
+ treeTypeToTreeNode
11088
11617
  };
11089
- //# sourceMappingURL=chunk-CRN65FY3.mjs.map
11618
+ //# sourceMappingURL=index.mjs.map