@dxos/plugin-debug 0.7.5-main.9d26e3a → 0.7.5-main.9d2a38b
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/{DebugApp-HCHR6GKO.mjs → DebugApp-LQHFFK3Y.mjs} +4 -2
- package/dist/lib/browser/{DebugApp-HCHR6GKO.mjs.map → DebugApp-LQHFFK3Y.mjs.map} +3 -3
- package/dist/lib/browser/{DebugSpace-V3K3PQP6.mjs → DebugSpace-4JHYA7FG.mjs} +7 -5
- package/dist/lib/browser/{DebugSpace-V3K3PQP6.mjs.map → DebugSpace-4JHYA7FG.mjs.map} +3 -3
- package/dist/lib/browser/{SpaceGenerator-Y2NXBQVR.mjs → SpaceGenerator-NJCG57CU.mjs} +7 -5
- package/dist/lib/browser/{SpaceGenerator-Y2NXBQVR.mjs.map → SpaceGenerator-NJCG57CU.mjs.map} +3 -3
- package/dist/lib/browser/app-graph-builder-FXELWOFS.mjs +177 -0
- package/dist/lib/browser/app-graph-builder-FXELWOFS.mjs.map +7 -0
- package/dist/lib/browser/{chunk-CAENAAHY.mjs → chunk-I3ON45JK.mjs} +3 -3
- package/dist/lib/browser/chunk-I3ON45JK.mjs.map +7 -0
- package/dist/lib/browser/{chunk-6CGQHKET.mjs → chunk-P7GHHMDB.mjs} +1 -1
- package/dist/lib/browser/chunk-P7GHHMDB.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +66 -712
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/react-context-OZU6J7G3.mjs +37 -0
- package/dist/lib/browser/react-context-OZU6J7G3.mjs.map +7 -0
- package/dist/lib/browser/react-surface-5GNO6NWP.mjs +468 -0
- package/dist/lib/browser/react-surface-5GNO6NWP.mjs.map +7 -0
- package/dist/lib/browser/settings-JCZUA643.mjs +25 -0
- package/dist/lib/browser/settings-JCZUA643.mjs.map +7 -0
- package/dist/types/src/DebugPlugin.d.ts +1 -2
- package/dist/types/src/DebugPlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/app-graph-builder.d.ts +181 -0
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts +185 -0
- package/dist/types/src/capabilities/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/react-context.d.ts +8 -0
- package/dist/types/src/capabilities/react-context.d.ts.map +1 -0
- package/dist/types/src/capabilities/react-surface.d.ts +4 -0
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
- package/dist/types/src/capabilities/settings.d.ts +4 -0
- package/dist/types/src/capabilities/settings.d.ts.map +1 -0
- package/dist/types/src/components/DebugStatus.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +1 -2
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +0 -3
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +43 -51
- package/src/DebugPlugin.tsx +58 -345
- package/src/capabilities/app-graph-builder.ts +177 -0
- package/src/capabilities/index.ts +10 -0
- package/src/capabilities/react-context.tsx +38 -0
- package/src/capabilities/react-surface.tsx +138 -0
- package/src/capabilities/settings.ts +18 -0
- package/src/components/DebugApp/DebugApp.tsx +1 -1
- package/src/components/DebugSettings.tsx +4 -4
- package/src/components/DebugSpace/DebugSpace.tsx +1 -1
- package/src/components/DebugStatus.tsx +3 -9
- package/src/components/SpaceGenerator/ObjectGenerator.tsx +3 -3
- package/src/components/SpaceGenerator/SpaceGenerator.tsx +1 -1
- package/src/index.ts +1 -4
- package/src/meta.ts +1 -1
- package/src/types.ts +0 -13
- package/dist/lib/browser/chunk-6CGQHKET.mjs.map +0 -7
- package/dist/lib/browser/chunk-CAENAAHY.mjs.map +0 -7
- package/dist/lib/browser/meta.mjs +0 -9
- package/dist/lib/browser/meta.mjs.map +0 -7
- package/dist/types/src/components/DebugSurface.d.ts +0 -9
- package/dist/types/src/components/DebugSurface.d.ts.map +0 -1
- package/src/components/DebugSurface.tsx +0 -55
package/src/DebugPlugin.tsx
CHANGED
|
@@ -2,355 +2,68 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
createIntent,
|
|
9
|
-
createSurface,
|
|
10
|
-
definePlugin,
|
|
11
|
-
parseGraphPlugin,
|
|
12
|
-
parseIntentPlugin,
|
|
13
|
-
parseMetadataResolverPlugin,
|
|
14
|
-
parseSettingsPlugin,
|
|
15
|
-
resolvePlugin,
|
|
16
|
-
} from '@dxos/app-framework';
|
|
17
|
-
import { Timer } from '@dxos/async';
|
|
18
|
-
import { Devtools } from '@dxos/devtools';
|
|
19
|
-
import { invariant } from '@dxos/invariant';
|
|
20
|
-
import { parseClientPlugin } from '@dxos/plugin-client/types';
|
|
21
|
-
import { createExtension, Graph, type Node, toSignal } from '@dxos/plugin-graph';
|
|
22
|
-
import { memoizeQuery, SpaceAction } from '@dxos/plugin-space';
|
|
23
|
-
import { CollectionType } from '@dxos/plugin-space/types';
|
|
5
|
+
import { Capabilities, contributes, defineModule, definePlugin, Events } from '@dxos/app-framework';
|
|
6
|
+
import { DeckCapabilities } from '@dxos/plugin-deck';
|
|
24
7
|
import { type Client } from '@dxos/react-client';
|
|
25
|
-
import {
|
|
26
|
-
create,
|
|
27
|
-
getTypename,
|
|
28
|
-
isEchoObject,
|
|
29
|
-
isSpace,
|
|
30
|
-
parseId,
|
|
31
|
-
type ReactiveEchoObject,
|
|
32
|
-
type ReactiveObject,
|
|
33
|
-
type Space,
|
|
34
|
-
SpaceState,
|
|
35
|
-
} from '@dxos/react-client/echo';
|
|
36
8
|
|
|
37
|
-
import {
|
|
38
|
-
|
|
39
|
-
DebugObjectPanel,
|
|
40
|
-
DebugSettings,
|
|
41
|
-
DebugSpace,
|
|
42
|
-
DebugStatus,
|
|
43
|
-
SpaceGenerator,
|
|
44
|
-
Wireframe,
|
|
45
|
-
} from './components';
|
|
46
|
-
import meta, { DEBUG_PLUGIN } from './meta';
|
|
9
|
+
import { AppGraphBuilder, DebugSettings, ReactContext, ReactSurface } from './capabilities';
|
|
10
|
+
import { DEBUG_PLUGIN, meta } from './meta';
|
|
47
11
|
import translations from './translations';
|
|
48
|
-
import { DebugContext, type DebugPluginProvides, type DebugSettingsProps, DebugSettingsSchema } from './types';
|
|
49
|
-
|
|
50
|
-
type SpaceDebug = {
|
|
51
|
-
type: string;
|
|
52
|
-
space: Space;
|
|
53
|
-
};
|
|
54
12
|
|
|
55
|
-
|
|
56
|
-
|
|
13
|
+
export const DebugPlugin = () => {
|
|
14
|
+
setupDevtools();
|
|
15
|
+
|
|
16
|
+
return definePlugin(meta, [
|
|
17
|
+
defineModule({
|
|
18
|
+
id: `${meta.id}/module/settings`,
|
|
19
|
+
activatesOn: Events.SetupSettings,
|
|
20
|
+
activate: DebugSettings,
|
|
21
|
+
}),
|
|
22
|
+
defineModule({
|
|
23
|
+
id: `${meta.id}/module/translations`,
|
|
24
|
+
activatesOn: Events.SetupTranslations,
|
|
25
|
+
activate: () => contributes(Capabilities.Translations, translations),
|
|
26
|
+
}),
|
|
27
|
+
defineModule({
|
|
28
|
+
id: `${meta.id}/module/complementary-panel`,
|
|
29
|
+
activatesOn: Events.Startup,
|
|
30
|
+
activate: () =>
|
|
31
|
+
contributes(DeckCapabilities.ComplementaryPanel, {
|
|
32
|
+
id: 'debug',
|
|
33
|
+
label: ['debug label', { ns: DEBUG_PLUGIN }],
|
|
34
|
+
icon: 'ph--bug--regular',
|
|
35
|
+
}),
|
|
36
|
+
}),
|
|
37
|
+
defineModule({
|
|
38
|
+
id: `${meta.id}/module/react-context`,
|
|
39
|
+
activatesOn: Events.Startup,
|
|
40
|
+
activate: ReactContext,
|
|
41
|
+
}),
|
|
42
|
+
defineModule({
|
|
43
|
+
id: `${meta.id}/module/react-surface`,
|
|
44
|
+
activatesOn: Events.Startup,
|
|
45
|
+
activate: ReactSurface,
|
|
46
|
+
}),
|
|
47
|
+
defineModule({
|
|
48
|
+
id: `${meta.id}/module/app-graph-builder`,
|
|
49
|
+
activatesOn: Events.SetupAppGraph,
|
|
50
|
+
activate: AppGraphBuilder,
|
|
51
|
+
}),
|
|
52
|
+
]);
|
|
57
53
|
};
|
|
58
54
|
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
context.resolvePlugin(parseSettingsPlugin).provides.settingsStore.createStore({
|
|
73
|
-
schema: DebugSettingsSchema,
|
|
74
|
-
prefix: DEBUG_PLUGIN,
|
|
75
|
-
value: settings,
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
// TODO(burdon): Remove hacky dependency on global variable.
|
|
79
|
-
// Used to test how composer handles breaking protocol changes.
|
|
80
|
-
const composer = (window as any).composer;
|
|
81
|
-
composer.changeStorageVersionInMetadata = async (version: number) => {
|
|
82
|
-
const { changeStorageVersionInMetadata } = await import('@dxos/echo-pipeline/testing');
|
|
83
|
-
const { createStorageObjects } = await import('@dxos/client-services');
|
|
84
|
-
const client: Client = (window as any).dxos.client;
|
|
85
|
-
const config = client.config;
|
|
86
|
-
await client.destroy();
|
|
87
|
-
const { storage } = createStorageObjects(config.values?.runtime?.client?.storage ?? {});
|
|
88
|
-
await changeStorageVersionInMetadata(storage, version);
|
|
89
|
-
location.pathname = '/';
|
|
90
|
-
};
|
|
91
|
-
},
|
|
92
|
-
unload: async () => {
|
|
93
|
-
context.dispose();
|
|
94
|
-
},
|
|
95
|
-
provides: {
|
|
96
|
-
settings,
|
|
97
|
-
translations,
|
|
98
|
-
complementary: {
|
|
99
|
-
panels: [{ id: 'debug', label: ['open debug panel label', { ns: DEBUG_PLUGIN }], icon: 'ph--bug--regular' }],
|
|
100
|
-
},
|
|
101
|
-
context: ({ children }) => {
|
|
102
|
-
const [timer, setTimer] = useState<Timer>();
|
|
103
|
-
useEffect(() => timer?.state.on((value) => !value && setTimer(undefined)), [timer]);
|
|
104
|
-
useEffect(() => {
|
|
105
|
-
timer?.stop();
|
|
106
|
-
}, []);
|
|
107
|
-
|
|
108
|
-
return (
|
|
109
|
-
<DebugContext.Provider
|
|
110
|
-
value={{
|
|
111
|
-
running: !!timer,
|
|
112
|
-
start: (cb, options) => {
|
|
113
|
-
timer?.stop();
|
|
114
|
-
setTimer(new Timer(cb).start(options));
|
|
115
|
-
},
|
|
116
|
-
stop: () => timer?.stop(),
|
|
117
|
-
}}
|
|
118
|
-
>
|
|
119
|
-
{children}
|
|
120
|
-
</DebugContext.Provider>
|
|
121
|
-
);
|
|
122
|
-
},
|
|
123
|
-
graph: {
|
|
124
|
-
builder: (plugins) => {
|
|
125
|
-
const clientPlugin = resolvePlugin(plugins, parseClientPlugin);
|
|
126
|
-
const metadataPlugin = resolvePlugin(plugins, parseMetadataResolverPlugin);
|
|
127
|
-
const graphPlugin = resolvePlugin(plugins, parseGraphPlugin);
|
|
128
|
-
const resolve = metadataPlugin?.provides.metadata.resolver;
|
|
129
|
-
const client = clientPlugin?.provides.client;
|
|
130
|
-
invariant(resolve);
|
|
131
|
-
invariant(client);
|
|
132
|
-
|
|
133
|
-
return [
|
|
134
|
-
// Devtools node.
|
|
135
|
-
createExtension({
|
|
136
|
-
id: 'dxos.org/plugin/debug/devtools',
|
|
137
|
-
filter: (node): node is Node<null> => !!settings.devtools && node.id === 'root',
|
|
138
|
-
connector: () => [
|
|
139
|
-
{
|
|
140
|
-
// TODO(zan): Removed `/` because it breaks deck layout reload. Fix?
|
|
141
|
-
id: 'dxos.org.plugin.debug.devtools',
|
|
142
|
-
data: 'devtools',
|
|
143
|
-
type: 'dxos.org/plugin/debug/devtools',
|
|
144
|
-
properties: {
|
|
145
|
-
label: ['devtools label', { ns: DEBUG_PLUGIN }],
|
|
146
|
-
icon: 'ph--hammer--regular',
|
|
147
|
-
},
|
|
148
|
-
},
|
|
149
|
-
],
|
|
150
|
-
}),
|
|
151
|
-
|
|
152
|
-
// Debug node.
|
|
153
|
-
createExtension({
|
|
154
|
-
id: 'dxos.org/plugin/debug/debug',
|
|
155
|
-
filter: (node): node is Node<null> => !!settings.debug && node.id === 'root',
|
|
156
|
-
connector: () => [
|
|
157
|
-
{
|
|
158
|
-
id: 'dxos.org/plugin/debug/debug',
|
|
159
|
-
type: 'dxos.org/plugin/debug/debug',
|
|
160
|
-
data: { graph: graphPlugin?.provides.graph },
|
|
161
|
-
properties: {
|
|
162
|
-
label: ['debug label', { ns: DEBUG_PLUGIN }],
|
|
163
|
-
icon: 'ph--bug--regular',
|
|
164
|
-
},
|
|
165
|
-
},
|
|
166
|
-
],
|
|
167
|
-
}),
|
|
168
|
-
|
|
169
|
-
// Space debug nodes.
|
|
170
|
-
createExtension({
|
|
171
|
-
id: 'dxos.org/plugin/debug/spaces',
|
|
172
|
-
filter: (node): node is Node<Space> => !!settings.debug && isSpace(node.data),
|
|
173
|
-
connector: ({ node }) => {
|
|
174
|
-
const space = node.data;
|
|
175
|
-
const state = toSignal(
|
|
176
|
-
(onChange) => space.state.subscribe(() => onChange()).unsubscribe,
|
|
177
|
-
() => space.state.get(),
|
|
178
|
-
space.id,
|
|
179
|
-
);
|
|
180
|
-
if (state !== SpaceState.SPACE_READY) {
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
// Not adding the debug node until the root collection is available aligns the behaviour of this
|
|
185
|
-
// extension with that of the space plugin adding objects. This ensures that the debug node is added at
|
|
186
|
-
// the same time as objects and prevents order from changing as the nodes are added.
|
|
187
|
-
const collection = space.properties[CollectionType.typename]?.target as CollectionType | undefined;
|
|
188
|
-
if (!collection) {
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
return [
|
|
193
|
-
{
|
|
194
|
-
id: `${space.id}-debug`, // TODO(burdon): Change to slashes consistently.
|
|
195
|
-
type: 'dxos.org/plugin/debug/space',
|
|
196
|
-
data: { space, type: 'dxos.org/plugin/debug/space' },
|
|
197
|
-
properties: {
|
|
198
|
-
label: ['debug label', { ns: DEBUG_PLUGIN }],
|
|
199
|
-
icon: 'ph--bug--regular',
|
|
200
|
-
},
|
|
201
|
-
},
|
|
202
|
-
];
|
|
203
|
-
},
|
|
204
|
-
}),
|
|
205
|
-
|
|
206
|
-
// Create nodes for debug sidebar.
|
|
207
|
-
createExtension({
|
|
208
|
-
id: `${DEBUG_PLUGIN}/debug-for-subject`,
|
|
209
|
-
resolver: ({ id }) => {
|
|
210
|
-
// TODO(Zan): Find util (or make one).
|
|
211
|
-
if (!id.endsWith('~debug')) {
|
|
212
|
-
return;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
const type = 'orphan-settings-for-subject';
|
|
216
|
-
const icon = 'ph--bug--regular';
|
|
217
|
-
|
|
218
|
-
const [subjectId] = id.split('~');
|
|
219
|
-
const { spaceId, objectId } = parseId(subjectId);
|
|
220
|
-
const spaces = toSignal(
|
|
221
|
-
(onChange) => client.spaces.subscribe(() => onChange()).unsubscribe,
|
|
222
|
-
() => client.spaces.get(),
|
|
223
|
-
);
|
|
224
|
-
const space = spaces?.find(
|
|
225
|
-
(space) => space.state.get() === SpaceState.SPACE_READY && space.id === spaceId,
|
|
226
|
-
);
|
|
227
|
-
if (!objectId) {
|
|
228
|
-
// TODO(burdon): Ref SPACE_PLUGIN ns.
|
|
229
|
-
const label = space
|
|
230
|
-
? space.properties.name || ['unnamed space label', { ns: DEBUG_PLUGIN }]
|
|
231
|
-
: ['unnamed object settings label', { ns: DEBUG_PLUGIN }];
|
|
232
|
-
|
|
233
|
-
// TODO(wittjosiah): Support comments for arbitrary subjects.
|
|
234
|
-
// This is to ensure that the comments panel is not stuck on an old object.
|
|
235
|
-
return {
|
|
236
|
-
id,
|
|
237
|
-
type,
|
|
238
|
-
data: null,
|
|
239
|
-
properties: {
|
|
240
|
-
icon,
|
|
241
|
-
label,
|
|
242
|
-
showResolvedThreads: false,
|
|
243
|
-
object: null,
|
|
244
|
-
space,
|
|
245
|
-
},
|
|
246
|
-
};
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
const [object] = memoizeQuery(space, { id: objectId });
|
|
250
|
-
if (!object || !subjectId) {
|
|
251
|
-
return;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
const meta = resolve(getTypename(object) ?? '');
|
|
255
|
-
const label = meta.label?.(object) ||
|
|
256
|
-
object.name ||
|
|
257
|
-
meta.placeholder || ['unnamed object settings label', { ns: DEBUG_PLUGIN }];
|
|
258
|
-
|
|
259
|
-
return {
|
|
260
|
-
id,
|
|
261
|
-
type,
|
|
262
|
-
data: null,
|
|
263
|
-
properties: {
|
|
264
|
-
icon,
|
|
265
|
-
label,
|
|
266
|
-
object,
|
|
267
|
-
},
|
|
268
|
-
};
|
|
269
|
-
},
|
|
270
|
-
}),
|
|
271
|
-
];
|
|
272
|
-
},
|
|
273
|
-
},
|
|
274
|
-
surface: {
|
|
275
|
-
definitions: () => [
|
|
276
|
-
createSurface({
|
|
277
|
-
id: `${DEBUG_PLUGIN}/settings`,
|
|
278
|
-
role: 'settings',
|
|
279
|
-
filter: (data): data is any => data.subject === DEBUG_PLUGIN,
|
|
280
|
-
component: () => <DebugSettings settings={settings} />,
|
|
281
|
-
}),
|
|
282
|
-
createSurface({
|
|
283
|
-
id: `${DEBUG_PLUGIN}/status`,
|
|
284
|
-
role: 'status',
|
|
285
|
-
component: () => <DebugStatus />,
|
|
286
|
-
}),
|
|
287
|
-
createSurface({
|
|
288
|
-
id: `${DEBUG_PLUGIN}/complementary`,
|
|
289
|
-
role: 'complementary--debug',
|
|
290
|
-
filter: (data): data is { subject: ReactiveEchoObject<any> } => isEchoObject(data.subject),
|
|
291
|
-
component: ({ data }) => <DebugObjectPanel object={data.subject} />,
|
|
292
|
-
}),
|
|
293
|
-
createSurface({
|
|
294
|
-
id: `${DEBUG_PLUGIN}/devtools`,
|
|
295
|
-
role: 'article',
|
|
296
|
-
filter: (data): data is any => data.subject === 'devtools' && !!settings.devtools,
|
|
297
|
-
component: () => <Devtools />,
|
|
298
|
-
}),
|
|
299
|
-
createSurface({
|
|
300
|
-
id: `${DEBUG_PLUGIN}/space`,
|
|
301
|
-
role: 'article',
|
|
302
|
-
filter: (data): data is { subject: SpaceDebug } => isSpaceDebug(data.subject),
|
|
303
|
-
component: ({ data }) => {
|
|
304
|
-
const handleCreateObject = useCallback(
|
|
305
|
-
(objects: ReactiveObject<any>[]) => {
|
|
306
|
-
if (!isSpace(data.subject.space)) {
|
|
307
|
-
return;
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
const collection =
|
|
311
|
-
data.subject.space.state.get() === SpaceState.SPACE_READY &&
|
|
312
|
-
data.subject.space.properties[CollectionType.typename]?.target;
|
|
313
|
-
if (!(collection instanceof CollectionType)) {
|
|
314
|
-
return;
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
objects.forEach((object) => {
|
|
318
|
-
void context
|
|
319
|
-
.resolvePlugin(parseIntentPlugin)
|
|
320
|
-
.provides.intent.dispatchPromise(
|
|
321
|
-
createIntent(SpaceAction.AddObject, { target: collection, object }),
|
|
322
|
-
);
|
|
323
|
-
});
|
|
324
|
-
},
|
|
325
|
-
[data.subject.space],
|
|
326
|
-
);
|
|
327
|
-
|
|
328
|
-
const deprecated = false;
|
|
329
|
-
return deprecated ? (
|
|
330
|
-
<DebugSpace space={data.subject.space} onAddObjects={handleCreateObject} />
|
|
331
|
-
) : (
|
|
332
|
-
<SpaceGenerator space={data.subject.space} onCreateObjects={handleCreateObject} />
|
|
333
|
-
);
|
|
334
|
-
},
|
|
335
|
-
}),
|
|
336
|
-
createSurface({
|
|
337
|
-
id: `${DEBUG_PLUGIN}/graph`,
|
|
338
|
-
role: 'article',
|
|
339
|
-
filter: (data): data is { subject: GraphDebug } => isGraphDebug(data.subject),
|
|
340
|
-
component: ({ data }) => <DebugApp graph={data.subject.graph} />,
|
|
341
|
-
}),
|
|
342
|
-
createSurface({
|
|
343
|
-
id: `${DEBUG_PLUGIN}/wireframe`,
|
|
344
|
-
role: ['article', 'section'],
|
|
345
|
-
disposition: 'hoist',
|
|
346
|
-
filter: (data): data is { subject: ReactiveEchoObject<any> } =>
|
|
347
|
-
isEchoObject(data.subject) && !!settings.wireframe,
|
|
348
|
-
component: ({ data, role }) => (
|
|
349
|
-
<Wireframe label={`${role}:${name}`} object={data.subject} classNames='row-span-2 overflow-hidden' />
|
|
350
|
-
),
|
|
351
|
-
}),
|
|
352
|
-
],
|
|
353
|
-
},
|
|
354
|
-
},
|
|
55
|
+
const setupDevtools = () => {
|
|
56
|
+
(globalThis as any).composer ??= {};
|
|
57
|
+
|
|
58
|
+
// Used to test how composer handles breaking protocol changes.
|
|
59
|
+
(globalThis as any).composer.changeStorageVersionInMetadata = async (version: number) => {
|
|
60
|
+
const { changeStorageVersionInMetadata } = await import('@dxos/echo-pipeline/testing');
|
|
61
|
+
const { createStorageObjects } = await import('@dxos/client-services');
|
|
62
|
+
const client: Client = (window as any).dxos.client;
|
|
63
|
+
const config = client.config;
|
|
64
|
+
await client.destroy();
|
|
65
|
+
const { storage } = createStorageObjects(config.values?.runtime?.client?.storage ?? {});
|
|
66
|
+
await changeStorageVersionInMetadata(storage, version);
|
|
67
|
+
location.pathname = '/';
|
|
355
68
|
};
|
|
356
|
-
}
|
|
69
|
+
};
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { contributes, Capabilities, type PluginsContext } from '@dxos/app-framework';
|
|
6
|
+
import { ClientCapabilities } from '@dxos/plugin-client';
|
|
7
|
+
import { createExtension, toSignal, type Node } from '@dxos/plugin-graph';
|
|
8
|
+
import { memoizeQuery } from '@dxos/plugin-space';
|
|
9
|
+
import { CollectionType } from '@dxos/plugin-space/types';
|
|
10
|
+
import { getTypename, parseId, SpaceState } from '@dxos/react-client/echo';
|
|
11
|
+
import { isSpace, type Space } from '@dxos/react-client/echo';
|
|
12
|
+
|
|
13
|
+
import { DEBUG_PLUGIN } from '../meta';
|
|
14
|
+
import { type DebugSettingsProps } from '../types';
|
|
15
|
+
|
|
16
|
+
export default (context: PluginsContext) => {
|
|
17
|
+
const resolve = (typename: string) =>
|
|
18
|
+
context.requestCapabilities(Capabilities.Metadata).find(({ id }) => id === typename)?.metadata ?? {};
|
|
19
|
+
|
|
20
|
+
return contributes(Capabilities.AppGraphBuilder, [
|
|
21
|
+
// Devtools node.
|
|
22
|
+
createExtension({
|
|
23
|
+
id: 'dxos.org/plugin/debug/devtools',
|
|
24
|
+
filter: (node): node is Node<null> => {
|
|
25
|
+
const settings = context
|
|
26
|
+
.requestCapabilities(Capabilities.SettingsStore)[0]
|
|
27
|
+
?.getStore<DebugSettingsProps>(DEBUG_PLUGIN)?.value;
|
|
28
|
+
return !!settings?.devtools && node.id === 'root';
|
|
29
|
+
},
|
|
30
|
+
connector: () => [
|
|
31
|
+
{
|
|
32
|
+
// TODO(zan): Removed `/` because it breaks deck layout reload. Fix?
|
|
33
|
+
id: 'dxos.org.plugin.debug.devtools',
|
|
34
|
+
data: 'devtools',
|
|
35
|
+
type: 'dxos.org/plugin/debug/devtools',
|
|
36
|
+
properties: {
|
|
37
|
+
label: ['devtools label', { ns: DEBUG_PLUGIN }],
|
|
38
|
+
icon: 'ph--hammer--regular',
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
}),
|
|
43
|
+
|
|
44
|
+
// Debug node.
|
|
45
|
+
createExtension({
|
|
46
|
+
id: 'dxos.org/plugin/debug/debug',
|
|
47
|
+
filter: (node): node is Node<null> => {
|
|
48
|
+
const settings = context
|
|
49
|
+
.requestCapabilities(Capabilities.SettingsStore)[0]
|
|
50
|
+
?.getStore<DebugSettingsProps>(DEBUG_PLUGIN)?.value;
|
|
51
|
+
return !!settings?.debug && node.id === 'root';
|
|
52
|
+
},
|
|
53
|
+
connector: () => {
|
|
54
|
+
const graph = context.requestCapability(Capabilities.AppGraph);
|
|
55
|
+
|
|
56
|
+
return [
|
|
57
|
+
{
|
|
58
|
+
id: 'dxos.org/plugin/debug/debug',
|
|
59
|
+
type: 'dxos.org/plugin/debug/debug',
|
|
60
|
+
data: { graph },
|
|
61
|
+
properties: {
|
|
62
|
+
label: ['debug label', { ns: DEBUG_PLUGIN }],
|
|
63
|
+
icon: 'ph--bug--regular',
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
];
|
|
67
|
+
},
|
|
68
|
+
}),
|
|
69
|
+
|
|
70
|
+
// Space debug nodes.
|
|
71
|
+
createExtension({
|
|
72
|
+
id: 'dxos.org/plugin/debug/spaces',
|
|
73
|
+
filter: (node): node is Node<Space> => {
|
|
74
|
+
const settings = context
|
|
75
|
+
.requestCapabilities(Capabilities.SettingsStore)[0]
|
|
76
|
+
?.getStore<DebugSettingsProps>(DEBUG_PLUGIN)?.value;
|
|
77
|
+
return !!settings?.debug && isSpace(node.data);
|
|
78
|
+
},
|
|
79
|
+
connector: ({ node }) => {
|
|
80
|
+
const space = node.data;
|
|
81
|
+
const state = toSignal(
|
|
82
|
+
(onChange) => space.state.subscribe(() => onChange()).unsubscribe,
|
|
83
|
+
() => space.state.get(),
|
|
84
|
+
space.id,
|
|
85
|
+
);
|
|
86
|
+
if (state !== SpaceState.SPACE_READY) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Not adding the debug node until the root collection is available aligns the behaviour of this
|
|
91
|
+
// extension with that of the space plugin adding objects. This ensures that the debug node is added at
|
|
92
|
+
// the same time as objects and prevents order from changing as the nodes are added.
|
|
93
|
+
const collection = space.properties[CollectionType.typename]?.target as CollectionType | undefined;
|
|
94
|
+
if (!collection) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return [
|
|
99
|
+
{
|
|
100
|
+
id: `${space.id}-debug`, // TODO(burdon): Change to slashes consistently.
|
|
101
|
+
type: 'dxos.org/plugin/debug/space',
|
|
102
|
+
data: { space, type: 'dxos.org/plugin/debug/space' },
|
|
103
|
+
properties: {
|
|
104
|
+
label: ['debug label', { ns: DEBUG_PLUGIN }],
|
|
105
|
+
icon: 'ph--bug--regular',
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
];
|
|
109
|
+
},
|
|
110
|
+
}),
|
|
111
|
+
|
|
112
|
+
// Create nodes for debug sidebar.
|
|
113
|
+
createExtension({
|
|
114
|
+
id: `${DEBUG_PLUGIN}/debug-for-subject`,
|
|
115
|
+
resolver: ({ id }) => {
|
|
116
|
+
// TODO(Zan): Find util (or make one).
|
|
117
|
+
if (!id.endsWith('~debug')) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const type = 'orphan-settings-for-subject';
|
|
122
|
+
const icon = 'ph--bug--regular';
|
|
123
|
+
|
|
124
|
+
const client = context.requestCapability(ClientCapabilities.Client);
|
|
125
|
+
const [subjectId] = id.split('~');
|
|
126
|
+
const { spaceId, objectId } = parseId(subjectId);
|
|
127
|
+
const spaces = toSignal(
|
|
128
|
+
(onChange) => client.spaces.subscribe(() => onChange()).unsubscribe,
|
|
129
|
+
() => client.spaces.get(),
|
|
130
|
+
);
|
|
131
|
+
const space = spaces?.find((space) => space.state.get() === SpaceState.SPACE_READY && space.id === spaceId);
|
|
132
|
+
if (!objectId) {
|
|
133
|
+
// TODO(burdon): Ref SPACE_PLUGIN ns.
|
|
134
|
+
const label = space
|
|
135
|
+
? space.properties.name || ['unnamed space label', { ns: DEBUG_PLUGIN }]
|
|
136
|
+
: ['unnamed object settings label', { ns: DEBUG_PLUGIN }];
|
|
137
|
+
|
|
138
|
+
// TODO(wittjosiah): Support comments for arbitrary subjects.
|
|
139
|
+
// This is to ensure that the comments panel is not stuck on an old object.
|
|
140
|
+
return {
|
|
141
|
+
id,
|
|
142
|
+
type,
|
|
143
|
+
data: null,
|
|
144
|
+
properties: {
|
|
145
|
+
icon,
|
|
146
|
+
label,
|
|
147
|
+
showResolvedThreads: false,
|
|
148
|
+
object: null,
|
|
149
|
+
space,
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const [object] = memoizeQuery(space, { id: objectId });
|
|
155
|
+
if (!object || !subjectId) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const meta = resolve(getTypename(object) ?? '');
|
|
160
|
+
const label = meta.label?.(object) ||
|
|
161
|
+
object.name ||
|
|
162
|
+
meta.placeholder || ['unnamed object settings label', { ns: DEBUG_PLUGIN }];
|
|
163
|
+
|
|
164
|
+
return {
|
|
165
|
+
id,
|
|
166
|
+
type,
|
|
167
|
+
data: null,
|
|
168
|
+
properties: {
|
|
169
|
+
icon,
|
|
170
|
+
label,
|
|
171
|
+
object,
|
|
172
|
+
},
|
|
173
|
+
};
|
|
174
|
+
},
|
|
175
|
+
}),
|
|
176
|
+
]);
|
|
177
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { lazy } from '@dxos/app-framework';
|
|
6
|
+
|
|
7
|
+
export const AppGraphBuilder = lazy(() => import('./app-graph-builder'));
|
|
8
|
+
export const ReactContext = lazy(() => import('./react-context'));
|
|
9
|
+
export const ReactSurface = lazy(() => import('./react-surface'));
|
|
10
|
+
export const DebugSettings = lazy(() => import('./settings'));
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React, { useEffect, useState } from 'react';
|
|
6
|
+
|
|
7
|
+
import { Capabilities, contributes } from '@dxos/app-framework';
|
|
8
|
+
import { Timer } from '@dxos/async';
|
|
9
|
+
|
|
10
|
+
import { DEBUG_PLUGIN } from '../meta';
|
|
11
|
+
import { DebugContext } from '../types';
|
|
12
|
+
|
|
13
|
+
export default () =>
|
|
14
|
+
contributes(Capabilities.ReactContext, {
|
|
15
|
+
id: DEBUG_PLUGIN,
|
|
16
|
+
context: ({ children }) => {
|
|
17
|
+
const [timer, setTimer] = useState<Timer>();
|
|
18
|
+
useEffect(() => timer?.state.on((value) => !value && setTimer(undefined)), [timer]);
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
timer?.stop();
|
|
21
|
+
}, []);
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<DebugContext.Provider
|
|
25
|
+
value={{
|
|
26
|
+
running: !!timer,
|
|
27
|
+
start: (cb, options) => {
|
|
28
|
+
timer?.stop();
|
|
29
|
+
setTimer(new Timer(cb).start(options));
|
|
30
|
+
},
|
|
31
|
+
stop: () => timer?.stop(),
|
|
32
|
+
}}
|
|
33
|
+
>
|
|
34
|
+
{children}
|
|
35
|
+
</DebugContext.Provider>
|
|
36
|
+
);
|
|
37
|
+
},
|
|
38
|
+
});
|