@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,49 @@
1
+ import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
+ import {
3
+ D3ForceGraph,
4
+ useGraphModel
5
+ } from "./chunk-35JCF4SD.mjs";
6
+ import "./chunk-HSLMI22Q.mjs";
7
+
8
+ // src/containers/ExplorerContainer/ExplorerContainer.tsx
9
+ import React, { useCallback, useMemo, useState } from "react";
10
+ import { QueryBuilder } from "@dxos/echo-query";
11
+ import { useGlobalSearch } from "@dxos/plugin-search";
12
+ import { getSpace, useObject } from "@dxos/react-client/echo";
13
+ import { Panel, Toolbar } from "@dxos/react-ui";
14
+ import { QueryEditor } from "@dxos/react-ui-components";
15
+ var ExplorerContainer = ({ role, subject: view }) => {
16
+ useObject(view);
17
+ const space = view && getSpace(view);
18
+ const [filter, setFilter] = useState();
19
+ const model = useGraphModel(space, filter);
20
+ const { match } = useGlobalSearch();
21
+ const builder = useMemo(() => new QueryBuilder(), []);
22
+ const handleChange = useCallback((value) => {
23
+ setFilter(builder.build(value).filter);
24
+ }, []);
25
+ const showToolbar = role === "article";
26
+ if (!space || !model) {
27
+ return null;
28
+ }
29
+ return /* @__PURE__ */ React.createElement(Panel.Root, {
30
+ role
31
+ }, showToolbar && /* @__PURE__ */ React.createElement(Panel.Toolbar, {
32
+ asChild: true
33
+ }, /* @__PURE__ */ React.createElement(Toolbar.Root, null, /* @__PURE__ */ React.createElement(QueryEditor, {
34
+ db: space.db,
35
+ onChange: handleChange
36
+ }))), /* @__PURE__ */ React.createElement(Panel.Content, {
37
+ asChild: true
38
+ }, /* @__PURE__ */ React.createElement(D3ForceGraph, {
39
+ model,
40
+ match
41
+ })));
42
+ };
43
+
44
+ // src/containers/ExplorerContainer/index.ts
45
+ var ExplorerContainer_default = ExplorerContainer;
46
+ export {
47
+ ExplorerContainer_default as default
48
+ };
49
+ //# sourceMappingURL=ExplorerContainer-KFHE5KU3.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,7 +1,6 @@
1
1
  import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
2
 
3
3
  // src/components/Chart/Chart.tsx
4
- import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
5
4
  import * as Plot from "@observablehq/plot";
6
5
  import React, { useEffect } from "react";
7
6
  import { useResizeDetector } from "react-resize-detector";
@@ -19,49 +18,43 @@ var defaultOptions = {
19
18
  fillOpacity: 0.2
20
19
  };
21
20
  var Chart = ({ items = [], accessor, options = defaultOptions }) => {
22
- var _effect = _useSignals();
23
- try {
24
- const { ref: containerRef, width = 0, height = 0 } = useResizeDetector({
25
- refreshRate: 200
26
- });
27
- useEffect(() => {
28
- if (!width || !height) {
29
- return;
30
- }
31
- const plot3 = Plot.plot({
32
- grid: true,
33
- width,
34
- height,
35
- style: {
36
- background: "transparent"
37
- },
38
- marks: [
39
- Plot.frame(),
40
- Plot.dot(items, {
41
- x: createAdapter("x", accessor),
42
- y: createAdapter("y", accessor),
43
- ...options
44
- })
45
- ]
46
- });
47
- containerRef.current.append(plot3);
48
- return () => plot3?.remove();
49
- }, [
50
- 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,
51
30
  width,
52
- height
53
- ]);
54
- return /* @__PURE__ */ React.createElement("div", {
55
- ref: containerRef,
56
- 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
+ ]
57
43
  });
58
- } finally {
59
- _effect.f();
60
- }
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
+ });
61
55
  };
62
56
 
63
57
  // src/components/Globe/Globe.tsx
64
- import { useSignals as _useSignals2 } from "@preact-signals/safe-react/tracking";
65
58
  import * as Plot2 from "@observablehq/plot";
66
59
  import React2, { useEffect as useEffect2 } from "react";
67
60
  import { useResizeDetector as useResizeDetector2 } from "react-resize-detector";
@@ -10775,70 +10768,246 @@ var defaultOptions2 = {
10775
10768
  fill: "#003300"
10776
10769
  };
