@dxos/plugin-debug 0.7.5-labs.e27f9b9 → 0.7.5-labs.f400bbc

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 (76) hide show
  1. package/dist/lib/browser/{DebugSpace-4JHYA7FG.mjs → DebugSpace-BTMTVZ6C.mjs} +2 -2
  2. package/dist/lib/browser/{SpaceGenerator-4VO7E5P2.mjs → SpaceGenerator-BPZGOSH4.mjs} +409 -17
  3. package/dist/lib/browser/SpaceGenerator-BPZGOSH4.mjs.map +7 -0
  4. package/dist/lib/browser/app-graph-builder-BZFZ6UG6.mjs +533 -0
  5. package/dist/lib/browser/app-graph-builder-BZFZ6UG6.mjs.map +7 -0
  6. package/dist/lib/browser/chunk-EF3UVAVI.mjs +21 -0
  7. package/dist/lib/browser/chunk-EF3UVAVI.mjs.map +7 -0
  8. package/dist/lib/browser/chunk-UASI2CRI.mjs +72 -0
  9. package/dist/lib/browser/chunk-UASI2CRI.mjs.map +7 -0
  10. package/dist/lib/browser/index.mjs +45 -9
  11. package/dist/lib/browser/index.mjs.map +3 -3
  12. package/dist/lib/browser/meta.json +1 -1
  13. package/dist/lib/browser/react-context-TCD3MNIT.mjs +16 -0
  14. package/dist/lib/browser/react-context-TCD3MNIT.mjs.map +7 -0
  15. package/dist/lib/browser/{react-surface-XDHEQY27.mjs → react-surface-W6QLG4YJ.mjs} +194 -37
  16. package/dist/lib/browser/react-surface-W6QLG4YJ.mjs.map +7 -0
  17. package/dist/lib/browser/{settings-JCZUA643.mjs → settings-INPXR64L.mjs} +6 -7
  18. package/dist/lib/browser/{settings-JCZUA643.mjs.map → settings-INPXR64L.mjs.map} +3 -3
  19. package/dist/types/src/DebugPlugin.d.ts.map +1 -1
  20. package/dist/types/src/capabilities/app-graph-builder.d.ts +110 -110
  21. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
  22. package/dist/types/src/capabilities/index.d.ts +115 -110
  23. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  24. package/dist/types/src/capabilities/react-context.d.ts +8 -0
  25. package/dist/types/src/capabilities/react-context.d.ts.map +1 -0
  26. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  27. package/dist/types/src/capabilities/settings.d.ts.map +1 -1
  28. package/dist/types/src/components/Container.d.ts +2 -2
  29. package/dist/types/src/components/Container.d.ts.map +1 -1
  30. package/dist/types/src/components/DebugObjectPanel.d.ts +1 -2
  31. package/dist/types/src/components/DebugObjectPanel.d.ts.map +1 -1
  32. package/dist/types/src/components/DebugSettings.d.ts +1 -2
  33. package/dist/types/src/components/DebugSettings.d.ts.map +1 -1
  34. package/dist/types/src/components/DebugSpace/ObjectCreator.d.ts +1 -2
  35. package/dist/types/src/components/DebugSpace/ObjectCreator.d.ts.map +1 -1
  36. package/dist/types/src/components/DebugStatus.d.ts +1 -2
  37. package/dist/types/src/components/DebugStatus.d.ts.map +1 -1
  38. package/dist/types/src/components/SpaceGenerator/SchemaTable.d.ts +1 -2
  39. package/dist/types/src/components/SpaceGenerator/SchemaTable.d.ts.map +1 -1
  40. package/dist/types/src/components/SpaceGenerator/SpaceGenerator.d.ts +1 -2
  41. package/dist/types/src/components/SpaceGenerator/SpaceGenerator.d.ts.map +1 -1
  42. package/dist/types/src/components/SpaceGenerator/presets.d.ts +6 -1
  43. package/dist/types/src/components/SpaceGenerator/presets.d.ts.map +1 -1
  44. package/dist/types/src/components/Wireframe.d.ts +1 -2
  45. package/dist/types/src/components/Wireframe.d.ts.map +1 -1
  46. package/dist/types/src/components/index.d.ts +4 -4
  47. package/dist/types/src/components/index.d.ts.map +1 -1
  48. package/dist/types/src/meta.d.ts +1 -0
  49. package/dist/types/src/meta.d.ts.map +1 -1
  50. package/dist/types/src/translations.d.ts +28 -0
  51. package/dist/types/src/translations.d.ts.map +1 -1
  52. package/dist/types/src/types.d.ts +44 -1
  53. package/dist/types/src/types.d.ts.map +1 -1
  54. package/package.json +49 -47
  55. package/src/DebugPlugin.tsx +12 -4
  56. package/src/capabilities/app-graph-builder.ts +292 -87
  57. package/src/capabilities/index.ts +1 -0
  58. package/src/capabilities/react-context.tsx +16 -0
  59. package/src/capabilities/react-surface.tsx +204 -27
  60. package/src/capabilities/settings.ts +0 -1
  61. package/src/components/DebugSettings.tsx +61 -66
  62. package/src/components/SpaceGenerator/ObjectGenerator.tsx +2 -2
  63. package/src/components/SpaceGenerator/SpaceGenerator.tsx +68 -2
  64. package/src/components/SpaceGenerator/presets.ts +250 -9
  65. package/src/meta.ts +3 -1
  66. package/src/translations.ts +28 -0
  67. package/src/types.ts +52 -1
  68. package/dist/lib/browser/SpaceGenerator-4VO7E5P2.mjs.map +0 -7
  69. package/dist/lib/browser/app-graph-builder-IMWFZ3OZ.mjs +0 -181
  70. package/dist/lib/browser/app-graph-builder-IMWFZ3OZ.mjs.map +0 -7
  71. package/dist/lib/browser/chunk-I3ON45JK.mjs +0 -18
  72. package/dist/lib/browser/chunk-I3ON45JK.mjs.map +0 -7
  73. package/dist/lib/browser/chunk-P7GHHMDB.mjs +0 -21
  74. package/dist/lib/browser/chunk-P7GHHMDB.mjs.map +0 -7
  75. package/dist/lib/browser/react-surface-XDHEQY27.mjs.map +0 -7
  76. /package/dist/lib/browser/{DebugSpace-4JHYA7FG.mjs.map → DebugSpace-BTMTVZ6C.mjs.map} +0 -0
