@dxos/plugin-explorer 0.8.4-main.72ec0f3 → 0.8.4-main.7996785055

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 (134) hide show
  1. package/dist/lib/browser/ExplorerContainer-H5RGY6AD.mjs +48 -0
  2. package/dist/lib/browser/ExplorerContainer-H5RGY6AD.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-ARBGXQFH.mjs → chunk-56VV76WZ.mjs} +354 -153
  4. package/dist/lib/{node-esm/chunk-NPIP4VEH.mjs.map → browser/chunk-56VV76WZ.mjs.map} +4 -4
  5. package/dist/lib/browser/chunk-6KEHUEEZ.mjs +71 -0
  6. package/dist/lib/browser/chunk-6KEHUEEZ.mjs.map +7 -0
  7. package/dist/lib/browser/{chunk-UBHZGWZQ.mjs → chunk-LSUP47BZ.mjs} +2 -2
  8. package/dist/lib/browser/chunk-LSUP47BZ.mjs.map +7 -0
  9. package/dist/lib/browser/index.mjs +59 -71
  10. package/dist/lib/browser/index.mjs.map +4 -4
  11. package/dist/lib/browser/meta.json +1 -1
  12. package/dist/lib/browser/meta.mjs +1 -1
  13. package/dist/lib/browser/react-surface-JYGFP5ZN.mjs +38 -0
  14. package/dist/lib/browser/react-surface-JYGFP5ZN.mjs.map +7 -0
  15. package/dist/lib/browser/types/index.mjs +1 -2
  16. package/dist/lib/node-esm/ExplorerContainer-KFHE5KU3.mjs +49 -0
  17. package/dist/lib/node-esm/ExplorerContainer-KFHE5KU3.mjs.map +7 -0
  18. package/dist/lib/node-esm/{chunk-NPIP4VEH.mjs → chunk-35JCF4SD.mjs} +354 -153
  19. package/dist/lib/{browser/chunk-ARBGXQFH.mjs.map → node-esm/chunk-35JCF4SD.mjs.map} +4 -4
  20. package/dist/lib/node-esm/{chunk-UXZM5VJB.mjs → chunk-EN3JZNEY.mjs} +2 -2
  21. package/dist/lib/node-esm/chunk-EN3JZNEY.mjs.map +7 -0
  22. package/dist/lib/node-esm/chunk-WSE2Z4OT.mjs +72 -0
  23. package/dist/lib/node-esm/chunk-WSE2Z4OT.mjs.map +7 -0
  24. package/dist/lib/node-esm/index.mjs +59 -71
  25. package/dist/lib/node-esm/index.mjs.map +4 -4
  26. package/dist/lib/node-esm/meta.json +1 -1
  27. package/dist/lib/node-esm/meta.mjs +1 -1
  28. package/dist/lib/node-esm/react-surface-HJEJL53N.mjs +39 -0
  29. package/dist/lib/node-esm/react-surface-HJEJL53N.mjs.map +7 -0
  30. package/dist/lib/node-esm/types/index.mjs +1 -2
  31. package/dist/types/src/ExplorerPlugin.d.ts +2 -1
  32. package/dist/types/src/ExplorerPlugin.d.ts.map +1 -1
  33. package/dist/types/src/capabilities/index.d.ts +1 -2
  34. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  35. package/dist/types/src/capabilities/react-surface/index.d.ts +3 -0
  36. package/dist/types/src/capabilities/react-surface/index.d.ts.map +1 -0
  37. package/dist/types/src/capabilities/react-surface/react-surface.d.ts +5 -0
  38. package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +1 -0
  39. package/dist/types/src/components/Graph/D3ForceGraph.d.ts +10 -5
  40. package/dist/types/src/components/Graph/D3ForceGraph.d.ts.map +1 -1
  41. package/dist/types/src/components/Graph/D3ForceGraph.stories.d.ts +8 -2
  42. package/dist/types/src/components/Graph/D3ForceGraph.stories.d.ts.map +1 -1
  43. package/dist/types/src/components/Graph/ForceGraph.stories.d.ts +1 -1
  44. package/dist/types/src/components/Graph/ForceGraph.stories.d.ts.map +1 -1
  45. package/dist/types/src/components/Graph/adapter.d.ts +1 -1
  46. package/dist/types/src/components/Graph/adapter.d.ts.map +1 -1
  47. package/dist/types/src/components/Graph/testing.d.ts.map +1 -1
  48. package/dist/types/src/components/Tree/Tree.d.ts.map +1 -1
  49. package/dist/types/src/components/Tree/Tree.stories.d.ts.map +1 -1
  50. package/dist/types/src/components/Tree/testing/generator.d.ts.map +1 -1
  51. package/dist/types/src/components/Tree/types/tree.d.ts +18 -16
  52. package/dist/types/src/components/Tree/types/tree.d.ts.map +1 -1
  53. package/dist/types/src/components/Tree/types/types.d.ts +1 -1
  54. package/dist/types/src/components/Tree/types/types.d.ts.map +1 -1
  55. package/dist/types/src/components/index.d.ts +0 -2
  56. package/dist/types/src/components/index.d.ts.map +1 -1
  57. package/dist/types/src/containers/ExplorerContainer/ExplorerContainer.d.ts +6 -0
  58. package/dist/types/src/containers/ExplorerContainer/ExplorerContainer.d.ts.map +1 -0
  59. package/dist/types/src/containers/ExplorerContainer/index.d.ts +3 -0
  60. package/dist/types/src/containers/ExplorerContainer/index.d.ts.map +1 -0
  61. package/dist/types/src/containers/index.d.ts +3 -0
  62. package/dist/types/src/containers/index.d.ts.map +1 -0
  63. package/dist/types/src/hooks/useGraphModel.d.ts.map +1 -1
  64. package/dist/types/src/meta.d.ts +2 -2
  65. package/dist/types/src/meta.d.ts.map +1 -1
  66. package/dist/types/src/translations.d.ts +19 -10
  67. package/dist/types/src/translations.d.ts.map +1 -1
  68. package/dist/types/src/types/ExplorerAction.d.ts +1 -18
  69. package/dist/types/src/types/ExplorerAction.d.ts.map +1 -1
  70. package/dist/types/src/types/Graph.d.ts +14 -24
  71. package/dist/types/src/types/Graph.d.ts.map +1 -1
  72. package/dist/types/tsconfig.tsbuildinfo +1 -1
  73. package/package.json +51 -46
  74. package/src/ExplorerPlugin.tsx +39 -52
  75. package/src/capabilities/index.ts +1 -4
  76. package/src/capabilities/react-surface/index.ts +7 -0
  77. package/src/capabilities/react-surface/react-surface.tsx +31 -0
  78. package/src/components/Chart/Chart.stories.tsx +3 -3
  79. package/src/components/Globe/Globe.stories.tsx +3 -3
  80. package/src/components/Graph/D3ForceGraph.stories.tsx +21 -16
  81. package/src/components/Graph/D3ForceGraph.tsx +82 -74
  82. package/src/components/Graph/ForceGraph.stories.tsx +21 -16
  83. package/src/components/Graph/adapter.ts +14 -8
  84. package/src/components/Graph/testing.ts +8 -5
  85. package/src/components/Tree/Tree.stories.tsx +7 -4
  86. package/src/components/Tree/Tree.tsx +8 -3
  87. package/src/components/Tree/testing/generator.ts +4 -2
  88. package/src/components/Tree/types/tree.test.ts +3 -1
  89. package/src/components/Tree/types/tree.ts +41 -20
  90. package/src/components/Tree/types/types.ts +1 -1
  91. package/src/components/index.ts +0 -4
  92. package/src/containers/ExplorerContainer/ExplorerContainer.tsx +53 -0
  93. package/src/containers/ExplorerContainer/index.ts +7 -0
  94. package/src/containers/index.ts +7 -0
  95. package/src/hooks/useGraphModel.ts +17 -10
  96. package/src/meta.ts +3 -3
  97. package/src/translations.ts +4 -1
  98. package/src/types/ExplorerAction.ts +9 -19
  99. package/src/types/Graph.ts +25 -22
  100. package/dist/lib/browser/ExplorerContainer-NOLLVUTE.mjs +0 -50
  101. package/dist/lib/browser/ExplorerContainer-NOLLVUTE.mjs.map +0 -7
  102. package/dist/lib/browser/chunk-2MKBRIUT.mjs +0 -31
  103. package/dist/lib/browser/chunk-2MKBRIUT.mjs.map +0 -7
  104. package/dist/lib/browser/chunk-6BVXZQPP.mjs +0 -188
  105. package/dist/lib/browser/chunk-6BVXZQPP.mjs.map +0 -7
  106. package/dist/lib/browser/chunk-JDSUIUNR.mjs +0 -80
  107. package/dist/lib/browser/chunk-JDSUIUNR.mjs.map +0 -7
  108. package/dist/lib/browser/chunk-UBHZGWZQ.mjs.map +0 -7
  109. package/dist/lib/browser/intent-resolver-YS5LZC3A.mjs +0 -31
  110. package/dist/lib/browser/intent-resolver-YS5LZC3A.mjs.map +0 -7
  111. package/dist/lib/browser/react-surface-BVTCOVLK.mjs +0 -35
  112. package/dist/lib/browser/react-surface-BVTCOVLK.mjs.map +0 -7
  113. package/dist/lib/node-esm/ExplorerContainer-N3S5KSUX.mjs +0 -51
  114. package/dist/lib/node-esm/ExplorerContainer-N3S5KSUX.mjs.map +0 -7
  115. package/dist/lib/node-esm/chunk-3ODK27PU.mjs +0 -33
  116. package/dist/lib/node-esm/chunk-3ODK27PU.mjs.map +0 -7
  117. package/dist/lib/node-esm/chunk-CRSVAZNA.mjs +0 -190
  118. package/dist/lib/node-esm/chunk-CRSVAZNA.mjs.map +0 -7
  119. package/dist/lib/node-esm/chunk-MS72BATS.mjs +0 -81
  120. package/dist/lib/node-esm/chunk-MS72BATS.mjs.map +0 -7
  121. package/dist/lib/node-esm/chunk-UXZM5VJB.mjs.map +0 -7
  122. package/dist/lib/node-esm/intent-resolver-VCEC67WX.mjs +0 -32
  123. package/dist/lib/node-esm/intent-resolver-VCEC67WX.mjs.map +0 -7
  124. package/dist/lib/node-esm/react-surface-4HFEX52O.mjs +0 -36
  125. package/dist/lib/node-esm/react-surface-4HFEX52O.mjs.map +0 -7
  126. package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
  127. package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
  128. package/dist/types/src/capabilities/react-surface.d.ts +0 -4
  129. package/dist/types/src/capabilities/react-surface.d.ts.map +0 -1
  130. package/dist/types/src/components/ExplorerContainer.d.ts +0 -9
  131. package/dist/types/src/components/ExplorerContainer.d.ts.map +0 -1
  132. package/src/capabilities/intent-resolver.ts +0 -21
  133. package/src/capabilities/react-surface.tsx +0 -27
  134. package/src/components/ExplorerContainer.tsx +0 -54