10777
10770
  var Globe = ({ items = [], accessor, projection = "orthographic", options = defaultOptions2 }) => {
10778
- var _effect = _useSignals2();
10779
- try {
10780
- const { ref: containerRef, width = 0, height = 0 } = useResizeDetector2({
10781
- refreshRate: 200
10782
- });
10783
- const land = topojson.feature(countries_110m_default, countries_110m_default.objects.land);
10784
- useEffect2(() => {
10785
- if (!width || !height) {
10786
- return;
10787
- }
10788
- const plot3 = Plot2.plot({
10789
- // https://observablehq.com/plot/features/projections
10790
- projection: {
10791
- type: projection,
10792
- rotate: [
10793
- -100,
10794
- -20
10795
- ]
10796
- },
10797
- // projection: { type: 'equirectangular', rotate: [-140, -30] },
10798
- width,
10799
- height,
10800
- style: {
10801
- background: "transparent"
10802
- },
10803
- // TODO(burdon): Create simple wrapper for Plot with good defaults.
10804
- marks: [
10805
- Plot2.sphere({
10806
- fill: "lightblue",
10807
- fillOpacity: 0.5
10808
- }),
10809
- Plot2.geo(land, {
10810
- fill: "darkgreen",
10811
- fillOpacity: 0.5
10812
- }),
10813
- Plot2.graticule(),
10814
- Plot2.dot(items, {
10815
- x: createAdapter("lat", accessor),
10816
- y: createAdapter("lng", accessor),
10817
- ...options
10818
- })
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
10819
10786
  ]
10820
- });
10821
- containerRef.current.append(plot3);
10822
- return () => plot3?.remove();
10823
- }, [
10824
- items,
10787
+ },
10788
+ // projection: { type: 'equirectangular', rotate: [-140, -30] },
10825
10789
  width,
10826
- height
10827
- ]);
10828
- return /* @__PURE__ */ React2.createElement("div", {
10829
- ref: containerRef,
10830
- 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
+ ]
10831
10811
  });
