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