@@ -0,0 +1,48 @@
1
+ import {
2
+ D3ForceGraph,
3
+ useGraphModel
4
+ } from "./chunk-56VV76WZ.mjs";
5
+ import "./chunk-J5LGTIGS.mjs";
6
+
7
+ // src/containers/ExplorerContainer/ExplorerContainer.tsx
8
+ import React, { useCallback, useMemo, useState } from "react";
9
+ import { QueryBuilder } from "@dxos/echo-query";
10
+ import { useGlobalSearch } from "@dxos/plugin-search";
11
+ import { getSpace, useObject } from "@dxos/react-client/echo";
12
+ import { Panel, Toolbar } from "@dxos/react-ui";
13
+ import { QueryEditor } from "@dxos/react-ui-components";
14
+ var ExplorerContainer = ({ role, subject: view }) => {
15
+ useObject(view);
16
+ const space = view && getSpace(view);
17
+ const [filter, setFilter] = useState();
18
+ const model = useGraphModel(space, filter);
19
+ const { match } = useGlobalSearch();
20
+ const builder = useMemo(() => new QueryBuilder(), []);
21
+ const handleChange = useCallback((value) => {
22
+ setFilter(builder.build(value).filter);
23
+ }, []);
24
+ const showToolbar = role === "article";
25
+ if (!space || !model) {
26
+ return null;
27
+ }
28
+ return /* @__PURE__ */ React.createElement(Panel.Root, {
29
+ role
30
+ }, showToolbar && /* @__PURE__ */ React.createElement(Panel.Toolbar, {
31
+ asChild: true
32
+ }, /* @__PURE__ */ React.createElement(Toolbar.Root, null, /* @__PURE__ */ React.createElement(QueryEditor, {
33
+ db: space.db,
34
+ onChange: handleChange
35
+ }))), /* @__PURE__ */ React.createElement(Panel.Content, {
36
+ asChild: true
37
+ }, /* @__PURE__ */ React.createElement(D3ForceGraph, {
38
+ model,
39
+ match
40
+ })));
41
+ };
42
+
43
+ // src/containers/ExplorerContainer/index.ts
44
+ var ExplorerContainer_default = ExplorerContainer;
45
+ export {
46
+ ExplorerContainer_default as default
47
+ };
48
+ //# sourceMappingURL=ExplorerContainer-H5RGY6AD.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/containers/ExplorerContainer/ExplorerContainer.tsx", "../../../src/containers/ExplorerContainer/index.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport React, { useCallback, useMemo, useState } from 'react';\n\nimport { type SurfaceComponentProps } from '@dxos/app-toolkit/ui';\nimport { type Filter } from '@dxos/echo';\nimport { type View } from '@dxos/echo';\nimport { QueryBuilder } from '@dxos/echo-query';\nimport { useGlobalSearch } from '@dxos/plugin-search';\nimport { getSpace, useObject } from '@dxos/react-client/echo';\nimport { Panel, Toolbar } from '@dxos/react-ui';\nimport { QueryEditor, type QueryEditorProps } from '@dxos/react-ui-components';\n\nimport { D3ForceGraph } from '../../components';\nimport { useGraphModel } from '../../hooks';\n\nexport type ExplorerContainerProps = SurfaceComponentProps<View.View>;\n\nexport const ExplorerContainer = ({ role, subject: view }: ExplorerContainerProps) => {\n useObject(view);\n const space = view && getSpace(view);\n const [filter, setFilter] = useState<Filter.Any>();\n const model = useGraphModel(space, filter);\n const { match } = useGlobalSearch();\n\n const builder = useMemo(() => new QueryBuilder(), []);\n const handleChange = useCallback<NonNullable<QueryEditorProps['onChange']>>((value) => {\n setFilter(builder.build(value).filter);\n }, []);\n\n const showToolbar = role === 'article';\n\n if (!space || !model) {\n return null;\n }\n\n return (\n <Panel.Root role={role}>\n {showToolbar && (\n <Panel.Toolbar asChild>\n <Toolbar.Root>\n <QueryEditor db={space.db} onChange={handleChange} />\n </Toolbar.Root>\n </Panel.Toolbar>\n )}\n <Panel.Content asChild>\n <D3ForceGraph model={model} match={match} />\n </Panel.Content>\n </Panel.Root>\n );\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { ExplorerContainer } from './ExplorerContainer';\n\nexport default ExplorerContainer;\n"],
5
+ "mappings": ";;;;;;;AAIA,OAAOA,SAASC,aAAaC,SAASC,gBAAgB;AAKtD,SAASC,oBAAoB;AAC7B,SAASC,uBAAuB;AAChC,SAASC,UAAUC,iBAAiB;AACpC,SAASC,OAAOC,eAAe;AAC/B,SAASC,mBAA0C;AAO5C,IAAMC,oBAAoB,CAAC,EAAEC,MAAMC,SAASC,KAAI,MAA0B;AAC/EC,YAAUD,IAAAA;AACV,QAAME,QAAQF,QAAQG,SAASH,IAAAA;AAC/B,QAAM,CAACI,QAAQC,SAAAA,IAAaC,SAAAA;AAC5B,QAAMC,QAAQC,cAAcN,OAAOE,MAAAA;AACnC,QAAM,EAAEK,MAAK,IAAKC,gBAAAA;AAElB,QAAMC,UAAUC,QAAQ,MAAM,IAAIC,aAAAA,GAAgB,CAAA,CAAE;AACpD,QAAMC,eAAeC,YAAuD,CAACC,UAAAA;AAC3EX,cAAUM,QAAQM,MAAMD,KAAAA,EAAOZ,MAAM;EACvC,GAAG,CAAA,CAAE;AAEL,QAAMc,cAAcpB,SAAS;AAE7B,MAAI,CAACI,SAAS,CAACK,OAAO;AACpB,WAAO;EACT;AAEA,SACE,sBAAA,cAACY,MAAMC,MAAI;IAACtB;KACToB,eACC,sBAAA,cAACC,MAAME,SAAO;IAACC,SAAAA;KACb,sBAAA,cAACD,QAAQD,MAAI,MACX,sBAAA,cAACG,aAAAA;IAAYC,IAAItB,MAAMsB;IAAIC,UAAUX;QAI3C,sBAAA,cAACK,MAAMO,SAAO;IAACJ,SAAAA;KACb,sBAAA,cAACK,cAAAA;IAAapB;IAAcE;;AAIpC;;;AC9CA,IAAA,4BAAemB;",
6
+ "names": ["React", "useCallback", "useMemo", "useState", "QueryBuilder", "useGlobalSearch", "getSpace", "useObject", "Panel", "Toolbar", "QueryEditor", "ExplorerContainer", "role", "subject", "view", "useObject", "space", "getSpace", "filter", "setFilter", "useState", "model", "useGraphModel", "match", "useGlobalSearch", "builder", "useMemo", "QueryBuilder", "handleChange", "useCallback", "value", "build", "showToolbar", "Panel", "Root", "Toolbar", "asChild", "QueryEditor", "db", "onChange", "Content", "D3ForceGraph", "ExplorerContainer"]
7
+ }
@@ -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,246 @@ 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 { Atom, useAtomValue } from "@effect-atom/atom-react";
10825
+ import React3, { useCallback, useEffect as useEffect3, useMemo, useRef } from "react";
10826
+ import { Obj } from "@dxos/echo";
10827
+ import { SelectionModel } from "@dxos/graph";
10828
+ import { GraphForceProjector, SVG } from "@dxos/react-ui-graph";
10829
+ import { composable, composableProps, getHashStyles } from "@dxos/ui-theme";
10830
+ import "@dxos/react-ui-graph/styles/graph.css";
10831
+ var EMPTY_ATOM = Atom.make({
10832
+ nodes: [],
10833
+ edges: []
10834
+ });
10835
+ var D3ForceGraph = composable(({ model, selection: _selection, grid, drag, ...props }, forwardedRef) => {
10836
+ useAtomValue(model?.graphAtom ?? EMPTY_ATOM);
10837
+ const svgRef = useRef(null);
10838
+ const projector = useMemo(() => {
10839
+ if (svgRef.current) {
10840
+ return new GraphForceProjector(svgRef.current, {
10841
+ attributes: {
10842
+ linkForce: (edge) => {
10843
+ return edge.data?.object?.active !== false;
10844
+ }
10845
+ },
10846
+ forces: {
10847
+ point: {
10848
+ strength: 0.01
10849
+ }
10850
+ }
10851
+ });
10852
+ }
10853
+ }, []);
10854
+ const graph = useRef(null);
10855
+ const selection = useMemo(() => _selection ?? new SelectionModel(), [
10856
+ _selection
10857
+ ]);
10858
+ useEffect3(() => selection.subscribe(() => graph.current?.repaint()), [
10859
+ selection
10860
+ ]);
10861
+ const handleSelect = useCallback((node) => {
10862
+ if (selection.contains(node.id)) {
10863
+ selection.remove(node.id);
10864
+ } else {
10865
+ selection.add(node.id);
10866
+ }
10867
+ }, [
10868
+ selection
10869
+ ]);
10870
+ return /* @__PURE__ */ React3.createElement("div", {
10871
+ ...composableProps(props, {
10872
+ role: "none",
10873
+ classNames: "dx-container"
10874
+ }),
10875
+ ref: forwardedRef
10876
+ }, /* @__PURE__ */ React3.createElement(SVG.Root, {
10877
+ ref: svgRef
10878
+ }, /* @__PURE__ */ React3.createElement(SVG.Markers, null), grid && /* @__PURE__ */ React3.createElement(SVG.Grid, {
10879
+ axis: true
10880
+ }), /* @__PURE__ */ React3.createElement(SVG.Zoom, {
10881
+ extent: [
10882
+ 1 / 2,
10883
+ 2
10884
+ ]
10885
+ }, /* @__PURE__ */ React3.createElement(SVG.Graph, {
10886
+ drag,
10887
+ ref: graph,
10888
+ model,
10889
+ projector,
10890
+ labels: {
10891
+ text: (node) => {
10892
+ return node.data?.data.label ?? node.id;
10893
+ }
10894
+ },
10895
+ attributes: {
10896
+ node: (node) => {
10897
+ const obj = node.data?.data.object;
10898
+ return {
10899
+ data: {
10900
+ color: getHashStyles(obj && Obj.getTypename(obj))?.hue
10901
+ },
10902
+ classes: {
10903
+ "dx-selected": selection.contains(node.id)
10904
+ }
10905
+ };
10906
+ }
10907
+ },
10908
+ onSelect: handleSelect
10909
+ }))));
10910
+ });
10911
+
10912
+ // src/components/Graph/ForceGraph.tsx
10913
+ import { forceLink, forceManyBody } from "d3";
10914
+ import NativeForceGraph from "force-graph";
10915
+ import React4, { useEffect as useEffect4, useRef as useRef2, useState } from "react";
10916
+ import { useResizeDetector as useResizeDetector3 } from "react-resize-detector";
10917
+ import { filterObjectsSync } from "@dxos/plugin-search";
10918
+
10919
+ // src/components/Graph/adapter.ts
10920
+ var GraphAdapter = class {
10921
+ graph;
10922
+ _nodes = [];
10923
+ _links = [];
10924
+ constructor(graph) {
10925
+ this.graph = graph;
10926
+ this._nodes = graph.nodes.map((node) => ({
10927
+ id: node.id,
10928
+ type: node.type,
10929
+ data: node.data
10930
+ }));
10931
+ const nodeIds = new Set(this._nodes.map((node) => node.id));
10932
+ this._links = graph.edges.filter((edge) => nodeIds.has(edge.source) && nodeIds.has(edge.target)).map((edge) => ({
10933
+ type: edge.type,
10934
+ source: edge.source,
10935
+ target: edge.target,
10936
+ data: edge.data
10937
+ }));
10938
+ }
10939
+ get nodes() {
10940
+ return this._nodes;
10941
+ }
10942
+ get links() {
10943
+ return this._links;
10832
10944
  }
10833
10945
  };
