@dxos/plugin-explorer 0.8.4-main.c4373fc → 0.8.4-main.c85a9c8dae

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 (146) hide show
  1. package/dist/lib/browser/ExplorerContainer-4RB2TY3G.mjs +48 -0
  2. package/dist/lib/browser/ExplorerContainer-4RB2TY3G.mjs.map +7 -0
  3. package/dist/lib/browser/chunk-4NFGHCGO.mjs +84 -0
  4. package/dist/lib/browser/chunk-4NFGHCGO.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-UCDNCIRV.mjs → chunk-6AZY4CDH.mjs} +343 -406
  6. package/dist/lib/{node-esm/chunk-WHKUQG5M.mjs.map → browser/chunk-6AZY4CDH.mjs.map} +4 -4
  7. package/dist/lib/browser/chunk-J5LGTIGS.mjs +10 -0
  8. package/dist/lib/browser/chunk-J5LGTIGS.mjs.map +7 -0
  9. package/dist/lib/browser/{chunk-2DGFNLRO.mjs → chunk-YNQF4CPY.mjs} +7 -2
  10. package/dist/lib/browser/chunk-YNQF4CPY.mjs.map +7 -0
  11. package/dist/lib/browser/index.mjs +51 -68
  12. package/dist/lib/browser/index.mjs.map +4 -4
  13. package/dist/lib/browser/meta.json +1 -1
  14. package/dist/lib/browser/meta.mjs +2 -1
  15. package/dist/lib/browser/react-surface-KAHVDMFX.mjs +38 -0
  16. package/dist/lib/browser/react-surface-KAHVDMFX.mjs.map +7 -0
  17. package/dist/lib/browser/types/index.mjs +6 -6
  18. package/dist/lib/node-esm/ExplorerContainer-LCG425I7.mjs +49 -0
  19. package/dist/lib/node-esm/ExplorerContainer-LCG425I7.mjs.map +7 -0
  20. package/dist/lib/node-esm/{chunk-PX6LHR2N.mjs → chunk-DK77RB6M.mjs} +7 -2
  21. package/dist/lib/node-esm/chunk-DK77RB6M.mjs.map +7 -0
  22. package/dist/lib/node-esm/{chunk-WHKUQG5M.mjs → chunk-DOXAIJEC.mjs} +343 -406
  23. package/dist/lib/{browser/chunk-UCDNCIRV.mjs.map → node-esm/chunk-DOXAIJEC.mjs.map} +4 -4
  24. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
  25. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +7 -0
  26. package/dist/lib/node-esm/chunk-V42OFY7B.mjs +85 -0
  27. package/dist/lib/node-esm/chunk-V42OFY7B.mjs.map +7 -0
  28. package/dist/lib/node-esm/index.mjs +51 -68
  29. package/dist/lib/node-esm/index.mjs.map +4 -4
  30. package/dist/lib/node-esm/meta.json +1 -1
  31. package/dist/lib/node-esm/meta.mjs +2 -1
  32. package/dist/lib/node-esm/react-surface-7XILIUI4.mjs +39 -0
  33. package/dist/lib/node-esm/react-surface-7XILIUI4.mjs.map +7 -0
  34. package/dist/lib/node-esm/types/index.mjs +6 -6
  35. package/dist/types/src/ExplorerPlugin.d.ts +2 -1
  36. package/dist/types/src/ExplorerPlugin.d.ts.map +1 -1
  37. package/dist/types/src/capabilities/index.d.ts +1 -2
  38. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  39. package/dist/types/src/capabilities/react-surface/index.d.ts +3 -0
  40. package/dist/types/src/capabilities/react-surface/index.d.ts.map +1 -0
  41. package/dist/types/src/capabilities/react-surface/react-surface.d.ts +5 -0
  42. package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +1 -0
  43. package/dist/types/src/components/Graph/D3ForceGraph.d.ts +3 -3
  44. package/dist/types/src/components/Graph/D3ForceGraph.d.ts.map +1 -1
  45. package/dist/types/src/components/Graph/D3ForceGraph.stories.d.ts +1 -1
  46. package/dist/types/src/components/Graph/D3ForceGraph.stories.d.ts.map +1 -1
  47. package/dist/types/src/components/Graph/ForceGraph.stories.d.ts.map +1 -1
  48. package/dist/types/src/components/Graph/adapter.d.ts +1 -1
  49. package/dist/types/src/components/Graph/adapter.d.ts.map +1 -1
  50. package/dist/types/src/components/Graph/testing.d.ts.map +1 -1
  51. package/dist/types/src/components/Tree/Tree.d.ts.map +1 -1
  52. package/dist/types/src/components/Tree/Tree.stories.d.ts.map +1 -1
  53. package/dist/types/src/components/Tree/testing/generator.d.ts.map +1 -1
  54. package/dist/types/src/components/Tree/types/tree.d.ts +18 -16
  55. package/dist/types/src/components/Tree/types/tree.d.ts.map +1 -1
  56. package/dist/types/src/components/Tree/types/types.d.ts +1 -1
  57. package/dist/types/src/components/Tree/types/types.d.ts.map +1 -1
  58. package/dist/types/src/components/index.d.ts +0 -4
  59. package/dist/types/src/components/index.d.ts.map +1 -1
  60. package/dist/types/src/containers/ExplorerContainer/ExplorerContainer.d.ts +6 -0
  61. package/dist/types/src/containers/ExplorerContainer/ExplorerContainer.d.ts.map +1 -0
  62. package/dist/types/src/containers/ExplorerContainer/index.d.ts +3 -0
  63. package/dist/types/src/containers/ExplorerContainer/index.d.ts.map +1 -0
  64. package/dist/types/src/containers/index.d.ts +3 -0
  65. package/dist/types/src/containers/index.d.ts.map +1 -0
  66. package/dist/types/src/hooks/useGraphModel.d.ts.map +1 -1
  67. package/dist/types/src/meta.d.ts +2 -2
  68. package/dist/types/src/meta.d.ts.map +1 -1
  69. package/dist/types/src/translations.d.ts +17 -10
  70. package/dist/types/src/translations.d.ts.map +1 -1
  71. package/dist/types/src/types/ExplorerAction.d.ts +6 -0
  72. package/dist/types/src/types/ExplorerAction.d.ts.map +1 -0
  73. package/dist/types/src/types/Graph.d.ts +30 -0
  74. package/dist/types/src/types/Graph.d.ts.map +1 -0
  75. package/dist/types/src/types/index.d.ts +2 -2
  76. package/dist/types/src/types/index.d.ts.map +1 -1
  77. package/dist/types/tsconfig.tsbuildinfo +1 -1
  78. package/package.json +51 -45
  79. package/src/ExplorerPlugin.tsx +29 -50
  80. package/src/capabilities/index.ts +1 -4
  81. package/src/capabilities/react-surface/index.ts +7 -0
  82. package/src/capabilities/react-surface/react-surface.tsx +31 -0
  83. package/src/components/Chart/Chart.stories.tsx +3 -3
  84. package/src/components/Globe/Globe.stories.tsx +3 -3
  85. package/src/components/Graph/D3ForceGraph.stories.tsx +30 -14
  86. package/src/components/Graph/D3ForceGraph.tsx +8 -7
  87. package/src/components/Graph/ForceGraph.stories.tsx +30 -14
  88. package/src/components/Graph/adapter.ts +14 -8
  89. package/src/components/Graph/testing.ts +11 -8
  90. package/src/components/Tree/Tree.stories.tsx +4 -3
  91. package/src/components/Tree/Tree.tsx +8 -3
  92. package/src/components/Tree/testing/generator.ts +4 -2
  93. package/src/components/Tree/types/tree.test.ts +5 -3
  94. package/src/components/Tree/types/tree.ts +40 -19
  95. package/src/components/Tree/types/types.ts +1 -1
  96. package/src/components/index.ts +0 -4
  97. package/src/containers/ExplorerContainer/ExplorerContainer.tsx +53 -0
  98. package/src/containers/ExplorerContainer/index.ts +7 -0
  99. package/src/containers/index.ts +7 -0
  100. package/src/hooks/useGraphModel.ts +6 -3
  101. package/src/meta.ts +8 -3
  102. package/src/translations.ts +4 -2
  103. package/src/types/ExplorerAction.ts +21 -0
  104. package/src/types/Graph.ts +63 -0
  105. package/src/types/index.ts +2 -2
  106. package/dist/lib/browser/ExplorerContainer-S66JDOAF.mjs +0 -49
  107. package/dist/lib/browser/ExplorerContainer-S66JDOAF.mjs.map +0 -7
  108. package/dist/lib/browser/chunk-2DGFNLRO.mjs.map +0 -7
  109. package/dist/lib/browser/chunk-2MKBRIUT.mjs +0 -31
  110. package/dist/lib/browser/chunk-2MKBRIUT.mjs.map +0 -7
  111. package/dist/lib/browser/chunk-4ETQJYX4.mjs +0 -38
  112. package/dist/lib/browser/chunk-4ETQJYX4.mjs.map +0 -7
  113. package/dist/lib/browser/chunk-NXGP6NTP.mjs +0 -203
  114. package/dist/lib/browser/chunk-NXGP6NTP.mjs.map +0 -7
  115. package/dist/lib/browser/intent-resolver-OXJJ3PII.mjs +0 -24
  116. package/dist/lib/browser/intent-resolver-OXJJ3PII.mjs.map +0 -7
  117. package/dist/lib/browser/react-surface-C4EC6ZDZ.mjs +0 -31
  118. package/dist/lib/browser/react-surface-C4EC6ZDZ.mjs.map +0 -7
  119. package/dist/lib/node-esm/ExplorerContainer-GIJN67DO.mjs +0 -50
  120. package/dist/lib/node-esm/ExplorerContainer-GIJN67DO.mjs.map +0 -7
  121. package/dist/lib/node-esm/chunk-3ODK27PU.mjs +0 -33
  122. package/dist/lib/node-esm/chunk-3ODK27PU.mjs.map +0 -7
  123. package/dist/lib/node-esm/chunk-6JACZE7E.mjs +0 -205
  124. package/dist/lib/node-esm/chunk-6JACZE7E.mjs.map +0 -7
  125. package/dist/lib/node-esm/chunk-AGHU3KVI.mjs +0 -39
  126. package/dist/lib/node-esm/chunk-AGHU3KVI.mjs.map +0 -7
  127. package/dist/lib/node-esm/chunk-PX6LHR2N.mjs.map +0 -7
  128. package/dist/lib/node-esm/intent-resolver-GVM36TJX.mjs +0 -25
  129. package/dist/lib/node-esm/intent-resolver-GVM36TJX.mjs.map +0 -7
  130. package/dist/lib/node-esm/react-surface-YGGLTBF3.mjs +0 -32
  131. package/dist/lib/node-esm/react-surface-YGGLTBF3.mjs.map +0 -7
  132. package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
  133. package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
  134. package/dist/types/src/capabilities/react-surface.d.ts +0 -4
  135. package/dist/types/src/capabilities/react-surface.d.ts.map +0 -1
  136. package/dist/types/src/components/ExplorerContainer.d.ts +0 -9
  137. package/dist/types/src/components/ExplorerContainer.d.ts.map +0 -1
  138. package/dist/types/src/types/schema.d.ts +0 -12
  139. package/dist/types/src/types/schema.d.ts.map +0 -1
  140. package/dist/types/src/types/types.d.ts +0 -18
  141. package/dist/types/src/types/types.d.ts.map +0 -1
  142. package/src/capabilities/intent-resolver.ts +0 -19
  143. package/src/capabilities/react-surface.tsx +0 -23
  144. package/src/components/ExplorerContainer.tsx +0 -50
  145. package/src/types/schema.ts +0 -16
  146. package/src/types/types.ts +0 -22
