@dxos/plugin-space 0.7.2 → 0.7.3-main.2dd075e

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 (95) hide show
  1. package/dist/lib/browser/{chunk-DJE2HYFV.mjs → chunk-FTKV32QZ.mjs} +9 -2
  2. package/dist/lib/browser/chunk-FTKV32QZ.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-OWZKSWMX.mjs → chunk-MWKXNS5S.mjs} +13 -3
  4. package/dist/lib/browser/{chunk-OWZKSWMX.mjs.map → chunk-MWKXNS5S.mjs.map} +3 -3
  5. package/dist/lib/browser/index.mjs +1056 -674
  6. package/dist/lib/browser/index.mjs.map +4 -4
  7. package/dist/lib/browser/meta.json +1 -1
  8. package/dist/lib/browser/meta.mjs +3 -1
  9. package/dist/lib/browser/types/index.mjs +5 -3
  10. package/dist/lib/node/{chunk-FYWGZYJB.cjs → chunk-6SNOZF7Y.cjs} +18 -7
  11. package/dist/lib/node/chunk-6SNOZF7Y.cjs.map +7 -0
  12. package/dist/lib/node/{chunk-JFDDZI4Y.cjs → chunk-QNVEU2UD.cjs} +12 -4
  13. package/dist/lib/node/chunk-QNVEU2UD.cjs.map +7 -0
  14. package/dist/lib/node/index.cjs +1160 -789
  15. package/dist/lib/node/index.cjs.map +4 -4
  16. package/dist/lib/node/meta.cjs +7 -5
  17. package/dist/lib/node/meta.cjs.map +2 -2
  18. package/dist/lib/node/meta.json +1 -1
  19. package/dist/lib/node/types/index.cjs +14 -12
  20. package/dist/lib/node/types/index.cjs.map +2 -2
  21. package/dist/lib/node-esm/{chunk-MCEAI4CV.mjs → chunk-OHEAWSCA.mjs} +13 -3
  22. package/dist/lib/node-esm/{chunk-MCEAI4CV.mjs.map → chunk-OHEAWSCA.mjs.map} +3 -3
  23. package/dist/lib/node-esm/{chunk-DVUZ7A7G.mjs → chunk-UMV7XREB.mjs} +9 -2
  24. package/dist/lib/node-esm/chunk-UMV7XREB.mjs.map +7 -0
  25. package/dist/lib/node-esm/index.mjs +1056 -674
  26. package/dist/lib/node-esm/index.mjs.map +4 -4
  27. package/dist/lib/node-esm/meta.json +1 -1
  28. package/dist/lib/node-esm/meta.mjs +3 -1
  29. package/dist/lib/node-esm/types/index.mjs +5 -3
  30. package/dist/types/src/SpacePlugin.d.ts.map +1 -1
  31. package/dist/types/src/components/CreateDialog/CreateObjectDialog.d.ts +9 -0
  32. package/dist/types/src/components/CreateDialog/CreateObjectDialog.d.ts.map +1 -0
  33. package/dist/types/src/components/CreateDialog/CreateObjectDialog.stories.d.ts +10 -0
  34. package/dist/types/src/components/CreateDialog/CreateObjectDialog.stories.d.ts.map +1 -0
  35. package/dist/types/src/components/CreateDialog/CreateObjectPanel.d.ts +22 -0
  36. package/dist/types/src/components/CreateDialog/CreateObjectPanel.d.ts.map +1 -0
  37. package/dist/types/src/components/CreateDialog/CreateSpaceDialog.d.ts +3 -0
  38. package/dist/types/src/components/CreateDialog/CreateSpaceDialog.d.ts.map +1 -0
  39. package/dist/types/src/components/CreateDialog/index.d.ts +3 -0
  40. package/dist/types/src/components/CreateDialog/index.d.ts.map +1 -0
  41. package/dist/types/src/components/PopoverRenameObject.d.ts +1 -1
  42. package/dist/types/src/components/SpacePluginSettings.d.ts.map +1 -1
  43. package/dist/types/src/components/SpaceSettings/SpaceSettingsPanel.d.ts.map +1 -1
  44. package/dist/types/src/components/SyncStatus/InlineSyncStatus.d.ts +6 -0
  45. package/dist/types/src/components/SyncStatus/InlineSyncStatus.d.ts.map +1 -0
  46. package/dist/types/src/components/SyncStatus/Space.d.ts +8 -3
  47. package/dist/types/src/components/SyncStatus/Space.d.ts.map +1 -1
  48. package/dist/types/src/components/SyncStatus/SyncStatus.d.ts +3 -2
  49. package/dist/types/src/components/SyncStatus/SyncStatus.d.ts.map +1 -1
  50. package/dist/types/src/components/SyncStatus/SyncStatus.stories.d.ts +1 -2
  51. package/dist/types/src/components/SyncStatus/SyncStatus.stories.d.ts.map +1 -1
  52. package/dist/types/src/components/SyncStatus/SyncStatusDetail.stories.d.ts +8 -0
  53. package/dist/types/src/components/SyncStatus/SyncStatusDetail.stories.d.ts.map +1 -0
  54. package/dist/types/src/components/SyncStatus/index.d.ts +1 -0
  55. package/dist/types/src/components/SyncStatus/index.d.ts.map +1 -1
  56. package/dist/types/src/components/SyncStatus/sync-state.d.ts +5 -1
  57. package/dist/types/src/components/SyncStatus/sync-state.d.ts.map +1 -1
  58. package/dist/types/src/components/index.d.ts +1 -0
  59. package/dist/types/src/components/index.d.ts.map +1 -1
  60. package/dist/types/src/meta.d.ts +5 -0
  61. package/dist/types/src/meta.d.ts.map +1 -1
  62. package/dist/types/src/translations.d.ts +224 -0
  63. package/dist/types/src/translations.d.ts.map +1 -1
  64. package/dist/types/src/types/types.d.ts +14 -14
  65. package/dist/types/src/types/types.d.ts.map +1 -1
  66. package/dist/types/src/util.d.ts +3 -13
  67. package/dist/types/src/util.d.ts.map +1 -1
  68. package/package.json +38 -35
  69. package/src/SpacePlugin.tsx +169 -75
  70. package/src/components/AwaitingObject.tsx +2 -2
  71. package/src/components/CreateDialog/CreateObjectDialog.stories.tsx +83 -0
  72. package/src/components/CreateDialog/CreateObjectDialog.tsx +97 -0
  73. package/src/components/CreateDialog/CreateObjectPanel.tsx +169 -0
  74. package/src/components/CreateDialog/CreateSpaceDialog.tsx +57 -0
  75. package/src/components/CreateDialog/index.ts +6 -0
  76. package/src/components/PopoverRenameObject.tsx +1 -1
  77. package/src/components/SpacePluginSettings.tsx +3 -32
  78. package/src/components/SpaceSettings/SpaceSettingsDialog.tsx +1 -1
  79. package/src/components/SpaceSettings/SpaceSettingsPanel.tsx +2 -6
  80. package/src/components/SyncStatus/InlineSyncStatus.tsx +45 -0
  81. package/src/components/SyncStatus/Space.tsx +30 -6
  82. package/src/components/SyncStatus/SyncStatus.stories.tsx +3 -32
  83. package/src/components/SyncStatus/SyncStatus.tsx +32 -14
  84. package/src/components/SyncStatus/SyncStatusDetail.stories.tsx +83 -0
  85. package/src/components/SyncStatus/index.ts +1 -0
  86. package/src/components/SyncStatus/sync-state.ts +24 -0
  87. package/src/components/index.ts +1 -0
  88. package/src/meta.ts +6 -0
  89. package/src/translations.ts +15 -0
  90. package/src/types/types.ts +20 -16
  91. package/src/util.tsx +51 -141
  92. package/dist/lib/browser/chunk-DJE2HYFV.mjs.map +0 -7
  93. package/dist/lib/node/chunk-FYWGZYJB.cjs.map +0 -7
  94. package/dist/lib/node/chunk-JFDDZI4Y.cjs.map +0 -7
  95. package/dist/lib/node-esm/chunk-DVUZ7A7G.mjs.map +0 -7
@@ -1,10 +1,11 @@
1
1
  import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
2
  import {
3
+ CollectionAction,
3
4
  SPACE_PLUGIN,
4
5
  SPACE_PLUGIN_SHORT_ID,
5
6
  SpaceAction,
6
7
  meta_default
7
- } from "./chunk-DVUZ7A7G.mjs";
8
+ } from "./chunk-UMV7XREB.mjs";
8
9
  import {
9
10
  ActorSchema,
10
11
  ChannelType,
@@ -13,19 +14,21 @@ import {
13
14
  MessageState,
14
15
  MessageType,
15
16
  SPACE_DIRECTORY_HANDLE,
17
+ SpaceForm,
16
18
  ThreadStatus,
17
19
  ThreadType,
18
- parseSpaceInitPlugin
19
- } from "./chunk-MCEAI4CV.mjs";
20
+ parseSchemaPlugin
21
+ } from "./chunk-OHEAWSCA.mjs";
20
22
 
21
23
  // packages/plugins/plugin-space/src/SpacePlugin.tsx
22
24
  import { signal } from "@preact/signals-core";
23
- import React17 from "react";
24
- import { LayoutAction as LayoutAction2, NavigationAction as NavigationAction4, Surface, findPlugin, firstIdInPart, openIds, parseGraphPlugin, parseIntentPlugin as parseIntentPlugin2, parseLayoutPlugin, parseMetadataResolverPlugin, parseNavigationPlugin as parseNavigationPlugin2, resolvePlugin } from "@dxos/app-framework";
25
+ import React21 from "react";
26
+ import { LayoutAction as LayoutAction2, NavigationAction as NavigationAction4, Surface, filterPlugins, findPlugin, firstIdInPart, openIds, parseGraphPlugin, parseIntentPlugin as parseIntentPlugin2, parseLayoutPlugin, parseMetadataResolverPlugin, parseNavigationPlugin as parseNavigationPlugin2, resolvePlugin } from "@dxos/app-framework";
25
27
  import { EventSubscriptions } from "@dxos/async";
26
- import { isDeleted, isReactiveObject as isReactiveObject2 } from "@dxos/echo-schema";
28
+ import { S as S2 } from "@dxos/echo-schema";
27
29
  import { scheduledEffect } from "@dxos/echo-signals/core";
28
30
  import { invariant as invariant2 } from "@dxos/invariant";
31
+ import { create, isDeleted, isReactiveObject as isReactiveObject3 } from "@dxos/live-object";
29
32
  import { LocalStorageStore } from "@dxos/local-storage";
30
33
  import { log as log3 } from "@dxos/log";
31
34
  import { Migrations as Migrations2 } from "@dxos/migrations";
@@ -33,17 +36,18 @@ import { parseAttentionPlugin } from "@dxos/plugin-attention";
33
36
  import { parseClientPlugin } from "@dxos/plugin-client";
34
37
  import { createExtension, memoize as memoize2, toSignal } from "@dxos/plugin-graph";
35
38
  import { ObservabilityAction as ObservabilityAction2 } from "@dxos/plugin-observability/meta";
39
+ import { EdgeReplicationSetting as EdgeReplicationSetting3 } from "@dxos/protocols/proto/dxos/echo/metadata";
36
40
  import { PublicKey as PublicKey2 } from "@dxos/react-client";
37
- import { Expando, Filter, SpaceState as SpaceState2, create as create2, fullyQualifiedId as fullyQualifiedId4, getSpace as getSpace4, getTypename as getTypename2, isEchoObject as isEchoObject2, isSpace as isSpace2, loadObjectReferences, parseId, FQ_ID_LENGTH, SPACE_ID_LENGTH, OBJECT_ID_LENGTH } from "@dxos/react-client/echo";
41
+ import { Expando, FQ_ID_LENGTH, Filter as Filter3, OBJECT_ID_LENGTH, SPACE_ID_LENGTH, SpaceState as SpaceState2, fullyQualifiedId as fullyQualifiedId4, getSpace as getSpace4, getTypename as getTypename2, isEchoObject as isEchoObject2, isSpace as isSpace4, loadObjectReferences, parseFullyQualifiedId, parseId } from "@dxos/react-client/echo";
38
42
  import { osTranslations } from "@dxos/shell/react";
39
- import { ComplexMap as ComplexMap2, nonNullable, reduceGroupBy } from "@dxos/util";
43
+ import { ComplexMap as ComplexMap2, nonNullable as nonNullable2, reduceGroupBy } from "@dxos/util";
40
44
 
41
45
  // packages/plugins/plugin-space/src/components/AwaitingObject.tsx
42
46
  import { CheckCircle, CircleDashed, CircleNotch } from "@phosphor-icons/react";
43
47
  import React, { useEffect, useState } from "react";
44
48
  import { parseIntentPlugin, useResolvePlugin, parseNavigationPlugin, NavigationAction } from "@dxos/app-framework";
45
49
  import { useClient } from "@dxos/react-client";
46
- import { fullyQualifiedId, useQuery } from "@dxos/react-client/echo";
50
+ import { Filter, fullyQualifiedId, useQuery } from "@dxos/react-client/echo";
47
51
  import { Button, Toast, useTranslation } from "@dxos/react-ui";
48
52
  import { getSize, mx } from "@dxos/react-ui-theme";
49
53
  var WAIT_FOR_OBJECT_TIMEOUT = 18e4;
@@ -56,7 +60,7 @@ var AwaitingObject = ({ id }) => {
56
60
  const intentPlugin = useResolvePlugin(parseIntentPlugin);
57
61
  const navigationPlugin = useResolvePlugin(parseNavigationPlugin);
58
62
  const client = useClient();
59
- const objects = useQuery(client.spaces);
63
+ const objects = useQuery(client.spaces, Filter.all());
60
64
  useEffect(() => {
61
65
  if (!id) {
62
66
  return;
@@ -133,155 +137,29 @@ var AwaitingObject = ({ id }) => {
133
137
  })))));
134
138
  };
135
139
 
136
- // packages/plugins/plugin-space/src/components/CollectionMain.tsx
137
- import React2 from "react";
138
- import { useTranslation as useTranslation2 } from "@dxos/react-ui";
139
- import { baseSurface, descriptionText, mx as mx2 } from "@dxos/react-ui-theme";
140
- var CollectionMain = ({ collection }) => {
141
- const { t } = useTranslation2(SPACE_PLUGIN);
142
- return /* @__PURE__ */ React2.createElement("div", {
143
- role: "none",
144
- className: mx2(baseSurface, "min-bs-screen is-full flex items-center justify-center p-8"),
145
- "data-testid": "composer.firstRunMessage"
146
- }, /* @__PURE__ */ React2.createElement("p", {
147
- role: "alert",
148
- className: mx2(descriptionText, "border border-dashed border-neutral-400/50 rounded-lg p-8 font-normal text-lg max-is-[24rem] break-words")
149
- }, collection.name ?? t("unnamed collection label")));
150
- };
151
-
152
- // packages/plugins/plugin-space/src/components/CollectionSection.tsx
153
- import React3 from "react";
154
- import { useTranslation as useTranslation3 } from "@dxos/react-ui";
155
- var CollectionSection = ({ collection }) => {
156
- const { t } = useTranslation3(SPACE_PLUGIN);
157
- return /* @__PURE__ */ React3.createElement("div", {
158
- className: "min-bs-[3.5rem] grid grid-rows-subgrid grid-cols-subgrid items-center"
159
- }, /* @__PURE__ */ React3.createElement("span", {
160
- className: "truncate"
161
- }, collection.name ?? t("unnamed collection label")));
162
- };
163
-
164
- // packages/plugins/plugin-space/src/components/DefaultObjectSettings.tsx
165
- import React4 from "react";
166
- import { Input, useTranslation as useTranslation4 } from "@dxos/react-ui";
167
- var DefaultObjectSettings = ({ object }) => {
168
- const { t } = useTranslation4(SPACE_PLUGIN);
169
- return /* @__PURE__ */ React4.createElement("div", {
170
- role: "form",
171
- className: "flex flex-col w-full p-2 gap-1"
172
- }, /* @__PURE__ */ React4.createElement(Input.Root, null, /* @__PURE__ */ React4.createElement(Input.Label, null, t("name label")), /* @__PURE__ */ React4.createElement(Input.TextInput, {
173
- placeholder: t("name placeholder"),
174
- value: object.name ?? "",
175
- onChange: (event) => {
176
- object.name = event.target.value;
177
- }
178
- })));
179
- };
180
-
181
- // packages/plugins/plugin-space/src/components/JoinDialog.tsx
182
- import React5, { useCallback } from "react";
183
- import { LayoutAction, NavigationAction as NavigationAction2, useIntentDispatcher } from "@dxos/app-framework";
184
- import { useGraph } from "@dxos/plugin-graph";
185
- import { ObservabilityAction } from "@dxos/plugin-observability/meta";
186
- import { useSpaces } from "@dxos/react-client/echo";
187
- import { Dialog, useTranslation as useTranslation5 } from "@dxos/react-ui";
188
- import { JoinPanel } from "@dxos/shell/react";
189
- var JoinDialog = ({ navigableCollections, ...props }) => {
190
- const { t } = useTranslation5(SPACE_PLUGIN);
191
- const dispatch = useIntentDispatcher();
192
- const spaces = useSpaces();
193
- const { graph } = useGraph();
194
- const handleDone = useCallback(async (result) => {
195
- if (result?.spaceKey) {
196
- await Promise.all([
197
- dispatch({
198
- action: LayoutAction.SET_LAYOUT,
199
- data: {
200
- element: "toast",
201
- subject: {
202
- id: `${SPACE_PLUGIN}/join-success`,
203
- duration: 5e3,
204
- title: t("join success label"),
205
- closeLabel: t("dismiss label")
206
- }
207
- }
208
- }),
209
- dispatch({
210
- action: LayoutAction.SET_LAYOUT,
211
- data: {
212
- element: "dialog",
213
- state: false
214
- }
215
- })
216
- ]);
217
- }
218
- const space = spaces.find(({ key }) => result?.spaceKey?.equals(key));
219
- const target = result?.target || (navigableCollections ? space?.id : void 0);
220
- if (target) {
221
- await graph.waitForPath({
222
- target
223
- }).catch(() => {
224
- });
225
- await Promise.all([
226
- dispatch({
227
- action: NavigationAction2.OPEN,
228
- data: {
229
- activeParts: {
230
- main: [
231
- target
232
- ]
233
- }
234
- }
235
- }),
236
- dispatch({
237
- action: NavigationAction2.EXPOSE,
238
- data: {
239
- id: target
240
- }
241
- })
242
- ]);
243
- }
244
- if (space) {
245
- await dispatch({
246
- action: ObservabilityAction.SEND_EVENT,
247
- data: {
248
- name: "space.join",
249
- properties: {
250
- spaceId: space.id
251
- }
252
- }
253
- });
254
- }
255
- }, [
256
- dispatch,
257
- spaces
258
- ]);
259
- return /* @__PURE__ */ React5.createElement(Dialog.Content, null, /* @__PURE__ */ React5.createElement(JoinPanel, {
260
- ...props,
261
- exitActionParent: /* @__PURE__ */ React5.createElement(Dialog.Close, {
262
- asChild: true
263
- }),
264
- doneActionParent: /* @__PURE__ */ React5.createElement(Dialog.Close, {
265
- asChild: true
266
- }),
267
- onDone: handleDone
268
- }));
269
- };
270
-
271
- // packages/plugins/plugin-space/src/components/MenuFooter.tsx
272
- import { Planet } from "@phosphor-icons/react";
273
- import React6 from "react";
274
- import { getSpace as getSpace2 } from "@dxos/client/echo";
140
+ // packages/plugins/plugin-space/src/components/CreateDialog/CreateObjectDialog.tsx
141
+ import React3, { useCallback as useCallback2, useRef } from "react";
142
+ import { NavigationAction as NavigationAction2, useIntentDispatcher } from "@dxos/app-framework";
275
143
  import { useClient as useClient2 } from "@dxos/react-client";
