@dxos/plugin-debug 0.7.4 → 0.7.5-labs.a279d8c

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 (80) hide show
  1. package/dist/lib/browser/{DebugApp-HCHR6GKO.mjs → DebugApp-LQHFFK3Y.mjs} +4 -2
  2. package/dist/lib/browser/{DebugApp-HCHR6GKO.mjs.map → DebugApp-LQHFFK3Y.mjs.map} +3 -3
  3. package/dist/lib/browser/{DebugSpace-DHKEAMIC.mjs → DebugSpace-4JHYA7FG.mjs} +7 -6
  4. package/dist/lib/browser/DebugSpace-4JHYA7FG.mjs.map +7 -0
  5. package/dist/lib/browser/{SpaceGenerator-BQ3645OS.mjs → SpaceGenerator-YNT3WDFI.mjs} +226 -20
  6. package/dist/lib/browser/SpaceGenerator-YNT3WDFI.mjs.map +7 -0
  7. package/dist/lib/browser/app-graph-builder-FXELWOFS.mjs +177 -0
  8. package/dist/lib/browser/app-graph-builder-FXELWOFS.mjs.map +7 -0
  9. package/dist/lib/browser/{chunk-CAENAAHY.mjs → chunk-I3ON45JK.mjs} +3 -3
  10. package/dist/lib/browser/chunk-I3ON45JK.mjs.map +7 -0
  11. package/dist/lib/browser/{chunk-LZEK532R.mjs → chunk-P7GHHMDB.mjs} +1 -11
  12. package/dist/lib/browser/chunk-P7GHHMDB.mjs.map +7 -0
  13. package/dist/lib/browser/index.mjs +66 -737
  14. package/dist/lib/browser/index.mjs.map +4 -4
  15. package/dist/lib/browser/meta.json +1 -1
  16. package/dist/lib/browser/react-context-OZU6J7G3.mjs +37 -0
  17. package/dist/lib/browser/react-context-OZU6J7G3.mjs.map +7 -0
  18. package/dist/lib/browser/react-surface-ACHNR2UU.mjs +481 -0
  19. package/dist/lib/browser/react-surface-ACHNR2UU.mjs.map +7 -0
  20. package/dist/lib/browser/settings-JCZUA643.mjs +25 -0
  21. package/dist/lib/browser/settings-JCZUA643.mjs.map +7 -0
  22. package/dist/types/src/DebugPlugin.d.ts +1 -2
  23. package/dist/types/src/DebugPlugin.d.ts.map +1 -1
  24. package/dist/types/src/capabilities/app-graph-builder.d.ts +181 -0
  25. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
  26. package/dist/types/src/capabilities/index.d.ts +185 -0
  27. package/dist/types/src/capabilities/index.d.ts.map +1 -0
  28. package/dist/types/src/capabilities/react-context.d.ts +8 -0
  29. package/dist/types/src/capabilities/react-context.d.ts.map +1 -0
  30. package/dist/types/src/capabilities/react-surface.d.ts +4 -0
  31. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
  32. package/dist/types/src/capabilities/settings.d.ts +4 -0
  33. package/dist/types/src/capabilities/settings.d.ts.map +1 -0
  34. package/dist/types/src/components/DebugObjectPanel.d.ts.map +1 -1
  35. package/dist/types/src/components/DebugSpace/DebugSpace.stories.d.ts.map +1 -1
  36. package/dist/types/src/components/DebugSpace/ObjectCreator.stories.d.ts.map +1 -1
  37. package/dist/types/src/components/DebugStatus.d.ts.map +1 -1
  38. package/dist/types/src/components/SpaceGenerator/ObjectGenerator.d.ts +2 -2
  39. package/dist/types/src/components/SpaceGenerator/ObjectGenerator.d.ts.map +1 -1
  40. package/dist/types/src/components/SpaceGenerator/SpaceGenerator.d.ts.map +1 -1
  41. package/dist/types/src/components/SpaceGenerator/draw-util.d.ts.map +1 -1
  42. package/dist/types/src/components/Wireframe.d.ts +2 -1
  43. package/dist/types/src/components/Wireframe.d.ts.map +1 -1
  44. package/dist/types/src/index.d.ts +1 -2
  45. package/dist/types/src/index.d.ts.map +1 -1
  46. package/dist/types/src/meta.d.ts +1 -2
  47. package/dist/types/src/meta.d.ts.map +1 -1
  48. package/dist/types/src/types.d.ts +0 -6
  49. package/dist/types/src/types.d.ts.map +1 -1
  50. package/dist/types/tsconfig.tsbuildinfo +1 -0
  51. package/package.json +48 -51
  52. package/src/DebugPlugin.tsx +60 -381
  53. package/src/capabilities/app-graph-builder.ts +177 -0
  54. package/src/capabilities/index.ts +10 -0
  55. package/src/capabilities/react-context.tsx +38 -0
  56. package/src/capabilities/react-surface.tsx +138 -0
  57. package/src/capabilities/settings.ts +18 -0
  58. package/src/components/DebugApp/DebugApp.tsx +1 -1
  59. package/src/components/DebugObjectPanel.tsx +17 -5
  60. package/src/components/DebugSettings.tsx +4 -4
  61. package/src/components/DebugSpace/DebugSpace.stories.tsx +4 -3
  62. package/src/components/DebugSpace/DebugSpace.tsx +1 -1
  63. package/src/components/DebugSpace/ObjectCreator.stories.tsx +4 -3
  64. package/src/components/DebugStatus.tsx +3 -9
  65. package/src/components/SpaceGenerator/ObjectGenerator.tsx +126 -18
  66. package/src/components/SpaceGenerator/SpaceGenerator.tsx +6 -4
  67. package/src/components/SpaceGenerator/draw-util.ts +7 -6
  68. package/src/components/Wireframe.tsx +2 -2
  69. package/src/index.ts +1 -4
  70. package/src/meta.ts +1 -1
  71. package/src/types.ts +0 -22
  72. package/dist/lib/browser/DebugSpace-DHKEAMIC.mjs.map +0 -7
  73. package/dist/lib/browser/SpaceGenerator-BQ3645OS.mjs.map +0 -7
  74. package/dist/lib/browser/chunk-CAENAAHY.mjs.map +0 -7
  75. package/dist/lib/browser/chunk-LZEK532R.mjs.map +0 -7
  76. package/dist/lib/browser/meta.mjs +0 -9
  77. package/dist/lib/browser/meta.mjs.map +0 -7
  78. package/dist/types/src/components/DebugSurface.d.ts +0 -9
  79. package/dist/types/src/components/DebugSurface.d.ts.map +0 -1
  80. package/src/components/DebugSurface.tsx +0 -55
