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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. package/dist/lib/browser/ExplorerContainer-BBZ54DJS.mjs +37 -0
  2. package/dist/lib/browser/ExplorerContainer-BBZ54DJS.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-RRXH3JYB.mjs → chunk-73GQ46YO.mjs} +415 -155
  4. package/dist/lib/{node-esm/chunk-VNMYGDGZ.mjs.map → browser/chunk-73GQ46YO.mjs.map} +4 -4
  5. package/dist/lib/browser/{chunk-QLQLPZNI.mjs → chunk-73YTQHOT.mjs} +12 -11
  6. package/dist/lib/browser/chunk-73YTQHOT.mjs.map +7 -0
  7. package/dist/lib/browser/chunk-M2BGAY6H.mjs +177 -0
  8. package/dist/lib/browser/chunk-M2BGAY6H.mjs.map +7 -0
  9. package/dist/lib/browser/{chunk-Z2SDLMQM.mjs → chunk-OBAFAA5V.mjs} +3 -3
  10. package/dist/lib/browser/{chunk-Z2SDLMQM.mjs.map → chunk-OBAFAA5V.mjs.map} +1 -1
  11. package/dist/lib/browser/chunk-SLB2F5AO.mjs +30 -0
  12. package/dist/lib/browser/chunk-SLB2F5AO.mjs.map +7 -0
  13. package/dist/lib/browser/index.mjs +15 -11
  14. package/dist/lib/browser/index.mjs.map +1 -1
  15. package/dist/lib/browser/{intent-resolver-P4YLQHXF.mjs → intent-resolver-FJDVBDE3.mjs} +3 -3
  16. package/dist/lib/browser/meta.json +1 -1
  17. package/dist/lib/browser/meta.mjs +1 -1
  18. package/dist/lib/browser/{react-surface-TPR4VUPE.mjs → react-surface-H3YDMXAQ.mjs} +5 -5
  19. package/dist/lib/browser/types/index.mjs +2 -2
  20. package/dist/lib/node/{ExplorerContainer-73AHSBAG.cjs → ExplorerContainer-MVP2AM7R.cjs} +24 -16
  21. package/dist/lib/node/ExplorerContainer-MVP2AM7R.cjs.map +7 -0
  22. package/dist/lib/node/chunk-4T4LCT5R.cjs +52 -0
  23. package/dist/lib/node/chunk-4T4LCT5R.cjs.map +7 -0
  24. package/dist/lib/node/{chunk-4QUNUHKB.cjs → chunk-72H5HBTK.cjs} +414 -153
  25. package/dist/lib/node/{chunk-4QUNUHKB.cjs.map → chunk-72H5HBTK.cjs.map} +4 -4
  26. package/dist/lib/node/{chunk-VB3QE6XY.cjs → chunk-BCDVG2CH.cjs} +6 -6
  27. package/dist/lib/node/{chunk-VB3QE6XY.cjs.map → chunk-BCDVG2CH.cjs.map} +1 -1
  28. package/dist/lib/node/{chunk-YLL7H7CZ.cjs → chunk-MLRYW4WQ.cjs} +15 -14
  29. package/dist/lib/node/chunk-MLRYW4WQ.cjs.map +7 -0
  30. package/dist/lib/node/chunk-NELWWGBU.cjs +204 -0
  31. package/dist/lib/node/chunk-NELWWGBU.cjs.map +7 -0
  32. package/dist/lib/node/index.cjs +34 -31
  33. package/dist/lib/node/index.cjs.map +1 -1
  34. package/dist/lib/node/{intent-resolver-T2R4PJVP.cjs → intent-resolver-DRT67ZU4.cjs} +8 -8
  35. package/dist/lib/node/meta.cjs +3 -3
  36. package/dist/lib/node/meta.cjs.map +1 -1
  37. package/dist/lib/node/meta.json +1 -1
  38. package/dist/lib/node/{react-surface-OLIOGYOK.cjs → react-surface-6ESLSM33.cjs} +11 -11
  39. package/dist/lib/node/types/index.cjs +4 -4
  40. package/dist/lib/node/types/index.cjs.map +1 -1
  41. package/dist/lib/node-esm/ExplorerContainer-APGUQI4M.mjs +38 -0
  42. package/dist/lib/node-esm/ExplorerContainer-APGUQI4M.mjs.map +7 -0
  43. package/dist/lib/node-esm/{chunk-VNMYGDGZ.mjs → chunk-34X2VFQN.mjs} +415 -154
  44. package/dist/lib/{browser/chunk-RRXH3JYB.mjs.map → node-esm/chunk-34X2VFQN.mjs.map} +4 -4
  45. package/dist/lib/node-esm/{chunk-PUFSCMN4.mjs → chunk-3CMBLK6W.mjs} +3 -3
  46. package/dist/lib/node-esm/{chunk-PUFSCMN4.mjs.map → chunk-3CMBLK6W.mjs.map} +1 -1
  47. package/dist/lib/node-esm/{chunk-QZH2GDN5.mjs → chunk-N6VEANUZ.mjs} +12 -11
  48. package/dist/lib/node-esm/chunk-N6VEANUZ.mjs.map +7 -0
  49. package/dist/lib/node-esm/chunk-PVII2K2B.mjs +179 -0
  50. package/dist/lib/node-esm/chunk-PVII2K2B.mjs.map +7 -0
  51. package/dist/lib/node-esm/chunk-VSORIAHH.mjs +32 -0
  52. package/dist/lib/node-esm/chunk-VSORIAHH.mjs.map +7 -0
  53. package/dist/lib/node-esm/index.mjs +15 -11
  54. package/dist/lib/node-esm/index.mjs.map +1 -1
  55. package/dist/lib/node-esm/{intent-resolver-OMUHLTGU.mjs → intent-resolver-4RBV644N.mjs} +3 -3
  56. package/dist/lib/node-esm/meta.json +1 -1
  57. package/dist/lib/node-esm/meta.mjs +1 -1
  58. package/dist/lib/node-esm/{react-surface-QLB55AWT.mjs → react-surface-ZEVL3FXG.mjs} +5 -5
  59. package/dist/lib/node-esm/types/index.mjs +2 -2
  60. package/dist/types/src/components/Chart/Chart.d.ts.map +1 -1
  61. package/dist/types/src/components/ExplorerContainer.d.ts +4 -3
  62. package/dist/types/src/components/ExplorerContainer.d.ts.map +1 -1
  63. package/dist/types/src/components/Globe/Globe.d.ts.map +1 -1
  64. package/dist/types/src/components/Graph/D3ForceGraph.d.ts +14 -0
  65. package/dist/types/src/components/Graph/D3ForceGraph.d.ts.map +1 -0
  66. package/dist/types/src/components/Graph/D3ForceGraph.stories.d.ts +6 -0
  67. package/dist/types/src/components/Graph/D3ForceGraph.stories.d.ts.map +1 -0
  68. package/dist/types/src/components/Graph/ForceGraph.d.ts +8 -0
  69. package/dist/types/src/components/Graph/ForceGraph.d.ts.map +1 -0
  70. package/dist/types/src/components/Graph/{Graph.stories.d.ts → ForceGraph.stories.d.ts} +1 -1
  71. package/dist/types/src/components/Graph/ForceGraph.stories.d.ts.map +1 -0
  72. package/dist/types/src/components/Graph/adapter.d.ts +21 -0
  73. package/dist/types/src/components/Graph/adapter.d.ts.map +1 -0
  74. package/dist/types/src/components/Graph/index.d.ts +2 -2
  75. package/dist/types/src/components/Graph/index.d.ts.map +1 -1
  76. package/dist/types/src/components/Graph/testing.d.ts +14 -0
  77. package/dist/types/src/components/Graph/testing.d.ts.map +1 -0
  78. package/dist/types/src/components/Tree/Tree.d.ts.map +1 -1
  79. package/dist/types/src/components/Tree/layout/HierarchicalEdgeBundling.d.ts.map +1 -1
  80. package/dist/types/src/components/Tree/layout/RadialTree.d.ts.map +1 -1
  81. package/dist/types/src/components/Tree/layout/TidyTree.d.ts.map +1 -1
  82. package/dist/types/src/components/Tree/testing/generator.d.ts +8 -0
  83. package/dist/types/src/components/Tree/testing/generator.d.ts.map +1 -0
  84. package/dist/types/src/components/Tree/testing/index.d.ts +2 -0
  85. package/dist/types/src/components/Tree/testing/index.d.ts.map +1 -0
  86. package/dist/types/src/components/Tree/types/index.d.ts +3 -0
  87. package/dist/types/src/components/Tree/types/index.d.ts.map +1 -0
  88. package/dist/types/src/components/Tree/types/tree.d.ts +83 -0
  89. package/dist/types/src/components/Tree/types/tree.d.ts.map +1 -0
  90. package/dist/types/src/components/Tree/types/tree.test.d.ts +2 -0
  91. package/dist/types/src/components/Tree/types/tree.test.d.ts.map +1 -0
  92. package/dist/types/src/components/Tree/types/types.d.ts +8 -0
  93. package/dist/types/src/components/Tree/types/types.d.ts.map +1 -0
  94. package/dist/types/src/components/index.d.ts +2 -2
  95. package/dist/types/src/components/plot.d.ts.map +1 -1
  96. package/dist/types/src/hooks/index.d.ts +2 -0
  97. package/dist/types/src/hooks/index.d.ts.map +1 -0
  98. package/dist/types/src/hooks/useGraphModel.d.ts +4 -0
  99. package/dist/types/src/hooks/useGraphModel.d.ts.map +1 -0
  100. package/dist/types/src/index.d.ts +2 -1
  101. package/dist/types/src/index.d.ts.map +1 -1
  102. package/dist/types/src/translations.d.ts +2 -8
  103. package/dist/types/src/translations.d.ts.map +1 -1
  104. package/dist/types/src/types/schema.d.ts +6 -6
  105. package/dist/types/src/types/schema.d.ts.map +1 -1
  106. package/dist/types/src/types/types.d.ts +6 -6
  107. package/dist/types/src/types/types.d.ts.map +1 -1
  108. package/dist/types/tsconfig.tsbuildinfo +1 -1
  109. package/package.json +30 -27
  110. package/src/components/ExplorerContainer.tsx +11 -4
  111. package/src/components/Graph/D3ForceGraph.stories.tsx +64 -0
  112. package/src/components/Graph/D3ForceGraph.tsx +101 -0
  113. package/src/components/Graph/ForceGraph.stories.tsx +64 -0
  114. package/src/components/Graph/{Graph.tsx → ForceGraph.tsx} +19 -26
  115. package/src/components/Graph/adapter.ts +47 -0
  116. package/src/components/Graph/index.ts +2 -3
  117. package/src/components/Graph/testing.ts +57 -0
  118. package/src/components/Tree/Tree.stories.tsx +1 -1
  119. package/src/components/Tree/Tree.tsx +11 -18
  120. package/src/components/Tree/testing/generator.ts +46 -0
  121. package/src/components/Tree/testing/index.ts +5 -0
  122. package/src/components/Tree/types/index.ts +6 -0
  123. package/src/components/Tree/types/tree.test.ts +133 -0
  124. package/src/components/Tree/types/tree.ts +287 -0
  125. package/src/components/Tree/types/types.ts +41 -0
  126. package/src/hooks/index.ts +5 -0
  127. package/src/hooks/useGraphModel.ts +35 -0
  128. package/src/index.ts +2 -2
  129. package/src/meta.ts +2 -2
  130. package/src/types/schema.ts +5 -3
  131. package/src/types/types.ts +5 -5
  132. package/dist/lib/browser/ExplorerContainer-HL532ODG.mjs +0 -27
  133. package/dist/lib/browser/ExplorerContainer-HL532ODG.mjs.map +0 -7
  134. package/dist/lib/browser/chunk-QLQLPZNI.mjs.map +0 -7
  135. package/dist/lib/browser/chunk-SBLNE7FL.mjs +0 -205
  136. package/dist/lib/browser/chunk-SBLNE7FL.mjs.map +0 -7
  137. package/dist/lib/node/ExplorerContainer-73AHSBAG.cjs.map +0 -7
  138. package/dist/lib/node/chunk-OIHH6TVE.cjs +0 -236
  139. package/dist/lib/node/chunk-OIHH6TVE.cjs.map +0 -7
  140. package/dist/lib/node/chunk-YLL7H7CZ.cjs.map +0 -7
  141. package/dist/lib/node-esm/ExplorerContainer-NMI55PYM.mjs +0 -28
  142. package/dist/lib/node-esm/ExplorerContainer-NMI55PYM.mjs.map +0 -7
  143. package/dist/lib/node-esm/chunk-QZH2GDN5.mjs.map +0 -7
  144. package/dist/lib/node-esm/chunk-SZRRNWYT.mjs +0 -207
  145. package/dist/lib/node-esm/chunk-SZRRNWYT.mjs.map +0 -7
  146. package/dist/types/src/components/Graph/Graph.d.ts +0 -8
  147. package/dist/types/src/components/Graph/Graph.d.ts.map +0 -1
  148. package/dist/types/src/components/Graph/Graph.stories.d.ts.map +0 -1
  149. package/dist/types/src/components/Graph/graph-model.d.ts +0 -39
  150. package/dist/types/src/components/Graph/graph-model.d.ts.map +0 -1
  151. package/dist/types/src/components/Tree/types.d.ts +0 -8
  152. package/dist/types/src/components/Tree/types.d.ts.map +0 -1
  153. package/src/components/Graph/Graph.stories.tsx +0 -62
  154. package/src/components/Graph/graph-model.ts +0 -193
  155. package/src/components/Tree/types.ts +0 -40
  156. /package/dist/lib/browser/{intent-resolver-P4YLQHXF.mjs.map → intent-resolver-FJDVBDE3.mjs.map} +0 -0
  157. /package/dist/lib/browser/{react-surface-TPR4VUPE.mjs.map → react-surface-H3YDMXAQ.mjs.map} +0 -0
  158. /package/dist/lib/node/{intent-resolver-T2R4PJVP.cjs.map → intent-resolver-DRT67ZU4.cjs.map} +0 -0
  159. /package/dist/lib/node/{react-surface-OLIOGYOK.cjs.map → react-surface-6ESLSM33.cjs.map} +0 -0
  160. /package/dist/lib/node-esm/{intent-resolver-OMUHLTGU.mjs.map → intent-resolver-4RBV644N.mjs.map} +0 -0
  161. /package/dist/lib/node-esm/{react-surface-QLB55AWT.mjs.map → react-surface-ZEVL3FXG.mjs.map} +0 -0