10834
10946
 
10947
+ // src/components/Graph/ForceGraph.tsx
10948
+ var ForceGraph = ({ model, match }) => {
10949
+ const { ref, width, height } = useResizeDetector3({
10950
+ refreshRate: 200
10951
+ });
10952
+ const rootRef = useRef2(null);
10953
+ const forceGraph = useRef2(null);
10954
+ const filteredRef = useRef2([]);
10955
+ filteredRef.current = filterObjectsSync(model?.objects ?? [], match);
10956
+ const [data, setData] = useState();
10957
+ useEffect4(() => {
10958
+ return model?.subscribe((model2) => {
10959
+ setData(new GraphAdapter(model2.graph));
10960
+ });
10961
+ }, [
10962
+ model
10963
+ ]);
10964
+ useEffect4(() => {
10965
+ if (rootRef.current) {
10966
+ 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);
10967
+ }
10968
+ return () => {
10969
+ forceGraph.current?.pauseAnimation().graphData({
10970
+ nodes: [],
10971
+ links: []
10972
+ });
10973
+ forceGraph.current = null;
10974
+ };
10975
+ }, []);
10976
+ useEffect4(() => {
10977
+ if (!data || !width || !height || !forceGraph.current) {
10978
+ return;
10979
+ }
10980
+ forceGraph.current.pauseAnimation().width(width).height(height).onEngineStop(() => {
10981
+ handleZoomToFit();
10982
+ }).onNodeClick((node) => {
10983
+ forceGraph.current?.emitParticle(node);
10984
+ }).d3Force("link", forceLink().distance(160).strength(0.5)).d3Force("charge", forceManyBody().strength(-30)).graphData(data).warmupTicks(100).cooldownTime(1e3).resumeAnimation();
10985
+ }, [
10986
+ data,
10987
+ width,
10988
+ height,
10989
+ forceGraph.current
10990
+ ]);
10991
+ const handleZoomToFit = () => {
10992
+ forceGraph.current?.zoomToFit(400, 40);
10993
+ };
10994
+ return /* @__PURE__ */ React4.createElement("div", {
10995
+ ref,
10996
+ className: "relative grow",
10997
+ onClick: handleZoomToFit
10998
+ }, /* @__PURE__ */ React4.createElement("div", {
10999
+ ref: rootRef,
11000
+ className: "absolute inset-0"
11001
+ }));
11002
+ };
11003
+
10835
11004
  // 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";