10832
- } finally {
10833
- _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/D3ForceGraph.tsx
10826
+ import { Atom, useAtomValue } from "@effect-atom/atom-react";
10827
+ import React3, { useCallback, useEffect as useEffect3, useMemo, useRef } from "react";
10828
+ import { Obj } from "@dxos/echo";
10829
+ import { SelectionModel } from "@dxos/graph";
10830
+ import { GraphForceProjector, SVG } from "@dxos/react-ui-graph";
10831
+ import { composable, composableProps, getHashStyles } from "@dxos/ui-theme";
10832
+ import "@dxos/react-ui-graph/styles/graph.css";
10833
+ var EMPTY_ATOM = Atom.make({
10834
+ nodes: [],
10835
+ edges: []
10836
+ });
10837
+ var D3ForceGraph = composable(({ model, selection: _selection, grid, drag, ...props }, forwardedRef) => {
10838
+ useAtomValue(model?.graphAtom ?? EMPTY_ATOM);
10839
+ const svgRef = useRef(null);
10840
+ const projector = useMemo(() => {
10841
+ if (svgRef.current) {
10842
+ return new GraphForceProjector(svgRef.current, {
10843
+ attributes: {
10844
+ linkForce: (edge) => {
10845
+ return edge.data?.object?.active !== false;
10846
+ }
10847
+ },
10848
+ forces: {
10849
+ point: {
10850
+ strength: 0.01
10851
+ }
10852
+ }
10853
+ });
10854
+ }
10855
+ }, []);
10856
+ const graph = useRef(null);
10857
+ const selection = useMemo(() => _selection ?? new SelectionModel(), [
10858
+ _selection
10859
+ ]);
10860
+ useEffect3(() => selection.subscribe(() => graph.current?.repaint()), [
10861
+ selection
10862
+ ]);
10863
+ const handleSelect = useCallback((node) => {
10864
+ if (selection.contains(node.id)) {
10865
+ selection.remove(node.id);
10866
+ } else {
10867
+ selection.add(node.id);
10868
+ }
10869
+ }, [
10870
+ selection
10871
+ ]);
10872
+ return /* @__PURE__ */ React3.createElement("div", {
10873
+ ...composableProps(props, {
10874
+ role: "none",
10875
+ classNames: "dx-container"
10876
+ }),
10877
+ ref: forwardedRef
10878
+ }, /* @__PURE__ */ React3.createElement(SVG.Root, {
10879
+ ref: svgRef
10880
+ }, /* @__PURE__ */ React3.createElement(SVG.Markers, null), grid && /* @__PURE__ */ React3.createElement(SVG.Grid, {
10881
+ axis: true
10882
+ }), /* @__PURE__ */ React3.createElement(SVG.Zoom, {
10883
+ extent: [
10884
+ 1 / 2,
10885
+ 2
10886
+ ]
10887
+ }, /* @__PURE__ */ React3.createElement(SVG.Graph, {
10888
+ drag,
10889
+ ref: graph,
10890
+ model,
10891
+ projector,
10892
+ labels: {
10893
+ text: (node) => {
10894
+ return node.data?.data.label ?? node.id;
10895
+ }
10896
+ },
10897
+ attributes: {
10898
+ node: (node) => {
10899
+ const obj = node.data?.data.object;
10900
+ return {
10901
+ data: {
10902
+ color: getHashStyles(obj && Obj.getTypename(obj))?.hue
10903
+ },
10904
+ classes: {
10905
+ "dx-selected": selection.contains(node.id)
10906
+ }
10907
+ };
10908
+ }
10909
+ },
10910
+ onSelect: handleSelect
10911
+ }))));
10912
+ });
10913
+
10914
+ // src/components/Graph/ForceGraph.tsx
10915
+ import { forceLink, forceManyBody } from "d3";
10916
+ import NativeForceGraph from "force-graph";
10917
+ import React4, { useEffect as useEffect4, useRef as useRef2, useState } from "react";
10918
+ import { useResizeDetector as useResizeDetector3 } from "react-resize-detector";
10919
+ import { filterObjectsSync } from "@dxos/plugin-search";
10920
+
10921
+ // src/components/Graph/adapter.ts
10922
+ var GraphAdapter = class {
10923
+ graph;
10924
+ _nodes = [];
10925
+ _links = [];
10926
+ constructor(graph) {
10927
+ this.graph = graph;
10928
+ this._nodes = graph.nodes.map((node) => ({
10929
+ id: node.id,
10930
+ type: node.type,
10931
+ data: node.data
10932
+ }));
10933
+ const nodeIds = new Set(this._nodes.map((node) => node.id));
10934
+ this._links = graph.edges.filter((edge) => nodeIds.has(edge.source) && nodeIds.has(edge.target)).map((edge) => ({
10935
+ type: edge.type,
10936
+ source: edge.source,
10937
+ target: edge.target,
10938
+ data: edge.data
10939
+ }));
10940
+ }
10941
+ get nodes() {
10942
+ return this._nodes;
10943
+ }
10944
+ get links() {
10945
+ return this._links;
10834
10946
  }
10835
10947
  };
10836
10948
 
10949
+ // src/components/Graph/ForceGraph.tsx
10950
+ var ForceGraph = ({ model, match }) => {
10951
+ const { ref, width, height } = useResizeDetector3({
10952
+ refreshRate: 200
10953
+ });
10954
+ const rootRef = useRef2(null);
10955
+ const forceGraph = useRef2(null);
10956
+ const filteredRef = useRef2([]);
10957
+ filteredRef.current = filterObjectsSync(model?.objects ?? [], match);
10958
+ const [data, setData] = useState();
10959
+ useEffect4(() => {
10960
+ return model?.subscribe((model2) => {
10961
+ setData(new GraphAdapter(model2.graph));
10962
+ });
10963
+ }, [
10964
+ model
10965
+ ]);
10966
+ useEffect4(() => {
10967
+ if (rootRef.current) {
10968
+ 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);
10969
+ }
10970
+ return () => {
10971
+ forceGraph.current?.pauseAnimation().graphData({
10972
+ nodes: [],
10973
+ links: []
10974
+ });
10975
+ forceGraph.current = null;
10976
+ };
10977
+ }, []);
10978
+ useEffect4(() => {
10979
+ if (!data || !width || !height || !forceGraph.current) {
10980
+ return;
10981
+ }
10982
+ forceGraph.current.pauseAnimation().width(width).height(height).onEngineStop(() => {
10983
+ handleZoomToFit();
10984
+ }).onNodeClick((node) => {
10985
+ forceGraph.current?.emitParticle(node);
10986
+ }).d3Force("link", forceLink().distance(160).strength(0.5)).d3Force("charge", forceManyBody().strength(-30)).graphData(data).warmupTicks(100).cooldownTime(1e3).resumeAnimation();
10987
+ }, [
10988
+ data,
10989
+ width,
10990
+ height,
10991
+ forceGraph.current
10992
+ ]);
10993
+ const handleZoomToFit = () => {
10994
+ forceGraph.current?.zoomToFit(400, 40);
10995
+ };
10996
+ return /* @__PURE__ */ React4.createElement("div", {
10997
+ ref,
10998
+ className: "relative grow",
10999
+ onClick: handleZoomToFit
11000
+ }, /* @__PURE__ */ React4.createElement("div", {
11001
+ ref: rootRef,
11002
+ className: "absolute inset-0"
11003
+ }));
11004
+ };
11005
+
10837
11006
  // src/components/Tree/Tree.tsx
