@dxos/plugin-space 0.8.4-main.72ec0f3 → 0.8.4-main.7ace549

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 (187) hide show
  1. package/dist/lib/browser/{ObjectDetailsPanel-2BRUBHP6.mjs → ObjectDetailsPanel-ACGHWPDX.mjs} +2 -2
  2. package/dist/lib/browser/{ObjectDetailsPanel-2BRUBHP6.mjs.map → ObjectDetailsPanel-ACGHWPDX.mjs.map} +3 -3
  3. package/dist/lib/browser/{ObjectSettings-5LLWCVEK.mjs → ObjectSettings-U3IH7BMV.mjs} +2 -2
  4. package/dist/lib/browser/{ObjectSettings-5LLWCVEK.mjs.map → ObjectSettings-U3IH7BMV.mjs.map} +3 -3
  5. package/dist/lib/browser/{RecordArticle-SXDRWTTU.mjs → RecordArticle-2PFEBPXY.mjs} +1 -1
  6. package/dist/lib/browser/RecordArticle-2PFEBPXY.mjs.map +7 -0
  7. package/dist/lib/browser/{app-graph-builder-VQAB3GCQ.mjs → app-graph-builder-HABMCWAI.mjs} +140 -151
  8. package/dist/lib/browser/app-graph-builder-HABMCWAI.mjs.map +7 -0
  9. package/dist/lib/browser/{app-graph-serializer-KSLKMEPP.mjs → app-graph-serializer-G3VFEGTN.mjs} +4 -4
  10. package/dist/lib/browser/chunk-6A3NWBB6.mjs +392 -0
  11. package/dist/lib/browser/chunk-6A3NWBB6.mjs.map +7 -0
  12. package/dist/lib/browser/{chunk-K5J7ZB5P.mjs → chunk-C6DAPIFF.mjs} +3 -3
  13. package/dist/lib/browser/chunk-C6DAPIFF.mjs.map +7 -0
  14. package/dist/lib/browser/{chunk-ERQMHU7L.mjs → chunk-GJOZILGC.mjs} +163 -105
  15. package/dist/lib/browser/chunk-GJOZILGC.mjs.map +7 -0
  16. package/dist/lib/browser/{chunk-J2BUK5E6.mjs → chunk-KCZ527AM.mjs} +169 -101
  17. package/dist/lib/browser/chunk-KCZ527AM.mjs.map +7 -0
  18. package/dist/lib/browser/{chunk-PU5IOFMG.mjs → chunk-P25R3AOK.mjs} +4 -47
  19. package/dist/lib/browser/{chunk-PU5IOFMG.mjs.map → chunk-P25R3AOK.mjs.map} +4 -4
  20. package/dist/lib/browser/{chunk-OLBBSOVI.mjs → chunk-POFUXISV.mjs} +53 -59
  21. package/dist/lib/browser/chunk-POFUXISV.mjs.map +7 -0
  22. package/dist/lib/browser/index.mjs +47 -94
  23. package/dist/lib/browser/index.mjs.map +3 -3
  24. package/dist/lib/browser/{intent-resolver-Q2XWHAVA.mjs → intent-resolver-RZEWNJ2K.mjs} +51 -40
  25. package/dist/lib/browser/intent-resolver-RZEWNJ2K.mjs.map +7 -0
  26. package/dist/lib/browser/meta.json +1 -1
  27. package/dist/lib/browser/{react-root-MM4HADPE.mjs → react-root-JCRD74GI.mjs} +6 -6
  28. package/dist/lib/browser/{react-surface-SGZC3Y4U.mjs → react-surface-VOETEAG3.mjs} +28 -14
  29. package/dist/lib/browser/react-surface-VOETEAG3.mjs.map +7 -0
  30. package/dist/lib/browser/repair-CNLE35NF.mjs +44 -0
  31. package/dist/lib/browser/repair-CNLE35NF.mjs.map +7 -0
  32. package/dist/lib/browser/{settings-WKLGKUHQ.mjs → settings-TRLI52I5.mjs} +2 -2
  33. package/dist/lib/browser/{spaces-ready-C5QC2UFL.mjs → spaces-ready-OHGCWZHQ.mjs} +13 -7
  34. package/dist/lib/browser/{spaces-ready-C5QC2UFL.mjs.map → spaces-ready-OHGCWZHQ.mjs.map} +2 -2
  35. package/dist/lib/browser/{state-Q7YRE5KG.mjs → state-C7N6EDDZ.mjs} +2 -2
  36. package/dist/lib/browser/types/index.mjs +9 -3
  37. package/dist/lib/node-esm/{ObjectDetailsPanel-6PZQIQG3.mjs → ObjectDetailsPanel-6OFTT3GG.mjs} +2 -2
  38. package/dist/lib/node-esm/{ObjectDetailsPanel-6PZQIQG3.mjs.map → ObjectDetailsPanel-6OFTT3GG.mjs.map} +3 -3
  39. package/dist/lib/node-esm/{ObjectSettings-OQSBOH7K.mjs → ObjectSettings-YXPJQMJ5.mjs} +2 -2
  40. package/dist/lib/node-esm/{ObjectSettings-OQSBOH7K.mjs.map → ObjectSettings-YXPJQMJ5.mjs.map} +3 -3
  41. package/dist/lib/node-esm/{RecordArticle-NACBH42P.mjs → RecordArticle-SSJ7PULS.mjs} +1 -1
  42. package/dist/lib/node-esm/RecordArticle-SSJ7PULS.mjs.map +7 -0
  43. package/dist/lib/node-esm/{app-graph-builder-24JCLJPX.mjs → app-graph-builder-T6VJKIOA.mjs} +140 -151
  44. package/dist/lib/node-esm/app-graph-builder-T6VJKIOA.mjs.map +7 -0
  45. package/dist/lib/node-esm/{app-graph-serializer-R723K764.mjs → app-graph-serializer-2NLWWFUB.mjs} +4 -4
  46. package/dist/lib/node-esm/{chunk-TJPQDQNI.mjs → chunk-7EV4SN47.mjs} +4 -47
  47. package/dist/lib/node-esm/{chunk-TJPQDQNI.mjs.map → chunk-7EV4SN47.mjs.map} +4 -4
  48. package/dist/lib/node-esm/{chunk-WC4VBFMA.mjs → chunk-AX3UGL5D.mjs} +53 -59
  49. package/dist/lib/node-esm/chunk-AX3UGL5D.mjs.map +7 -0
  50. package/dist/lib/node-esm/{chunk-VH2EBZEV.mjs → chunk-I6FZP42D.mjs} +163 -105
  51. package/dist/lib/node-esm/chunk-I6FZP42D.mjs.map +7 -0
  52. package/dist/lib/node-esm/{chunk-ITQFSFQ3.mjs → chunk-JAMGJUFU.mjs} +169 -101
  53. package/dist/lib/node-esm/chunk-JAMGJUFU.mjs.map +7 -0
  54. package/dist/lib/node-esm/{chunk-Z7BB6HC2.mjs → chunk-WWGV5FJM.mjs} +3 -3
  55. package/dist/lib/node-esm/chunk-WWGV5FJM.mjs.map +7 -0
  56. package/dist/lib/node-esm/chunk-X34VDVMY.mjs +393 -0
  57. package/dist/lib/node-esm/chunk-X34VDVMY.mjs.map +7 -0
  58. package/dist/lib/node-esm/index.mjs +47 -94
  59. package/dist/lib/node-esm/index.mjs.map +3 -3
  60. package/dist/lib/node-esm/{intent-resolver-YK4ESSET.mjs → intent-resolver-4PHJWDXW.mjs} +51 -40
  61. package/dist/lib/node-esm/intent-resolver-4PHJWDXW.mjs.map +7 -0
  62. package/dist/lib/node-esm/meta.json +1 -1
  63. package/dist/lib/node-esm/{react-root-5ANDLQMX.mjs → react-root-O5I5CDJ7.mjs} +6 -6
  64. package/dist/lib/node-esm/{react-surface-V7J2QB44.mjs → react-surface-J3XDMU2D.mjs} +28 -14
  65. package/dist/lib/node-esm/react-surface-J3XDMU2D.mjs.map +7 -0
  66. package/dist/lib/node-esm/repair-EHZS6MFY.mjs +45 -0
  67. package/dist/lib/node-esm/repair-EHZS6MFY.mjs.map +7 -0
  68. package/dist/lib/node-esm/{settings-RBB5633M.mjs → settings-MNQTKHL7.mjs} +2 -2
  69. package/dist/lib/node-esm/{spaces-ready-SJCXV6YH.mjs → spaces-ready-ZPU24DA2.mjs} +13 -7
  70. package/dist/lib/node-esm/{spaces-ready-SJCXV6YH.mjs.map → spaces-ready-ZPU24DA2.mjs.map} +2 -2
  71. package/dist/lib/node-esm/{state-362I5BMK.mjs → state-45TXZQJ6.mjs} +2 -2
  72. package/dist/lib/node-esm/types/index.mjs +9 -3
  73. package/dist/types/src/SpacePlugin.d.ts.map +1 -1
  74. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
  75. package/dist/types/src/capabilities/capabilities.d.ts +9 -4
  76. package/dist/types/src/capabilities/capabilities.d.ts.map +1 -1
  77. package/dist/types/src/capabilities/index.d.ts +1 -1
  78. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  79. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
  80. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  81. package/dist/types/src/capabilities/repair.d.ts +4 -0
  82. package/dist/types/src/capabilities/repair.d.ts.map +1 -0
  83. package/dist/types/src/capabilities/spaces-ready.d.ts.map +1 -1
  84. package/dist/types/src/components/CreateDialog/CreateObjectDialog.d.ts.map +1 -1
  85. package/dist/types/src/components/CreateDialog/CreateObjectDialog.stories.d.ts +147 -253
  86. package/dist/types/src/components/CreateDialog/CreateObjectDialog.stories.d.ts.map +1 -1
  87. package/dist/types/src/components/CreateDialog/CreateObjectPanel.d.ts +14 -7
  88. package/dist/types/src/components/CreateDialog/CreateObjectPanel.d.ts.map +1 -1
  89. package/dist/types/src/components/MembersContainer/MembersContainer.stories.d.ts +147 -253
  90. package/dist/types/src/components/MembersContainer/MembersContainer.stories.d.ts.map +1 -1
  91. package/dist/types/src/components/ObjectSettings/AdvancedObjectSettings.d.ts.map +1 -1
  92. package/dist/types/src/components/ObjectSettings/BaseObjectSettings.stories.d.ts +147 -253
  93. package/dist/types/src/components/ObjectSettings/BaseObjectSettings.stories.d.ts.map +1 -1
  94. package/dist/types/src/components/ObjectSettings/ForeignKeys.d.ts +3 -3
  95. package/dist/types/src/components/ObjectSettings/ForeignKeys.d.ts.map +1 -1
  96. package/dist/types/src/components/RecordArticle.stories.d.ts +147 -253
  97. package/dist/types/src/components/RecordArticle.stories.d.ts.map +1 -1
  98. package/dist/types/src/components/SchemaContainer.d.ts +1 -1
  99. package/dist/types/src/components/SchemaContainer.d.ts.map +1 -1
  100. package/dist/types/src/components/SpacePresence/SpacePresence.d.ts +2 -2
  101. package/dist/types/src/components/SpacePresence/SpacePresence.d.ts.map +1 -1
  102. package/dist/types/src/components/SpacePresence/SpacePresence.stories.d.ts +147 -253
  103. package/dist/types/src/components/SpacePresence/SpacePresence.stories.d.ts.map +1 -1
  104. package/dist/types/src/components/SpaceSettings/SpaceSettingsContainer.d.ts.map +1 -1
  105. package/dist/types/src/components/SpaceSettings/SpaceSettingsContainer.stories.d.ts +147 -253
  106. package/dist/types/src/components/SpaceSettings/SpaceSettingsContainer.stories.d.ts.map +1 -1
  107. package/dist/types/src/components/SyncStatus/SyncStatus.stories.d.ts +147 -253
  108. package/dist/types/src/components/SyncStatus/SyncStatus.stories.d.ts.map +1 -1
  109. package/dist/types/src/components/ViewEditor.d.ts.map +1 -1
  110. package/dist/types/src/components/index.d.ts +2 -2
  111. package/dist/types/src/helpers/query.d.ts +1 -1
  112. package/dist/types/src/helpers/query.d.ts.map +1 -1
  113. package/dist/types/src/hooks/useTypeOptions.d.ts +2 -2
  114. package/dist/types/src/hooks/useTypeOptions.d.ts.map +1 -1
  115. package/dist/types/src/translations.d.ts +147 -253
  116. package/dist/types/src/translations.d.ts.map +1 -1
  117. package/dist/types/src/types/form.d.ts +24 -0
  118. package/dist/types/src/types/form.d.ts.map +1 -0
  119. package/dist/types/src/types/index.d.ts +1 -0
  120. package/dist/types/src/types/index.d.ts.map +1 -1
  121. package/dist/types/src/types/types.d.ts +29 -72
  122. package/dist/types/src/types/types.d.ts.map +1 -1
  123. package/dist/types/src/util.d.ts +16 -32
  124. package/dist/types/src/util.d.ts.map +1 -1
  125. package/dist/types/tsconfig.tsbuildinfo +1 -1
  126. package/package.json +54 -50
  127. package/src/SpacePlugin.ts +34 -84
  128. package/src/capabilities/app-graph-builder.ts +130 -227
  129. package/src/capabilities/capabilities.ts +10 -5
  130. package/src/capabilities/index.ts +1 -1
  131. package/src/capabilities/intent-resolver.ts +31 -35
  132. package/src/capabilities/react-surface.tsx +34 -8
  133. package/src/capabilities/repair.ts +57 -0
  134. package/src/capabilities/spaces-ready.ts +7 -1
  135. package/src/components/CreateDialog/CreateObjectDialog.tsx +33 -23
  136. package/src/components/CreateDialog/CreateObjectPanel.tsx +32 -25
  137. package/src/components/ObjectDetailsPanel/ObjectForm.tsx +1 -1
  138. package/src/components/ObjectSettings/AdvancedObjectSettings.tsx +4 -5
  139. package/src/components/ObjectSettings/BaseObjectSettings.tsx +1 -1
  140. package/src/components/ObjectSettings/ForeignKeys.tsx +5 -5
  141. package/src/components/RecordArticle.tsx +6 -6
  142. package/src/components/SchemaContainer.tsx +2 -2
  143. package/src/components/SpacePresence/SpacePresence.tsx +2 -2
  144. package/src/components/SpaceSettings/SpaceSettingsContainer.tsx +25 -6
  145. package/src/components/ViewEditor.tsx +9 -3
  146. package/src/helpers/query.ts +1 -1
  147. package/src/hooks/useTypeOptions.ts +3 -35
  148. package/src/translations.ts +52 -57
  149. package/src/types/form.ts +75 -0
  150. package/src/types/index.ts +1 -0
  151. package/src/types/types.ts +26 -36
  152. package/src/util.tsx +165 -107
  153. package/dist/lib/browser/RecordArticle-SXDRWTTU.mjs.map +0 -7
  154. package/dist/lib/browser/app-graph-builder-VQAB3GCQ.mjs.map +0 -7
  155. package/dist/lib/browser/chunk-ERQMHU7L.mjs.map +0 -7
  156. package/dist/lib/browser/chunk-J2BUK5E6.mjs.map +0 -7
  157. package/dist/lib/browser/chunk-K5J7ZB5P.mjs.map +0 -7
  158. package/dist/lib/browser/chunk-M2Z6D4ZI.mjs +0 -349
  159. package/dist/lib/browser/chunk-M2Z6D4ZI.mjs.map +0 -7
  160. package/dist/lib/browser/chunk-OLBBSOVI.mjs.map +0 -7
  161. package/dist/lib/browser/intent-resolver-Q2XWHAVA.mjs.map +0 -7
  162. package/dist/lib/browser/react-surface-SGZC3Y4U.mjs.map +0 -7
  163. package/dist/lib/browser/schema-defs-QPI2JU3X.mjs +0 -26
  164. package/dist/lib/browser/schema-defs-QPI2JU3X.mjs.map +0 -7
  165. package/dist/lib/node-esm/RecordArticle-NACBH42P.mjs.map +0 -7
  166. package/dist/lib/node-esm/app-graph-builder-24JCLJPX.mjs.map +0 -7
  167. package/dist/lib/node-esm/chunk-2PN7QNGV.mjs +0 -350
  168. package/dist/lib/node-esm/chunk-2PN7QNGV.mjs.map +0 -7
  169. package/dist/lib/node-esm/chunk-ITQFSFQ3.mjs.map +0 -7
  170. package/dist/lib/node-esm/chunk-VH2EBZEV.mjs.map +0 -7
  171. package/dist/lib/node-esm/chunk-WC4VBFMA.mjs.map +0 -7
  172. package/dist/lib/node-esm/chunk-Z7BB6HC2.mjs.map +0 -7
  173. package/dist/lib/node-esm/intent-resolver-YK4ESSET.mjs.map +0 -7
  174. package/dist/lib/node-esm/react-surface-V7J2QB44.mjs.map +0 -7
  175. package/dist/lib/node-esm/schema-defs-ZS2D47XW.mjs +0 -27
  176. package/dist/lib/node-esm/schema-defs-ZS2D47XW.mjs.map +0 -7
  177. package/dist/types/src/capabilities/schema-defs.d.ts +0 -4
  178. package/dist/types/src/capabilities/schema-defs.d.ts.map +0 -1
  179. package/src/capabilities/schema-defs.ts +0 -31
  180. /package/dist/lib/browser/{app-graph-serializer-KSLKMEPP.mjs.map → app-graph-serializer-G3VFEGTN.mjs.map} +0 -0
  181. /package/dist/lib/browser/{react-root-MM4HADPE.mjs.map → react-root-JCRD74GI.mjs.map} +0 -0
  182. /package/dist/lib/browser/{settings-WKLGKUHQ.mjs.map → settings-TRLI52I5.mjs.map} +0 -0
  183. /package/dist/lib/browser/{state-Q7YRE5KG.mjs.map → state-C7N6EDDZ.mjs.map} +0 -0
  184. /package/dist/lib/node-esm/{app-graph-serializer-R723K764.mjs.map → app-graph-serializer-2NLWWFUB.mjs.map} +0 -0
  185. /package/dist/lib/node-esm/{react-root-5ANDLQMX.mjs.map → react-root-O5I5CDJ7.mjs.map} +0 -0
  186. /package/dist/lib/node-esm/{settings-RBB5633M.mjs.map → settings-MNQTKHL7.mjs.map} +0 -0
  187. /package/dist/lib/node-esm/{state-362I5BMK.mjs.map → state-45TXZQJ6.mjs.map} +0 -0
