@dxos/plugin-space 0.7.5-main.9d26e3a → 0.7.5-main.e9bb01b

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 (211) hide show
  1. package/dist/lib/browser/app-graph-builder-J4NX44Y4.mjs +367 -0
  2. package/dist/lib/browser/app-graph-builder-J4NX44Y4.mjs.map +7 -0
  3. package/dist/lib/browser/app-graph-serializer-QF7VVRCV.mjs +80 -0
  4. package/dist/lib/browser/app-graph-serializer-QF7VVRCV.mjs.map +7 -0
  5. package/dist/lib/browser/chunk-6UIFMVVI.mjs +528 -0
  6. package/dist/lib/browser/chunk-6UIFMVVI.mjs.map +7 -0
  7. package/dist/lib/browser/chunk-PQXZCNAU.mjs +13 -0
  8. package/dist/lib/browser/chunk-PQXZCNAU.mjs.map +7 -0
  9. package/dist/lib/browser/chunk-RLZQJD47.mjs +22 -0
  10. package/dist/lib/browser/chunk-RLZQJD47.mjs.map +7 -0
  11. package/dist/lib/browser/chunk-SDK7RZI3.mjs +133 -0
  12. package/dist/lib/browser/chunk-SDK7RZI3.mjs.map +7 -0
  13. package/dist/lib/browser/{chunk-54VE4GTA.mjs → chunk-XPZ6IIXF.mjs} +11 -15
  14. package/dist/lib/browser/chunk-XPZ6IIXF.mjs.map +7 -0
  15. package/dist/lib/browser/chunk-XZ2NH3CP.mjs +1713 -0
  16. package/dist/lib/browser/chunk-XZ2NH3CP.mjs.map +7 -0
  17. package/dist/lib/browser/identity-created-25TK5XNO.mjs +28 -0
  18. package/dist/lib/browser/identity-created-25TK5XNO.mjs.map +7 -0
  19. package/dist/lib/browser/index.mjs +186 -3481
  20. package/dist/lib/browser/index.mjs.map +4 -4
  21. package/dist/lib/browser/intent-resolver-IEDVV74T.mjs +523 -0
  22. package/dist/lib/browser/intent-resolver-IEDVV74T.mjs.map +7 -0
  23. package/dist/lib/browser/meta.json +1 -1
  24. package/dist/lib/browser/react-root-6VRPRLQR.mjs +28 -0
  25. package/dist/lib/browser/react-root-6VRPRLQR.mjs.map +7 -0
  26. package/dist/lib/browser/react-surface-DMNDXLZ7.mjs +231 -0
  27. package/dist/lib/browser/react-surface-DMNDXLZ7.mjs.map +7 -0
  28. package/dist/lib/browser/settings-K4JPYYEM.mjs +24 -0
  29. package/dist/lib/browser/settings-K4JPYYEM.mjs.map +7 -0
  30. package/dist/lib/browser/spaces-ready-2MUWWVVO.mjs +199 -0
  31. package/dist/lib/browser/spaces-ready-2MUWWVVO.mjs.map +7 -0
  32. package/dist/lib/browser/state-6DCY5YJP.mjs +47 -0
  33. package/dist/lib/browser/state-6DCY5YJP.mjs.map +7 -0
  34. package/dist/lib/browser/types/index.mjs +6 -6
  35. package/dist/lib/node/app-graph-builder-ZOPG4MOS.cjs +370 -0
  36. package/dist/lib/node/app-graph-builder-ZOPG4MOS.cjs.map +7 -0
  37. package/dist/lib/node/app-graph-serializer-QE2G4MWB.cjs +88 -0
  38. package/dist/lib/node/app-graph-serializer-QE2G4MWB.cjs.map +7 -0
  39. package/dist/lib/node/chunk-3QWZCN6L.cjs +556 -0
  40. package/dist/lib/node/chunk-3QWZCN6L.cjs.map +7 -0
  41. package/dist/lib/node/{chunk-YF2AQ7KP.cjs → chunk-6MEOP3DH.cjs} +18 -22
  42. package/dist/lib/node/chunk-6MEOP3DH.cjs.map +7 -0
  43. package/dist/lib/node/chunk-D6BFKOXY.cjs +150 -0
  44. package/dist/lib/node/chunk-D6BFKOXY.cjs.map +7 -0
  45. package/dist/lib/node/chunk-SZEIQGQU.cjs +1710 -0
  46. package/dist/lib/node/chunk-SZEIQGQU.cjs.map +7 -0
  47. package/dist/lib/node/chunk-UX3U4RU2.cjs +42 -0
  48. package/dist/lib/node/chunk-UX3U4RU2.cjs.map +7 -0
  49. package/dist/lib/node/{chunk-46S3JOES.cjs → chunk-WZR6OAN3.cjs} +9 -12
  50. package/dist/lib/node/chunk-WZR6OAN3.cjs.map +7 -0
  51. package/dist/lib/node/identity-created-7G5U7R36.cjs +44 -0
  52. package/dist/lib/node/identity-created-7G5U7R36.cjs.map +7 -0
  53. package/dist/lib/node/index.cjs +171 -3469
  54. package/dist/lib/node/index.cjs.map +4 -4
  55. package/dist/lib/node/intent-resolver-N2W2L6OL.cjs +522 -0
  56. package/dist/lib/node/intent-resolver-N2W2L6OL.cjs.map +7 -0
  57. package/dist/lib/node/meta.json +1 -1
  58. package/dist/lib/node/react-root-YD35W3VU.cjs +50 -0
  59. package/dist/lib/node/react-root-YD35W3VU.cjs.map +7 -0
  60. package/dist/lib/node/react-surface-QPLXK7DT.cjs +229 -0
  61. package/dist/lib/node/react-surface-QPLXK7DT.cjs.map +7 -0
  62. package/dist/lib/node/{meta.cjs → settings-TEELGWS4.cjs} +19 -13
  63. package/dist/lib/node/settings-TEELGWS4.cjs.map +7 -0
  64. package/dist/lib/node/spaces-ready-PZZQWS6T.cjs +210 -0
  65. package/dist/lib/node/spaces-ready-PZZQWS6T.cjs.map +7 -0
  66. package/dist/lib/node/state-WPZC4JXB.cjs +61 -0
  67. package/dist/lib/node/state-WPZC4JXB.cjs.map +7 -0
  68. package/dist/lib/node/types/index.cjs +18 -18
  69. package/dist/lib/node/types/index.cjs.map +1 -1
  70. package/dist/lib/node-esm/app-graph-builder-TKGLOK22.mjs +368 -0
  71. package/dist/lib/node-esm/app-graph-builder-TKGLOK22.mjs.map +7 -0
  72. package/dist/lib/node-esm/app-graph-serializer-HLX2JRNF.mjs +81 -0
  73. package/dist/lib/node-esm/app-graph-serializer-HLX2JRNF.mjs.map +7 -0
  74. package/dist/lib/node-esm/chunk-4UX5WGKJ.mjs +134 -0
  75. package/dist/lib/node-esm/chunk-4UX5WGKJ.mjs.map +7 -0
  76. package/dist/lib/node-esm/{chunk-CDZETPO7.mjs → chunk-AAQRELDK.mjs} +11 -15
  77. package/dist/lib/node-esm/chunk-AAQRELDK.mjs.map +7 -0
  78. package/dist/lib/node-esm/{chunk-2MNFEB23.mjs → chunk-ICCM4YRJ.mjs} +5 -7
  79. package/dist/lib/node-esm/chunk-ICCM4YRJ.mjs.map +7 -0
  80. package/dist/lib/node-esm/chunk-LA45TPAN.mjs +529 -0
  81. package/dist/lib/node-esm/chunk-LA45TPAN.mjs.map +7 -0
  82. package/dist/lib/node-esm/chunk-LGL4A5B5.mjs +23 -0
  83. package/dist/lib/node-esm/chunk-LGL4A5B5.mjs.map +7 -0
  84. package/dist/lib/node-esm/chunk-N6EAOMIS.mjs +1714 -0
  85. package/dist/lib/node-esm/chunk-N6EAOMIS.mjs.map +7 -0
  86. package/dist/lib/node-esm/identity-created-7THGZ7EW.mjs +29 -0
  87. package/dist/lib/node-esm/identity-created-7THGZ7EW.mjs.map +7 -0
  88. package/dist/lib/node-esm/index.mjs +186 -3481
  89. package/dist/lib/node-esm/index.mjs.map +4 -4
  90. package/dist/lib/node-esm/intent-resolver-L2TKJU4I.mjs +524 -0
  91. package/dist/lib/node-esm/intent-resolver-L2TKJU4I.mjs.map +7 -0
  92. package/dist/lib/node-esm/meta.json +1 -1
  93. package/dist/lib/node-esm/react-root-Q5MFDXZE.mjs +29 -0
  94. package/dist/lib/node-esm/react-root-Q5MFDXZE.mjs.map +7 -0
  95. package/dist/lib/node-esm/react-surface-RQQZ5BOG.mjs +232 -0
  96. package/dist/lib/node-esm/react-surface-RQQZ5BOG.mjs.map +7 -0
  97. package/dist/lib/node-esm/settings-KXYUZBLN.mjs +25 -0
  98. package/dist/lib/node-esm/settings-KXYUZBLN.mjs.map +7 -0
  99. package/dist/lib/node-esm/spaces-ready-MWNP3WBX.mjs +200 -0
  100. package/dist/lib/node-esm/spaces-ready-MWNP3WBX.mjs.map +7 -0
  101. package/dist/lib/node-esm/state-5GH2D5U4.mjs +48 -0
  102. package/dist/lib/node-esm/state-5GH2D5U4.mjs.map +7 -0
  103. package/dist/lib/node-esm/types/index.mjs +6 -6
  104. package/dist/types/src/SpacePlugin.d.ts +1 -24
  105. package/dist/types/src/SpacePlugin.d.ts.map +1 -1
  106. package/dist/types/src/capabilities/app-graph-builder.d.ts +181 -0
  107. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
  108. package/dist/types/src/capabilities/app-graph-serializer.d.ts +4 -0
  109. package/dist/types/src/capabilities/app-graph-serializer.d.ts.map +1 -0
  110. package/dist/types/src/capabilities/capabilities.d.ts +21 -0
  111. package/dist/types/src/capabilities/capabilities.d.ts.map +1 -0
  112. package/dist/types/src/capabilities/identity-created.d.ts +4 -0
  113. package/dist/types/src/capabilities/identity-created.d.ts.map +1 -0
  114. package/dist/types/src/capabilities/index.d.ts +195 -0
  115. package/dist/types/src/capabilities/index.d.ts.map +1 -0
  116. package/dist/types/src/capabilities/intent-resolver.d.ts +8 -0
  117. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -0
  118. package/dist/types/src/capabilities/react-root.d.ts +7 -0
  119. package/dist/types/src/capabilities/react-root.d.ts.map +1 -0
  120. package/dist/types/src/capabilities/react-surface.d.ts +7 -0
  121. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
  122. package/dist/types/src/capabilities/settings.d.ts +4 -0
  123. package/dist/types/src/capabilities/settings.d.ts.map +1 -0
  124. package/dist/types/src/capabilities/spaces-ready.d.ts +4 -0
  125. package/dist/types/src/capabilities/spaces-ready.d.ts.map +1 -0
  126. package/dist/types/src/capabilities/state.d.ts +5 -0
  127. package/dist/types/src/capabilities/state.d.ts.map +1 -0
  128. package/dist/types/src/components/AdvancedObjectSettings/AdvancedObjectSettings.d.ts +7 -0
  129. package/dist/types/src/components/AdvancedObjectSettings/AdvancedObjectSettings.d.ts.map +1 -0
  130. package/dist/types/src/components/AdvancedObjectSettings/ForeignKeys.d.ts +8 -0
  131. package/dist/types/src/components/AdvancedObjectSettings/ForeignKeys.d.ts.map +1 -0
  132. package/dist/types/src/components/AdvancedObjectSettings/index.d.ts +2 -0
  133. package/dist/types/src/components/AdvancedObjectSettings/index.d.ts.map +1 -0
  134. package/dist/types/src/components/AwaitingObject.d.ts.map +1 -1
  135. package/dist/types/src/components/BaseObjectSettings.d.ts +7 -0
  136. package/dist/types/src/components/BaseObjectSettings.d.ts.map +1 -0
  137. package/dist/types/src/components/CreateDialog/CreateObjectDialog.d.ts +1 -2
  138. package/dist/types/src/components/CreateDialog/CreateObjectDialog.d.ts.map +1 -1
  139. package/dist/types/src/components/CreateDialog/CreateObjectPanel.d.ts +6 -6
  140. package/dist/types/src/components/CreateDialog/CreateObjectPanel.d.ts.map +1 -1
  141. package/dist/types/src/components/CreateDialog/CreateSpaceDialog.d.ts.map +1 -1
  142. package/dist/types/src/components/JoinDialog.d.ts.map +1 -1
  143. package/dist/types/src/components/SpacePluginSettings.d.ts.map +1 -1
  144. package/dist/types/src/components/SpacePresence.d.ts.map +1 -1
  145. package/dist/types/src/components/SpaceSettings/SpaceSettingsDialog.d.ts.map +1 -1
  146. package/dist/types/src/components/SpaceSettings/SpaceSettingsPanel.d.ts.map +1 -1
  147. package/dist/types/src/components/SyncStatus/SyncStatus.d.ts.map +1 -1
  148. package/dist/types/src/components/index.d.ts +2 -1
  149. package/dist/types/src/components/index.d.ts.map +1 -1
  150. package/dist/types/src/events.d.ts +5 -0
  151. package/dist/types/src/events.d.ts.map +1 -0
  152. package/dist/types/src/index.d.ts +3 -5
  153. package/dist/types/src/index.d.ts.map +1 -1
  154. package/dist/types/src/meta.d.ts +2 -4
  155. package/dist/types/src/meta.d.ts.map +1 -1
  156. package/dist/types/src/translations.d.ts +12 -0
  157. package/dist/types/src/translations.d.ts.map +1 -1
  158. package/dist/types/src/types/types.d.ts +7 -28
  159. package/dist/types/src/types/types.d.ts.map +1 -1
  160. package/dist/types/src/util.d.ts +7 -6
  161. package/dist/types/src/util.d.ts.map +1 -1
  162. package/dist/types/tsconfig.tsbuildinfo +1 -1
  163. package/package.json +38 -46
  164. package/src/SpacePlugin.tsx +114 -1412
  165. package/src/capabilities/app-graph-builder.ts +394 -0
  166. package/src/capabilities/app-graph-serializer.ts +73 -0
  167. package/src/capabilities/capabilities.ts +26 -0
  168. package/src/capabilities/identity-created.ts +26 -0
  169. package/src/capabilities/index.ts +17 -0
  170. package/src/capabilities/intent-resolver.ts +489 -0
  171. package/src/capabilities/react-root.tsx +20 -0
  172. package/src/capabilities/react-surface.tsx +226 -0
  173. package/src/capabilities/settings.ts +17 -0
  174. package/src/capabilities/spaces-ready.ts +230 -0
  175. package/src/capabilities/state.ts +45 -0
  176. package/src/components/AdvancedObjectSettings/AdvancedObjectSettings.tsx +72 -0
  177. package/src/components/AdvancedObjectSettings/ForeignKeys.tsx +51 -0
  178. package/src/components/AdvancedObjectSettings/index.ts +5 -0
  179. package/src/components/AwaitingObject.tsx +5 -11
  180. package/src/components/{DefaultObjectSettings.tsx → BaseObjectSettings.tsx} +2 -2
  181. package/src/components/CreateDialog/CreateObjectDialog.tsx +19 -19
  182. package/src/components/CreateDialog/CreateObjectPanel.tsx +136 -99
  183. package/src/components/CreateDialog/CreateSpaceDialog.tsx +10 -8
  184. package/src/components/JoinDialog.tsx +27 -19
  185. package/src/components/SpacePluginSettings.tsx +5 -10
  186. package/src/components/SpacePresence.tsx +7 -7
  187. package/src/components/SpaceSettings/SpaceSettingsDialog.tsx +16 -1
  188. package/src/components/SpaceSettings/SpaceSettingsPanel.tsx +3 -4
  189. package/src/components/SyncStatus/InlineSyncStatus.tsx +2 -2
  190. package/src/components/SyncStatus/SyncStatus.tsx +2 -1
  191. package/src/components/index.ts +2 -1
  192. package/src/events.ts +12 -0
  193. package/src/index.ts +3 -7
  194. package/src/meta.ts +2 -3
  195. package/src/translations.ts +4 -0
  196. package/src/types/types.ts +12 -51
  197. package/src/util.tsx +38 -28
  198. package/dist/lib/browser/chunk-54VE4GTA.mjs.map +0 -7
  199. package/dist/lib/browser/chunk-73BCBSLP.mjs +0 -15
  200. package/dist/lib/browser/chunk-73BCBSLP.mjs.map +0 -7
  201. package/dist/lib/browser/meta.mjs +0 -11
  202. package/dist/lib/browser/meta.mjs.map +0 -7
  203. package/dist/lib/node/chunk-46S3JOES.cjs.map +0 -7
  204. package/dist/lib/node/chunk-YF2AQ7KP.cjs.map +0 -7
  205. package/dist/lib/node/meta.cjs.map +0 -7
  206. package/dist/lib/node-esm/chunk-2MNFEB23.mjs.map +0 -7
  207. package/dist/lib/node-esm/chunk-CDZETPO7.mjs.map +0 -7
  208. package/dist/lib/node-esm/meta.mjs +0 -12
  209. package/dist/lib/node-esm/meta.mjs.map +0 -7
  210. package/dist/types/src/components/DefaultObjectSettings.d.ts +0 -7
  211. package/dist/types/src/components/DefaultObjectSettings.d.ts.map +0 -1