11005
+ import { RegistryContext } from "@effect-atom/atom-react";
11006
+ import React5, { useContext, useEffect as useEffect5, useRef as useRef3, useState as useState2 } from "react";
10838
11007
  import { useAsyncState } from "@dxos/react-ui";
10839
- import { SVG } from "@dxos/react-ui-graph";
11008
+ import { SVG as SVG2 } from "@dxos/react-ui-graph";
10840
11009
  import { SpaceGraphModel } from "@dxos/schema";
10841
11010
 
10842
11011
  // src/components/Tree/layout/HierarchicalEdgeBundling.ts
@@ -10974,7 +11143,8 @@ var TidyTree_default = TidyTree;
10974
11143
 
10975
11144
  // src/components/Tree/types/tree.ts
10976
11145
  import * as Schema from "effect/Schema";
10977
- import { Key, Obj, Type } from "@dxos/echo";
11146
+ import { Key, Obj as Obj2, Ref, Type } from "@dxos/echo";
11147
+ import { TestSchema } from "@dxos/echo/testing";
10978
11148
  import { invariant } from "@dxos/invariant";
10979
11149
  var TreeNodeType = Schema.Struct({
10980
11150
  id: Key.ObjectId,
@@ -10983,7 +11153,7 @@ var TreeNodeType = Schema.Struct({
10983
11153
  key: Schema.String,
10984
11154
  value: Schema.Any
10985
11155
  })),
10986
- ref: Schema.optional(Type.Ref(Type.Expando))
11156
+ ref: Schema.optional(Ref.Ref(TestSchema.Expando))
10987
11157
  }).pipe(Schema.mutable);