@@ -6,13 +6,15 @@ import * as Effect from 'effect/Effect';
6
6
 
7
7
  import {
8
8
  Capabilities,
9
+ type Label,
9
10
  LayoutAction,
10
11
  type PluginContext,
11
12
  contributes,
12
13
  createIntent,
13
14
  createResolver,
14
15
  } from '@dxos/app-framework';
15
- import { Filter, Obj, Query, Ref, Relation, Type } from '@dxos/echo';
16
+ import { Obj, Query, Ref, Relation, Type } from '@dxos/echo';
17
+ import { Serializer } from '@dxos/echo-db';
16
18
  import { DatabaseService } from '@dxos/functions';
17
19
  import { invariant } from '@dxos/invariant';
18
20
  import { Migrations } from '@dxos/migrations';
@@ -24,7 +26,7 @@ import { Invitation, InvitationEncoder } from '@dxos/react-client/invitations';
24
26
  import { ATTENDABLE_PATH_SEPARATOR } from '@dxos/react-ui-attention';
25
27
  import { iconValues } from '@dxos/react-ui-pickers';
26
28
  import { hues } from '@dxos/react-ui-theme';
27
- import { Collection, ProjectionModel, StoredSchema, getTypenameFromQuery } from '@dxos/schema';
29
+ import { Collection, ProjectionModel, getTypenameFromQuery } from '@dxos/schema';
28
30
 