@@ -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
+ });
@@ -0,0 +1,138 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import React, { useCallback } from 'react';
6
+
7
+ import {
8
+ Capabilities,
9
+ contributes,
10
+ createIntent,
11
+ createSurface,
12
+ useCapability,
13
+ type PluginsContext,
14
+ } from '@dxos/app-framework';
15
+ import { Devtools } from '@dxos/devtools';
16
+ import { Graph } from '@dxos/plugin-graph';
17
+ import { SpaceAction, CollectionType } from '@dxos/plugin-space/types';
18
+ import {
19
+ SpaceState,
20
+ isSpace,
21
+ isEchoObject,
22
+ type ReactiveEchoObject,
23
+ type ReactiveObject,
24
+ type Space,
25
+ } from '@dxos/react-client/echo';
26
+
27
+ import {
28
+ DebugApp,
29
+ DebugObjectPanel,
30
+ DebugSettings,
31
+ DebugSpace,
32
+ DebugStatus,
33
+ SpaceGenerator,
34
+ Wireframe,
35
+ } from '../components';
36
+ import { DEBUG_PLUGIN } from '../meta';
37
+ import { type DebugSettingsProps } from '../types';
38
+
39
+ type SpaceDebug = {
40
+ type: string;
41
+ space: Space;
42
+ };
43
+
44
+ type GraphDebug = {
45
+ graph: Graph;
46
+ };
47
+
48
+ const isSpaceDebug = (data: any): data is SpaceDebug => data.type === `${DEBUG_PLUGIN}/space` && isSpace(data.space);
49
+ const isGraphDebug = (data: any): data is GraphDebug => data.graph instanceof Graph;
50
+
51
+ export default (context: PluginsContext) =>
52
+ contributes(Capabilities.ReactSurface, [
53
+ createSurface({
54
+ id: `${DEBUG_PLUGIN}/settings`,
55
+ role: 'settings',
56
+ filter: (data): data is any => data.subject === DEBUG_PLUGIN,
57
+ component: () => {
58
+ const settings = useCapability(Capabilities.SettingsStore).getStore<DebugSettingsProps>(DEBUG_PLUGIN)!.value;
59
+ return <DebugSettings settings={settings} />;
60
+ },
61
+ }),
62
+ createSurface({
63
+ id: `${DEBUG_PLUGIN}/status`,
64
+ role: 'status',
65
+ component: () => <DebugStatus />,
66
+ }),
67
+ createSurface({
68
+ id: `${DEBUG_PLUGIN}/complementary`,
69
+ role: 'complementary--debug',
70
+ filter: (data): data is { subject: ReactiveEchoObject<any> } => isEchoObject(data.subject),
71
+ component: ({ data }) => <DebugObjectPanel object={data.subject} />,
72
+ }),
73
+ createSurface({
74
+ id: `${DEBUG_PLUGIN}/devtools`,
75
+ role: 'article',
76
+ filter: (data): data is any => {
77
+ const settings = context
78
+ .requestCapability(Capabilities.SettingsStore)
79
+ .getStore<DebugSettingsProps>(DEBUG_PLUGIN)!.value;
80
+ return data.subject === 'devtools' && !!settings.devtools;
81
+ },
82
+ component: () => <Devtools />,
83
+ }),
84
+ createSurface({
85
+ id: `${DEBUG_PLUGIN}/space`,
86
+ role: 'article',
87
+ filter: (data): data is { subject: SpaceDebug } => isSpaceDebug(data.subject),
88
+ component: ({ data }) => {
89
+ const handleCreateObject = useCallback(
90
+ (objects: ReactiveObject<any>[]) => {
91
+ if (!isSpace(data.subject.space)) {
92
+ return;
93
+ }
94
+
95
+ const collection =
96
+ data.subject.space.state.get() === SpaceState.SPACE_READY &&
97
+ data.subject.space.properties[CollectionType.typename]?.target;
98
+ if (!(collection instanceof CollectionType)) {
99
+ return;
100
+ }
101
+
102
+ const { dispatchPromise: dispatch } = context.requestCapability(Capabilities.IntentDispatcher);
103
+ objects.forEach((object) => {
104
+ void dispatch(createIntent(SpaceAction.AddObject, { target: collection, object }));
105
+ });
106
+ },
107
+ [data.subject.space],
108
+ );
109
+
110
+ const deprecated = false;
111
+ return deprecated ? (
112
+ <DebugSpace space={data.subject.space} onAddObjects={handleCreateObject} />
113
+ ) : (
114
+ <SpaceGenerator space={data.subject.space} onCreateObjects={handleCreateObject} />
115
+ );
116
+ },
117
+ }),
118
+ createSurface({
119
+ id: `${DEBUG_PLUGIN}/graph`,
120
+ role: 'article',
121
+ filter: (data): data is { subject: GraphDebug } => isGraphDebug(data.subject),
122
+ component: ({ data }) => <DebugApp graph={data.subject.graph} />,
123
+ }),
124
+ createSurface({
125
+ id: `${DEBUG_PLUGIN}/wireframe`,
126
+ role: ['article', 'section'],
127
+ disposition: 'hoist',
128
+ filter: (data): data is { subject: ReactiveEchoObject<any> } => {
129
+ const settings = context
130
+ .requestCapability(Capabilities.SettingsStore)
131
+ .getStore<DebugSettingsProps>(DEBUG_PLUGIN)!.value;
132
+ return isEchoObject(data.subject) && !!settings.wireframe;
133
+ },
134
+ component: ({ data, role }) => (
135
+ <Wireframe label={`${role}:${name}`} object={data.subject} classNames='row-span-2 overflow-hidden' />
136
+ ),
137
+ }),
138
+ ]);
@@ -0,0 +1,18 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { Capabilities, contributes } from '@dxos/app-framework';
6
+ import { create } from '@dxos/react-client/echo';
7
+
8
+ import { DEBUG_PLUGIN } from '../meta';
9
+ import { type DebugSettingsProps, DebugSettingsSchema } from '../types';
10
+
11
+ export default () => {
12
+ const settings = create<DebugSettingsProps>({
13
+ debug: true,
14
+ devtools: true,
15
+ });
16
+
17
+ return contributes(Capabilities.Settings, { schema: DebugSettingsSchema, prefix: DEBUG_PLUGIN, value: settings });
18
+ };
@@ -59,7 +59,7 @@ export const DebugApp: FC<{ graph: Graph }> = ({ graph }) => {
59
59
  </ToggleGroupItem>
60
60
  </ToggleGroup>
61
61
 
62
- <Toolbar.Expander />
62
+ <Toolbar.Separator variant='gap' />
63
63
  <Button onClick={(event) => handleResetClient(event.shiftKey)} title='Reset client'>
64
64
  <Warning className={mx(getSize(5), 'text-red-700')} />
65
65
  </Button>
@@ -5,6 +5,7 @@
5
5
  import React from 'react';
6
6
 
7
7
  import { type ReactiveEchoObject } from '@dxos/client/echo';
8
+ import { Clipboard, Input } from '@dxos/react-ui';
8
9
  import { SyntaxHighlighter } from '@dxos/react-ui-syntax-highlighter';
9
10
 
10
11
  export type DebugObjectPanelProps = {
@@ -13,11 +14,22 @@ export type DebugObjectPanelProps = {
13
14
 
14
15
  // TODO(burdon): Get schema and traverse references.
15
16
  export const DebugObjectPanel = ({ object }: DebugObjectPanelProps) => {
17
+ const dxn = `dxn:echo:@:${object.id}`;
16
18
  return (
17
- <div className='flex flex-col'>
18
- <SyntaxHighlighter classNames='flex text-xs' language='json'>
19
- {JSON.stringify(object, null, 2)}
20
- </SyntaxHighlighter>
21
- </div>
19
+ <Clipboard.Provider>
20
+ <div className='flex flex-col'>
21
+ <Input.Root>
22
+ <div role='none' className='flex flex-col gap-1'>
23
+ <div role='none' className='flex gap-1'>
24
+ <Input.TextInput disabled value={dxn} />
25
+ <Clipboard.IconButton value={dxn} />
26
+ </div>
27
+ </div>
28
+ </Input.Root>
29
+ <SyntaxHighlighter classNames='flex text-xs' language='json'>
30
+ {JSON.stringify(object, null, 2)}
31
+ </SyntaxHighlighter>
32
+ </div>
33
+ </Clipboard.Provider>
22
34
  );
23
35
  };
@@ -5,7 +5,7 @@
5
5
  import { Gift, DownloadSimple, FirstAidKit } from '@phosphor-icons/react';
6
6
  import React, { useEffect, useState } from 'react';
7
7
 
8
- import { parseFileManagerPlugin, useResolvePlugin } from '@dxos/app-framework';
8
+ import { Capabilities, useCapabilities } from '@dxos/app-framework';
9
9
  import { type ConfigProto, defs, SaveConfig, Storage } from '@dxos/config';
10
10
  import { log } from '@dxos/log';
11
11
  import { useClient } from '@dxos/react-client';
@@ -34,7 +34,7 @@ export const DebugSettings = ({ settings }: { settings: DebugSettingsProps }) =>
34
34
  const download = useFileDownload();
35
35
  // TODO(mykola): Get updates from other places that change Config.
36
36
  const [storageConfig, setStorageConfig] = useState<ConfigProto>({});
37
- const fileManagerPlugin = useResolvePlugin(parseFileManagerPlugin);
37
+ const [upload] = useCapabilities(Capabilities.FileUploader);
38
38
 
39
39
  useEffect(() => {
40
40
  void Storage().then((config) => setStorageConfig(config));
@@ -52,8 +52,8 @@ export const DebugSettings = ({ settings }: { settings: DebugSettingsProps }) =>
52
52
  const fileName = `composer-${new Date().toISOString().replace(/\W/g, '-')}.json`;
53
53
  download(file, fileName);
54
54
 
55
- if (fileManagerPlugin?.provides.file.upload) {
56
- const info = await fileManagerPlugin.provides.file.upload(new File([file], fileName), client.spaces.default);
55
+ if (upload) {
56
+ const info = await upload(new File([file], fileName), client.spaces.default);
57
57
  if (!info) {
58
58
  log.error('diagnostics failed to upload to IPFS');
59
59
  return;
@@ -5,21 +5,22 @@
5
5
  import '@dxos-theme';
6
6
 
7
7
  import { type Meta } from '@storybook/react';
8
- import React, { useEffect } from 'react';
8
+ import React from 'react';
9
9
 
10
10
  import { createSpaceObjectGenerator } from '@dxos/echo-generator';
11
11
  import { useSpaces } from '@dxos/react-client/echo';
12
12
  import { withClientProvider } from '@dxos/react-client/testing';
13
+ import { useAsyncEffect } from '@dxos/react-hooks';
13
14
  import { render, withLayout, withTheme } from '@dxos/storybook-utils';
14
15
 
15
16
  import { DebugSpace } from './DebugSpace';
16
17
 
17
18
  const DefaultStory = () => {
18
19
  const [space] = useSpaces();
19
- useEffect(() => {
20
+ useAsyncEffect(async () => {
20
21
  if (space) {
21
22
  const generator = createSpaceObjectGenerator(space);
22
- generator.addSchemas();
23
+ await generator.addSchemas();
23
24
  }
24
25
  }, [space]);
25
26
 
@@ -158,7 +158,7 @@ export const DebugSpace: FC<{
158
158
  <IconButton icon='ph--arrow-clockwise--regular' iconOnly label='Refresh' size={5} onClick={handleUpdate} />
159
159
  <IconButton icon='ph--download-simple--regular' iconOnly label='Download' size={5} onClick={handleDownload} />
160
160
 
161
- <Toolbar.Expander />
161
+ <Toolbar.Separator variant='gap' />
162
162
  <IconButton
163
163
  icon='ph--flag-pennant--regular'
164
164
  iconOnly
@@ -5,22 +5,23 @@
5
5
  import '@dxos-theme';
6
6
 
7
7
  import { type Meta } from '@storybook/react';
8
- import React, { useEffect } from 'react';
8
+ import React from 'react';
9
9
 
10
10
  import { createSpaceObjectGenerator } from '@dxos/echo-generator';
11
11
  import { log } from '@dxos/log';
12
12
  import { useSpaces } from '@dxos/react-client/echo';
13
13
  import { withClientProvider } from '@dxos/react-client/testing';
14
+ import { useAsyncEffect } from '@dxos/react-hooks';
14
15
  import { render, withLayout, withTheme } from '@dxos/storybook-utils';
15
16
 
16
17
  import { ObjectCreator, type ObjectCreatorProps } from './ObjectCreator';
17
18
 
18
19
  const DefaultStory = () => {
19
20
  const [space] = useSpaces();
20
- useEffect(() => {
21
+ useAsyncEffect(async () => {
21
22
  if (space) {
22
23
  const generator = createSpaceObjectGenerator(space);
23
- generator.addSchemas();
24
+ await generator.addSchemas();
24
25
  }
25
26
  }, [space]);
26
27
 
@@ -4,10 +4,9 @@
4
4
 
5
5
  import React, { useEffect, useRef, useState } from 'react';
6
6
 
7
- import { firstIdInPart, parseGraphPlugin, parseNavigationPlugin, useResolvePlugin } from '@dxos/app-framework';
7
+ import { Capabilities, firstIdInPart, useCapability } from '@dxos/app-framework';
8
8
  import { TimeoutError } from '@dxos/async';
9
9
  import { StatsPanel, useStats } from '@dxos/devtools';
10
- import { log } from '@dxos/log';
11
10
  import { getActiveSpace } from '@dxos/plugin-space';
12
11
  import { StatusBar } from '@dxos/plugin-status-bar';
13
12
  import { ConnectionState } from '@dxos/protocols/proto/dxos/client/services';
@@ -67,10 +66,7 @@ const ErrorIndicator = () => {
67
66
  useEffect(() => {
68
67
  const errorListener = (event: any) => {
69
68
  const error: Error = event.error ?? event.reason;
70
- // event.preventDefault();
71
69
  if (errorRef.current !== error) {
72
- // eslint-disable-next-line no-console
73
- log.error('onError', { event });
74
70
  errorRef.current = error;
75
71
  forceUpdate({});
76
72
  }
@@ -140,10 +136,8 @@ const SwarmIndicator = () => {
140
136
  // TODO(burdon): Merge with SaveStatus.
141
137
  const SavingIndicator = () => {
142
138
  const [state, _setState] = useState(0);
143
- const navigationPlugin = useResolvePlugin(parseNavigationPlugin);
144
- const graphPlugin = useResolvePlugin(parseGraphPlugin);
145
- const location = navigationPlugin?.provides.location;
146
- const graph = graphPlugin?.provides.graph;
139
+ const location = useCapability(Capabilities.Location);
140
+ const { graph } = useCapability(Capabilities.AppGraph);
147
141
  const _space = location && graph ? getActiveSpace(graph, firstIdInPart(location.active, 'main')) : undefined;
148
142
  // TODO(dmaretskyi): Fix this when we have save status for automerge.
149
143
  // useEffect(() => {