@@ -0,0 +1,16 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import React from 'react';
6
+
7
+ import { Capabilities, contributes } from '@dxos/app-framework';
8
+ import { DevtoolsContextProvider } from '@dxos/devtools';
9
+
10
+ import { DEBUG_PLUGIN } from '../meta';
11
+
12
+ export default () =>
13
+ contributes(Capabilities.ReactContext, {
14
+ id: DEBUG_PLUGIN,
15
+ context: ({ children }) => <DevtoolsContextProvider>{children}</DevtoolsContextProvider>,
16
+ });
@@ -4,8 +4,39 @@
4
4
 
5
5
  import React, { useCallback } from 'react';
6
6
 
7
- import { Capabilities, contributes, createIntent, createSurface, type PluginsContext } from '@dxos/app-framework';
8
- import { Devtools } from '@dxos/devtools';
7
+ import {
8
+ Capabilities,
9
+ contributes,
10
+ createIntent,
11
+ createSurface,
12
+ LayoutAction,
13
+ type PluginsContext,
14
+ } from '@dxos/app-framework';
15
+ import {
16
+ ConfigPanel,
17
+ CredentialsPanel,
18
+ DeviceListPanel,
19
+ DiagnosticsPanel,
20
+ FeedsPanel,
21
+ IdentityPanel,
22
+ KeyringPanel,
23
+ LoggingPanel,
24
+ MembersPanel,
25
+ MetadataPanel,
26
+ NetworkPanel,
27
+ ObjectsPanel,
28
+ SignalPanel,
29
+ SpaceInfoPanel,
30
+ SpaceListPanel,
31
+ StoragePanel,
32
+ SwarmPanel,
33
+ TracingPanel,
34
+ DashboardPanel,
35
+ EdgeDashboardPanel,
36
+ SearchPanel,
37
+ AutomergePanel,
38
+ WorkflowPanel,
39
+ } from '@dxos/devtools';
9
40
  import { SettingsStore } from '@dxos/local-storage';