29
31
  import {
30
32
  CREATE_OBJECT_DIALOG,
@@ -43,7 +45,7 @@ import { COMPOSER_SPACE_LOCK, cloneObject, getNestedObjects } from '../util';
43
45
  import { SpaceCapabilities } from './capabilities';
44
46
 
45
47
  // TODO(wittjosiah): Remove.
46
- const SPACE_MAX_OBJECTS = 500;
48
+ const SPACE_MAX_OBJECTS = 750;
47
49
 
48
50
  type IntentResolverOptions = {
49
51
  context: PluginContext;
@@ -92,20 +94,13 @@ export default ({ context, observability, createInvitationUrl }: IntentResolverO
92
94
  }
93
95
 
94
96
  // Create records smart collection.
95
- collection.objects.push(
96
- Ref.make(
97
- Obj.make(Collection.QueryCollection, {
98
- // NOTE: This is specifically Filter.typename due to current limitations in query collection parsing.
99
- query: Query.select(Filter.typename(StoredSchema.typename)).ast,
100
- }),
101
- ),
102
- );
97
+ collection.objects.push(Ref.make(Collection.makeManaged({ key: Type.getTypename(Type.PersistentType) })));
103
98
 
104
99
  // Allow other plugins to add default content.
105
100
  await context.activatePromise(SpaceEvents.SpaceCreated);
106
- const onCreateSpaceCallbacks = context.getCapabilities(SpaceCapabilities.onCreateSpace);
101
+ const onCreateSpaceCallbacks = context.getCapabilities(SpaceCapabilities.OnCreateSpace);
107
102
  const spaceCreatedIntents = onCreateSpaceCallbacks.map((onCreateSpace) =>
108
- onCreateSpace({ space, rootCollection: collection }),
103
+ onCreateSpace({ space, isDefault: false, rootCollection: collection }),
109
104
  );
110
105
 
111
106
  return {
@@ -330,6 +325,17 @@ export default ({ context, observability, createInvitationUrl }: IntentResolverO
330
325
  };
331
326
  },
332
327
  }),