10988
11158
  var TreeType = Schema.Struct({
10989
11159
  root: Key.ObjectId,
@@ -10991,8 +11161,8 @@ var TreeType = Schema.Struct({
10991
11161
  key: Key.ObjectId,
10992
11162
  value: TreeNodeType
10993
11163
  }))
10994
- }).pipe(Type.Obj({
10995
- typename: "dxos.org/type/Tree",
11164
+ }).pipe(Type.object({
11165
+ typename: "org.dxos.type.tree",
10996
11166
  version: "0.1.0"
10997
11167
  }));
10998
11168
 
@@ -11023,67 +11193,98 @@ var renderers = /* @__PURE__ */ new Map([
11023
11193
  ]
11024
11194
  ]);
11025
11195
  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
- }
11196
+ const registry = useContext(RegistryContext);
11197
+ const [model] = useAsyncState(async () => space ? new SpaceGraphModel(registry).open(space.db) : void 0, [
11198
+ space,
11199
+ selected,
11200
+ registry
11201
+ ]);
11202
+ const [tree3, setTree] = useState2();
11203
+ useEffect5(() => {
11204
+ return model?.subscribe(() => {
11205
+ const tree4 = mapGraphToTreeData(model);
11206
+ setTree(tree4);
11207
+ }, true);
11208
+ }, [
11209
+ model
11210
+ ]);
11211
+ const context = useRef3(null);
11212
+ useEffect5(() => {
11213
+ if (context.current?.size) {
11214
+ const { width, height } = context.current.size;
11215
+ const size = Math.min(width, height);
11216
+ const radius = size * 0.4;
11217
+ const options = {
11218
+ // TODO(burdon): Type.
11219
+ label: (d) => d.label ?? d.id,
11220
+ width,
11221
+ height,
11222
+ radius,
11223
+ marginLeft: (width - radius * 2) / 2,
11224
+ marginRight: (width - radius * 2) / 2,
11225
+ marginTop: (height - radius * 2) / 2,
11226
+ marginBottom: (height - radius * 2) / 2,
11227
+ slots: defaultTreeLayoutSlots
11228
+ };
11229
+ if (tree3) {
11230
+ const renderer = renderers.get(variant);
11231
+ renderer?.(context.current.svg, tree3, options);
11063
11232
  }
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();
11075
- }
11233
+ }
11234
+ }, [
11235
+ context.current,
11236
+ tree3
11237
+ ]);
11238
+ return /* @__PURE__ */ React5.createElement("div", {
11239
+ className: "grow",
11240
+ onClick: () => onNodeClick?.()
11241
+ }, /* @__PURE__ */ React5.createElement(SVG2.Root, {
11242
+ ref: context
11243
+ }));
11076
11244
  };