276
- import { DropdownMenu, toLocalizedString, useTranslation as useTranslation6 } from "@dxos/react-ui";
144
+ import { isReactiveObject as isReactiveObject2, isSpace as isSpace3, useSpaces } from "@dxos/react-client/echo";
145
+ import { Button as Button2, Dialog, Icon as Icon2, useTranslation as useTranslation3 } from "@dxos/react-ui";
146
+
147
+ // packages/plugins/plugin-space/src/components/CreateDialog/CreateObjectPanel.tsx
148
+ import React2, { useCallback, useState as useState2 } from "react";
149
+ import { getObjectAnnotation as getObjectAnnotation2, S } from "@dxos/echo-schema";
150
+ import { isSpace as isSpace2 } from "@dxos/react-client/echo";
151
+ import { Icon, IconButton, Input, toLocalizedString, useTranslation as useTranslation2 } from "@dxos/react-ui";
152
+ import { Form, InputHeader } from "@dxos/react-ui-form";
153
+ import { SearchList } from "@dxos/react-ui-searchlist";
154
+ import { nonNullable } from "@dxos/util";
277
155
 
278
156
  // packages/plugins/plugin-space/src/util.tsx
279
- import { NavigationAction as NavigationAction3 } from "@dxos/app-framework";
280
- import { create, isReactiveObject, getTypename, getSchema, getObjectAnnotation, EXPANDO_TYPENAME } from "@dxos/echo-schema";
157
+ import { EXPANDO_TYPENAME, getObjectAnnotation, getTypename } from "@dxos/echo-schema";
281
158
  import { invariant } from "@dxos/invariant";
159
+ import { getSchema, isReactiveObject } from "@dxos/live-object";
282
160
  import { Migrations } from "@dxos/migrations";
283
- import { ACTION_TYPE, ACTION_GROUP_TYPE, actionGroupSymbol, getGraph, cleanup, memoize } from "@dxos/plugin-graph";
284
- import { fullyQualifiedId as fullyQualifiedId2, getSpace, isEchoObject, isSpace, SpaceState } from "@dxos/react-client/echo";
161
+ import { ACTION_GROUP_TYPE, ACTION_TYPE, cleanup, getGraph, memoize } from "@dxos/plugin-graph";
162
+ import { Filter as Filter2, fullyQualifiedId as fullyQualifiedId2, getSpace, isEchoObject, isSpace, SpaceState } from "@dxos/react-client/echo";
285
163
  var __dxlog_file = "/home/runner/work/dxos/dxos/packages/plugins/plugin-space/src/util.tsx";
286
164
  var SPACES = `${SPACE_PLUGIN}-spaces`;
287
165
  var SPACE_TYPE = "dxos.org/type/Space";
@@ -289,7 +167,10 @@ var COMPOSER_SPACE_LOCK = "dxos.org/plugin/space/lock";
289
167
  var SHARED = "shared-spaces";
290
168
  var EMPTY_ARRAY = [];
291
169
  var memoizeQuery = (spaceOrEcho, filter, options) => {
292
- const key = isSpace(spaceOrEcho) ? spaceOrEcho.id : void 0;
170
+ const key = JSON.stringify({
171
+ space: isSpace(spaceOrEcho) ? spaceOrEcho.id : void 0,
172
+ filter: Filter2.from(filter).toProto()
173
+ });
293
174
  const query = memoize(() => isSpace(spaceOrEcho) ? spaceOrEcho.db.query(filter, options) : spaceOrEcho?.query(filter, options), key);
294
175
  const unsubscribe = memoize(() => query?.subscribe(), key);
295
176
  cleanup(() => unsubscribe?.());
@@ -381,69 +262,6 @@ var constructSpaceNode = ({ space, navigable = false, personal, namesCache, reso
381
262
  }
382
263
  };
383
264
  };