328
+ createResolver({
329
+ intent: SpaceAction.Snapshot,
330
+ resolve: async ({ space, query }) => {
331
+ const backup = await new Serializer().export(space.db, query && Query.fromAst(query));
332
+ return {
333
+ data: {
334
+ snapshot: new Blob([JSON.stringify(backup, null, 2)], { type: 'application/json' }),
335
+ },
336
+ };
337
+ },
338
+ }),
333
339
  createResolver({
334
340
  intent: SpaceAction.UseStaticSchema,
335
341
  resolve: async ({ space, typename, show }) => {
@@ -455,8 +461,8 @@ export default ({ context, observability, createInvitationUrl }: IntentResolverO
455
461
  shouldNavigate: navigable
456
462
  ? (object: Obj.Any) => {
457
463
  const isCollection = Obj.instanceOf(Collection.Collection, object);
458
- const isQueryCollection = Obj.instanceOf(Collection.QueryCollection, object);
459
- return (!isCollection && !isQueryCollection) || state.navigableCollections;
464
+ const isSystemCollection = Obj.instanceOf(Collection.Managed, object);
465
+ return (!isCollection && !isSystemCollection) || state.navigableCollections;
460
466
  }
461
467
  : () => false,
462
468
  } satisfies Partial<CreateObjectDialogProps>,
@@ -598,16 +604,17 @@ export default ({ context, observability, createInvitationUrl }: IntentResolverO
598
604
  });
599
605
  objects.forEach((obj) => space.db.remove(obj));
600
606
 
601
- const undoMessageKey = objects.some((obj) => Obj.instanceOf(Collection.Collection, obj))
602
- ? 'collection deleted label'
603
- : objects.length > 1
604
- ? 'objects deleted label'
605
- : 'object deleted label';
607
+ // TODO(wittjosiah): Once we can compose translations outside of react, use count instead.
608
+ // ['deleted label', { ns: meta.id, typename: ['typename label', { ns: typename, count: objects.length }] }]
609
+ const undoMessageLabel: Label =
610
+ objects.length === 1
611
+ ? ['object deleted label', { ns: Obj.getTypename(objects[0]) ?? meta.id, defaultValue: 'Object deleted' }]
612
+ : ['objects deleted label', { ns: meta.id }];
606
613
 
607
614
  return {
608
615
  undoable: {
609
616
  // TODO(ZaymonFC): Pluralize if more than one object.
610
- message: [undoMessageKey, { ns: meta.id }],
617
+ message: undoMessageLabel,
611
618
  data: { deletionData },
612
619
  },
613
620
  intents:
@@ -628,16 +635,16 @@ export default ({ context, observability, createInvitationUrl }: IntentResolverO
628
635
  Obj.instanceOf(Collection.Collection, deletionData.parentCollection)
629
636
  ) {
630
637
  // Restore the object to the space.
631
- const restoredObjects = deletionData.objects.map((obj: Type.Expando) => space.db.add(obj));
638
+ const restoredObjects = deletionData.objects.map((obj: Obj.Any) => space.db.add(obj));
632
639
 
633
640
  // Restore nested objects to the space.
634
- deletionData.nestedObjectsList.flat().forEach((obj: Type.Expando) => {
641
+ deletionData.nestedObjectsList.flat().forEach((obj: Obj.Any) => {
635
642
  space.db.add(obj);
636
643
  });
637
644
 
638
645
  deletionData.indices.forEach((index: number, i: number) => {
639
646
  if (index !== -1) {
640
- deletionData.parentCollection.objects.splice(index, 0, Ref.make(restoredObjects[i] as Type.Expando));
647
+ deletionData.parentCollection.objects.splice(index, 0, Ref.make(restoredObjects[i] as Obj.Any));
641
648
  }
642
649
  });
643
650
 
@@ -695,16 +702,5 @@ export default ({ context, observability, createInvitationUrl }: IntentResolverO
695
702
  data: { object: Obj.make(Collection.Collection, { name, objects: [] }) },
696
703
  }),
697
704
  }),
698
- createResolver({
699
- intent: CollectionAction.CreateQueryCollection,
700
- resolve: async ({ name, typename }) => ({
701
- data: {
702
- object: Obj.make(Collection.QueryCollection, {
703
- name,
704
- query: Query.select(Filter.typename(typename)).ast,
705
- }),
706
- },
707
- }),
708
- }),
709
705
  ]);
710
706
  };
