@dxos/plugin-debug 0.7.1 → 0.7.2-main.f1adc9f
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/{DebugGlobal-ZTCBF3XR.mjs → DebugApp-HCHR6GKO.mjs} +18 -16
- package/dist/lib/browser/DebugApp-HCHR6GKO.mjs.map +7 -0
- package/dist/lib/browser/DebugSpace-HK2GQYIB.mjs +276 -0
- package/dist/lib/browser/DebugSpace-HK2GQYIB.mjs.map +7 -0
- package/dist/lib/browser/SpaceGenerator-TIBUROQA.mjs +155 -0
- package/dist/lib/browser/SpaceGenerator-TIBUROQA.mjs.map +7 -0
- package/dist/lib/browser/chunk-GSJS3HEM.mjs +15 -0
- package/dist/lib/browser/chunk-GSJS3HEM.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +39 -41
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/DebugPlugin.d.ts.map +1 -1
- package/dist/types/src/components/Container.d.ts +5 -0
- package/dist/types/src/components/Container.d.ts.map +1 -0
- package/dist/types/src/components/{DebugGlobal.d.ts → DebugApp/DebugApp.d.ts} +2 -3
- package/dist/types/src/components/DebugApp/DebugApp.d.ts.map +1 -0
- package/dist/types/src/components/DebugApp/Tree.d.ts.map +1 -0
- package/dist/types/src/components/DebugApp/index.d.ts +3 -0
- package/dist/types/src/components/DebugApp/index.d.ts.map +1 -0
- package/dist/types/src/components/DebugObjectPanel.d.ts +2 -2
- package/dist/types/src/components/DebugObjectPanel.d.ts.map +1 -1
- package/dist/types/src/components/{DebugSpace.d.ts → DebugSpace/DebugSpace.d.ts} +1 -2
- package/dist/types/src/components/DebugSpace/DebugSpace.d.ts.map +1 -0
- package/dist/types/src/components/{DebugSpace.stories.d.ts → DebugSpace/DebugSpace.stories.d.ts} +1 -1
- package/dist/types/src/components/DebugSpace/DebugSpace.stories.d.ts.map +1 -0
- package/dist/types/src/components/{ObjectCreator.d.ts → DebugSpace/ObjectCreator.d.ts} +4 -6
- package/dist/types/src/components/DebugSpace/ObjectCreator.d.ts.map +1 -0
- package/dist/types/src/components/{ObjectCreator.stories.d.ts → DebugSpace/ObjectCreator.stories.d.ts} +1 -1
- package/dist/types/src/components/DebugSpace/ObjectCreator.stories.d.ts.map +1 -0
- package/dist/types/src/components/DebugSpace/index.d.ts +3 -0
- package/dist/types/src/components/DebugSpace/index.d.ts.map +1 -0
- package/dist/types/src/components/{SurfaceDebug.d.ts → DebugSurface.d.ts} +2 -2
- package/dist/types/src/components/{SurfaceDebug.d.ts.map → DebugSurface.d.ts.map} +1 -1
- package/dist/types/src/components/SpaceGenerator/SpaceGenerator.d.ts +9 -0
- package/dist/types/src/components/SpaceGenerator/SpaceGenerator.d.ts.map +1 -0
- package/dist/types/src/components/SpaceGenerator/SpaceGenerator.stories.d.ts +6 -0
- package/dist/types/src/components/SpaceGenerator/SpaceGenerator.stories.d.ts.map +1 -0
- package/dist/types/src/components/SpaceGenerator/index.d.ts +3 -0
- package/dist/types/src/components/SpaceGenerator/index.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +2 -1
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/package.json +41 -38
- package/src/DebugPlugin.tsx +61 -48
- package/src/components/Container.tsx +15 -0
- package/src/components/{DebugGlobal.tsx → DebugApp/DebugApp.tsx} +9 -11
- package/src/components/{Tree.tsx → DebugApp/Tree.tsx} +1 -1
- package/src/components/DebugApp/index.ts +7 -0
- package/src/components/DebugObjectPanel.tsx +4 -3
- package/src/components/{DebugSpace.stories.tsx → DebugSpace/DebugSpace.stories.tsx} +8 -6
- package/src/components/{DebugSpace.tsx → DebugSpace/DebugSpace.tsx} +70 -82
- package/src/components/{ObjectCreator.stories.tsx → DebugSpace/ObjectCreator.stories.tsx} +14 -11
- package/src/components/DebugSpace/ObjectCreator.tsx +100 -0
- package/src/components/DebugSpace/index.ts +7 -0
- package/src/components/{SurfaceDebug.tsx → DebugSurface.tsx} +1 -1
- package/src/components/SpaceGenerator/SpaceGenerator.stories.tsx +37 -0
- package/src/components/SpaceGenerator/SpaceGenerator.tsx +169 -0
- package/src/components/SpaceGenerator/index.ts +7 -0
- package/src/components/index.ts +2 -1
- package/dist/lib/browser/DebugGlobal-ZTCBF3XR.mjs.map +0 -7
- package/dist/lib/browser/DebugSpace-6TGT3H4I.mjs +0 -411
- package/dist/lib/browser/DebugSpace-6TGT3H4I.mjs.map +0 -7
- package/dist/lib/browser/chunk-H3BJHVRD.mjs +0 -24
- package/dist/lib/browser/chunk-H3BJHVRD.mjs.map +0 -7
- package/dist/types/src/components/DebugGlobal.d.ts.map +0 -1
- package/dist/types/src/components/DebugPanel.d.ts +0 -5
- package/dist/types/src/components/DebugPanel.d.ts.map +0 -1
- package/dist/types/src/components/DebugSpace.d.ts.map +0 -1
- package/dist/types/src/components/DebugSpace.stories.d.ts.map +0 -1
- package/dist/types/src/components/ObjectCreator.d.ts.map +0 -1
- package/dist/types/src/components/ObjectCreator.stories.d.ts.map +0 -1
- package/dist/types/src/components/Tree.d.ts.map +0 -1
- package/dist/types/src/scaffolding/generator.d.ts +0 -11
- package/dist/types/src/scaffolding/generator.d.ts.map +0 -1
- package/dist/types/src/scaffolding/index.d.ts +0 -2
- package/dist/types/src/scaffolding/index.d.ts.map +0 -1
- package/src/components/DebugPanel.tsx +0 -29
- package/src/components/ObjectCreator.tsx +0 -99
- package/src/scaffolding/generator.ts +0 -146
- package/src/scaffolding/index.ts +0 -5
- /package/dist/types/src/components/{Tree.d.ts → DebugApp/Tree.d.ts} +0 -0
package/src/DebugPlugin.tsx
CHANGED
|
@@ -17,10 +17,19 @@ import { Devtools } from '@dxos/devtools';
|
|
|
17
17
|
import { invariant } from '@dxos/invariant';
|
|
18
18
|
import { type ClientPluginProvides, parseClientPlugin } from '@dxos/plugin-client';
|
|
19
19
|
import { createExtension, Graph, type Node, toSignal } from '@dxos/plugin-graph';
|
|
20
|
-
import { SpaceAction } from '@dxos/plugin-space';
|
|
20
|
+
import { memoizeQuery, SpaceAction } from '@dxos/plugin-space';
|
|
21
21
|
import { CollectionType } from '@dxos/plugin-space/types';
|
|
22
22
|
import { type Client } from '@dxos/react-client';
|
|
23
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
create,
|
|
25
|
+
getTypename,
|
|
26
|
+
isEchoObject,
|
|
27
|
+
isSpace,
|
|
28
|
+
parseId,
|
|
29
|
+
type ReactiveObject,
|
|
30
|
+
type Space,
|
|
31
|
+
SpaceState,
|
|
32
|
+
} from '@dxos/react-client/echo';
|
|
24
33
|
import { Main } from '@dxos/react-ui';
|
|
25
34
|
import {
|
|
26
35
|
baseSurface,
|
|
@@ -29,7 +38,15 @@ import {
|
|
|
29
38
|
topbarBlockPaddingStart,
|
|
30
39
|
} from '@dxos/react-ui-theme';
|
|
31
40
|
|
|
32
|
-
import {
|
|
41
|
+
import {
|
|
42
|
+
DebugApp,
|
|
43
|
+
DebugObjectPanel,
|
|
44
|
+
DebugSettings,
|
|
45
|
+
DebugSpace,
|
|
46
|
+
DebugStatus,
|
|
47
|
+
SpaceGenerator,
|
|
48
|
+
Wireframe,
|
|
49
|
+
} from './components';
|
|
33
50
|
import meta, { DEBUG_PLUGIN } from './meta';
|
|
34
51
|
import translations from './translations';
|
|
35
52
|
import {
|
|
@@ -157,7 +174,7 @@ export const DebugPlugin = definePlugin<DebugPluginProvides>((context) => {
|
|
|
157
174
|
{
|
|
158
175
|
id: `${space.id}-debug`, // TODO(burdon): Change to slashes consistently.
|
|
159
176
|
type: 'dxos.org/plugin/debug/space',
|
|
160
|
-
data: { space },
|
|
177
|
+
data: { space, type: 'dxos.org/plugin/debug/space' },
|
|
161
178
|
properties: {
|
|
162
179
|
label: ['debug label', { ns: DEBUG_PLUGIN }],
|
|
163
180
|
icon: 'ph--bug--regular',
|
|
@@ -181,7 +198,13 @@ export const DebugPlugin = definePlugin<DebugPluginProvides>((context) => {
|
|
|
181
198
|
|
|
182
199
|
const [subjectId] = id.split('~');
|
|
183
200
|
const { spaceId, objectId } = parseId(subjectId);
|
|
184
|
-
const
|
|
201
|
+
const spaces = toSignal(
|
|
202
|
+
(onChange) => client.spaces.subscribe(() => onChange()).unsubscribe,
|
|
203
|
+
() => client.spaces.get(),
|
|
204
|
+
);
|
|
205
|
+
const space = spaces?.find(
|
|
206
|
+
(space) => space.state.get() === SpaceState.SPACE_READY && space.id === spaceId,
|
|
207
|
+
);
|
|
185
208
|
if (!objectId) {
|
|
186
209
|
// TODO(burdon): Ref SPACE_PLUGIN ns.
|
|
187
210
|
const label = space
|
|
@@ -204,18 +227,7 @@ export const DebugPlugin = definePlugin<DebugPluginProvides>((context) => {
|
|
|
204
227
|
};
|
|
205
228
|
}
|
|
206
229
|
|
|
207
|
-
const object =
|
|
208
|
-
(onChange) => {
|
|
209
|
-
const timeout = setTimeout(async () => {
|
|
210
|
-
await space?.db.loadObjectById(objectId);
|
|
211
|
-
onChange();
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
return () => clearTimeout(timeout);
|
|
215
|
-
},
|
|
216
|
-
() => space?.db.getObjectById(objectId),
|
|
217
|
-
subjectId,
|
|
218
|
-
);
|
|
230
|
+
const [object] = memoizeQuery(space, { id: objectId });
|
|
219
231
|
if (!object || !subjectId) {
|
|
220
232
|
return;
|
|
221
233
|
}
|
|
@@ -277,41 +289,46 @@ export const DebugPlugin = definePlugin<DebugPluginProvides>((context) => {
|
|
|
277
289
|
}
|
|
278
290
|
|
|
279
291
|
const primary = data.active ?? data.object;
|
|
280
|
-
let component: ReactNode;
|
|
292
|
+
let component: ReactNode = null;
|
|
281
293
|
if (role === 'main' || role === 'article') {
|
|
282
294
|
if (primary === 'devtools' && settings.devtools) {
|
|
283
295
|
component = <Devtools />;
|
|
284
296
|
} else if (!primary || typeof primary !== 'object' || !settings.debug) {
|
|
285
297
|
component = null;
|
|
286
|
-
} else if (
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
298
|
+
} else if (
|
|
299
|
+
'type' in primary &&
|
|
300
|
+
primary.type === 'dxos.org/plugin/debug/space' &&
|
|
301
|
+
'space' in primary &&
|
|
302
|
+
isSpace(primary.space)
|
|
303
|
+
) {
|
|
304
|
+
const handleAddObject = (objects: ReactiveObject<any>[]) => {
|
|
305
|
+
if (!isSpace(primary.space)) {
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
294
308
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
309
|
+
const collection =
|
|
310
|
+
primary.space.state.get() === SpaceState.SPACE_READY &&
|
|
311
|
+
primary.space.properties[CollectionType.typename];
|
|
312
|
+
if (!(collection instanceof CollectionType)) {
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
void context.resolvePlugin(parseIntentPlugin).provides.intent.dispatch(
|
|
317
|
+
objects.map((object) => ({
|
|
318
|
+
action: SpaceAction.ADD_OBJECT,
|
|
319
|
+
data: { target: collection, object },
|
|
320
|
+
})),
|
|
321
|
+
);
|
|
322
|
+
};
|
|
301
323
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
);
|
|
308
|
-
}}
|
|
309
|
-
/>
|
|
324
|
+
const deprecated = false;
|
|
325
|
+
component = deprecated ? (
|
|
326
|
+
<DebugSpace space={primary.space} onAddObjects={handleAddObject} />
|
|
327
|
+
) : (
|
|
328
|
+
<SpaceGenerator space={primary.space} onAddObjects={handleAddObject} />
|
|
310
329
|
);
|
|
311
330
|
} else if ('graph' in primary && primary.graph instanceof Graph) {
|
|
312
|
-
component = <
|
|
313
|
-
} else {
|
|
314
|
-
component = null;
|
|
331
|
+
component = <DebugApp graph={primary.graph} />;
|
|
315
332
|
}
|
|
316
333
|
}
|
|
317
334
|
|
|
@@ -337,11 +354,7 @@ export const DebugPlugin = definePlugin<DebugPluginProvides>((context) => {
|
|
|
337
354
|
|
|
338
355
|
switch (role) {
|
|
339
356
|
case 'article':
|
|
340
|
-
return
|
|
341
|
-
<div role='none' className='row-span-2 rounded-t-md overflow-x-auto'>
|
|
342
|
-
{component}
|
|
343
|
-
</div>
|
|
344
|
-
);
|
|
357
|
+
return <>{component}</>;
|
|
345
358
|
case 'main':
|
|
346
359
|
return (
|
|
347
360
|
<Main.Content
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React, { type PropsWithChildren, type ReactNode } from 'react';
|
|
6
|
+
|
|
7
|
+
// TODO(burdon): Convert to grid.
|
|
8
|
+
export const Container = ({ toolbar, children }: PropsWithChildren<{ toolbar: ReactNode }>) => {
|
|
9
|
+
return (
|
|
10
|
+
<div role='none' className='flex flex-col grow overflow-hidden divide-y divide-separator'>
|
|
11
|
+
{toolbar}
|
|
12
|
+
<div className='flex flex-col grow overflow-auto'>{children}</div>
|
|
13
|
+
</div>
|
|
14
|
+
);
|
|
15
|
+
};
|
|
@@ -7,13 +7,13 @@ import React, { type FC, useEffect, useState } from 'react';
|
|
|
7
7
|
|
|
8
8
|
import { type Graph } from '@dxos/plugin-graph';
|
|
9
9
|
import { useClient, useConfig } from '@dxos/react-client';
|
|
10
|
-
import { Button, ToggleGroup, ToggleGroupItem } from '@dxos/react-ui';
|
|
10
|
+
import { Button, ToggleGroup, ToggleGroupItem, Toolbar } from '@dxos/react-ui';
|
|
11
11
|
import { getSize, mx } from '@dxos/react-ui-theme';
|
|
12
12
|
|
|
13
|
-
import { DebugPanel } from './DebugPanel';
|
|
14
13
|
import { Json, Tree } from './Tree';
|
|
14
|
+
import { Container } from '../Container';
|
|
15
15
|
|
|
16
|
-
const
|
|
16
|
+
export const DebugApp: FC<{ graph: Graph }> = ({ graph }) => {
|
|
17
17
|
const [view, setView] = useState<'config' | 'diagnostics' | 'graph'>('graph');
|
|
18
18
|
const [data, setData] = useState<any>({});
|
|
19
19
|
const client = useClient();
|
|
@@ -44,9 +44,9 @@ const DebugGlobal: FC<{ graph: Graph }> = ({ graph }) => {
|
|
|
44
44
|
};
|
|
45
45
|
|
|
46
46
|
return (
|
|
47
|
-
<
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
<Container
|
|
48
|
+
toolbar={
|
|
49
|
+
<Toolbar.Root classNames='p-1'>
|
|
50
50
|
<ToggleGroup type='single' value={view}>
|
|
51
51
|
<ToggleGroupItem value={'graph'} onClick={() => setView('graph')} title={'Plugin graph'}>
|
|
52
52
|
<GraphIcon className={getSize(5)} />
|
|
@@ -59,21 +59,19 @@ const DebugGlobal: FC<{ graph: Graph }> = ({ graph }) => {
|
|
|
59
59
|
</ToggleGroupItem>
|
|
60
60
|
</ToggleGroup>
|
|
61
61
|
|
|
62
|
-
<
|
|
62
|
+
<Toolbar.Expander />
|
|
63
63
|
<Button onClick={(event) => handleResetClient(event.shiftKey)} title='Reset client'>
|
|
64
64
|
<Warning className={mx(getSize(5), 'text-red-700')} />
|
|
65
65
|
</Button>
|
|
66
66
|
<Button onClick={handleOpenDevtools} title='Open Devtools'>
|
|
67
67
|
<Toolbox weight='duotone' className={mx(getSize(5), 'text-700')} />
|
|
68
68
|
</Button>
|
|
69
|
-
|
|
69
|
+
</Toolbar.Root>
|
|
70
70
|
}
|
|
71
71
|
>
|
|
72
72
|
{view === 'graph' && <Tree data={graph.toJSON()} />}
|
|
73
73
|
{view === 'config' && <Json data={data.diagnostics?.config} />}
|
|
74
74
|
{view === 'diagnostics' && <Json data={data} />}
|
|
75
|
-
</
|
|
75
|
+
</Container>
|
|
76
76
|
);
|
|
77
77
|
};
|
|
78
|
-
|
|
79
|
-
export default DebugGlobal;
|
|
@@ -34,7 +34,7 @@ export const Json: FC<{ data?: object }> = ({ data }) => {
|
|
|
34
34
|
|
|
35
35
|
export const Tree: FC<{ data?: object }> = ({ data }) => {
|
|
36
36
|
return (
|
|
37
|
-
<div className='
|
|
37
|
+
<div className='p-2'>
|
|
38
38
|
<Node data={data} root />
|
|
39
39
|
</div>
|
|
40
40
|
);
|
|
@@ -4,16 +4,17 @@
|
|
|
4
4
|
|
|
5
5
|
import React from 'react';
|
|
6
6
|
|
|
7
|
-
import { type
|
|
7
|
+
import { type ReactiveEchoObject } from '@dxos/client/echo';
|
|
8
8
|
import { SyntaxHighlighter } from '@dxos/react-ui-syntax-highlighter';
|
|
9
9
|
|
|
10
10
|
export type DebugObjectPanelProps = {
|
|
11
|
-
object:
|
|
11
|
+
object: ReactiveEchoObject<any>;
|
|
12
12
|
};
|
|
13
13
|
|
|
14
|
+
// TODO(burdon): Get schema and traverse references.
|
|
14
15
|
export const DebugObjectPanel = ({ object }: DebugObjectPanelProps) => {
|
|
15
16
|
return (
|
|
16
|
-
<div
|
|
17
|
+
<div className='flex flex-col'>
|
|
17
18
|
<SyntaxHighlighter classNames='flex text-xs' language='json'>
|
|
18
19
|
{JSON.stringify(object, null, 2)}
|
|
19
20
|
</SyntaxHighlighter>
|
|
@@ -9,11 +9,12 @@ import React, { useEffect } from 'react';
|
|
|
9
9
|
|
|
10
10
|
import { createSpaceObjectGenerator } from '@dxos/echo-generator';
|
|
11
11
|
import { useSpaces } from '@dxos/react-client/echo';
|
|
12
|
-
import {
|
|
12
|
+
import { withClientProvider } from '@dxos/react-client/testing';
|
|
13
|
+
import { render, withLayout, withTheme } from '@dxos/storybook-utils';
|
|
13
14
|
|
|
14
|
-
import DebugSpace from './DebugSpace';
|
|
15
|
+
import { DebugSpace } from './DebugSpace';
|
|
15
16
|
|
|
16
|
-
const
|
|
17
|
+
const DefaultStory = () => {
|
|
17
18
|
const [space] = useSpaces();
|
|
18
19
|
useEffect(() => {
|
|
19
20
|
if (space) {
|
|
@@ -29,15 +30,16 @@ const Story = () => {
|
|
|
29
30
|
return <DebugSpace space={space} />;
|
|
30
31
|
};
|
|
31
32
|
|
|
32
|
-
export const Default = {};
|
|
33
|
-
|
|
34
33
|
const meta: Meta = {
|
|
35
34
|
title: 'plugins/plugin-debug/DebugSpace',
|
|
36
35
|
component: DebugSpace,
|
|
37
|
-
render: ()
|
|
36
|
+
render: render(DefaultStory),
|
|
37
|
+
decorators: [withClientProvider({ createSpace: true }), withLayout({ tooltips: true }), withTheme],
|
|
38
38
|
parameters: {
|
|
39
39
|
layout: 'fullscreen',
|
|
40
40
|
},
|
|
41
41
|
};
|
|
42
42
|
|
|
43
43
|
export default meta;
|
|
44
|
+
|
|
45
|
+
export const Default = {};
|
|
@@ -2,19 +2,9 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
ArrowClockwise,
|
|
7
|
-
DownloadSimple,
|
|
8
|
-
Flag,
|
|
9
|
-
FlagPennant,
|
|
10
|
-
HandPalm,
|
|
11
|
-
Play,
|
|
12
|
-
PlusMinus,
|
|
13
|
-
Timer,
|
|
14
|
-
UserCirclePlus,
|
|
15
|
-
} from '@phosphor-icons/react';
|
|
16
5
|
import React, { type FC, useContext, useMemo, useState } from 'react';
|
|
17
6
|
|
|
7
|
+
import { createSpaceObjectGenerator } from '@dxos/echo-generator';
|
|
18
8
|
import { type ReactiveObject } from '@dxos/echo-schema';
|
|
19
9
|
import { DocumentType } from '@dxos/plugin-markdown/types';
|
|
20
10
|
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
@@ -23,26 +13,34 @@ import { useClient } from '@dxos/react-client';
|
|
|
23
13
|
import { Filter, type Space, useSpaceInvitation } from '@dxos/react-client/echo';
|
|
24
14
|
import { InvitationEncoder } from '@dxos/react-client/invitations';
|
|
25
15
|
import { useAsyncEffect } from '@dxos/react-hooks';
|
|
26
|
-
import {
|
|
27
|
-
import { getSize, mx } from '@dxos/react-ui-theme';
|
|
16
|
+
import { Icon, IconButton, Input, type IconProps, type TextInputProps, Toolbar, useFileDownload } from '@dxos/react-ui';
|
|
28
17
|
import { safeParseInt } from '@dxos/util';
|
|
29
18
|
|
|
30
|
-
import { DebugPanel } from './DebugPanel';
|
|
31
19
|
import { ObjectCreator } from './ObjectCreator';
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
20
|
+
import { DebugContext } from '../../types';
|
|
21
|
+
import { Container } from '../Container';
|
|
34
22
|
|
|
35
23
|
const DEFAULT_COUNT = 100;
|
|
36
24
|
const DEFAULT_PERIOD = 500;
|
|
37
25
|
const DEFAULT_JITTER = 50;
|
|
38
26
|
|
|
39
|
-
// TODO(burdon): Factor out.
|
|
40
27
|
const useRefresh = (): [any, () => void] => {
|
|
41
28
|
const [update, setUpdate] = useState({});
|
|
42
29
|
return [update, () => setUpdate({})];
|
|
43
30
|
};
|
|
44
31
|
|
|
45
|
-
const
|
|
32
|
+
const CustomInput = ({ icon, ...props }: Pick<IconProps, 'icon'> & TextInputProps) => {
|
|
33
|
+
return (
|
|
34
|
+
<div role='none' className='relative'>
|
|
35
|
+
<Input.Root>
|
|
36
|
+
<Input.TextInput classNames='w-[100px] text-right pie-[22px]' size={5} {...props} />
|
|
37
|
+
</Input.Root>
|
|
38
|
+
<Icon icon={icon} size={3} classNames='absolute inline-end-1 block-start-1 mt-[6px]' />
|
|
39
|
+
</div>
|
|
40
|
+
);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const DebugSpace: FC<{
|
|
46
44
|
space: Space;
|
|
47
45
|
onAddObjects?: (objects: ReactiveObject<any>[]) => void;
|
|
48
46
|
}> = ({ space, onAddObjects }) => {
|
|
@@ -66,7 +64,7 @@ const DebugSpace: FC<{
|
|
|
66
64
|
);
|
|
67
65
|
|
|
68
66
|
const download = useFileDownload();
|
|
69
|
-
const
|
|
67
|
+
const handleDownload = async () => {
|
|
70
68
|
download(
|
|
71
69
|
new Blob([JSON.stringify(data, undefined, 2)], { type: 'text/plain' }),
|
|
72
70
|
`${new Date().toISOString().replace(/\W/g, '-')}.json`,
|
|
@@ -125,71 +123,61 @@ const DebugSpace: FC<{
|
|
|
125
123
|
};
|
|
126
124
|
|
|
127
125
|
return (
|
|
128
|
-
<
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
<
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
<div className='grow' />
|
|
181
|
-
<Button onClick={handleCreateEpoch} title='Create epoch'>
|
|
182
|
-
<FlagPennant className={mx(getSize(5))} />
|
|
183
|
-
</Button>
|
|
184
|
-
<Button onClick={handleCreateInvitation} title='Create Space invitation'>
|
|
185
|
-
<UserCirclePlus className={mx(getSize(5), 'text-blue-500')} />
|
|
186
|
-
</Button>
|
|
187
|
-
</>
|
|
126
|
+
<Container
|
|
127
|
+
toolbar={
|
|
128
|
+
<Toolbar.Root classNames='p-1'>
|
|
129
|
+
<CustomInput
|
|
130
|
+
icon='ph--flag--regular'
|
|
131
|
+
autoComplete='off'
|
|
132
|
+
placeholder='Count'
|
|
133
|
+
value={mutationCount}
|
|
134
|
+
onChange={({ target: { value } }) => setMutationCount(value)}
|
|
135
|
+
/>
|
|
136
|
+
<CustomInput
|
|
137
|
+
icon='ph--timer--regular'
|
|
138
|
+
autoComplete='off'
|
|
139
|
+
placeholder='Interval'
|
|
140
|
+
value={mutationInterval}
|
|
141
|
+
onChange={({ target: { value } }) => setMutationInterval(value)}
|
|
142
|
+
/>
|
|
143
|
+
<CustomInput
|
|
144
|
+
icon='ph--plus-minus--regular'
|
|
145
|
+
autoComplete='off'
|
|
146
|
+
placeholder='Jitter'
|
|
147
|
+
value={mutationJitter}
|
|
148
|
+
onChange={({ target: { value } }) => setMutationJitter(value)}
|
|
149
|
+
/>
|
|
150
|
+
|
|
151
|
+
<IconButton
|
|
152
|
+
icon={running ? 'ph--pause-circle--regular' : 'ph--play-circle--regular'}
|
|
153
|
+
iconOnly
|
|
154
|
+
label='Start/stop'
|
|
155
|
+
size={5}
|
|
156
|
+
onClick={handleToggleRunning}
|
|
157
|
+
/>
|
|
158
|
+
<IconButton icon='ph--arrow-clockwise--regular' iconOnly label='Refresh' size={5} onClick={handleUpdate} />
|
|
159
|
+
<IconButton icon='ph--download-simple--regular' iconOnly label='Download' size={5} onClick={handleDownload} />
|
|
160
|
+
|
|
161
|
+
<Toolbar.Expander />
|
|
162
|
+
<IconButton
|
|
163
|
+
icon='ph--flag-pennant--regular'
|
|
164
|
+
iconOnly
|
|
165
|
+
label='Create epoch'
|
|
166
|
+
size={5}
|
|
167
|
+
onClick={handleCreateEpoch}
|
|
168
|
+
/>
|
|
169
|
+
<IconButton
|
|
170
|
+
icon='ph--user-circle-plus--regular'
|
|
171
|
+
iconOnly
|
|
172
|
+
iconClassNames='text-blue-500'
|
|
173
|
+
label='Create Invitation'
|
|
174
|
+
size={5}
|
|
175
|
+
onClick={handleCreateInvitation}
|
|
176
|
+
/>
|
|
177
|
+
</Toolbar.Root>
|
|
188
178
|
}
|
|
189
179
|
>
|
|
190
180
|
<ObjectCreator space={space} onAddObjects={onAddObjects} />
|
|
191
|
-
</
|
|
181
|
+
</Container>
|
|
192
182
|
);
|
|
193
183
|
};
|
|
194
|
-
|
|
195
|
-
export default DebugSpace;
|
|
@@ -8,12 +8,14 @@ import { type Meta } from '@storybook/react';
|
|
|
8
8
|
import React, { useEffect } from 'react';
|
|
9
9
|
|
|
10
10
|
import { createSpaceObjectGenerator } from '@dxos/echo-generator';
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
11
|
+
import { log } from '@dxos/log';
|
|
12
|
+
import { useSpaces } from '@dxos/react-client/echo';
|
|
13
|
+
import { withClientProvider } from '@dxos/react-client/testing';
|
|
14
|
+
import { render, withLayout, withTheme } from '@dxos/storybook-utils';
|
|
13
15
|
|
|
14
16
|
import { ObjectCreator, type ObjectCreatorProps } from './ObjectCreator';
|
|
15
17
|
|
|
16
|
-
const
|
|
18
|
+
const DefaultStory = () => {
|
|
17
19
|
const [space] = useSpaces();
|
|
18
20
|
useEffect(() => {
|
|
19
21
|
if (space) {
|
|
@@ -22,26 +24,27 @@ const Story = () => {
|
|
|
22
24
|
}
|
|
23
25
|
}, [space]);
|
|
24
26
|
|
|
27
|
+
const handleCreate: ObjectCreatorProps['onAddObjects'] = (objects) => {
|
|
28
|
+
log.info('created', { objects });
|
|
29
|
+
};
|
|
30
|
+
|
|
25
31
|
if (!space) {
|
|
26
32
|
return null;
|
|
27
33
|
}
|
|
28
34
|
|
|
29
|
-
const handleCreate: ObjectCreatorProps['onAddObjects'] = (objects: ReactiveObject<any>[]) => {
|
|
30
|
-
console.log('Created:', objects);
|
|
31
|
-
};
|
|
32
|
-
|
|
33
35
|
return <ObjectCreator space={space} onAddObjects={handleCreate} />;
|
|
34
36
|
};
|
|
35
37
|
|
|
36
|
-
export const Default = {};
|
|
37
|
-
|
|
38
38
|
const meta: Meta = {
|
|
39
|
-
title: 'plugins/plugin-debug/
|
|
39
|
+
title: 'plugins/plugin-debug/ObjectCreator',
|
|
40
40
|
component: ObjectCreator,
|
|
41
|
-
render: ()
|
|
41
|
+
render: render(DefaultStory),
|
|
42
|
+
decorators: [withClientProvider({ createSpace: true }), withLayout({ tooltips: true }), withTheme],
|
|
42
43
|
parameters: {
|
|
43
44
|
layout: 'fullscreen',
|
|
44
45
|
},
|
|
45
46
|
};
|
|
46
47
|
|
|
47
48
|
export default meta;
|
|
49
|
+
|
|
50
|
+
export const Default = {};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React, { useMemo, useState } from 'react';
|
|
6
|
+
|
|
7
|
+
import { type MutationsProviderParams, TestSchemaType, createSpaceObjectGenerator } from '@dxos/echo-generator';
|
|
8
|
+
import { type ReactiveEchoObject, type ReactiveObject, type Space } from '@dxos/react-client/echo';
|
|
9
|
+
import { IconButton, Toolbar } from '@dxos/react-ui';
|
|
10
|
+
import { createColumnBuilder, type TableColumnDef, Table } from '@dxos/react-ui-table/deprecated';
|
|
11
|
+
|
|
12
|
+
const BATCH_SIZE = 10;
|
|
13
|
+
|
|
14
|
+
export type CreateObjectsParams = {
|
|
15
|
+
schema: string;
|
|
16
|
+
enabled: boolean;
|
|
17
|
+
objects: number;
|
|
18
|
+
mutations: Pick<MutationsProviderParams, 'count' | 'mutationSize' | 'maxContentLength'>;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export type ObjectCreatorProps = {
|
|
22
|
+
space: Space;
|
|
23
|
+
onAddObjects?: (objects: ReactiveObject<any>[]) => void;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const ObjectCreator = ({ space, onAddObjects }: ObjectCreatorProps) => {
|
|
27
|
+
const generator = useMemo(() => createSpaceObjectGenerator(space), [space]);
|
|
28
|
+
|
|
29
|
+
const [objects, setObjects] = useState<CreateObjectsParams[]>(
|
|
30
|
+
Object.values(TestSchemaType).map((schema) => ({
|
|
31
|
+
schema,
|
|
32
|
+
enabled: true,
|
|
33
|
+
objects: 10,
|
|
34
|
+
mutations: {
|
|
35
|
+
count: 10,
|
|
36
|
+
mutationSize: 10,
|
|
37
|
+
maxContentLength: 1000,
|
|
38
|
+
},
|
|
39
|
+
})),
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
const handleCreate = async () => {
|
|
43
|
+
for (const params of objects) {
|
|
44
|
+
if (!params.enabled) {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
let objectsCreated = 0;
|
|
49
|
+
while (objectsCreated < params.objects) {
|
|
50
|
+
const objects = (await generator.createObjects({
|
|
51
|
+
[params.schema]: Math.min(BATCH_SIZE, params.objects - objectsCreated),
|
|
52
|
+
})) as ReactiveEchoObject<any>[];
|
|
53
|
+
|
|
54
|
+
await generator.mutateObjects(objects, params.mutations);
|
|
55
|
+
objectsCreated += objects.length;
|
|
56
|
+
onAddObjects?.(objects);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
await space.db.flush();
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const handleUpdate = (row: CreateObjectsParams, key: string, value: any) => {
|
|
64
|
+
const newObjects = [...objects];
|
|
65
|
+
Object.assign(newObjects.find((object) => object.schema === row.schema)!, { [key]: value });
|
|
66
|
+
setObjects(newObjects);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const { helper, builder } = createColumnBuilder<CreateObjectsParams>();
|
|
70
|
+
const columns: TableColumnDef<CreateObjectsParams>[] = [
|
|
71
|
+
helper.accessor('enabled', builder.switch({ label: 'Live', onUpdate: handleUpdate })),
|
|
72
|
+
helper.accessor('schema', builder.string({ label: 'Schema', classNames: 'font-mono' })),
|
|
73
|
+
helper.accessor('objects', builder.number({ label: 'Objects', onUpdate: handleUpdate })),
|
|
74
|
+
helper.accessor((obj) => obj.mutations.count, {
|
|
75
|
+
id: 'mutations',
|
|
76
|
+
...builder.number({ label: 'Mutations', onUpdate: handleUpdate }),
|
|
77
|
+
}),
|
|
78
|
+
helper.accessor((obj) => obj.mutations.mutationSize, {
|
|
79
|
+
id: 'mutationSize',
|
|
80
|
+
...builder.number({ label: 'Mut. Size', onUpdate: handleUpdate }),
|
|
81
|
+
}),
|
|
82
|
+
helper.accessor((obj) => obj.mutations.maxContentLength, {
|
|
83
|
+
id: 'mutationMaxContentLength',
|
|
84
|
+
...builder.number({ label: 'Length', onUpdate: handleUpdate }),
|
|
85
|
+
}),
|
|
86
|
+
];
|
|
87
|
+
|
|
88
|
+
return (
|
|
89
|
+
<>
|
|
90
|
+
<Table.Root>
|
|
91
|
+
<Table.Viewport>
|
|
92
|
+
<Table.Main<CreateObjectsParams> columns={columns} data={objects} />
|
|
93
|
+
</Table.Viewport>
|
|
94
|
+
</Table.Root>
|
|
95
|
+
<Toolbar.Root classNames='p-1'>
|
|
96
|
+
<IconButton icon='ph--plus--regular' label='Create' onClick={handleCreate} />
|
|
97
|
+
</Toolbar.Root>
|
|
98
|
+
</>
|
|
99
|
+
);
|
|
100
|
+
};
|