@@ -1,5 +1,4 @@
1
1
  // src/components/Chart/Chart.tsx
2
- import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
3
2
  import * as Plot from "@observablehq/plot";
4
3
  import React, { useEffect } from "react";
5
4
  import { useResizeDetector } from "react-resize-detector";
@@ -17,49 +16,43 @@ var defaultOptions = {
17
16
  fillOpacity: 0.2
18
17
  };
19
18
  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,
19
+ const { ref: containerRef, width = 0, height = 0 } = useResizeDetector({
20
+ refreshRate: 200
21
+ });
22
+ useEffect(() => {
23
+ if (!width || !height) {
24
+ return;
25
+ }
26
+ const plot3 = Plot.plot({
27
+ grid: true,
49
28
  width,
50
- height
51
- ]);
52
- return /* @__PURE__ */ React.createElement("div", {
53
- ref: containerRef,
54
- className: "grow"
29
+ height,
30
+ style: {
31
+ background: "transparent"
32
+ },
33
+ marks: [
34
+ Plot.frame(),
35
+ Plot.dot(items, {
36
+ x: createAdapter("x", accessor),
37
+ y: createAdapter("y", accessor),
38
+ ...options
39
+ })
40
+ ]
55
41
  });
56
- } finally {
57
- _effect.f();
58
- }
42
+ containerRef.current.append(plot3);
43
+ return () => plot3?.remove();
44
+ }, [
45
+ items,
46
+ width,
47
+ height
48
+ ]);
49
+ return /* @__PURE__ */ React.createElement("div", {
50
+ ref: containerRef,
51
+ className: "grow"
52
+ });
59
53
  };