@@ -2,19 +2,20 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
+ import * as Option from 'effect/Option';
5
6
  import type * as Schema from 'effect/Schema';
6
7
  import React, { useCallback } from 'react';
7
8
 
8
9
  import { Capabilities, contributes, createSurface } from '@dxos/app-framework';
9
10
  import { Surface, useCapability, useLayout } from '@dxos/app-framework/react';
10
- import { Obj } from '@dxos/echo';
11
+ import { Obj, type Ref } from '@dxos/echo';
11
12
  import { findAnnotation } from '@dxos/effect';
12
13
  import { SettingsStore } from '@dxos/local-storage';
13
14
  import { type Space, SpaceState, getSpace, isLiveObject, isSpace, parseId, useSpace } from '@dxos/react-client/echo';
14
15
  import { Input } from '@dxos/react-ui';
15
16
  import { type InputProps, SelectInput } from '@dxos/react-ui-form';
16
17
  import { HuePicker, IconPicker } from '@dxos/react-ui-pickers';
17
- import { Collection, type TypenameAnnotation, TypenameAnnotationId, View } from '@dxos/schema';
18
+ import { Collection, View, ViewAnnotation } from '@dxos/schema';
18
19
  import { type JoinPanelProps } from '@dxos/shell/react';
19
20
 
20
21
  // TODO(burdon): Component name standard: NounVerbComponent.
@@ -48,7 +49,13 @@ import {
48
49
  } from '../components';
49
50
  import { useTypeOptions } from '../hooks';
50
51
  import { meta } from '../meta';
51
- import { HueAnnotationId, IconAnnotationId, type SpaceSettingsProps } from '../types';
52
+ import {
53
+ HueAnnotationId,
54
+ IconAnnotationId,
55
+ type SpaceSettingsProps,
56
+ type TypeInputOptions,
57
+ TypeInputOptionsAnnotationId,
58
+ } from '../types';
52
59
 
53
60
  import { SpaceCapabilities } from './capabilities';
54
61
 
@@ -224,20 +231,22 @@ export default ({ createInvitationUrl }: ReactSurfaceOptions) =>
224
231
  data,
225
232
  ): data is {
226
233
  prop: string;
227
- schema: Schema.Schema<any>;
234
+ schema: Schema.Schema.Any;
228
235
  target: Space | Collection.Collection | undefined;
229
236
  } => {
230
237
  if (data.prop !== 'typename') {
231
238
  return false;
232
239
  }
233
240
 
234
- const annotation = findAnnotation((data.schema as Schema.Schema.All).ast, TypenameAnnotationId);
241
+ // TODO(wittjosiah): This doesn't work here.
242
+ // const annotation = TypeInputOptionsAnnotation.get(data.schema as Schema.Schema.Any);
243
+ const annotation = findAnnotation((data.schema as Schema.Schema.All).ast, TypeInputOptionsAnnotationId);
235
244
  return !!annotation;
236
245
  },