10838
- import { useSignals as _useSignals3 } from "@preact-signals/safe-react/tracking";
10839
- import React3, { useEffect as useEffect3, useRef, useState } from "react";
11007
+ import { RegistryContext } from "@effect-atom/atom-react";
11008
+ import React5, { useContext, useEffect as useEffect5, useRef as useRef3, useState as useState2 } from "react";
10840
11009
  import { useAsyncState } from "@dxos/react-ui";
10841
- import { SVG } from "@dxos/react-ui-graph";
11010
+ import { SVG as SVG2 } from "@dxos/react-ui-graph";
10842
11011
  import { SpaceGraphModel } from "@dxos/schema";
10843
11012
 
10844
11013
  // src/components/Tree/layout/HierarchicalEdgeBundling.ts
@@ -10976,7 +11145,8 @@ var TidyTree_default = TidyTree;
10976
11145
 
10977
11146
  // src/components/Tree/types/tree.ts
10978
11147
  import * as Schema from "effect/Schema";
10979
- import { Key, Obj, Type } from "@dxos/echo";
11148
+ import { Key, Obj as Obj2, Ref, Type } from "@dxos/echo";
11149
+ import { TestSchema } from "@dxos/echo/testing";
10980
11150
  import { invariant } from "@dxos/invariant";
10981
11151
  var TreeNodeType = Schema.Struct({
10982
11152
  id: Key.ObjectId,
@@ -10985,7 +11155,7 @@ var TreeNodeType = Schema.Struct({
10985
11155
  key: Schema.String,
10986
11156
  value: Schema.Any
10987
11157
  })),
10988
- ref: Schema.optional(Type.Ref(Type.Expando))
11158
+ ref: Schema.optional(Ref.Ref(TestSchema.Expando))
10989
11159
  }).pipe(Schema.mutable);
10990
11160
  var TreeType = Schema.Struct({
10991
11161
  root: Key.ObjectId,
@@ -10993,8 +11163,8 @@ var TreeType = Schema.Struct({
10993
11163
  key: Key.ObjectId,
10994
11164
  value: TreeNodeType
10995
11165
  }))
10996
- }).pipe(Type.Obj({
10997
- typename: "dxos.org/type/Tree",
11166
+ }).pipe(Type.object({
11167
+ typename: "org.dxos.type.tree",
10998
11168
  version: "0.1.0"
10999
11169
  }));
11000
11170
 
@@ -11025,67 +11195,98 @@ var renderers = /* @__PURE__ */ new Map([
11025
11195
  ]
11026
11196
  ]);