@@ -1,207 +0,0 @@
1
- import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
-
3
- // packages/plugins/plugin-explorer/src/components/Graph/graph-model.ts
4
- import { getSchema, getSchemaDXN, AST, ReferenceAnnotationId, SchemaValidator, StoredSchema } from "@dxos/echo-schema";
5
- import { GraphModel } from "@dxos/gem-spore";
6
- import { log } from "@dxos/log";
7
- import { CollectionType } from "@dxos/plugin-space/types";
8
- import { Filter } from "@dxos/react-client/echo";
9
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/plugins/plugin-explorer/src/components/Graph/graph-model.ts";
10
- var SpaceGraphModel = class extends GraphModel {
11
- constructor(_options = {}) {
12
- super();
13
- this._options = _options;
14
- this._graph = {
15
- nodes: [],
16
- links: []
17
- };
18
- }
19
- get graph() {
20
- return this._graph;
21
- }
22
- get objects() {
23
- return this._objects ?? [];
24
- }
25
- // TODO(burdon): Alternative diagram types:
26
- // - https://observablehq.com/@d3/radial-tree/2
27
- // - https://observablehq.com/@d3/disjoint-force-directed-graph/2
28
- // - https://observablehq.com/@mbostock/tadpoles
29
- // - https://observablehq.com/@d3/psr-b1919-21
30
- // - https://vasturiano.github.io/react-force-graph/example/basic (3D)
31
- async open(space, objectId) {
32
- if (!this._schemaSubscription) {
33
- const schemaaQuery = space.db.schemaRegistry.query({});
34
- const schemas = await schemaaQuery.run();
35
- const onSchemaUpdate = ({ results }) => this._schema = results;
36
- this._schemaSubscription = schemaaQuery.subscribe(onSchemaUpdate);
37
- onSchemaUpdate({
38
- results: schemas
39
- });
40
- this._objectsSubscription = space.db.query(Filter.not(Filter.or(Filter.schema(StoredSchema), Filter.schema(CollectionType)))).subscribe(({ objects }) => {
41
- this._objects = objects;
42
- const currentNodes = this._graph.nodes;
43
- this._graph.nodes = [];
44
- this._graph.links = [];
45
- const addSchema = (typename) => {
46
- const current = currentNodes.find((node) => node.id === typename);
47
- if (typename) {
48
- this._graph.nodes.push({
49
- ...current,
50
- id: typename,
51
- type: "schema",
52
- data: {
53
- typename
54
- }
55
- });
56
- }
57
- };
58
- space.db.graph.schemaRegistry.schemas.forEach((schema) => {
59
- const typename = getSchemaDXN(schema)?.typename;
60
- if (typename) {
61
- addSchema(typename);
62
- }
63
- });
64
- this._schema?.forEach((schema) => {
65
- const typename = getSchemaDXN(schema)?.typename;
66
- if (typename) {
67
- addSchema(typename);
68
- }
69
- });
70
- this._objects.forEach((object) => {
71
- const schema = getSchema(object);
72
- if (schema) {
73
- const typename = getSchemaDXN(schema)?.typename;
74
- if (typename) {
75
- const current = currentNodes.find((node) => node.id === object.id);
76
- this._graph.nodes.push({
77
- ...current,
78
- id: object.id,
79
- type: "object",
80
- data: {
81
- typename,
82
- object
83
- }
84
- });
85
- const schemaNode = this._graph.nodes.find((node) => node.type === "schema" && node.data.typename === typename);
86
- if (schemaNode) {
87
- this._graph.links.push({
88
- id: `${object.id}-${schemaNode.id}`,
89
- source: object.id,
90
- target: schemaNode.id
91
- });
92
- } else {
93
- log.info("schema node not found", {
94
- typename
95
- }, {
96
- F: __dxlog_file,
97
- L: 147,
98
- S: this,
99
- C: (f, a) => f(...a)
100
- });
101
- }
102
- AST.getPropertySignatures(schema.ast).forEach((prop) => {
103
- if (!SchemaValidator.hasTypeAnnotation(schema, prop.name.toString(), ReferenceAnnotationId)) {
104
- return;
105
- }
106
- const value = object[String(prop.name)];
107
- if (value) {
108
- const refs = Array.isArray(value) ? value : [
109
- value
110
- ];
111
- for (const ref of refs) {
112
- if (objects.findIndex((obj) => obj.id === ref.id) !== -1) {
113
- this._graph.links.push({
114
- id: `${object.id}-${String(prop.name)}-${ref.id}`,
115
- source: object.id,
116
- target: ref.id
117
- });
118
- }
119
- }
120
- }
121
- });
122
- }
123
- }
124
- });
125
- this.triggerUpdate();
126
- }, {
127
- fire: true
128
- });
129
- }
130
- this.setSelected(objectId);
131
- return this;
132
- }
133
- close() {
134
- this._schemaSubscription?.();
135
- this._schemaSubscription = void 0;
136
- this._objectsSubscription?.();
137
- this._objectsSubscription = void 0;
138
- return this;
139
- }
140
- };
141
-
142
- // packages/plugins/plugin-explorer/src/components/Graph/Graph.tsx
143
- import { forceLink, forceManyBody } from "d3";
144
- import ForceGraph from "force-graph";
145
- import React, { useEffect, useRef } from "react";
146
- import { useResizeDetector } from "react-resize-detector";
147
- import { filterObjectsSync } from "@dxos/plugin-search";
148
- import { useAsyncState } from "@dxos/react-ui";
149
- var Graph = ({ space, match }) => {
150
- const { ref, width, height } = useResizeDetector({
151
- refreshRate: 200
152
- });
153
- const rootRef = useRef(null);
154
- const forceGraph = useRef();
155
- const [model] = useAsyncState(async () => space ? new SpaceGraphModel({
156
- schema: true
157
- }).open(space) : void 0, [
158
- space
159
- ]);
160
- const filteredRef = useRef();
161
- filteredRef.current = filterObjectsSync(model?.objects ?? [], match);
162
- useEffect(() => {
163
- if (rootRef.current) {
164
- forceGraph.current = new ForceGraph(rootRef.current).nodeRelSize(6).nodeLabel((node) => {
165
- if (node.type === "schema") {
166
- return node.data.typename;
167
- }
168
- return node.id;
169
- }).nodeAutoColorBy((node) => node.type === "schema" ? "schema" : node.data.typename).linkColor(() => "rgba(255,255,255,0.25)");
170
- }
171
- return () => {
172
- forceGraph.current?.pauseAnimation().graphData({
173
- nodes: [],
174
- links: []
175
- });
176
- forceGraph.current = void 0;
177
- };
178
- }, []);
179
- useEffect(() => {
180
- if (forceGraph.current && width && height && model) {
181
- forceGraph.current.pauseAnimation().width(width).height(height).onEngineStop(() => {
182
- handleZoomToFit();
183
- }).d3Force("link", forceLink().distance(160).strength(0.5)).d3Force("charge", forceManyBody().strength(-30)).graphData(model.graph).warmupTicks(100).cooldownTime(1e3).resumeAnimation();
184
- }
185
- }, [
186
- model,
187
- width,
188
- height
189
- ]);
190
- const handleZoomToFit = () => {
191
- forceGraph.current?.zoomToFit(400, 40);
192
- };
193
- return /* @__PURE__ */ React.createElement("div", {
194
- ref,
195
- className: "relative grow",
196
- onClick: handleZoomToFit
197
- }, /* @__PURE__ */ React.createElement("div", {
198
- ref: rootRef,
199
- className: "absolute inset-0"
200
- }));
201
- };
202
-
203
- export {
204
- SpaceGraphModel,
205
- Graph
206
- };
207
- //# sourceMappingURL=chunk-SZRRNWYT.mjs.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/components/Graph/graph-model.ts", "../../../src/components/Graph/Graph.tsx"],
4
- "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { type CleanupFn } from '@dxos/async';\nimport {\n getSchema,\n getSchemaDXN,\n AST,\n type EchoSchema,\n ReferenceAnnotationId,\n SchemaValidator,\n StoredSchema,\n} from '@dxos/echo-schema';\nimport { type GraphData, GraphModel } from '@dxos/gem-spore';\nimport { log } from '@dxos/log';\nimport { CollectionType } from '@dxos/plugin-space/types';\nimport { Filter, type ReactiveEchoObject, type Space } from '@dxos/react-client/echo';\n\nexport type SpaceGraphModelOptions = {\n schema?: boolean;\n};\n\n// TODO(burdon): Convert to common/graph.\n\ntype SchemaGraphNode = {\n id: string;\n type: 'schema';\n data: { typename: string };\n};\n\ntype ObjectGraphNode = {\n id: string;\n type: 'object';\n data: { typename: string; object: ReactiveEchoObject<any> };\n};\n\nexport type EchoGraphNode = SchemaGraphNode | ObjectGraphNode;\n\n/**\n * Converts ECHO objects to a graph.\n */\nexport class SpaceGraphModel extends GraphModel<EchoGraphNode> {\n private readonly _graph: GraphData<EchoGraphNode> = {\n nodes: [],\n links: [],\n };\n\n private _schema?: EchoSchema[];\n private _schemaSubscription?: CleanupFn;\n private _objects?: ReactiveEchoObject<any>[];\n private _objectsSubscription?: CleanupFn;\n\n constructor(private readonly _options: SpaceGraphModelOptions = {}) {\n super();\n }\n\n override get graph(): GraphData<EchoGraphNode> {\n return this._graph;\n }\n\n get objects(): ReactiveEchoObject<any>[] {\n return this._objects ?? [];\n }\n\n // TODO(burdon): Alternative diagram types:\n // - https://observablehq.com/@d3/radial-tree/2\n // - https://observablehq.com/@d3/disjoint-force-directed-graph/2\n // - https://observablehq.com/@mbostock/tadpoles\n // - https://observablehq.com/@d3/psr-b1919-21\n // - https://vasturiano.github.io/react-force-graph/example/basic (3D)\n\n async open(space: Space, objectId?: string) {\n // TODO(burdon): Factor out graph builder to lib (use common/graph abstraction).\n if (!this._schemaSubscription) {\n // TODO(burdon): Normalize unsubscribe callbacks and merge handlers.\n // TODO(burdon): Trigger initial subscription update.\n // TODO(burdon): Normalize subscription cb for objects, schema, etc.\n\n const schemaaQuery = space.db.schemaRegistry.query({});\n const schemas = await schemaaQuery.run();\n const onSchemaUpdate = ({ results }: { results: EchoSchema[] }) => (this._schema = results);\n this._schemaSubscription = schemaaQuery.subscribe(onSchemaUpdate);\n onSchemaUpdate({ results: schemas });\n\n this._objectsSubscription = space.db\n // TODO(burdon): ERROR: Cannot mix type and or filters.\n .query(Filter.not(Filter.or(Filter.schema(StoredSchema), Filter.schema(CollectionType))))\n .subscribe(\n ({ objects }) => {\n this._objects = objects;\n\n // Merge with current nodes.\n const currentNodes = this._graph.nodes;\n\n this._graph.nodes = [];\n this._graph.links = [];\n\n const addSchema = (typename: string) => {\n const current = currentNodes.find((node) => node.id === typename);\n if (typename) {\n this._graph.nodes.push({\n ...current,\n id: typename,\n type: 'schema',\n data: { typename },\n });\n }\n };\n\n // Runtime schema.\n space.db.graph.schemaRegistry.schemas.forEach((schema) => {\n const typename = getSchemaDXN(schema)?.typename;\n if (typename) {\n addSchema(typename);\n }\n });\n\n // Database Schema.\n this._schema?.forEach((schema) => {\n const typename = getSchemaDXN(schema)?.typename;\n if (typename) {\n addSchema(typename);\n }\n });\n\n // Database Objects.\n this._objects.forEach((object) => {\n const schema = getSchema(object);\n if (schema) {\n const typename = getSchemaDXN(schema)?.typename;\n if (typename) {\n const current = currentNodes.find((node) => node.id === object.id);\n this._graph.nodes.push({ ...current, id: object.id, type: 'object', data: { typename, object } });\n\n // Link to schema.\n const schemaNode = this._graph.nodes.find(\n (node) => node.type === 'schema' && node.data.typename === typename,\n );\n if (schemaNode) {\n this._graph.links.push({\n id: `${object.id}-${schemaNode.id}`,\n source: object.id,\n target: schemaNode.id,\n });\n } else {\n log.info('schema node not found', { typename });\n }\n\n // Link ot refs.\n // TODO(burdon): This isn't working.\n AST.getPropertySignatures(schema.ast).forEach((prop) => {\n if (!SchemaValidator.hasTypeAnnotation(schema, prop.name.toString(), ReferenceAnnotationId)) {\n return;\n }\n\n const value = object[String(prop.name)];\n if (value) {\n const refs = Array.isArray(value) ? value : [value];\n for (const ref of refs) {\n if (objects.findIndex((obj) => obj.id === ref.id) !== -1) {\n this._graph.links.push({\n id: `${object.id}-${String(prop.name)}-${ref.id}`,\n source: object.id,\n target: ref.id,\n });\n }\n }\n }\n });\n }\n }\n });\n\n this.triggerUpdate();\n },\n { fire: true },\n );\n }\n\n this.setSelected(objectId);\n return this;\n }\n\n close() {\n this._schemaSubscription?.();\n this._schemaSubscription = undefined;\n this._objectsSubscription?.();\n this._objectsSubscription = undefined;\n\n return this;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { forceLink, forceManyBody } from 'd3';\nimport ForceGraph from 'force-graph';\nimport React, { type FC, useEffect, useRef } from 'react';\nimport { useResizeDetector } from 'react-resize-detector';\n\nimport { type Space } from '@dxos/client/echo';\nimport { filterObjectsSync, type SearchResult } from '@dxos/plugin-search';\nimport { useAsyncState } from '@dxos/react-ui';\n\nimport { SpaceGraphModel } from './graph-model';\n\nexport type GraphProps = {\n space: Space;\n match?: RegExp;\n};\n\nexport const Graph: FC<GraphProps> = ({ space, match }) => {\n const { ref, width, height } = useResizeDetector({ refreshRate: 200 });\n const rootRef = useRef<HTMLDivElement>(null);\n const forceGraph = useRef<ForceGraph>();\n\n const [model] = useAsyncState(\n async () => (space ? new SpaceGraphModel({ schema: true }).open(space) : undefined),\n [space],\n );\n\n const filteredRef = useRef<SearchResult[]>();\n filteredRef.current = filterObjectsSync(model?.objects ?? [], match);\n\n useEffect(() => {\n if (rootRef.current) {\n // https://github.com/vasturiano/force-graph\n // https://github.com/vasturiano/3d-force-graph\n forceGraph.current = new ForceGraph(rootRef.current)\n .nodeRelSize(6)\n .nodeLabel((node: any) => {\n if (node.type === 'schema') {\n return node.data.typename;\n }\n\n return node.id;\n })\n .nodeAutoColorBy((node: any) => (node.type === 'schema' ? 'schema' : node.data.typename))\n .linkColor(() => 'rgba(255,255,255,0.25)');\n }\n\n return () => {\n forceGraph.current?.pauseAnimation().graphData({ nodes: [], links: [] });\n forceGraph.current = undefined;\n };\n }, []);\n\n useEffect(() => {\n if (forceGraph.current && width && height && model) {\n forceGraph.current\n .pauseAnimation()\n .width(width)\n .height(height)\n .onEngineStop(() => {\n handleZoomToFit();\n })\n\n // https://github.com/vasturiano/force-graph?tab=readme-ov-file#force-engine-d3-force-configuration\n // .d3Force('center', forceCenter().strength(0.9))\n .d3Force('link', forceLink().distance(160).strength(0.5))\n .d3Force('charge', forceManyBody().strength(-30))\n // .d3AlphaDecay(0.0228)\n // .d3VelocityDecay(0.4)\n\n .graphData(model.graph)\n .warmupTicks(100)\n .cooldownTime(1000)\n .resumeAnimation();\n }\n }, [model, width, height]);\n\n const handleZoomToFit = () => {\n forceGraph.current?.zoomToFit(400, 40);\n };\n\n return (\n <div ref={ref} className='relative grow' onClick={handleZoomToFit}>\n <div ref={rootRef} className='absolute inset-0' />\n </div>\n );\n};\n"],
5
- "mappings": "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",
6
- "names": ["getSchema", "getSchemaDXN", "AST", "ReferenceAnnotationId", "SchemaValidator", "StoredSchema", "GraphModel", "log", "CollectionType", "Filter", "SpaceGraphModel", "constructor", "_options", "_graph", "nodes", "links", "graph", "objects", "_objects", "open", "space", "objectId", "_schemaSubscription", "schemaaQuery", "db", "schemaRegistry", "query", "schemas", "run", "onSchemaUpdate", "results", "_schema", "subscribe", "_objectsSubscription", "not", "or", "schema", "currentNodes", "addSchema", "typename", "current", "find", "node", "id", "push", "type", "data", "forEach", "object", "schemaNode", "source", "target", "info", "getPropertySignatures", "ast", "prop", "hasTypeAnnotation", "name", "toString", "value", "String", "refs", "Array", "isArray", "ref", "findIndex", "obj", "triggerUpdate", "fire", "setSelected", "close", "undefined", "forceLink", "forceManyBody", "ForceGraph", "React", "useEffect", "useRef", "useResizeDetector", "filterObjectsSync", "useAsyncState", "Graph", "space", "match", "ref", "width", "height", "useResizeDetector", "refreshRate", "rootRef", "useRef", "forceGraph", "model", "useAsyncState", "SpaceGraphModel", "schema", "open", "undefined", "filteredRef", "current", "filterObjectsSync", "objects", "useEffect", "ForceGraph", "nodeRelSize", "nodeLabel", "node", "type", "data", "typename", "id", "nodeAutoColorBy", "linkColor", "pauseAnimation", "graphData", "nodes", "links", "onEngineStop", "handleZoomToFit", "d3Force", "forceLink", "distance", "strength", "forceManyBody", "graph", "warmupTicks", "cooldownTime", "resumeAnimation", "zoomToFit", "div", "className", "onClick"]
7
- }
@@ -1,8 +0,0 @@
1
- import { type FC } from 'react';
2
- import { type Space } from '@dxos/client/echo';
3
- export type GraphProps = {
4
- space: Space;
5
- match?: RegExp;
6
- };
7
- export declare const Graph: FC<GraphProps>;
8
- //# sourceMappingURL=Graph.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Graph.d.ts","sourceRoot":"","sources":["../../../../../src/components/Graph/Graph.tsx"],"names":[],"mappings":"AAMA,OAAc,EAAE,KAAK,EAAE,EAAqB,MAAM,OAAO,CAAC;AAG1D,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAM/C,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,EAAE,CAAC,UAAU,CAqEhC,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"Graph.stories.d.ts","sourceRoot":"","sources":["../../../../../src/components/Graph/Graph.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,aAAa,CAAC;AAErB,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,kBAAkB,CAAC;AA2C7C,QAAA,MAAM,IAAI,EAAE,IAQX,CAAC;AAEF,eAAe,IAAI,CAAC;AAEpB,eAAO,MAAM,OAAO,IAAK,CAAC"}
@@ -1,39 +0,0 @@
1
- import { type GraphData, GraphModel } from '@dxos/gem-spore';
2
- import { type ReactiveEchoObject, type Space } from '@dxos/react-client/echo';
3
- export type SpaceGraphModelOptions = {
4
- schema?: boolean;
5
- };
6
- type SchemaGraphNode = {
7
- id: string;
8
- type: 'schema';
9
- data: {
10
- typename: string;
11
- };
12
- };
13
- type ObjectGraphNode = {
14
- id: string;
15
- type: 'object';
16
- data: {
17
- typename: string;
18
- object: ReactiveEchoObject<any>;
19
- };
20
- };
21
- export type EchoGraphNode = SchemaGraphNode | ObjectGraphNode;
22
- /**
23
- * Converts ECHO objects to a graph.
24
- */
25
- export declare class SpaceGraphModel extends GraphModel<EchoGraphNode> {
26
- private readonly _options;
27
- private readonly _graph;
28
- private _schema?;
29
- private _schemaSubscription?;
30
- private _objects?;
31
- private _objectsSubscription?;
32
- constructor(_options?: SpaceGraphModelOptions);
33
- get graph(): GraphData<EchoGraphNode>;
34
- get objects(): ReactiveEchoObject<any>[];
35
- open(space: Space, objectId?: string): Promise<this>;
36
- close(): this;
37
- }
38
- export {};
39
- //# sourceMappingURL=graph-model.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"graph-model.d.ts","sourceRoot":"","sources":["../../../../../src/components/Graph/graph-model.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,KAAK,SAAS,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAG7D,OAAO,EAAU,KAAK,kBAAkB,EAAE,KAAK,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAEtF,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAIF,KAAK,eAAe,GAAG;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5B,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,kBAAkB,CAAC,GAAG,CAAC,CAAA;KAAE,CAAC;CAC7D,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,eAAe,GAAG,eAAe,CAAC;AAE9D;;GAEG;AACH,qBAAa,eAAgB,SAAQ,UAAU,CAAC,aAAa,CAAC;IAWhD,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAVrC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAGrB;IAEF,OAAO,CAAC,OAAO,CAAC,CAAe;IAC/B,OAAO,CAAC,mBAAmB,CAAC,CAAY;IACxC,OAAO,CAAC,QAAQ,CAAC,CAA4B;IAC7C,OAAO,CAAC,oBAAoB,CAAC,CAAY;gBAEZ,QAAQ,GAAE,sBAA2B;IAIlE,IAAa,KAAK,IAAI,SAAS,CAAC,aAAa,CAAC,CAE7C;IAED,IAAI,OAAO,IAAI,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAEvC;IASK,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,EAAE,MAAM;IAgH1C,KAAK;CAQN"}
@@ -1,8 +0,0 @@
1
- import { type GraphModel } from '@dxos/gem-spore';
2
- export type TreeNode = {
3
- id: string;
4
- label?: string;
5
- children?: TreeNode[];
6
- };
7
- export declare const mapGraphToTreeData: <N>(model: GraphModel<N>, maxDepth?: number) => TreeNode | undefined;
8
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/components/Tree/types.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,MAAM,QAAQ,GAAG;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAC;CACvB,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,CAAC,SAAS,UAAU,CAAC,CAAC,CAAC,wBAAiB,QAAQ,GAAG,SA0BrF,CAAC"}
@@ -1,62 +0,0 @@
1
- //
2
- // Copyright 2023 DXOS.org
3
- //
4
-
5
- import '@dxos-theme';
6
-
7
- import { type Meta } from '@storybook/react';
8
- import React, { useEffect, useState } from 'react';
9
-
10
- import { createSpaceObjectGenerator, TestSchemaType } from '@dxos/echo-generator';
11
- import { faker } from '@dxos/random';
12
- import { useClient } from '@dxos/react-client';
13
- import { live } from '@dxos/react-client/echo';
14
- import { type Space } from '@dxos/react-client/echo';
15
- import { ClientRepeater } from '@dxos/react-client/testing';
16
- import { withLayout, withTheme } from '@dxos/storybook-utils';
17
-
18
- import { Graph } from './Graph';
19
- import { ViewType } from '../../types';
20
-
21
- faker.seed(1);
22
-
23
- const Story = () => {
24
- const client = useClient();
25
- const [space, setSpace] = useState<Space>();
26
- const [view, setView] = useState<ViewType>();
27
- useEffect(() => {
28
- const space = client.spaces.default;
29
- const generator = createSpaceObjectGenerator(space);
30
- queueMicrotask(async () => {
31
- await generator.addSchemas();
32
- await generator.createObjects({
33
- [TestSchemaType.organization]: 20,
34
- [TestSchemaType.contact]: 50,
35
- });
36
- });
37
-
38
- const view = space.db.add(live(ViewType, { name: '', type: '' }));
39
- setSpace(space);
40
- setView(view);
41
- }, []);
42
-
43
- if (!space || !view) {
44
- return null;
45
- }
46
-
47
- return <Graph space={space} />;
48
- };
49
-
50
- const meta: Meta = {
51
- title: 'plugins/plugin-explorer/Graph',
52
- component: Graph,
53
- render: () => <ClientRepeater component={Story} createSpace types={[ViewType]} />,
54
- decorators: [withTheme, withLayout({ fullscreen: true })],
55
- parameters: {
56
- layout: 'fullscreen',
57
- },
58
- };
59
-
60
- export default meta;
61
-
62
- export const Default = {};
@@ -1,193 +0,0 @@
1
- //
2
- // Copyright 2023 DXOS.org
3
- //
4
-
5
- import { type CleanupFn } from '@dxos/async';
6
- import {
7
- getSchema,
8
- getSchemaDXN,
9
- AST,
10
- type EchoSchema,
11
- ReferenceAnnotationId,
12
- SchemaValidator,
13
- StoredSchema,
14
- } from '@dxos/echo-schema';
15
- import { type GraphData, GraphModel } from '@dxos/gem-spore';
16
- import { log } from '@dxos/log';
17
- import { CollectionType } from '@dxos/plugin-space/types';
18
- import { Filter, type ReactiveEchoObject, type Space } from '@dxos/react-client/echo';
19
-
20
- export type SpaceGraphModelOptions = {
21
- schema?: boolean;
22
- };
23
-
24
- // TODO(burdon): Convert to common/graph.
25
-
26
- type SchemaGraphNode = {
27
- id: string;
28
- type: 'schema';
29
- data: { typename: string };
30
- };
31
-
32
- type ObjectGraphNode = {
33
- id: string;
34
- type: 'object';
35
- data: { typename: string; object: ReactiveEchoObject<any> };
36
- };
37
-
38
- export type EchoGraphNode = SchemaGraphNode | ObjectGraphNode;
39
-
40
- /**
41
- * Converts ECHO objects to a graph.
42
- */
43
- export class SpaceGraphModel extends GraphModel<EchoGraphNode> {
44
- private readonly _graph: GraphData<EchoGraphNode> = {
45
- nodes: [],
46
- links: [],
47
- };
48
-
49
- private _schema?: EchoSchema[];
50
- private _schemaSubscription?: CleanupFn;
51
- private _objects?: ReactiveEchoObject<any>[];
52
- private _objectsSubscription?: CleanupFn;
53
-
54
- constructor(private readonly _options: SpaceGraphModelOptions = {}) {
55
- super();
56
- }
57
-
58
- override get graph(): GraphData<EchoGraphNode> {
59
- return this._graph;
60
- }
61
-
62
- get objects(): ReactiveEchoObject<any>[] {
63
- return this._objects ?? [];
64
- }
65
-
66
- // TODO(burdon): Alternative diagram types:
67
- // - https://observablehq.com/@d3/radial-tree/2
68
- // - https://observablehq.com/@d3/disjoint-force-directed-graph/2
69
- // - https://observablehq.com/@mbostock/tadpoles
70
- // - https://observablehq.com/@d3/psr-b1919-21
71
- // - https://vasturiano.github.io/react-force-graph/example/basic (3D)
72
-
73
- async open(space: Space, objectId?: string) {
74
- // TODO(burdon): Factor out graph builder to lib (use common/graph abstraction).
75
- if (!this._schemaSubscription) {
76
- // TODO(burdon): Normalize unsubscribe callbacks and merge handlers.
77
- // TODO(burdon): Trigger initial subscription update.
78
- // TODO(burdon): Normalize subscription cb for objects, schema, etc.
79
-
80
- const schemaaQuery = space.db.schemaRegistry.query({});
81
- const schemas = await schemaaQuery.run();
82
- const onSchemaUpdate = ({ results }: { results: EchoSchema[] }) => (this._schema = results);
83
- this._schemaSubscription = schemaaQuery.subscribe(onSchemaUpdate);
84
- onSchemaUpdate({ results: schemas });
85
-
86
- this._objectsSubscription = space.db
87
- // TODO(burdon): ERROR: Cannot mix type and or filters.
88
- .query(Filter.not(Filter.or(Filter.schema(StoredSchema), Filter.schema(CollectionType))))
89
- .subscribe(
90
- ({ objects }) => {
91
- this._objects = objects;
92
-
93
- // Merge with current nodes.
94
- const currentNodes = this._graph.nodes;
95
-
96
- this._graph.nodes = [];
97
- this._graph.links = [];
98
-
99
- const addSchema = (typename: string) => {
100
- const current = currentNodes.find((node) => node.id === typename);
101
- if (typename) {
102
- this._graph.nodes.push({
103
- ...current,
104
- id: typename,
105
- type: 'schema',
106
- data: { typename },
107
- });
108
- }
109
- };
110
-
111
- // Runtime schema.
112
- space.db.graph.schemaRegistry.schemas.forEach((schema) => {
113
- const typename = getSchemaDXN(schema)?.typename;
114
- if (typename) {
115
- addSchema(typename);
116
- }
117
- });
118
-
119
- // Database Schema.
120
- this._schema?.forEach((schema) => {
121
- const typename = getSchemaDXN(schema)?.typename;
122
- if (typename) {
123
- addSchema(typename);
124
- }
125
- });
126
-
127
- // Database Objects.
128
- this._objects.forEach((object) => {
129
- const schema = getSchema(object);
130
- if (schema) {
131
- const typename = getSchemaDXN(schema)?.typename;
132
- if (typename) {
133
- const current = currentNodes.find((node) => node.id === object.id);
134
- this._graph.nodes.push({ ...current, id: object.id, type: 'object', data: { typename, object } });
135
-
136
- // Link to schema.
137
- const schemaNode = this._graph.nodes.find(
138
- (node) => node.type === 'schema' && node.data.typename === typename,
139
- );
140
- if (schemaNode) {
141
- this._graph.links.push({
142
- id: `${object.id}-${schemaNode.id}`,
143
- source: object.id,
144
- target: schemaNode.id,
145
- });
146
- } else {
147
- log.info('schema node not found', { typename });
148
- }
149
-
150
- // Link ot refs.
151
- // TODO(burdon): This isn't working.
152
- AST.getPropertySignatures(schema.ast).forEach((prop) => {
153
- if (!SchemaValidator.hasTypeAnnotation(schema, prop.name.toString(), ReferenceAnnotationId)) {
154
- return;
155
- }
156
-
157
- const value = object[String(prop.name)];
158
- if (value) {
159
- const refs = Array.isArray(value) ? value : [value];
160
- for (const ref of refs) {
161
- if (objects.findIndex((obj) => obj.id === ref.id) !== -1) {
162
- this._graph.links.push({
163
- id: `${object.id}-${String(prop.name)}-${ref.id}`,
164
- source: object.id,
165
- target: ref.id,
166
- });
167
- }
168
- }
169
- }
170
- });
171
- }
172
- }
173
- });
174
-
175
- this.triggerUpdate();
176
- },
177
- { fire: true },
178
- );
179
- }
180
-
181
- this.setSelected(objectId);
182
- return this;
183
- }
184
-
185
- close() {
186
- this._schemaSubscription?.();
187
- this._schemaSubscription = undefined;
188
- this._objectsSubscription?.();
189
- this._objectsSubscription = undefined;
190
-
191
- return this;
192
- }
193
- }
@@ -1,40 +0,0 @@
1
- //
2
- // Copyright 2023 DXOS.org
3
- //
4
-
5
- // TODO(burdon): Convert to common/graph.
6
- import { type GraphModel } from '@dxos/gem-spore';
7
-
8
- export type TreeNode = {
9
- id: string;
10
- label?: string;
11
- children?: TreeNode[];
12
- };
13
-
14
- export const mapGraphToTreeData = <N>(model: GraphModel<N>, maxDepth = 8): TreeNode | undefined => {
15
- const mapNode = (node: N, depth = 0): TreeNode => {
16
- const treeNode: TreeNode = {
17
- id: model.idAccessor(node),
18
- label: model.idAccessor(node).slice(0, 8),
19
- };
20
-
21
- const links = model.graph.links.filter((link) => link.source === treeNode.id);
22
- if (depth < maxDepth) {
23
- treeNode.children = links.map((link) =>
24
- mapNode(model.graph.nodes.find((node) => model.idAccessor(node) === link.target)!, depth + 1),
25
- );
26
- }
27
-
28
- return treeNode;
29
- };
30
-
31
- let data: TreeNode | undefined;
32
- if (model.selected) {
33
- const node = model.graph.nodes.find((node) => model.idAccessor(node) === model.selected);
34
- if (node) {
35
- data = mapNode(node);
36
- }
37
- }
38
-
39
- return data;
40
- };