@dxos/plugin-explorer 0.8.3-main.672df60 → 0.8.3-staging.0fa589b
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-BBZ54DJS.mjs → ExplorerContainer-DXL34I3F.mjs} +6 -6
- package/dist/lib/browser/ExplorerContainer-DXL34I3F.mjs.map +7 -0
- package/dist/lib/browser/{chunk-73GQ46YO.mjs → chunk-JRKQNHS6.mjs} +14 -16
- package/dist/lib/browser/{chunk-73GQ46YO.mjs.map → chunk-JRKQNHS6.mjs.map} +3 -3
- package/dist/lib/browser/{chunk-M2BGAY6H.mjs → chunk-Z5BGAHLD.mjs} +22 -12
- package/dist/lib/browser/chunk-Z5BGAHLD.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +9 -5
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/{intent-resolver-FJDVBDE3.mjs → intent-resolver-JZKYVFQJ.mjs} +3 -3
- package/dist/lib/browser/intent-resolver-JZKYVFQJ.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{react-surface-H3YDMXAQ.mjs → react-surface-IAEP2GBT.mjs} +5 -5
- package/dist/lib/browser/react-surface-IAEP2GBT.mjs.map +7 -0
- package/dist/lib/node/{ExplorerContainer-MVP2AM7R.cjs → ExplorerContainer-VUXH55VV.cjs} +8 -8
- package/dist/lib/node/ExplorerContainer-VUXH55VV.cjs.map +7 -0
- package/dist/lib/node/{chunk-72H5HBTK.cjs → chunk-SVU4VMYX.cjs} +16 -18
- package/dist/lib/node/{chunk-72H5HBTK.cjs.map → chunk-SVU4VMYX.cjs.map} +3 -3
- package/dist/lib/node/{chunk-NELWWGBU.cjs → chunk-TY543HPV.cjs} +24 -14
- package/dist/lib/node/chunk-TY543HPV.cjs.map +7 -0
- package/dist/lib/node/index.cjs +16 -12
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/{intent-resolver-DRT67ZU4.cjs → intent-resolver-G2MFNIXA.cjs} +6 -6
- package/dist/lib/node/intent-resolver-G2MFNIXA.cjs.map +7 -0
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/{react-surface-6ESLSM33.cjs → react-surface-UJD5RGRZ.cjs} +9 -9
- package/dist/lib/node/react-surface-UJD5RGRZ.cjs.map +7 -0
- package/dist/lib/node-esm/{ExplorerContainer-APGUQI4M.mjs → ExplorerContainer-MFE7PXF4.mjs} +6 -6
- package/dist/lib/node-esm/ExplorerContainer-MFE7PXF4.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-PVII2K2B.mjs → chunk-AE7VHUJM.mjs} +22 -12
- package/dist/lib/node-esm/chunk-AE7VHUJM.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-34X2VFQN.mjs → chunk-IUFYOE44.mjs} +14 -16
- package/dist/lib/node-esm/{chunk-34X2VFQN.mjs.map → chunk-IUFYOE44.mjs.map} +3 -3
- package/dist/lib/node-esm/index.mjs +9 -5
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/{intent-resolver-4RBV644N.mjs → intent-resolver-7G6ZKM6E.mjs} +3 -3
- package/dist/lib/node-esm/intent-resolver-7G6ZKM6E.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{react-surface-ZEVL3FXG.mjs → react-surface-XBH3WZDL.mjs} +5 -5
- package/dist/lib/node-esm/react-surface-XBH3WZDL.mjs.map +7 -0
- package/dist/types/src/components/Graph/ForceGraph.d.ts.map +1 -1
- package/dist/types/src/components/Graph/adapter.d.ts +3 -0
- package/dist/types/src/components/Graph/adapter.d.ts.map +1 -1
- package/dist/types/src/components/Graph/testing.d.ts.map +1 -1
- package/dist/types/src/components/Tree/types/tree.d.ts +14 -9
- package/dist/types/src/components/Tree/types/tree.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +14 -2
- package/dist/types/src/translations.d.ts.map +1 -1
- package/package.json +27 -26
- package/src/capabilities/intent-resolver.ts +2 -2
- package/src/capabilities/react-surface.tsx +2 -2
- package/src/components/ExplorerContainer.tsx +4 -4
- package/src/components/Graph/D3ForceGraph.stories.tsx +2 -2
- package/src/components/Graph/D3ForceGraph.tsx +2 -2
- package/src/components/Graph/ForceGraph.stories.tsx +2 -2
- package/src/components/Graph/ForceGraph.tsx +33 -24
- package/src/components/Graph/adapter.ts +3 -0
- package/src/components/Graph/testing.ts +12 -14
- package/src/components/Tree/testing/generator.ts +2 -2
- package/src/components/Tree/types/tree.test.ts +3 -3
- package/src/components/Tree/types/tree.ts +12 -14
- package/src/translations.ts +6 -1
- package/dist/lib/browser/ExplorerContainer-BBZ54DJS.mjs.map +0 -7
- package/dist/lib/browser/chunk-M2BGAY6H.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-FJDVBDE3.mjs.map +0 -7
- package/dist/lib/browser/react-surface-H3YDMXAQ.mjs.map +0 -7
- package/dist/lib/node/ExplorerContainer-MVP2AM7R.cjs.map +0 -7
- package/dist/lib/node/chunk-NELWWGBU.cjs.map +0 -7
- package/dist/lib/node/intent-resolver-DRT67ZU4.cjs.map +0 -7
- package/dist/lib/node/react-surface-6ESLSM33.cjs.map +0 -7
- package/dist/lib/node-esm/ExplorerContainer-APGUQI4M.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-PVII2K2B.mjs.map +0 -7
- package/dist/lib/node-esm/intent-resolver-4RBV644N.mjs.map +0 -7
- package/dist/lib/node-esm/react-surface-ZEVL3FXG.mjs.map +0 -7
|
@@ -8,7 +8,7 @@ import { useGlobalSearch } from '@dxos/plugin-search';
|
|
|
8
8
|
import { getSpace } from '@dxos/react-client/echo';
|
|
9
9
|
import { StackItem } from '@dxos/react-ui-stack';
|
|
10
10
|
|
|
11
|
-
import {
|
|
11
|
+
import { D3ForceGraph } from './Graph';
|
|
12
12
|
import { useGraphModel } from '../hooks';
|
|
13
13
|
import { type ViewType } from '../types';
|
|
14
14
|
|
|
@@ -19,16 +19,16 @@ type ExplorerContainerProps = {
|
|
|
19
19
|
|
|
20
20
|
const ExplorerContainer = ({ role, view }: ExplorerContainerProps) => {
|
|
21
21
|
const space = getSpace(view);
|
|
22
|
-
const { match } = useGlobalSearch();
|
|
23
22
|
const model = useGraphModel(space);
|
|
23
|
+
const { match } = useGlobalSearch();
|
|
24
24
|
|
|
25
|
-
if (!
|
|
25
|
+
if (!space || !model) {
|
|
26
26
|
return null;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
return (
|
|
30
30
|
<StackItem.Content size={role === 'section' ? 'square' : 'intrinsic'}>
|
|
31
|
-
<
|
|
31
|
+
<D3ForceGraph model={model} match={match} />
|
|
32
32
|
</StackItem.Content>
|
|
33
33
|
);
|
|
34
34
|
};
|
|
@@ -7,9 +7,9 @@ import '@dxos-theme';
|
|
|
7
7
|
import { type Meta } from '@storybook/react';
|
|
8
8
|
import React, { useEffect, useState } from 'react';
|
|
9
9
|
|
|
10
|
+
import { Obj } from '@dxos/echo';
|
|
10
11
|
import { faker } from '@dxos/random';
|
|
11
12
|
import { useClient } from '@dxos/react-client';
|
|
12
|
-
import { live } from '@dxos/react-client/echo';
|
|
13
13
|
import { type Space } from '@dxos/react-client/echo';
|
|
14
14
|
import { withClientProvider } from '@dxos/react-client/testing';
|
|
15
15
|
import { DataType } from '@dxos/schema';
|
|
@@ -32,7 +32,7 @@ const DefaultStory = () => {
|
|
|
32
32
|
useEffect(() => {
|
|
33
33
|
const space = client.spaces.default;
|
|
34
34
|
void generate(space, generator);
|
|
35
|
-
const view = space.db.add(
|
|
35
|
+
const view = space.db.add(Obj.make(ViewType, { name: '', type: '' }));
|
|
36
36
|
setSpace(space);
|
|
37
37
|
setView(view);
|
|
38
38
|
}, []);
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import React, { type FC, useCallback, useEffect, useMemo, useRef } from 'react';
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { Obj } from '@dxos/echo';
|
|
8
8
|
import { SelectionModel } from '@dxos/graph';
|
|
9
9
|
import { type ThemedClassName } from '@dxos/react-ui';
|
|
10
10
|
import {
|
|
@@ -85,7 +85,7 @@ export const D3ForceGraph: FC<D3ForceGraphProps> = ({ classNames, model, selecti
|
|
|
85
85
|
const obj = node.data?.data.object;
|
|
86
86
|
return {
|
|
87
87
|
data: {
|
|
88
|
-
color: getHashColor(obj && getTypename(obj))?.color,
|
|
88
|
+
color: getHashColor(obj && Obj.getTypename(obj))?.color,
|
|
89
89
|
},
|
|
90
90
|
classes: {
|
|
91
91
|
'dx-selected': selection.contains(node.id),
|
|
@@ -7,9 +7,9 @@ import '@dxos-theme';
|
|
|
7
7
|
import { type Meta } from '@storybook/react';
|
|
8
8
|
import React, { useEffect, useState } from 'react';
|
|
9
9
|
|
|
10
|
+
import { Obj } from '@dxos/echo';
|
|
10
11
|
import { faker } from '@dxos/random';
|
|
11
12
|
import { useClient } from '@dxos/react-client';
|
|
12
|
-
import { live } from '@dxos/react-client/echo';
|
|
13
13
|
import { type Space } from '@dxos/react-client/echo';
|
|
14
14
|
import { withClientProvider } from '@dxos/react-client/testing';
|
|
15
15
|
import { DataType } from '@dxos/schema';
|
|
@@ -32,7 +32,7 @@ const DefaultStory = () => {
|
|
|
32
32
|
useEffect(() => {
|
|
33
33
|
const space = client.spaces.default;
|
|
34
34
|
void generate(space, generator);
|
|
35
|
-
const view = space.db.add(
|
|
35
|
+
const view = space.db.add(Obj.make(ViewType, { name: '', type: '' }));
|
|
36
36
|
setSpace(space);
|
|
37
37
|
setView(view);
|
|
38
38
|
}, []);
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { forceLink, forceManyBody } from 'd3';
|
|
6
6
|
import NativeForceGraph from 'force-graph';
|
|
7
|
-
import React, { type FC, useEffect, useRef } from 'react';
|
|
7
|
+
import React, { type FC, useEffect, useRef, useState } from 'react';
|
|
8
8
|
import { useResizeDetector } from 'react-resize-detector';
|
|
9
9
|
|
|
10
10
|
import { filterObjectsSync, type SearchResult } from '@dxos/plugin-search';
|
|
@@ -25,6 +25,13 @@ export const ForceGraph: FC<ForceGraphProps> = ({ model, match }) => {
|
|
|
25
25
|
const filteredRef = useRef<SearchResult[]>();
|
|
26
26
|
filteredRef.current = filterObjectsSync(model?.objects ?? [], match);
|
|
27
27
|
|
|
28
|
+
const [data, setData] = useState<GraphAdapter>();
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
return model?.subscribe((model) => {
|
|
31
|
+
setData(new GraphAdapter(model.graph));
|
|
32
|
+
});
|
|
33
|
+
}, [model]);
|
|
34
|
+
|
|
28
35
|
useEffect(() => {
|
|
29
36
|
if (rootRef.current) {
|
|
30
37
|
// https://github.com/vasturiano/force-graph
|
|
@@ -46,30 +53,32 @@ export const ForceGraph: FC<ForceGraphProps> = ({ model, match }) => {
|
|
|
46
53
|
}, []);
|
|
47
54
|
|
|
48
55
|
useEffect(() => {
|
|
49
|
-
if (
|
|
50
|
-
|
|
51
|
-
forceGraph.current
|
|
52
|
-
.pauseAnimation()
|
|
53
|
-
.width(width)
|
|
54
|
-
.height(height)
|
|
55
|
-
.onEngineStop(() => {
|
|
56
|
-
handleZoomToFit();
|
|
57
|
-
})
|
|
58
|
-
.onNodeClick((node: any) => {
|
|
59
|
-
forceGraph.current?.emitParticle(node);
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
// https://github.com/vasturiano/force-graph?tab=readme-ov-file#force-engine-d3-force-configuration
|
|
63
|
-
// .d3Force('center', forceCenter().strength(0.9))
|
|
64
|
-
.d3Force('link', forceLink().distance(160).strength(0.5))
|
|
65
|
-
.d3Force('charge', forceManyBody().strength(-30))
|
|
66
|
-
|
|
67
|
-
.graphData(new GraphAdapter(model))
|
|
68
|
-
.warmupTicks(100)
|
|
69
|
-
.cooldownTime(1_000)
|
|
70
|
-
.resumeAnimation();
|
|
56
|
+
if (!data || !width || !height || !forceGraph.current) {
|
|
57
|
+
return;
|
|
71
58
|
}
|
|
72
|
-
|
|
59
|
+
|
|
60
|
+
// https://github.com/vasturiano/force-graph?tab=readme-ov-file#container-layout
|
|
61
|
+
forceGraph.current
|
|
62
|
+
.pauseAnimation()
|
|
63
|
+
.width(width)
|
|
64
|
+
.height(height)
|
|
65
|
+
.onEngineStop(() => {
|
|
66
|
+
handleZoomToFit();
|
|
67
|
+
})
|
|
68
|
+
.onNodeClick((node: any) => {
|
|
69
|
+
forceGraph.current?.emitParticle(node);
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
// https://github.com/vasturiano/force-graph?tab=readme-ov-file#force-engine-d3-force-configuration
|
|
73
|
+
// .d3Force('center', forceCenter().strength(0.9))
|
|
74
|
+
.d3Force('link', forceLink().distance(160).strength(0.5))
|
|
75
|
+
.d3Force('charge', forceManyBody().strength(-30))
|
|
76
|
+
|
|
77
|
+
.graphData(data)
|
|
78
|
+
.warmupTicks(100)
|
|
79
|
+
.cooldownTime(1_000)
|
|
80
|
+
.resumeAnimation();
|
|
81
|
+
}, [data, width, height, forceGraph.current]);
|
|
73
82
|
|
|
74
83
|
const handleZoomToFit = () => {
|
|
75
84
|
forceGraph.current?.zoomToFit(400, 40);
|
|
@@ -18,6 +18,9 @@ export type GraphData = {
|
|
|
18
18
|
links: GraphLink[];
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Map common graph to force-graph format.
|
|
23
|
+
*/
|
|
21
24
|
export class GraphAdapter implements GraphData {
|
|
22
25
|
private readonly _nodes: GraphNode[] = [];
|
|
23
26
|
private readonly _links: GraphLink[] = [];
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { type
|
|
6
|
-
import { Query,
|
|
5
|
+
import { type Space } from '@dxos/client/echo';
|
|
6
|
+
import { Query, Relation, type Obj } from '@dxos/echo';
|
|
7
7
|
import { DataType } from '@dxos/schema';
|
|
8
8
|
import { createObjectFactory, type ValueGenerator, type TypeSpec } from '@dxos/schema/testing';
|
|
9
9
|
import { range } from '@dxos/util';
|
|
10
10
|
|
|
11
|
-
const getObject = (objects:
|
|
11
|
+
const getObject = (objects: Obj.Any[]) => objects[Math.floor(Math.random() * objects.length)];
|
|
12
12
|
|
|
13
13
|
const defaultTypes: TypeSpec[] = [
|
|
14
14
|
{ type: DataType.Organization, count: 5 },
|
|
@@ -24,7 +24,7 @@ export type GenerateOptions = {
|
|
|
24
24
|
};
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
-
const defaultRelations: GenerateOptions['relations'] = {
|
|
27
|
+
const defaultRelations: GenerateOptions['relations'] = { kind: 'friend', count: 10 };
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* @deprecated Use @dxos/schema.
|
|
@@ -42,16 +42,14 @@ export const generate = async (
|
|
|
42
42
|
for (const _ of range(relations.count)) {
|
|
43
43
|
const source = getObject(contacts);
|
|
44
44
|
const target = getObject(contacts);
|
|
45
|
-
if (source.id
|
|
46
|
-
|
|
45
|
+
if (source.id !== target.id) {
|
|
46
|
+
space.db.add(
|
|
47
|
+
Relation.make(DataType.HasRelationship, {
|
|
48
|
+
[Relation.Source]: source,
|
|
49
|
+
[Relation.Target]: target,
|
|
50
|
+
kind: relations.kind,
|
|
51
|
+
}),
|
|
52
|
+
);
|
|
47
53
|
}
|
|
48
|
-
|
|
49
|
-
space.db.add(
|
|
50
|
-
live(DataType.HasRelationship, {
|
|
51
|
-
kind: relations.kind,
|
|
52
|
-
[RelationSourceId]: source,
|
|
53
|
-
[RelationTargetId]: target,
|
|
54
|
-
}),
|
|
55
|
-
);
|
|
56
54
|
}
|
|
57
55
|
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { Key } from '@dxos/echo';
|
|
6
6
|
import { range } from '@dxos/util';
|
|
7
7
|
|
|
8
8
|
import { Tree, type TreeNodeType } from '../types';
|
|
@@ -21,7 +21,7 @@ export const createTree = (spec: NumberOrNumberArray[] = [], createText?: () =>
|
|
|
21
21
|
const createNodes = (parent: TreeNodeType, spec: NumberOrNumberArray = 0): TreeNodeType[] => {
|
|
22
22
|
const count = Array.isArray(spec) ? random(spec[0], spec[1]) : spec;
|
|
23
23
|
return range(count, (i) => ({
|
|
24
|
-
id: ObjectId.random(),
|
|
24
|
+
id: Key.ObjectId.random(),
|
|
25
25
|
children: [],
|
|
26
26
|
data: {
|
|
27
27
|
text: createText?.() ?? [parent.data.text, i + 1].join('.'),
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { describe, test } from 'vitest';
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { Obj, Ref } from '@dxos/echo';
|
|
8
8
|
import { faker } from '@dxos/random';
|
|
9
9
|
import { DataType } from '@dxos/schema';
|
|
10
10
|
|
|
@@ -123,11 +123,11 @@ describe('tree', () => {
|
|
|
123
123
|
});
|
|
124
124
|
|
|
125
125
|
test('task', ({ expect }) => {
|
|
126
|
-
const task =
|
|
126
|
+
const task = Obj.make(DataType.Task, { text: 'Test task.' });
|
|
127
127
|
expect(task.text).to.eq('Test task.');
|
|
128
128
|
|
|
129
129
|
const tree = createTree();
|
|
130
130
|
const node = tree.addNode(tree.root);
|
|
131
|
-
node.ref =
|
|
131
|
+
node.ref = Ref.make(task);
|
|
132
132
|
});
|
|
133
133
|
});
|
|
@@ -4,25 +4,23 @@
|
|
|
4
4
|
|
|
5
5
|
import { Schema } from 'effect';
|
|
6
6
|
|
|
7
|
-
import { Type } from '@dxos/echo';
|
|
8
|
-
import { ObjectId, Ref, Expando } from '@dxos/echo-schema';
|
|
7
|
+
import { Key, Obj, Type } from '@dxos/echo';
|
|
9
8
|
import { invariant } from '@dxos/invariant';
|
|
10
|
-
import { live } from '@dxos/live-object';
|
|
11
9
|
|
|
12
10
|
// TODO(burdon): Reconcile with @dxos/graph (i.e., common types).
|
|
13
11
|
|
|
14
12
|
export const TreeNodeType = Schema.Struct({
|
|
15
|
-
id: ObjectId,
|
|
16
|
-
children: Schema.mutable(Schema.Array(ObjectId)),
|
|
13
|
+
id: Key.ObjectId,
|
|
14
|
+
children: Schema.mutable(Schema.Array(Key.ObjectId)),
|
|
17
15
|
data: Schema.mutable(Schema.Record({ key: Schema.String, value: Schema.Any })),
|
|
18
|
-
ref: Schema.optional(Ref(Expando)),
|
|
16
|
+
ref: Schema.optional(Type.Ref(Type.Expando)),
|
|
19
17
|
}).pipe(Schema.mutable);
|
|
20
18
|
|
|
21
19
|
export interface TreeNodeType extends Schema.Schema.Type<typeof TreeNodeType> {}
|
|
22
20
|
|
|
23
21
|
export const TreeType = Schema.Struct({
|
|
24
|
-
root: ObjectId,
|
|
25
|
-
nodes: Schema.mutable(Schema.Record({ key: ObjectId, value: TreeNodeType })),
|
|
22
|
+
root: Key.ObjectId,
|
|
23
|
+
nodes: Schema.mutable(Schema.Record({ key: Key.ObjectId, value: TreeNodeType })),
|
|
26
24
|
}).pipe(
|
|
27
25
|
Type.Obj({
|
|
28
26
|
typename: 'dxos.org/type/Tree',
|
|
@@ -37,8 +35,8 @@ export interface TreeType extends Schema.Schema.Type<typeof TreeType> {}
|
|
|
37
35
|
*/
|
|
38
36
|
export class Tree {
|
|
39
37
|
static create = (): TreeType => {
|
|
40
|
-
const id = ObjectId.random();
|
|
41
|
-
return
|
|
38
|
+
const id = Key.ObjectId.random();
|
|
39
|
+
return Obj.make(TreeType, {
|
|
42
40
|
root: id,
|
|
43
41
|
nodes: {
|
|
44
42
|
[id]: {
|
|
@@ -78,7 +76,7 @@ export class Tree {
|
|
|
78
76
|
*/
|
|
79
77
|
tranverse<T>(
|
|
80
78
|
callback: (node: TreeNodeType, depth: number) => T | void,
|
|
81
|
-
root: ObjectId = this._tree.root,
|
|
79
|
+
root: Key.ObjectId = this._tree.root,
|
|
82
80
|
depth = 0,
|
|
83
81
|
): T | void {
|
|
84
82
|
const node = this._tree.nodes[root];
|
|
@@ -95,7 +93,7 @@ export class Tree {
|
|
|
95
93
|
}
|
|
96
94
|
}
|
|
97
95
|
|
|
98
|
-
getNode(id: ObjectId): TreeNodeType {
|
|
96
|
+
getNode(id: Key.ObjectId): TreeNodeType {
|
|
99
97
|
const node = this._tree.nodes[id];
|
|
100
98
|
invariant(node);
|
|
101
99
|
return node;
|
|
@@ -196,7 +194,7 @@ export class Tree {
|
|
|
196
194
|
*/
|
|
197
195
|
addNode(parent: TreeNodeType, node?: TreeNodeType, index?: number): TreeNodeType {
|
|
198
196
|
if (!node) {
|
|
199
|
-
const id = ObjectId.random();
|
|
197
|
+
const id = Key.ObjectId.random();
|
|
200
198
|
node = { id, children: [], data: { text: '' } }; // TODO(burdon): Generic.
|
|
201
199
|
}
|
|
202
200
|
|
|
@@ -208,7 +206,7 @@ export class Tree {
|
|
|
208
206
|
/**
|
|
209
207
|
* Delete node.
|
|
210
208
|
*/
|
|
211
|
-
deleteNode(parent: TreeNodeType, id: ObjectId): TreeNodeType | undefined {
|
|
209
|
+
deleteNode(parent: TreeNodeType, id: Key.ObjectId): TreeNodeType | undefined {
|
|
212
210
|
const node = this._tree.nodes[id];
|
|
213
211
|
if (!node) {
|
|
214
212
|
return undefined;
|
package/src/translations.ts
CHANGED
|
@@ -2,14 +2,19 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { Type } from '@dxos/echo';
|
|
6
|
+
|
|
5
7
|
import { EXPLORER_PLUGIN } from './meta';
|
|
6
8
|
import { ViewType } from './types';
|
|
7
9
|
|
|
8
10
|
export default [
|
|
9
11
|
{
|
|
10
12
|
'en-US': {
|
|
11
|
-
[ViewType
|
|
13
|
+
[Type.getTypename(ViewType)]: {
|
|
12
14
|
'typename label': 'Explorer',
|
|
15
|
+
'typename label_zero': 'Explorers',
|
|
16
|
+
'typename label_one': 'Explorer',
|
|
17
|
+
'typename label_other': 'Explorers',
|
|
13
18
|
'object name placeholder': 'New explorer',
|
|
14
19
|
},
|
|
15
20
|
[EXPLORER_PLUGIN]: {
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/components/ExplorerContainer.tsx"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport React from 'react';\n\nimport { useGlobalSearch } from '@dxos/plugin-search';\nimport { getSpace } from '@dxos/react-client/echo';\nimport { StackItem } from '@dxos/react-ui-stack';\n\nimport { ForceGraph } from './Graph';\nimport { useGraphModel } from '../hooks';\nimport { type ViewType } from '../types';\n\ntype ExplorerContainerProps = {\n role: string;\n view: ViewType;\n};\n\nconst ExplorerContainer = ({ role, view }: ExplorerContainerProps) => {\n const space = getSpace(view);\n const { match } = useGlobalSearch();\n const model = useGraphModel(space);\n\n if (!model || !space) {\n return null;\n }\n\n return (\n <StackItem.Content size={role === 'section' ? 'square' : 'intrinsic'}>\n <ForceGraph model={model} match={match} />\n </StackItem.Content>\n );\n};\n\nexport default ExplorerContainer;\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;AAIA,OAAOA,WAAW;AAElB,SAASC,uBAAuB;AAChC,SAASC,gBAAgB;AACzB,SAASC,iBAAiB;AAW1B,IAAMC,oBAAoB,CAAC,EAAEC,MAAMC,KAAI,MAA0B;;;AAC/D,UAAMC,QAAQC,SAASF,IAAAA;AACvB,UAAM,EAAEG,MAAK,IAAKC,gBAAAA;AAClB,UAAMC,QAAQC,cAAcL,KAAAA;AAE5B,QAAI,CAACI,SAAS,CAACJ,OAAO;AACpB,aAAO;IACT;AAEA,WACE,sBAAA,cAACM,UAAUC,SAAO;MAACC,MAAMV,SAAS,YAAY,WAAW;OACvD,sBAAA,cAACW,YAAAA;MAAWL;MAAcF;;;;;AAGhC;AAEA,IAAA,4BAAeL;",
|
|
6
|
-
"names": ["React", "useGlobalSearch", "getSpace", "StackItem", "ExplorerContainer", "role", "view", "space", "getSpace", "match", "useGlobalSearch", "model", "useGraphModel", "StackItem", "Content", "size", "ForceGraph"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/components/Graph/D3ForceGraph.tsx", "../../../src/components/Graph/ForceGraph.tsx", "../../../src/components/Graph/adapter.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport React, { type FC, useCallback, useEffect, useMemo, useRef } from 'react';\n\nimport { getTypename } from '@dxos/echo-schema';\nimport { SelectionModel } from '@dxos/graph';\nimport { type ThemedClassName } from '@dxos/react-ui';\nimport {\n type GraphController,\n GraphForceProjector,\n type GraphLayoutNode,\n type GraphProps,\n SVG,\n type SVGContext,\n} from '@dxos/react-ui-graph';\nimport { getHashColor } from '@dxos/react-ui-theme';\nimport { type SpaceGraphNode, type SpaceGraphModel, type SpaceGraphEdge } from '@dxos/schema';\n\nimport '@dxos/react-ui-graph/styles/graph.css';\n\nexport type D3ForceGraphProps = ThemedClassName<\n {\n model?: SpaceGraphModel;\n match?: RegExp;\n selection?: SelectionModel;\n grid?: boolean;\n } & Pick<GraphProps, 'drag'>\n>;\n\nexport const D3ForceGraph: FC<D3ForceGraphProps> = ({ classNames, model, selection: _selection, grid, ...props }) => {\n const context = useRef<SVGContext>(null);\n const projector = useMemo<GraphForceProjector | undefined>(() => {\n if (context.current) {\n return new GraphForceProjector(context.current, {\n attributes: {\n linkForce: (edge) => {\n // TODO(burdon): Check type (currently assumes Employee property).\n // Edge shouldn't contribute to force if it's not active.\n return edge.data?.object?.active !== false;\n },\n },\n forces: {\n point: {\n strength: 0.01,\n },\n },\n });\n }\n }, [context.current]);\n\n const graph = useRef<GraphController>(null);\n const selection = useMemo(() => _selection ?? new SelectionModel(), [_selection]);\n useEffect(() => graph.current?.repaint(), [selection.selected.value]);\n\n const handleSelect = useCallback<NonNullable<GraphProps['onSelect']>>(\n (node) => {\n if (selection.contains(node.id)) {\n selection.remove(node.id);\n } else {\n selection.add(node.id);\n }\n },\n [selection],\n );\n\n return (\n <SVG.Root ref={context} classNames={classNames}>\n <SVG.Markers />\n {grid && <SVG.Grid axis />}\n <SVG.Zoom extent={[1 / 2, 2]}>\n <SVG.Graph<SpaceGraphNode, SpaceGraphEdge>\n {...props}\n ref={graph}\n model={model}\n projector={projector}\n labels={{\n text: (node) => {\n return node.data?.data.label ?? node.id;\n },\n }}\n attributes={{\n node: (node: GraphLayoutNode<SpaceGraphNode>) => {\n const obj = node.data?.data.object;\n return {\n data: {\n color: getHashColor(obj && getTypename(obj))?.color,\n },\n classes: {\n 'dx-selected': selection.contains(node.id),\n },\n };\n },\n }}\n onSelect={handleSelect}\n />\n </SVG.Zoom>\n </SVG.Root>\n );\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { forceLink, forceManyBody } from 'd3';\nimport NativeForceGraph from 'force-graph';\nimport React, { type FC, useEffect, useRef } from 'react';\nimport { useResizeDetector } from 'react-resize-detector';\n\nimport { filterObjectsSync, type SearchResult } from '@dxos/plugin-search';\nimport { type SpaceGraphModel } from '@dxos/schema';\n\nimport { GraphAdapter } from './adapter';\n\nexport type ForceGraphProps = {\n model?: SpaceGraphModel;\n match?: RegExp;\n};\n\nexport const ForceGraph: FC<ForceGraphProps> = ({ model, match }) => {\n const { ref, width, height } = useResizeDetector({ refreshRate: 200 });\n const rootRef = useRef<HTMLDivElement>(null);\n const forceGraph = useRef<NativeForceGraph>();\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 NativeForceGraph(rootRef.current)\n // https://github.com/vasturiano/force-graph?tab=readme-ov-file#node-styling\n .nodeRelSize(6)\n .nodeLabel((node: any) => (node.type === 'schema' ? node.data.typename : node.data.label ?? node.id))\n .nodeAutoColorBy((node: any) => (node.type === 'schema' ? 'schema' : node.data.typename))\n\n // https://github.com/vasturiano/force-graph?tab=readme-ov-file#link-styling\n .linkAutoColorBy((link: any) => link.type);\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 // https://github.com/vasturiano/force-graph?tab=readme-ov-file#container-layout\n forceGraph.current\n .pauseAnimation()\n .width(width)\n .height(height)\n .onEngineStop(() => {\n handleZoomToFit();\n })\n .onNodeClick((node: any) => {\n forceGraph.current?.emitParticle(node);\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\n .graphData(new GraphAdapter(model))\n .warmupTicks(100)\n .cooldownTime(1_000)\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", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Graph } from '@dxos/graph';\n\nexport type GraphNode = {\n id?: string;\n};\n\nexport type GraphLink = {\n source?: string;\n target?: string;\n};\n\nexport type GraphData = {\n nodes: GraphNode[];\n links: GraphLink[];\n};\n\nexport class GraphAdapter implements GraphData {\n private readonly _nodes: GraphNode[] = [];\n private readonly _links: GraphLink[] = [];\n\n constructor(private readonly graph: Graph) {\n this._nodes = graph.nodes.map((node) => ({\n id: node.id,\n type: node.type,\n data: node.data,\n }));\n\n this._links = graph.edges.map((edge) => ({\n type: edge.type,\n source: edge.source,\n target: edge.target,\n data: edge.data,\n }));\n }\n\n get nodes() {\n return this._nodes;\n }\n\n get links() {\n return this._links;\n }\n}\n"],
|
|
5
|
-
"mappings": ";;AAIA,OAAOA,SAAkBC,aAAaC,WAAWC,SAASC,cAAc;AAExE,SAASC,mBAAmB;AAC5B,SAASC,sBAAsB;AAE/B,SAEEC,qBAGAC,WAEK;AACP,SAASC,oBAAoB;AAG7B,OAAO;AAWA,IAAMC,eAAsC,CAAC,EAAEC,YAAYC,OAAOC,WAAWC,YAAYC,MAAM,GAAGC,MAAAA,MAAO;;;AAC9G,UAAMC,UAAUC,OAAmB,IAAA;AACnC,UAAMC,YAAYC,QAAyC,MAAA;AACzD,UAAIH,QAAQI,SAAS;AACnB,eAAO,IAAIC,oBAAoBL,QAAQI,SAAS;UAC9CE,YAAY;YACVC,WAAW,CAACC,SAAAA;AAGV,qBAAOA,KAAKC,MAAMC,QAAQC,WAAW;YACvC;UACF;UACAC,QAAQ;YACNC,OAAO;cACLC,UAAU;YACZ;UACF;QACF,CAAA;MACF;IACF,GAAG;MAACd,QAAQI;KAAQ;AAEpB,UAAMW,QAAQd,OAAwB,IAAA;AACtC,UAAML,YAAYO,QAAQ,MAAMN,cAAc,IAAImB,eAAAA,GAAkB;MAACnB;KAAW;AAChFoB,cAAU,MAAMF,MAAMX,SAASc,QAAAA,GAAW;MAACtB,UAAUuB,SAASC;KAAM;AAEpE,UAAMC,eAAeC,YACnB,CAACC,SAAAA;AACC,UAAI3B,UAAU4B,SAASD,KAAKE,EAAE,GAAG;AAC/B7B,kBAAU8B,OAAOH,KAAKE,EAAE;MAC1B,OAAO;AACL7B,kBAAU+B,IAAIJ,KAAKE,EAAE;MACvB;IACF,GACA;MAAC7B;KAAU;AAGb,WACE,sBAAA,cAACgC,IAAIC,MAAI;MAACC,KAAK9B;MAASN;OACtB,sBAAA,cAACkC,IAAIG,SAAO,IAAA,GACXjC,QAAQ,sBAAA,cAAC8B,IAAII,MAAI;MAACC,MAAAA;QACnB,sBAAA,cAACL,IAAIM,MAAI;MAACC,QAAQ;QAAC,IAAI;QAAG;;OACxB,sBAAA,cAACP,IAAIQ,OAAK;MACP,GAAGrC;MACJ+B,KAAKf;MACLpB;MACAO;MACAmC,QAAQ;QACNC,MAAM,CAACf,SAAAA;AACL,iBAAOA,KAAKd,MAAMA,KAAK8B,SAAShB,KAAKE;QACvC;MACF;MACAnB,YAAY;QACViB,MAAM,CAACA,SAAAA;AACL,gBAAMiB,MAAMjB,KAAKd,MAAMA,KAAKC;AAC5B,iBAAO;YACLD,MAAM;cACJgC,OAAOC,aAAaF,OAAOG,YAAYH,GAAAA,CAAAA,GAAOC;YAChD;YACAG,SAAS;cACP,eAAehD,UAAU4B,SAASD,KAAKE,EAAE;YAC3C;UACF;QACF;MACF;MACAoB,UAAUxB;;;;;AAKpB;;;;AChGA,SAASyB,WAAWC,qBAAqB;AACzC,OAAOC,sBAAsB;AAC7B,OAAOC,UAAkBC,aAAAA,YAAWC,UAAAA,eAAc;AAClD,SAASC,yBAAyB;AAElC,SAASC,yBAA4C;;;ACW9C,IAAMC,eAAN,MAAMA;EAIX,YAA6BC,OAAc;SAAdA,QAAAA;SAHZC,SAAsB,CAAA;SACtBC,SAAsB,CAAA;AAGrC,SAAKD,SAASD,MAAMG,MAAMC,IAAI,CAACC,UAAU;MACvCC,IAAID,KAAKC;MACTC,MAAMF,KAAKE;MACXC,MAAMH,KAAKG;IACb,EAAA;AAEA,SAAKN,SAASF,MAAMS,MAAML,IAAI,CAACM,UAAU;MACvCH,MAAMG,KAAKH;MACXI,QAAQD,KAAKC;MACbC,QAAQF,KAAKE;MACbJ,MAAME,KAAKF;IACb,EAAA;EACF;EAEA,IAAIL,QAAQ;AACV,WAAO,KAAKF;EACd;EAEA,IAAIY,QAAQ;AACV,WAAO,KAAKX;EACd;AACF;;;AD3BO,IAAMY,aAAkC,CAAC,EAAEC,OAAOC,MAAK,MAAE;;;AAC9D,UAAM,EAAEC,KAAKC,OAAOC,OAAM,IAAKC,kBAAkB;MAAEC,aAAa;IAAI,CAAA;AACpE,UAAMC,UAAUC,QAAuB,IAAA;AACvC,UAAMC,aAAaD,QAAAA;AAEnB,UAAME,cAAcF,QAAAA;AACpBE,gBAAYC,UAAUC,kBAAkBZ,OAAOa,WAAW,CAAA,GAAIZ,KAAAA;AAE9Da,IAAAA,WAAU,MAAA;AACR,UAAIP,QAAQI,SAAS;AAGnBF,mBAAWE,UAAU,IAAII,iBAAiBR,QAAQI,OAAO,EAEtDK,YAAY,CAAA,EACZC,UAAU,CAACC,SAAeA,KAAKC,SAAS,WAAWD,KAAKE,KAAKC,WAAWH,KAAKE,KAAKE,SAASJ,KAAKK,EAAE,EAClGC,gBAAgB,CAACN,SAAeA,KAAKC,SAAS,WAAW,WAAWD,KAAKE,KAAKC,QAAQ,EAGtFI,gBAAgB,CAACC,SAAcA,KAAKP,IAAI;MAC7C;AAEA,aAAO,MAAA;AACLV,mBAAWE,SAASgB,eAAAA,EAAiBC,UAAU;UAAEC,OAAO,CAAA;UAAIC,OAAO,CAAA;QAAG,CAAA;AACtErB,mBAAWE,UAAUoB;MACvB;IACF,GAAG,CAAA,CAAE;AAELjB,IAAAA,WAAU,MAAA;AACR,UAAIL,WAAWE,WAAWR,SAASC,UAAUJ,OAAO;AAElDS,mBAAWE,QACRgB,eAAc,EACdxB,MAAMA,KAAAA,EACNC,OAAOA,MAAAA,EACP4B,aAAa,MAAA;AACZC,0BAAAA;QACF,CAAA,EACCC,YAAY,CAAChB,SAAAA;AACZT,qBAAWE,SAASwB,aAAajB,IAAAA;QACnC,CAAA,EAICkB,QAAQ,QAAQC,UAAAA,EAAYC,SAAS,GAAA,EAAKC,SAAS,GAAA,CAAA,EACnDH,QAAQ,UAAUI,cAAAA,EAAgBD,SAAS,GAAC,CAAA,EAE5CX,UAAU,IAAIa,aAAazC,KAAAA,CAAAA,EAC3B0C,YAAY,GAAA,EACZC,aAAa,GAAA,EACbC,gBAAe;MACpB;IACF,GAAG;MAAC5C;MAAOG;MAAOC;KAAO;AAEzB,UAAM6B,kBAAkB,MAAA;AACtBxB,iBAAWE,SAASkC,UAAU,KAAK,EAAA;IACrC;AAEA,WACE,gBAAAC,OAAA,cAACC,OAAAA;MAAI7C;MAAU8C,WAAU;MAAgBC,SAAShB;OAChD,gBAAAa,OAAA,cAACC,OAAAA;MAAI7C,KAAKK;MAASyC,WAAU;;;;;AAGnC;",
|
|
6
|
-
"names": ["React", "useCallback", "useEffect", "useMemo", "useRef", "getTypename", "SelectionModel", "GraphForceProjector", "SVG", "getHashColor", "D3ForceGraph", "classNames", "model", "selection", "_selection", "grid", "props", "context", "useRef", "projector", "useMemo", "current", "GraphForceProjector", "attributes", "linkForce", "edge", "data", "object", "active", "forces", "point", "strength", "graph", "SelectionModel", "useEffect", "repaint", "selected", "value", "handleSelect", "useCallback", "node", "contains", "id", "remove", "add", "SVG", "Root", "ref", "Markers", "Grid", "axis", "Zoom", "extent", "Graph", "labels", "text", "label", "obj", "color", "getHashColor", "getTypename", "classes", "onSelect", "forceLink", "forceManyBody", "NativeForceGraph", "React", "useEffect", "useRef", "useResizeDetector", "filterObjectsSync", "GraphAdapter", "graph", "_nodes", "_links", "nodes", "map", "node", "id", "type", "data", "edges", "edge", "source", "target", "links", "ForceGraph", "model", "match", "ref", "width", "height", "useResizeDetector", "refreshRate", "rootRef", "useRef", "forceGraph", "filteredRef", "current", "filterObjectsSync", "objects", "useEffect", "NativeForceGraph", "nodeRelSize", "nodeLabel", "node", "type", "data", "typename", "label", "id", "nodeAutoColorBy", "linkAutoColorBy", "link", "pauseAnimation", "graphData", "nodes", "links", "undefined", "onEngineStop", "handleZoomToFit", "onNodeClick", "emitParticle", "d3Force", "forceLink", "distance", "strength", "forceManyBody", "GraphAdapter", "warmupTicks", "cooldownTime", "resumeAnimation", "zoomToFit", "React", "div", "className", "onClick"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/capabilities/intent-resolver.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { contributes, Capabilities, createResolver } from '@dxos/app-framework';\nimport { live } from '@dxos/live-object';\n\nimport { ExplorerAction, ViewType } from '../types';\n\nexport default () =>\n contributes(\n Capabilities.IntentResolver,\n createResolver({\n intent: ExplorerAction.Create,\n resolve: ({ name }) => ({\n data: { object: live(ViewType, { name, type: '' }) },\n }),\n }),\n );\n"],
|
|
5
|
-
"mappings": ";;;;;;;AAIA,SAASA,aAAaC,cAAcC,sBAAsB;AAC1D,SAASC,YAAY;AAIrB,IAAA,0BAAe,MACbC,YACEC,aAAaC,gBACbC,eAAe;EACbC,QAAQC,eAAeC;EACvBC,SAAS,CAAC,EAAEC,KAAI,OAAQ;IACtBC,MAAM;MAAEC,QAAQC,KAAKC,UAAU;QAAEJ;QAAMK,MAAM;MAAG,CAAA;IAAG;EACrD;AACF,CAAA,CAAA;",
|
|
6
|
-
"names": ["contributes", "Capabilities", "createResolver", "live", "contributes", "Capabilities", "IntentResolver", "createResolver", "intent", "ExplorerAction", "Create", "resolve", "name", "data", "object", "live", "ViewType", "type"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/capabilities/react-surface.tsx"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport React from 'react';\n\nimport { Capabilities, contributes, createSurface } from '@dxos/app-framework';\nimport { isInstanceOf } from '@dxos/echo-schema';\n\nimport { ExplorerContainer } from '../components';\nimport { EXPLORER_PLUGIN } from '../meta';\nimport { ViewType } from '../types';\n\nexport default () =>\n contributes(\n Capabilities.ReactSurface,\n createSurface({\n id: `${EXPLORER_PLUGIN}/article`,\n role: ['article', 'section'],\n filter: (data): data is { subject: ViewType } => isInstanceOf(ViewType, data.subject),\n component: ({ data, role }) => <ExplorerContainer view={data.subject} role={role} />,\n }),\n );\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;AAIA,OAAOA,WAAW;AAElB,SAASC,cAAcC,aAAaC,qBAAqB;AACzD,SAASC,oBAAoB;AAM7B,IAAA,wBAAe,MACbC,YACEC,aAAaC,cACbC,cAAc;EACZC,IAAI,GAAGC,eAAAA;EACPC,MAAM;IAAC;IAAW;;EAClBC,QAAQ,CAACC,SAAwCC,aAAaC,UAAUF,KAAKG,OAAO;EACpFC,WAAW,CAAC,EAAEJ,MAAMF,KAAI,MAAO,sBAAA,cAACO,mBAAAA;IAAkBC,MAAMN,KAAKG;IAASL;;AACxE,CAAA,CAAA;",
|
|
6
|
-
"names": ["React", "Capabilities", "contributes", "createSurface", "isInstanceOf", "contributes", "Capabilities", "ReactSurface", "createSurface", "id", "EXPLORER_PLUGIN", "role", "filter", "data", "isInstanceOf", "ViewType", "subject", "component", "ExplorerContainer", "view"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/components/ExplorerContainer.tsx"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport React from 'react';\n\nimport { useGlobalSearch } from '@dxos/plugin-search';\nimport { getSpace } from '@dxos/react-client/echo';\nimport { StackItem } from '@dxos/react-ui-stack';\n\nimport { ForceGraph } from './Graph';\nimport { useGraphModel } from '../hooks';\nimport { type ViewType } from '../types';\n\ntype ExplorerContainerProps = {\n role: string;\n view: ViewType;\n};\n\nconst ExplorerContainer = ({ role, view }: ExplorerContainerProps) => {\n const space = getSpace(view);\n const { match } = useGlobalSearch();\n const model = useGraphModel(space);\n\n if (!model || !space) {\n return null;\n }\n\n return (\n <StackItem.Content size={role === 'section' ? 'square' : 'intrinsic'}>\n <ForceGraph model={model} match={match} />\n </StackItem.Content>\n );\n};\n\nexport default ExplorerContainer;\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,mBAAkB;AAElB,2BAAgC;AAChC,kBAAyB;AACzB,4BAA0B;AAW1B,IAAMA,oBAAoB,CAAC,EAAEC,MAAMC,KAAI,MAA0B;;;AAC/D,UAAMC,YAAQC,sBAASF,IAAAA;AACvB,UAAM,EAAEG,MAAK,QAAKC,sCAAAA;AAClB,UAAMC,YAAQC,qCAAcL,KAAAA;AAE5B,QAAI,CAACI,SAAS,CAACJ,OAAO;AACpB,aAAO;IACT;AAEA,WACE,6BAAAM,QAAA,cAACC,gCAAUC,SAAO;MAACC,MAAMX,SAAS,YAAY,WAAW;OACvD,6BAAAQ,QAAA,cAACI,kCAAAA;MAAWN;MAAcF;;;;;AAGhC;AAEA,IAAA,4BAAeL;",
|
|
6
|
-
"names": ["ExplorerContainer", "role", "view", "space", "getSpace", "match", "useGlobalSearch", "model", "useGraphModel", "React", "StackItem", "Content", "size", "ForceGraph"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/components/Graph/D3ForceGraph.tsx", "../../../src/components/Graph/ForceGraph.tsx", "../../../src/components/Graph/adapter.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport React, { type FC, useCallback, useEffect, useMemo, useRef } from 'react';\n\nimport { getTypename } from '@dxos/echo-schema';\nimport { SelectionModel } from '@dxos/graph';\nimport { type ThemedClassName } from '@dxos/react-ui';\nimport {\n type GraphController,\n GraphForceProjector,\n type GraphLayoutNode,\n type GraphProps,\n SVG,\n type SVGContext,\n} from '@dxos/react-ui-graph';\nimport { getHashColor } from '@dxos/react-ui-theme';\nimport { type SpaceGraphNode, type SpaceGraphModel, type SpaceGraphEdge } from '@dxos/schema';\n\nimport '@dxos/react-ui-graph/styles/graph.css';\n\nexport type D3ForceGraphProps = ThemedClassName<\n {\n model?: SpaceGraphModel;\n match?: RegExp;\n selection?: SelectionModel;\n grid?: boolean;\n } & Pick<GraphProps, 'drag'>\n>;\n\nexport const D3ForceGraph: FC<D3ForceGraphProps> = ({ classNames, model, selection: _selection, grid, ...props }) => {\n const context = useRef<SVGContext>(null);\n const projector = useMemo<GraphForceProjector | undefined>(() => {\n if (context.current) {\n return new GraphForceProjector(context.current, {\n attributes: {\n linkForce: (edge) => {\n // TODO(burdon): Check type (currently assumes Employee property).\n // Edge shouldn't contribute to force if it's not active.\n return edge.data?.object?.active !== false;\n },\n },\n forces: {\n point: {\n strength: 0.01,\n },\n },\n });\n }\n }, [context.current]);\n\n const graph = useRef<GraphController>(null);\n const selection = useMemo(() => _selection ?? new SelectionModel(), [_selection]);\n useEffect(() => graph.current?.repaint(), [selection.selected.value]);\n\n const handleSelect = useCallback<NonNullable<GraphProps['onSelect']>>(\n (node) => {\n if (selection.contains(node.id)) {\n selection.remove(node.id);\n } else {\n selection.add(node.id);\n }\n },\n [selection],\n );\n\n return (\n <SVG.Root ref={context} classNames={classNames}>\n <SVG.Markers />\n {grid && <SVG.Grid axis />}\n <SVG.Zoom extent={[1 / 2, 2]}>\n <SVG.Graph<SpaceGraphNode, SpaceGraphEdge>\n {...props}\n ref={graph}\n model={model}\n projector={projector}\n labels={{\n text: (node) => {\n return node.data?.data.label ?? node.id;\n },\n }}\n attributes={{\n node: (node: GraphLayoutNode<SpaceGraphNode>) => {\n const obj = node.data?.data.object;\n return {\n data: {\n color: getHashColor(obj && getTypename(obj))?.color,\n },\n classes: {\n 'dx-selected': selection.contains(node.id),\n },\n };\n },\n }}\n onSelect={handleSelect}\n />\n </SVG.Zoom>\n </SVG.Root>\n );\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { forceLink, forceManyBody } from 'd3';\nimport NativeForceGraph from 'force-graph';\nimport React, { type FC, useEffect, useRef } from 'react';\nimport { useResizeDetector } from 'react-resize-detector';\n\nimport { filterObjectsSync, type SearchResult } from '@dxos/plugin-search';\nimport { type SpaceGraphModel } from '@dxos/schema';\n\nimport { GraphAdapter } from './adapter';\n\nexport type ForceGraphProps = {\n model?: SpaceGraphModel;\n match?: RegExp;\n};\n\nexport const ForceGraph: FC<ForceGraphProps> = ({ model, match }) => {\n const { ref, width, height } = useResizeDetector({ refreshRate: 200 });\n const rootRef = useRef<HTMLDivElement>(null);\n const forceGraph = useRef<NativeForceGraph>();\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 NativeForceGraph(rootRef.current)\n // https://github.com/vasturiano/force-graph?tab=readme-ov-file#node-styling\n .nodeRelSize(6)\n .nodeLabel((node: any) => (node.type === 'schema' ? node.data.typename : node.data.label ?? node.id))\n .nodeAutoColorBy((node: any) => (node.type === 'schema' ? 'schema' : node.data.typename))\n\n // https://github.com/vasturiano/force-graph?tab=readme-ov-file#link-styling\n .linkAutoColorBy((link: any) => link.type);\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 // https://github.com/vasturiano/force-graph?tab=readme-ov-file#container-layout\n forceGraph.current\n .pauseAnimation()\n .width(width)\n .height(height)\n .onEngineStop(() => {\n handleZoomToFit();\n })\n .onNodeClick((node: any) => {\n forceGraph.current?.emitParticle(node);\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\n .graphData(new GraphAdapter(model))\n .warmupTicks(100)\n .cooldownTime(1_000)\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", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Graph } from '@dxos/graph';\n\nexport type GraphNode = {\n id?: string;\n};\n\nexport type GraphLink = {\n source?: string;\n target?: string;\n};\n\nexport type GraphData = {\n nodes: GraphNode[];\n links: GraphLink[];\n};\n\nexport class GraphAdapter implements GraphData {\n private readonly _nodes: GraphNode[] = [];\n private readonly _links: GraphLink[] = [];\n\n constructor(private readonly graph: Graph) {\n this._nodes = graph.nodes.map((node) => ({\n id: node.id,\n type: node.type,\n data: node.data,\n }));\n\n this._links = graph.edges.map((edge) => ({\n type: edge.type,\n source: edge.source,\n target: edge.target,\n data: edge.data,\n }));\n }\n\n get nodes() {\n return this._nodes;\n }\n\n get links() {\n return this._links;\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["import_graph", "import_react", "D3ForceGraph", "classNames", "model", "selection", "_selection", "grid", "props", "context", "useRef", "projector", "useMemo", "current", "GraphForceProjector", "attributes", "linkForce", "edge", "data", "object", "active", "forces", "point", "strength", "graph", "SelectionModel", "useEffect", "repaint", "selected", "value", "handleSelect", "useCallback", "node", "contains", "id", "remove", "add", "React", "SVG", "Root", "ref", "Markers", "Grid", "axis", "Zoom", "extent", "Graph", "labels", "text", "label", "obj", "color", "getHashColor", "getTypename", "classes", "onSelect", "GraphAdapter", "_nodes", "_links", "nodes", "map", "type", "edges", "source", "target", "links", "ForceGraph", "match", "width", "height", "useResizeDetector", "refreshRate", "rootRef", "forceGraph", "filteredRef", "filterObjectsSync", "objects", "NativeForceGraph", "nodeRelSize", "nodeLabel", "typename", "nodeAutoColorBy", "linkAutoColorBy", "link", "pauseAnimation", "graphData", "undefined", "onEngineStop", "handleZoomToFit", "onNodeClick", "emitParticle", "d3Force", "forceLink", "distance", "forceManyBody", "warmupTicks", "cooldownTime", "resumeAnimation", "zoomToFit", "div", "className", "onClick"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/capabilities/intent-resolver.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { contributes, Capabilities, createResolver } from '@dxos/app-framework';\nimport { live } from '@dxos/live-object';\n\nimport { ExplorerAction, ViewType } from '../types';\n\nexport default () =>\n contributes(\n Capabilities.IntentResolver,\n createResolver({\n intent: ExplorerAction.Create,\n resolve: ({ name }) => ({\n data: { object: live(ViewType, { name, type: '' }) },\n }),\n }),\n );\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;AAIA,2BAA0D;AAC1D,yBAAqB;AAIrB,IAAA,0BAAe,UACbA,kCACEC,kCAAaC,oBACbC,qCAAe;EACbC,QAAQC,qCAAeC;EACvBC,SAAS,CAAC,EAAEC,KAAI,OAAQ;IACtBC,MAAM;MAAEC,YAAQC,yBAAKC,gCAAU;QAAEJ;QAAMK,MAAM;MAAG,CAAA;IAAG;EACrD;AACF,CAAA,CAAA;",
|
|
6
|
-
"names": ["contributes", "Capabilities", "IntentResolver", "createResolver", "intent", "ExplorerAction", "Create", "resolve", "name", "data", "object", "live", "ViewType", "type"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/capabilities/react-surface.tsx"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport React from 'react';\n\nimport { Capabilities, contributes, createSurface } from '@dxos/app-framework';\nimport { isInstanceOf } from '@dxos/echo-schema';\n\nimport { ExplorerContainer } from '../components';\nimport { EXPLORER_PLUGIN } from '../meta';\nimport { ViewType } from '../types';\n\nexport default () =>\n contributes(\n Capabilities.ReactSurface,\n createSurface({\n id: `${EXPLORER_PLUGIN}/article`,\n role: ['article', 'section'],\n filter: (data): data is { subject: ViewType } => isInstanceOf(ViewType, data.subject),\n component: ({ data, role }) => <ExplorerContainer view={data.subject} role={role} />,\n }),\n );\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,mBAAkB;AAElB,2BAAyD;AACzD,yBAA6B;AAM7B,IAAA,wBAAe,UACbA,kCACEC,kCAAaC,kBACbC,oCAAc;EACZC,IAAI,GAAGC,qCAAAA;EACPC,MAAM;IAAC;IAAW;;EAClBC,QAAQ,CAACC,aAAwCC,iCAAaC,gCAAUF,KAAKG,OAAO;EACpFC,WAAW,CAAC,EAAEJ,MAAMF,KAAI,MAAO,6BAAAO,QAAA,cAACC,yCAAAA;IAAkBC,MAAMP,KAAKG;IAASL;;AACxE,CAAA,CAAA;",
|
|
6
|
-
"names": ["contributes", "Capabilities", "ReactSurface", "createSurface", "id", "EXPLORER_PLUGIN", "role", "filter", "data", "isInstanceOf", "ViewType", "subject", "component", "React", "ExplorerContainer", "view"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/components/ExplorerContainer.tsx"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport React from 'react';\n\nimport { useGlobalSearch } from '@dxos/plugin-search';\nimport { getSpace } from '@dxos/react-client/echo';\nimport { StackItem } from '@dxos/react-ui-stack';\n\nimport { ForceGraph } from './Graph';\nimport { useGraphModel } from '../hooks';\nimport { type ViewType } from '../types';\n\ntype ExplorerContainerProps = {\n role: string;\n view: ViewType;\n};\n\nconst ExplorerContainer = ({ role, view }: ExplorerContainerProps) => {\n const space = getSpace(view);\n const { match } = useGlobalSearch();\n const model = useGraphModel(space);\n\n if (!model || !space) {\n return null;\n }\n\n return (\n <StackItem.Content size={role === 'section' ? 'square' : 'intrinsic'}>\n <ForceGraph model={model} match={match} />\n </StackItem.Content>\n );\n};\n\nexport default ExplorerContainer;\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;AAIA,OAAOA,WAAW;AAElB,SAASC,uBAAuB;AAChC,SAASC,gBAAgB;AACzB,SAASC,iBAAiB;AAW1B,IAAMC,oBAAoB,CAAC,EAAEC,MAAMC,KAAI,MAA0B;;;AAC/D,UAAMC,QAAQC,SAASF,IAAAA;AACvB,UAAM,EAAEG,MAAK,IAAKC,gBAAAA;AAClB,UAAMC,QAAQC,cAAcL,KAAAA;AAE5B,QAAI,CAACI,SAAS,CAACJ,OAAO;AACpB,aAAO;IACT;AAEA,WACE,sBAAA,cAACM,UAAUC,SAAO;MAACC,MAAMV,SAAS,YAAY,WAAW;OACvD,sBAAA,cAACW,YAAAA;MAAWL;MAAcF;;;;;AAGhC;AAEA,IAAA,4BAAeL;",
|
|
6
|
-
"names": ["React", "useGlobalSearch", "getSpace", "StackItem", "ExplorerContainer", "role", "view", "space", "getSpace", "match", "useGlobalSearch", "model", "useGraphModel", "StackItem", "Content", "size", "ForceGraph"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/components/Graph/D3ForceGraph.tsx", "../../../src/components/Graph/ForceGraph.tsx", "../../../src/components/Graph/adapter.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport React, { type FC, useCallback, useEffect, useMemo, useRef } from 'react';\n\nimport { getTypename } from '@dxos/echo-schema';\nimport { SelectionModel } from '@dxos/graph';\nimport { type ThemedClassName } from '@dxos/react-ui';\nimport {\n type GraphController,\n GraphForceProjector,\n type GraphLayoutNode,\n type GraphProps,\n SVG,\n type SVGContext,\n} from '@dxos/react-ui-graph';\nimport { getHashColor } from '@dxos/react-ui-theme';\nimport { type SpaceGraphNode, type SpaceGraphModel, type SpaceGraphEdge } from '@dxos/schema';\n\nimport '@dxos/react-ui-graph/styles/graph.css';\n\nexport type D3ForceGraphProps = ThemedClassName<\n {\n model?: SpaceGraphModel;\n match?: RegExp;\n selection?: SelectionModel;\n grid?: boolean;\n } & Pick<GraphProps, 'drag'>\n>;\n\nexport const D3ForceGraph: FC<D3ForceGraphProps> = ({ classNames, model, selection: _selection, grid, ...props }) => {\n const context = useRef<SVGContext>(null);\n const projector = useMemo<GraphForceProjector | undefined>(() => {\n if (context.current) {\n return new GraphForceProjector(context.current, {\n attributes: {\n linkForce: (edge) => {\n // TODO(burdon): Check type (currently assumes Employee property).\n // Edge shouldn't contribute to force if it's not active.\n return edge.data?.object?.active !== false;\n },\n },\n forces: {\n point: {\n strength: 0.01,\n },\n },\n });\n }\n }, [context.current]);\n\n const graph = useRef<GraphController>(null);\n const selection = useMemo(() => _selection ?? new SelectionModel(), [_selection]);\n useEffect(() => graph.current?.repaint(), [selection.selected.value]);\n\n const handleSelect = useCallback<NonNullable<GraphProps['onSelect']>>(\n (node) => {\n if (selection.contains(node.id)) {\n selection.remove(node.id);\n } else {\n selection.add(node.id);\n }\n },\n [selection],\n );\n\n return (\n <SVG.Root ref={context} classNames={classNames}>\n <SVG.Markers />\n {grid && <SVG.Grid axis />}\n <SVG.Zoom extent={[1 / 2, 2]}>\n <SVG.Graph<SpaceGraphNode, SpaceGraphEdge>\n {...props}\n ref={graph}\n model={model}\n projector={projector}\n labels={{\n text: (node) => {\n return node.data?.data.label ?? node.id;\n },\n }}\n attributes={{\n node: (node: GraphLayoutNode<SpaceGraphNode>) => {\n const obj = node.data?.data.object;\n return {\n data: {\n color: getHashColor(obj && getTypename(obj))?.color,\n },\n classes: {\n 'dx-selected': selection.contains(node.id),\n },\n };\n },\n }}\n onSelect={handleSelect}\n />\n </SVG.Zoom>\n </SVG.Root>\n );\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { forceLink, forceManyBody } from 'd3';\nimport NativeForceGraph from 'force-graph';\nimport React, { type FC, useEffect, useRef } from 'react';\nimport { useResizeDetector } from 'react-resize-detector';\n\nimport { filterObjectsSync, type SearchResult } from '@dxos/plugin-search';\nimport { type SpaceGraphModel } from '@dxos/schema';\n\nimport { GraphAdapter } from './adapter';\n\nexport type ForceGraphProps = {\n model?: SpaceGraphModel;\n match?: RegExp;\n};\n\nexport const ForceGraph: FC<ForceGraphProps> = ({ model, match }) => {\n const { ref, width, height } = useResizeDetector({ refreshRate: 200 });\n const rootRef = useRef<HTMLDivElement>(null);\n const forceGraph = useRef<NativeForceGraph>();\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 NativeForceGraph(rootRef.current)\n // https://github.com/vasturiano/force-graph?tab=readme-ov-file#node-styling\n .nodeRelSize(6)\n .nodeLabel((node: any) => (node.type === 'schema' ? node.data.typename : node.data.label ?? node.id))\n .nodeAutoColorBy((node: any) => (node.type === 'schema' ? 'schema' : node.data.typename))\n\n // https://github.com/vasturiano/force-graph?tab=readme-ov-file#link-styling\n .linkAutoColorBy((link: any) => link.type);\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 // https://github.com/vasturiano/force-graph?tab=readme-ov-file#container-layout\n forceGraph.current\n .pauseAnimation()\n .width(width)\n .height(height)\n .onEngineStop(() => {\n handleZoomToFit();\n })\n .onNodeClick((node: any) => {\n forceGraph.current?.emitParticle(node);\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\n .graphData(new GraphAdapter(model))\n .warmupTicks(100)\n .cooldownTime(1_000)\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", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Graph } from '@dxos/graph';\n\nexport type GraphNode = {\n id?: string;\n};\n\nexport type GraphLink = {\n source?: string;\n target?: string;\n};\n\nexport type GraphData = {\n nodes: GraphNode[];\n links: GraphLink[];\n};\n\nexport class GraphAdapter implements GraphData {\n private readonly _nodes: GraphNode[] = [];\n private readonly _links: GraphLink[] = [];\n\n constructor(private readonly graph: Graph) {\n this._nodes = graph.nodes.map((node) => ({\n id: node.id,\n type: node.type,\n data: node.data,\n }));\n\n this._links = graph.edges.map((edge) => ({\n type: edge.type,\n source: edge.source,\n target: edge.target,\n data: edge.data,\n }));\n }\n\n get nodes() {\n return this._nodes;\n }\n\n get links() {\n return this._links;\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["React", "useCallback", "useEffect", "useMemo", "useRef", "getTypename", "SelectionModel", "GraphForceProjector", "SVG", "getHashColor", "D3ForceGraph", "classNames", "model", "selection", "_selection", "grid", "props", "context", "useRef", "projector", "useMemo", "current", "GraphForceProjector", "attributes", "linkForce", "edge", "data", "object", "active", "forces", "point", "strength", "graph", "SelectionModel", "useEffect", "repaint", "selected", "value", "handleSelect", "useCallback", "node", "contains", "id", "remove", "add", "SVG", "Root", "ref", "Markers", "Grid", "axis", "Zoom", "extent", "Graph", "labels", "text", "label", "obj", "color", "getHashColor", "getTypename", "classes", "onSelect", "forceLink", "forceManyBody", "NativeForceGraph", "React", "useEffect", "useRef", "useResizeDetector", "filterObjectsSync", "GraphAdapter", "graph", "_nodes", "_links", "nodes", "map", "node", "id", "type", "data", "edges", "edge", "source", "target", "links", "ForceGraph", "model", "match", "ref", "width", "height", "useResizeDetector", "refreshRate", "rootRef", "useRef", "forceGraph", "filteredRef", "current", "filterObjectsSync", "objects", "useEffect", "NativeForceGraph", "nodeRelSize", "nodeLabel", "node", "type", "data", "typename", "label", "id", "nodeAutoColorBy", "linkAutoColorBy", "link", "pauseAnimation", "graphData", "nodes", "links", "undefined", "onEngineStop", "handleZoomToFit", "onNodeClick", "emitParticle", "d3Force", "forceLink", "distance", "strength", "forceManyBody", "GraphAdapter", "warmupTicks", "cooldownTime", "resumeAnimation", "zoomToFit", "React", "div", "className", "onClick"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/capabilities/intent-resolver.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { contributes, Capabilities, createResolver } from '@dxos/app-framework';\nimport { live } from '@dxos/live-object';\n\nimport { ExplorerAction, ViewType } from '../types';\n\nexport default () =>\n contributes(\n Capabilities.IntentResolver,\n createResolver({\n intent: ExplorerAction.Create,\n resolve: ({ name }) => ({\n data: { object: live(ViewType, { name, type: '' }) },\n }),\n }),\n );\n"],
|
|
5
|
-
"mappings": ";;;;;;;;AAIA,SAASA,aAAaC,cAAcC,sBAAsB;AAC1D,SAASC,YAAY;AAIrB,IAAA,0BAAe,MACbC,YACEC,aAAaC,gBACbC,eAAe;EACbC,QAAQC,eAAeC;EACvBC,SAAS,CAAC,EAAEC,KAAI,OAAQ;IACtBC,MAAM;MAAEC,QAAQC,KAAKC,UAAU;QAAEJ;QAAMK,MAAM;MAAG,CAAA;IAAG;EACrD;AACF,CAAA,CAAA;",
|
|
6
|
-
"names": ["contributes", "Capabilities", "createResolver", "live", "contributes", "Capabilities", "IntentResolver", "createResolver", "intent", "ExplorerAction", "Create", "resolve", "name", "data", "object", "live", "ViewType", "type"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/capabilities/react-surface.tsx"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport React from 'react';\n\nimport { Capabilities, contributes, createSurface } from '@dxos/app-framework';\nimport { isInstanceOf } from '@dxos/echo-schema';\n\nimport { ExplorerContainer } from '../components';\nimport { EXPLORER_PLUGIN } from '../meta';\nimport { ViewType } from '../types';\n\nexport default () =>\n contributes(\n Capabilities.ReactSurface,\n createSurface({\n id: `${EXPLORER_PLUGIN}/article`,\n role: ['article', 'section'],\n filter: (data): data is { subject: ViewType } => isInstanceOf(ViewType, data.subject),\n component: ({ data, role }) => <ExplorerContainer view={data.subject} role={role} />,\n }),\n );\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;AAIA,OAAOA,WAAW;AAElB,SAASC,cAAcC,aAAaC,qBAAqB;AACzD,SAASC,oBAAoB;AAM7B,IAAA,wBAAe,MACbC,YACEC,aAAaC,cACbC,cAAc;EACZC,IAAI,GAAGC,eAAAA;EACPC,MAAM;IAAC;IAAW;;EAClBC,QAAQ,CAACC,SAAwCC,aAAaC,UAAUF,KAAKG,OAAO;EACpFC,WAAW,CAAC,EAAEJ,MAAMF,KAAI,MAAO,sBAAA,cAACO,mBAAAA;IAAkBC,MAAMN,KAAKG;IAASL;;AACxE,CAAA,CAAA;",
|
|
6
|
-
"names": ["React", "Capabilities", "contributes", "createSurface", "isInstanceOf", "contributes", "Capabilities", "ReactSurface", "createSurface", "id", "EXPLORER_PLUGIN", "role", "filter", "data", "isInstanceOf", "ViewType", "subject", "component", "ExplorerContainer", "view"]
|
|
7
|
-
}
|