10
41
  import { Graph } from '@dxos/plugin-graph';
11
42
  import { SpaceAction, CollectionType } from '@dxos/plugin-space/types';
@@ -28,7 +59,7 @@ import {
28
59
  Wireframe,
29
60
  } from '../components';
30
61
  import { DEBUG_PLUGIN } from '../meta';
31
- import { type DebugSettingsProps } from '../types';
62
+ import { type DebugSettingsProps, Devtools } from '../types';
32
63
 
33
64
  type SpaceDebug = {
34
65
  type: string;
@@ -39,8 +70,8 @@ type GraphDebug = {
39
70
  graph: Graph;
40
71
  };
41
72
 
42
- const isSpaceDebug = (data: any): data is SpaceDebug => data.type === `${DEBUG_PLUGIN}/space` && isSpace(data.space);
43
- const isGraphDebug = (data: any): data is GraphDebug => data.graph instanceof Graph;
73
+ const isSpaceDebug = (data: any): data is SpaceDebug => data?.type === `${DEBUG_PLUGIN}/space` && isSpace(data.space);
74
+ const isGraphDebug = (data: any): data is GraphDebug => data?.graph instanceof Graph;
44
75
 
45
76
  export default (context: PluginsContext) =>
46
77
  contributes(Capabilities.ReactSurface, [
@@ -51,28 +82,6 @@ export default (context: PluginsContext) =>
51
82
  data.subject instanceof SettingsStore && data.subject.prefix === DEBUG_PLUGIN,
52
83
  component: ({ data: { subject } }) => <DebugSettings settings={subject.value} />,
53
84
  }),
54
- createSurface({
55
- id: `${DEBUG_PLUGIN}/status`,
56
- role: 'status',
57
- component: () => <DebugStatus />,
58
- }),
59
- createSurface({
60
- id: `${DEBUG_PLUGIN}/complementary`,
61
- role: 'complementary--debug',
62
- filter: (data): data is { subject: ReactiveEchoObject<any> } => isEchoObject(data.subject),
63
- component: ({ data }) => <DebugObjectPanel object={data.subject} />,
64
- }),
65
- createSurface({
66
- id: `${DEBUG_PLUGIN}/devtools`,
67
- role: 'article',
68
- filter: (data): data is any => {
69
- const settings = context
70
- .requestCapability(Capabilities.SettingsStore)
71
- .getStore<DebugSettingsProps>(DEBUG_PLUGIN)!.value;
72
- return data.subject === 'devtools' && !!settings.devtools;
73
- },
74
- component: () => <Devtools />,
75
- }),
76
85
  createSurface({
77
86
  id: `${DEBUG_PLUGIN}/space`,
78
87
  role: 'article',
@@ -127,4 +136,172 @@ export default (context: PluginsContext) =>
127
136
  <Wireframe label={`${role}:${name}`} object={data.subject} classNames='row-span-2 overflow-hidden' />
128
137
  ),
129
138
  }),