@@ -0,0 +1,489 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import {
6
+ Capabilities,
7
+ contributes,
8
+ createIntent,
9
+ createResolver,
10
+ LayoutAction,
11
+ type PluginsContext,
12
+ } from '@dxos/app-framework';
13
+ import { type Expando, getTypename, type HasId } from '@dxos/echo-schema';
14
+ import { invariant } from '@dxos/invariant';
15
+ import { create, makeRef, type ReactiveObject } from '@dxos/live-object';
16
+ import { Migrations } from '@dxos/migrations';
17
+ import { AttentionCapabilities } from '@dxos/plugin-attention';
18
+ import { ClientCapabilities } from '@dxos/plugin-client';
19
+ import { ObservabilityAction } from '@dxos/plugin-observability/types';
20
+ import { EdgeReplicationSetting } from '@dxos/protocols/proto/dxos/echo/metadata';
21
+ import { isSpace, getSpace, SpaceState, type Space, fullyQualifiedId, isEchoObject } from '@dxos/react-client/echo';
22
+
23
+ import { SpaceCapabilities } from './capabilities';
24
+ import {
25
+ CREATE_SPACE_DIALOG,
26
+ JOIN_DIALOG,
27
+ SPACE_SETTINGS_DIALOG,
28
+ type SpaceSettingsDialogProps,
29
+ type JoinDialogProps,
30
+ POPOVER_RENAME_SPACE,
31
+ CREATE_OBJECT_DIALOG,
32
+ type CreateObjectDialogProps,
33
+ POPOVER_RENAME_OBJECT,
34
+ } from '../components';
35
+ import { SPACE_PLUGIN } from '../meta';
36
+ import { CollectionAction, CollectionType, SpaceAction } from '../types';
37
+ import { cloneObject, COMPOSER_SPACE_LOCK, getNestedObjects } from '../util';
38
+
39
+ // TODO(wittjosiah): Remove.
40
+ const SPACE_MAX_OBJECTS = 500;
41
+
42
+ type IntentResolverOptions = {
43
+ createInvitationUrl: (invitationCode: string) => string;
44
+ context: PluginsContext;
45
+ };
46
+
47
+ export default ({ createInvitationUrl, context }: IntentResolverOptions) => {
48
+ const resolve = (typename: string) =>
49
+ context.requestCapabilities(Capabilities.Metadata).find(({ id }) => id === typename)?.metadata ?? {};
50
+
51
+ return contributes(Capabilities.IntentResolver, [
52
+ createResolver({
53
+ intent: SpaceAction.OpenCreateSpace,
54
+ resolve: () => ({
55
+ intents: [
56
+ createIntent(LayoutAction.UpdateDialog, {
57
+ part: 'dialog',
58
+ subject: CREATE_SPACE_DIALOG,
59
+ options: {
60
+ blockAlign: 'start',
61
+ },
62
+ }),
63
+ ],
64
+ }),
65
+ }),
66
+ createResolver({
67
+ intent: SpaceAction.Create,
68
+ resolve: async ({ name, edgeReplication }) => {
69
+ const client = context.requestCapability(ClientCapabilities.Client);
70
+ const space = await client.spaces.create({ name });
71
+ if (edgeReplication) {
72
+ await space.internal.setEdgeReplicationPreference(EdgeReplicationSetting.ENABLED);
73
+ }
74
+ await space.waitUntilReady();
75
+ const collection = create(CollectionType, { objects: [], views: {} });
76
+ space.properties[CollectionType.typename] = makeRef(collection);
77
+
78
+ if (Migrations.versionProperty) {
79
+ space.properties[Migrations.versionProperty] = Migrations.targetVersion;
80
+ }
81
+
82
+ return {
83
+ data: {
84
+ id: space.id,
85
+ subject: [space.id],
86
+ space,
87
+ },
88
+ intents: [
89
+ createIntent(ObservabilityAction.SendEvent, {
90
+ name: 'space.create',
91
+ properties: {
92
+ spaceId: space.id,
93
+ },
94
+ }),
95
+ ],
96
+ };
97
+ },
98
+ }),
99
+ createResolver({
100
+ intent: SpaceAction.Join,
101
+ resolve: ({ invitationCode }) => ({
102
+ intents: [
103
+ createIntent(LayoutAction.UpdateDialog, {
104
+ part: 'dialog',
105
+ subject: JOIN_DIALOG,
106
+ options: {
107
+ blockAlign: 'start',
108
+ props: {
109
+ initialInvitationCode: invitationCode,
110
+ } satisfies Partial<JoinDialogProps>,
111
+ },
112
+ }),
113
+ ],
114
+ }),
115
+ }),
116
+ createResolver({
117
+ intent: SpaceAction.Share,
118
+ filter: (data): data is { space: Space } => !data.space.properties[COMPOSER_SPACE_LOCK],
119
+ resolve: ({ space }) => {
120
+ const attention = context.requestCapability(AttentionCapabilities.Attention);
121
+ const current = attention.current.at(-1);
122
+ const target = current?.startsWith(space.id) ? current : undefined;
123
+
124
+ return {
125
+ intents: [
126
+ createIntent(LayoutAction.UpdateDialog, {
127
+ part: 'dialog',
128
+ subject: SPACE_SETTINGS_DIALOG,
129
+ options: {
130
+ blockAlign: 'start',
131
+ props: {
132
+ space,
133
+ target,
134
+ initialTab: 'members',
135
+ createInvitationUrl,
136
+ } satisfies Partial<SpaceSettingsDialogProps>,
137
+ },
138
+ }),
139
+ createIntent(ObservabilityAction.SendEvent, {
140
+ name: 'space.share',
141
+ properties: {
142
+ space: space.id,
143
+ },
144
+ }),
145
+ ],
146
+ };
147
+ },
148
+ }),
149
+ createResolver({
150
+ intent: SpaceAction.Lock,
151
+ resolve: ({ space }) => {
152
+ space.properties[COMPOSER_SPACE_LOCK] = true;
153
+ return {
154
+ intents: [
155
+ createIntent(ObservabilityAction.SendEvent, {
156
+ name: 'space.lock',
157
+ properties: {
158
+ spaceId: space.id,
159
+ },
160
+ }),
161
+ ],
162
+ };
163
+ },
164
+ }),
165
+ createResolver({
166
+ intent: SpaceAction.Unlock,
167
+ resolve: ({ space }) => {
168
+ space.properties[COMPOSER_SPACE_LOCK] = false;
169
+ return {
170
+ intents: [
171
+ createIntent(ObservabilityAction.SendEvent, {
172
+ name: 'space.unlock',
173
+ properties: {
174
+ spaceId: space.id,
175
+ },
176
+ }),
177
+ ],
178
+ };
179
+ },
180
+ }),
181
+ createResolver({
182
+ intent: SpaceAction.Rename,
183
+ resolve: ({ caller, space }) => {
184
+ return {
185
+ intents: [
186
+ createIntent(LayoutAction.UpdatePopover, {
187
+ part: 'popover',
188
+ subject: POPOVER_RENAME_SPACE,
189
+ options: {
190
+ anchorId: `dxos.org/ui/${caller}/${space.id}`,
191
+ props: space,
192
+ },
193
+ }),
194
+ ],
195
+ };
196
+ },
197
+ }),
198
+ createResolver({
199
+ intent: SpaceAction.OpenSettings,
200
+ resolve: ({ space }) => {
201
+ return {
202
+ intents: [
203
+ createIntent(LayoutAction.UpdateDialog, {
204
+ part: 'dialog',
205
+ subject: SPACE_SETTINGS_DIALOG,
206
+ options: {
207
+ blockAlign: 'start',
208
+ props: {
209
+ space,
210
+ initialTab: 'settings',
211
+ createInvitationUrl,
212
+ } satisfies Partial<SpaceSettingsDialogProps>,
213
+ },
214
+ }),
215
+ ],
216
+ };
217
+ },
218
+ }),
219
+ createResolver({
220
+ intent: SpaceAction.Open,
221
+ resolve: async ({ space }) => {
222
+ await space.open();
223
+ },
224
+ }),
225
+ createResolver({
226
+ intent: SpaceAction.Close,
227
+ resolve: async ({ space }) => {
228
+ await space.close();
229
+ },
230
+ }),
231
+ createResolver({
232
+ intent: SpaceAction.Migrate,
233
+ resolve: async ({ space, version }) => {
234
+ const state = context.requestCapability(SpaceCapabilities.MutableState);
235
+
236
+ if (space.state.get() === SpaceState.SPACE_REQUIRES_MIGRATION) {
237
+ state.sdkMigrationRunning[space.id] = true;
238
+ await space.internal.migrate();
239
+ state.sdkMigrationRunning[space.id] = false;
240
+ }
241
+ const result = await Migrations.migrate(space, version);
242
+ return {
243
+ data: result,
244
+ intents: [
245
+ createIntent(ObservabilityAction.SendEvent, {
246
+ name: 'space.migrate',
247
+ properties: {
248
+ spaceId: space.id,
249
+ version,
250
+ },
251
+ }),
252
+ ],
253
+ };
254
+ },
255
+ }),
256
+ createResolver({
257
+ intent: SpaceAction.OpenCreateObject,
258
+ resolve: ({ target, navigable = true }) => {
259
+ const state = context.requestCapability(SpaceCapabilities.State);
260
+
261
+ return {
262
+ intents: [
263
+ createIntent(LayoutAction.UpdateDialog, {
264
+ part: 'dialog',
265
+ subject: CREATE_OBJECT_DIALOG,
266
+ options: {
267
+ blockAlign: 'start',
268
+ props: {
269
+ target,
270
+ shouldNavigate: navigable
271
+ ? (object: ReactiveObject<any>) => !(object instanceof CollectionType) || state.navigableCollections
272
+ : () => false,
273
+ } satisfies Partial<CreateObjectDialogProps>,
274
+ },
275
+ }),
276
+ ],
277
+ };
278
+ },
279
+ }),
280
+ createResolver({
281
+ intent: SpaceAction.AddObject,
282
+ resolve: async ({ target, object }) => {
283
+ const space = isSpace(target) ? target : getSpace(target);
284
+ invariant(space, 'Space not found.');
285
+
286
+ if (space.db.coreDatabase.getAllObjectIds().length >= SPACE_MAX_OBJECTS) {
287
+ return {
288
+ error: new Error('Space limit reached.'),
289
+ intents: [
290
+ createIntent(LayoutAction.AddToast, {
291
+ part: 'toast',
292
+ subject: {
293
+ id: `${SPACE_PLUGIN}/space-limit`,
294
+ title: ['space limit label', { ns: SPACE_PLUGIN }],
295
+ description: ['space limit description', { ns: SPACE_PLUGIN }],
296
+ duration: 5_000,
297
+ icon: 'ph--warning--regular',
298
+ actionLabel: ['remove deleted objects label', { ns: SPACE_PLUGIN }],
299
+ actionAlt: ['remove deleted objects alt', { ns: SPACE_PLUGIN }],
300
+ closeLabel: ['close label', { ns: 'os' }],
301
+ onAction: () => space.db.coreDatabase.unlinkDeletedObjects(),
302
+ },
303
+ }),
304
+ createIntent(ObservabilityAction.SendEvent, {
305
+ name: 'space.limit',
306
+ properties: {
307
+ spaceId: space.id,
308
+ },
309
+ }),
310
+ ],
311
+ };
312
+ }
313
+
314
+ if (target instanceof CollectionType) {
315
+ target.objects.push(makeRef(object as HasId));
316
+ } else if (isSpace(target)) {
317
+ const collection = space.properties[CollectionType.typename]?.target;
318
+ if (collection instanceof CollectionType) {
319
+ collection.objects.push(makeRef(object as HasId));
320
+ } else {
321
+ // TODO(wittjosiah): Can't add non-echo objects by including in a collection because of types.
322
+ const collection = create(CollectionType, { objects: [makeRef(object as HasId)], views: {} });
323
+ space.properties[CollectionType.typename] = makeRef(collection);
324
+ }
325
+ }
326
+
327
+ return {
328
+ data: {
329
+ id: fullyQualifiedId(object),
330
+ subject: [fullyQualifiedId(object)],
331
+ object: object as HasId,
332
+ },
333
+ intents: [
334
+ createIntent(ObservabilityAction.SendEvent, {
335
+ name: 'space.object.add',
336
+ properties: {
337
+ spaceId: space.id,
338
+ objectId: object.id,
339
+ typename: getTypename(object),
340
+ },
341
+ }),
342
+ ],
343
+ };
344
+ },
345
+ }),
346
+ createResolver({
347
+ intent: SpaceAction.RemoveObjects,
348
+ resolve: async ({ objects, target, deletionData }, undo) => {
349
+ const layout = context.requestCapability(Capabilities.Layout);
350
+
351
+ // All objects must be a member of the same space.
352
+ const space = getSpace(objects[0]);
353
+ invariant(space && objects.every((obj) => isEchoObject(obj) && getSpace(obj) === space));
354
+ const openObjectIds = new Set<string>(layout.active);
355
+
356
+ if (!undo) {
357
+ const parentCollection: CollectionType = target ?? space.properties[CollectionType.typename]?.target;
358
+ const nestedObjectsList = await Promise.all(objects.map((obj) => getNestedObjects(obj, resolve)));
359
+
360
+ const deletionData = {
361
+ objects,
362
+ parentCollection,
363
+ indices: objects.map((obj) =>
364
+ parentCollection instanceof CollectionType
365
+ ? parentCollection.objects.findIndex((object) => object.target === obj)
366
+ : -1,
367
+ ),
368
+ nestedObjectsList,
369
+ wasActive: objects
370
+ .flatMap((obj, i) => [obj, ...nestedObjectsList[i]])
371
+ .map((obj) => fullyQualifiedId(obj))
372
+ .filter((id) => openObjectIds.has(id)),
373
+ } satisfies SpaceAction.DeletionData;
374
+
375
+ if (deletionData.parentCollection instanceof CollectionType) {
376
+ [...deletionData.indices]
377
+ .sort((a, b) => b - a)
378
+ .forEach((index: number) => {
379
+ if (index !== -1) {
380
+ deletionData.parentCollection.objects.splice(index, 1);
381
+ }
382
+ });
383
+ }
384
+
385
+ deletionData.nestedObjectsList.flat().forEach((obj) => {
386
+ space.db.remove(obj);
387
+ });
388
+ objects.forEach((obj) => space.db.remove(obj));
389
+
390
+ const undoMessageKey = objects.some((obj) => obj instanceof CollectionType)
391
+ ? 'collection deleted label'
392
+ : objects.length > 1
393
+ ? 'objects deleted label'
394
+ : 'object deleted label';
395
+
396
+ return {
397
+ undoable: {
398
+ // TODO(ZaymonFC): Pluralize if more than one object.
399
+ message: [undoMessageKey, { ns: SPACE_PLUGIN }],
400
+ data: { deletionData },
401
+ },
402
+ intents:
403
+ deletionData.wasActive.length > 0
404
+ ? [
405
+ createIntent(LayoutAction.Close, {
406
+ part: 'main',
407
+ subject: deletionData.wasActive,
408
+ options: { state: false },
409
+ }),
410
+ ]
411
+ : undefined,
412
+ };
413
+ } else {
414
+ if (
415
+ deletionData?.objects?.length &&
416
+ deletionData.objects.every(isEchoObject) &&
417
+ deletionData.parentCollection instanceof CollectionType
418
+ ) {
419
+ // Restore the object to the space.
420
+ const restoredObjects = deletionData.objects.map((obj: Expando) => space.db.add(obj));
421
+
422
+ // Restore nested objects to the space.
423
+ deletionData.nestedObjectsList.flat().forEach((obj: Expando) => {
424
+ space.db.add(obj);
425
+ });
426
+
427
+ deletionData.indices.forEach((index: number, i: number) => {
428
+ if (index !== -1) {
429
+ deletionData.parentCollection.objects.splice(index, 0, makeRef(restoredObjects[i] as Expando));
430
+ }
431
+ });
432
+
433
+ return {
434
+ intents:
435
+ deletionData.wasActive.length > 0
436
+ ? [
437
+ createIntent(LayoutAction.Open, {
438
+ part: 'main',
439
+ subject: deletionData.wasActive,
440
+ }),
441
+ ]
442
+ : undefined,
443
+ };
444
+ }
445
+ }
446
+ },
447
+ }),
448
+ createResolver({
449
+ intent: SpaceAction.RenameObject,
450
+ resolve: async ({ object, caller }) => ({
451
+ intents: [
452
+ createIntent(LayoutAction.UpdatePopover, {
453
+ part: 'popover',
454
+ subject: POPOVER_RENAME_OBJECT,
455
+ options: {
456
+ anchorId: `dxos.org/ui/${caller}/${fullyQualifiedId(object)}`,
457
+ props: object,
458
+ },
459
+ }),
460
+ ],
461
+ }),
462
+ }),
463
+ createResolver({
464
+ intent: SpaceAction.DuplicateObject,
465
+ resolve: async ({ object, target }) => {
466
+ const space = isSpace(target) ? target : getSpace(target);
467
+ invariant(space, 'Space not found.');
468
+
469
+ const newObject = await cloneObject(object, resolve, space);
470
+ return {
471
+ intents: [createIntent(SpaceAction.AddObject, { object: newObject, target })],
472
+ };
473
+ },
474
+ }),
475
+ createResolver({
476
+ intent: SpaceAction.WaitForObject,
477
+ resolve: async ({ id }) => {
478
+ const state = context.requestCapability(SpaceCapabilities.MutableState);
479
+ state.awaiting = id;
480
+ },
481
+ }),
482
+ createResolver({
483
+ intent: CollectionAction.Create,
484
+ resolve: async ({ name }) => ({
485
+ data: { object: create(CollectionType, { name, objects: [], views: {} }) },
486
+ }),
487
+ }),
488
+ ]);
489
+ };
@@ -0,0 +1,20 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import React from 'react';
6
+
7
+ import { Capabilities, contributes, useCapability } from '@dxos/app-framework';
8
+
9
+ import { SpaceCapabilities } from './capabilities';
10
+ import { AwaitingObject } from '../components';
11
+ import { SPACE_PLUGIN } from '../meta';
12
+
13
+ export default () =>
14
+ contributes(Capabilities.ReactRoot, {
15
+ id: SPACE_PLUGIN,
16
+ root: () => {
17
+ const state = useCapability(SpaceCapabilities.State);
18
+ return state.awaiting ? <AwaitingObject id={state.awaiting} /> : null;
19
+ },
20
+ });