60
54
 
61
55
  // src/components/Globe/Globe.tsx
62
- import { useSignals as _useSignals2 } from "@preact-signals/safe-react/tracking";
63
56
  import * as Plot2 from "@observablehq/plot";
64
57
  import React2, { useEffect as useEffect2 } from "react";
65
58
  import { useResizeDetector as useResizeDetector2 } from "react-resize-detector";
@@ -10773,70 +10766,238 @@ var defaultOptions2 = {
10773
10766
  fill: "#003300"
10774
10767
  };
10775
10768
  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
- })
10769
+ const { ref: containerRef, width = 0, height = 0 } = useResizeDetector2({
10770
+ refreshRate: 200
10771
+ });
10772
+ const land = topojson.feature(countries_110m_default, countries_110m_default.objects.land);
10773
+ useEffect2(() => {
10774
+ if (!width || !height) {
10775
+ return;
10776
+ }
10777
+ const plot3 = Plot2.plot({
10778
+ // https://observablehq.com/plot/features/projections
10779
+ projection: {
10780
+ type: projection,
10781
+ rotate: [
10782
+ -100,
10783
+ -20
10817
10784
  ]
10818
- });
10819
- containerRef.current.append(plot3);
10820
- return () => plot3?.remove();
10821
- }, [
10822
- items,
10785
+ },
10786
+ // projection: { type: 'equirectangular', rotate: [-140, -30] },
10823
10787
  width,
10824
- height
10825
- ]);
10826
- return /* @__PURE__ */ React2.createElement("div", {
10827
- ref: containerRef,
10828
- className: "grow p-4"
10788
+ height,
10789
+ style: {
10790
+ background: "transparent"
10791
+ },
10792
+ // TODO(burdon): Create simple wrapper for Plot with good defaults.
10793
+ marks: [
10794
+ Plot2.sphere({
10795
+ fill: "lightblue",
10796
+ fillOpacity: 0.5
10797
+ }),
10798
+ Plot2.geo(land, {
10799
+ fill: "darkgreen",
10800
+ fillOpacity: 0.5
10801
+ }),
10802
+ Plot2.graticule(),
10803
+ Plot2.dot(items, {
10804
+ x: createAdapter("lat", accessor),
10805
+ y: createAdapter("lng", accessor),
10806
+ ...options
10807
+ })
10808
+ ]
10829
10809
  });