11027
11197
  var Tree = ({ space, selected, variant = "tidy", onNodeClick }) => {
11028
- var _effect = _useSignals3();
11029
- try {
11030
- const [model] = useAsyncState(async () => space ? new SpaceGraphModel().open(space) : void 0, [
11031
- space,
11032
- selected
11033
- ]);
11034
- const [tree3, setTree] = useState();
11035
- useEffect3(() => {
11036
- return model?.subscribe(() => {
11037
- const tree4 = mapGraphToTreeData(model);
11038
- setTree(tree4);
11039
- }, true);
11040
- }, [
11041
- model
11042
- ]);
11043
- const context = useRef(null);
11044
- useEffect3(() => {
11045
- if (context.current?.size) {
11046
- const { width, height } = context.current.size;
11047
- const size = Math.min(width, height);
11048
- const radius = size * 0.4;
11049
- const options = {
11050
- // TODO(burdon): Type.
11051
- label: (d) => d.label ?? d.id,
11052
- width,
11053
- height,
11054
- radius,
11055
- marginLeft: (width - radius * 2) / 2,
11056
- marginRight: (width - radius * 2) / 2,
11057
- marginTop: (height - radius * 2) / 2,
11058
- marginBottom: (height - radius * 2) / 2,
11059
- slots: defaultTreeLayoutSlots
11060
- };
11061
- if (tree3) {
11062
- const renderer = renderers.get(variant);
11063
- renderer?.(context.current.svg, tree3, options);
11064
- }
11198
+ const registry = useContext(RegistryContext);
11199
+ const [model] = useAsyncState(async () => space ? new SpaceGraphModel(registry).open(space.db) : void 0, [
11200
+ space,
11201
+ selected,
11202
+ registry
11203
+ ]);
11204
+ const [tree3, setTree] = useState2();
11205
+ useEffect5(() => {
11206
+ return model?.subscribe(() => {
11207
+ const tree4 = mapGraphToTreeData(model);
11208
+ setTree(tree4);
11209
+ }, true);
11210
+ }, [
11211
+ model
11212
+ ]);
11213
+ const context = useRef3(null);
11214
+ useEffect5(() => {
11215
+ if (context.current?.size) {
11216
+ const { width, height } = context.current.size;
11217
+ const size = Math.min(width, height);
11218
+ const radius = size * 0.4;
11219
+ const options = {
11220
+ // TODO(burdon): Type.
11221
+ label: (d) => d.label ?? d.id,
11222
+ width,
11223
+ height,
11224
+ radius,
11225
+ marginLeft: (width - radius * 2) / 2,
11226
+ marginRight: (width - radius * 2) / 2,
11227
+ marginTop: (height - radius * 2) / 2,
11228
+ marginBottom: (height - radius * 2) / 2,
11229
+ slots: defaultTreeLayoutSlots
11230
+ };
11231
+ if (tree3) {
11232
+ const renderer = renderers.get(variant);
11233
+ renderer?.(context.current.svg, tree3, options);
11065
11234
  }
11066
- }, [
11067
- context.current,
11068
- tree3
11069
- ]);
11070
- return /* @__PURE__ */ React3.createElement("div", {
11071
- onClick: () => onNodeClick?.()
11072
- }, /* @__PURE__ */ React3.createElement(SVG.Root, {
11073
- ref: context
11074
- }));
11075
- } finally {
11076
- _effect.f();
11077
- }
11235
+ }
11236
+ }, [
11237
+ context.current,
11238
+ tree3
11239
+ ]);
11240
+ return /* @__PURE__ */ React5.createElement("div", {
11241
+ className: "grow",
11242
+ onClick: () => onNodeClick?.()
11243
+ }, /* @__PURE__ */ React5.createElement(SVG2.Root, {
11244
+ ref: context
11245
+ }));
11078
11246
  };
11079
11247
 
11080
- // src/components/index.ts
11081
- import { lazy } from "react";
11082
- var ExplorerContainer = lazy(() => import("./ExplorerContainer-N3S5KSUX.mjs"));
11248
+ // src/hooks/useGraphModel.ts
11249
+ import { useEffect as useEffect6, useState as useState3 } from "react";
11250
+ import { Capabilities } from "@dxos/app-framework";
11251
+ import { useCapability } from "@dxos/app-framework/ui";
11252
+ import { SpaceGraphModel as SpaceGraphModel2 } from "@dxos/schema";
11253
+ var useGraphModel = (space, filter, options, queue) => {
11254
+ const registry = useCapability(Capabilities.AtomRegistry);
11255
+ const [model, setModel] = useState3(void 0);
11256
+ useEffect6(() => {
11257
+ if (!space) {
11258
+ setModel(void 0);
11259
+ return;
11260
+ }
11261
+ const newModel = new SpaceGraphModel2(registry);
11262
+ void newModel.open(space.db, queue);
11263
+ setModel(newModel);
11264
+ return () => {
11265
+ setModel(void 0);
11266
+ void newModel.close();
11267
+ };
11268
+ }, [
11269
+ space,
11270
+ registry,
11271
+ queue
11272
+ ]);
11273
+ useEffect6(() => {
11274
+ model?.setFilter(filter).setOptions(options);
11275
+ }, [
11276
+ model,
11277
+ filter,
11278
+ options
11279
+ ]);
11280
+ return model;
11281
+ };
11083
11282
 
11084
11283
  export {
11085
11284
  Chart,
11086
11285
  Globe,
11286
+ D3ForceGraph,
11287
+ ForceGraph,
11087
11288
  defaultTreeLayoutSlots,
11088
11289
  Tree,
11089
- ExplorerContainer
11290
+ useGraphModel
11090
11291
  };
11091
- //# sourceMappingURL=chunk-NPIP4VEH.mjs.map
11292
+ //# sourceMappingURL=chunk-35JCF4SD.mjs.map