@dxos/plugin-explorer 0.7.5-staging.b81e783 → 0.8.0

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 (45) hide show
  1. package/dist/lib/browser/{ExplorerContainer-A7UBZ3QP.mjs → ExplorerContainer-GJTCBEM4.mjs} +2 -2
  2. package/dist/lib/browser/{chunk-DTAFIUA7.mjs → chunk-S3QNIEBS.mjs} +2 -2
  3. package/dist/lib/browser/{chunk-5GTLMW4Q.mjs → chunk-YQL7YE6N.mjs} +171 -100
  4. package/dist/lib/browser/chunk-YQL7YE6N.mjs.map +7 -0
  5. package/dist/lib/browser/index.mjs +3 -3
  6. package/dist/lib/browser/meta.json +1 -1
  7. package/dist/lib/browser/{react-surface-EGSBRYNS.mjs → react-surface-3X2V3VPN.mjs} +3 -3
  8. package/dist/lib/node/{ExplorerContainer-ZV2YKOUE.cjs → ExplorerContainer-RJT54IOS.cjs} +6 -6
  9. package/dist/lib/node/{chunk-4H2Y5RER.cjs → chunk-VSACDC6F.cjs} +5 -5
  10. package/dist/lib/node/{chunk-WHMJ2VQ2.cjs → chunk-YH4QYCZH.cjs} +168 -97
  11. package/dist/lib/node/chunk-YH4QYCZH.cjs.map +7 -0
  12. package/dist/lib/node/index.cjs +10 -10
  13. package/dist/lib/node/meta.json +1 -1
  14. package/dist/lib/node/{react-surface-6B67W6YP.cjs → react-surface-36YIY7NA.cjs} +7 -7
  15. package/dist/lib/node-esm/{ExplorerContainer-JXY6XN2D.mjs → ExplorerContainer-TM3VIXVK.mjs} +2 -2
  16. package/dist/lib/node-esm/{chunk-WTGQFG6L.mjs → chunk-3KRWHGBM.mjs} +171 -100
  17. package/dist/lib/node-esm/chunk-3KRWHGBM.mjs.map +7 -0
  18. package/dist/lib/node-esm/{chunk-HIMBUOZ3.mjs → chunk-BRJI3QC2.mjs} +2 -2
  19. package/dist/lib/node-esm/index.mjs +3 -3
  20. package/dist/lib/node-esm/meta.json +1 -1
  21. package/dist/lib/node-esm/{react-surface-72EIBLSU.mjs → react-surface-YDY7IBMY.mjs} +3 -3
  22. package/dist/types/src/components/Globe/Globe.d.ts +1 -1
  23. package/dist/types/src/components/Globe/Globe.d.ts.map +1 -1
  24. package/dist/types/src/components/Graph/Graph.d.ts +2 -0
  25. package/dist/types/src/components/Graph/Graph.d.ts.map +1 -1
  26. package/dist/types/src/components/Graph/graph-model.d.ts +16 -10
  27. package/dist/types/src/components/Graph/graph-model.d.ts.map +1 -1
  28. package/dist/types/src/components/Tree/Tree.d.ts.map +1 -1
  29. package/dist/types/src/types/schema.d.ts +2 -2
  30. package/package.json +25 -24
  31. package/src/components/Graph/Graph.tsx +92 -26
  32. package/src/components/Graph/graph-model.ts +127 -73
  33. package/src/components/Tree/Tree.tsx +7 -2
  34. package/dist/lib/browser/chunk-5GTLMW4Q.mjs.map +0 -7
  35. package/dist/lib/node/chunk-WHMJ2VQ2.cjs.map +0 -7
  36. package/dist/lib/node-esm/chunk-WTGQFG6L.mjs.map +0 -7
  37. /package/dist/lib/browser/{ExplorerContainer-A7UBZ3QP.mjs.map → ExplorerContainer-GJTCBEM4.mjs.map} +0 -0
  38. /package/dist/lib/browser/{chunk-DTAFIUA7.mjs.map → chunk-S3QNIEBS.mjs.map} +0 -0
  39. /package/dist/lib/browser/{react-surface-EGSBRYNS.mjs.map → react-surface-3X2V3VPN.mjs.map} +0 -0
  40. /package/dist/lib/node/{ExplorerContainer-ZV2YKOUE.cjs.map → ExplorerContainer-RJT54IOS.cjs.map} +0 -0
  41. /package/dist/lib/node/{chunk-4H2Y5RER.cjs.map → chunk-VSACDC6F.cjs.map} +0 -0
  42. /package/dist/lib/node/{react-surface-6B67W6YP.cjs.map → react-surface-36YIY7NA.cjs.map} +0 -0
  43. /package/dist/lib/node-esm/{ExplorerContainer-JXY6XN2D.mjs.map → ExplorerContainer-TM3VIXVK.mjs.map} +0 -0
  44. /package/dist/lib/node-esm/{chunk-HIMBUOZ3.mjs.map → chunk-BRJI3QC2.mjs.map} +0 -0
  45. /package/dist/lib/node-esm/{react-surface-72EIBLSU.mjs.map → react-surface-YDY7IBMY.mjs.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Graph
3
- } from "./chunk-5GTLMW4Q.mjs";
3
+ } from "./chunk-YQL7YE6N.mjs";
4
4
 
5
5
  // packages/plugins/experimental/plugin-explorer/src/components/ExplorerContainer.tsx
6
6
  import React from "react";
@@ -25,4 +25,4 @@ var ExplorerContainer_default = ExplorerContainer;
25
25
  export {
26
26
  ExplorerContainer_default as default
27
27
  };