139
+ createSurface({
140
+ id: `${DEBUG_PLUGIN}/complementary`,
141
+ role: 'complementary--debug',
142
+ filter: (data): data is { subject: ReactiveEchoObject<any> } => isEchoObject(data.subject),
143
+ component: ({ data }) => <DebugObjectPanel object={data.subject} />,
144
+ }),
145
+ createSurface({
146
+ id: `${DEBUG_PLUGIN}/status`,
147
+ role: 'status',
148
+ component: () => <DebugStatus />,
149
+ }),
150
+
151
+ //
152
+ // Devtools
153
+ //
154
+
155
+ createSurface({
156
+ id: `${DEBUG_PLUGIN}/client/config`,
157
+ role: 'article',
158
+ filter: (data): data is any => data.subject === Devtools.Client.Config,
159
+ component: () => <ConfigPanel />,
160
+ }),
161
+ createSurface({
162
+ id: `${DEBUG_PLUGIN}/client/storage`,
163
+ role: 'article',
164
+ filter: (data): data is any => data.subject === Devtools.Client.Storage,
165
+ component: () => <StoragePanel />,
166
+ }),
167
+ createSurface({
168
+ id: `${DEBUG_PLUGIN}/client/logs`,
169
+ role: 'article',
170
+ filter: (data): data is any => data.subject === Devtools.Client.Logs,
171
+ component: () => <LoggingPanel />,
172
+ }),
173
+ createSurface({
174
+ id: `${DEBUG_PLUGIN}/client/diagnostics`,
175
+ role: 'article',
176
+ filter: (data): data is any => data.subject === Devtools.Client.Diagnostics,
177
+ component: () => <DiagnosticsPanel />,
178
+ }),
179
+ createSurface({
180
+ id: `${DEBUG_PLUGIN}/client/tracing`,
181
+ role: 'article',
182
+ filter: (data): data is any => data.subject === Devtools.Client.Tracing,
183
+ component: () => <TracingPanel />,
184
+ }),
185
+ createSurface({
186
+ id: `${DEBUG_PLUGIN}/halo/identity`,
187
+ role: 'article',
188
+ filter: (data): data is any => data.subject === Devtools.Halo.Identity,
189
+ component: () => <IdentityPanel />,
190
+ }),
191
+ createSurface({
192
+ id: `${DEBUG_PLUGIN}/halo/devices`,
193
+ role: 'article',
194
+ filter: (data): data is any => data.subject === Devtools.Halo.Devices,
195
+ component: () => <DeviceListPanel />,
196
+ }),
197
+ createSurface({
198
+ id: `${DEBUG_PLUGIN}/halo/keyring`,
199
+ role: 'article',
200
+ filter: (data): data is any => data.subject === Devtools.Halo.Keyring,
201
+ component: () => <KeyringPanel />,
202
+ }),
203
+ createSurface({
204
+ id: `${DEBUG_PLUGIN}/halo/credentials`,
205
+ role: 'article',
206
+ filter: (data): data is any => data.subject === Devtools.Halo.Credentials,
207
+ component: () => <CredentialsPanel />,
208
+ }),
209
+ createSurface({
210
+ id: `${DEBUG_PLUGIN}/echo/spaces`,
211
+ role: 'article',
212
+ filter: (data): data is any => data.subject === Devtools.Echo.Spaces,
213
+ component: () => {
214
+ const { dispatchPromise: dispatch } = context.requestCapability(Capabilities.IntentDispatcher);
215
+ const handleSelect = useCallback(
216
+ () => dispatch(createIntent(LayoutAction.Open, { part: 'main', subject: [Devtools.Echo.Space] })),
217
+ [dispatch],
218
+ );
219
+ return <SpaceListPanel onSelect={handleSelect} />;
220
+ },
221
+ }),
222
+ createSurface({
223
+ id: `${DEBUG_PLUGIN}/echo/space`,
224
+ role: 'article',
225
+ filter: (data): data is any => data.subject === Devtools.Echo.Space,
226
+ component: () => {
227
+ const { dispatchPromise: dispatch } = context.requestCapability(Capabilities.IntentDispatcher);
228
+ const handleSelect = useCallback(
229
+ () => dispatch(createIntent(LayoutAction.Open, { part: 'main', subject: [Devtools.Echo.Feeds] })),
230
+ [dispatch],
231
+ );
232
+ return <SpaceInfoPanel onSelectFeed={handleSelect} onSelectPipeline={handleSelect} />;
233
+ },
234
+ }),
235
+ createSurface({
236
+ id: `${DEBUG_PLUGIN}/echo/feeds`,
237
+ role: 'article',
238
+ filter: (data): data is any => data.subject === Devtools.Echo.Feeds,
239
+ component: () => <FeedsPanel />,
240
+ }),
241
+ createSurface({
242
+ id: `${DEBUG_PLUGIN}/echo/objects`,
243
+ role: 'article',
244
+ filter: (data): data is any => data.subject === Devtools.Echo.Objects,
245
+ component: () => <ObjectsPanel />,
246
+ }),
247
+ createSurface({
248
+ id: `${DEBUG_PLUGIN}/echo/automerge`,
249
+ role: 'article',
250
+ filter: (data): data is any => data.subject === Devtools.Echo.Automerge,
251
+ component: () => <AutomergePanel />,
252
+ }),
253
+ createSurface({
254
+ id: `${DEBUG_PLUGIN}/echo/members`,
255
+ role: 'article',
256
+ filter: (data): data is any => data.subject === Devtools.Echo.Members,
257
+ component: () => <MembersPanel />,
258
+ }),
259
+ createSurface({
260
+ id: `${DEBUG_PLUGIN}/echo/metadata`,
261
+ role: 'article',
262
+ filter: (data): data is any => data.subject === Devtools.Echo.Metadata,
263
+ component: () => <MetadataPanel />,
264
+ }),
265
+ createSurface({
266
+ id: `${DEBUG_PLUGIN}/mesh/signal`,
267
+ role: 'article',
268
+ filter: (data): data is any => data.subject === Devtools.Mesh.Signal,
269
+ component: () => <SignalPanel />,
270
+ }),
271
+ createSurface({
272
+ id: `${DEBUG_PLUGIN}/mesh/swarm`,
273
+ role: 'article',
274
+ filter: (data): data is any => data.subject === Devtools.Mesh.Swarm,
275
+ component: () => <SwarmPanel />,
276
+ }),
277
+ createSurface({
278
+ id: `${DEBUG_PLUGIN}/mesh/network`,
279
+ role: 'article',
280
+ filter: (data): data is any => data.subject === Devtools.Mesh.Network,
281
+ component: () => <NetworkPanel />,
282
+ }),
283
+ createSurface({
284
+ id: `${DEBUG_PLUGIN}/agent/dashboard`,
285
+ role: 'article',
286
+ filter: (data): data is any => data.subject === Devtools.Agent.Dashboard,
287
+ component: () => <DashboardPanel />,
288
+ }),
289
+ createSurface({
290
+ id: `${DEBUG_PLUGIN}/agent/search`,
291
+ role: 'article',
292
+ filter: (data): data is any => data.subject === Devtools.Agent.Search,
293
+ component: () => <SearchPanel />,
294
+ }),
295
+ createSurface({
296
+ id: `${DEBUG_PLUGIN}/edge/dashboard`,
297
+ role: 'article',
298
+ filter: (data): data is any => data.subject === Devtools.Edge.Dashboard,
299
+ component: () => <EdgeDashboardPanel />,
300
+ }),
301
+ createSurface({
302
+ id: `${DEBUG_PLUGIN}/edge/workflows`,
303
+ role: 'article',
304
+ filter: (data): data is any => data.subject === Devtools.Edge.Workflows,
305
+ component: () => <WorkflowPanel />,
306
+ }),
130
307
  ]);
