@dxos/plugin-space 0.7.2 → 0.7.3-staging.0905f03

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