11077
11245
 
11078
- // src/components/index.ts
11079
- import { lazy } from "react";
11080
- var ExplorerContainer = lazy(() => import("./ExplorerContainer-NOLLVUTE.mjs"));
11246
+ // src/hooks/useGraphModel.ts
11247
+ import { useEffect as useEffect6, useState as useState3 } from "react";
11248
+ import { Capabilities } from "@dxos/app-framework";
11249
+ import { useCapability } from "@dxos/app-framework/ui";
11250
+ import { SpaceGraphModel as SpaceGraphModel2 } from "@dxos/schema";
11251
+ var useGraphModel = (space, filter, options, queue) => {
11252
+ const registry = useCapability(Capabilities.AtomRegistry);
11253
+ const [model, setModel] = useState3(void 0);
11254
+ useEffect6(() => {
11255
+ if (!space) {
11256
+ setModel(void 0);
11257
+ return;
11258
+ }
11259
+ const newModel = new SpaceGraphModel2(registry);
11260
+ void newModel.open(space.db, queue);
11261
+ setModel(newModel);
11262
+ return () => {
11263
+ setModel(void 0);
11264
+ void newModel.close();
11265
+ };
11266
+ }, [
11267
+ space,
11268
+ registry,
11269
+ queue
11270
+ ]);
11271
+ useEffect6(() => {
11272
+ model?.setFilter(filter).setOptions(options);
11273
+ }, [
11274
+ model,
11275
+ filter,
11276
+ options
11277
+ ]);
11278
+ return model;
11279
+ };
11081
11280
 
11082
11281
  export {
11083
11282
  Chart,
11084
11283
  Globe,
11284
+ D3ForceGraph,
11285
+ ForceGraph,
11085
11286
  defaultTreeLayoutSlots,
11086
11287
  Tree,
11087
- ExplorerContainer
11288
+ useGraphModel
11088
11289
  };
11089
- //# sourceMappingURL=chunk-ARBGXQFH.mjs.map
11290
+ //# sourceMappingURL=chunk-56VV76WZ.mjs.map