@@ -11,7 +11,6 @@ import { type DebugSettingsProps, DebugSettingsSchema } from '../types';
11
11
  export default () => {
12
12
  const settings = create<DebugSettingsProps>({
13
13
  debug: true,
14
- devtools: true,
15
14
  });
16
15
 
17
16
  return contributes(Capabilities.Settings, { schema: DebugSettingsSchema, prefix: DEBUG_PLUGIN, value: settings });
@@ -78,73 +78,68 @@ export const DebugSettings = ({ settings }: { settings: DebugSettingsProps }) =>
78
78
 
79
79
  return (
80
80
  <DeprecatedFormContainer>
81
- <DeprecatedFormContainer>
82
- <DeprecatedFormInput label={t('settings show debug panel')}>
83
- <Input.Switch checked={settings.debug} onCheckedChange={(checked) => (settings.debug = !!checked)} />
84
- </DeprecatedFormInput>
85
- <DeprecatedFormInput label={t('settings show devtools panel')}>
86
- <Input.Switch checked={settings.devtools} onCheckedChange={(checked) => (settings.devtools = !!checked)} />
87
- </DeprecatedFormInput>
88
- <DeprecatedFormInput label={t('settings wireframe')}>
89
- <Input.Switch checked={settings.wireframe} onCheckedChange={(checked) => (settings.wireframe = !!checked)} />
90
- </DeprecatedFormInput>
91
- <DeprecatedFormInput label={t('settings download diagnostics')}>
92
- <Button onClick={handleDownload}>
93
- <Icon icon='ph--download-simple--regular' size={5} />
94
- </Button>
95
- </DeprecatedFormInput>
96
- <DeprecatedFormInput label={t('settings repair')}>
97
- <Button onClick={handleRepair}>
98
- <Icon icon='ph--first-aid-kit--regular' size={5} />
99
- </Button>
100
- </DeprecatedFormInput>
101
-
102
- {/* TODO(burdon): Move to layout? */}
103
- {toast && (
104
- <Toast.Root>
105
- <Toast.Body>
106
- <Toast.Title>
107
- <Icon icon='ph--gift--duotone' size={5} classNames='inline mr-1' />
108
- <span>{toast.title}</span>
109
- </Toast.Title>
110
- {toast.description && <Toast.Description>{toast.description}</Toast.Description>}
111
- </Toast.Body>
112
- </Toast.Root>
113
- )}
114
-
115
- <DeprecatedFormInput label={t('settings choose storage adaptor')}>
116
- <Select.Root
117
- value={
118
- Object.entries(StorageAdapters).find(
119
- ([name, value]) => value === storageConfig?.runtime?.client?.storage?.dataStore,
120
- )?.[0]
81
+ <DeprecatedFormInput label={t('settings show debug panel')}>
82
+ <Input.Switch checked={settings.debug} onCheckedChange={(checked) => (settings.debug = !!checked)} />
83
+ </DeprecatedFormInput>
84
+ <DeprecatedFormInput label={t('settings wireframe')}>
85
+ <Input.Switch checked={settings.wireframe} onCheckedChange={(checked) => (settings.wireframe = !!checked)} />
86
+ </DeprecatedFormInput>
87
+ <DeprecatedFormInput label={t('settings download diagnostics')}>
88
+ <Button onClick={handleDownload}>
89
+ <Icon icon='ph--download-simple--regular' size={5} />
90
+ </Button>
91
+ </DeprecatedFormInput>
92
+ <DeprecatedFormInput label={t('settings repair')}>
93
+ <Button onClick={handleRepair}>
94
+ <Icon icon='ph--first-aid-kit--regular' size={5} />
95
+ </Button>
96
+ </DeprecatedFormInput>
97
+
98
+ {/* TODO(burdon): Move to layout? */}
99
+ {toast && (
100
+ <Toast.Root>
101
+ <Toast.Body>
102
+ <Toast.Title>
103
+ <Icon icon='ph--gift--duotone' size={5} classNames='inline mr-1' />
104
+ <span>{toast.title}</span>
105
+ </Toast.Title>
106
+ {toast.description && <Toast.Description>{toast.description}</Toast.Description>}
107
+ </Toast.Body>
108
+ </Toast.Root>
109
+ )}
110
+
111
+ <DeprecatedFormInput label={t('settings choose storage adaptor')}>
112
+ <Select.Root
113
+ value={
114
+ Object.entries(StorageAdapters).find(
115
+ ([name, value]) => value === storageConfig?.runtime?.client?.storage?.dataStore,
116
+ )?.[0]
117
+ }
118
+ onValueChange={(value) => {
119
+ if (confirm(t('settings storage adapter changed alert'))) {
120
+ updateConfig(
121
+ storageConfig,
122
+ setStorageConfig,
123
+ ['runtime', 'client', 'storage', 'dataStore'],
124
+ StorageAdapters[value as keyof typeof StorageAdapters],
125
+ );
121
126
  }
122
- onValueChange={(value) => {
123
- if (confirm(t('settings storage adapter changed alert'))) {
124
- updateConfig(
125
- storageConfig,
126
- setStorageConfig,
127
- ['runtime', 'client', 'storage', 'dataStore'],
128
- StorageAdapters[value as keyof typeof StorageAdapters],
129
- );
130
- }
131
- }}
132
- >
133
- <Select.TriggerButton placeholder={t('settings data store label')} />
134
- <Select.Portal>
135
- <Select.Content>
136
- <Select.Viewport>
137
- {Object.keys(StorageAdapters).map((key) => (
138
- <Select.Option key={key} value={key}>
139
- {t(`settings storage adaptor ${key} label`)}
140
- </Select.Option>
141
- ))}
142
- </Select.Viewport>
143
- </Select.Content>
144
- </Select.Portal>
145
- </Select.Root>
146
- </DeprecatedFormInput>
147
- </DeprecatedFormContainer>
127
+ }}
128
+ >
129
+ <Select.TriggerButton placeholder={t('settings data store label')} />
130
+ <Select.Portal>
131
+ <Select.Content>
132
+ <Select.Viewport>
133
+ {Object.keys(StorageAdapters).map((key) => (
134
+ <Select.Option key={key} value={key}>
135
+ {t(`settings storage adaptor ${key} label`)}
136
+ </Select.Option>
137
+ ))}
138
+ </Select.Viewport>
139
+ </Select.Content>
140
+ </Select.Portal>
141
+ </Select.Root>
142
+ </DeprecatedFormInput>
148
143
  </DeprecatedFormContainer>
149
144
  );
150
145
  };
@@ -5,7 +5,7 @@
5
5
  import { addressToA1Notation } from '@dxos/compute';
6
6
  import { ComputeGraph, ComputeGraphModel, DEFAULT_OUTPUT, NODE_INPUT, NODE_OUTPUT } from '@dxos/conductor';
7
7
  import { ObjectId, type BaseObject, type TypedObject } from '@dxos/echo-schema';
8
- import { DXN, SpaceId } from '@dxos/keys';
8
+ import { DXN } from '@dxos/keys';
9
9
  import { create, makeRef, type ReactiveObject } from '@dxos/live-object';
10
10
  import { DocumentType } from '@dxos/plugin-markdown/types';
11
11
  import { createSheet } from '@dxos/plugin-sheet/types';
@@ -120,7 +120,7 @@ export const staticGenerators = new Map<string, ObjectGenerator<any>>([
120
120
  .createNode({
121
121
  id: 'gpt-QUEUE_ID',
122
122
  type: 'constant',
123
- value: new DXN(DXN.kind.QUEUE, ['data', SpaceId.random(), ObjectId.random()]).toString(),
123
+ value: new DXN(DXN.kind.QUEUE, ['data', space.id, ObjectId.random()]).toString(),
124
124
  })
125
125
  .createNode({ id: 'gpt-APPEND', type: 'append' })
126
126
  .createNode({ id: 'gpt-OUTPUT', type: NODE_OUTPUT })
@@ -4,15 +4,20 @@
4
4
 
5
5
  import React, { useCallback, useMemo, useState } from 'react';
6
6
 
7
+ import { createIntent, useIntentDispatcher } from '@dxos/app-framework';
7
8
  import { ComputeGraph } from '@dxos/conductor';
8
- import { type ReactiveObject } from '@dxos/live-object';
9
+ import { toEffectSchema } from '@dxos/echo-schema';
10
+ import { create, type ReactiveObject } from '@dxos/live-object';
11
+ import { log } from '@dxos/log';
9
12
  import { DocumentType } from '@dxos/plugin-markdown/types';
10
13
  import { SheetType } from '@dxos/plugin-sheet/types';
11
14
  import { DiagramType } from '@dxos/plugin-sketch/types';
15
+ import { SpaceAction } from '@dxos/plugin-space/types';
12
16
  import { useClient } from '@dxos/react-client';
13
17
  import { getTypename, type Space } from '@dxos/react-client/echo';
14
18
  import { IconButton, Input, Toolbar, useAsyncEffect } from '@dxos/react-ui';
15
19
  import { SyntaxHighlighter } from '@dxos/react-ui-syntax-highlighter';
20
+ import { initializeTable, TableType } from '@dxos/react-ui-table';
16
21
  import { Testing } from '@dxos/schema/testing';
17
22
  import { jsonKeyReplacer, sortKeys } from '@dxos/util';
18
23
 
@@ -26,9 +31,16 @@ export type SpaceGeneratorProps = {
26
31
  };
27
32
 
28
33
  export const SpaceGenerator = ({ space, onCreateObjects }: SpaceGeneratorProps) => {
34
+ const { dispatchPromise: dispatch } = useIntentDispatcher();
29
35
  const client = useClient();
30
36
  const staticTypes = [DocumentType, DiagramType, SheetType, ComputeGraph]; // TODO(burdon): Make extensible.
31
- const mutableTypes = [Testing.OrgType, Testing.ProjectType, Testing.ContactType, Testing.EmailType];
37
+ const mutableTypes = [
38
+ Testing.OrgType,
39
+ Testing.ProjectType,
40
+ Testing.ContactType,
41
+ Testing.EmailType,
42
+ Testing.MessageType,
43
+ ];
32
44
  const [count, setCount] = useState(1);
33
45
  const [info, setInfo] = useState<any>({});
34
46
 
@@ -84,10 +96,64 @@ export const SpaceGenerator = ({ space, onCreateObjects }: SpaceGeneratorProps)
84
96
  [typeMap, count],
85
97
  );
86
98
 
99
+ // TODO(wittjosiah): Remove. Replace with proper echo import.
100
+ const handleLoadTables = useCallback(async () => {
101
+ const input = document.createElement('input');
102
+ input.type = 'file';
103
+ input.accept = '.json';
104
+
105
+ input.onchange = async (e) => {
106
+ const file = (e.target as HTMLInputElement).files?.[0];
107
+ if (!file) {
108
+ return;
109
+ }
110
+
111
+ try {
112
+ const content = await file.text();
113
+ const data = JSON.parse(content);
114
+ const schemas = await space.db.schemaRegistry.register(data.schemas.map(toEffectSchema));
115
+ // TODO(wittjosiah): If the schema is already registered this should skip.
116
+ await Promise.all(
117
+ schemas.map(async (schema) => {
118
+ const parts = schema.typename.split('/');
119
+ const name = parts[parts.length - 1];
120
+ const table = create(TableType, { name, threads: [] });
121
+ await initializeTable({ space, table, initialSchema: schema.typename });
122
+ await dispatch(createIntent(SpaceAction.AddObject, { target: space, object: table }));
123
+ return table;
124
+ }),
125
+ );
126
+ // TODO(wittjosiah): This should query the space for schemas.
127
+ await Promise.all(
128
+ data.objects.map(async ({ id, '@type': typename, ...fields }: any) => {
129
+ const schema = schemas.find((s) => `dxn:type:${s.typename}:${s.version}` === typename);
130
+ if (!schema) {
131
+ log.warn('Missing schema for object', { id, typename });
132
+ return;
133
+ }
134
+ const object = create(schema, fields);
135
+ space.db.add(object);
136
+ return object;
137
+ }),
138
+ );
139
+ } catch (err) {
140
+ log.catch(err);
141
+ }
142
+ };
143
+
144
+ input.click();
145
+ }, []);
146
+
87
147
  return (
88
148
  <div role='none' className='flex flex-col divide-y divide-separator'>
89
149
  <Toolbar.Root classNames='p-1'>
90
150
  <IconButton icon='ph--arrow-clockwise--regular' iconOnly label='Refresh' onClick={updateInfo} />
151
+ <IconButton
152
+ icon='ph--file-arrow-up--regular'
153
+ iconOnly
154
+ label='Load tables from JSON'
155
+ onClick={handleLoadTables}
156
+ />
91
157
  <Toolbar.Separator variant='gap' />
92
158
  <div className='flex'>
93
159
  <Input.Root>