10830
- } finally {
10831
- _effect.f();
10810
+ containerRef.current.append(plot3);
10811
+ return () => plot3?.remove();
10812
+ }, [
10813
+ items,
10814
+ width,
10815
+ height
10816
+ ]);
10817
+ return /* @__PURE__ */ React2.createElement("div", {
10818
+ ref: containerRef,
10819
+ className: "grow p-4"
10820
+ });
10821
+ };
10822
+
10823
+ // src/components/Graph/D3ForceGraph.tsx
10824
+ import React3, { useCallback, useEffect as useEffect3, useMemo, useRef } from "react";
10825
+ import { Obj } from "@dxos/echo";
10826
+ import { SelectionModel } from "@dxos/graph";
10827
+ import { GraphForceProjector, SVG } from "@dxos/react-ui-graph";
10828
+ import { getHashStyles } from "@dxos/ui-theme";
10829
+ import "@dxos/react-ui-graph/styles/graph.css";
10830
+ var D3ForceGraph = ({ classNames, model, selection: _selection, grid, drag, ...props }) => {
10831
+ const context = useRef(null);
10832
+ const projector = useMemo(() => {
10833
+ if (context.current) {
10834
+ return new GraphForceProjector(context.current, {
10835
+ attributes: {
10836
+ linkForce: (edge) => {
10837
+ return edge.data?.object?.active !== false;
10838
+ }
10839
+ },
10840
+ forces: {
10841
+ point: {
10842
+ strength: 0.01
10843
+ }
10844
+ }
10845
+ });
10846
+ }
10847
+ }, [
10848
+ context.current
10849
+ ]);
10850
+ const graph = useRef(null);
10851
+ const selection = useMemo(() => _selection ?? new SelectionModel(), [
10852
+ _selection
10853
+ ]);
10854
+ useEffect3(() => selection.subscribe(() => graph.current?.repaint()), [
10855
+ selection
10856
+ ]);
10857
+ const handleSelect = useCallback((node) => {
10858
+ if (selection.contains(node.id)) {
10859
+ selection.remove(node.id);
10860
+ } else {
10861
+ selection.add(node.id);
10862
+ }
10863
+ }, [
10864
+ selection
10865
+ ]);
10866
+ return /* @__PURE__ */ React3.createElement(SVG.Root, {
10867
+ ref: context,
10868
+ classNames,
10869
+ ...props
10870
+ }, /* @__PURE__ */ React3.createElement(SVG.Markers, null), grid && /* @__PURE__ */ React3.createElement(SVG.Grid, {
10871
+ axis: true
10872
+ }), /* @__PURE__ */ React3.createElement(SVG.Zoom, {
10873
+ extent: [
10874
+ 1 / 2,
10875
+ 2
10876
+ ]
10877
+ }, /* @__PURE__ */ React3.createElement(SVG.Graph, {
10878
+ drag,
10879
+ ref: graph,
10880
+ model,
10881
+ projector,
10882
+ labels: {
10883
+ text: (node) => {
10884
+ return node.data?.data.label ?? node.id;
10885
+ }
10886
+ },
10887
+ attributes: {
10888
+ node: (node) => {
10889
+ const obj = node.data?.data.object;
10890
+ return {
10891
+ data: {
10892
+ color: getHashStyles(obj && Obj.getTypename(obj))?.hue
10893
+ },
10894
+ classes: {
10895
+ "dx-selected": selection.contains(node.id)
10896
+ }
10897
+ };
10898
+ }
10899
+ },
10900
+ onSelect: handleSelect
10901
+ })));
10902
+ };
10903
+
10904
+ // src/components/Graph/ForceGraph.tsx
10905
+ import { forceLink, forceManyBody } from "d3";
10906
+ import NativeForceGraph from "force-graph";
10907
+ import React4, { useEffect as useEffect4, useRef as useRef2, useState } from "react";
10908
+ import { useResizeDetector as useResizeDetector3 } from "react-resize-detector";
10909
+ import { filterObjectsSync } from "@dxos/plugin-search";
10910
+
10911
+ // src/components/Graph/adapter.ts
10912
+ var GraphAdapter = class {
10913
+ graph;
10914
+ _nodes = [];
10915
+ _links = [];
10916
+ constructor(graph) {
10917
+ this.graph = graph;
10918
+ this._nodes = graph.nodes.map((node) => ({
10919
+ id: node.id,
10920
+ type: node.type,
10921
+ data: node.data
10922
+ }));
10923
+ const nodeIds = new Set(this._nodes.map((node) => node.id));
10924
+ this._links = graph.edges.filter((edge) => nodeIds.has(edge.source) && nodeIds.has(edge.target)).map((edge) => ({
10925
+ type: edge.type,
10926
+ source: edge.source,
10927
+ target: edge.target,
10928
+ data: edge.data
10929
+ }));
10930
+ }
10931
+ get nodes() {
10932
+ return this._nodes;
10933
+ }
10934
+ get links() {
10935
+ return this._links;
10832
10936
  }
10833
10937
  };