28
- //# sourceMappingURL=ExplorerContainer-A7UBZ3QP.mjs.map
28
+ //# sourceMappingURL=ExplorerContainer-GJTCBEM4.mjs.map
@@ -10822,11 +10822,11 @@ var Globe = ({ items = [], accessor, projection = "orthographic", options = defa
10822
10822
 
10823
10823
  // packages/plugins/experimental/plugin-explorer/src/components/index.ts
10824
10824
  import { lazy } from "react";
10825
- var ExplorerContainer = lazy(() => import("./ExplorerContainer-A7UBZ3QP.mjs"));
10825
+ var ExplorerContainer = lazy(() => import("./ExplorerContainer-GJTCBEM4.mjs"));
10826
10826
 
10827
10827
  export {
10828
10828
  Chart,
10829
10829
  Globe,
10830
10830
  ExplorerContainer
10831
10831
  };
10832
- //# sourceMappingURL=chunk-DTAFIUA7.mjs.map
10832
+ //# sourceMappingURL=chunk-S3QNIEBS.mjs.map
@@ -1,9 +1,9 @@
1
1
  // packages/plugins/experimental/plugin-explorer/src/components/Graph/graph-model.ts
2
- import { AST, EchoSchema, ReferenceAnnotationId, SchemaValidator, StoredSchema } from "@dxos/echo-schema";
2
+ import { getSchema, getSchemaDXN, AST, ReferenceAnnotationId, SchemaValidator, StoredSchema } from "@dxos/echo-schema";
3
3
  import { GraphModel } from "@dxos/gem-spore";
4
4
  import { log } from "@dxos/log";
5
5
  import { CollectionType } from "@dxos/plugin-space/types";
6
- import { getSchema, getType } from "@dxos/react-client/echo";
6
+ import { Filter } from "@dxos/react-client/echo";
7
7
  var __dxlog_file = "/home/runner/work/dxos/dxos/packages/plugins/experimental/plugin-explorer/src/components/Graph/graph-model.ts";
8
8
  var SpaceGraphModel = class extends GraphModel {
9
9
  constructor(_options = {}) {
@@ -20,79 +20,106 @@ var SpaceGraphModel = class extends GraphModel {
20
20
  get objects() {
21
21
  return this._objects ?? [];
22
22
  }
23
- open(space, objectId) {
24
- if (!this._subscription) {
25
- const query = space.db.query((object) => !(object instanceof CollectionType));
26
- this._subscription = query.subscribe(({ objects }) => {
23
+ // TODO(burdon): Alternative diagram types:
24
+ // - https://observablehq.com/@d3/radial-tree/2
25
+ // - https://observablehq.com/@d3/disjoint-force-directed-graph/2
26
+ // - https://observablehq.com/@mbostock/tadpoles
27
+ // - https://observablehq.com/@d3/psr-b1919-21
28
+ // - https://vasturiano.github.io/react-force-graph/example/basic (3D)
29
+ async open(space, objectId) {
30
+ if (!this._schemaSubscription) {
31
+ const schemaaQuery = space.db.schemaRegistry.query({});
32
+ const schemas = await schemaaQuery.run();
33
+ const onSchemaUpdate = ({ results }) => this._schema = results;
34
+ this._schemaSubscription = schemaaQuery.subscribe(onSchemaUpdate);
35
+ onSchemaUpdate({
36
+ results: schemas
37
+ });
38
+ this._objectsSubscription = space.db.query(Filter.not(Filter.or(Filter.schema(StoredSchema), Filter.schema(CollectionType)))).subscribe(({ objects }) => {
27
39
  this._objects = objects;
28
- this._graph.nodes = objects.map((object) => {
29
- if (object instanceof StoredSchema) {
30
- const effectSchema = space.db.schemaRegistry.getSchemaById(object.id);
31
- return {
40
+ const currentNodes = this._graph.nodes;
41
+ this._graph.nodes = [];
42
+ this._graph.links = [];
43
+ const addSchema = (typename) => {
44
+ const current = currentNodes.find((node) => node.id === typename);
45
+ if (typename) {
46
+ this._graph.nodes.push({
47
+ ...current,
48
+ id: typename,
32
49
  type: "schema",
33
- id: object.id,
34
- schema: effectSchema.schema
35
- };
36
- }
37
- return {
38
- type: "echo-object",
39
- id: object.id,
40
- object
41
- };
42
- });
43
- this._graph.links = objects.reduce((links, object) => {
44
- const objectSchema = getSchema(object);
45
- const typename = getType(object)?.objectId;
46
- if (objectSchema == null || typename == null) {
47
- log.info("no schema for object:", {
48
- id: object.id.slice(0, 8)
49
- }, {
50
- F: __dxlog_file,
51
- L: 72,
52
- S: this,
53
- C: (f, a) => f(...a)
50
+ data: {
51
+ typename
52
+ }
54
53
  });
55
- return links;
56
54
  }
57
- if (!(objectSchema instanceof EchoSchema)) {
58
- const idx = objects.findIndex((obj) => obj.id === typename);
59
- if (idx === -1) {
60
- this._graph.nodes.push({
61
- id: typename,
62
- type: "schema",
63
- schema: objectSchema
64
- });
65
- }
55
+ };
56
+ space.db.graph.schemaRegistry.schemas.forEach((schema) => {
57
+ const typename = getSchemaDXN(schema)?.toTypename();
58
+ if (typename) {
59
+ addSchema(typename);
66
60
  }
67
- if (this._options.schema) {
68
- links.push({
69
- id: `${object.id}-${typename}`,
70
- source: object.id,
71
- target: typename
72
- });
61
+ });
62
+ this._schema?.forEach((schema) => {
63
+ const typename = getSchemaDXN(schema)?.toTypename();
64
+ if (typename) {
65
+ addSchema(typename);
73
66
  }
74
- AST.getPropertySignatures(objectSchema.ast).forEach((prop) => {
75
- if (!SchemaValidator.hasTypeAnnotation(objectSchema, prop.name.toString(), ReferenceAnnotationId)) {
76
- return;
77
- }
78
- const value = object[String(prop.name)];
79
- if (value) {
80
- const refs = Array.isArray(value) ? value : [
81
- value
82
- ];
83
- for (const ref of refs) {
84
- if (objects.findIndex((obj) => obj.id === ref.id) !== -1) {
85
- links.push({
86
- id: `${object.id}-${String(prop.name)}-${ref.id}`,
87
- source: object.id,
88
- target: ref.id
89
- });
67
+ });
68
+ this._objects.forEach((object) => {
69
+ const schema = getSchema(object);
70
+ if (schema) {
71
+ const typename = getSchemaDXN(schema)?.toTypename();
72
+ if (typename) {
73
+ const current = currentNodes.find((node) => node.id === object.id);
74
+ this._graph.nodes.push({
75
+ ...current,
76
+ id: object.id,
77
+ type: "object",
78
+ data: {
79
+ typename,
80
+ object
90
81
  }
82
+ });
83
+ const schemaNode = this._graph.nodes.find((node) => node.type === "schema" && node.data.typename === typename);
84
+ if (schemaNode) {
85
+ this._graph.links.push({
86
+ id: `${object.id}-${schemaNode.id}`,
87
+ source: object.id,
88
+ target: schemaNode.id
89
+ });
90
+ } else {
91
+ log.info("schema node not found", {
92
+ typename
93
+ }, {
94
+ F: __dxlog_file,
95
+ L: 145,
96
+ S: this,
97
+ C: (f, a) => f(...a)
98
+ });
91
99
  }
100
+ AST.getPropertySignatures(schema.ast).forEach((prop) => {
101
+ if (!SchemaValidator.hasTypeAnnotation(schema, prop.name.toString(), ReferenceAnnotationId)) {
102
+ return;
103
+ }
104
+ const value = object[String(prop.name)];
105
+ if (value) {
106
+ const refs = Array.isArray(value) ? value : [
107
+ value
108
+ ];
109
+ for (const ref of refs) {
110
+ if (objects.findIndex((obj) => obj.id === ref.id) !== -1) {
111
+ this._graph.links.push({
112
+ id: `${object.id}-${String(prop.name)}-${ref.id}`,
113
+ source: object.id,
114
+ target: ref.id
115
+ });
116
+ }
117
+ }
118
+ }
119
+ });
92
120
  }
93
- });
94
- return links;
95
- }, []);
121
+ }
122
+ });
96
123
  this.triggerUpdate();
97
124
  }, {
98
125
  fire: true
@@ -102,18 +129,19 @@ var SpaceGraphModel = class extends GraphModel {
102
129
  return this;
103
130
  }
104
131
  close() {
105
- if (this._subscription) {
106
- this._subscription();
107
- this._subscription = void 0;
108
- }
132
+ this._schemaSubscription?.();
133
+ this._schemaSubscription = void 0;
134
+ this._objectsSubscription?.();
135
+ this._objectsSubscription = void 0;
109
136
  return this;
110
137
  }
111
138
  };
112
139
 
113
140
  // packages/plugins/experimental/plugin-explorer/src/components/Tree/Tree.tsx
114
- import React2, { useEffect as useEffect2, useMemo as useMemo2, useState as useState2 } from "react";
115
- import { useResizeDetector } from "react-resize-detector";
141
+ import React2, { useEffect as useEffect2, useState as useState2 } from "react";
142
+ import { useResizeDetector as useResizeDetector2 } from "react-resize-detector";
116
143
  import { createSvgContext as createSvgContext2, SVG as SVG2, SVGRoot as SVGRoot2 } from "@dxos/gem-core";
144
+ import { useAsyncState as useAsyncState2 } from "@dxos/react-ui";
117
145
 
118
146
  // packages/plugins/experimental/plugin-explorer/src/components/Tree/layout/HierarchicalEdgeBundling.ts
119
147
  import * as d3 from "d3";
@@ -272,12 +300,15 @@ var mapGraphToTreeData = (model, maxDepth = 8) => {
272
300
  };
273
301
 
274
302
  // packages/plugins/experimental/plugin-explorer/src/components/Graph/Graph.tsx
303
+ import { forceLink, forceManyBody } from "d3";
304
+ import ForceGraph from "force-graph";
275
305
  import React, { useEffect, useMemo, useRef, useState } from "react";
276
- import { getType as getType2 } from "@dxos/client/echo";
306
+ import { useResizeDetector } from "react-resize-detector";
307
+ import { getTypename } from "@dxos/client/echo";
277
308
  import { createSvgContext, defaultGridStyles, Grid, SVG, SVGRoot, Zoom } from "@dxos/gem-core";
278
309
  import { defaultStyles, Graph as GraphComponent, GraphForceProjector, Markers } from "@dxos/gem-spore";
279
310
  import { filterObjectsSync } from "@dxos/plugin-search";
280
- import { useThemeContext } from "@dxos/react-ui";
311
+ import { useAsyncState, useThemeContext } from "@dxos/react-ui";
281
312
  import { mx } from "@dxos/react-ui-theme";
282
313
  import "@dxos/gem-spore/styles";
283
314
  var slots = {};
@@ -293,14 +324,14 @@ var colors = [
293
324
  "[&>circle]:!fill-teal-300 [&>circle]:!stroke-teal-600",
294
325
  "[&>circle]:!fill-indigo-300 [&>circle]:!stroke-indigo-600"
295
326
  ];
296
- var Graph = ({ space, match }) => {
297
- const model = useMemo(() => space ? new SpaceGraphModel({
327
+ var Graph = ({ space, match, grid, svg }) => {
328
+ const { themeMode } = useThemeContext();
329
+ const [selected, setSelected] = useState();
330
+ const [model] = useAsyncState(async () => space ? new SpaceGraphModel({
298
331
  schema: true
299
332
  }).open(space) : void 0, [
300
333
  space
301
334
  ]);
302
- const [selected, setSelected] = useState();
303
- const { themeMode } = useThemeContext();
304
335
  const context = createSvgContext();
305
336
  const projector = useMemo(() => new GraphForceProjector(context, {
306
337
  forces: {
@@ -308,15 +339,15 @@ var Graph = ({ space, match }) => {
308
339
  strength: -100
309
340
  },
310
341
  link: {
311
- distance: 180
342
+ distance: 100
312
343
  },
313
344
  radial: {
314
- radius: 200,
345
+ radius: 150,
315
346
  strength: 0.05
316
347
  }
317
348
  },
318
349
  attributes: {
319
- radius: (node) => node.data?.type === "schema" ? 24 : 12
350
+ radius: (node) => node.data?.type === "schema" ? 12 : 8
320
351
  }
321
352
  }), []);
322
353
  const filteredRef = useRef();
@@ -327,8 +358,49 @@ var Graph = ({ space, match }) => {
327
358
  match
328
359
  ]);
329
360
  const [colorMap] = useState(/* @__PURE__ */ new Map());
330
- if (!model) {
331
- return null;
361
+ const { ref, width, height } = useResizeDetector();
362
+ const rootRef = useRef(null);
363
+ const forceGraph = useRef();
364
+ useEffect(() => {
365
+ if (rootRef.current) {
366
+ forceGraph.current = new ForceGraph(rootRef.current).nodeRelSize(6).nodeLabel((node) => {
367
+ if (node.type === "schema") {
368
+ return node.data.typename;
369
+ }
370
+ return node.id;
371
+ }).nodeAutoColorBy((node) => node.type === "schema" ? "schema" : node.data.typename).linkColor(() => "rgba(255,255,255,0.25)");
372
+ }
373
+ return () => {
374
+ forceGraph.current?.pauseAnimation().graphData({
375
+ nodes: [],
376
+ links: []
377
+ });
378
+ forceGraph.current = void 0;
379
+ };
380
+ }, []);
381
+ useEffect(() => {
382
+ if (forceGraph.current && width && height && model) {
383
+ forceGraph.current.pauseAnimation().width(width).height(height).onEngineStop(() => {
384
+ forceGraph.current?.zoomToFit(400, 40);
385
+ }).d3Force("link", forceLink().distance(160).strength(0.5)).d3Force("charge", forceManyBody().strength(-30)).warmupTicks(100).graphData(model.graph).resumeAnimation();
386
+ }
387
+ }, [
388
+ model,
389
+ width,
390
+ height
391
+ ]);
392
+ const handleZoomToFit = () => {
393
+ forceGraph.current?.zoomToFit(400, 40);
394
+ };
395
+ if (!svg) {
396
+ return /* @__PURE__ */ React.createElement("div", {
397
+ ref,
398
+ className: "relative grow",
399
+ onClick: handleZoomToFit
400
+ }, /* @__PURE__ */ React.createElement("div", {
401
+ ref: rootRef,
402
+ className: "absolute inset-0"
403
+ }));
332
404
  }
333
405
  if (selected) {
334
406
  return /* @__PURE__ */ React.createElement(Tree, {
@@ -344,7 +416,7 @@ var Graph = ({ space, match }) => {
344
416
  className: mx(defaultStyles, slots?.root?.className)
345
417
  }, /* @__PURE__ */ React.createElement(Markers, {
346
418
  arrowSize: 6
347
- }), /* @__PURE__ */ React.createElement(Grid, {
419
+ }), grid && /* @__PURE__ */ React.createElement(Grid, {
348
420
  className: slots?.grid?.className ?? defaultGridStyles(themeMode)
349
421
  }), /* @__PURE__ */ React.createElement(Zoom, {
350
422
  extent: [
@@ -369,27 +441,26 @@ var Graph = ({ space, match }) => {
369
441
  node: (node) => {
370
442
  let className;
371
443
  if (node.data) {
372
- const typename = getType2(node.data)?.objectId;
373
- if (typename) {
374
- className = colorMap.get(typename);
375
- if (!className) {
376
- className = colors[colorMap.size % colors.length];
377
- colorMap.set(typename, className);
444
+ const { object } = node.data;
445
+ if (object) {
446
+ const typename = getTypename(object);
447
+ if (typename) {
448
+ className = colorMap.get(typename);
449
+ if (!className) {
450
+ className = colors[colorMap.size % colors.length];
451
+ colorMap.set(typename, className);
452
+ }
378
453
  }
379
454
  }
380
455
  }
381
456
  const selected2 = filteredRef.current?.some((object) => object.id === node.data?.id);
457
+ const blur = !selected2 && !!filteredRef.current?.length;
382
458
  return {
383
- class: mx(filteredRef.current?.length ? selected2 ? [
384
- className
385
- ] : "[&>text]:!fill-neutral-300" : [
386
- "[&>text]:!fill-neutral-700",
387
- className
388
- ])
459
+ class: mx(className, blur && "opacity-70")
389
460
  };
390
461
  },
391
462
  link: () => ({
392
- class: "[&>path]:!stroke-neutral-300"
463
+ class: "[&>path]:!stroke-neutral-300 dark:[&>path]:!stroke-neutral-700"
393
464
  })
394
465
  }
395
466
  }))));
@@ -416,7 +487,7 @@ var renderers = /* @__PURE__ */ new Map([
416
487
  ]
417
488
  ]);
418
489
  var Tree = ({ space, selected, variant = "tidy", onNodeClick }) => {
419
- const model = useMemo2(() => space ? new SpaceGraphModel().open(space, selected) : void 0, [
490
+ const [model] = useAsyncState2(async () => space ? new SpaceGraphModel().open(space, selected) : void 0, [
420
491
  space,
421
492
  selected
422
493
  ]);
@@ -430,7 +501,7 @@ var Tree = ({ space, selected, variant = "tidy", onNodeClick }) => {
430
501
  model
431
502
  ]);
432
503
  const context = createSvgContext2();
433
- const { ref, width = 0, height = 0 } = useResizeDetector();
504
+ const { ref, width = 0, height = 0 } = useResizeDetector2();
434
505
  useEffect2(() => {
435
506
  if (width && height) {
436
507
  const size = Math.min(width, height);
@@ -472,4 +543,4 @@ export {
472
543
  Tree,
473
544
  Graph
474
545
  };
475
- //# sourceMappingURL=chunk-5GTLMW4Q.mjs.map
546
+ //# sourceMappingURL=chunk-YQL7YE6N.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/components/Graph/graph-model.ts", "../../../src/components/Tree/Tree.tsx", "../../../src/components/Tree/layout/HierarchicalEdgeBundling.ts", "../../../src/components/Tree/layout/RadialTree.ts", "../../../src/components/Tree/layout/TidyTree.ts", "../../../src/components/Tree/types.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\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 React, { useEffect, useState } from 'react';\nimport { useResizeDetector } from 'react-resize-detector';\n\nimport { type Space } from '@dxos/client/echo';\nimport { createSvgContext, SVG, SVGRoot } from '@dxos/gem-core';\nimport { useAsyncState } from '@dxos/react-ui';\n\nimport { HierarchicalEdgeBundling, RadialTree, TidyTree } from './layout';\nimport { mapGraphToTreeData, type TreeNode } from './types';\nimport { SpaceGraphModel } from '../Graph';\n\n// TODO(burdon): Create dge bundling graph using d3.hierarchy.\n// https://observablehq.com/@d3/hierarchical-edge-bundling?intent=fork\n\ntype Renderer = (svg: SVGSVGElement, data: any, options: any) => void;\n\nexport type LayoutVariant = 'tidy' | 'radial' | 'edge';\n\n// TODO(burdon): Remove slots?\nexport type TreeLayoutSlots = {\n node?: string;\n path?: string;\n text?: string;\n};\n\nexport type TreeOptions = {\n label: (d: any) => string;\n\n slots?: TreeLayoutSlots;\n radius?: number;\n\n width: number;\n height: number;\n margin?: number;\n\n padding?: number;\n // Radius of nodes.\n r?: number;\n};\n\nexport const defaultTreeLayoutSlots: TreeLayoutSlots = {\n node: 'fill-blue-600',\n path: 'fill-none stroke-blue-400 stroke-[0.5px]',\n text: 'stroke-[0.5px] stroke-neutral-700 text-xs', // TODO(burdon): Create box instead of halo.\n};\n\nconst renderers = new Map<LayoutVariant, Renderer>([\n ['tidy', TidyTree],\n ['radial', RadialTree],\n ['edge', HierarchicalEdgeBundling],\n]);\n\nexport type TreeComponentProps<N = unknown> = {\n space: Space;\n selected?: string;\n variant?: LayoutVariant;\n onNodeClick?: (node?: N) => void;\n};\n\n// TODO(burdon): Label accessor.\nexport const Tree = <N,>({ space, selected, variant = 'tidy', onNodeClick }: TreeComponentProps<N>) => {\n const [model] = useAsyncState(\n async () => (space ? new SpaceGraphModel().open(space, selected) : undefined),\n [space, selected],\n );\n\n const [tree, setTree] = useState<TreeNode>();\n useEffect(() => {\n return model?.subscribe(() => {\n const tree = mapGraphToTreeData(model);\n setTree(tree);\n }, true);\n }, [model]);\n\n const context = createSvgContext();\n const { ref, width = 0, height = 0 } = useResizeDetector();\n\n useEffect(() => {\n if (width && height) {\n const size = Math.min(width, height);\n const radius = size * 0.4;\n const options = {\n // TODO(burdon): Type.\n label: (d: any) => d.label ?? d.id,\n width,\n height,\n radius,\n marginLeft: (width - radius * 2) / 2,\n marginRight: (width - radius * 2) / 2,\n marginTop: (height - radius * 2) / 2,\n marginBottom: (height - radius * 2) / 2,\n slots: defaultTreeLayoutSlots,\n };\n\n if (tree) {\n const renderer = renderers.get(variant);\n renderer?.(context.ref.current!, tree, options);\n }\n }\n }, [tree, width, height]);\n\n // TODO(burdon): Provider should expand.\n return (\n <div ref={ref} className='flex grow overflow-hidden' onClick={() => onNodeClick?.()}>\n <SVGRoot context={context}>\n <SVG />\n </SVGRoot>\n </div>\n );\n};\n", "//\n// Copyright 2023 DXOS.org\n// Copyright 2022 Observable, Inc.\n//\n\nimport * as d3 from 'd3';\nimport { type HierarchyNode } from 'd3-hierarchy';\n\nimport { type TreeOptions } from '../Tree';\nimport { type TreeNode } from '../types';\n\n// Create hierarchical ID.\n// eslint-disable-next-line unused-imports/no-unused-vars\nconst getId = (node: HierarchyNode<TreeNode>): string =>\n `${node.parent ? getId(node.parent) + '/' : ''}${node.data.id.slice(0, 4)}`;\n\n// https://github.com/d3/d3-hierarchy\n// https://observablehq.com/@d3/hierarchical-edge-bundling?intent=fork\nconst HierarchicalEdgeBundling = (s: SVGSVGElement, data: TreeNode, options: TreeOptions) => {\n const svg = d3.select(s);\n svg.selectAll('*').remove();\n\n const { radius = 600, padding = 100, slots } = options;\n\n // https://d3js.org/d3-hierarchy/hierarchy\n const root = d3.hierarchy(flatten(data));\n // .sort((a, b) => d3.ascending(a.height, b.height) || d3.ascending(getName(a.data), getName(b.data)));\n\n const tree = d3.cluster<TreeNode>().size([2 * Math.PI, radius - padding]);\n const layout = tree(addLinks(root));\n\n // eslint-disable-next-line unused-imports/no-unused-vars\n const node = svg\n .append('g')\n .selectAll()\n .data(layout.leaves())\n .join('g')\n .attr('transform', (d) => `rotate(${d.x * (180 / Math.PI) - 90}) translate(${d.y},0)`)\n .append('text')\n .attr('class', slots?.text ?? '')\n .attr('dy', '0.31em') // TODO(burdon): Based on font size.\n .attr('x', (d) => (d.x < Math.PI ? 6 : -6))\n .attr('text-anchor', (d) => (d.x < Math.PI ? 'start' : 'end'))\n .attr('transform', (d) => (d.x >= Math.PI ? 'rotate(180)' : null))\n // .text((d: any) => d.data.id)\n // .each(function (d: any) {\n // d.text = this;\n // })\n // .on('mouseover', overed)\n // .on('mouseout', outed)\n .call(\n (text) => text.text((d: any) => d.data.id.slice(0, 8)),\n // .text((d: any) => `${getId(d)} [${[(d as any).outgoing?.length ?? 0]}]`),\n );\n\n // https://d3js.org/d3-shape/radial-line\n const line = d3\n .lineRadial()\n .curve(d3.curveBundle.beta(0.85))\n .radius((d: any) => d.y)\n .angle((d: any) => d.x);\n\n // eslint-disable-next-line unused-imports/no-unused-vars\n const links = svg\n .append('g')\n .selectAll()\n .data(layout.leaves().flatMap((leaf: any) => leaf.outgoing))\n .join('path')\n .style('mix-blend-mode', 'multiply')\n .attr('class', slots?.path ?? '')\n .attr('d', ([i, o]) => {\n return line(i.path(o));\n })\n .each(function (d) {\n d.path = this;\n });\n\n // function overed(event: any, d: X) {\n // link.style('mix-blend-mode', null);\n // d3.select(this).attr('font-weight', 'bold');\n // d3.selectAll(d.incoming.map((d) => d.path))\n // .attr('stroke', color.in)\n // .raise();\n // d3.selectAll((d as any).incoming.map(([d]) => d.text))\n // .attr('fill', color.in)\n // .attr('font-weight', 'bold');\n // d3.selectAll(d.outgoing.map((d) => d.path))\n // .attr('stroke', color.out)\n // .raise();\n // d3.selectAll(d.outgoing.map(([, d]) => d.text))\n // .attr('fill', color.out)\n // .attr('font-weight', 'bold');\n // }\n\n // function outed(event: any, d: HierarchyNode<Datum>) {\n // // @ts-ignore\n // d3.select(this).attr('font-weight', null);\n // d3.selectAll(d.incoming.map((d) => d.path)).attr('stroke', null);\n // d3.selectAll(d.incoming.map(([d]) => d.text))\n // .attr('fill', null)\n // .attr('font-weight', null);\n // d3.selectAll(d.outgoing.map((d) => d.path)).attr('stroke', null);\n // d3.selectAll(d.outgoing.map(([, d]) => d.text))\n // .attr('fill', null)\n // .attr('font-weight', null);\n // }\n};\n\n// Monkey-patch with incoming/outgoing nodes.\nconst addLinks = (root: HierarchyNode<TreeNode>) => {\n // Map of nodes indexed by ID.\n const nodes = new Map(root.descendants().map((d) => [d.data.id, d]));\n const parents = root.descendants().reduce((map, d) => {\n if (d.children?.length) {\n map.set(d.data.id, d);\n }\n return map;\n }, new Map<string, HierarchyNode<TreeNode>>());\n\n for (const d of root.leaves()) {\n // (d as any).incoming = [];\n\n const parent = parents.get(d.data.id);\n if (parent) {\n // Skip the first node which is a placeholder created by flatten().\n (d as any).outgoing =\n parent.data.children?.slice(1).map((child) => {\n return [d, nodes.get(child.id)!];\n }) ?? [];\n } else {\n (d as any).outgoing = [];\n }\n }\n\n // for (const d of root.leaves()) {\n // for (const [_, o] of (d as any).outgoing) {\n // o.incoming.push(o);\n // }\n // }\n\n return root;\n};\n\n/**\n * We are using a hierarchy in order to group nodes by parent, but we want the parent\n * nodes to be positioned at the first level along with all descendents.\n * So we add a placeholder for all parents at the head of each group.\n * @param node\n */\nconst flatten = (node: TreeNode) => {\n const clone: TreeNode = {\n id: node.id,\n };\n\n // TODO(burdon): NOTE: Should exclude schema (since requires a tree).\n if (node.children?.length) {\n const children = node.children.map((child) => flatten(child));\n clone.children = [{ id: node.id }, ...children];\n }\n\n return clone;\n};\n\nexport default HierarchicalEdgeBundling;\n", "//\n// Copyright 2023 DXOS.org\n// Copyright 2022 Observable, Inc.\n//\n\nimport * as d3 from 'd3';\n\nimport { type TreeOptions } from '../Tree';\n\n// Released under the ISC license.\n// https://observablehq.com/@d3/radial-tree\n// https://observablehq.com/@d3/tree\nconst RadialTree = (s: SVGSVGElement, data: any, options: TreeOptions) => {\n const svg = d3.select(s);\n svg.selectAll('*').remove();\n\n const {\n label, // given a node d, returns the display name\n radius = 400,\n r = 4, // radius of nodes\n slots,\n } = options;\n\n const arc = 2 * Math.PI;\n\n const root = d3.hierarchy(data);\n\n // Sort the nodes.\n // if (sort) {\n // root.sort(sort);\n // }\n\n // Compute labels and titles.\n const descendants = root.descendants();\n const getLabel = label === null ? null : descendants.map((d) => label(d.data));\n\n // Compute the layout.\n const layout = d3\n .tree()\n .size([arc, radius])\n .separation((a: any, b: any) => (a.parent === b.parent ? 1 : 2) / a.depth);\n layout(root);\n\n // Links.\n svg\n .append('g')\n .selectAll('path')\n .data(root.links())\n .join('path')\n .attr('class', slots?.path ?? '')\n .attr(\n 'd',\n d3\n .linkRadial()\n .angle((d: any) => d.x + Math.PI / 2)\n .radius((d: any) => d.y) as any,\n );\n\n // Nodes.\n const node = svg\n .append('g')\n .selectAll('a')\n .data(root.descendants())\n .join('a')\n // .attr('xlink:href', link == null ? null : (d) => link(d.data, d))\n // .attr('target', link == null ? null : linkTarget)\n .attr('transform', (d: any) => `rotate(${(d.x * 180) / Math.PI}) translate(${d.y},0)`);\n\n node\n .append('circle')\n .attr('class', slots?.node ?? '')\n .attr('r', r);\n\n // if (title != null) {\n // node.append('title').text((d) => title(d.data, d));\n // }\n\n // Text.\n if (getLabel) {\n node\n .append('text')\n .attr('transform', (d: any) => `rotate(${d.x >= Math.PI ? 180 : 0})`)\n .attr('dy', '0.32em')\n // eslint-disable-next-line no-mixed-operators\n .attr('x', (d: any) => (d.x < Math.PI === !d.children ? 6 : -6))\n // eslint-disable-next-line no-mixed-operators\n .attr('text-anchor', (d: any) => (d.x < Math.PI === !d.children ? 'start' : 'end'))\n // .attr('paint-order', 'stroke')\n .attr('class', slots?.text ?? '')\n .text((d, i) => getLabel[i]);\n }\n\n return svg.node();\n};\n\nexport default RadialTree;\n", "//\n// Copyright 2023 DXOS.org\n// Copyright 2021 Observable, Inc.\n//\n\nimport * as d3 from 'd3';\n\nimport { type TreeOptions } from '../Tree';\n\n// Released under the ISC license.\n// https://observablehq.com/@d3/tree\nconst TidyTree = (s: SVGSVGElement, data: any, options: TreeOptions) => {\n const svg = d3.select(s);\n svg.selectAll('*').remove();\n\n const { label, width, height, r = 4, padding = 4, margin = 60, slots } = options;\n\n const root = d3.hierarchy(data);\n\n // Compute labels and titles.\n const descendants = root.descendants();\n const getLabel = label == null ? null : descendants.map((d) => label(d.data));\n\n // Compute the layout.\n const dx = 16;\n const dy = width / (root.height + padding);\n const layout = d3.tree().nodeSize([dx, dy]);\n layout(root);\n\n // Center the tree.\n let x0 = Infinity;\n let x1 = -x0;\n let y0 = Infinity;\n let y1 = -y0;\n root.each((d: any) => {\n if (d.x > x1) {\n x1 = d.x;\n }\n if (d.x < x0) {\n x0 = d.x;\n }\n if (d.y > y1) {\n y1 = d.y;\n }\n if (d.y < y0) {\n y0 = d.y;\n }\n });\n\n // TODO(burdon): Option to expand.\n // NOTE: x and y are flipped.\n const sx = Math.min(2, Math.max(1, (height - margin * 2) / (x1 - x0)));\n const oy = -(width - (y1 - y0)) / 2;\n\n // Links.\n svg\n .append('g')\n .selectAll('path')\n .data(root.links())\n .join('path')\n .attr('class', slots?.path ?? '')\n .attr(\n 'd',\n d3\n .link(d3.curveBumpX)\n .x((d: any) => d.y + oy)\n .y((d: any) => d.x * sx) as any,\n );\n\n // Nodes.\n const node = svg\n .append('g')\n .selectAll('a')\n .data(root.descendants())\n .join('a')\n // .attr('xlink:href', link == null ? null : (d) => link(d.data, d))\n // .attr('target', link == null ? null : linkTarget)\n .attr('transform', (d: any) => `translate(${d.y + oy},${d.x * sx})`);\n\n node\n .append('circle')\n .attr('class', slots?.node ?? '')\n .attr('r', r);\n\n // if (title != null) {\n // node.append('title').text((d) => title(d.data, d));\n // }\n\n if (getLabel) {\n node\n .append('text')\n\n .attr('dy', '0.32em')\n .attr('x', (d) => (d.children ? -6 : 6))\n .attr('text-anchor', (d) => (d.children ? 'end' : 'start'))\n // .attr('paint-order', 'stroke')\n .attr('class', slots?.text ?? '')\n .text((d, i) => getLabel[i]);\n }\n};\n\nexport default TidyTree;\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport type { GraphModel } from '@dxos/gem-spore';\n\nexport type TreeNode = {\n id: string;\n label?: string;\n children?: TreeNode[];\n};\n\nexport const mapGraphToTreeData = <N>(model: GraphModel<N>, maxDepth = 8): TreeNode | undefined => {\n const mapNode = (node: N, depth = 0): TreeNode => {\n const treeNode: TreeNode = {\n id: model.idAccessor(node),\n label: model.idAccessor(node).slice(0, 8),\n };\n\n const links = model.graph.links.filter((link) => link.source === treeNode.id);\n if (depth < maxDepth) {\n treeNode.children = links.map((link) =>\n mapNode(model.graph.nodes.find((node) => model.idAccessor(node) === link.target)!, depth + 1),\n );\n }\n\n return treeNode;\n };\n\n let data: TreeNode | undefined;\n if (model.selected) {\n const node = model.graph.nodes.find((node) => model.idAccessor(node) === model.selected);\n if (node) {\n data = mapNode(node);\n }\n }\n\n return data;\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { forceLink, forceManyBody } from 'd3';\nimport ForceGraph from 'force-graph';\nimport React, { type FC, useEffect, useMemo, useRef, useState } from 'react';\nimport { useResizeDetector } from 'react-resize-detector';\n\nimport { getTypename, type ReactiveEchoObject, type Space } from '@dxos/client/echo';\nimport { createSvgContext, defaultGridStyles, Grid, SVG, SVGRoot, Zoom } from '@dxos/gem-core';\nimport {\n defaultStyles,\n Graph as GraphComponent,\n GraphForceProjector,\n type GraphLayoutNode,\n Markers,\n} from '@dxos/gem-spore';\nimport { filterObjectsSync, type SearchResult } from '@dxos/plugin-search';\nimport { useAsyncState, useThemeContext } from '@dxos/react-ui';\nimport { mx } from '@dxos/react-ui-theme';\nimport '@dxos/gem-spore/styles';\n\nimport { type EchoGraphNode, SpaceGraphModel } from './graph-model';\nimport { Tree } from '../Tree';\n\ntype Slots = {\n root?: { className?: string };\n grid?: { className?: string };\n};\n\nconst slots: Slots = {};\n\nconst colors = [\n '[&>circle]:!fill-black-300 [&>circle]:!stroke-black-600',\n '[&>circle]:!fill-slate-300 [&>circle]:!stroke-slate-600',\n '[&>circle]:!fill-green-300 [&>circle]:!stroke-green-600',\n '[&>circle]:!fill-sky-300 [&>circle]:!stroke-sky-600',\n '[&>circle]:!fill-cyan-300 [&>circle]:!stroke-cyan-600',\n '[&>circle]:!fill-rose-300 [&>circle]:!stroke-rose-600',\n '[&>circle]:!fill-purple-300 [&>circle]:!stroke-purple-600',\n '[&>circle]:!fill-orange-300 [&>circle]:!stroke-orange-600',\n '[&>circle]:!fill-teal-300 [&>circle]:!stroke-teal-600',\n '[&>circle]:!fill-indigo-300 [&>circle]:!stroke-indigo-600',\n];\n\nexport type GraphProps = {\n space: Space;\n match?: RegExp;\n grid?: boolean;\n svg?: boolean;\n};\n\nexport const Graph: FC<GraphProps> = ({ space, match, grid, svg }) => {\n const { themeMode } = useThemeContext();\n const [selected, setSelected] = useState<string>();\n\n const [model] = useAsyncState(\n async () => (space ? new SpaceGraphModel({ schema: true }).open(space) : undefined),\n [space],\n );\n\n const context = createSvgContext();\n const projector = useMemo(\n () =>\n new GraphForceProjector<EchoGraphNode>(context, {\n forces: {\n manyBody: {\n strength: -100,\n },\n link: {\n distance: 100,\n },\n radial: {\n radius: 150,\n strength: 0.05,\n },\n },\n attributes: {\n radius: (node: GraphLayoutNode<EchoGraphNode>) => (node.data?.type === 'schema' ? 12 : 8),\n },\n }),\n [],\n );\n\n const filteredRef = useRef<SearchResult[]>();\n filteredRef.current = filterObjectsSync(model?.objects ?? [], match);\n useEffect(() => {\n void projector.start();\n }, [match]);\n\n const [colorMap] = useState(new Map<string, string>());\n\n // https://github.com/vasturiano/force-graph\n const { ref, width, height } = useResizeDetector();\n const rootRef = useRef<HTMLDivElement>(null);\n const forceGraph = useRef<ForceGraph>();\n\n useEffect(() => {\n if (rootRef.current) {\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 // Update.\n useEffect(() => {\n if (forceGraph.current && width && height && model) {\n forceGraph.current\n .pauseAnimation()\n .width(width)\n .height(height)\n .onEngineStop(() => {\n forceGraph.current?.zoomToFit(400, 40);\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 .warmupTicks(100)\n // .cooldownTime(1000)\n\n //\n .graphData(model.graph)\n .resumeAnimation();\n }\n }, [model, width, height]);\n\n const handleZoomToFit = () => {\n forceGraph.current?.zoomToFit(400, 40);\n };\n\n if (!svg) {\n return (\n <div ref={ref} className='relative grow' onClick={handleZoomToFit}>\n <div ref={rootRef} className='absolute inset-0' />\n </div>\n );\n }\n\n if (selected) {\n return <Tree space={space} selected={selected} variant='tidy' onNodeClick={() => setSelected(undefined)} />;\n }\n\n return (\n <SVGRoot context={context}>\n <SVG className={mx(defaultStyles, slots?.root?.className)}>\n <Markers arrowSize={6} />\n {grid && <Grid className={slots?.grid?.className ?? defaultGridStyles(themeMode)} />}\n <Zoom extent={[1 / 2, 4]}>\n <GraphComponent\n model={model}\n projector={projector}\n drag\n arrows\n onSelect={(node) => setSelected(node?.data?.id)}\n labels={{\n text: (node: GraphLayoutNode<ReactiveEchoObject<any>>) => {\n if (filteredRef.current?.length && !filteredRef.current.some((object) => object.id === node.data?.id)) {\n return undefined;\n }\n\n // TODO(burdon): Use schema.\n return node.data?.label ?? node.data?.title ?? node.data?.name ?? node.data?.id.slice(0, 8);\n },\n }}\n attributes={{\n node: (node: GraphLayoutNode<ReactiveEchoObject<any>>) => {\n let className: string | undefined;\n if (node.data) {\n const { object } = node.data;\n if (object) {\n const typename = getTypename(object);\n if (typename) {\n className = colorMap.get(typename);\n if (!className) {\n className = colors[colorMap.size % colors.length];\n colorMap.set(typename, className);\n }\n }\n }\n }\n\n const selected = filteredRef.current?.some((object) => object.id === node.data?.id);\n const blur = !selected && !!filteredRef.current?.length;\n return {\n class: mx(className, blur && 'opacity-70'),\n };\n },\n link: () => ({\n class: '[&>path]:!stroke-neutral-300 dark:[&>path]:!stroke-neutral-700',\n }),\n }}\n />\n </Zoom>\n </SVG>\n </SVGRoot>\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", "toTypename", "object", "schemaNode", "source", "target", "info", "getPropertySignatures", "ast", "prop", "hasTypeAnnotation", "name", "toString", "value", "String", "refs", "Array", "isArray", "ref", "findIndex", "obj", "triggerUpdate", "fire", "setSelected", "close", "undefined", "React", "useEffect", "useState", "useResizeDetector", "createSvgContext", "SVG", "SVGRoot", "useAsyncState", "d3", "HierarchicalEdgeBundling", "s", "data", "options", "svg", "select", "selectAll", "remove", "radius", "padding", "slots", "root", "hierarchy", "flatten", "tree", "cluster", "size", "Math", "PI", "layout", "addLinks", "node", "append", "leaves", "join", "attr", "d", "x", "y", "text", "call", "id", "slice", "line", "lineRadial", "curve", "curveBundle", "beta", "angle", "links", "flatMap", "leaf", "outgoing", "style", "path", "i", "o", "each", "nodes", "Map", "descendants", "map", "parents", "reduce", "children", "length", "set", "parent", "get", "child", "clone", "d3", "RadialTree", "s", "data", "options", "svg", "select", "selectAll", "remove", "label", "radius", "r", "slots", "arc", "Math", "PI", "root", "hierarchy", "descendants", "getLabel", "map", "d", "layout", "tree", "size", "separation", "a", "b", "parent", "depth", "append", "links", "join", "attr", "path", "linkRadial", "angle", "x", "y", "node", "children", "text", "i", "d3", "TidyTree", "s", "data", "options", "svg", "select", "selectAll", "remove", "label", "width", "height", "r", "padding", "margin", "slots", "root", "hierarchy", "descendants", "getLabel", "map", "d", "dx", "dy", "layout", "tree", "nodeSize", "x0", "Infinity", "x1", "y0", "y1", "each", "x", "y", "sx", "Math", "min", "max", "oy", "append", "links", "join", "attr", "path", "link", "curveBumpX", "node", "children", "text", "i", "mapGraphToTreeData", "model", "maxDepth", "mapNode", "node", "depth", "treeNode", "id", "idAccessor", "label", "slice", "links", "graph", "filter", "link", "source", "children", "map", "nodes", "find", "target", "data", "selected", "forceLink", "forceManyBody", "ForceGraph", "React", "useEffect", "useMemo", "useRef", "useState", "useResizeDetector", "getTypename", "createSvgContext", "defaultGridStyles", "Grid", "SVG", "SVGRoot", "Zoom", "defaultStyles", "Graph", "GraphComponent", "GraphForceProjector", "Markers", "filterObjectsSync", "useAsyncState", "useThemeContext", "mx", "slots", "colors", "Graph", "space", "match", "grid", "svg", "themeMode", "useThemeContext", "selected", "setSelected", "useState", "model", "useAsyncState", "SpaceGraphModel", "schema", "open", "undefined", "context", "createSvgContext", "projector", "useMemo", "GraphForceProjector", "forces", "manyBody", "strength", "link", "distance", "radial", "radius", "attributes", "node", "data", "type", "filteredRef", "useRef", "current", "filterObjectsSync", "objects", "useEffect", "start", "colorMap", "Map", "ref", "width", "height", "useResizeDetector", "rootRef", "forceGraph", "ForceGraph", "nodeRelSize", "nodeLabel", "typename", "id", "nodeAutoColorBy", "linkColor", "pauseAnimation", "graphData", "nodes", "links", "onEngineStop", "zoomToFit", "d3Force", "forceLink", "forceManyBody", "warmupTicks", "graph", "resumeAnimation", "handleZoomToFit", "div", "className", "onClick", "Tree", "variant", "onNodeClick", "SVGRoot", "SVG", "mx", "defaultStyles", "root", "Markers", "arrowSize", "Grid", "defaultGridStyles", "Zoom", "extent", "GraphComponent", "drag", "arrows", "onSelect", "labels", "text", "length", "some", "object", "label", "title", "name", "slice", "getTypename", "get", "size", "set", "blur", "class", "defaultTreeLayoutSlots", "node", "path", "text", "renderers", "Map", "TidyTree", "RadialTree", "HierarchicalEdgeBundling", "Tree", "space", "selected", "variant", "onNodeClick", "model", "useAsyncState", "SpaceGraphModel", "open", "undefined", "tree", "setTree", "useState", "useEffect", "subscribe", "mapGraphToTreeData", "context", "createSvgContext", "ref", "width", "height", "useResizeDetector", "size", "Math", "min", "radius", "options", "label", "d", "id", "marginLeft", "marginRight", "marginTop", "marginBottom", "slots", "renderer", "get", "current", "React", "div", "className", "onClick", "SVGRoot", "SVG"]
7
+ }
@@ -2,13 +2,13 @@ import {
2
2
  Chart,
3
3
  ExplorerContainer,
4
4
  Globe
5
- } from "./chunk-DTAFIUA7.mjs";
5
+ } from "./chunk-S3QNIEBS.mjs";
6
6
  import {
7
7
  Graph,
8
8
  SpaceGraphModel,
9
9
  Tree,
10
10
  defaultTreeLayoutSlots
11
- } from "./chunk-5GTLMW4Q.mjs";
11
+ } from "./chunk-YQL7YE6N.mjs";
12
12
  import {
13
13
  ExplorerAction,
14
14
  ViewType
@@ -27,7 +27,7 @@ import { defineObjectForm } from "@dxos/plugin-space/types";
27
27
  // packages/plugins/experimental/plugin-explorer/src/capabilities/index.ts
28
28
  import { lazy } from "@dxos/app-framework";
29
29
  var IntentResolver = lazy(() => import("./intent-resolver-UJNDAIDZ.mjs"));
30
- var ReactSurface = lazy(() => import("./react-surface-EGSBRYNS.mjs"));
30
+ var ReactSurface = lazy(() => import("./react-surface-3X2V3VPN.mjs"));
31
31
 
32
32
  // packages/plugins/experimental/plugin-explorer/src/translations.ts
33
33
  var translations_default = [