@dxos/plugin-explorer 0.8.0 → 0.8.1-main.ae460ac
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.
- package/dist/lib/browser/{ExplorerContainer-GJTCBEM4.mjs → ExplorerContainer-T5CTMBIS.mjs} +2 -2
- package/dist/lib/{node-esm/chunk-BRJI3QC2.mjs → browser/chunk-SU3K2HL7.mjs} +240 -3
- package/dist/lib/{node-esm/chunk-BRJI3QC2.mjs.map → browser/chunk-SU3K2HL7.mjs.map} +4 -4
- package/dist/lib/browser/chunk-V23FAKIX.mjs +205 -0
- package/dist/lib/browser/chunk-V23FAKIX.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +7 -7
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{react-surface-3X2V3VPN.mjs → react-surface-Q7OT6GXC.mjs} +3 -3
- package/dist/lib/node/{ExplorerContainer-RJT54IOS.cjs → ExplorerContainer-SO5XAXFS.cjs} +6 -6
- package/dist/lib/node/chunk-6GTOKVKH.cjs +236 -0
- package/dist/lib/node/chunk-6GTOKVKH.cjs.map +7 -0
- package/dist/lib/node/{chunk-VSACDC6F.cjs → chunk-CQYBCGC4.cjs} +234 -8
- package/dist/lib/node/chunk-CQYBCGC4.cjs.map +7 -0
- package/dist/lib/node/index.cjs +10 -10
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/{react-surface-36YIY7NA.cjs → react-surface-5G52HSJW.cjs} +7 -7
- package/dist/lib/node-esm/{ExplorerContainer-TM3VIXVK.mjs → ExplorerContainer-DTUTEZLK.mjs} +2 -2
- package/dist/lib/{browser/chunk-S3QNIEBS.mjs → node-esm/chunk-4IST6Y3Z.mjs} +242 -2
- package/dist/lib/{browser/chunk-S3QNIEBS.mjs.map → node-esm/chunk-4IST6Y3Z.mjs.map} +4 -4
- package/dist/lib/node-esm/chunk-Q2IQDIKJ.mjs +207 -0
- package/dist/lib/node-esm/chunk-Q2IQDIKJ.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +7 -7
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{react-surface-YDY7IBMY.mjs → react-surface-QSQVINGP.mjs} +3 -3
- package/dist/types/src/components/Graph/Graph.d.ts +0 -3
- package/dist/types/src/components/Graph/Graph.d.ts.map +1 -1
- package/dist/types/src/components/Graph/Graph.stories.d.ts +1 -1
- package/dist/types/src/components/Graph/Graph.stories.d.ts.map +1 -1
- package/dist/types/src/components/Graph/graph-model.d.ts.map +1 -1
- package/dist/types/src/components/Tree/types.d.ts +1 -1
- package/dist/types/src/components/Tree/types.d.ts.map +1 -1
- package/package.json +24 -25
- package/src/components/Graph/Graph.stories.tsx +2 -2
- package/src/components/Graph/Graph.tsx +15 -142
- package/src/components/Graph/graph-model.ts +2 -0
- package/src/components/Tree/types.ts +2 -1
- package/dist/lib/browser/chunk-YQL7YE6N.mjs +0 -546
- package/dist/lib/browser/chunk-YQL7YE6N.mjs.map +0 -7
- package/dist/lib/node/chunk-VSACDC6F.cjs.map +0 -7
- package/dist/lib/node/chunk-YH4QYCZH.cjs +0 -567
- package/dist/lib/node/chunk-YH4QYCZH.cjs.map +0 -7
- package/dist/lib/node-esm/chunk-3KRWHGBM.mjs +0 -548
- package/dist/lib/node-esm/chunk-3KRWHGBM.mjs.map +0 -7
- /package/dist/lib/browser/{ExplorerContainer-GJTCBEM4.mjs.map → ExplorerContainer-T5CTMBIS.mjs.map} +0 -0
- /package/dist/lib/browser/{react-surface-3X2V3VPN.mjs.map → react-surface-Q7OT6GXC.mjs.map} +0 -0
- /package/dist/lib/node/{ExplorerContainer-RJT54IOS.cjs.map → ExplorerContainer-SO5XAXFS.cjs.map} +0 -0
- /package/dist/lib/node/{react-surface-36YIY7NA.cjs.map → react-surface-5G52HSJW.cjs.map} +0 -0
- /package/dist/lib/node-esm/{ExplorerContainer-TM3VIXVK.mjs.map → ExplorerContainer-DTUTEZLK.mjs.map} +0 -0
- /package/dist/lib/node-esm/{react-surface-YDY7IBMY.mjs.map → react-surface-QSQVINGP.mjs.map} +0 -0
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var chunk_6GTOKVKH_exports = {};
|
|
30
|
+
__export(chunk_6GTOKVKH_exports, {
|
|
31
|
+
Graph: () => Graph,
|
|
32
|
+
SpaceGraphModel: () => SpaceGraphModel
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(chunk_6GTOKVKH_exports);
|
|
35
|
+
var import_echo_schema = require("@dxos/echo-schema");
|
|
36
|
+
var import_gem_spore = require("@dxos/gem-spore");
|
|
37
|
+
var import_log = require("@dxos/log");
|
|
38
|
+
var import_types = require("@dxos/plugin-space/types");
|
|
39
|
+
var import_echo = require("@dxos/react-client/echo");
|
|
40
|
+
var import_d3 = require("d3");
|
|
41
|
+
var import_force_graph = __toESM(require("force-graph"));
|
|
42
|
+
var import_react = __toESM(require("react"));
|
|
43
|
+
var import_react_resize_detector = require("react-resize-detector");
|
|
44
|
+
var import_plugin_search = require("@dxos/plugin-search");
|
|
45
|
+
var import_react_ui = require("@dxos/react-ui");
|
|
46
|
+
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/plugins/experimental/plugin-explorer/src/components/Graph/graph-model.ts";
|
|
47
|
+
var SpaceGraphModel = class extends import_gem_spore.GraphModel {
|
|
48
|
+
constructor(_options = {}) {
|
|
49
|
+
super();
|
|
50
|
+
this._options = _options;
|
|
51
|
+
this._graph = {
|
|
52
|
+
nodes: [],
|
|
53
|
+
links: []
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
get graph() {
|
|
57
|
+
return this._graph;
|
|
58
|
+
}
|
|
59
|
+
get objects() {
|
|
60
|
+
return this._objects ?? [];
|
|
61
|
+
}
|
|
62
|
+
// TODO(burdon): Alternative diagram types:
|
|
63
|
+
// - https://observablehq.com/@d3/radial-tree/2
|
|
64
|
+
// - https://observablehq.com/@d3/disjoint-force-directed-graph/2
|
|
65
|
+
// - https://observablehq.com/@mbostock/tadpoles
|
|
66
|
+
// - https://observablehq.com/@d3/psr-b1919-21
|
|
67
|
+
// - https://vasturiano.github.io/react-force-graph/example/basic (3D)
|
|
68
|
+
async open(space, objectId) {
|
|
69
|
+
if (!this._schemaSubscription) {
|
|
70
|
+
const schemaaQuery = space.db.schemaRegistry.query({});
|
|
71
|
+
const schemas = await schemaaQuery.run();
|
|
72
|
+
const onSchemaUpdate = ({ results }) => this._schema = results;
|
|
73
|
+
this._schemaSubscription = schemaaQuery.subscribe(onSchemaUpdate);
|
|
74
|
+
onSchemaUpdate({
|
|
75
|
+
results: schemas
|
|
76
|
+
});
|
|
77
|
+
this._objectsSubscription = space.db.query(import_echo.Filter.not(import_echo.Filter.or(import_echo.Filter.schema(import_echo_schema.StoredSchema), import_echo.Filter.schema(import_types.CollectionType)))).subscribe(({ objects }) => {
|
|
78
|
+
this._objects = objects;
|
|
79
|
+
const currentNodes = this._graph.nodes;
|
|
80
|
+
this._graph.nodes = [];
|
|
81
|
+
this._graph.links = [];
|
|
82
|
+
const addSchema = (typename) => {
|
|
83
|
+
const current = currentNodes.find((node) => node.id === typename);
|
|
84
|
+
if (typename) {
|
|
85
|
+
this._graph.nodes.push({
|
|
86
|
+
...current,
|
|
87
|
+
id: typename,
|
|
88
|
+
type: "schema",
|
|
89
|
+
data: {
|
|
90
|
+
typename
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
space.db.graph.schemaRegistry.schemas.forEach((schema) => {
|
|
96
|
+
const typename = (0, import_echo_schema.getSchemaDXN)(schema)?.toTypename();
|
|
97
|
+
if (typename) {
|
|
98
|
+
addSchema(typename);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
this._schema?.forEach((schema) => {
|
|
102
|
+
const typename = (0, import_echo_schema.getSchemaDXN)(schema)?.toTypename();
|
|
103
|
+
if (typename) {
|
|
104
|
+
addSchema(typename);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
this._objects.forEach((object) => {
|
|
108
|
+
const schema = (0, import_echo_schema.getSchema)(object);
|
|
109
|
+
if (schema) {
|
|
110
|
+
const typename = (0, import_echo_schema.getSchemaDXN)(schema)?.toTypename();
|
|
111
|
+
if (typename) {
|
|
112
|
+
const current = currentNodes.find((node) => node.id === object.id);
|
|
113
|
+
this._graph.nodes.push({
|
|
114
|
+
...current,
|
|
115
|
+
id: object.id,
|
|
116
|
+
type: "object",
|
|
117
|
+
data: {
|
|
118
|
+
typename,
|
|
119
|
+
object
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
const schemaNode = this._graph.nodes.find((node) => node.type === "schema" && node.data.typename === typename);
|
|
123
|
+
if (schemaNode) {
|
|
124
|
+
this._graph.links.push({
|
|
125
|
+
id: `${object.id}-${schemaNode.id}`,
|
|
126
|
+
source: object.id,
|
|
127
|
+
target: schemaNode.id
|
|
128
|
+
});
|
|
129
|
+
} else {
|
|
130
|
+
import_log.log.info("schema node not found", {
|
|
131
|
+
typename
|
|
132
|
+
}, {
|
|
133
|
+
F: __dxlog_file,
|
|
134
|
+
L: 147,
|
|
135
|
+
S: this,
|
|
136
|
+
C: (f, a) => f(...a)
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
import_echo_schema.AST.getPropertySignatures(schema.ast).forEach((prop) => {
|
|
140
|
+
if (!import_echo_schema.SchemaValidator.hasTypeAnnotation(schema, prop.name.toString(), import_echo_schema.ReferenceAnnotationId)) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const value = object[String(prop.name)];
|
|
144
|
+
if (value) {
|
|
145
|
+
const refs = Array.isArray(value) ? value : [
|
|
146
|
+
value
|
|
147
|
+
];
|
|
148
|
+
for (const ref of refs) {
|
|
149
|
+
if (objects.findIndex((obj) => obj.id === ref.id) !== -1) {
|
|
150
|
+
this._graph.links.push({
|
|
151
|
+
id: `${object.id}-${String(prop.name)}-${ref.id}`,
|
|
152
|
+
source: object.id,
|
|
153
|
+
target: ref.id
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
this.triggerUpdate();
|
|
163
|
+
}, {
|
|
164
|
+
fire: true
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
this.setSelected(objectId);
|
|
168
|
+
return this;
|
|
169
|
+
}
|
|
170
|
+
close() {
|
|
171
|
+
this._schemaSubscription?.();
|
|
172
|
+
this._schemaSubscription = void 0;
|
|
173
|
+
this._objectsSubscription?.();
|
|
174
|
+
this._objectsSubscription = void 0;
|
|
175
|
+
return this;
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
var Graph = ({ space, match }) => {
|
|
179
|
+
const { ref, width, height } = (0, import_react_resize_detector.useResizeDetector)({
|
|
180
|
+
refreshRate: 200
|
|
181
|
+
});
|
|
182
|
+
const rootRef = (0, import_react.useRef)(null);
|
|
183
|
+
const forceGraph = (0, import_react.useRef)();
|
|
184
|
+
const [model] = (0, import_react_ui.useAsyncState)(async () => space ? new SpaceGraphModel({
|
|
185
|
+
schema: true
|
|
186
|
+
}).open(space) : void 0, [
|
|
187
|
+
space
|
|
188
|
+
]);
|
|
189
|
+
const filteredRef = (0, import_react.useRef)();
|
|
190
|
+
filteredRef.current = (0, import_plugin_search.filterObjectsSync)(model?.objects ?? [], match);
|
|
191
|
+
(0, import_react.useEffect)(() => {
|
|
192
|
+
if (rootRef.current) {
|
|
193
|
+
forceGraph.current = new import_force_graph.default(rootRef.current).nodeRelSize(6).nodeLabel((node) => {
|
|
194
|
+
if (node.type === "schema") {
|
|
195
|
+
return node.data.typename;
|
|
196
|
+
}
|
|
197
|
+
return node.id;
|
|
198
|
+
}).nodeAutoColorBy((node) => node.type === "schema" ? "schema" : node.data.typename).linkColor(() => "rgba(255,255,255,0.25)");
|
|
199
|
+
}
|
|
200
|
+
return () => {
|
|
201
|
+
forceGraph.current?.pauseAnimation().graphData({
|
|
202
|
+
nodes: [],
|
|
203
|
+
links: []
|
|
204
|
+
});
|
|
205
|
+
forceGraph.current = void 0;
|
|
206
|
+
};
|
|
207
|
+
}, []);
|
|
208
|
+
(0, import_react.useEffect)(() => {
|
|
209
|
+
if (forceGraph.current && width && height && model) {
|
|
210
|
+
forceGraph.current.pauseAnimation().width(width).height(height).onEngineStop(() => {
|
|
211
|
+
handleZoomToFit();
|
|
212
|
+
}).d3Force("link", (0, import_d3.forceLink)().distance(160).strength(0.5)).d3Force("charge", (0, import_d3.forceManyBody)().strength(-30)).graphData(model.graph).warmupTicks(100).cooldownTime(1e3).resumeAnimation();
|
|
213
|
+
}
|
|
214
|
+
}, [
|
|
215
|
+
model,
|
|
216
|
+
width,
|
|
217
|
+
height
|
|
218
|
+
]);
|
|
219
|
+
const handleZoomToFit = () => {
|
|
220
|
+
forceGraph.current?.zoomToFit(400, 40);
|
|
221
|
+
};
|
|
222
|
+
return /* @__PURE__ */ import_react.default.createElement("div", {
|
|
223
|
+
ref,
|
|
224
|
+
className: "relative grow",
|
|
225
|
+
onClick: handleZoomToFit
|
|
226
|
+
}, /* @__PURE__ */ import_react.default.createElement("div", {
|
|
227
|
+
ref: rootRef,
|
|
228
|
+
className: "absolute inset-0"
|
|
229
|
+
}));
|
|
230
|
+
};
|
|
231
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
232
|
+
0 && (module.exports = {
|
|
233
|
+
Graph,
|
|
234
|
+
SpaceGraphModel
|
|
235
|
+
});
|
|
236
|
+
//# sourceMappingURL=chunk-6GTOKVKH.cjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
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 UnsubscribeCallback } 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, type Subscription } 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?: UnsubscribeCallback;\n private _objects?: ReactiveEchoObject<any>[];\n private _objectsSubscription?: Subscription;\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)?.toTypename();\n if (typename) {\n addSchema(typename);\n }\n });\n\n // Database Schema.\n this._schema?.forEach((schema) => {\n const typename = getSchemaDXN(schema)?.toTypename();\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)?.toTypename();\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 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": ["SpaceGraphModel", "GraphModel", "constructor", "_options", "_graph", "nodes", "links", "graph", "objects", "_objects", "open", "space", "objectId", "_schemaSubscription", "schemaaQuery", "db", "schemaRegistry", "query", "schemas", "run", "onSchemaUpdate", "results", "_schema", "subscribe", "_objectsSubscription", "Filter", "not", "or", "schema", "StoredSchema", "CollectionType", "currentNodes", "addSchema", "typename", "current", "find", "node", "id", "push", "type", "data", "forEach", "getSchemaDXN", "toTypename", "object", "getSchema", "schemaNode", "source", "target", "log", "info", "AST", "getPropertySignatures", "ast", "prop", "SchemaValidator", "hasTypeAnnotation", "name", "toString", "ReferenceAnnotationId", "value", "String", "refs", "Array", "isArray", "ref", "findIndex", "obj", "triggerUpdate", "fire", "setSelected", "close", "undefined", "Graph", "match", "width", "height", "useResizeDetector", "refreshRate", "rootRef", "useRef", "forceGraph", "model", "useAsyncState", "filteredRef", "filterObjectsSync", "useEffect", "ForceGraph", "nodeRelSize", "nodeLabel", "nodeAutoColorBy", "linkColor", "pauseAnimation", "graphData", "onEngineStop", "handleZoomToFit", "d3Force", "forceLink", "distance", "strength", "forceManyBody", "warmupTicks", "cooldownTime", "resumeAnimation", "zoomToFit", "React", "div", "className", "onClick"]
|
|
7
|
+
}
|
|
@@ -26,13 +26,16 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
26
|
mod
|
|
27
27
|
));
|
|
28
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
-
var
|
|
30
|
-
__export(
|
|
29
|
+
var chunk_CQYBCGC4_exports = {};
|
|
30
|
+
__export(chunk_CQYBCGC4_exports, {
|
|
31
31
|
Chart: () => Chart,
|
|
32
32
|
ExplorerContainer: () => ExplorerContainer,
|
|
33
|
-
Globe: () => Globe
|
|
33
|
+
Globe: () => Globe,
|
|
34
|
+
Tree: () => Tree,
|
|
35
|
+
defaultTreeLayoutSlots: () => defaultTreeLayoutSlots
|
|
34
36
|
});
|
|
35
|
-
module.exports = __toCommonJS(
|
|
37
|
+
module.exports = __toCommonJS(chunk_CQYBCGC4_exports);
|
|
38
|
+
var import_chunk_6GTOKVKH = require("./chunk-6GTOKVKH.cjs");
|
|
36
39
|
var Plot = __toESM(require("@observablehq/plot"));
|
|
37
40
|
var import_react = __toESM(require("react"));
|
|
38
41
|
var import_react_resize_detector = require("react-resize-detector");
|
|
@@ -40,7 +43,14 @@ var Plot2 = __toESM(require("@observablehq/plot"));
|
|
|
40
43
|
var import_react2 = __toESM(require("react"));
|
|
41
44
|
var import_react_resize_detector2 = require("react-resize-detector");
|
|
42
45
|
var topojson = __toESM(require("topojson-client"));
|
|
43
|
-
var import_react3 = require("react");
|
|
46
|
+
var import_react3 = __toESM(require("react"));
|
|
47
|
+
var import_react_resize_detector3 = require("react-resize-detector");
|
|
48
|
+
var import_gem_core = require("@dxos/gem-core");
|
|
49
|
+
var import_react_ui = require("@dxos/react-ui");
|
|
50
|
+
var d3 = __toESM(require("d3"));
|
|
51
|
+
var d32 = __toESM(require("d3"));
|
|
52
|
+
var d33 = __toESM(require("d3"));
|
|
53
|
+
var import_react4 = require("react");
|
|
44
54
|
var createAdapter = (prop, accessor) => accessor ? {
|
|
45
55
|
transform: (values) => values.map((value) => accessor(value)[prop])
|
|
46
56
|
} : prop;
|
|
@@ -10844,11 +10854,227 @@ var Globe = ({ items = [], accessor, projection = "orthographic", options = defa
|
|
|
10844
10854
|
className: "grow p-4"
|
|
10845
10855
|
});
|
|
10846
10856
|
};
|
|
10847
|
-
var
|
|
10857
|
+
var HierarchicalEdgeBundling = (s, data, options) => {
|
|
10858
|
+
const svg = d3.select(s);
|
|
10859
|
+
svg.selectAll("*").remove();
|
|
10860
|
+
const { radius = 600, padding = 100, slots } = options;
|
|
10861
|
+
const root = d3.hierarchy(flatten(data));
|
|
10862
|
+
const tree3 = d3.cluster().size([
|
|
10863
|
+
2 * Math.PI,
|
|
10864
|
+
radius - padding
|
|
10865
|
+
]);
|
|
10866
|
+
const layout = tree3(addLinks(root));
|
|
10867
|
+
const node = svg.append("g").selectAll().data(layout.leaves()).join("g").attr("transform", (d) => `rotate(${d.x * (180 / Math.PI) - 90}) translate(${d.y},0)`).append("text").attr("class", slots?.text ?? "").attr("dy", "0.31em").attr("x", (d) => d.x < Math.PI ? 6 : -6).attr("text-anchor", (d) => d.x < Math.PI ? "start" : "end").attr("transform", (d) => d.x >= Math.PI ? "rotate(180)" : null).call((text) => text.text((d) => d.data.id.slice(0, 8)));
|
|
10868
|
+
const line = d3.lineRadial().curve(d3.curveBundle.beta(0.85)).radius((d) => d.y).angle((d) => d.x);
|
|
10869
|
+
const links = svg.append("g").selectAll().data(layout.leaves().flatMap((leaf) => leaf.outgoing)).join("path").style("mix-blend-mode", "multiply").attr("class", slots?.path ?? "").attr("d", ([i, o]) => {
|
|
10870
|
+
return line(i.path(o));
|
|
10871
|
+
}).each(function(d) {
|
|
10872
|
+
d.path = this;
|
|
10873
|
+
});
|
|
10874
|
+
};
|
|
10875
|
+
var addLinks = (root) => {
|
|
10876
|
+
const nodes = new Map(root.descendants().map((d) => [
|
|
10877
|
+
d.data.id,
|
|
10878
|
+
d
|
|
10879
|
+
]));
|
|
10880
|
+
const parents = root.descendants().reduce((map, d) => {
|
|
10881
|
+
if (d.children?.length) {
|
|
10882
|
+
map.set(d.data.id, d);
|
|
10883
|
+
}
|
|
10884
|
+
return map;
|
|
10885
|
+
}, /* @__PURE__ */ new Map());
|
|
10886
|
+
for (const d of root.leaves()) {
|
|
10887
|
+
const parent = parents.get(d.data.id);
|
|
10888
|
+
if (parent) {
|
|
10889
|
+
d.outgoing = parent.data.children?.slice(1).map((child) => {
|
|
10890
|
+
return [
|
|
10891
|
+
d,
|
|
10892
|
+
nodes.get(child.id)
|
|
10893
|
+
];
|
|
10894
|
+
}) ?? [];
|
|
10895
|
+
} else {
|
|
10896
|
+
d.outgoing = [];
|
|
10897
|
+
}
|
|
10898
|
+
}
|
|
10899
|
+
return root;
|
|
10900
|
+
};
|
|
10901
|
+
var flatten = (node) => {
|
|
10902
|
+
const clone = {
|
|
10903
|
+
id: node.id
|
|
10904
|
+
};
|
|
10905
|
+
if (node.children?.length) {
|
|
10906
|
+
const children = node.children.map((child) => flatten(child));
|
|
10907
|
+
clone.children = [
|
|
10908
|
+
{
|
|
10909
|
+
id: node.id
|
|
10910
|
+
},
|
|
10911
|
+
...children
|
|
10912
|
+
];
|
|
10913
|
+
}
|
|
10914
|
+
return clone;
|
|
10915
|
+
};
|
|
10916
|
+
var HierarchicalEdgeBundling_default = HierarchicalEdgeBundling;
|
|
10917
|
+
var RadialTree = (s, data, options) => {
|
|
10918
|
+
const svg = d32.select(s);
|
|
10919
|
+
svg.selectAll("*").remove();
|
|
10920
|
+
const { label, radius = 400, r = 4, slots } = options;
|
|
10921
|
+
const arc = 2 * Math.PI;
|
|
10922
|
+
const root = d32.hierarchy(data);
|
|
10923
|
+
const descendants = root.descendants();
|
|
10924
|
+
const getLabel = label === null ? null : descendants.map((d) => label(d.data));
|
|
10925
|
+
const layout = d32.tree().size([
|
|
10926
|
+
arc,
|
|
10927
|
+
radius
|
|
10928
|
+
]).separation((a, b) => (a.parent === b.parent ? 1 : 2) / a.depth);
|
|
10929
|
+
layout(root);
|
|
10930
|
+
svg.append("g").selectAll("path").data(root.links()).join("path").attr("class", slots?.path ?? "").attr("d", d32.linkRadial().angle((d) => d.x + Math.PI / 2).radius((d) => d.y));
|
|
10931
|
+
const node = svg.append("g").selectAll("a").data(root.descendants()).join("a").attr("transform", (d) => `rotate(${d.x * 180 / Math.PI}) translate(${d.y},0)`);
|
|
10932
|
+
node.append("circle").attr("class", slots?.node ?? "").attr("r", r);
|
|
10933
|
+
if (getLabel) {
|
|
10934
|
+
node.append("text").attr("transform", (d) => `rotate(${d.x >= Math.PI ? 180 : 0})`).attr("dy", "0.32em").attr("x", (d) => d.x < Math.PI === !d.children ? 6 : -6).attr("text-anchor", (d) => d.x < Math.PI === !d.children ? "start" : "end").attr("class", slots?.text ?? "").text((d, i) => getLabel[i]);
|
|
10935
|
+
}
|
|
10936
|
+
return svg.node();
|
|
10937
|
+
};
|
|
10938
|
+
var RadialTree_default = RadialTree;
|
|
10939
|
+
var TidyTree = (s, data, options) => {
|
|
10940
|
+
const svg = d33.select(s);
|
|
10941
|
+
svg.selectAll("*").remove();
|
|
10942
|
+
const { label, width, height, r = 4, padding = 4, margin = 60, slots } = options;
|
|
10943
|
+
const root = d33.hierarchy(data);
|
|
10944
|
+
const descendants = root.descendants();
|
|
10945
|
+
const getLabel = label == null ? null : descendants.map((d) => label(d.data));
|
|
10946
|
+
const dx = 16;
|
|
10947
|
+
const dy = width / (root.height + padding);
|
|
10948
|
+
const layout = d33.tree().nodeSize([
|
|
10949
|
+
dx,
|
|
10950
|
+
dy
|
|
10951
|
+
]);
|
|
10952
|
+
layout(root);
|
|
10953
|
+
let x0 = Infinity;
|
|
10954
|
+
let x1 = -x0;
|
|
10955
|
+
let y0 = Infinity;
|
|
10956
|
+
let y1 = -y0;
|
|
10957
|
+
root.each((d) => {
|
|
10958
|
+
if (d.x > x1) {
|
|
10959
|
+
x1 = d.x;
|
|
10960
|
+
}
|
|
10961
|
+
if (d.x < x0) {
|
|
10962
|
+
x0 = d.x;
|
|
10963
|
+
}
|
|
10964
|
+
if (d.y > y1) {
|
|
10965
|
+
y1 = d.y;
|
|
10966
|
+
}
|
|
10967
|
+
if (d.y < y0) {
|
|
10968
|
+
y0 = d.y;
|
|
10969
|
+
}
|
|
10970
|
+
});
|
|
10971
|
+
const sx = Math.min(2, Math.max(1, (height - margin * 2) / (x1 - x0)));
|
|
10972
|
+
const oy = -(width - (y1 - y0)) / 2;
|
|
10973
|
+
svg.append("g").selectAll("path").data(root.links()).join("path").attr("class", slots?.path ?? "").attr("d", d33.link(d33.curveBumpX).x((d) => d.y + oy).y((d) => d.x * sx));
|
|
10974
|
+
const node = svg.append("g").selectAll("a").data(root.descendants()).join("a").attr("transform", (d) => `translate(${d.y + oy},${d.x * sx})`);
|
|
10975
|
+
node.append("circle").attr("class", slots?.node ?? "").attr("r", r);
|
|
10976
|
+
if (getLabel) {
|
|
10977
|
+
node.append("text").attr("dy", "0.32em").attr("x", (d) => d.children ? -6 : 6).attr("text-anchor", (d) => d.children ? "end" : "start").attr("class", slots?.text ?? "").text((d, i) => getLabel[i]);
|
|
10978
|
+
}
|
|
10979
|
+
};
|
|
10980
|
+
var TidyTree_default = TidyTree;
|
|
10981
|
+
var mapGraphToTreeData = (model, maxDepth = 8) => {
|
|
10982
|
+
const mapNode = (node, depth = 0) => {
|
|
10983
|
+
const treeNode = {
|
|
10984
|
+
id: model.idAccessor(node),
|
|
10985
|
+
label: model.idAccessor(node).slice(0, 8)
|
|
10986
|
+
};
|
|
10987
|
+
const links = model.graph.links.filter((link2) => link2.source === treeNode.id);
|
|
10988
|
+
if (depth < maxDepth) {
|
|
10989
|
+
treeNode.children = links.map((link2) => mapNode(model.graph.nodes.find((node2) => model.idAccessor(node2) === link2.target), depth + 1));
|
|
10990
|
+
}
|
|
10991
|
+
return treeNode;
|
|
10992
|
+
};
|
|
10993
|
+
let data;
|
|
10994
|
+
if (model.selected) {
|
|
10995
|
+
const node = model.graph.nodes.find((node2) => model.idAccessor(node2) === model.selected);
|
|
10996
|
+
if (node) {
|
|
10997
|
+
data = mapNode(node);
|
|
10998
|
+
}
|
|
10999
|
+
}
|
|
11000
|
+
return data;
|
|
11001
|
+
};
|
|
11002
|
+
var defaultTreeLayoutSlots = {
|
|
11003
|
+
node: "fill-blue-600",
|
|
11004
|
+
path: "fill-none stroke-blue-400 stroke-[0.5px]",
|
|
11005
|
+
text: "stroke-[0.5px] stroke-neutral-700 text-xs"
|
|
11006
|
+
};
|
|
11007
|
+
var renderers = /* @__PURE__ */ new Map([
|
|
11008
|
+
[
|
|
11009
|
+
"tidy",
|
|
11010
|
+
TidyTree_default
|
|
11011
|
+
],
|
|
11012
|
+
[
|
|
11013
|
+
"radial",
|
|
11014
|
+
RadialTree_default
|
|
11015
|
+
],
|
|
11016
|
+
[
|
|
11017
|
+
"edge",
|
|
11018
|
+
HierarchicalEdgeBundling_default
|
|
11019
|
+
]
|
|
11020
|
+
]);
|
|
11021
|
+
var Tree = ({ space, selected, variant = "tidy", onNodeClick }) => {
|
|
11022
|
+
const [model] = (0, import_react_ui.useAsyncState)(async () => space ? new import_chunk_6GTOKVKH.SpaceGraphModel().open(space, selected) : void 0, [
|
|
11023
|
+
space,
|
|
11024
|
+
selected
|
|
11025
|
+
]);
|
|
11026
|
+
const [tree3, setTree] = (0, import_react3.useState)();
|
|
11027
|
+
(0, import_react3.useEffect)(() => {
|
|
11028
|
+
return model?.subscribe(() => {
|
|
11029
|
+
const tree4 = mapGraphToTreeData(model);
|
|
11030
|
+
setTree(tree4);
|
|
11031
|
+
}, true);
|
|
11032
|
+
}, [
|
|
11033
|
+
model
|
|
11034
|
+
]);
|
|
11035
|
+
const context = (0, import_gem_core.createSvgContext)();
|
|
11036
|
+
const { ref, width = 0, height = 0 } = (0, import_react_resize_detector3.useResizeDetector)();
|
|
11037
|
+
(0, import_react3.useEffect)(() => {
|
|
11038
|
+
if (width && height) {
|
|
11039
|
+
const size = Math.min(width, height);
|
|
11040
|
+
const radius = size * 0.4;
|
|
11041
|
+
const options = {
|
|
11042
|
+
// TODO(burdon): Type.
|
|
11043
|
+
label: (d) => d.label ?? d.id,
|
|
11044
|
+
width,
|
|
11045
|
+
height,
|
|
11046
|
+
radius,
|
|
11047
|
+
marginLeft: (width - radius * 2) / 2,
|
|
11048
|
+
marginRight: (width - radius * 2) / 2,
|
|
11049
|
+
marginTop: (height - radius * 2) / 2,
|
|
11050
|
+
marginBottom: (height - radius * 2) / 2,
|
|
11051
|
+
slots: defaultTreeLayoutSlots
|
|
11052
|
+
};
|
|
11053
|
+
if (tree3) {
|
|
11054
|
+
const renderer = renderers.get(variant);
|
|
11055
|
+
renderer?.(context.ref.current, tree3, options);
|
|
11056
|
+
}
|
|
11057
|
+
}
|
|
11058
|
+
}, [
|
|
11059
|
+
tree3,
|
|
11060
|
+
width,
|
|
11061
|
+
height
|
|
11062
|
+
]);
|
|
11063
|
+
return /* @__PURE__ */ import_react3.default.createElement("div", {
|
|
11064
|
+
ref,
|
|
11065
|
+
className: "flex grow overflow-hidden",
|
|
11066
|
+
onClick: () => onNodeClick?.()
|
|
11067
|
+
}, /* @__PURE__ */ import_react3.default.createElement(import_gem_core.SVGRoot, {
|
|
11068
|
+
context
|
|
11069
|
+
}, /* @__PURE__ */ import_react3.default.createElement(import_gem_core.SVG, null)));
|
|
11070
|
+
};
|
|
11071
|
+
var ExplorerContainer = (0, import_react4.lazy)(() => import("./ExplorerContainer-SO5XAXFS.cjs"));
|
|
10848
11072
|
// Annotate the CommonJS export names for ESM import in node:
|
|
10849
11073
|
0 && (module.exports = {
|
|
10850
11074
|
Chart,
|
|
10851
11075
|
ExplorerContainer,
|
|
10852
|
-
Globe
|
|
11076
|
+
Globe,
|
|
11077
|
+
Tree,
|
|
11078
|
+
defaultTreeLayoutSlots
|
|
10853
11079
|
});
|
|
10854
|
-
//# sourceMappingURL=chunk-
|
|
11080
|
+
//# sourceMappingURL=chunk-CQYBCGC4.cjs.map
|