10834
10938
 
10939
+ // src/components/Graph/ForceGraph.tsx
10940
+ var ForceGraph = ({ model, match }) => {
10941
+ const { ref, width, height } = useResizeDetector3({
10942
+ refreshRate: 200
10943
+ });
10944
+ const rootRef = useRef2(null);
10945
+ const forceGraph = useRef2(null);
10946
+ const filteredRef = useRef2([]);
10947
+ filteredRef.current = filterObjectsSync(model?.objects ?? [], match);
10948
+ const [data, setData] = useState();
10949
+ useEffect4(() => {
10950
+ return model?.subscribe((model2) => {
10951
+ setData(new GraphAdapter(model2.graph));
10952
+ });
10953
+ }, [
10954
+ model
10955
+ ]);
10956
+ useEffect4(() => {
10957
+ if (rootRef.current) {
10958
+ 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((link2) => link2.type);
10959
+ }
10960
+ return () => {
10961
+ forceGraph.current?.pauseAnimation().graphData({
10962
+ nodes: [],
10963
+ links: []
10964
+ });
10965
+ forceGraph.current = null;
10966
+ };
10967
+ }, []);
10968
+ useEffect4(() => {
10969
+ if (!data || !width || !height || !forceGraph.current) {
10970
+ return;
10971
+ }
10972
+ forceGraph.current.pauseAnimation().width(width).height(height).onEngineStop(() => {
10973
+ handleZoomToFit();
10974
+ }).onNodeClick((node) => {
10975
+ forceGraph.current?.emitParticle(node);
10976
+ }).d3Force("link", forceLink().distance(160).strength(0.5)).d3Force("charge", forceManyBody().strength(-30)).graphData(data).warmupTicks(100).cooldownTime(1e3).resumeAnimation();
10977
+ }, [
10978
+ data,
10979
+ width,
10980
+ height,
10981
+ forceGraph.current
10982
+ ]);
10983
+ const handleZoomToFit = () => {
10984
+ forceGraph.current?.zoomToFit(400, 40);
10985
+ };
10986
+ return /* @__PURE__ */ React4.createElement("div", {
10987
+ ref,
10988
+ className: "relative grow",
10989
+ onClick: handleZoomToFit
10990
+ }, /* @__PURE__ */ React4.createElement("div", {
10991
+ ref: rootRef,
10992
+ className: "absolute inset-0"
10993
+ }));
10994
+ };
10995
+
10835
10996
  // 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";
10997
+ import { RegistryContext } from "@effect-atom/atom-react";
10998
+ import React5, { useContext, useEffect as useEffect5, useRef as useRef3, useState as useState2 } from "react";
10838
10999
  import { useAsyncState } from "@dxos/react-ui";
10839
- import { SVG } from "@dxos/react-ui-graph";
11000
+ import { SVG as SVG2 } from "@dxos/react-ui-graph";
10840
11001
  import { SpaceGraphModel } from "@dxos/schema";
10841
11002
 
10842
11003
  // src/components/Tree/layout/HierarchicalEdgeBundling.ts
@@ -10974,22 +11135,9 @@ var TidyTree_default = TidyTree;
10974
11135
 
10975
11136
  // src/components/Tree/types/tree.ts
10976
11137
  import * as Schema from "effect/Schema";
10977
- import { Key, Obj, Type } from "@dxos/echo";
11138
+ import { Key, Obj as Obj2, Ref, Type } from "@dxos/echo";
11139
+ import { TestSchema } from "@dxos/echo/testing";
10978
11140
  import { invariant } from "@dxos/invariant";