237
246
  component: ({ data: { schema, target }, ...inputProps }) => {
238
247
  const props = inputProps as any as InputProps;
239
248
  const space = isSpace(target) ? target : getSpace(target);
240
- const annotation = findAnnotation<TypenameAnnotation[]>(schema.ast, TypenameAnnotationId)!;
249
+ const annotation = findAnnotation<TypeInputOptions>(schema.ast, TypeInputOptionsAnnotationId)!;
241
250
  const options = useTypeOptions({ space, annotation });
242
251
 
243
252
  return <SelectInput {...props} options={options} />;
@@ -246,8 +255,25 @@ export default ({ createInvitationUrl }: ReactSurfaceOptions) =>
246
255
  createSurface({
247
256
  id: `${meta.id}/object-settings`,
248
257
  role: 'object-settings',
249
- filter: (data): data is { subject: View.View } => Obj.instanceOf(View.View, data.subject),
250
- component: ({ data }) => <ViewEditor view={data.subject} />,
258
+ filter: (data): data is { subject: { view: Ref.Ref<View.View> } } => {
259
+ if (!Obj.isObject(data.subject)) {
260
+ return false;
261
+ }
262
+
263
+ const schema = Obj.getSchema(data.subject);
264
+ return Option.fromNullable(schema).pipe(
265
+ Option.flatMap((schema) => ViewAnnotation.get(schema)),
266
+ Option.getOrElse(() => false),
267
+ );
268
+ },
269
+ component: ({ data }) => {
270
+ const view = data.subject.view.target;
271
+ if (!view) {
272
+ return null;
273
+ }
274
+
275
+ return <ViewEditor view={view} />;
276
+ },
251
277
  }),
252
278
  createSurface({
253
279
  id: SPACE_RENAME_POPOVER,
@@ -0,0 +1,57 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { contributes } from '@dxos/app-framework';
6
+ import { Obj, Ref, Type } from '@dxos/echo';
7
+ import { type Space } from '@dxos/react-client/echo';
8
+ import { Collection } from '@dxos/schema';
9
+
10
+ import { SpaceCapabilities } from './capabilities';
11
+
12
+ export default () =>
13
+ contributes(SpaceCapabilities.Repair, async ({ space }) => {
14
+ await removeQueryCollections(space);
15
+ await ensureSystemCollection(space);
16
+ });
17
+
18
+ /**
19
+ * Remove all existing query collections from the root collection.
20
+ */
21
+ const removeQueryCollections = async (space: Space) => {
22
+ const rootCollection: Collection.Collection = await space.properties[Collection.Collection.typename]?.load();
23
+ if (!rootCollection) {
24
+ return;
25
+ }
26
+
27
+ const objects = await Promise.all(rootCollection.objects.map((ref) => ref.load()));
28
+ const queryCollections = objects.filter((object) => Obj.getTypename(object) === 'dxos.org/type/QueryCollection');
29
+ if (queryCollections.length === 0) {
30
+ return;
31
+ }
32
+
33
+ rootCollection.objects = objects
34
+ .filter((object) => Obj.getTypename(object) !== 'dxos.org/type/QueryCollection')
35
+ .map((object) => Ref.make(object));
36
+ queryCollections.forEach((object) => space.db.remove(object));
37
+ };
38
+
39
+ /**
40
+ * Ensure the root collection has a system collection for StoredSchema.
41
+ */
42
+ const ensureSystemCollection = async (space: Space) => {
43
+ const rootCollection: Collection.Collection = await space.properties[Collection.Collection.typename]?.load();
44
+ if (!rootCollection) {
45
+ return;
46
+ }
47
+
48
+ const objects = await Promise.all(rootCollection.objects.map((ref) => ref.load()));
49
+ const records = objects.find(
50
+ (object) => Obj.instanceOf(Collection.Managed, object) && object.key === Type.getTypename(Type.PersistentType),
51
+ );
52
+ if (records) {
53
+ return;
54
+ }
55
+
56
+ rootCollection.objects.push(Ref.make(Collection.makeManaged({ key: Type.getTypename(Type.PersistentType) })));
57
+ };
@@ -101,7 +101,13 @@ export default async (context: PluginContext) => {
101
101
  subscriptions.add(
102
102
  scheduledEffect(
103
103
  () => ({ name: space.properties.name }),
104
- ({ name }) => (state.spaceNames[space.id] = name),
104
+ ({ name }) => {
105
+ if (!name) {
106
+ delete state.spaceNames[space.id];
107
+ } else {
108
+ state.spaceNames[space.id] = name;
109
+ }
110
+ },
105
111
  ),
106
112
  );
107
113
  });
@@ -4,24 +4,24 @@
4
4
 
5
5
  import * as Effect from 'effect/Effect';
6
6
  import * as Function from 'effect/Function';
7
- import React, { useCallback, useRef, useState } from 'react';
7
+ import * as Option from 'effect/Option';
8
+ import React, { useCallback, useMemo, useRef, useState } from 'react';
8
9
 
9
10
  import { Capabilities, LayoutAction, chain, createIntent } from '@dxos/app-framework';
10
- import { useCapabilities, useIntentDispatcher, usePluginManager } from '@dxos/app-framework/react';
11
- import { Obj, Query, Type } from '@dxos/echo';
11
+ import { useIntentDispatcher, usePluginManager } from '@dxos/app-framework/react';
12
+ import { Obj, Type } from '@dxos/echo';
13
+ import { EntityKind, SystemTypeAnnotation, getTypeAnnotation } from '@dxos/echo/internal';
12
14
  import { invariant } from '@dxos/invariant';
13
15
  import { useClient } from '@dxos/react-client';
14
- import { type Space, getSpace, isLiveObject, isSpace, useQuery, useSpaces } from '@dxos/react-client/echo';
16
+ import { type Space, getSpace, isLiveObject, isSpace, useSpaces } from '@dxos/react-client/echo';
15
17
  import { Dialog, IconButton, useTranslation } from '@dxos/react-ui';
16
18
  import { cardDialogContent, cardDialogHeader } from '@dxos/react-ui-stack';
17
- import { Collection, StoredSchema, getTypenameFromQuery } from '@dxos/schema';
18
- import { isNonNullable } from '@dxos/util';
19
+ import { type Collection } from '@dxos/schema';
19
20
 
20
- import { SpaceCapabilities } from '../../capabilities';
21
21
  import { meta } from '../../meta';
22
22
  import { SpaceAction } from '../../types';
23
23
 
24
- import { CreateObjectPanel, type CreateObjectPanelProps } from './CreateObjectPanel';
24
+ import { CreateObjectPanel, type CreateObjectPanelProps, type Metadata } from './CreateObjectPanel';
25
25
 
26
26
  export const CREATE_OBJECT_DIALOG = `${meta.id}/CreateObjectDialog`;
27
27
 
@@ -44,26 +44,36 @@ export const CreateObjectDialog = ({
44
44
  const manager = usePluginManager();
45
45
  const { t } = useTranslation(meta.id);
46
46
  const { dispatch } = useIntentDispatcher();
47
- const forms = useCapabilities(SpaceCapabilities.ObjectForm);
48
47
  const [target, setTarget] = useState<Space | Collection.Collection | undefined>(initialTarget);
49
48
  const [typename, setTypename] = useState<string | undefined>(initialTypename);
50
49
  const client = useClient();
51
50
  const spaces = useSpaces();
52
- const space = isSpace(target) ? target : getSpace(target);
53
- const queryCollections = useQuery(space, Query.type(Collection.QueryCollection));
54
- const hiddenTypenames = queryCollections
55
- .map((collection) => getTypenameFromQuery(collection.query))
56
- .filter(isNonNullable);
57
51
  const closeRef = useRef<HTMLButtonElement | null>(null);
58
52
 
59
53
  const resolve = useCallback<NonNullable<CreateObjectPanelProps['resolve']>>(
60
- (typename) =>
61
- manager.context.getCapabilities(Capabilities.Metadata).find(({ id }) => id === typename)?.metadata ?? {},
54
+ (typename) => {
55
+ const metadata = manager.context
56
+ .getCapabilities(Capabilities.Metadata)
57
+ .find(({ id }) => id === typename)?.metadata;
58
+ return metadata?.createObjectIntent ? (metadata as Metadata) : undefined;
59
+ },
62
60
  [manager],
63
61
  );
64
62
 
63
+ const space = isSpace(target) ? target : getSpace(target);
64
+ // TODO(wittjosiah): Support database schemas.
65
+ const schemas = space?.db.schemaRegistry.query({ location: ['runtime'] }).runSync();
66
+ const userSchemas = useMemo(
67
+ () =>
68
+ schemas
69
+ ?.filter((schema) => getTypeAnnotation(schema)?.kind !== EntityKind.Relation)
70
+ .filter((schema) => !!resolve(Type.getTypename(schema)))
71
+ .filter((schema) => !SystemTypeAnnotation.get(schema).pipe(Option.getOrElse(() => false))) ?? [],
72
+ [schemas],
73
+ );
74
+
65
75
  const handleCreateObject = useCallback<NonNullable<CreateObjectPanelProps['onCreateObject']>>(
66
- ({ form, data = {} }) =>
76
+ ({ metadata, data = {} }) =>
67
77
  Effect.gen(function* () {
68
78
  if (!target) {
69
79
  // TODO(wittjosiah): UI feedback.
@@ -75,10 +85,10 @@ export const CreateObjectDialog = ({
75
85
 
76
86
  const space = isSpace(target) ? target : getSpace(target);
77
87
  invariant(space, 'Missing space');
78
- const { object } = yield* dispatch(form.getIntent(data, { space }));
79
- if (isLiveObject(object) && !Obj.instanceOf(StoredSchema, object)) {
88
+ const { object } = yield* dispatch(metadata.createObjectIntent(data, { space }));
89
+ if (isLiveObject(object) && !Obj.instanceOf(Type.PersistentType, object)) {
80
90
  // TODO(wittjosiah): Selection in navtree isn't working as expected when hidden typenames evals to true.
81
- const hidden = form.hidden || hiddenTypenames.includes(Type.getTypename(form.objectSchema));
91
+ const hidden = !metadata.addToCollectionOnCreate;
82
92
  const addObjectIntent = createIntent(SpaceAction.AddObject, {
83
93
  target,
84
94
  object,
@@ -94,7 +104,7 @@ export const CreateObjectDialog = ({
94
104
  onCreateObject?.(object);
95
105
  }
96
106
  }).pipe(Effect.runPromise),
97
- [dispatch, target, resolve, hiddenTypenames, _shouldNavigate],
107
+ [dispatch, target, resolve, _shouldNavigate],
98
108
  );
99
109
 
100
110
  return (
@@ -106,7 +116,7 @@ export const CreateObjectDialog = ({
106
116
  {t('create object dialog title', {
107
117
  object: t('typename label', {
108
118
  ns: typename,
109
- defaultValue: views ? 'View' : 'Item',
119
+ defaultValue: views ? 'View' : 'Object',
110
120
  }),
111
121
  })}
112
122
  </Dialog.Title>
@@ -125,7 +135,7 @@ export const CreateObjectDialog = ({
125
135
  </div>
126
136
 
127
137
  <CreateObjectPanel
128
- forms={forms}
138
+ schemas={userSchemas}
129
139
  spaces={spaces}
130
140
  target={target}
131
141
  views={views}
@@ -3,39 +3,46 @@
3
3
  //
4
4
 
5
5
  import * as Option from 'effect/Option';
6
+ import type * as Schema from 'effect/Schema';
6
7
  import React, { useCallback } from 'react';
7
8
 
8
- import { Type } from '@dxos/echo';
9
- import { type BaseObject, type TypeAnnotation, ViewAnnotation, getTypeAnnotation } from '@dxos/echo/internal';
9
+ import { type AnyProperties, type TypeAnnotation, getTypeAnnotation } from '@dxos/echo/internal';
10
10
  import { type Space, type SpaceId } from '@dxos/react-client/echo';
11
11
  import { Icon, toLocalizedString, useDefaultValue, useTranslation } from '@dxos/react-ui';
12
12
  import { Form } from '@dxos/react-ui-form';
13
13
  import { SearchList } from '@dxos/react-ui-searchlist';
14
14
  import { cardDialogOverflow, cardDialogPaddedOverflow, cardDialogSearchListRoot } from '@dxos/react-ui-stack';
15
- import { type Collection } from '@dxos/schema';
15
+ import { type Collection, ViewAnnotation } from '@dxos/schema';
16
16
  import { type MaybePromise, isNonNullable } from '@dxos/util';
17
17
 
18
18
  import { useInputSurfaceLookup } from '../../hooks';
19
19
  import { meta } from '../../meta';
20
- import { type ObjectForm } from '../../types';
20
+ import { type CreateObjectIntent } from '../../types';
21
21
  import { getSpaceDisplayName } from '../../util';
22
22
 
23
+ export type Metadata = {
24
+ createObjectIntent: CreateObjectIntent;
25
+ inputSchema?: Schema.Schema.AnyNoContext;
26
+ addToCollectionOnCreate?: boolean;
27
+ icon?: string;
28
+ };
29
+
23
30
  export type CreateObjectPanelProps = {
24
- forms: ObjectForm[];
31
+ schemas: Schema.Schema.AnyNoContext[];
25
32
  spaces: Space[];
26
33
  typename?: string;
27
34
  target?: Space | Collection.Collection;
28
35
  views?: boolean;
29
- initialFormValues?: Partial<BaseObject>;
36
+ initialFormValues?: Partial<AnyProperties>;
30
37
  defaultSpaceId?: SpaceId;
31
- resolve?: (typename: string) => Record<string, any>;
38
+ resolve?: (typename: string) => Metadata | undefined;
32
39
  onTargetChange?: (target: Space) => void;
33
40
  onTypenameChange?: (typename: string) => void;
34
- onCreateObject?: (params: { form: ObjectForm; data?: Record<string, any> }) => MaybePromise<void>;
41
+ onCreateObject?: (params: { metadata: Metadata; data?: Record<string, any> }) => MaybePromise<void>;
35
42
  };
36
43
 
37
44
  export const CreateObjectPanel = ({
38
- forms,
45
+ schemas,
39
46
  spaces,
40
47
  typename,
41
48
  target,
@@ -49,16 +56,16 @@ export const CreateObjectPanel = ({
49
56
  }: CreateObjectPanelProps) => {
50
57
  const { t } = useTranslation(meta.id);
51
58
  const initialFormValues = useDefaultValue(_initialFormValues, () => ({}));
52
- const form = forms.find((form) => Type.getTypename(form.objectSchema) === typename);
53
- const options: TypeAnnotation[] = forms
54
- .filter((form) => {
59
+ const metadata = typename && resolve?.(typename);
60
+ const options: TypeAnnotation[] = schemas
61
+ .filter((schema) => {
55
62
  if (views == null) {
56
63
  return true;
57
64
  } else {
58
- return views === ViewAnnotation.get(form.objectSchema).pipe(Option.getOrElse(() => false));
65
+ return views === ViewAnnotation.get(schema).pipe(Option.getOrElse(() => false));
59
66
  }
60
67
  })
61
- .map((form) => getTypeAnnotation(form.objectSchema))
68
+ .map((schema) => getTypeAnnotation(schema))
62
69
  .filter(isNonNullable)
63
70
  .sort((a, b) => {
64
71
  const nameA = t('typename label', { ns: a.typename, defaultValue: a.typename });
@@ -68,39 +75,39 @@ export const CreateObjectPanel = ({
68
75
 
69
76
  const handleCreateObject = useCallback(
70
77
  async (props: Record<string, any>) => {
71
- if (!form) {
78
+ if (!metadata) {
72
79
  return;
73
80
  }
74
- await onCreateObject?.({ form, data: props });
81
+ await onCreateObject?.({ metadata, data: props });
75
82
  },
76
- [onCreateObject, form],
83
+ [onCreateObject, metadata],
77
84
  );
78
85
 
79
86
  const handleSetTypename = useCallback(
80
87
  async (typename: string) => {
81
- const form = forms.find((form) => getTypeAnnotation(form.objectSchema)?.typename === typename);
82
- if (form && !form.formSchema) {
83
- await onCreateObject?.({ form });
88
+ const metadata = resolve?.(typename);
89
+ if (metadata && !metadata.inputSchema) {
90
+ await onCreateObject?.({ metadata });
84
91
  } else {
85
92
  onTypenameChange?.(typename);
86
93
  }
87
94
  },
88
- [forms, onCreateObject],
95
+ [resolve, onCreateObject],
89
96
  );
90
97
 
91
98
  const inputSurfaceLookup = useInputSurfaceLookup({ target });
92
99
 
93
100
  // TODO(wittjosiah): These inputs should be rolled into a `Form` once it supports the necessary variants.
94
- return !form ? (
101
+ return !metadata ? (
95
102
  <SelectSchema options={options} resolve={resolve} onChange={handleSetTypename} />
96
103
  ) : !target ? (
97
104
  <SelectSpace spaces={spaces} defaultSpaceId={defaultSpaceId} onChange={onTargetChange} />
98
- ) : form.formSchema ? (
105
+ ) : metadata.inputSchema ? (
99
106
  <div role='none' className={cardDialogOverflow}>
100
107
  <Form
101
108
  autoFocus
102
109
  values={initialFormValues}
103
- schema={form.formSchema}
110
+ schema={metadata.inputSchema}
104
111
  testId='create-object-form'
105
112
  onSave={handleCreateObject}
106
113
  lookupComponent={inputSurfaceLookup}
@@ -174,7 +181,7 @@ const SelectSchema = ({
174
181
  classNames='flex items-center gap-2'
175
182
  >
176
183
  <span className='flex gap-2 items-center grow truncate'>
177
- <Icon icon={resolve?.(option.typename).icon ?? 'ph--placeholder--regular'} size={5} />
184
+ <Icon icon={resolve?.(option.typename)?.icon ?? 'ph--placeholder--regular'} size={5} />
178
185
  {t('typename label', { ns: option.typename, defaultValue: option.typename })}
179
186
  </span>
180
187
  </SearchList.Item>
@@ -28,7 +28,7 @@ export const ObjectForm = ({ object, schema }: ObjectFormProps) => {
28
28
  );
29
29
 
30
30
  const meta = Obj.getMeta(object);
31
- const tags = (meta.tags ?? []).map((tag) => space?.db.ref(DXN.parse(tag))).filter(isNonNullable);
31
+ const tags = (meta.tags ?? []).map((tag) => space?.db.makeRef(DXN.parse(tag))).filter(isNonNullable);
32
32
  const values = useMemo(() => ({ tags, ...object }), [object, tags]);
33
33
 
34
34
  const handleCreateTag = useCallback((values: Schema.Schema.Type<typeof TagSchema>) => {
@@ -4,8 +4,7 @@
4
4
 
5
5
  import React, { useCallback, useState } from 'react';
6
6
 
7
- import { Obj } from '@dxos/echo';
8
- import { ForeignKey } from '@dxos/echo/internal';
7
+ import { Key, Obj } from '@dxos/echo';
9
8
  import { IconButton, useTranslation } from '@dxos/react-ui';
10
9
  import { Form } from '@dxos/react-ui-form';
11
10
 
@@ -30,7 +29,7 @@ export const AdvancedObjectSettings = ({ object }: AdvancedObjectSettingsProps)
30
29
  const handleNew = useCallback(() => setAdding(true), []);
31
30
  const handleCancel = useCallback(() => setAdding(false), []);
32
31
  const handleSave = useCallback(
33
- (key: ForeignKey) => {
32
+ (key: Key.ForeignKey) => {
34
33
  const index = keys.findIndex(({ source, id }) => source === key.source && id === key.id);
35
34
  if (index === -1) {
36
35
  keys.push(key);
@@ -40,7 +39,7 @@ export const AdvancedObjectSettings = ({ object }: AdvancedObjectSettingsProps)
40
39
  [keys],
41
40
  );
42
41
  const handleDelete = useCallback(
43
- (key: ForeignKey) => {
42
+ (key: Key.ForeignKey) => {
44
43
  const index = keys.findIndex(({ source, id }) => source === key.source && id === key.id);
45
44
  if (index !== -1) {
46
45
  keys.splice(index, 1);
@@ -70,7 +69,7 @@ export const AdvancedObjectSettings = ({ object }: AdvancedObjectSettingsProps)
70
69
  {adding && (
71
70
  <Form
72
71
  outerSpacing={false}
73
- schema={ForeignKey}
72
+ schema={Key.ForeignKey}
74
73
  values={initialValues}
75
74
  onSave={handleSave}
76
75
  onCancel={handleCancel}
@@ -47,7 +47,7 @@ export const BaseObjectSettings = ({ classNames, children, object }: BaseObjectS
47
47
  }, [object]);
48
48
 
49
49
  const meta = Obj.getMeta(object);
50
- const tags = (meta.tags ?? []).map((tag) => space?.db.ref(DXN.parse(tag))).filter(isNonNullable);
50
+ const tags = (meta.tags ?? []).map((tag) => space?.db.makeRef(DXN.parse(tag))).filter(isNonNullable);
51
51
  const values = useMemo(
52
52
  () => ({
53
53
  tags,
@@ -4,14 +4,14 @@
4
4
 
5
5
  import React, { useCallback } from 'react';
6
6
 
7
- import { type ForeignKey } from '@dxos/echo/internal';
7
+ import { type Key } from '@dxos/echo';
8
8
  import { IconButton, List, ListItem, useTranslation } from '@dxos/react-ui';
9
9
 
10
10
  import { meta } from '../../meta';
11
11
 
12
12
  export type ForeignKeysProps = {
13
- keys: ForeignKey[];
14
- onDelete?: (key: ForeignKey) => void;
13
+ keys: Key.ForeignKey[];
14
+ onDelete?: (key: Key.ForeignKey) => void;
15
15
  };
16
16
 
17
17
  // TODO(wittjosiah): This is a clone of `TokenManager`. Consider a form variant for arrays of read-only objects.
@@ -26,8 +26,8 @@ export const ForeignKeys = ({ keys, onDelete }: ForeignKeysProps) => {
26
26
  };
27
27
 
28
28
  type KeyItemProps = {
29
- forignKey: ForeignKey;
30
- onDelete?: (key: ForeignKey) => void;
29
+ forignKey: Key.ForeignKey;
30
+ onDelete?: (key: Key.ForeignKey) => void;
31
31
  };
32
32
 
33
33
  const KeyItem = ({ forignKey, onDelete }: KeyItemProps) => {