384
- var constructSpaceActionGroups = ({ space, navigable, dispatch }) => {
385
- const state = space.state.get();
386
- const hasPendingMigration = checkPendingMigration(space);
387
- const getId = (id) => `${id}/${space.id}`;
388
- if (state !== SpaceState.SPACE_READY || hasPendingMigration) {
389
- return [];
390
- }
391
- const collection = space.properties[CollectionType.typename];
392
- const actions = [
393
- {
394
- id: getId(SpaceAction.ADD_OBJECT),
395
- type: ACTION_GROUP_TYPE,
396
- data: actionGroupSymbol,
397
- properties: {
398
- label: [
399
- "create object in space label",
400
- {
401
- ns: SPACE_PLUGIN
402
- }
403
- ],
404
- icon: "ph--plus--regular",
405
- disposition: "toolbar",
406
- menuType: "searchList",
407
- testId: "spacePlugin.createObject"
408
- },
409
- nodes: [
410
- {
411
- id: getId(SpaceAction.ADD_OBJECT.replace("object", "collection")),
412
- type: ACTION_TYPE,
413
- data: () => dispatch([
414
- {
415
- plugin: SPACE_PLUGIN,
416
- action: SpaceAction.ADD_OBJECT,
417
- data: {
418
- target: collection,
419
- object: create(CollectionType, {
420
- objects: [],
421
- views: {}
422
- })
423
- }
424
- },
425
- ...navigable ? [
426
- {
427
- action: NavigationAction3.OPEN
428
- }
429
- ] : []
430
- ]),
431
- properties: {
432
- label: [
433
- "create collection label",
434
- {
435
- ns: SPACE_PLUGIN
436
- }
437
- ],
438
- icon: "ph--cards-three--regular",
439
- testId: "spacePlugin.createCollection"
440
- }
441
- }
442
- ]
443
- }
444
- ];
445
- return actions;
446
- };
447
265
  var constructSpaceActions = ({ space, dispatch, personal, migrating }) => {
448
266
  const state = space.state.get();
449
267
  const hasPendingMigration = checkPendingMigration(space);
@@ -478,6 +296,29 @@ var constructSpaceActions = ({ space, dispatch, personal, migrating }) => {
478
296
  if (state === SpaceState.SPACE_READY && !hasPendingMigration) {
479
297
  const locked = space.properties[COMPOSER_SPACE_LOCK];
480
298
  actions.push({
299
+ id: getId(SpaceAction.OPEN_CREATE_OBJECT),
300
+ type: ACTION_TYPE,
301
+ data: async () => {
302
+ await dispatch({
303
+ plugin: SPACE_PLUGIN,
304
+ action: SpaceAction.OPEN_CREATE_OBJECT,
305
+ data: {
306
+ target: space
307
+ }
308
+ });
309
+ },
310
+ properties: {
311
+ label: [
312
+ "create object in space label",
313
+ {
314
+ ns: SPACE_PLUGIN
315
+ }
316
+ ],
317
+ icon: "ph--plus--regular",
318
+ disposition: "toolbar",
319
+ testId: "spacePlugin.createObject"
320
+ }
321
+ }, {
481
322
  id: getId(SpaceAction.SHARE),
482
323
  type: ACTION_TYPE,
483
324
  data: async () => {
@@ -667,71 +508,36 @@ var createObjectNode = ({ object, space, navigable = false, resolve }) => {
667
508
  }
668
509
  };
669
510
  };
670
- var constructObjectActionGroups = ({ object, navigable, dispatch }) => {
671
- if (!(object instanceof CollectionType)) {
672
- return [];
673
- }
674
- const collection = object;
675
- const getId = (id) => `${id}/${fullyQualifiedId2(object)}`;
676
- const actions = [
677
- {
678
- id: getId(SpaceAction.ADD_OBJECT),
679
- type: ACTION_GROUP_TYPE,
680
- data: actionGroupSymbol,
681
- properties: {
682
- label: [
683
- "create object in collection label",
684
- {
685
- ns: SPACE_PLUGIN
686
- }
687
- ],
688
- icon: "ph--plus--regular",
689
- disposition: "toolbar",
690
- menuType: "searchList",
691
- testId: "spacePlugin.createObject"
692
- },
693
- nodes: [
694
- {
695
- id: getId(SpaceAction.ADD_OBJECT.replace("object", "collection")),
696
- type: ACTION_TYPE,
697
- data: () => dispatch([
698
- {
699
- plugin: SPACE_PLUGIN,
700
- action: SpaceAction.ADD_OBJECT,
701
- data: {
702
- target: collection,
703
- object: create(CollectionType, {
704
- objects: [],
705
- views: {}
706
- })
707
- }
708
- },
709
- ...navigable ? [
710
- {
711
- action: NavigationAction3.OPEN
712
- }
713
- ] : []
714
- ]),
715
- properties: {
716
- label: [
717
- "create collection label",
718
- {
719
- ns: SPACE_PLUGIN
720
- }
721
- ],
722
- icon: "ph--cards-three--regular",
723
- testId: "spacePlugin.createCollection"
724
- }
725
- }
726
- ]
727
- }
728
- ];
729
- return actions;
730
- };
731
511
  var constructObjectActions = ({ node, dispatch }) => {
732
512
  const object = node.data;
733
513
  const getId = (id) => `${id}/${fullyQualifiedId2(object)}`;
734
514
  const actions = [
515
+ ...object instanceof CollectionType ? [
516
+ {
517
+ id: getId(SpaceAction.ADD_OBJECT),
518
+ type: ACTION_TYPE,
519
+ data: async () => {
520
+ await dispatch({
521
+ plugin: SPACE_PLUGIN,
522
+ action: SpaceAction.OPEN_CREATE_OBJECT,
523
+ data: {
524
+ target: object
525
+ }
526
+ });
527
+ },
528
+ properties: {
529
+ label: [
530
+ "create object in collection label",
531
+ {
532
+ ns: SPACE_PLUGIN
533
+ }
534
+ ],
535
+ icon: "ph--plus--regular",
536
+ disposition: "toolbar",
537
+ testId: "spacePlugin.createObject"
538
+ }
539
+ }
540
+ ] : [],
735
541
  {
736
542
  id: getId(SpaceAction.RENAME_OBJECT),
737
543
  type: ACTION_TYPE,
@@ -844,7 +650,7 @@ var cloneObject = async (object, resolve, newSpace) => {
844
650
  const serializer = metadata.serializer;
845
651
  invariant(serializer, `No serializer for type: ${typename}`, {
846
652
  F: __dxlog_file,
847
- L: 634,
653
+ L: 544,
848
654
  S: void 0,
849
655
  A: [
850
656
  "serializer",
@@ -861,30 +667,425 @@ var cloneObject = async (object, resolve, newSpace) => {
861
667
  });
862
668
  };
863
669
 
670
+ // packages/plugins/plugin-space/src/components/CreateDialog/CreateObjectPanel.tsx
671
+ var CreateObjectPanel = ({ schemas, spaces, typename: initialTypename, target: initialTarget, name: initialName, defaultSpaceId, resolve, onCreateObject }) => {
672
+ const { t } = useTranslation2(SPACE_PLUGIN);
673
+ const [typename, setTypename] = useState2(initialTypename);
674
+ const [target, setTarget] = useState2(initialTarget);
675
+ const schema = schemas.find((schema2) => getObjectAnnotation2(schema2)?.typename === typename);
676
+ const options = schemas.map(getObjectAnnotation2).filter(nonNullable);
677
+ const handleClearSchema = useCallback(() => setTypename(void 0), []);
678
+ const handleClearTarget = useCallback(() => setTarget(void 0), []);
679
+ const handleCreateObject = useCallback(async ({ name }) => {
680
+ if (!schema || !target) {
681
+ return;
682
+ }
683
+ await onCreateObject?.({
684
+ schema,
685
+ target,
686
+ name
687
+ });
688
+ }, [
689
+ onCreateObject,
690
+ schema,
691
+ target
692
+ ]);
693
+ const schemaInput = /* @__PURE__ */ React2.createElement(SearchList.Root, {
694
+ label: t("schema input label"),
695
+ classNames: "flex flex-col grow overflow-hidden my-2 px-2"
696
+ }, /* @__PURE__ */ React2.createElement(SearchList.Input, {
697
+ autoFocus: true,
698
+ "data-testid": "create-object-form.schema-input",
699
+ placeholder: t("schema input placeholder"),
700
+ classNames: "px-1 my-2"
701
+ }), /* @__PURE__ */ React2.createElement(SearchList.Content, {
702
+ classNames: "max-bs-[24rem] overflow-auto"
703
+ }, options.map((option) => /* @__PURE__ */ React2.createElement(SearchList.Item, {
704
+ key: option.typename,
705
+ value: t("typename label", {
706
+ ns: option.typename,
707
+ defaultValue: option.typename
708
+ }),
709
+ onSelect: () => setTypename(option.typename),
710
+ classNames: "flex items-center gap-2"
711
+ }, /* @__PURE__ */ React2.createElement("span", {
712
+ className: "flex gap-2 items-center grow truncate"
713
+ }, /* @__PURE__ */ React2.createElement(Icon, {
714
+ icon: resolve?.(option.typename).icon ?? "ph--placeholder--regular",
715
+ size: 5
716
+ }), t("typename label", {
717
+ ns: option.typename,
718
+ defaultValue: option.typename
719
+ }))))));
720
+ const spaceInput = /* @__PURE__ */ React2.createElement(SearchList.Root, {
721
+ label: t("space input label"),
722
+ classNames: "flex flex-col grow overflow-hidden my-2 px-2"
723
+ }, /* @__PURE__ */ React2.createElement(SearchList.Input, {
724
+ autoFocus: true,
725
+ "data-testid": "create-object-form.space-input",
726
+ placeholder: t("space input placeholder"),
727
+ classNames: "px-1 my-2"
728
+ }), /* @__PURE__ */ React2.createElement(SearchList.Content, {
729
+ classNames: "max-bs-[24rem] overflow-auto"
730
+ }, spaces.map((space) => /* @__PURE__ */ React2.createElement(SearchList.Item, {
731
+ key: space.id,
732
+ value: toLocalizedString(getSpaceDisplayName(space, {
733
+ personal: space.id === defaultSpaceId
734
+ }), t),
735
+ onSelect: () => setTarget(space),
736
+ classNames: "flex items-center gap-2"
737
+ }, /* @__PURE__ */ React2.createElement("span", {
738
+ className: "grow truncate"
739
+ }, toLocalizedString(getSpaceDisplayName(space, {
740
+ personal: space.id === defaultSpaceId
741
+ }), t))))));
742
+ const form = /* @__PURE__ */ React2.createElement(Form, {
743
+ autoFocus: true,
744
+ values: {
745
+ name: initialName
746
+ },
747
+ schema: S.Struct({
748
+ name: S.optional(S.String)
749
+ }),
750
+ testId: "create-object-form",
751
+ onSave: handleCreateObject
752
+ });
753
+ return /* @__PURE__ */ React2.createElement("div", {
754
+ role: "form",
755
+ className: "flex flex-col gap-2"
756
+ }, target && /* @__PURE__ */ React2.createElement("div", {
757
+ role: "none",
758
+ className: "px-2"
759
+ }, /* @__PURE__ */ React2.createElement(Input.Root, null, /* @__PURE__ */ React2.createElement(InputHeader, null, /* @__PURE__ */ React2.createElement(Input.Label, null, t(isSpace2(target) ? "creating in space label" : "creating in collection label"))), /* @__PURE__ */ React2.createElement("div", {
760
+ role: "none",
761
+ className: "flex gap-2"
762
+ }, /* @__PURE__ */ React2.createElement(Input.TextInput, {
763
+ disabled: true,
764
+ value: isSpace2(target) ? toLocalizedString(getSpaceDisplayName(target, {
765
+ personal: target.id === defaultSpaceId
766
+ }), t) : target.name || t("unnamed collection label")
767
+ }), /* @__PURE__ */ React2.createElement(IconButton, {
768
+ iconOnly: true,
769
+ icon: "ph--x--regular",
770
+ label: t("clear input label"),
771
+ onClick: handleClearTarget
772
+ })))), schema && /* @__PURE__ */ React2.createElement("div", {
773
+ role: "none",
774
+ className: "px-2"
775
+ }, /* @__PURE__ */ React2.createElement(Input.Root, null, /* @__PURE__ */ React2.createElement(InputHeader, null, /* @__PURE__ */ React2.createElement(Input.Label, null, t("creating object type label"))), /* @__PURE__ */ React2.createElement("div", {
776
+ role: "none",
777
+ className: "flex gap-2"
778
+ }, /* @__PURE__ */ React2.createElement(Input.TextInput, {
779
+ disabled: true,
780
+ value: t("typename label", {
781
+ ns: schema.typename,
782
+ defaultValue: schema.typename
783
+ })
784
+ }), /* @__PURE__ */ React2.createElement(IconButton, {
785
+ iconOnly: true,
786
+ icon: "ph--x--regular",
787
+ label: t("clear input label"),
788
+ onClick: handleClearSchema
789
+ })))), !schema ? schemaInput : !target ? spaceInput : form);
790
+ };
791
+
792
+ // packages/plugins/plugin-space/src/components/CreateDialog/CreateObjectDialog.tsx
793
+ var CreateObjectDialog = ({ schemas, target, typename, name, navigableCollections, resolve }) => {
794
+ const closeRef = useRef(null);
795
+ const { t } = useTranslation3(SPACE_PLUGIN);
796
+ const client = useClient2();
797
+ const spaces = useSpaces();
798
+ const dispatch = useIntentDispatcher();
799
+ const handleCreateObject = useCallback2(async ({ schema, target: _target, name: name2 }) => {
800
+ const target2 = isSpace3(_target) ? _target.properties[CollectionType.typename] : _target;
801
+ const createObjectAction = resolve?.(schema.typename)?.createObject;
802
+ if (!createObjectAction || !target2) {
803
+ return;
804
+ }
805
+ closeRef.current?.click();
806
+ const result = await dispatch({
807
+ action: createObjectAction,
808
+ data: {
809
+ name: name2
810
+ }
811
+ });
812
+ const object = result?.data;
813
+ if (isReactiveObject2(object)) {
814
+ await dispatch([
815
+ {
816
+ plugin: SPACE_PLUGIN,
817
+ action: SpaceAction.ADD_OBJECT,
818
+ data: {
819
+ target: target2,
820
+ object
821
+ }
822
+ },
823
+ ...!(object instanceof CollectionType) || navigableCollections ? [
824
+ {
825
+ action: NavigationAction2.OPEN
826
+ }
827
+ ] : []
828
+ ]);
829
+ }
830
+ }, [
831
+ dispatch,
832
+ resolve
833
+ ]);
834
+ return (
835
+ // TODO(wittjosiah): The tablist dialog pattern is copied from @dxos/plugin-manager.
836
+ // Consider factoring it out to the tabs package.
837
+ /* @__PURE__ */ React3.createElement(Dialog.Content, {
838
+ classNames: "p-0 bs-content min-bs-[15rem] max-bs-full md:max-is-[40rem] overflow-hidden"
839
+ }, /* @__PURE__ */ React3.createElement("div", {
840
+ role: "none",
841
+ className: "flex justify-between pbs-3 pis-2 pie-3 @md:pbs-4 @md:pis-4 @md:pie-5"
842
+ }, /* @__PURE__ */ React3.createElement(Dialog.Title, null, t("create object dialog title")), /* @__PURE__ */ React3.createElement(Dialog.Close, {
843
+ asChild: true
844
+ }, /* @__PURE__ */ React3.createElement(Button2, {
845
+ ref: closeRef,
846
+ density: "fine",
847
+ variant: "ghost",
848
+ autoFocus: true
849
+ }, /* @__PURE__ */ React3.createElement(Icon2, {
850
+ icon: "ph--x--regular",
851
+ size: 4
852
+ })))), /* @__PURE__ */ React3.createElement("div", {
853
+ className: "p-4"
854
+ }, /* @__PURE__ */ React3.createElement(CreateObjectPanel, {
855
+ schemas,
856
+ spaces,
857
+ target,
858
+ typename,
859
+ name,
860
+ defaultSpaceId: client.spaces.default.id,
861
+ resolve,
862
+ onCreateObject: handleCreateObject
863
+ })))
864
+ );
865
+ };
866
+
867
+ // packages/plugins/plugin-space/src/components/CreateDialog/CreateSpaceDialog.tsx
868
+ import React4, { useCallback as useCallback3, useRef as useRef2 } from "react";
869
+ import { useIntentDispatcher as useIntentDispatcher2 } from "@dxos/app-framework";
870
+ import { Button as Button3, Dialog as Dialog2, Icon as Icon3, useTranslation as useTranslation4 } from "@dxos/react-ui";
871
+ import { Form as Form2 } from "@dxos/react-ui-form";
872
+ var initialValues = {
873
+ edgeReplication: true
874
+ };
875
+ var CreateSpaceDialog = () => {
876
+ const closeRef = useRef2(null);
877
+ const { t } = useTranslation4(SPACE_PLUGIN);
878
+ const dispatch = useIntentDispatcher2();
879
+ const handleCreateSpace = useCallback3(async (data) => {
880
+ const result = await dispatch({
881
+ action: SpaceAction.CREATE,
882
+ data
883
+ });
884
+ const target = result?.data.space;
885
+ if (target) {
886
+ await dispatch({
887
+ action: SpaceAction.OPEN_CREATE_OBJECT,
888
+ data: {
889
+ target
890
+ }
891
+ });
892
+ }
893
+ }, [
894
+ dispatch
895
+ ]);
896
+ return (
897
+ // TODO(wittjosiah): The tablist dialog pattern is copied from @dxos/plugin-manager.
898
+ // Consider factoring it out to the tabs package.
899
+ /* @__PURE__ */ React4.createElement(Dialog2.Content, {
900
+ classNames: "p-0 bs-content min-bs-[15rem] max-bs-full md:max-is-[40rem] overflow-hidden"
901
+ }, /* @__PURE__ */ React4.createElement("div", {
902
+ role: "none",
903
+ className: "flex justify-between pbs-3 pis-2 pie-3 @md:pbs-4 @md:pis-4 @md:pie-5"
904
+ }, /* @__PURE__ */ React4.createElement(Dialog2.Title, null, t("create space dialog title")), /* @__PURE__ */ React4.createElement(Dialog2.Close, {
905
+ asChild: true
906
+ }, /* @__PURE__ */ React4.createElement(Button3, {
907
+ ref: closeRef,
908
+ density: "fine",
909
+ variant: "ghost",
910
+ autoFocus: true
911
+ }, /* @__PURE__ */ React4.createElement(Icon3, {
912
+ icon: "ph--x--regular",
913
+ size: 4
914
+ })))), /* @__PURE__ */ React4.createElement("div", {
915
+ className: "p-4"
916
+ }, /* @__PURE__ */ React4.createElement(Form2, {
917
+ testId: "create-space-form",
918
+ values: initialValues,
919
+ schema: SpaceForm,
920
+ onSave: handleCreateSpace
921
+ })))
922
+ );
923
+ };
924
+
925
+ // packages/plugins/plugin-space/src/components/CollectionMain.tsx
926
+ import React5 from "react";
927
+ import { useTranslation as useTranslation5 } from "@dxos/react-ui";
928
+ import { baseSurface, descriptionText, mx as mx2 } from "@dxos/react-ui-theme";
929
+ var CollectionMain = ({ collection }) => {
930
+ const { t } = useTranslation5(SPACE_PLUGIN);
931
+ return /* @__PURE__ */ React5.createElement("div", {
932
+ role: "none",
933
+ className: mx2(baseSurface, "min-bs-screen is-full flex items-center justify-center p-8"),
934
+ "data-testid": "composer.firstRunMessage"
935
+ }, /* @__PURE__ */ React5.createElement("p", {
936
+ role: "alert",
937
+ className: mx2(descriptionText, "border border-dashed border-neutral-400/50 rounded-lg p-8 font-normal text-lg max-is-[24rem] break-words")
938
+ }, collection.name ?? t("unnamed collection label")));
939
+ };
940
+
941
+ // packages/plugins/plugin-space/src/components/CollectionSection.tsx
942
+ import React6 from "react";
943
+ import { useTranslation as useTranslation6 } from "@dxos/react-ui";
944
+ var CollectionSection = ({ collection }) => {
945
+ const { t } = useTranslation6(SPACE_PLUGIN);
946
+ return /* @__PURE__ */ React6.createElement("div", {
947
+ className: "min-bs-[3.5rem] grid grid-rows-subgrid grid-cols-subgrid items-center"
948
+ }, /* @__PURE__ */ React6.createElement("span", {
949
+ className: "truncate"
950
+ }, collection.name ?? t("unnamed collection label")));
951
+ };
952
+
953
+ // packages/plugins/plugin-space/src/components/DefaultObjectSettings.tsx
954
+ import React7 from "react";
955
+ import { Input as Input2, useTranslation as useTranslation7 } from "@dxos/react-ui";
956
+ var DefaultObjectSettings = ({ object }) => {
957
+ const { t } = useTranslation7(SPACE_PLUGIN);
958
+ return /* @__PURE__ */ React7.createElement("div", {
959
+ role: "form",
960
+ className: "flex flex-col w-full p-2 gap-1"
961
+ }, /* @__PURE__ */ React7.createElement(Input2.Root, null, /* @__PURE__ */ React7.createElement(Input2.Label, null, t("name label")), /* @__PURE__ */ React7.createElement(Input2.TextInput, {
962
+ placeholder: t("name placeholder"),
963
+ value: object.name ?? "",
964
+ onChange: (event) => {
965
+ object.name = event.target.value;
966
+ }
967
+ })));
968
+ };
969
+
970
+ // packages/plugins/plugin-space/src/components/JoinDialog.tsx
971
+ import React8, { useCallback as useCallback4 } from "react";
972
+ import { LayoutAction, NavigationAction as NavigationAction3, useIntentDispatcher as useIntentDispatcher3 } from "@dxos/app-framework";
973
+ import { useGraph } from "@dxos/plugin-graph";
974
+ import { ObservabilityAction } from "@dxos/plugin-observability/meta";
975
+ import { useSpaces as useSpaces2 } from "@dxos/react-client/echo";
976
+ import { Dialog as Dialog3, useTranslation as useTranslation8 } from "@dxos/react-ui";
977
+ import { JoinPanel } from "@dxos/shell/react";
978
+ var JoinDialog = ({ navigableCollections, ...props }) => {
979
+ const { t } = useTranslation8(SPACE_PLUGIN);
980
+ const dispatch = useIntentDispatcher3();
981
+ const spaces = useSpaces2();
982
+ const { graph } = useGraph();
983
+ const handleDone = useCallback4(async (result) => {
984
+ if (result?.spaceKey) {
985
+ await Promise.all([
986
+ dispatch({
987
+ action: LayoutAction.SET_LAYOUT,
988
+ data: {
989
+ element: "toast",
990
+ subject: {
991
+ id: `${SPACE_PLUGIN}/join-success`,
992
+ duration: 5e3,
993
+ title: t("join success label"),
994
+ closeLabel: t("dismiss label")
995
+ }
996
+ }
997
+ }),
998
+ dispatch({
999
+ action: LayoutAction.SET_LAYOUT,
1000
+ data: {
1001
+ element: "dialog",
1002
+ state: false
1003
+ }
1004
+ })
1005
+ ]);
1006
+ }
1007
+ const space = spaces.find(({ key }) => result?.spaceKey?.equals(key));
1008
+ const target = result?.target || (navigableCollections ? space?.id : void 0);
1009
+ if (target) {
1010
+ await graph.waitForPath({
1011
+ target
1012
+ }).catch(() => {
1013
+ });
1014
+ await Promise.all([
1015
+ dispatch({
1016
+ action: NavigationAction3.OPEN,
1017
+ data: {
1018
+ activeParts: {
1019
+ main: [
1020
+ target
1021
+ ]
1022
+ }
1023
+ }
1024
+ }),
1025
+ dispatch({
1026
+ action: NavigationAction3.EXPOSE,
1027
+ data: {
1028
+ id: target
1029
+ }
1030
+ })
1031
+ ]);
1032
+ }
1033
+ if (space) {
1034
+ await dispatch({
1035
+ action: ObservabilityAction.SEND_EVENT,
1036
+ data: {
1037
+ name: "space.join",
1038
+ properties: {
1039
+ spaceId: space.id
1040
+ }
1041
+ }
1042
+ });
1043
+ }
1044
+ }, [
1045
+ dispatch,
1046
+ spaces
1047
+ ]);
1048
+ return /* @__PURE__ */ React8.createElement(Dialog3.Content, null, /* @__PURE__ */ React8.createElement(JoinPanel, {
1049
+ ...props,
1050
+ exitActionParent: /* @__PURE__ */ React8.createElement(Dialog3.Close, {
1051
+ asChild: true
1052
+ }),
1053
+ doneActionParent: /* @__PURE__ */ React8.createElement(Dialog3.Close, {
1054
+ asChild: true
1055
+ }),
1056
+ onDone: handleDone
1057
+ }));
1058
+ };
1059
+
864
1060
  // packages/plugins/plugin-space/src/components/MenuFooter.tsx
1061
+ import { Planet } from "@phosphor-icons/react";
1062
+ import React9 from "react";
1063
+ import { getSpace as getSpace2 } from "@dxos/client/echo";
1064
+ import { useClient as useClient3 } from "@dxos/react-client";
1065
+ import { DropdownMenu, toLocalizedString as toLocalizedString2, useTranslation as useTranslation9 } from "@dxos/react-ui";
865
1066
  var MenuFooter = ({ object }) => {
866
- const { t } = useTranslation6(SPACE_PLUGIN);
867
- const client = useClient2();
1067
+ const { t } = useTranslation9(SPACE_PLUGIN);
1068
+ const client = useClient3();
868
1069
  const space = getSpace2(object);
869
1070
  const spaceName = space ? getSpaceDisplayName(space, {
870
1071
  personal: client.spaces.default === space
871
1072
  }) : "";
872
- return space ? /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(DropdownMenu.Separator, null), /* @__PURE__ */ React6.createElement(DropdownMenu.GroupLabel, null, t("menu footer label")), /* @__PURE__ */ React6.createElement("dl", {
1073
+ return space ? /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement(DropdownMenu.Separator, null), /* @__PURE__ */ React9.createElement(DropdownMenu.GroupLabel, null, t("menu footer label")), /* @__PURE__ */ React9.createElement("dl", {
873
1074
  className: "pis-2 mbe-2 text-xs grid grid-cols-[max-content_1fr] gap-2"
874
- }, /* @__PURE__ */ React6.createElement("dt", {
1075
+ }, /* @__PURE__ */ React9.createElement("dt", {
875
1076
  className: "uppercase text-[.75em] tracking-wide font-medium mbs-px self-start"
876
- }, t("location label")), /* @__PURE__ */ React6.createElement("dd", {
1077
+ }, t("location label")), /* @__PURE__ */ React9.createElement("dd", {
877
1078
  className: "line-clamp-3"
878
- }, /* @__PURE__ */ React6.createElement(Planet, {
1079
+ }, /* @__PURE__ */ React9.createElement(Planet, {
879
1080
  className: "inline-block mie-1"
880
- }), toLocalizedString(spaceName, t)))) : null;
1081
+ }), toLocalizedString2(spaceName, t)))) : null;
881
1082
  };
882
1083
 
883
1084
  // packages/plugins/plugin-space/src/components/PersistenceStatus.tsx
884
1085
  import { ArrowsCounterClockwise, CheckCircle as CheckCircle2, Warning } from "@phosphor-icons/react";
885
- import React7, { useEffect as useEffect2, useState as useState2 } from "react";
1086
+ import React10, { useEffect as useEffect2, useState as useState3 } from "react";
886
1087
  import { debounce } from "@dxos/async";
887
- import { Tooltip, useTranslation as useTranslation7 } from "@dxos/react-ui";
1088
+ import { Tooltip, useTranslation as useTranslation10 } from "@dxos/react-ui";
888
1089
  import { getSize as getSize2, mx as mx3, staticPlaceholderText, warningText } from "@dxos/react-ui-theme";
889
1090
  var Status;
890
1091
  (function(Status2) {
@@ -893,10 +1094,10 @@ var Status;
893
1094
  Status2[Status2["ERROR"] = 2] = "ERROR";
894
1095
  })(Status || (Status = {}));
895
1096
  var PersistenceStatus = ({ db }) => {
896
- const { t } = useTranslation7(SPACE_PLUGIN);
897
- const [displayMessage, setDisplayMessage] = useState2(false);
898
- const [status, naturalSetStatus] = useState2(0);
899
- const [prevStatus, setPrevStatus] = useState2(0);
1097
+ const { t } = useTranslation10(SPACE_PLUGIN);
1098
+ const [displayMessage, setDisplayMessage] = useState3(false);
1099
+ const [status, naturalSetStatus] = useState3(0);
1100
+ const [prevStatus, setPrevStatus] = useState3(0);
900
1101
  const _setStatus = debounce(naturalSetStatus, 500);
901
1102
  useEffect2(() => {
902
1103
  setPrevStatus(status);
@@ -910,49 +1111,49 @@ var PersistenceStatus = ({ db }) => {
910
1111
  ]);
911
1112
  switch (status) {
912
1113
  case 2:
913
- return /* @__PURE__ */ React7.createElement("div", {
1114
+ return /* @__PURE__ */ React10.createElement("div", {
914
1115
  className: "flex items-center"
915
- }, /* @__PURE__ */ React7.createElement(Warning, {
1116
+ }, /* @__PURE__ */ React10.createElement(Warning, {
916
1117
  className: mx3(getSize2(4), "me-1")
917
- }), /* @__PURE__ */ React7.createElement("span", {
1118
+ }), /* @__PURE__ */ React10.createElement("span", {
918
1119
  className: mx3("text-sm", warningText)
919
1120
  }, t("persistence error label")));
920
1121
  case 1:
921
- return /* @__PURE__ */ React7.createElement("div", {
1122
+ return /* @__PURE__ */ React10.createElement("div", {
922
1123
  className: "flex items-center"
923
- }, /* @__PURE__ */ React7.createElement(ArrowsCounterClockwise, {
1124
+ }, /* @__PURE__ */ React10.createElement(ArrowsCounterClockwise, {
924
1125
  className: mx3(getSize2(4), "me-1")
925
- }), /* @__PURE__ */ React7.createElement("span", {
1126
+ }), /* @__PURE__ */ React10.createElement("span", {
926
1127
  className: mx3("text-sm", staticPlaceholderText)
927
1128
  }, t("persistence pending label")));
928
1129
  case 0:
929
1130
  default:
930
- return /* @__PURE__ */ React7.createElement(Tooltip.Root, {
1131
+ return /* @__PURE__ */ React10.createElement(Tooltip.Root, {
931
1132
  delayDuration: 400
932
- }, /* @__PURE__ */ React7.createElement(Tooltip.Trigger, {
1133
+ }, /* @__PURE__ */ React10.createElement(Tooltip.Trigger, {
933
1134
  role: "status",
934
1135
  className: "flex items-center"
935
- }, /* @__PURE__ */ React7.createElement(CheckCircle2, {
1136
+ }, /* @__PURE__ */ React10.createElement(CheckCircle2, {
936
1137
  className: mx3(getSize2(4), "me-1")
937
- }), displayMessage && /* @__PURE__ */ React7.createElement("span", {
1138
+ }), displayMessage && /* @__PURE__ */ React10.createElement("span", {
938
1139
  className: mx3("text-sm", staticPlaceholderText)
939
- }, t("persisted locally label"))), /* @__PURE__ */ React7.createElement(Tooltip.Portal, null, /* @__PURE__ */ React7.createElement(Tooltip.Content, {
1140
+ }, t("persisted locally label"))), /* @__PURE__ */ React10.createElement(Tooltip.Portal, null, /* @__PURE__ */ React10.createElement(Tooltip.Content, {
940
1141
  classNames: "z-10"
941
- }, t("persisted locally message"), /* @__PURE__ */ React7.createElement(Tooltip.Arrow, null))));
1142
+ }, t("persisted locally message"), /* @__PURE__ */ React10.createElement(Tooltip.Arrow, null))));
942
1143
  }
943
1144
  };
944
1145
 
945
1146
  // packages/plugins/plugin-space/src/components/PopoverRenameObject.tsx
946
- import React8, { useCallback as useCallback2, useRef, useState as useState3 } from "react";
1147
+ import React11, { useCallback as useCallback5, useRef as useRef3, useState as useState4 } from "react";
947
1148
  import { log } from "@dxos/log";
948
- import { Button as Button2, Input as Input2, Popover, useTranslation as useTranslation8 } from "@dxos/react-ui";
1149
+ import { Button as Button4, Input as Input3, Popover, useTranslation as useTranslation11 } from "@dxos/react-ui";
949
1150
  var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-space/src/components/PopoverRenameObject.tsx";
950
1151
  var PopoverRenameObject = ({ object: obj }) => {
951
- const { t } = useTranslation8(SPACE_PLUGIN);
952
- const doneButton = useRef(null);
1152
+ const { t } = useTranslation11(SPACE_PLUGIN);
1153
+ const doneButton = useRef3(null);
953
1154
  const object = obj;
954
- const [name, setName] = useState3(object.name || object.title || "");
955
- const handleDone = useCallback2(() => {
1155
+ const [name, setName] = useState4(object.name || object.title || "");
1156
+ const handleDone = useCallback5(() => {
956
1157
  try {
957
1158
  object.name = name;
958
1159
  } catch {
@@ -973,23 +1174,23 @@ var PopoverRenameObject = ({ object: obj }) => {
973
1174
  object,
974
1175
  name
975
1176
  ]);
976
- return /* @__PURE__ */ React8.createElement("div", {
1177
+ return /* @__PURE__ */ React11.createElement("div", {
977
1178
  role: "none",
978
1179
  className: "p-1 flex gap-2"
979
- }, /* @__PURE__ */ React8.createElement("div", {
1180
+ }, /* @__PURE__ */ React11.createElement("div", {
980
1181
  role: "none",
981
1182
  className: "flex-1"
982
- }, /* @__PURE__ */ React8.createElement(Input2.Root, null, /* @__PURE__ */ React8.createElement(Input2.Label, {
1183
+ }, /* @__PURE__ */ React11.createElement(Input3.Root, null, /* @__PURE__ */ React11.createElement(Input3.Label, {
983
1184
  srOnly: true
984
- }, t("object name label")), /* @__PURE__ */ React8.createElement(Input2.TextInput, {
1185
+ }, t("object name label")), /* @__PURE__ */ React11.createElement(Input3.TextInput, {
985
1186
  placeholder: t("object title placeholder"),
986
1187
  value: name,
987
1188
  "data-testid": "spacePlugin.renameObject.input",
988
1189
  onChange: ({ target: { value } }) => setName(value),
989
1190
  onKeyDown: ({ key }) => key === "Enter" && doneButton.current?.click()
990
- }))), /* @__PURE__ */ React8.createElement(Popover.Close, {
1191
+ }))), /* @__PURE__ */ React11.createElement(Popover.Close, {
991
1192
  asChild: true
992
- }, /* @__PURE__ */ React8.createElement(Button2, {
1193
+ }, /* @__PURE__ */ React11.createElement(Button4, {
993
1194
  ref: doneButton,
994
1195
  classNames: "self-stretch",
995
1196
  onClick: handleDone
@@ -999,36 +1200,36 @@ var PopoverRenameObject = ({ object: obj }) => {
999
1200
  };
1000
1201
 
1001
1202
  // packages/plugins/plugin-space/src/components/PopoverRenameSpace.tsx
1002
- import React9, { useCallback as useCallback3, useRef as useRef2, useState as useState4 } from "react";
1003
- import { Button as Button3, Input as Input3, Popover as Popover2, useTranslation as useTranslation9 } from "@dxos/react-ui";
1203
+ import React12, { useCallback as useCallback6, useRef as useRef4, useState as useState5 } from "react";
1204
+ import { Button as Button5, Input as Input4, Popover as Popover2, useTranslation as useTranslation12 } from "@dxos/react-ui";
1004
1205
  var PopoverRenameSpace = ({ space }) => {
1005
- const { t } = useTranslation9(SPACE_PLUGIN);
1006
- const doneButton = useRef2(null);
1007
- const [name, setName] = useState4(space.properties.name ?? "");
1008
- const handleDone = useCallback3(() => {
1206
+ const { t } = useTranslation12(SPACE_PLUGIN);
1207
+ const doneButton = useRef4(null);
1208
+ const [name, setName] = useState5(space.properties.name ?? "");
1209
+ const handleDone = useCallback6(() => {
1009
1210
  space.properties.name = name;
1010
1211
  }, [
1011
1212
  space,
1012
1213
  name
1013
1214
  ]);
1014
- return /* @__PURE__ */ React9.createElement("div", {
1215
+ return /* @__PURE__ */ React12.createElement("div", {
1015
1216
  role: "none",
1016
1217
  className: "p-1 flex gap-2"
1017
- }, /* @__PURE__ */ React9.createElement("div", {
1218
+ }, /* @__PURE__ */ React12.createElement("div", {
1018
1219
  role: "none",
1019
1220
  className: "flex-1"
1020
- }, /* @__PURE__ */ React9.createElement(Input3.Root, null, /* @__PURE__ */ React9.createElement(Input3.Label, {
1221
+ }, /* @__PURE__ */ React12.createElement(Input4.Root, null, /* @__PURE__ */ React12.createElement(Input4.Label, {
1021
1222
  srOnly: true
1022
- }, t("space name label")), /* @__PURE__ */ React9.createElement(Input3.TextInput, {
1223
+ }, t("space name label")), /* @__PURE__ */ React12.createElement(Input4.TextInput, {
1023
1224
  defaultValue: space.properties.name ?? "",
1024
1225
  placeholder: t("unnamed space label"),
1025
1226
  onChange: ({ target: { value } }) => setName(value),
1026
1227
  // TODO(wittjosiah): Ideally this should access the popover context to close the popover.
1027
1228
  // Currently this is not possible because Radix does not expose the popover context.
1028
1229
  onKeyDown: ({ key }) => key === "Enter" && doneButton.current?.click()
1029
- }))), /* @__PURE__ */ React9.createElement(Popover2.Close, {
1230
+ }))), /* @__PURE__ */ React12.createElement(Popover2.Close, {
1030
1231
  asChild: true
1031
- }, /* @__PURE__ */ React9.createElement(Button3, {
1232
+ }, /* @__PURE__ */ React12.createElement(Button5, {
1032
1233
  ref: doneButton,
1033
1234
  classNames: "self-stretch",
1034
1235
  onClick: handleDone
@@ -1038,12 +1239,12 @@ var PopoverRenameSpace = ({ space }) => {
1038
1239
  };
1039
1240
 
1040
1241
  // packages/plugins/plugin-space/src/components/ShareSpaceButton.tsx
1041
- import React10 from "react";
1042
- import { useIntentDispatcher as useIntentDispatcher2 } from "@dxos/app-framework";
1043
- import { IconButton, useTranslation as useTranslation10 } from "@dxos/react-ui";
1242
+ import React13 from "react";
1243
+ import { useIntentDispatcher as useIntentDispatcher4 } from "@dxos/app-framework";
1244
+ import { IconButton as IconButton2, useTranslation as useTranslation13 } from "@dxos/react-ui";
1044
1245
  var ShareSpaceButton = ({ space }) => {
1045
- const dispatch = useIntentDispatcher2();
1046
- return /* @__PURE__ */ React10.createElement(ShareSpaceButtonImpl, {
1246
+ const dispatch = useIntentDispatcher4();
1247
+ return /* @__PURE__ */ React13.createElement(ShareSpaceButtonImpl, {
1047
1248
  onClick: () => dispatch({
1048
1249
  action: SpaceAction.SHARE,
1049
1250
  data: {
@@ -1053,8 +1254,8 @@ var ShareSpaceButton = ({ space }) => {
1053
1254
  });
1054
1255
  };
1055
1256
  var ShareSpaceButtonImpl = ({ onClick }) => {
1056
- const { t } = useTranslation10(SPACE_PLUGIN);
1057
- return /* @__PURE__ */ React10.createElement(IconButton, {
1257
+ const { t } = useTranslation13(SPACE_PLUGIN);
1258
+ return /* @__PURE__ */ React13.createElement(IconButton2, {
1058
1259
  "data-testid": "spacePlugin.shareSpaceButton",
1059
1260
  icon: "ph--users--regular",
1060
1261
  label: t("share space label"),
@@ -1063,13 +1264,13 @@ var ShareSpaceButtonImpl = ({ onClick }) => {
1063
1264
  };
1064
1265
 
1065
1266
  // packages/plugins/plugin-space/src/components/SpacePresence.tsx
1066
- import React11, { useCallback as useCallback4, useEffect as useEffect3, useState as useState5 } from "react";
1267
+ import React14, { useCallback as useCallback7, useEffect as useEffect3, useState as useState6 } from "react";
1067
1268
  import { usePlugin } from "@dxos/app-framework";
1068
1269
  import { generateName } from "@dxos/display-name";
1069
- import { PublicKey, useClient as useClient3 } from "@dxos/react-client";
1270
+ import { PublicKey, useClient as useClient4 } from "@dxos/react-client";
1070
1271
  import { getSpace as getSpace3, useMembers, fullyQualifiedId as fullyQualifiedId3 } from "@dxos/react-client/echo";
1071
1272
  import { useIdentity } from "@dxos/react-client/halo";
1072
- import { Avatar, AvatarGroup, AvatarGroupItem, Tooltip as Tooltip2, useTranslation as useTranslation11, List, ListItem, useDefaultValue } from "@dxos/react-ui";
1273
+ import { Avatar, AvatarGroup, AvatarGroupItem, Tooltip as Tooltip2, useTranslation as useTranslation14, List, ListItem, useDefaultValue } from "@dxos/react-ui";
1073
1274
  import { AttentionGlyph, useAttention } from "@dxos/react-ui-attention";
1074
1275
  import { ComplexMap, keyToFallback } from "@dxos/util";
1075
1276
  var REFRESH_INTERVAL = 5e3;
@@ -1078,17 +1279,17 @@ var noViewers = new ComplexMap(PublicKey.hash);
1078
1279
  var getName = (identity) => identity.profile?.displayName ?? generateName(identity.identityKey.toHex());
1079
1280
  var SpacePresence = ({ object, spaceKey }) => {
1080
1281
  const spacePlugin = usePlugin(SPACE_PLUGIN);
1081
- const client = useClient3();
1282
+ const client = useClient4();
1082
1283
  const identity = useIdentity();
1083
1284
  const space = spaceKey ? client.spaces.get(spaceKey) : getSpace3(object);
1084
1285
  const spaceMembers = useMembers(space?.key);
1085
- const [_moment, setMoment] = useState5(Date.now());
1286
+ const [_moment, setMoment] = useState6(Date.now());
1086
1287
  useEffect3(() => {
1087
1288
  const interval = setInterval(() => setMoment(Date.now()), REFRESH_INTERVAL);
1088
1289
  return () => clearInterval(interval);
1089
1290
  }, []);
1090
- const memberOnline = useCallback4((member) => member.presence === 1, []);
1091
- const memberIsNotSelf = useCallback4((member) => !identity?.identityKey.equals(member.identity.identityKey), [
1291
+ const memberOnline = useCallback7((member) => member.presence === 1, []);
1292
+ const memberIsNotSelf = useCallback7((member) => !identity?.identityKey.equals(member.identity.identityKey), [
1092
1293
  identity?.identityKey
1093
1294
  ]);
1094
1295
  if (!identity || !spacePlugin || !space) {
@@ -1106,7 +1307,7 @@ var SpacePresence = ({ object, spaceKey }) => {
1106
1307
  lastSeen
1107
1308
  };
1108
1309
  }).toSorted((a, b) => a.lastSeen - b.lastSeen);
1109
- return /* @__PURE__ */ React11.createElement(FullPresence, {
1310
+ return /* @__PURE__ */ React14.createElement(FullPresence, {
1110
1311
  members: membersForObject
1111
1312
  });
1112
1313
  };
@@ -1116,38 +1317,38 @@ var FullPresence = (props) => {
1116
1317
  if (members.length === 0) {
1117
1318
  return null;
1118
1319
  }
1119
- return /* @__PURE__ */ React11.createElement(AvatarGroup.Root, {
1320
+ return /* @__PURE__ */ React14.createElement(AvatarGroup.Root, {
1120
1321
  size,
1121
1322
  classNames: "mbs-2 mie-4",
1122
1323
  "data-testid": "spacePlugin.presence"
1123
- }, members.slice(0, 3).map((member, i) => /* @__PURE__ */ React11.createElement(Tooltip2.Root, {
1324
+ }, members.slice(0, 3).map((member, i) => /* @__PURE__ */ React14.createElement(Tooltip2.Root, {
1124
1325
  key: member.identity.identityKey.toHex()
1125
- }, /* @__PURE__ */ React11.createElement(Tooltip2.Trigger, null, /* @__PURE__ */ React11.createElement(PrensenceAvatar, {
1326
+ }, /* @__PURE__ */ React14.createElement(Tooltip2.Trigger, null, /* @__PURE__ */ React14.createElement(PrensenceAvatar, {
1126
1327
  identity: member.identity,
1127
1328
  group: true,
1128
1329
  match: member.currentlyAttended,
1129
1330
  index: members.length - i,
1130
1331
  onClick: () => onMemberClick?.(member)
1131
- })), /* @__PURE__ */ React11.createElement(Tooltip2.Portal, null, /* @__PURE__ */ React11.createElement(Tooltip2.Content, {
1332
+ })), /* @__PURE__ */ React14.createElement(Tooltip2.Portal, null, /* @__PURE__ */ React14.createElement(Tooltip2.Content, {
1132
1333
  side: "bottom"
1133
- }, /* @__PURE__ */ React11.createElement("span", null, getName(member.identity)), /* @__PURE__ */ React11.createElement(Tooltip2.Arrow, null))))), members.length > 3 && /* @__PURE__ */ React11.createElement(Tooltip2.Root, null, /* @__PURE__ */ React11.createElement(Tooltip2.Trigger, null, /* @__PURE__ */ React11.createElement(AvatarGroupItem.Root, {
1334
+ }, /* @__PURE__ */ React14.createElement("span", null, getName(member.identity)), /* @__PURE__ */ React14.createElement(Tooltip2.Arrow, null))))), members.length > 3 && /* @__PURE__ */ React14.createElement(Tooltip2.Root, null, /* @__PURE__ */ React14.createElement(Tooltip2.Trigger, null, /* @__PURE__ */ React14.createElement(AvatarGroupItem.Root, {
1134
1335
  status: "inactive"
1135
- }, /* @__PURE__ */ React11.createElement(Avatar.Frame, {
1336
+ }, /* @__PURE__ */ React14.createElement(Avatar.Frame, {
1136
1337
  style: {
1137
1338
  zIndex: members.length - 4
1138
1339
  }
1139
- }, /* @__PURE__ */ React11.createElement(Avatar.Fallback, {
1340
+ }, /* @__PURE__ */ React14.createElement(Avatar.Fallback, {
1140
1341
  text: `+${members.length - 3}`
1141
- })))), /* @__PURE__ */ React11.createElement(Tooltip2.Portal, null, /* @__PURE__ */ React11.createElement(Tooltip2.Content, {
1342
+ })))), /* @__PURE__ */ React14.createElement(Tooltip2.Portal, null, /* @__PURE__ */ React14.createElement(Tooltip2.Content, {
1142
1343
  side: "bottom"
1143
- }, /* @__PURE__ */ React11.createElement(Tooltip2.Arrow, null), /* @__PURE__ */ React11.createElement(List, {
1344
+ }, /* @__PURE__ */ React14.createElement(Tooltip2.Arrow, null), /* @__PURE__ */ React14.createElement(List, {
1144
1345
  classNames: "max-h-56 overflow-y-auto"
1145
- }, members.map((member) => /* @__PURE__ */ React11.createElement(ListItem.Root, {
1346
+ }, members.map((member) => /* @__PURE__ */ React14.createElement(ListItem.Root, {
1146
1347
  key: member.identity.identityKey.toHex(),
1147
1348
  classNames: "flex gap-2 items-center cursor-pointer mbe-2",
1148
1349
  onClick: () => onMemberClick?.(member),
1149
1350
  "data-testid": "identity-list-item"
1150
- }, /* @__PURE__ */ React11.createElement(PrensenceAvatar, {
1351
+ }, /* @__PURE__ */ React14.createElement(PrensenceAvatar, {
1151
1352
  identity: member.identity,
1152
1353
  showName: true,
1153
1354
  match: member.currentlyAttended
@@ -1157,10 +1358,10 @@ var PrensenceAvatar = ({ identity, showName, match, group, index, onClick }) =>
1157
1358
  const Root = group ? AvatarGroupItem.Root : Avatar.Root;
1158
1359
  const status = match ? "current" : "active";
1159
1360
  const fallbackValue = keyToFallback(identity.identityKey);
1160
- return /* @__PURE__ */ React11.createElement(Root, {
1361
+ return /* @__PURE__ */ React14.createElement(Root, {
1161
1362
  status,
1162
1363
  hue: identity.profile?.data?.hue || fallbackValue.hue
1163
- }, /* @__PURE__ */ React11.createElement(Avatar.Frame, {
1364
+ }, /* @__PURE__ */ React14.createElement(Avatar.Frame, {
1164
1365
  "data-testid": "spacePlugin.presence.member",
1165
1366
  "data-status": status,
1166
1367
  ...index ? {
@@ -1169,9 +1370,9 @@ var PrensenceAvatar = ({ identity, showName, match, group, index, onClick }) =>
1169
1370
  }
1170
1371
  } : {},
1171
1372
  onClick: () => onClick?.()
1172
- }, /* @__PURE__ */ React11.createElement(Avatar.Fallback, {
1373
+ }, /* @__PURE__ */ React14.createElement(Avatar.Fallback, {
1173
1374
  text: identity.profile?.data?.emoji || fallbackValue.emoji
1174
- })), showName && /* @__PURE__ */ React11.createElement(Avatar.Label, {
1375
+ })), showName && /* @__PURE__ */ React14.createElement(Avatar.Label, {
1175
1376
  classNames: "text-sm truncate pli-2"
1176
1377
  }, getName(identity)));
1177
1378
  };
@@ -1180,7 +1381,7 @@ var SmallPresenceLive = ({ id, viewers }) => {
1180
1381
  const moment = Date.now();
1181
1382
  return Array.from(viewers2.values()).filter(({ lastSeen }) => moment - lastSeen < ACTIVITY_DURATION);
1182
1383
  };
1183
- const [activeViewers, setActiveViewers] = useState5(viewers ? getActiveViewers(viewers) : []);
1384
+ const [activeViewers, setActiveViewers] = useState6(viewers ? getActiveViewers(viewers) : []);
1184
1385
  useEffect3(() => {
1185
1386
  if (viewers) {
1186
1387
  setActiveViewers(getActiveViewers(viewers));
@@ -1192,44 +1393,43 @@ var SmallPresenceLive = ({ id, viewers }) => {
1192
1393
  }, [
1193
1394
  viewers
1194
1395
  ]);
1195
- return /* @__PURE__ */ React11.createElement(SmallPresence, {
1396
+ return /* @__PURE__ */ React14.createElement(SmallPresence, {
1196
1397
  id,
1197
1398
  count: activeViewers.length
1198
1399
  });
1199
1400
  };
1200
1401
  var SmallPresence = ({ id, count }) => {
1201
- const { t } = useTranslation11(SPACE_PLUGIN);
1402
+ const { t } = useTranslation14(SPACE_PLUGIN);
1202
1403
  const { hasAttention, isAncestor, isRelated } = useAttention(id);
1203
1404
  const attention = hasAttention || isAncestor || isRelated;
1204
- return /* @__PURE__ */ React11.createElement(Tooltip2.Root, null, /* @__PURE__ */ React11.createElement(Tooltip2.Trigger, {
1405
+ return /* @__PURE__ */ React14.createElement(Tooltip2.Root, null, /* @__PURE__ */ React14.createElement(Tooltip2.Trigger, {
1205
1406
  asChild: true
1206
- }, /* @__PURE__ */ React11.createElement("div", {
1407
+ }, /* @__PURE__ */ React14.createElement("div", {
1207
1408
  role: "none",
1208
1409
  className: "flex",
1209
1410
  "data-attention": attention
1210
- }, /* @__PURE__ */ React11.createElement(AttentionGlyph, {
1411
+ }, /* @__PURE__ */ React14.createElement(AttentionGlyph, {
1211
1412
  presence: count > 1 ? "many" : count === 1 ? "one" : "none",
1212
1413
  classNames: "self-center mie-1"
1213
- }))), /* @__PURE__ */ React11.createElement(Tooltip2.Portal, null, /* @__PURE__ */ React11.createElement(Tooltip2.Content, {
1414
+ }))), /* @__PURE__ */ React14.createElement(Tooltip2.Portal, null, /* @__PURE__ */ React14.createElement(Tooltip2.Content, {
1214
1415
  side: "bottom",
1215
1416
  classNames: "z-[70]"
1216
- }, /* @__PURE__ */ React11.createElement("span", null, t("presence label", {
1417
+ }, /* @__PURE__ */ React14.createElement("span", null, t("presence label", {
1217
1418
  count
1218
- })), /* @__PURE__ */ React11.createElement(Tooltip2.Arrow, null))));
1419
+ })), /* @__PURE__ */ React14.createElement(Tooltip2.Arrow, null))));
1219
1420
  };
1220
1421
 
1221
1422
  // packages/plugins/plugin-space/src/components/SpacePluginSettings.tsx
1222
- import React12 from "react";
1223
- import { useIntentDispatcher as useIntentDispatcher3, useResolvePlugins } from "@dxos/app-framework";
1224
- import { Input as Input4, Select, toLocalizedString as toLocalizedString2, useTranslation as useTranslation12 } from "@dxos/react-ui";
1423
+ import React15 from "react";
1424
+ import { useIntentDispatcher as useIntentDispatcher5 } from "@dxos/app-framework";
1425
+ import { Input as Input5, useTranslation as useTranslation15 } from "@dxos/react-ui";
1225
1426
  import { DeprecatedFormInput } from "@dxos/react-ui-form";
1226
- var SpacePluginSettings = ({ settings }) => {
1227
- const { t } = useTranslation12(SPACE_PLUGIN);
1228
- const dispatch = useIntentDispatcher3();
1229
- const plugins = useResolvePlugins(parseSpaceInitPlugin);
1230
- return /* @__PURE__ */ React12.createElement(React12.Fragment, null, /* @__PURE__ */ React12.createElement(DeprecatedFormInput, {
1427
+ var SpacePluginSettings = ({ settings }) => {
1428
+ const { t } = useTranslation15(SPACE_PLUGIN);
1429
+ const dispatch = useIntentDispatcher5();
1430
+ return /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(DeprecatedFormInput, {
1231
1431
  label: t("show hidden spaces label")
1232
- }, /* @__PURE__ */ React12.createElement(Input4.Switch, {
1432
+ }, /* @__PURE__ */ React15.createElement(Input5.Switch, {
1233
1433
  checked: settings.showHidden,
1234
1434
  onCheckedChange: (checked) => dispatch({
1235
1435
  plugin: SPACE_PLUGIN,
@@ -1238,49 +1438,35 @@ var SpacePluginSettings = ({ settings }) => {
1238
1438
  state: !!checked
1239
1439
  }
1240
1440
  })
1241
- })), /* @__PURE__ */ React12.createElement(DeprecatedFormInput, {
1242
- label: t("default on space create label")
1243
- }, /* @__PURE__ */ React12.createElement(Select.Root, {
1244
- value: settings.onSpaceCreate,
1245
- onValueChange: (value) => {
1246
- settings.onSpaceCreate = value;
1247
- }
1248
- }, /* @__PURE__ */ React12.createElement(Select.TriggerButton, null), /* @__PURE__ */ React12.createElement(Select.Portal, null, /* @__PURE__ */ React12.createElement(Select.Content, null, /* @__PURE__ */ React12.createElement(Select.Viewport, null, plugins.map(({ provides: { space: { onSpaceCreate } } }) => /* @__PURE__ */ React12.createElement(Select.Option, {
1249
- key: onSpaceCreate.action,
1250
- value: onSpaceCreate.action
1251
- }, toLocalizedString2(onSpaceCreate.label, t)))))))));
1441
+ })));
1252
1442
  };
1253
1443
 
1254
1444
  // packages/plugins/plugin-space/src/components/SpaceSettings/SpaceSettingsDialog.tsx
1255
- import React14, { useState as useState7 } from "react";
1256
- import { useClient as useClient5 } from "@dxos/react-client";
1257
- import { Button as Button4, Dialog as Dialog2, Icon, toLocalizedString as toLocalizedString3, useTranslation as useTranslation14 } from "@dxos/react-ui";
1445
+ import React17, { useState as useState8 } from "react";
1446
+ import { useClient as useClient6 } from "@dxos/react-client";
1447
+ import { Button as Button6, Dialog as Dialog4, Icon as Icon4, toLocalizedString as toLocalizedString3, useTranslation as useTranslation17 } from "@dxos/react-ui";
1258
1448
  import { Tabs } from "@dxos/react-ui-tabs";
1259
1449
  import { ClipboardProvider, SpacePanel } from "@dxos/shell/react";
1260
1450
 
1261
1451
  // packages/plugins/plugin-space/src/components/SpaceSettings/SpaceSettingsPanel.tsx
1262
- import React13, { useCallback as useCallback5, useState as useState6 } from "react";
1452
+ import React16, { useCallback as useCallback8, useState as useState7 } from "react";
1263
1453
  import { log as log2 } from "@dxos/log";
1264
1454
  import { EdgeReplicationSetting } from "@dxos/protocols/proto/dxos/echo/metadata";
1265
- import { useClient as useClient4 } from "@dxos/react-client";
1266
- import { DeviceType, useDevices } from "@dxos/react-client/halo";
1267
- import { Input as Input5, useTranslation as useTranslation13 } from "@dxos/react-ui";
1455
+ import { useClient as useClient5 } from "@dxos/react-client";
1456
+ import { Input as Input6, useTranslation as useTranslation16 } from "@dxos/react-ui";
1268
1457
  import { DeprecatedFormInput as DeprecatedFormInput2 } from "@dxos/react-ui-form";
1269
1458
  var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-space/src/components/SpaceSettings/SpaceSettingsPanel.tsx";
1270
1459
  var SpaceSettingsPanel = ({ space }) => {
1271
- const { t } = useTranslation13(SPACE_PLUGIN);
1272
- const client = useClient4();
1273
- const devices = useDevices();
1274
- const managedDeviceAvailable = devices.find((device) => device.profile?.type === DeviceType.AGENT_MANAGED);
1275
- const edgeAgents = Boolean(client.config.values.runtime?.client?.edgeFeatures?.agents);
1276
- const edgeReplicationAvailable = edgeAgents && managedDeviceAvailable;
1277
- const [edgeReplication, setEdgeReplication] = useState6(space.internal.data.edgeReplication === EdgeReplicationSetting.ENABLED);
1278
- const toggleEdgeReplication = useCallback5(async (next) => {
1460
+ const { t } = useTranslation16(SPACE_PLUGIN);
1461
+ const client = useClient5();
1462
+ const edgeEnabled = Boolean(client.config.values.runtime?.client?.edgeFeatures?.echoReplicator);
1463
+ const [edgeReplication, setEdgeReplication] = useState7(space.internal.data.edgeReplication === EdgeReplicationSetting.ENABLED);
1464
+ const toggleEdgeReplication = useCallback8(async (next) => {
1279
1465
  setEdgeReplication(next);
1280
1466
  await space?.internal.setEdgeReplicationPreference(next ? EdgeReplicationSetting.ENABLED : EdgeReplicationSetting.DISABLED).catch((err) => {
1281
1467
  log2.catch(err, void 0, {
1282
1468
  F: __dxlog_file3,
1283
- L: 39,
1469
+ L: 35,
1284
1470
  S: void 0,
1285
1471
  C: (f, a) => f(...a)
1286
1472
  });
@@ -1289,20 +1475,20 @@ var SpaceSettingsPanel = ({ space }) => {
1289
1475
  }, [
1290
1476
  space
1291
1477
  ]);
1292
- return /* @__PURE__ */ React13.createElement("div", {
1478
+ return /* @__PURE__ */ React16.createElement("div", {
1293
1479
  role: "form",
1294
1480
  className: "flex flex-col"
1295
- }, /* @__PURE__ */ React13.createElement(DeprecatedFormInput2, {
1481
+ }, /* @__PURE__ */ React16.createElement(DeprecatedFormInput2, {
1296
1482
  label: t("name label")
1297
- }, /* @__PURE__ */ React13.createElement(Input5.TextInput, {
1483
+ }, /* @__PURE__ */ React16.createElement(Input6.TextInput, {
1298
1484
  placeholder: t("unnamed space label"),
1299
1485
  value: space.properties.name ?? "",
1300
1486
  onChange: (event) => {
1301
1487
  space.properties.name = event.target.value;
1302
1488
  }
1303
- })), edgeReplicationAvailable && /* @__PURE__ */ React13.createElement(DeprecatedFormInput2, {
1489
+ })), edgeEnabled && /* @__PURE__ */ React16.createElement(DeprecatedFormInput2, {
1304
1490
  label: t("edge replication label")
1305
- }, /* @__PURE__ */ React13.createElement(Input5.Switch, {
1491
+ }, /* @__PURE__ */ React16.createElement(Input6.Switch, {
1306
1492
  checked: edgeReplication,
1307
1493
  onCheckedChange: toggleEdgeReplication
1308
1494
  })));
@@ -1310,10 +1496,10 @@ var SpaceSettingsPanel = ({ space }) => {
1310
1496
 
1311
1497
  // packages/plugins/plugin-space/src/components/SpaceSettings/SpaceSettingsDialog.tsx
1312
1498
  var SpaceSettingsDialog = ({ space, target, createInvitationUrl, initialTab = "members", namesCache }) => {
1313
- const { t } = useTranslation14(SPACE_PLUGIN);
1314
- const client = useClient5();
1315
- const [tabsActivePart, setTabsActivePart] = useState7("list");
1316
- const [selected, setSelected] = useState7(initialTab);
1499
+ const { t } = useTranslation17(SPACE_PLUGIN);
1500
+ const client = useClient6();
1501
+ const [tabsActivePart, setTabsActivePart] = useState8("list");
1502
+ const [selected, setSelected] = useState8(initialTab);
1317
1503
  const locked = space.properties[COMPOSER_SPACE_LOCK];
1318
1504
  const name = getSpaceDisplayName(space, {
1319
1505
  personal: client.spaces.default === space,
@@ -1322,64 +1508,64 @@ var SpaceSettingsDialog = ({ space, target, createInvitationUrl, initialTab = "m
1322
1508
  return (
1323
1509
  // TODO(wittjosiah): The tablist dialog pattern is copied from @dxos/plugin-manager.
1324
1510
  // Consider factoring it out to the tabs package.
1325
- /* @__PURE__ */ React14.createElement(Dialog2.Content, {
1511
+ /* @__PURE__ */ React17.createElement(Dialog4.Content, {
1326
1512
  classNames: "p-0 bs-content min-bs-[15rem] max-bs-full md:max-is-[40rem] overflow-hidden"
1327
- }, /* @__PURE__ */ React14.createElement("div", {
1513
+ }, /* @__PURE__ */ React17.createElement("div", {
1328
1514
  role: "none",
1329
1515
  className: "flex justify-between pbs-3 pis-2 pie-3 @md:pbs-4 @md:pis-4 @md:pie-5"
1330
- }, /* @__PURE__ */ React14.createElement(Dialog2.Title, {
1516
+ }, /* @__PURE__ */ React17.createElement(Dialog4.Title, {
1331
1517
  onClick: () => setTabsActivePart("list"),
1332
1518
  "aria-description": t("click to return to tablist description"),
1333
1519
  classNames: "flex cursor-pointer items-center group/title"
1334
- }, /* @__PURE__ */ React14.createElement(Icon, {
1520
+ }, /* @__PURE__ */ React17.createElement(Icon4, {
1335
1521
  icon: "ph--caret-left--regular",
1336
1522
  size: 4,
1337
1523
  classNames: [
1338
1524
  "@md:hidden",
1339
1525
  tabsActivePart === "list" && "invisible"
1340
1526
  ]
1341
- }), /* @__PURE__ */ React14.createElement("span", {
1527
+ }), /* @__PURE__ */ React17.createElement("span", {
1342
1528
  className: tabsActivePart !== "list" ? "group-hover/title:underline @md:group-hover/title:no-underline underline-offset-4 decoration-1" : ""
1343
- }, toLocalizedString3(name, t))), /* @__PURE__ */ React14.createElement(Dialog2.Close, {
1529
+ }, toLocalizedString3(name, t))), /* @__PURE__ */ React17.createElement(Dialog4.Close, {
1344
1530
  asChild: true
1345
- }, /* @__PURE__ */ React14.createElement(Button4, {
1531
+ }, /* @__PURE__ */ React17.createElement(Button6, {
1346
1532
  density: "fine",
1347
1533
  variant: "ghost",
1348
1534
  autoFocus: true
1349
- }, /* @__PURE__ */ React14.createElement(Icon, {
1535
+ }, /* @__PURE__ */ React17.createElement(Icon4, {
1350
1536
  icon: "ph--x--regular",
1351
- size: 3
1352
- })))), /* @__PURE__ */ React14.createElement(Tabs.Root, {
1537
+ size: 4
1538
+ })))), /* @__PURE__ */ React17.createElement(Tabs.Root, {
1353
1539
  orientation: "vertical",
1354
1540
  value: selected,
1355
1541
  onValueChange: setSelected,
1356
1542
  activePart: tabsActivePart,
1357
1543
  onActivePartChange: setTabsActivePart,
1358
1544
  classNames: "flex flex-col flex-1 mbs-2"
1359
- }, /* @__PURE__ */ React14.createElement(Tabs.Viewport, {
1545
+ }, /* @__PURE__ */ React17.createElement(Tabs.Viewport, {
1360
1546
  classNames: "flex-1 min-bs-0"
1361
- }, /* @__PURE__ */ React14.createElement("div", {
1547
+ }, /* @__PURE__ */ React17.createElement("div", {
1362
1548
  role: "none",
1363
1549
  className: "overflow-y-auto pli-3 @md:pis-2 @md:pie-0 mbe-4 border-r border-separator"
1364
- }, /* @__PURE__ */ React14.createElement(Tabs.Tablist, {
1550
+ }, /* @__PURE__ */ React17.createElement(Tabs.Tablist, {
1365
1551
  classNames: "flex flex-col max-bs-none min-is-[200px] gap-4 overflow-y-auto"
1366
- }, /* @__PURE__ */ React14.createElement("div", {
1552
+ }, /* @__PURE__ */ React17.createElement("div", {
1367
1553
  role: "none",
1368
1554
  className: "flex flex-col ml-1"
1369
- }, /* @__PURE__ */ React14.createElement(Tabs.Tab, {
1555
+ }, /* @__PURE__ */ React17.createElement(Tabs.Tab, {
1370
1556
  value: "settings"
1371
- }, t("settings tab label")), /* @__PURE__ */ React14.createElement(Tabs.Tab, {
1557
+ }, t("settings tab label")), /* @__PURE__ */ React17.createElement(Tabs.Tab, {
1372
1558
  value: "members",
1373
1559
  disabled: locked
1374
- }, t("members tab label"))))), /* @__PURE__ */ React14.createElement(Tabs.Tabpanel, {
1560
+ }, t("members tab label"))))), /* @__PURE__ */ React17.createElement(Tabs.Tabpanel, {
1375
1561
  value: "settings",
1376
1562
  classNames: "pli-3 @md:pli-5 max-bs-dvh overflow-y-auto"
1377
- }, /* @__PURE__ */ React14.createElement(SpaceSettingsPanel, {
1563
+ }, /* @__PURE__ */ React17.createElement(SpaceSettingsPanel, {
1378
1564
  space
1379
- })), /* @__PURE__ */ React14.createElement(Tabs.Tabpanel, {
1565
+ })), /* @__PURE__ */ React17.createElement(Tabs.Tabpanel, {
1380
1566
  value: "members",
1381
1567
  classNames: "pli-3 @md:pli-5 max-bs-dvh overflow-y-auto"
1382
- }, /* @__PURE__ */ React14.createElement(ClipboardProvider, null, /* @__PURE__ */ React14.createElement(SpacePanel, {
1568
+ }, /* @__PURE__ */ React17.createElement(ClipboardProvider, null, /* @__PURE__ */ React17.createElement(SpacePanel, {
1383
1569
  space,
1384
1570
  hideHeading: true,
1385
1571
  target,
@@ -1388,17 +1574,140 @@ var SpaceSettingsDialog = ({ space, target, createInvitationUrl, initialTab = "m
1388
1574
  );
1389
1575
  };
1390
1576
 
1577
+ // packages/plugins/plugin-space/src/components/SyncStatus/InlineSyncStatus.tsx
1578
+ import React18, { useEffect as useEffect5, useState as useState10 } from "react";
1579
+ import { QueryEdgeStatusResponse } from "@dxos/protocols/proto/dxos/client/services";
1580
+ import { EdgeReplicationSetting as EdgeReplicationSetting2 } from "@dxos/protocols/proto/dxos/echo/metadata";
1581
+ import { useClient as useClient8 } from "@dxos/react-client";
1582
+ import { Icon as Icon5, useTranslation as useTranslation18 } from "@dxos/react-ui";
1583
+
1584
+ // packages/plugins/plugin-space/src/components/SyncStatus/sync-state.ts
1585
+ import { useEffect as useEffect4, useState as useState9 } from "react";
1586
+ import { Context } from "@dxos/context";
1587
+ import { EdgeService } from "@dxos/protocols";
1588
+ import { useClient as useClient7 } from "@dxos/react-client";
1589
+ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-space/src/components/SyncStatus/sync-state.ts";
1590
+ var createEmptyEdgeSyncState = () => ({
1591
+ missingOnLocal: 0,
1592
+ missingOnRemote: 0,
1593
+ localDocumentCount: 0,
1594
+ remoteDocumentCount: 0,
1595
+ differentDocuments: 0
1596
+ });
1597
+ var getSyncSummary = (syncMap) => {
1598
+ return Object.entries(syncMap).reduce((summary, [_spaceId, peerState]) => {
1599
+ summary.missingOnLocal += peerState.missingOnLocal;
1600
+ summary.missingOnRemote += peerState.missingOnRemote;
1601
+ summary.localDocumentCount += peerState.localDocumentCount;
1602
+ summary.remoteDocumentCount += peerState.remoteDocumentCount;
1603
+ summary.differentDocuments += peerState.differentDocuments;
1604
+ return summary;
1605
+ }, createEmptyEdgeSyncState());
1606
+ };
1607
+ var isEdgePeerId = (peerId, spaceId) => peerId.startsWith(`${EdgeService.AUTOMERGE_REPLICATOR}:${spaceId}`);
1608
+ var useSyncState = () => {
1609
+ const client = useClient7();
1610
+ const [spaceState, setSpaceState] = useState9({});
1611
+ useEffect4(() => {
1612
+ const ctx = new Context(void 0, {
1613
+ F: __dxlog_file4,
1614
+ L: 48
1615
+ });
1616
+ const createSubscriptions = (spaces) => {
1617
+ for (const space of spaces) {
1618
+ if (spaceState[space.id]) {
1619
+ continue;
1620
+ }
1621
+ ctx.onDispose(space.crud.subscribeToSyncState(ctx, ({ peers = [] }) => {
1622
+ const syncState = peers.find((state) => isEdgePeerId(state.peerId, space.id));
1623
+ if (syncState) {
1624
+ setSpaceState((spaceState2) => ({
1625
+ ...spaceState2,
1626
+ [space.id]: syncState
1627
+ }));
1628
+ }
1629
+ }));
1630
+ }
1631
+ };
1632
+ createSubscriptions(client.spaces.get());
1633
+ client.spaces.subscribe((spaces) => {
1634
+ createSubscriptions(spaces);
1635
+ });
1636
+ return () => {
1637
+ void ctx.dispose();
1638
+ };
1639
+ }, [
1640
+ client
1641
+ ]);
1642
+ return spaceState;
1643
+ };
1644
+ var useSpaceSyncState = (space) => {
1645
+ const [spaceState, setSpaceState] = useState9();
1646
+ useEffect4(() => {
1647
+ const ctx = new Context(void 0, {
1648
+ F: __dxlog_file4,
1649
+ L: 87
1650
+ });
1651
+ space.crud.subscribeToSyncState(ctx, ({ peers = [] }) => {
1652
+ const syncState = peers.find((state) => isEdgePeerId(state.peerId, space.id));
1653
+ if (syncState) {
1654
+ setSpaceState(syncState);
1655
+ }
1656
+ });
1657
+ return () => {
1658
+ void ctx.dispose();
1659
+ };
1660
+ }, [
1661
+ space
1662
+ ]);
1663
+ return spaceState;
1664
+ };
1665
+
1666
+ // packages/plugins/plugin-space/src/components/SyncStatus/InlineSyncStatus.tsx
1667
+ var useEdgeStatus = () => {
1668
+ const [status, setStatus] = useState10(QueryEdgeStatusResponse.EdgeStatus.NOT_CONNECTED);
1669
+ const client = useClient8();
1670
+ useEffect5(() => {
1671
+ client.services.services.EdgeAgentService?.queryEdgeStatus().subscribe(({ status: status2 }) => {
1672
+ setStatus(status2);
1673
+ });
1674
+ }, [
1675
+ client
1676
+ ]);
1677
+ return status;
1678
+ };
1679
+ var InlineSyncStatus = ({ space }) => {
1680
+ const { t } = useTranslation18(SPACE_PLUGIN);
1681
+ const connectedToEdge = useEdgeStatus() === QueryEdgeStatusResponse.EdgeStatus.CONNECTED;
1682
+ const edgeSyncEnabled = space.internal.data.edgeReplication === EdgeReplicationSetting2.ENABLED;
1683
+ const syncState = useSpaceSyncState(space);
1684
+ if (!connectedToEdge || !edgeSyncEnabled || !syncState || syncState.missingOnLocal === 0) {
1685
+ return null;
1686
+ }
1687
+ return /* @__PURE__ */ React18.createElement("div", {
1688
+ role: "status",
1689
+ "aria-label": t("syncing message"),
1690
+ className: "flex items-center"
1691
+ }, /* @__PURE__ */ React18.createElement(Icon5, {
1692
+ icon: "ph--arrows-clockwise--regular",
1693
+ size: 3,
1694
+ classNames: "animate-spin"
1695
+ }));
1696
+ };
1697
+
1391
1698
  // packages/plugins/plugin-space/src/components/SyncStatus/SyncStatus.tsx
1392
- import React16, { useEffect as useEffect6, useState as useState10 } from "react";
1699
+ import React20, { useCallback as useCallback9, useEffect as useEffect7, useState as useState12 } from "react";
1393
1700
  import { StatusBar } from "@dxos/plugin-status-bar";
1394
- import { useClient as useClient7 } from "@dxos/react-client";
1395
- import { Icon as Icon3, Popover as Popover3, useTranslation as useTranslation15 } from "@dxos/react-ui";
1701
+ import { useClient as useClient10 } from "@dxos/react-client";
1702
+ import { Icon as Icon7, Input as Input7, Popover as Popover3, useTranslation as useTranslation20 } from "@dxos/react-ui";
1396
1703
  import { SyntaxHighlighter } from "@dxos/react-ui-syntax-highlighter";
1397
1704
  import { mx as mx5 } from "@dxos/react-ui-theme";
1398
1705
 
1399
1706
  // packages/plugins/plugin-space/src/components/SyncStatus/Space.tsx
1400
- import React15, { useEffect as useEffect4, useState as useState8 } from "react";
1401
- import { Icon as Icon2 } from "@dxos/react-ui";
1707
+ import React19, { useEffect as useEffect6, useState as useState11 } from "react";
1708
+ import { useClient as useClient9 } from "@dxos/react-client";
1709
+ import { useSpace } from "@dxos/react-client/echo";
1710
+ import { Icon as Icon6, toLocalizedString as toLocalizedString4, useTranslation as useTranslation19 } from "@dxos/react-ui";
1402
1711
  import { mx as mx4 } from "@dxos/react-ui-theme";
1403
1712
  var SYNC_STALLED_TIMEOUT = 5e3;
1404
1713
  var styles = {
@@ -1407,9 +1716,9 @@ var styles = {
1407
1716
  barHover: "dark:hover:bg-green-500"
1408
1717
  };
1409
1718
  var useActive = (count) => {
1410
- const [current, setCurrent] = useState8(count);
1411
- const [active, setActive] = useState8(false);
1412
- useEffect4(() => {
1719
+ const [current, setCurrent] = useState11(count);
1720
+ const [active, setActive] = useState11(false);
1721
+ useEffect6(() => {
1413
1722
  let t;
1414
1723
  if (count !== current) {
1415
1724
  setActive(true);
@@ -1429,20 +1738,38 @@ var useActive = (count) => {
1429
1738
  ]);
1430
1739
  return active;
1431
1740
  };
1432
- var SpaceRow = ({ spaceId, state: { localDocumentCount, remoteDocumentCount, missingOnLocal, missingOnRemote } }) => {
1741
+ var SpaceRowContainer = ({ spaceId, state }) => {
1742
+ const { t } = useTranslation19(SPACE_PLUGIN);
1743
+ const client = useClient9();
1744
+ const space = useSpace(spaceId);
1745
+ if (!space) {
1746
+ return null;
1747
+ }
1748
+ const spaceName = toLocalizedString4(getSpaceDisplayName(space, {
1749
+ personal: space === client.spaces.default
1750
+ }), t);
1751
+ return /* @__PURE__ */ React19.createElement(SpaceRow, {
1752
+ spaceId,
1753
+ spaceName,
1754
+ state
1755
+ });
1756
+ };
1757
+ var SpaceRow = ({ spaceId, spaceName, state: { localDocumentCount, remoteDocumentCount, missingOnLocal, missingOnRemote } }) => {
1433
1758
  const downActive = useActive(localDocumentCount);
1434
1759
  const upActive = useActive(remoteDocumentCount);
1435
- return /* @__PURE__ */ React15.createElement("div", {
1436
- className: mx4("flex items-center mx-[2px] gap-[2px] cursor-pointer", styles.barHover),
1760
+ return /* @__PURE__ */ React19.createElement("div", {
1761
+ className: "flex items-center mx-0.5 gap-0.5 cursor-pointer",
1437
1762
  title: spaceId,
1438
1763
  onClick: () => {
1439
1764
  void navigator.clipboard.writeText(spaceId);
1440
1765
  }
1441
- }, /* @__PURE__ */ React15.createElement(Icon2, {
1766
+ }, /* @__PURE__ */ React19.createElement("span", {
1767
+ className: "is-1/2 truncate"
1768
+ }, spaceName), /* @__PURE__ */ React19.createElement(Icon6, {
1442
1769
  icon: "ph--arrow-fat-line-left--regular",
1443
1770
  size: 3,
1444
1771
  classNames: mx4(downActive && "animate-[pulse_1s_infinite]")
1445
- }), /* @__PURE__ */ React15.createElement(Candle, {
1772
+ }), /* @__PURE__ */ React19.createElement(Candle, {
1446
1773
  up: {
1447
1774
  count: remoteDocumentCount,
1448
1775
  total: remoteDocumentCount + missingOnRemote
@@ -1452,44 +1779,44 @@ var SpaceRow = ({ spaceId, state: { localDocumentCount, remoteDocumentCount, mis
1452
1779
  total: localDocumentCount + missingOnLocal
1453
1780
  },
1454
1781
  title: spaceId
1455
- }), /* @__PURE__ */ React15.createElement(Icon2, {
1782
+ }), /* @__PURE__ */ React19.createElement(Icon6, {
1456
1783
  icon: "ph--arrow-fat-line-right--regular",
1457
1784
  size: 3,
1458
1785
  classNames: mx4(upActive && "animate-[pulse_1s_step-start_infinite]")
1459
1786
  }));
1460
1787
  };
1461
1788
  var Candle = ({ classNames, up, down }) => {
1462
- return /* @__PURE__ */ React15.createElement("div", {
1789
+ return /* @__PURE__ */ React19.createElement("div", {
1463
1790
  className: mx4("grid grid-cols-[1fr_2rem_1fr] w-full h-3", classNames)
1464
- }, /* @__PURE__ */ React15.createElement(Bar, {
1791
+ }, /* @__PURE__ */ React19.createElement(Bar, {
1465
1792
  classNames: "justify-end",
1466
1793
  ...up
1467
- }), /* @__PURE__ */ React15.createElement("div", {
1794
+ }), /* @__PURE__ */ React19.createElement("div", {
1468
1795
  className: "relative"
1469
- }, /* @__PURE__ */ React15.createElement("div", {
1796
+ }, /* @__PURE__ */ React19.createElement("div", {
1470
1797
  className: mx4("absolute inset-0 flex items-center justify-center text-xs", styles.barBg)
1471
- }, up.total)), /* @__PURE__ */ React15.createElement(Bar, down));
1798
+ }, up.total)), /* @__PURE__ */ React19.createElement(Bar, down));
1472
1799
  };
1473
1800
  var Bar = ({ classNames, count, total }) => {
1474
1801
  let p = count / total * 100;
1475
1802
  if (count < total) {
1476
1803
  p = Math.min(p, 95);
1477
1804
  }
1478
- return /* @__PURE__ */ React15.createElement("div", {
1805
+ return /* @__PURE__ */ React19.createElement("div", {
1479
1806
  className: mx4("relative flex w-full", styles.barBg, classNames)
1480
- }, /* @__PURE__ */ React15.createElement("div", {
1807
+ }, /* @__PURE__ */ React19.createElement("div", {
1481
1808
  className: mx4("shrink-0", styles.barFg),
1482
1809
  style: {
1483
1810
  width: `${p}%`
1484
1811
  }
1485
- }), count !== total && /* @__PURE__ */ React15.createElement("div", {
1812
+ }), count !== total && /* @__PURE__ */ React19.createElement("div", {
1486
1813
  className: "absolute top-0 bottom-0 flex items-center mx-0.5 text-black text-xs"
1487
1814
  }, count));
1488
1815
  };
1489
1816
 
1490
1817
  // packages/plugins/plugin-space/src/components/SyncStatus/save-tracker.ts
1491
- import { Context } from "@dxos/context";
1492
- var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-space/src/components/SyncStatus/save-tracker.ts";
1818
+ import { Context as Context2 } from "@dxos/context";
1819
+ var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-space/src/components/SyncStatus/save-tracker.ts";
1493
1820
  var createClientSaveTracker = (client, cb) => {
1494
1821
  const unsubscribeCallbacks = {};
1495
1822
  const state = {};
@@ -1516,8 +1843,8 @@ var createClientSaveTracker = (client, cb) => {
1516
1843
  };
1517
1844
  };
1518
1845
  var createSpaceSaveTracker = (space, cb) => {
1519
- const ctx = new Context(void 0, {
1520
- F: __dxlog_file4,
1846
+ const ctx = new Context2(void 0, {
1847
+ F: __dxlog_file5,
1521
1848
  L: 40
1522
1849
  });
1523
1850
  void space.waitUntilReady().then(() => {
@@ -1578,84 +1905,23 @@ var getIcon = (status) => {
1578
1905
  }
1579
1906
  };
1580
1907
 
1581
- // packages/plugins/plugin-space/src/components/SyncStatus/sync-state.ts
1582
- import { useEffect as useEffect5, useState as useState9 } from "react";
1583
- import { Context as Context2 } from "@dxos/context";
1584
- import { EdgeService } from "@dxos/protocols";
1585
- import { useClient as useClient6 } from "@dxos/react-client";
1586
- var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-space/src/components/SyncStatus/sync-state.ts";
1587
- var createEmptyEdgeSyncState = () => ({
1588
- missingOnLocal: 0,
1589
- missingOnRemote: 0,
1590
- localDocumentCount: 0,
1591
- remoteDocumentCount: 0,
1592
- differentDocuments: 0
1593
- });
1594
- var getSyncSummary = (syncMap) => {
1595
- return Object.entries(syncMap).reduce((summary, [_spaceId, peerState]) => {
1596
- summary.missingOnLocal += peerState.missingOnLocal;
1597
- summary.missingOnRemote += peerState.missingOnRemote;
1598
- summary.localDocumentCount += peerState.localDocumentCount;
1599
- summary.remoteDocumentCount += peerState.remoteDocumentCount;
1600
- summary.differentDocuments += peerState.differentDocuments;
1601
- return summary;
1602
- }, createEmptyEdgeSyncState());
1603
- };
1604
- var isEdgePeerId = (peerId, spaceId) => peerId.startsWith(`${EdgeService.AUTOMERGE_REPLICATOR}:${spaceId}`);
1605
- var useSyncState = () => {
1606
- const client = useClient6();
1607
- const [spaceState, setSpaceState] = useState9({});
1608
- useEffect5(() => {
1609
- const ctx = new Context2(void 0, {
1610
- F: __dxlog_file5,
1611
- L: 48
1612
- });
1613
- const createSubscriptions = (spaces) => {
1614
- for (const space of spaces) {
1615
- if (spaceState[space.id]) {
1616
- continue;
1617
- }
1618
- ctx.onDispose(space.crud.subscribeToSyncState(ctx, ({ peers = [] }) => {
1619
- const syncState = peers.find((state) => isEdgePeerId(state.peerId, space.id));
1620
- if (syncState) {
1621
- setSpaceState((spaceState2) => ({
1622
- ...spaceState2,
1623
- [space.id]: syncState
1624
- }));
1625
- }
1626
- }));
1627
- }
1628
- };
1629
- createSubscriptions(client.spaces.get());
1630
- client.spaces.subscribe((spaces) => {
1631
- createSubscriptions(spaces);
1632
- });
1633
- return () => {
1634
- void ctx.dispose();
1635
- };
1636
- }, [
1637
- client
1638
- ]);
1639
- return spaceState;
1640
- };
1641
-
1642
1908
  // packages/plugins/plugin-space/src/components/SyncStatus/SyncStatus.tsx
1643
1909
  var SyncStatus = () => {
1644
- const client = useClient7();
1910
+ const client = useClient10();
1645
1911
  const state = useSyncState();
1646
- const [saved, setSaved] = useState10(true);
1647
- useEffect6(() => {
1912
+ const [saved, setSaved] = useState12(true);
1913
+ useEffect7(() => {
1648
1914
  return createClientSaveTracker(client, (state2) => {
1649
1915
  setSaved(state2 === "saved");
1650
1916
  });
1651
1917
  }, []);
1652
- return /* @__PURE__ */ React16.createElement(SyncStatusIndicator, {
1918
+ return /* @__PURE__ */ React20.createElement(SyncStatusIndicator, {
1653
1919
  state,
1654
1920
  saved
1655
1921
  });
1656
1922
  };
1657
1923
  var SyncStatusIndicator = ({ state, saved }) => {
1658
- const { t } = useTranslation15(SPACE_PLUGIN);
1924
+ const { t } = useTranslation20(SPACE_PLUGIN);
1659
1925
  const summary = getSyncSummary(state);
1660
1926
  const offline = Object.values(state).length === 0;
1661
1927
  const needsToUpload = summary.differentDocuments > 0 || summary.missingOnRemote > 0;
@@ -1666,8 +1932,8 @@ var SyncStatusIndicator = ({ state, saved }) => {
1666
1932
  needsToUpload,
1667
1933
  needsToDownload
1668
1934
  });
1669
- const [classNames, setClassNames] = useState10();
1670
- useEffect6(() => {
1935
+ const [classNames, setClassNames] = useState12();
1936
+ useEffect7(() => {
1671
1937
  setClassNames(void 0);
1672
1938
  if (offline || !needsToUpload && !needsToDownload) {
1673
1939
  return;
@@ -1682,23 +1948,23 @@ var SyncStatusIndicator = ({ state, saved }) => {
1682
1948
  needsToDownload
1683
1949
  ]);
1684
1950
  const title = t(`${status} label`);
1685
- const icon = /* @__PURE__ */ React16.createElement(Icon3, {
1951
+ const icon = /* @__PURE__ */ React20.createElement(Icon7, {
1686
1952
  icon: getIcon(status),
1687
1953
  size: 4,
1688
1954
  classNames
1689
1955
  });
1690
1956
  if (offline) {
1691
- return /* @__PURE__ */ React16.createElement(StatusBar.Item, {
1957
+ return /* @__PURE__ */ React20.createElement(StatusBar.Item, {
1692
1958
  title
1693
1959
  }, icon);
1694
1960
  } else {
1695
- return /* @__PURE__ */ React16.createElement(Popover3.Root, null, /* @__PURE__ */ React16.createElement(Popover3.Trigger, {
1961
+ return /* @__PURE__ */ React20.createElement(Popover3.Root, null, /* @__PURE__ */ React20.createElement(Popover3.Trigger, {
1696
1962
  asChild: true
1697
- }, /* @__PURE__ */ React16.createElement(StatusBar.Button, {
1963
+ }, /* @__PURE__ */ React20.createElement(StatusBar.Button, {
1698
1964
  title
1699
- }, icon)), /* @__PURE__ */ React16.createElement(Popover3.Portal, null, /* @__PURE__ */ React16.createElement(Popover3.Content, {
1965
+ }, icon)), /* @__PURE__ */ React20.createElement(Popover3.Portal, null, /* @__PURE__ */ React20.createElement(Popover3.Content, {
1700
1966
  sideOffset: 16
1701
- }, /* @__PURE__ */ React16.createElement(SyncStatusDetail, {
1967
+ }, /* @__PURE__ */ React20.createElement(SyncStatusDetail, {
1702
1968
  state,
1703
1969
  summary,
1704
1970
  debug: false
@@ -1706,17 +1972,36 @@ var SyncStatusIndicator = ({ state, saved }) => {
1706
1972
  }
1707
1973
  };
1708
1974
  var SyncStatusDetail = ({ classNames, state, summary, debug }) => {
1709
- const { t } = useTranslation15(SPACE_PLUGIN);
1710
- const entries = Object.entries(state).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
1711
- return /* @__PURE__ */ React16.createElement("div", {
1712
- className: mx5("flex flex-col gap-3 p-2 text-xs min-w-[16rem]", classNames)
1713
- }, /* @__PURE__ */ React16.createElement("h1", null, t("sync status title")), /* @__PURE__ */ React16.createElement("div", {
1975
+ const [showAll, setShowAll] = useState12(false);
1976
+ const { t } = useTranslation20(SPACE_PLUGIN);
1977
+ const entries = Object.entries(state).filter(([_, value]) => showAll || value.missingOnLocal + value.missingOnRemote > 0).toSorted(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
1978
+ const handleCheckedChange = useCallback9((state2) => setShowAll(state2), [
1979
+ setShowAll
1980
+ ]);
1981
+ return /* @__PURE__ */ React20.createElement("div", {
1982
+ className: mx5("flex flex-col gap-3 p-2 text-xs min-w-96", classNames)
1983
+ }, /* @__PURE__ */ React20.createElement("div", {
1984
+ role: "none",
1985
+ className: "flex items-center"
1986
+ }, /* @__PURE__ */ React20.createElement("h1", {
1987
+ className: "flex-1"
1988
+ }, t("sync status title")), /* @__PURE__ */ React20.createElement("div", {
1989
+ className: "flex items-center gap-2"
1990
+ }, /* @__PURE__ */ React20.createElement(Input7.Root, null, /* @__PURE__ */ React20.createElement(Input7.Label, {
1991
+ classNames: "text-xs"
1992
+ }, t("show all label")), /* @__PURE__ */ React20.createElement(Input7.Checkbox, {
1993
+ checked: showAll,
1994
+ onCheckedChange: handleCheckedChange
1995
+ })))), /* @__PURE__ */ React20.createElement("div", {
1714
1996
  className: "flex flex-col gap-2"
1715
- }, entries.map(([spaceId, state2]) => /* @__PURE__ */ React16.createElement(SpaceRow, {
1997
+ }, entries.length === 0 && /* @__PURE__ */ React20.createElement("div", {
1998
+ role: "none",
1999
+ className: "flex justify-center"
2000
+ }, t("no sync status label")), entries.map(([spaceId, state2]) => /* @__PURE__ */ React20.createElement(SpaceRowContainer, {
1716
2001
  key: spaceId,
1717
2002
  spaceId,
1718
2003
  state: state2
1719
- }))), debug && /* @__PURE__ */ React16.createElement(SyntaxHighlighter, {
2004
+ }))), debug && /* @__PURE__ */ React20.createElement(SyntaxHighlighter, {
1720
2005
  language: "json"
1721
2006
  }, JSON.stringify(summary, null, 2)));
1722
2007
  };
@@ -1725,6 +2010,9 @@ var SyncStatusDetail = ({ classNames, state, summary, debug }) => {
1725
2010
  var translations_default = [
1726
2011
  {
1727
2012
  "en-US": {
2013
+ [CollectionType.typename]: {
2014
+ "typename label": "Collection"
2015
+ },
1728
2016
  [SPACE_PLUGIN]: {
1729
2017
  "plugin name": "Spaces",
1730
2018
  "first run message": "Nothing selected.",
@@ -1818,7 +2106,18 @@ var translations_default = [
1818
2106
  "open settings panel label": "Show Settings",
1819
2107
  "open space settings label": "Space Settings",
1820
2108
  "members tab label": "Members",
1821
- "settings tab label": "Settings"
2109
+ "settings tab label": "Settings",
2110
+ "syncing message": "Space syncing",
2111
+ "show all label": "Show all",
2112
+ "no sync status label": "No space with missing objects.",
2113
+ "create space dialog title": "Create Space",
2114
+ "create object dialog title": "Create Object",
2115
+ "space input placeholder": "Select space",
2116
+ "schema input placeholder": "Select object type",
2117
+ "creating object type label": "Type",
2118
+ "creating in space label": "In Space",
2119
+ "creating in collection label": "In Collection",
2120
+ "clear input label": "Clear"
1822
2121
  }
1823
2122
  }
1824
2123
  }
@@ -1832,9 +2131,7 @@ var SPACE_MAX_OBJECTS = 500;
1832
2131
  var DIRECTORY_TYPE = "text/directory";
1833
2132
  var parseSpacePlugin = (plugin) => Array.isArray(plugin?.provides.space?.enabled) ? plugin : void 0;
1834
2133
  var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "spaceInvitationCode", firstRun, onFirstRun } = {}) => {
1835
- const settings = new LocalStorageStore(SPACE_PLUGIN, {
1836
- onSpaceCreate: "dxos.org/plugin/markdown/action/create"
1837
- });
2134
+ const settings = new LocalStorageStore(SPACE_PLUGIN, {});
1838
2135
  const state = new LocalStorageStore(SPACE_PLUGIN, {
1839
2136
  awaiting: void 0,
1840
2137
  spaceNames: {},
@@ -1842,17 +2139,20 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
1842
2139
  // TODO(wittjosiah): Stop using (Complex)Map inside reactive object.
1843
2140
  viewersByIdentity: new ComplexMap2(PublicKey2.hash),
1844
2141
  sdkMigrationRunning: {},
1845
- navigableCollections: false
2142
+ navigableCollections: false,
2143
+ enabledEdgeReplication: false
1846
2144
  });
1847
2145
  const subscriptions = new EventSubscriptions();
1848
2146
  const spaceSubscriptions = new EventSubscriptions();
1849
2147
  const graphSubscriptions = /* @__PURE__ */ new Map();
2148
+ const schemas = [];
1850
2149
  let clientPlugin;
1851
2150
  let graphPlugin;
1852
2151
  let intentPlugin;
1853
2152
  let layoutPlugin;
1854
2153
  let navigationPlugin;
1855
2154
  let attentionPlugin;
2155
+ let metadataPlugin;
1856
2156
  const createSpaceInvitationUrl = (invitationCode) => {
1857
2157
  const baseUrl = new URL(invitationUrl);
1858
2158
  baseUrl.searchParams.set(invitationParam, invitationCode);
@@ -1872,11 +2172,11 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
1872
2172
  if (typeof defaultSpace.properties[COMPOSER_SPACE_LOCK] !== "boolean") {
1873
2173
  defaultSpace.properties[COMPOSER_SPACE_LOCK] = true;
1874
2174
  }
1875
- const { objects: [spacesOrder] } = await defaultSpace.db.query(Filter.schema(Expando, {
2175
+ const { objects: [spacesOrder] } = await defaultSpace.db.query(Filter3.schema(Expando, {
1876
2176
  key: SHARED
1877
2177
  })).run();
1878
2178
  if (!spacesOrder) {
1879
- defaultSpace.db.add(create2({
2179
+ defaultSpace.db.add(create({
1880
2180
  key: SHARED,
1881
2181
  order: []
1882
2182
  }));
@@ -1916,25 +2216,42 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
1916
2216
  });
1917
2217
  }).unsubscribe);
1918
2218
  subscriptions.add(scheduledEffect(() => ({
1919
- ids: openIds(location.active),
1920
- removed: location.closed ? [
1921
- location.closed
1922
- ].flat() : []
1923
- }), ({ ids, removed }) => {
2219
+ open: openIds(location.active, layout.layoutMode === "solo" ? [
2220
+ "solo"
2221
+ ] : [
2222
+ "main"
2223
+ ]),
2224
+ closed: [
2225
+ ...location.closed
2226
+ ]
2227
+ }), ({ open, closed }) => {
1924
2228
  const send = () => {
1925
2229
  const spaces = client.spaces.get();
1926
2230
  const identity = client.halo.identity.get();
1927
2231
  if (identity && location.active) {
1928
- const idsBySpace = reduceGroupBy(ids, (id) => {
1929
- const [spaceId] = id.split(":");
1930
- return spaceId;
2232
+ const idsBySpace = reduceGroupBy(open, (id) => {
2233
+ try {
2234
+ const [spaceId] = parseFullyQualifiedId(id);
2235
+ return spaceId;
2236
+ } catch {
2237
+ return null;
2238
+ }
2239
+ });
2240
+ const removedBySpace = reduceGroupBy(closed, (id) => {
2241
+ try {
2242
+ const [spaceId] = parseFullyQualifiedId(id);
2243
+ return spaceId;
2244
+ } catch {
2245
+ return null;
2246
+ }
1931
2247
  });
1932
2248
  for (const space of spaces) {
1933
2249
  if (!idsBySpace.has(space.id)) {
1934
2250
  idsBySpace.set(space.id, []);
1935
2251
  }
1936
2252
  }
1937
- for (const [spaceId, ids2] of idsBySpace) {
2253
+ for (const [spaceId, added] of idsBySpace) {
2254
+ const removed = removedBySpace.get(spaceId) ?? [];
1938
2255
  const space = spaces.find((space2) => space2.id === spaceId);
1939
2256
  if (!space) {
1940
2257
  continue;
@@ -1944,15 +2261,14 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
1944
2261
  attended: attention.attended ? [
1945
2262
  ...attention.attended
1946
2263
  ] : [],
1947
- added: ids2,
1948
- // TODO(Zan): When we re-open a part, we should remove it from the removed list in the navigation plugin.
1949
- removed: removed.filter((id) => !ids2.includes(id))
2264
+ added,
2265
+ removed
1950
2266
  }).catch((err) => {
1951
2267
  log3.warn("Failed to broadcast active node for presence.", {
1952
2268
  err: err.message
1953
2269
  }, {
1954
2270
  F: __dxlog_file6,
1955
- L: 294,
2271
+ L: 320,
1956
2272
  S: void 0,
1957
2273
  C: (f, a) => f(...a)
1958
2274
  });
@@ -1970,7 +2286,8 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
1970
2286
  spaceSubscriptions.add(space.listen("viewing", (message) => {
1971
2287
  const { added, removed, attended } = message.payload;
1972
2288
  const identityKey = PublicKey2.safeFrom(message.payload.identityKey);
1973
- if (identityKey && Array.isArray(added) && Array.isArray(removed)) {
2289
+ const currentIdentity = client.halo.identity.get();
2290
+ if (identityKey && !currentIdentity?.identityKey.equals(identityKey) && Array.isArray(added) && Array.isArray(removed)) {
1974
2291
  added.forEach((id) => {
1975
2292
  if (typeof id === "string") {
1976
2293
  if (!(id in state.values.viewersByObject)) {
@@ -1997,6 +2314,19 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
1997
2314
  });
1998
2315
  }).unsubscribe);
1999
2316
  };
2317
+ const setEdgeReplicationDefault = async (client) => {
2318
+ try {
2319
+ await Promise.all(client.spaces.get().map((space) => space.internal.setEdgeReplicationPreference(EdgeReplicationSetting3.ENABLED)));
2320
+ state.values.enabledEdgeReplication = true;
2321
+ } catch (err) {
2322
+ log3.catch(err, void 0, {
2323
+ F: __dxlog_file6,
2324
+ L: 389,
2325
+ S: void 0,
2326
+ C: (f, a) => f(...a)
2327
+ });
2328
+ }
2329
+ };
2000
2330
  return {
2001
2331
  meta: meta_default,
2002
2332
  ready: async (plugins) => {
@@ -2009,12 +2339,16 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2009
2339
  state.prop({
2010
2340
  key: "spaceNames",
2011
2341
  type: LocalStorageStore.json()
2342
+ }).prop({
2343
+ key: "enabledEdgeReplication",
2344
+ type: LocalStorageStore.bool()
2012
2345
  });
2013
2346
  if (findPlugin(plugins, "dxos.org/plugin/stack")) {
2014
2347
  state.values.navigableCollections = true;
2015
2348
  }
2016
2349
  graphPlugin = resolvePlugin(plugins, parseGraphPlugin);
2017
2350
  layoutPlugin = resolvePlugin(plugins, parseLayoutPlugin);
2351
+ metadataPlugin = resolvePlugin(plugins, parseMetadataResolverPlugin);
2018
2352
  navigationPlugin = resolvePlugin(plugins, parseNavigationPlugin2);
2019
2353
  attentionPlugin = resolvePlugin(plugins, parseAttentionPlugin);
2020
2354
  clientPlugin = resolvePlugin(plugins, parseClientPlugin);
@@ -2024,9 +2358,21 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2024
2358
  }
2025
2359
  const client = clientPlugin.provides.client;
2026
2360
  const dispatch = intentPlugin.provides.intent.dispatch;
2361
+ schemas.push(...filterPlugins(plugins, parseSchemaPlugin).map((plugin) => plugin.provides.echo.schema).filter(nonNullable2).reduce((acc, schema) => {
2362
+ return [
2363
+ ...acc,
2364
+ ...schema
2365
+ ];
2366
+ }));
2367
+ client.addTypes(schemas);
2368
+ filterPlugins(plugins, parseSchemaPlugin).forEach((plugin) => {
2369
+ if (plugin.provides.echo.system) {
2370
+ client.addTypes(plugin.provides.echo.system);
2371
+ }
2372
+ });
2027
2373
  const handleFirstRun = async () => {
2028
2374
  const defaultSpace = client.spaces.default;
2029
- defaultSpace.properties[CollectionType.typename] = create2(CollectionType, {
2375
+ defaultSpace.properties[CollectionType.typename] = create(CollectionType, {
2030
2376
  objects: [],
2031
2377
  views: {}
2032
2378
  });
@@ -2047,6 +2393,7 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2047
2393
  await handleFirstRun();
2048
2394
  }
2049
2395
  await onSpaceReady();
2396
+ await setEdgeReplicationDefault(client);
2050
2397
  }
2051
2398
  }).unsubscribe);
2052
2399
  },
@@ -2078,12 +2425,13 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2078
2425
  }
2079
2426
  ]
2080
2427
  },
2081
- root: () => state.values.awaiting ? /* @__PURE__ */ React17.createElement(AwaitingObject, {
2428
+ root: () => state.values.awaiting ? /* @__PURE__ */ React21.createElement(AwaitingObject, {
2082
2429
  id: state.values.awaiting
2083
2430
  }) : null,
2084
2431
  metadata: {
2085
2432
  records: {
2086
2433
  [CollectionType.typename]: {
2434
+ createObject: CollectionAction.CREATE,
2087
2435
  placeholder: [
2088
2436
  "unnamed collection label",
2089
2437
  {
@@ -2108,7 +2456,7 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2108
2456
  component: ({ data, role, ...rest }) => {
2109
2457
  switch (role) {
2110
2458
  case "article":
2111
- return isSpace2(data.object) && data.object.state.get() === SpaceState2.SPACE_READY ? /* @__PURE__ */ React17.createElement(Surface, {
2459
+ return isSpace4(data.object) && data.object.state.get() === SpaceState2.SPACE_READY ? /* @__PURE__ */ React21.createElement(Surface, {
2112
2460
  data: {
2113
2461
  object: data.object.properties[CollectionType.typename],
2114
2462
  id: data.object.id
@@ -2116,89 +2464,100 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2116
2464
  role,
2117
2465
  ...rest
2118
2466
  }) : data.object instanceof CollectionType ? {
2119
- node: /* @__PURE__ */ React17.createElement(CollectionMain, {
2467
+ node: /* @__PURE__ */ React21.createElement(CollectionMain, {
2120
2468
  collection: data.object
2121
2469
  }),
2122
2470
  disposition: "fallback"
2123
2471
  } : null;
2472
+ // TODO(burdon): Add role name syntax to minimal plugin docs.
2124
2473
  case "complementary--settings":
2125
- return isSpace2(data.subject) ? /* @__PURE__ */ React17.createElement(SpaceSettingsPanel, {
2474
+ return isSpace4(data.subject) ? /* @__PURE__ */ React21.createElement(SpaceSettingsPanel, {
2126
2475
  space: data.subject
2127
2476
  }) : isEchoObject2(data.subject) ? {
2128
- node: /* @__PURE__ */ React17.createElement(DefaultObjectSettings, {
2477
+ node: /* @__PURE__ */ React21.createElement(DefaultObjectSettings, {
2129
2478
  object: data.subject
2130
2479
  }),
2131
2480
  disposition: "fallback"
2132
2481
  } : null;
2133
2482
  case "dialog":
2134
2483
  if (data.component === "dxos.org/plugin/space/SpaceSettingsDialog") {
2135
- return /* @__PURE__ */ React17.createElement(SpaceSettingsDialog, {
2484
+ return /* @__PURE__ */ React21.createElement(SpaceSettingsDialog, {
2136
2485
  ...data.subject,
2137
2486
  createInvitationUrl: createSpaceInvitationUrl
2138
2487
  });
2139
2488
  } else if (data.component === "dxos.org/plugin/space/JoinDialog") {
2140
- return /* @__PURE__ */ React17.createElement(JoinDialog, data.subject);
2489
+ return /* @__PURE__ */ React21.createElement(JoinDialog, data.subject);
2490
+ } else if (data.component === "dxos.org/plugin/space/CreateSpaceDialog") {
2491
+ return /* @__PURE__ */ React21.createElement(CreateSpaceDialog, null);
2492
+ } else if (data.component === "dxos.org/plugin/space/CreateObjectDialog") {
2493
+ return /* @__PURE__ */ React21.createElement(CreateObjectDialog, {
2494
+ ...data.subject,
2495
+ schemas,
2496
+ navigableCollections: state.values.navigableCollections,
2497
+ resolve: metadataPlugin?.provides.metadata.resolver
2498
+ });
2141
2499
  }
2142
2500
  return null;
2143
2501
  case "popover": {
2144
- if (data.component === "dxos.org/plugin/space/RenameSpacePopover" && isSpace2(data.subject)) {
2145
- return /* @__PURE__ */ React17.createElement(PopoverRenameSpace, {
2502
+ if (data.component === "dxos.org/plugin/space/RenameSpacePopover" && isSpace4(data.subject)) {
2503
+ return /* @__PURE__ */ React21.createElement(PopoverRenameSpace, {
2146
2504
  space: data.subject
2147
2505
  });
2148
2506
  }
2149
- if (data.component === "dxos.org/plugin/space/RenameObjectPopover" && isReactiveObject2(data.subject)) {
2150
- return /* @__PURE__ */ React17.createElement(PopoverRenameObject, {
2507
+ if (data.component === "dxos.org/plugin/space/RenameObjectPopover" && isReactiveObject3(data.subject)) {
2508
+ return /* @__PURE__ */ React21.createElement(PopoverRenameObject, {
2151
2509
  object: data.subject
2152
2510
  });
2153
2511
  }
2154
2512
  return null;
2155
2513
  }
2156
- // TODO(burdon): Add role name syntax to minimal plugin docs.
2157
- case "presence--glyph": {
2158
- return isReactiveObject2(data.object) ? /* @__PURE__ */ React17.createElement(SmallPresenceLive, {
2514
+ case "navtree-item-end": {
2515
+ return isReactiveObject3(data.object) ? /* @__PURE__ */ React21.createElement(SmallPresenceLive, {
2159
2516
  id: data.id,
2160
2517
  viewers: state.values.viewersByObject[fullyQualifiedId4(data.object)]
2161
- }) : /* @__PURE__ */ React17.createElement(SmallPresence, {
2162
- id: data.id,
2163
- count: 0
2164
- });
2165
- }
2166
- case "navbar-start": {
2167
- return null;
2518
+ }) : isSpace4(data.object) ? /* @__PURE__ */ React21.createElement(InlineSyncStatus, {
2519
+ space: data.object
2520
+ }) : (
2521
+ // TODO(wittjosiah): Attention glyph for non-echo items should be handled elsewhere.
2522
+ /* @__PURE__ */ React21.createElement(SmallPresence, {
2523
+ id: data.id,
2524
+ count: 0
2525
+ })
2526
+ );
2168
2527
  }
2169
2528
  case "navbar-end": {
2170
- if (!isEchoObject2(data.object) && !isSpace2(data.object)) {
2529
+ if (!isEchoObject2(data.object) && !isSpace4(data.object)) {
2171
2530
  return null;
2172
2531
  }
2173
- const space = isSpace2(data.object) ? data.object : getSpace4(data.object);
2174
- const object = isSpace2(data.object) ? data.object.state.get() === SpaceState2.SPACE_READY ? space?.properties[CollectionType.typename] : void 0 : data.object;
2532
+ const space = isSpace4(data.object) ? data.object : getSpace4(data.object);
2533
+ const object = isSpace4(data.object) ? data.object.state.get() === SpaceState2.SPACE_READY ? space?.properties[CollectionType.typename] : void 0 : data.object;
2175
2534
  return space && object ? {
2176
- node: /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement(SpacePresence, {
2535
+ node: /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement(SpacePresence, {
2177
2536
  object
2178
- }), space.properties[COMPOSER_SPACE_LOCK] ? null : /* @__PURE__ */ React17.createElement(ShareSpaceButton, {
2537
+ }), space.properties[COMPOSER_SPACE_LOCK] ? null : /* @__PURE__ */ React21.createElement(ShareSpaceButton, {
2179
2538
  space
2180
2539
  })),
2181
2540
  disposition: "hoist"
2182
2541
  } : null;
2183
2542
  }
2184
2543
  case "section":
2185
- return data.object instanceof CollectionType ? /* @__PURE__ */ React17.createElement(CollectionSection, {
2544
+ return data.object instanceof CollectionType ? /* @__PURE__ */ React21.createElement(CollectionSection, {
2186
2545
  collection: data.object
2187
2546
  }) : null;
2188
2547
  case "settings":
2189
- return data.plugin === meta_default.id ? /* @__PURE__ */ React17.createElement(SpacePluginSettings, {
2548
+ return data.plugin === meta_default.id ? /* @__PURE__ */ React21.createElement(SpacePluginSettings, {
2190
2549
  settings: settings.values
2191
2550
  }) : null;
2192
2551
  case "menu-footer":
2193
2552
  if (isEchoObject2(data.object)) {
2194
- return /* @__PURE__ */ React17.createElement(MenuFooter, {
2553
+ return /* @__PURE__ */ React21.createElement(MenuFooter, {
2195
2554
  object: data.object
2196
2555
  });
2197
2556
  } else {
2198
2557
  return null;
2199
2558
  }
2200
2559
  case "status": {
2201
- return /* @__PURE__ */ React17.createElement(SyncStatus, null);
2560
+ return /* @__PURE__ */ React21.createElement(SyncStatus, null);
2202
2561
  }
2203
2562
  default:
2204
2563
  return null;
@@ -2208,11 +2567,11 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2208
2567
  graph: {
2209
2568
  builder: (plugins) => {
2210
2569
  const clientPlugin2 = resolvePlugin(plugins, parseClientPlugin);
2211
- const metadataPlugin = resolvePlugin(plugins, parseMetadataResolverPlugin);
2570
+ const metadataPlugin2 = resolvePlugin(plugins, parseMetadataResolverPlugin);
2212
2571
  const graphPlugin2 = resolvePlugin(plugins, parseGraphPlugin);
2213
2572
  const client = clientPlugin2?.provides.client;
2214
2573
  const dispatch = intentPlugin?.provides.intent.dispatch;
2215
- const resolve = metadataPlugin?.provides.metadata.resolver;
2574
+ const resolve = metadataPlugin2?.provides.metadata.resolver;
2216
2575
  const graph = graphPlugin2?.provides.graph;
2217
2576
  if (!client || !dispatch || !resolve || !graph) {
2218
2577
  return [];
@@ -2256,7 +2615,7 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2256
2615
  childrenPersistenceClass: "echo",
2257
2616
  onRearrangeChildren: async (nextOrder) => {
2258
2617
  graph._sortEdges(SPACES, "outbound", nextOrder.map(({ id }) => id));
2259
- const { objects: [spacesOrder] } = await client.spaces.default.db.query(Filter.schema(Expando, {
2618
+ const { objects: [spacesOrder] } = await client.spaces.default.db.query(Filter3.schema(Expando, {
2260
2619
  key: SHARED
2261
2620
  })).run();
2262
2621
  if (spacesOrder) {
@@ -2264,7 +2623,7 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2264
2623
  } else {
2265
2624
  log3.warn("spaces order object not found", void 0, {
2266
2625
  F: __dxlog_file6,
2267
- L: 599,
2626
+ L: 674,
2268
2627
  S: void 0,
2269
2628
  C: (f, a) => f(...a)
2270
2629
  });
@@ -2281,11 +2640,11 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2281
2640
  filter: (node) => node.id === SPACES,
2282
2641
  actions: () => [
2283
2642
  {
2284
- id: SpaceAction.CREATE,
2643
+ id: SpaceAction.OPEN_CREATE_SPACE,
2285
2644
  data: async () => {
2286
2645
  await dispatch({
2287
2646
  plugin: SPACE_PLUGIN,
2288
- action: SpaceAction.CREATE
2647
+ action: SpaceAction.OPEN_CREATE_SPACE
2289
2648
  });
2290
2649
  },
2291
2650
  properties: {
@@ -2296,8 +2655,8 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2296
2655
  }
2297
2656
  ],
2298
2657
  icon: "ph--plus--regular",
2299
- disposition: "item",
2300
2658
  testId: "spacePlugin.createSpace",
2659
+ disposition: "item",
2301
2660
  className: "border-t border-separator"
2302
2661
  }
2303
2662
  },
@@ -2317,8 +2676,8 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2317
2676
  }
2318
2677
  ],
2319
2678
  icon: "ph--sign-in--regular",
2320
- disposition: "item",
2321
- testId: "spacePlugin.joinSpace"
2679
+ testId: "spacePlugin.joinSpace",
2680
+ disposition: "item"
2322
2681
  }
2323
2682
  }
2324
2683
  ],
@@ -2329,7 +2688,7 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2329
2688
  return;
2330
2689
  }
2331
2690
  try {
2332
- const [spacesOrder] = memoizeQuery(client.spaces.default, Filter.schema(Expando, {
2691
+ const [spacesOrder] = memoizeQuery(client.spaces.default, Filter3.schema(Expando, {
2333
2692
  key: SHARED
2334
2693
  }));
2335
2694
  const order = spacesOrder?.order ?? [];
@@ -2376,15 +2735,10 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2376
2735
  }
2377
2736
  }
2378
2737
  }),
2379
- // Create space actions and action groups.
2738
+ // Create space actions.
2380
2739
  createExtension({
2381
2740
  id: `${SPACE_PLUGIN}/actions`,
2382
- filter: (node) => isSpace2(node.data),
2383
- actionGroups: ({ node }) => constructSpaceActionGroups({
2384
- space: node.data,
2385
- dispatch,
2386
- navigable: state.values.navigableCollections
2387
- }),
2741
+ filter: (node) => isSpace4(node.data),
2388
2742
  actions: ({ node }) => {
2389
2743
  const space = node.data;
2390
2744
  return constructSpaceActions({
@@ -2398,7 +2752,7 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2398
2752
  // Create nodes for objects in the root collection of a space.
2399
2753
  createExtension({
2400
2754
  id: `${SPACE_PLUGIN}/root-collection`,
2401
- filter: (node) => isSpace2(node.data),
2755
+ filter: (node) => isSpace4(node.data),
2402
2756
  connector: ({ node }) => {
2403
2757
  const space = node.data;
2404
2758
  const spaceState = toSignal((onChange) => space.state.subscribe(() => onChange()).unsubscribe, () => space.state.get(), space.id);
@@ -2409,12 +2763,12 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2409
2763
  if (!collection) {
2410
2764
  return;
2411
2765
  }
2412
- return collection.objects.filter(nonNullable).map((object) => createObjectNode({
2766
+ return collection.objects.filter(nonNullable2).map((object) => createObjectNode({
2413
2767
  object,
2414
2768
  space,
2415
2769
  resolve,
2416
2770
  navigable: state.values.navigableCollections
2417
- })).filter(nonNullable);
2771
+ })).filter(nonNullable2);
2418
2772
  }
2419
2773
  }),
2420
2774
  // Create nodes for objects in a collection or by its fully qualified id.
@@ -2427,12 +2781,12 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2427
2781
  if (!space) {
2428
2782
  return;
2429
2783
  }
2430
- return collection.objects.filter(nonNullable).map((object) => createObjectNode({
2784
+ return collection.objects.filter(nonNullable2).map((object) => createObjectNode({
2431
2785
  object,
2432
2786
  space,
2433
2787
  resolve,
2434
2788
  navigable: state.values.navigableCollections
2435
- })).filter(nonNullable);
2789
+ })).filter(nonNullable2);
2436
2790
  },
2437
2791
  resolver: ({ id }) => {
2438
2792
  if (id.length !== FQ_ID_LENGTH) {
@@ -2455,7 +2809,14 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2455
2809
  if (!store.value) {
2456
2810
  void space.db.query({
2457
2811
  id: objectId
2458
- }).first().then((o) => store.value = o);
2812
+ }).first().then((o) => store.value = o).catch((err) => log3.catch(err, {
2813
+ objectId
2814
+ }, {
2815
+ F: __dxlog_file6,
2816
+ L: 891,
2817
+ S: void 0,
2818
+ C: (f, a) => f(...a)
2819
+ }));
2459
2820
  }
2460
2821
  }, id);
2461
2822
  const object = store.value;
@@ -2478,11 +2839,6 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2478
2839
  createExtension({
2479
2840
  id: `${SPACE_PLUGIN}/object-actions`,
2480
2841
  filter: (node) => isEchoObject2(node.data),
2481
- actionGroups: ({ node }) => constructObjectActionGroups({
2482
- object: node.data,
2483
- dispatch,
2484
- navigable: state.values.navigableCollections
2485
- }),
2486
2842
  actions: ({ node }) => constructObjectActions({
2487
2843
  node,
2488
2844
  dispatch
@@ -2526,15 +2882,9 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2526
2882
  }
2527
2883
  };
2528
2884
  }
2529
- const object = toSignal((onChange) => {
2530
- const timeout = setTimeout(async () => {
2531
- await space?.db.query({
2532
- id: objectId
2533
- }).first();
2534
- onChange();
2535
- });
2536
- return () => clearTimeout(timeout);
2537
- }, () => space?.db.getObjectById(objectId), subjectId);
2885
+ const [object] = memoizeQuery(space, {
2886
+ id: objectId
2887
+ });
2538
2888
  if (!object || !subjectId) {
2539
2889
  return;
2540
2890
  }
@@ -2604,7 +2954,7 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2604
2954
  type: DIRECTORY_TYPE
2605
2955
  }),
2606
2956
  deserialize: async (data, ancestors) => {
2607
- const space = ancestors.find(isSpace2);
2957
+ const space = ancestors.find(isSpace4);
2608
2958
  const collection = ancestors.findLast((ancestor) => ancestor instanceof CollectionType) ?? space?.properties[CollectionType.typename];
2609
2959
  if (!space || !collection) {
2610
2960
  return;
@@ -2614,7 +2964,7 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2614
2964
  action: SpaceAction.ADD_OBJECT,
2615
2965
  data: {
2616
2966
  target: collection,
2617
- object: create2(CollectionType, {
2967
+ object: create(CollectionType, {
2618
2968
  name: data.name,
2619
2969
  objects: [],
2620
2970
  views: {}
@@ -2638,13 +2988,36 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2638
2988
  data: true
2639
2989
  };
2640
2990
  }
2991
+ case SpaceAction.OPEN_CREATE_SPACE: {
2992
+ return {
2993
+ data: true,
2994
+ intents: [
2995
+ [
2996
+ {
2997
+ action: LayoutAction2.SET_LAYOUT,
2998
+ data: {
2999
+ element: "dialog",
3000
+ component: "dxos.org/plugin/space/CreateSpaceDialog",
3001
+ dialogBlockAlign: "start",
3002
+ subject: intent.data
3003
+ }
3004
+ }
3005
+ ]
3006
+ ]
3007
+ };
3008
+ }
2641
3009
  case SpaceAction.CREATE: {
2642
- if (!client) {
3010
+ if (!client || !S2.is(SpaceForm)(intent.data)) {
2643
3011
  return;
2644
3012
  }
2645
- const space = await client.spaces.create(intent.data);
3013
+ const space = await client.spaces.create({
3014
+ name: intent.data.name
3015
+ });
3016
+ if (intent.data.edgeReplication) {
3017
+ await space.internal.setEdgeReplicationPreference(EdgeReplicationSetting3.ENABLED);
3018
+ }
2646
3019
  await space.waitUntilReady();
2647
- const collection = create2(CollectionType, {
3020
+ const collection = create(CollectionType, {
2648
3021
  objects: [],
2649
3022
  views: {}
2650
3023
  });
@@ -2663,28 +3036,6 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2663
3036
  }
2664
3037
  },
2665
3038
  intents: [
2666
- ...settings.values.onSpaceCreate ? [
2667
- [
2668
- {
2669
- action: settings.values.onSpaceCreate,
2670
- data: {
2671
- space
2672
- }
2673
- },
2674
- {
2675
- action: SpaceAction.ADD_OBJECT,
2676
- data: {
2677
- target: space
2678
- }
2679
- },
2680
- {
2681
- action: NavigationAction4.OPEN
2682
- },
2683
- {
2684
- action: NavigationAction4.EXPOSE
2685
- }
2686
- ]
2687
- ] : [],
2688
3039
  [
2689
3040
  {
2690
3041
  action: ObservabilityAction2.SEND_EVENT,
@@ -2721,7 +3072,7 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2721
3072
  }
2722
3073
  case SpaceAction.SHARE: {
2723
3074
  const space = intent.data?.space;
2724
- if (isSpace2(space) && !space.properties[COMPOSER_SPACE_LOCK]) {
3075
+ if (isSpace4(space) && !space.properties[COMPOSER_SPACE_LOCK]) {
2725
3076
  const active = navigationPlugin?.provides.location.active;
2726
3077
  const mode = layoutPlugin?.provides.layout.layoutMode;
2727
3078
  const current = active ? firstIdInPart(active, mode === "solo" ? "solo" : "main") : void 0;
@@ -2763,7 +3114,7 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2763
3114
  }
2764
3115
  case SpaceAction.LOCK: {
2765
3116
  const space = intent.data?.space;
2766
- if (isSpace2(space)) {
3117
+ if (isSpace4(space)) {
2767
3118
  space.properties[COMPOSER_SPACE_LOCK] = true;
2768
3119
  return {
2769
3120
  data: true,
@@ -2786,7 +3137,7 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2786
3137
  }
2787
3138
  case SpaceAction.UNLOCK: {
2788
3139
  const space = intent.data?.space;
2789
- if (isSpace2(space)) {
3140
+ if (isSpace4(space)) {
2790
3141
  space.properties[COMPOSER_SPACE_LOCK] = false;
2791
3142
  return {
2792
3143
  data: true,
@@ -2809,7 +3160,7 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2809
3160
  }
2810
3161
  case SpaceAction.RENAME: {
2811
3162
  const { caller, space } = intent.data ?? {};
2812
- if (typeof caller === "string" && isSpace2(space)) {
3163
+ if (typeof caller === "string" && isSpace4(space)) {
2813
3164
  return {
2814
3165
  intents: [
2815
3166
  [
@@ -2830,7 +3181,7 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2830
3181
  }
2831
3182
  case SpaceAction.OPEN_SETTINGS: {
2832
3183
  const space = intent.data?.space;
2833
- if (isSpace2(space)) {
3184
+ if (isSpace4(space)) {
2834
3185
  return {
2835
3186
  data: true,
2836
3187
  intents: [
@@ -2856,7 +3207,7 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2856
3207
  }
2857
3208
  case SpaceAction.OPEN: {
2858
3209
  const space = intent.data?.space;
2859
- if (isSpace2(space)) {
3210
+ if (isSpace4(space)) {
2860
3211
  await space.open();
2861
3212
  return {
2862
3213
  data: true
@@ -2866,7 +3217,7 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2866
3217
  }
2867
3218
  case SpaceAction.CLOSE: {
2868
3219
  const space = intent.data?.space;
2869
- if (isSpace2(space)) {
3220
+ if (isSpace4(space)) {
2870
3221
  await space.close();
2871
3222
  return {
2872
3223
  data: true
@@ -2876,7 +3227,7 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2876
3227
  }
2877
3228
  case SpaceAction.MIGRATE: {
2878
3229
  const space = intent.data?.space;
2879
- if (isSpace2(space)) {
3230
+ if (isSpace4(space)) {
2880
3231
  if (space.state.get() === SpaceState2.SPACE_REQUIRES_MIGRATION) {
2881
3232
  state.values.sdkMigrationRunning[space.id] = true;
2882
3233
  await space.internal.migrate();
@@ -2903,12 +3254,30 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2903
3254
  }
2904
3255
  break;
2905
3256
  }
3257
+ case SpaceAction.OPEN_CREATE_OBJECT: {
3258
+ return {
3259
+ data: true,
3260
+ intents: [
3261
+ [
3262
+ {
3263
+ action: LayoutAction2.SET_LAYOUT,
3264
+ data: {
3265
+ element: "dialog",
3266
+ component: "dxos.org/plugin/space/CreateObjectDialog",
3267
+ dialogBlockAlign: "start",
3268
+ subject: intent.data
3269
+ }
3270
+ }
3271
+ ]
3272
+ ]
3273
+ };
3274
+ }
2906
3275
  case SpaceAction.ADD_OBJECT: {
2907
3276
  const object = intent.data?.object ?? intent.data?.result;
2908
- if (!isReactiveObject2(object)) {
3277
+ if (!isReactiveObject3(object)) {
2909
3278
  return;
2910
3279
  }
2911
- const space = isSpace2(intent.data?.target) ? intent.data?.target : getSpace4(intent.data?.target);
3280
+ const space = isSpace4(intent.data?.target) ? intent.data?.target : getSpace4(intent.data?.target);
2912
3281
  if (!space) {
2913
3282
  return;
2914
3283
  }
@@ -2952,12 +3321,12 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2952
3321
  }
2953
3322
  if (intent.data?.target instanceof CollectionType) {
2954
3323
  intent.data?.target.objects.push(object);
2955
- } else if (isSpace2(intent.data?.target)) {
3324
+ } else if (isSpace4(intent.data?.target)) {
2956
3325
  const collection = space.properties[CollectionType.typename];
2957
3326
  if (collection instanceof CollectionType) {
2958
3327
  collection.objects.push(object);
2959
3328
  } else {
2960
- const collection2 = create2(CollectionType, {
3329
+ const collection2 = create(CollectionType, {
2961
3330
  objects: [
2962
3331
  object
2963
3332
  ],
@@ -2997,7 +3366,7 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
2997
3366
  const objects = intent.data?.objects ?? intent.data?.result;
2998
3367
  invariant2(Array.isArray(objects), void 0, {
2999
3368
  F: __dxlog_file6,
3000
- L: 1346,
3369
+ L: 1430,
3001
3370
  S: void 0,
3002
3371
  A: [
3003
3372
  "Array.isArray(objects)",
@@ -3091,7 +3460,7 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
3091
3460
  case SpaceAction.RENAME_OBJECT: {
3092
3461
  const object = intent.data?.object ?? intent.data?.result;
3093
3462
  const caller = intent.data?.caller;
3094
- if (isReactiveObject2(object) && caller) {
3463
+ if (isReactiveObject3(object) && caller) {
3095
3464
  return {
3096
3465
  intents: [
3097
3466
  [
@@ -3113,7 +3482,7 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
3113
3482
  case SpaceAction.DUPLICATE_OBJECT: {
3114
3483
  const originalObject = intent.data?.object ?? intent.data?.result;
3115
3484
  const resolve = resolvePlugin(plugins, parseMetadataResolverPlugin)?.provides.metadata.resolver;
3116
- const space = isSpace2(intent.data?.target) ? intent.data?.target : getSpace4(intent.data?.target);
3485
+ const space = isSpace4(intent.data?.target) ? intent.data?.target : getSpace4(intent.data?.target);
3117
3486
  if (!isEchoObject2(originalObject) || !resolve || !space) {
3118
3487
  return;
3119
3488
  }
@@ -3138,6 +3507,16 @@ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "
3138
3507
  data: true
3139
3508
  };
3140
3509
  }
3510
+ case CollectionAction.CREATE: {
3511
+ const collection = create(CollectionType, {
3512
+ name: intent.data?.name,
3513
+ objects: [],
3514
+ views: {}
3515
+ });
3516
+ return {
3517
+ data: collection
3518
+ };
3519
+ }
3141
3520
  }
3142
3521
  }
3143
3522
  }
@@ -3152,12 +3531,16 @@ export {
3152
3531
  AwaitingObject,
3153
3532
  COMPOSER_SPACE_LOCK,
3154
3533
  ChannelType,
3534
+ CollectionAction,
3155
3535
  CollectionMain,
3156
3536
  CollectionSection,
3157
3537
  CollectionType,
3158
3538
  ContactType,
3539
+ CreateObjectDialog,
3540
+ CreateSpaceDialog,
3159
3541
  DefaultObjectSettings,
3160
3542
  FullPresence,
3543
+ InlineSyncStatus,
3161
3544
  JoinDialog,
3162
3545
  MenuFooter,
3163
3546
  MessageState,
@@ -3176,6 +3559,7 @@ export {
3176
3559
  SmallPresence,
3177
3560
  SmallPresenceLive,
3178
3561
  SpaceAction,
3562
+ SpaceForm,
3179
3563
  SpacePlugin,
3180
3564
  SpacePluginSettings,
3181
3565
  SpacePresence,
@@ -3187,9 +3571,7 @@ export {
3187
3571
  ThreadStatus,
3188
3572
  ThreadType,
3189
3573
  cloneObject,
3190
- constructObjectActionGroups,
3191
3574
  constructObjectActions,
3192
- constructSpaceActionGroups,
3193
3575
  constructSpaceActions,
3194
3576
  constructSpaceNode,
3195
3577
  createObjectNode,
@@ -3198,7 +3580,7 @@ export {
3198
3580
  getNestedObjects,
3199
3581
  getSpaceDisplayName,
3200
3582
  memoizeQuery,
3201
- parseSpaceInitPlugin,
3583
+ parseSchemaPlugin,
3202
3584
  parseSpacePlugin,
3203
3585
  translations_default as translations
3204
3586
  };