10979
- function _define_property(obj, key, value) {
10980
- if (key in obj) {
10981
- Object.defineProperty(obj, key, {
10982
- value,
10983
- enumerable: true,
10984
- configurable: true,
10985
- writable: true
10986
- });
10987
- } else {
10988
- obj[key] = value;
10989
- }
10990
- return obj;
10991
- }
10992
- var __dxlog_file = "/__w/dxos/dxos/packages/plugins/plugin-explorer/src/components/Tree/types/tree.ts";
10993
11141
  var TreeNodeType = Schema.Struct({
10994
11142
  id: Key.ObjectId,
10995
11143
  children: Schema.mutable(Schema.Array(Key.ObjectId)),
@@ -10997,7 +11145,7 @@ var TreeNodeType = Schema.Struct({
10997
11145
  key: Schema.String,
10998
11146
  value: Schema.Any
10999
11147
  })),
11000
- ref: Schema.optional(Type.Ref(Type.Expando))
11148
+ ref: Schema.optional(Ref.Ref(TestSchema.Expando))
11001
11149
  }).pipe(Schema.mutable);
11002
11150
  var TreeType = Schema.Struct({
11003
11151
  root: Key.ObjectId,
@@ -11005,248 +11153,10 @@ var TreeType = Schema.Struct({
11005
11153
  key: Key.ObjectId,
11006
11154
  value: TreeNodeType
11007
11155
  }))
11008
- }).pipe(Type.Obj({
11156
+ }).pipe(Type.object({
11009
11157
  typename: "dxos.org/type/Tree",
11010
11158
  version: "0.1.0"
11011
11159
  }));
11012
- var Tree = class _Tree {
11013
- get tree() {
11014
- return this._tree;
11015
- }
11016
- // TODO(burdon): Make reactive.
11017
- get size() {
11018
- return Object.keys(this._tree.nodes).length;
11019
- }
11020
- get root() {
11021
- return this.getNode(this._tree.root);
11022
- }
11023
- //
11024
- // Traversal
11025
- //
11026
- /**
11027
- * Recursively traverse the tree until the callback returns a value.
11028
- */
11029
- tranverse(callback, root = this._tree.root, depth = 0) {
11030
- const node = this._tree.nodes[root];
11031
- const result = callback(node, depth);
11032
- if (result !== void 0) {
11033
- return result;
11034
- }
11035
- for (const childId of node.children) {
11036
- const result2 = this.tranverse(callback, childId, depth + 1);
11037
- if (result2 !== void 0) {
11038
- return result2;
11039
- }
11040
- }
11041
- }
11042
- getNode(id) {
11043
- const node = this._tree.nodes[id];
11044
- invariant(node, void 0, {
11045
- F: __dxlog_file,
11046
- L: 98,
11047
- S: this,
11048
- A: [
11049
- "node",
11050
- ""
11051
- ]
11052
- });
11053
- return node;
11054
- }
11055
- /**
11056
- * Get the children of a node.
11057
- */
11058
- getChildNodes(node) {
11059
- return node.children.map((id) => this.getNode(id));
11060
- }
11061
- /**
11062
- * Get the parent of a node.
11063
- */
11064
- getParent(node) {
11065
- const parent = this.tranverse((n) => {
11066
- if (n.children.includes(node.id)) {
11067
- return n;
11068
- }
11069
- });
11070
- return parent ?? null;
11071
- }
11072
- /**
11073
- * Get the next node in the tree.
11074
- */
11075
- getNext(node, hierarchical = true) {
11076
- if (hierarchical && node.children.length) {
11077
- return this.getChildNodes(node)[0];
11078
- } else {
11079
- const parent = this.getParent(node);
11080
- if (parent) {
11081
- const idx = this.getChildNodes(parent).findIndex(({ id }) => id === node.id);
11082
- if (idx < parent.children.length - 1) {
11083
- return this.getNode(parent.children[idx + 1]);
11084
- } else {
11085
- return this.getNext(parent, false);
11086
- }
11087
- }
11088
- }
11089
- }
11090
- /**
11091
- * Get the previous node in the tree.
11092
- */
11093
- getPrevious(node, hierarchical = true) {
11094
- const parent = this.getParent(node);
11095
- const idx = this.getChildNodes(parent).findIndex(({ id }) => id === node.id);
11096
- if (idx === 0) {
11097
- if (hierarchical) {
11098
- return parent;
11099
- }
11100
- } else {
11101
- const previous = this.getNode(parent.children[idx - 1]);
11102
- if (hierarchical && previous.children.length) {
11103
- return this.getLastDescendent(previous);
11104
- }
11105
- return previous;
11106
- }
11107
- }
11108
- /**
11109
- * Get the last descendent of a node.
11110
- */
11111
- getLastDescendent(node) {
11112
- const children = this.getChildNodes(node);
11113
- const last = children.length ? children[children.length - 1] : void 0;
11114
- if (last) {
11115
- return this.getLastDescendent(last);
11116
- }
11117
- return node;
11118
- }
11119
- //
11120
- // Mutations
11121
- //
11122
- /**
11123
- * Clear tree.
11124
- */
11125
- clear() {
11126
- const root = this._tree.nodes[this._tree.root];
11127
- root.children.length = 0;
11128
- this._tree.nodes = {
11129
- [root.id]: root
11130
- };
11131
- }
11132
- /**
11133
- * Add node.
11134
- */
11135
- addNode(parent, node, index) {
11136
- if (!node) {
11137
- const id = Key.ObjectId.random();
11138
- node = {
11139
- id,
11140
- children: [],
11141
- data: {
11142
- text: ""
11143
- }
11144
- };
11145
- }
11146
- this._tree.nodes[node.id] = node;
11147
- parent.children.splice(index ?? parent.children.length, 0, node.id);
11148
- return node;
11149
- }
11150
- /**
11151
- * Delete node.
11152
- */
11153
- deleteNode(parent, id) {
11154
- const node = this._tree.nodes[id];
11155
- if (!node) {
11156
- return void 0;
11157
- }
11158
- delete this._tree.nodes[node.id];
11159
- const idx = parent.children.findIndex((child) => child === id);
11160
- if (idx !== -1) {
11161
- parent.children.splice(idx, 1);
11162
- }
11163
- return node;
11164
- }
11165
- /**
11166
- * Move child node.
11167
- */
11168
- moveNode(node, from, to) {
11169
- invariant(from >= 0 && from < node.children.length, void 0, {
11170
- F: __dxlog_file,
11171
- L: 228,
11172
- S: this,
11173
- A: [
11174
- "from >= 0 && from < node.children.length",
11175
- ""
11176
- ]
11177
- });
11178
- invariant(to >= 0 && to < node.children.length, void 0, {
11179
- F: __dxlog_file,
11180
- L: 229,
11181
- S: this,
11182
- A: [
11183
- "to >= 0 && to < node.children.length",
11184
- ""
11185
- ]
11186
- });
11187
- if (from === to) {
11188
- return null;
11189
- }
11190
- const child = node.children[from];
11191
- node.children.splice(from, 1);
11192
- node.children.splice(to, 0, child);
11193
- return this.getNode(child);
11194
- }
11195
- /**
11196
- * Indent node.
11197
- */
11198
- indentNode(node) {
11199
- const parent = this.getParent(node);
11200
- if (!parent) {
11201
- return;
11202
- }
11203
- const idx = parent.children.findIndex((child) => child === node.id);
11204
- if (idx < 1 || idx >= parent.children.length) {
11205
- return;
11206
- }
11207
- const previous = this.getNode(parent.children[idx - 1]);
11208
- parent.children.splice(idx, 1);
11209
- previous.children.push(node.id);
11210
- }
11211
- /**
11212
- * Unindent node.
11213
- */
11214
- unindentNode(node) {
11215
- const parent = this.getParent(node);
11216
- if (!parent) {
11217
- return;
11218
- }
11219
- const ancestor = this.getParent(parent);
11220
- if (!ancestor) {
11221
- return;
11222
- }
11223
- const nodeIdx = parent.children.findIndex((id) => id === node.id);
11224
- const [_, ...rest] = parent.children.splice(nodeIdx, parent.children.length - nodeIdx);
11225
- parent.children.splice(nodeIdx, parent.children.length - nodeIdx);
11226
- const parentIdx = this.getChildNodes(ancestor).findIndex((n) => n.id === parent.id);
11227
- ancestor.children.splice(parentIdx + 1, 0, node.id);
11228
- node.children.push(...rest);
11229
- }
11230
- constructor(tree3) {
11231
- _define_property(this, "_tree", void 0);
11232
- this._tree = tree3 ?? _Tree.create();
11233
- }
11234
- };
11235
- _define_property(Tree, "create", () => {
11236
- const id = Key.ObjectId.random();
11237
- return Obj.make(TreeType, {
11238
- root: id,
11239
- nodes: {
11240
- [id]: {
11241
- id,
11242
- children: [],
11243
- data: {
11244
- text: ""
11245
- }
11246
- }
11247
- }
11248
- });
11249
- });
11250
11160
 
11251
11161
  // src/components/Tree/types/types.ts
11252
11162
  var mapGraphToTreeData = (model, maxDepth = 8) => {
@@ -11274,68 +11184,95 @@ var renderers = /* @__PURE__ */ new Map([
11274
11184
  HierarchicalEdgeBundling_default
11275
11185
  ]
11276
11186
  ]);
11277
- var Tree2 = ({ space, selected, variant = "tidy", onNodeClick }) => {
11278
- var _effect = _useSignals3();
11279
- try {
11280
- const [model] = useAsyncState(async () => space ? new SpaceGraphModel().open(space) : void 0, [
11281
- space,
11282
- selected
11283
- ]);
11284
- const [tree3, setTree] = useState();
11285
- useEffect3(() => {
11286
- return model?.subscribe(() => {
11287
- const tree4 = mapGraphToTreeData(model);
11288
- setTree(tree4);
11289
- }, true);
11290
- }, [
11291
- model
11292
- ]);
11293
- const context = useRef(null);
11294
- useEffect3(() => {
11295
- if (context.current?.size) {
11296
- const { width, height } = context.current.size;
11297
- const size = Math.min(width, height);
11298
- const radius = size * 0.4;
11299
- const options = {
11300
- // TODO(burdon): Type.
11301
- label: (d) => d.label ?? d.id,
11302
- width,
11303
- height,
11304
- radius,
11305
- marginLeft: (width - radius * 2) / 2,
11306
- marginRight: (width - radius * 2) / 2,
11307
- marginTop: (height - radius * 2) / 2,
11308
- marginBottom: (height - radius * 2) / 2,
11309
- slots: defaultTreeLayoutSlots
11310
- };
11311
- if (tree3) {
11312
- const renderer = renderers.get(variant);
11313
- renderer?.(context.current.svg, tree3, options);
11314
- }
11187
+ var Tree = ({ space, selected, variant = "tidy", onNodeClick }) => {
11188
+ const registry = useContext(RegistryContext);
11189
+ const [model] = useAsyncState(async () => space ? new SpaceGraphModel(registry).open(space.db) : void 0, [
11190
+ space,
11191
+ selected,
11192
+ registry
11193
+ ]);
11194
+ const [tree3, setTree] = useState2();
11195
+ useEffect5(() => {
11196
+ return model?.subscribe(() => {
11197
+ const tree4 = mapGraphToTreeData(model);
11198
+ setTree(tree4);
11199
+ }, true);
11200
+ }, [
11201
+ model
11202
+ ]);
11203
+ const context = useRef3(null);
11204
+ useEffect5(() => {
11205
+ if (context.current?.size) {
11206
+ const { width, height } = context.current.size;
11207
+ const size = Math.min(width, height);
11208
+ const radius = size * 0.4;
11209
+ const options = {
11210
+ // TODO(burdon): Type.
11211
+ label: (d) => d.label ?? d.id,
11212
+ width,
11213
+ height,
11214
+ radius,
11215
+ marginLeft: (width - radius * 2) / 2,
11216
+ marginRight: (width - radius * 2) / 2,
11217
+ marginTop: (height - radius * 2) / 2,
11218
+ marginBottom: (height - radius * 2) / 2,
11219
+ slots: defaultTreeLayoutSlots
11220
+ };
11221
+ if (tree3) {
11222
+ const renderer = renderers.get(variant);
11223
+ renderer?.(context.current.svg, tree3, options);
11315
11224
  }
11316
- }, [
11317
- context.current,
11318
- tree3
11319
- ]);
11320
- return /* @__PURE__ */ React3.createElement("div", {
11321
- onClick: () => onNodeClick?.()
11322
- }, /* @__PURE__ */ React3.createElement(SVG.Root, {
11323
- ref: context
11324
- }));
11325
- } finally {
11326
- _effect.f();
11327
- }
11225
+ }
11226
+ }, [
11227
+ context.current,
11228
+ tree3
11229
+ ]);
11230
+ return /* @__PURE__ */ React5.createElement("div", {
11231
+ className: "grow",
11232
+ onClick: () => onNodeClick?.()
11233
+ }, /* @__PURE__ */ React5.createElement(SVG2.Root, {
11234
+ ref: context
11235
+ }));
11328
11236
  };
11329
11237
 
11330
- // src/components/index.ts
11331
- import { lazy } from "react";
11332
- var ExplorerContainer = lazy(() => import("./ExplorerContainer-S66JDOAF.mjs"));
11238
+ // src/hooks/useGraphModel.ts
11239
+ import { useEffect as useEffect6, useState as useState3 } from "react";
11240
+ import { Capabilities } from "@dxos/app-framework";
11241
+ import { useCapability } from "@dxos/app-framework/ui";
11242
+ import { SpaceGraphModel as SpaceGraphModel2 } from "@dxos/schema";
11243
+ var useGraphModel = (space, filter, options, queue) => {
11244
+ const registry = useCapability(Capabilities.AtomRegistry);
11245
+ const [model, setModel] = useState3(void 0);
11246
+ useEffect6(() => {
11247
+ if (!space) {
11248
+ void model?.close();
11249
+ setModel(void 0);
11250
+ return;
11251
+ }
11252
+ if (!model || model.queue !== queue) {
11253
+ const model2 = new SpaceGraphModel2(registry).setFilter(filter).setOptions(options);
11254
+ void model2.open(space.db, queue);
11255
+ setModel(model2);
11256
+ } else {
11257
+ model.setFilter(filter).setOptions(options);
11258
+ }
11259
+ }, [
11260
+ space,
11261
+ filter,
11262
+ options,
11263
+ queue,
11264
+ registry
11265
+ ]);
11266
+ return model;
11267
+ };
11333
11268
 
11334
11269
  export {
11335
11270
  Chart,
11336
11271
  Globe,
11272
+ D3ForceGraph,
11273
+ ForceGraph,
11337
11274
  defaultTreeLayoutSlots,
11338
- Tree2 as Tree,
11339
- ExplorerContainer
11275
+ Tree,
11276
+ useGraphModel
11340
11277
  };
11341
- //# sourceMappingURL=chunk-UCDNCIRV.mjs.map
11278
+ //# sourceMappingURL=chunk-6AZY4CDH.mjs.map