@dxos/plugin-space 0.6.14-main.7bd9c89 → 0.6.14-main.f49f251

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 (46) hide show
  1. package/dist/lib/browser/{chunk-47SVNCZM.mjs → chunk-FOI7DAUV.mjs} +1 -1
  2. package/dist/lib/browser/{chunk-47SVNCZM.mjs.map → chunk-FOI7DAUV.mjs.map} +2 -2
  3. package/dist/lib/browser/index.mjs +208 -108
  4. package/dist/lib/browser/index.mjs.map +4 -4
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/types/index.mjs +1 -1
  7. package/dist/lib/node/{chunk-CTYDNFGG.cjs → chunk-OTDRTHT4.cjs} +4 -4
  8. package/dist/lib/node/{chunk-CTYDNFGG.cjs.map → chunk-OTDRTHT4.cjs.map} +2 -2
  9. package/dist/lib/node/index.cjs +234 -135
  10. package/dist/lib/node/index.cjs.map +4 -4
  11. package/dist/lib/node/meta.json +1 -1
  12. package/dist/lib/node/types/index.cjs +11 -11
  13. package/dist/lib/node/types/index.cjs.map +1 -1
  14. package/dist/lib/node-esm/{chunk-PLPMYTLC.mjs → chunk-FYDGMPSC.mjs} +1 -1
  15. package/dist/lib/node-esm/{chunk-PLPMYTLC.mjs.map → chunk-FYDGMPSC.mjs.map} +2 -2
  16. package/dist/lib/node-esm/index.mjs +208 -108
  17. package/dist/lib/node-esm/index.mjs.map +4 -4
  18. package/dist/lib/node-esm/meta.json +1 -1
  19. package/dist/lib/node-esm/types/index.mjs +1 -1
  20. package/dist/types/src/SpacePlugin.d.ts.map +1 -1
  21. package/dist/types/src/components/DefaultObjectSettings.d.ts +1 -1
  22. package/dist/types/src/components/DefaultObjectSettings.d.ts.map +1 -1
  23. package/dist/types/src/components/SpacePresence.d.ts +4 -2
  24. package/dist/types/src/components/SpacePresence.d.ts.map +1 -1
  25. package/dist/types/src/components/SpaceSettingsPanel.d.ts +7 -0
  26. package/dist/types/src/components/SpaceSettingsPanel.d.ts.map +1 -0
  27. package/dist/types/src/components/SyncStatus/SyncStatus.stories.d.ts.map +1 -1
  28. package/dist/types/src/components/index.d.ts +1 -0
  29. package/dist/types/src/components/index.d.ts.map +1 -1
  30. package/dist/types/src/translations.d.ts +2 -0
  31. package/dist/types/src/translations.d.ts.map +1 -1
  32. package/dist/types/src/types/types.d.ts +3 -0
  33. package/dist/types/src/types/types.d.ts.map +1 -1
  34. package/dist/types/src/util.d.ts +1 -1
  35. package/dist/types/src/util.d.ts.map +1 -1
  36. package/package.json +40 -48
  37. package/src/SpacePlugin.tsx +62 -32
  38. package/src/components/DefaultObjectSettings.tsx +3 -2
  39. package/src/components/SpacePresence.tsx +33 -22
  40. package/src/components/SpaceSettings.tsx +5 -5
  41. package/src/components/SpaceSettingsPanel.tsx +59 -0
  42. package/src/components/SyncStatus/SyncStatus.tsx +1 -1
  43. package/src/components/index.ts +1 -0
  44. package/src/translations.ts +4 -2
  45. package/src/types/types.ts +3 -1
  46. package/src/util.tsx +3 -3
@@ -15,24 +15,24 @@ import {
15
15
  ThreadStatus,
16
16
  ThreadType,
17
17
  parseSpaceInitPlugin
18
- } from "./chunk-47SVNCZM.mjs";
18
+ } from "./chunk-FOI7DAUV.mjs";
19
19
 
20
20
  // packages/plugins/plugin-space/src/SpacePlugin.tsx
21
21
  import { signal } from "@preact/signals-core";
22
- import React17 from "react";
22
+ import React18 from "react";
23
23
  import { LayoutAction as LayoutAction2, NavigationAction as NavigationAction3, Surface as Surface2, firstIdInPart, openIds, parseGraphPlugin, parseIntentPlugin as parseIntentPlugin3, parseMetadataResolverPlugin, parseNavigationPlugin as parseNavigationPlugin2, resolvePlugin } from "@dxos/app-framework";
24
24
  import { EventSubscriptions } from "@dxos/async";
25
25
  import { isReactiveObject as isReactiveObject2 } from "@dxos/echo-schema";
26
26
  import { scheduledEffect } from "@dxos/echo-signals/core";
27
27
  import { LocalStorageStore } from "@dxos/local-storage";
28
- import { log as log2 } from "@dxos/log";
28
+ import { log as log3 } from "@dxos/log";
29
29
  import { Migrations as Migrations2 } from "@dxos/migrations";
30
30
  import { parseAttentionPlugin } from "@dxos/plugin-attention";
31
31
  import { parseClientPlugin } from "@dxos/plugin-client";
32
32
  import { createExtension, memoize as memoize2, toSignal } from "@dxos/plugin-graph";
33
33
  import { ObservabilityAction } from "@dxos/plugin-observability/meta";
34
34
  import { PublicKey as PublicKey2 } from "@dxos/react-client";
35
- import { Expando, Filter, SpaceState as SpaceState3, create as create2, fullyQualifiedId as fullyQualifiedId4, getSpace as getSpace4, getTypename as getTypename2, isEchoObject as isEchoObject2, isSpace as isSpace2, loadObjectReferences, parseFullyQualifiedId } from "@dxos/react-client/echo";
35
+ import { Expando, Filter, SpaceState as SpaceState3, create as create2, fullyQualifiedId as fullyQualifiedId4, getSpace as getSpace4, getTypename as getTypename2, isEchoObject as isEchoObject2, isSpace as isSpace2, loadObjectReferences, parseId } from "@dxos/react-client/echo";
36
36
  import { Dialog } from "@dxos/react-ui";
37
37
  import { ClipboardProvider as ClipboardProvider2, InvitationManager, osTranslations } from "@dxos/shell/react";
38
38
  import { ComplexMap as ComplexMap2, nonNullable, reduceGroupBy } from "@dxos/util";
@@ -170,7 +170,7 @@ var DefaultObjectSettings = ({ object }) => {
170
170
  className: "flex flex-col w-full p-2 gap-1"
171
171
  }, /* @__PURE__ */ React4.createElement(Input.Root, null, /* @__PURE__ */ React4.createElement(Input.Label, null, t("name label")), /* @__PURE__ */ React4.createElement(Input.TextInput, {
172
172
  placeholder: t("name placeholder"),
173
- value: object.name,
173
+ value: object.name ?? "",
174
174
  onChange: (event) => {
175
175
  object.name = event.target.value;
176
176
  }
@@ -245,7 +245,7 @@ var getCollectionGraphNodePartials = ({ collection, space, resolve }) => {
245
245
  }
246
246
  },
247
247
  onCopy: async (child, index) => {
248
- const newObject = await cloneObject(child.data, resolve);
248
+ const newObject = await cloneObject(child.data, resolve, space);
249
249
  space.db.add(newObject);
250
250
  if (typeof index !== "undefined") {
251
251
  collection.objects.splice(index, 0, newObject);
@@ -715,7 +715,7 @@ var getNestedObjects = async (object, resolve) => {
715
715
  ...nested.flat()
716
716
  ];
717
717
  };
718
- var cloneObject = async (object, resolve) => {
718
+ var cloneObject = async (object, resolve, newSpace) => {
719
719
  const schema = getSchema(object);
720
720
  const typename = schema ? getObjectAnnotation(schema)?.typename ?? EXPANDO_TYPENAME : EXPANDO_TYPENAME;
721
721
  const metadata = resolve(typename);
@@ -734,6 +734,7 @@ var cloneObject = async (object, resolve) => {
734
734
  });
735
735
  return serializer.deserialize({
736
736
  content,
737
+ space: newSpace,
737
738
  newId: true
738
739
  });
739
740
  };
@@ -1220,15 +1221,14 @@ import { generateName } from "@dxos/display-name";
1220
1221
  import { PublicKey, useClient as useClient3 } from "@dxos/react-client";
1221
1222
  import { getSpace as getSpace3, useMembers as useMembers2, fullyQualifiedId as fullyQualifiedId3 } from "@dxos/react-client/echo";
1222
1223
  import { useIdentity } from "@dxos/react-client/halo";
1223
- import { Avatar, AvatarGroup, AvatarGroupItem, Tooltip as Tooltip2, useDensityContext, useTranslation as useTranslation13, List as List2, ListItem, useDefaultValue } from "@dxos/react-ui";
1224
- import { AttentionGlyph } from "@dxos/react-ui-attention";
1224
+ import { Avatar, AvatarGroup, AvatarGroupItem, Tooltip as Tooltip2, useTranslation as useTranslation13, List as List2, ListItem, useDefaultValue } from "@dxos/react-ui";
1225
+ import { AttentionGlyph, useAttention } from "@dxos/react-ui-attention";
1225
1226
  import { ComplexMap, keyToFallback } from "@dxos/util";
1226
1227
  var REFRESH_INTERVAL = 5e3;
1227
1228
  var ACTIVITY_DURATION = 3e4;
1228
1229
  var noViewers = new ComplexMap(PublicKey.hash);
1229
1230
  var getName = (identity) => identity.profile?.displayName ?? generateName(identity.identityKey.toHex());
1230
1231
  var SpacePresence = ({ object, spaceKey }) => {
1231
- const density = useDensityContext();
1232
1232
  const spacePlugin = usePlugin(SPACE_PLUGIN);
1233
1233
  const client = useClient3();
1234
1234
  const identity = useIdentity();
@@ -1258,9 +1258,7 @@ var SpacePresence = ({ object, spaceKey }) => {
1258
1258
  lastSeen
1259
1259
  };
1260
1260
  }).toSorted((a, b) => a.lastSeen - b.lastSeen);
1261
- return density === "fine" ? /* @__PURE__ */ React13.createElement(SmallPresence, {
1262
- count: membersForObject.length
1263
- }) : /* @__PURE__ */ React13.createElement(FullPresence, {
1261
+ return /* @__PURE__ */ React13.createElement(FullPresence, {
1264
1262
  members: membersForObject
1265
1263
  });
1266
1264
  };
@@ -1329,25 +1327,42 @@ var PrensenceAvatar = ({ identity, showName, match, group, index, onClick }) =>
1329
1327
  classNames: "text-sm truncate pli-2"
1330
1328
  }, getName(identity)));
1331
1329
  };
1332
- var SmallPresenceLive = ({ viewers }) => {
1333
- const [moment, setMoment] = useState7(Date.now());
1330
+ var SmallPresenceLive = ({ id, viewers }) => {
1331
+ const getActiveViewers = (viewers2) => {
1332
+ const moment = Date.now();
1333
+ return Array.from(viewers2.values()).filter(({ lastSeen }) => moment - lastSeen < ACTIVITY_DURATION);
1334
+ };
1335
+ const [activeViewers, setActiveViewers] = useState7(viewers ? getActiveViewers(viewers) : []);
1334
1336
  useEffect4(() => {
1335
- const interval = setInterval(() => setMoment(Date.now()), REFRESH_INTERVAL);
1336
- return () => clearInterval(interval);
1337
- }, []);
1338
- const activeViewers = viewers ? Array.from(viewers.values()).filter(({ lastSeen }) => moment - lastSeen < ACTIVITY_DURATION) : [];
1337
+ if (viewers) {
1338
+ setActiveViewers(getActiveViewers(viewers));
1339
+ const interval = setInterval(() => {
1340
+ setActiveViewers(getActiveViewers(viewers));
1341
+ }, REFRESH_INTERVAL);
1342
+ return () => clearInterval(interval);
1343
+ }
1344
+ }, [
1345
+ viewers
1346
+ ]);
1339
1347
  return /* @__PURE__ */ React13.createElement(SmallPresence, {
1348
+ id,
1340
1349
  count: activeViewers.length
1341
1350
  });
1342
1351
  };
1343
- var SmallPresence = ({ count }) => {
1352
+ var SmallPresence = ({ id, count }) => {
1344
1353
  const { t } = useTranslation13(SPACE_PLUGIN);
1354
+ const { hasAttention, isAncestor, isRelated } = useAttention(id);
1355
+ const attention = hasAttention || isAncestor || isRelated;
1345
1356
  return /* @__PURE__ */ React13.createElement(Tooltip2.Root, null, /* @__PURE__ */ React13.createElement(Tooltip2.Trigger, {
1346
1357
  asChild: true
1358
+ }, /* @__PURE__ */ React13.createElement("div", {
1359
+ role: "none",
1360
+ className: "flex",
1361
+ "data-attention": attention
1347
1362
  }, /* @__PURE__ */ React13.createElement(AttentionGlyph, {
1348
1363
  presence: count > 1 ? "many" : count === 1 ? "one" : "none",
1349
1364
  classNames: "self-center mie-1"
1350
- })), /* @__PURE__ */ React13.createElement(Tooltip2.Portal, null, /* @__PURE__ */ React13.createElement(Tooltip2.Content, {
1365
+ }))), /* @__PURE__ */ React13.createElement(Tooltip2.Portal, null, /* @__PURE__ */ React13.createElement(Tooltip2.Content, {
1351
1366
  side: "bottom",
1352
1367
  classNames: "z-[70]"
1353
1368
  }, /* @__PURE__ */ React13.createElement("span", null, t("presence label", {
@@ -1358,13 +1373,13 @@ var SmallPresence = ({ count }) => {
1358
1373
  // packages/plugins/plugin-space/src/components/SpaceSettings.tsx
1359
1374
  import React14 from "react";
1360
1375
  import { useIntentDispatcher as useIntentDispatcher2, useResolvePlugins } from "@dxos/app-framework";
1361
- import { SettingsValue } from "@dxos/plugin-settings";
1362
1376
  import { Input as Input4, Select, toLocalizedString as toLocalizedString2, useTranslation as useTranslation14 } from "@dxos/react-ui";
1377
+ import { FormInput } from "@dxos/react-ui-data";
1363
1378
  var SpaceSettings = ({ settings }) => {
1364
1379
  const { t } = useTranslation14(SPACE_PLUGIN);
1365
1380
  const dispatch = useIntentDispatcher2();
1366
1381
  const plugins = useResolvePlugins(parseSpaceInitPlugin);
1367
- return /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(SettingsValue, {
1382
+ return /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(FormInput, {
1368
1383
  label: t("show hidden spaces label")
1369
1384
  }, /* @__PURE__ */ React14.createElement(Input4.Switch, {
1370
1385
  checked: settings.showHidden,
@@ -1375,7 +1390,7 @@ var SpaceSettings = ({ settings }) => {
1375
1390
  state: !!checked
1376
1391
  }
1377
1392
  })
1378
- })), /* @__PURE__ */ React14.createElement(SettingsValue, {
1393
+ })), /* @__PURE__ */ React14.createElement(FormInput, {
1379
1394
  label: t("default on space create label")
1380
1395
  }, /* @__PURE__ */ React14.createElement(Select.Root, {
1381
1396
  value: settings.onSpaceCreate,
@@ -1388,25 +1403,69 @@ var SpaceSettings = ({ settings }) => {
1388
1403
  }, toLocalizedString2(onSpaceCreate.label, t)))))))));
1389
1404
  };
1390
1405
 
1406
+ // packages/plugins/plugin-space/src/components/SpaceSettingsPanel.tsx
1407
+ import React15, { useCallback as useCallback5, useState as useState8 } from "react";
1408
+ import { log as log2 } from "@dxos/log";
1409
+ import { EdgeReplicationSetting } from "@dxos/protocols/proto/dxos/echo/metadata";
1410
+ import { Input as Input5, useTranslation as useTranslation15 } from "@dxos/react-ui";
1411
+ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-space/src/components/SpaceSettingsPanel.tsx";
1412
+ var SpaceSettingsPanel = ({ space }) => {
1413
+ const { t } = useTranslation15(SPACE_PLUGIN);
1414
+ const [edgeReplication, setEdgeReplication] = useState8(space.internal.data.edgeReplication === EdgeReplicationSetting.ENABLED);
1415
+ const toggleEdgeReplication = useCallback5(async (next) => {
1416
+ setEdgeReplication(next);
1417
+ await space?.internal.setEdgeReplicationPreference(next ? EdgeReplicationSetting.ENABLED : EdgeReplicationSetting.DISABLED).catch((err) => {
1418
+ log2.catch(err, void 0, {
1419
+ F: __dxlog_file3,
1420
+ L: 30,
1421
+ S: void 0,
1422
+ C: (f, a) => f(...a)
1423
+ });
1424
+ setEdgeReplication(!next);
1425
+ });
1426
+ }, [
1427
+ space
1428
+ ]);
1429
+ return /* @__PURE__ */ React15.createElement("div", {
1430
+ role: "form",
1431
+ className: "flex flex-col w-full p-2 gap-4"
1432
+ }, /* @__PURE__ */ React15.createElement(Input5.Root, null, /* @__PURE__ */ React15.createElement("div", {
1433
+ role: "none",
1434
+ className: "flex flex-col gap-1"
1435
+ }, /* @__PURE__ */ React15.createElement(Input5.Label, null, t("name label")), /* @__PURE__ */ React15.createElement(Input5.TextInput, {
1436
+ placeholder: t("name placeholder"),
1437
+ value: space.properties.name,
1438
+ onChange: (event) => {
1439
+ space.properties.name = event.target.value;
1440
+ }
1441
+ }))), /* @__PURE__ */ React15.createElement(Input5.Root, null, /* @__PURE__ */ React15.createElement("div", {
1442
+ role: "none",
1443
+ className: "flex justify-between"
1444
+ }, /* @__PURE__ */ React15.createElement(Input5.Label, null, t("edge replication label")), /* @__PURE__ */ React15.createElement(Input5.Switch, {
1445
+ checked: edgeReplication,
1446
+ onCheckedChange: toggleEdgeReplication
1447
+ }))));
1448
+ };
1449
+
1391
1450
  // packages/plugins/plugin-space/src/components/SaveStatus.tsx
1392
- import React15, { useEffect as useEffect5, useState as useState8 } from "react";
1451
+ import React16, { useEffect as useEffect5, useState as useState9 } from "react";
1393
1452
  import { Context } from "@dxos/context";
1394
1453
  import { StatusBar } from "@dxos/plugin-status-bar";
1395
1454
  import { useClient as useClient4 } from "@dxos/react-client";
1396
- import { Icon, useTranslation as useTranslation15 } from "@dxos/react-ui";
1397
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-space/src/components/SaveStatus.tsx";
1455
+ import { Icon, useTranslation as useTranslation16 } from "@dxos/react-ui";
1456
+ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-space/src/components/SaveStatus.tsx";
1398
1457
  var SaveStatus = () => {
1399
- const { t } = useTranslation15(SPACE_PLUGIN);
1458
+ const { t } = useTranslation16(SPACE_PLUGIN);
1400
1459
  const client = useClient4();
1401
- const [state, setState] = useState8("saved");
1460
+ const [state, setState] = useState9("saved");
1402
1461
  useEffect5(() => {
1403
1462
  return createClientSaveTracker(client, (state2) => {
1404
1463
  setState(state2);
1405
1464
  });
1406
1465
  }, []);
1407
- return /* @__PURE__ */ React15.createElement(StatusBar.Item, {
1466
+ return /* @__PURE__ */ React16.createElement(StatusBar.Item, {
1408
1467
  title: state === "saving" ? t("saving label") : t("saved label")
1409
- }, /* @__PURE__ */ React15.createElement(Icon, {
1468
+ }, /* @__PURE__ */ React16.createElement(Icon, {
1410
1469
  icon: state === "saving" ? "ph--arrows-clockwise--regular" : "ph--check-circle--regular",
1411
1470
  size: 4
1412
1471
  }));
@@ -1438,7 +1497,7 @@ var createClientSaveTracker = (client, cb) => {
1438
1497
  };
1439
1498
  var createSpaceSaveTracker = (space, cb) => {
1440
1499
  const ctx = new Context(void 0, {
1441
- F: __dxlog_file3,
1500
+ F: __dxlog_file4,
1442
1501
  L: 64
1443
1502
  });
1444
1503
  void space.waitUntilReady().then(() => {
@@ -1471,18 +1530,18 @@ var createSpaceSaveTracker = (space, cb) => {
1471
1530
  };
1472
1531
 
1473
1532
  // packages/plugins/plugin-space/src/components/SyncStatus/SyncStatus.tsx
1474
- import React16, { useEffect as useEffect7, useState as useState10 } from "react";
1533
+ import React17, { useEffect as useEffect7, useState as useState11 } from "react";
1475
1534
  import { StatusBar as StatusBar2 } from "@dxos/plugin-status-bar";
1476
- import { Icon as Icon2, Popover as Popover3, useTranslation as useTranslation16 } from "@dxos/react-ui";
1535
+ import { Icon as Icon2, Popover as Popover3, useTranslation as useTranslation17 } from "@dxos/react-ui";
1477
1536
  import { SyntaxHighlighter } from "@dxos/react-ui-syntax-highlighter";
1478
1537
  import { mx as mx7 } from "@dxos/react-ui-theme";
1479
1538
 
1480
1539
  // packages/plugins/plugin-space/src/components/SyncStatus/types.ts
1481
- import { useEffect as useEffect6, useState as useState9 } from "react";
1540
+ import { useEffect as useEffect6, useState as useState10 } from "react";
1482
1541
  import { Context as Context2 } from "@dxos/context";
1483
1542
  import { EdgeService } from "@dxos/protocols";
1484
1543
  import { useClient as useClient5 } from "@dxos/react-client";
1485
- var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-space/src/components/SyncStatus/types.ts";
1544
+ var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-space/src/components/SyncStatus/types.ts";
1486
1545
  var createEmptyEdgeSyncState = () => ({
1487
1546
  missingOnLocal: 0,
1488
1547
  missingOnRemote: 0,
@@ -1503,10 +1562,10 @@ var getSyncSummary = (syncMap) => {
1503
1562
  var isEdgePeerId = (peerId, spaceId) => peerId.startsWith(`${EdgeService.AUTOMERGE_REPLICATOR}:${spaceId}`);
1504
1563
  var useSyncState = () => {
1505
1564
  const client = useClient5();
1506
- const [spaceState, setSpaceState] = useState9({});
1565
+ const [spaceState, setSpaceState] = useState10({});
1507
1566
  useEffect6(() => {
1508
1567
  const ctx = new Context2(void 0, {
1509
- F: __dxlog_file4,
1568
+ F: __dxlog_file5,
1510
1569
  L: 48
1511
1570
  });
1512
1571
  const createSubscriptions = (spaces) => {
@@ -1547,7 +1606,7 @@ var styles = {
1547
1606
  };
1548
1607
  var SyncStatus = () => {
1549
1608
  const state = useSyncState();
1550
- return /* @__PURE__ */ React16.createElement(SyncStatusIndicator, {
1609
+ return /* @__PURE__ */ React17.createElement(SyncStatusIndicator, {
1551
1610
  state
1552
1611
  });
1553
1612
  };
@@ -1556,7 +1615,7 @@ var SyncStatusIndicator = ({ state }) => {
1556
1615
  const offline = false;
1557
1616
  const needsToUpload = summary.differentDocuments > 0 || summary.missingOnRemote > 0;
1558
1617
  const needsToDownload = summary.differentDocuments > 0 || summary.missingOnLocal > 0;
1559
- const [classNames, setClassNames] = useState10();
1618
+ const [classNames, setClassNames] = useState11();
1560
1619
  useEffect7(() => {
1561
1620
  setClassNames(void 0);
1562
1621
  if (!needsToUpload && !needsToDownload) {
@@ -1570,36 +1629,38 @@ var SyncStatusIndicator = ({ state }) => {
1570
1629
  needsToUpload,
1571
1630
  needsToDownload
1572
1631
  ]);
1573
- return /* @__PURE__ */ React16.createElement(StatusBar2.Item, null, /* @__PURE__ */ React16.createElement(Popover3.Root, null, /* @__PURE__ */ React16.createElement(Popover3.Trigger, null, /* @__PURE__ */ React16.createElement(Icon2, {
1632
+ return /* @__PURE__ */ React17.createElement(StatusBar2.Item, null, /* @__PURE__ */ React17.createElement(Popover3.Root, null, /* @__PURE__ */ React17.createElement(Popover3.Trigger, null, /* @__PURE__ */ React17.createElement(Icon2, {
1574
1633
  icon: offline ? "ph--cloud-x--regular" : needsToUpload ? "ph--cloud-arrow-up--regular" : needsToDownload ? "ph--cloud-arrow-down--regular" : "ph--cloud-check--regular",
1575
1634
  size: 4,
1576
1635
  classNames
1577
- })), /* @__PURE__ */ React16.createElement(Popover3.Content, null, /* @__PURE__ */ React16.createElement(SyncStatusDetail, {
1636
+ })), /* @__PURE__ */ React17.createElement(Popover3.Content, {
1637
+ sideOffset: 16
1638
+ }, /* @__PURE__ */ React17.createElement(SyncStatusDetail, {
1578
1639
  state,
1579
1640
  summary,
1580
1641
  debug: false
1581
1642
  }))));
1582
1643
  };
1583
1644
  var SyncStatusDetail = ({ classNames, state, summary, debug }) => {
1584
- const { t } = useTranslation16(SPACE_PLUGIN);
1645
+ const { t } = useTranslation17(SPACE_PLUGIN);
1585
1646
  const entries = Object.entries(state).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
1586
- return /* @__PURE__ */ React16.createElement("div", {
1647
+ return /* @__PURE__ */ React17.createElement("div", {
1587
1648
  className: mx7("flex flex-col text-xs min-w-[16rem]", classNames)
1588
- }, /* @__PURE__ */ React16.createElement("h1", {
1649
+ }, /* @__PURE__ */ React17.createElement("h1", {
1589
1650
  className: "p-2"
1590
- }, t("sync status title")), /* @__PURE__ */ React16.createElement("div", {
1651
+ }, t("sync status title")), /* @__PURE__ */ React17.createElement("div", {
1591
1652
  className: "flex flex-col gap-[2px] my-[2px]"
1592
- }, entries.map(([spaceId, state2]) => /* @__PURE__ */ React16.createElement(SpaceRow, {
1653
+ }, entries.map(([spaceId, state2]) => /* @__PURE__ */ React17.createElement(SpaceRow, {
1593
1654
  key: spaceId,
1594
1655
  spaceId,
1595
1656
  state: state2
1596
- }))), debug && /* @__PURE__ */ React16.createElement(SyntaxHighlighter, {
1657
+ }))), debug && /* @__PURE__ */ React17.createElement(SyntaxHighlighter, {
1597
1658
  language: "json"
1598
1659
  }, JSON.stringify(summary, null, 2)));
1599
1660
  };
1600
1661
  var useActive = (count) => {
1601
- const [current, setCurrent] = useState10(count);
1602
- const [active, setActive] = useState10(false);
1662
+ const [current, setCurrent] = useState11(count);
1663
+ const [active, setActive] = useState11(false);
1603
1664
  useEffect7(() => {
1604
1665
  let t;
1605
1666
  if (count !== current) {
@@ -1623,17 +1684,17 @@ var useActive = (count) => {
1623
1684
  var SpaceRow = ({ spaceId, state: { localDocumentCount, remoteDocumentCount, missingOnLocal, missingOnRemote } }) => {
1624
1685
  const downActive = useActive(localDocumentCount);
1625
1686
  const upActive = useActive(remoteDocumentCount);
1626
- return /* @__PURE__ */ React16.createElement("div", {
1687
+ return /* @__PURE__ */ React17.createElement("div", {
1627
1688
  className: mx7("flex items-center mx-[2px] gap-[2px] cursor-pointer", styles.barHover),
1628
1689
  title: spaceId,
1629
1690
  onClick: () => {
1630
1691
  void navigator.clipboard.writeText(spaceId);
1631
1692
  }
1632
- }, /* @__PURE__ */ React16.createElement(Icon2, {
1693
+ }, /* @__PURE__ */ React17.createElement(Icon2, {
1633
1694
  icon: "ph--arrow-fat-line-left--regular",
1634
1695
  size: 3,
1635
1696
  classNames: mx7(downActive && "animate-[pulse_1s_infinite]")
1636
- }), /* @__PURE__ */ React16.createElement(Candle, {
1697
+ }), /* @__PURE__ */ React17.createElement(Candle, {
1637
1698
  up: {
1638
1699
  count: remoteDocumentCount,
1639
1700
  total: remoteDocumentCount + missingOnRemote
@@ -1643,37 +1704,37 @@ var SpaceRow = ({ spaceId, state: { localDocumentCount, remoteDocumentCount, mis
1643
1704
  total: localDocumentCount + missingOnLocal
1644
1705
  },
1645
1706
  title: spaceId
1646
- }), /* @__PURE__ */ React16.createElement(Icon2, {
1707
+ }), /* @__PURE__ */ React17.createElement(Icon2, {
1647
1708
  icon: "ph--arrow-fat-line-right--regular",
1648
1709
  size: 3,
1649
1710
  classNames: mx7(upActive && "animate-[pulse_1s_step-start_infinite]")
1650
1711
  }));
1651
1712
  };
1652
1713
  var Candle = ({ classNames, up, down }) => {
1653
- return /* @__PURE__ */ React16.createElement("div", {
1714
+ return /* @__PURE__ */ React17.createElement("div", {
1654
1715
  className: mx7("grid grid-cols-[1fr_2rem_1fr] w-full h-3", classNames)
1655
- }, /* @__PURE__ */ React16.createElement(Bar, {
1716
+ }, /* @__PURE__ */ React17.createElement(Bar, {
1656
1717
  classNames: "justify-end",
1657
1718
  ...up
1658
- }), /* @__PURE__ */ React16.createElement("div", {
1719
+ }), /* @__PURE__ */ React17.createElement("div", {
1659
1720
  className: "relative"
1660
- }, /* @__PURE__ */ React16.createElement("div", {
1721
+ }, /* @__PURE__ */ React17.createElement("div", {
1661
1722
  className: mx7("absolute inset-0 flex items-center justify-center text-xs", styles.barBg)
1662
- }, up.total)), /* @__PURE__ */ React16.createElement(Bar, down));
1723
+ }, up.total)), /* @__PURE__ */ React17.createElement(Bar, down));
1663
1724
  };
1664
1725
  var Bar = ({ classNames, count, total }) => {
1665
1726
  let p = count / total * 100;
1666
1727
  if (count < total) {
1667
1728
  p = Math.min(p, 95);
1668
1729
  }
1669
- return /* @__PURE__ */ React16.createElement("div", {
1730
+ return /* @__PURE__ */ React17.createElement("div", {
1670
1731
  className: mx7("relative flex w-full", styles.barBg, classNames)
1671
- }, /* @__PURE__ */ React16.createElement("div", {
1732
+ }, /* @__PURE__ */ React17.createElement("div", {
1672
1733
  className: mx7("shrink-0", styles.barFg),
1673
1734
  style: {
1674
1735
  width: `${p}%`
1675
1736
  }
1676
- }), count !== total && /* @__PURE__ */ React16.createElement("div", {
1737
+ }), count !== total && /* @__PURE__ */ React17.createElement("div", {
1677
1738
  className: "absolute top-0 bottom-0 flex items-center mx-0.5 text-black text-xs"
1678
1739
  }, count));
1679
1740
  };
@@ -1685,8 +1746,8 @@ var translations_default = [
1685
1746
  [SPACE_PLUGIN]: {
1686
1747
  "plugin name": "Spaces",
1687
1748
  "first run message": "Nothing selected.",
1688
- "create space label": "Create a new space",
1689
- "join space label": "Join a space",
1749
+ "create space label": "Create space",
1750
+ "join space label": "Join space",
1690
1751
  "empty space message": "No documents",
1691
1752
  "empty tree message": "No spaces",
1692
1753
  "unnamed space label": "New space",
@@ -1763,14 +1824,16 @@ var translations_default = [
1763
1824
  "dismiss label": "Dismiss",
1764
1825
  "join success label": "Successfully joined space",
1765
1826
  "name label": "Name",
1766
- "name placeholder": "Name"
1827
+ "name placeholder": "Name",
1828
+ "unnamed object settings label": "Settings",
1829
+ "edge replication label": "Enable EDGE Replication"
1767
1830
  }
1768
1831
  }
1769
1832
  }
1770
1833
  ];
1771
1834
 
1772
1835
  // packages/plugins/plugin-space/src/SpacePlugin.tsx
1773
- var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-space/src/SpacePlugin.tsx";
1836
+ var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-space/src/SpacePlugin.tsx";
1774
1837
  var ACTIVE_NODE_BROADCAST_INTERVAL = 3e4;
1775
1838
  var OBJECT_ID_LENGTH = 60;
1776
1839
  var SPACE_MAX_OBJECTS = 500;
@@ -1784,6 +1847,7 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
1784
1847
  awaiting: void 0,
1785
1848
  spaceNames: {},
1786
1849
  viewersByObject: {},
1850
+ // TODO(wittjosiah): Stop using (Complex)Map inside reactive object.
1787
1851
  viewersByIdentity: new ComplexMap2(PublicKey2.hash),
1788
1852
  sdkMigrationRunning: {}
1789
1853
  });
@@ -1857,11 +1921,11 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
1857
1921
  // TODO(Zan): When we re-open a part, we should remove it from the removed list in the navigation plugin.
1858
1922
  removed: removed.filter((id) => !ids2.includes(id))
1859
1923
  }).catch((err) => {
1860
- log2.warn("Failed to broadcast active node for presence.", {
1924
+ log3.warn("Failed to broadcast active node for presence.", {
1861
1925
  err: err.message
1862
1926
  }, {
1863
- F: __dxlog_file5,
1864
- L: 229,
1927
+ F: __dxlog_file6,
1928
+ L: 231,
1865
1929
  S: void 0,
1866
1930
  C: (f, a) => f(...a)
1867
1931
  });
@@ -1911,14 +1975,12 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
1911
1975
  ready: async (plugins) => {
1912
1976
  settings.prop({
1913
1977
  key: "showHidden",
1914
- storageKey: "show-hidden",
1915
1978
  type: LocalStorageStore.bool({
1916
1979
  allowUndefined: true
1917
1980
  })
1918
1981
  });
1919
1982
  state.prop({
1920
1983
  key: "spaceNames",
1921
- storageKey: "space-names",
1922
1984
  type: LocalStorageStore.json()
1923
1985
  });
1924
1986
  navigationPlugin = resolvePlugin(plugins, parseNavigationPlugin2);
@@ -1970,7 +2032,7 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
1970
2032
  ...translations_default,
1971
2033
  osTranslations
1972
2034
  ],
1973
- root: () => state.values.awaiting ? /* @__PURE__ */ React17.createElement(AwaitingObject, {
2035
+ root: () => state.values.awaiting ? /* @__PURE__ */ React18.createElement(AwaitingObject, {
1974
2036
  id: state.values.awaiting
1975
2037
  }) : null,
1976
2038
  metadata: {
@@ -2002,7 +2064,7 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2002
2064
  switch (role) {
2003
2065
  case "article":
2004
2066
  case "main":
2005
- return isSpace2(primary) && primary.state.get() === SpaceState3.SPACE_READY ? /* @__PURE__ */ React17.createElement(Surface2, {
2067
+ return isSpace2(primary) && primary.state.get() === SpaceState3.SPACE_READY ? /* @__PURE__ */ React18.createElement(Surface2, {
2006
2068
  data: {
2007
2069
  active: primary.properties[CollectionType.typename],
2008
2070
  id: primary.id
@@ -2010,43 +2072,50 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2010
2072
  role,
2011
2073
  ...rest
2012
2074
  }) : primary instanceof CollectionType ? {
2013
- node: /* @__PURE__ */ React17.createElement(CollectionMain, {
2075
+ node: /* @__PURE__ */ React18.createElement(CollectionMain, {
2014
2076
  collection: primary
2015
2077
  }),
2016
2078
  disposition: "fallback"
2017
- } : typeof primary === "string" && primary.length === OBJECT_ID_LENGTH ? /* @__PURE__ */ React17.createElement(MissingObject, {
2079
+ } : typeof primary === "string" && primary.length === OBJECT_ID_LENGTH ? /* @__PURE__ */ React18.createElement(MissingObject, {
2018
2080
  id: primary
2019
2081
  }) : null;
2020
2082
  case "complementary--settings":
2021
- return isEchoObject2(data.subject) ? /* @__PURE__ */ React17.createElement(DefaultObjectSettings, {
2022
- object: data.subject
2023
- }) : null;
2083
+ return isSpace2(data.subject) ? /* @__PURE__ */ React18.createElement(SpaceSettingsPanel, {
2084
+ space: data.subject
2085
+ }) : isEchoObject2(data.subject) ? {
2086
+ node: /* @__PURE__ */ React18.createElement(DefaultObjectSettings, {
2087
+ object: data.subject
2088
+ }),
2089
+ disposition: "fallback"
2090
+ } : null;
2024
2091
  case "dialog":
2025
2092
  if (data.component === "dxos.org/plugin/space/InvitationManagerDialog") {
2026
- return /* @__PURE__ */ React17.createElement(Dialog.Content, null, /* @__PURE__ */ React17.createElement(ClipboardProvider2, null, /* @__PURE__ */ React17.createElement(InvitationManager, {
2093
+ return /* @__PURE__ */ React18.createElement(Dialog.Content, null, /* @__PURE__ */ React18.createElement(ClipboardProvider2, null, /* @__PURE__ */ React18.createElement(InvitationManager, {
2027
2094
  active: true,
2028
2095
  ...data.subject
2029
2096
  })));
2030
- } else {
2031
- return null;
2032
2097
  }
2033
- case "popover":
2098
+ return null;
2099
+ case "popover": {
2034
2100
  if (data.component === "dxos.org/plugin/space/RenameSpacePopover" && isSpace2(data.subject)) {
2035
- return /* @__PURE__ */ React17.createElement(PopoverRenameSpace, {
2101
+ return /* @__PURE__ */ React18.createElement(PopoverRenameSpace, {
2036
2102
  space: data.subject
2037
2103
  });
2038
2104
  }
2039
2105
  if (data.component === "dxos.org/plugin/space/RenameObjectPopover" && isReactiveObject2(data.subject)) {
2040
- return /* @__PURE__ */ React17.createElement(PopoverRenameObject, {
2106
+ return /* @__PURE__ */ React18.createElement(PopoverRenameObject, {
2041
2107
  object: data.subject
2042
2108
  });
2043
2109
  }
2044
2110
  return null;
2111
+ }
2045
2112
  // TODO(burdon): Add role name syntax to minimal plugin docs.
2046
2113
  case "presence--glyph": {
2047
- return isReactiveObject2(data.object) ? /* @__PURE__ */ React17.createElement(SmallPresenceLive, {
2114
+ return isReactiveObject2(data.object) ? /* @__PURE__ */ React18.createElement(SmallPresenceLive, {
2115
+ id: data.id,
2048
2116
  viewers: state.values.viewersByObject[fullyQualifiedId4(data.object)]
2049
- }) : /* @__PURE__ */ React17.createElement(SmallPresence, {
2117
+ }) : /* @__PURE__ */ React18.createElement(SmallPresence, {
2118
+ id: data.id,
2050
2119
  count: 0
2051
2120
  });
2052
2121
  }
@@ -2060,32 +2129,32 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2060
2129
  const space = isSpace2(data.object) ? data.object : getSpace4(data.object);
2061
2130
  const object = isSpace2(data.object) ? data.object.state.get() === SpaceState3.SPACE_READY ? space?.properties[CollectionType.typename] : void 0 : data.object;
2062
2131
  return space && object ? {
2063
- node: /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement(SpacePresence, {
2132
+ node: /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement(SpacePresence, {
2064
2133
  object
2065
- }), space.properties[COMPOSER_SPACE_LOCK] ? null : /* @__PURE__ */ React17.createElement(ShareSpaceButton, {
2134
+ }), space.properties[COMPOSER_SPACE_LOCK] ? null : /* @__PURE__ */ React18.createElement(ShareSpaceButton, {
2066
2135
  spaceId: space.id
2067
2136
  })),
2068
2137
  disposition: "hoist"
2069
2138
  } : null;
2070
2139
  }
2071
2140
  case "section":
2072
- return data.object instanceof CollectionType ? /* @__PURE__ */ React17.createElement(CollectionSection, {
2141
+ return data.object instanceof CollectionType ? /* @__PURE__ */ React18.createElement(CollectionSection, {
2073
2142
  collection: data.object
2074
2143
  }) : null;
2075
2144
  case "settings":
2076
- return data.plugin === meta_default.id ? /* @__PURE__ */ React17.createElement(SpaceSettings, {
2145
+ return data.plugin === meta_default.id ? /* @__PURE__ */ React18.createElement(SpaceSettings, {
2077
2146
  settings: settings.values
2078
2147
  }) : null;
2079
2148
  case "menu-footer":
2080
- if (!isEchoObject2(data.object)) {
2081
- return null;
2082
- } else {
2083
- return /* @__PURE__ */ React17.createElement(MenuFooter, {
2149
+ if (isEchoObject2(data.object)) {
2150
+ return /* @__PURE__ */ React18.createElement(MenuFooter, {
2084
2151
  object: data.object
2085
2152
  });
2153
+ } else {
2154
+ return null;
2086
2155
  }
2087
2156
  case "status": {
2088
- return /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement(SyncStatus, null), /* @__PURE__ */ React17.createElement(SaveStatus, null));
2157
+ return /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement(SyncStatus, null), /* @__PURE__ */ React18.createElement(SaveStatus, null));
2089
2158
  }
2090
2159
  default:
2091
2160
  return null;
@@ -2101,7 +2170,7 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2101
2170
  const dispatch = intentPlugin?.provides.intent.dispatch;
2102
2171
  const resolve = metadataPlugin?.provides.metadata.resolver;
2103
2172
  const graph = graphPlugin?.provides.graph;
2104
- if (!graph || !dispatch || !resolve || !client) {
2173
+ if (!client || !dispatch || !resolve || !graph) {
2105
2174
  return [];
2106
2175
  }
2107
2176
  return [
@@ -2133,7 +2202,6 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2133
2202
  ns: SPACE_PLUGIN
2134
2203
  }
2135
2204
  ],
2136
- palette: "teal",
2137
2205
  testId: "spacePlugin.spaces",
2138
2206
  role: "branch",
2139
2207
  childrenPersistenceClass: "echo",
@@ -2145,9 +2213,9 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2145
2213
  if (spacesOrder) {
2146
2214
  spacesOrder.order = nextOrder.map(({ id }) => id);
2147
2215
  } else {
2148
- log2.warn("spaces order object not found", void 0, {
2149
- F: __dxlog_file5,
2150
- L: 526,
2216
+ log3.warn("spaces order object not found", void 0, {
2217
+ F: __dxlog_file6,
2218
+ L: 528,
2151
2219
  S: void 0,
2152
2220
  C: (f, a) => f(...a)
2153
2221
  });
@@ -2184,8 +2252,9 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2184
2252
  }
2185
2253
  ],
2186
2254
  icon: "ph--plus--regular",
2187
- disposition: "toolbar",
2188
- testId: "spacePlugin.createSpace"
2255
+ disposition: "item",
2256
+ testId: "spacePlugin.createSpace",
2257
+ className: "pbs-4"
2189
2258
  }
2190
2259
  },
2191
2260
  {
@@ -2209,7 +2278,9 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2209
2278
  }
2210
2279
  ],
2211
2280
  icon: "ph--sign-in--regular",
2212
- testId: "spacePlugin.joinSpace"
2281
+ disposition: "item",
2282
+ testId: "spacePlugin.joinSpace",
2283
+ className: "pbe-4"
2213
2284
  }
2214
2285
  }
2215
2286
  ],
@@ -2344,9 +2415,36 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2344
2415
  if (!id.endsWith("~settings")) {
2345
2416
  return;
2346
2417
  }
2418
+ const type = "orphan-settings-for-subject";
2419
+ const icon = "ph--gear--regular";
2347
2420
  const [subjectId] = id.split("~");
2348
- const [spaceId, objectId] = parseFullyQualifiedId(subjectId);
2421
+ const { spaceId, objectId } = parseId(subjectId);
2349
2422
  const space = client.spaces.get().find((space2) => space2.id === spaceId);
2423
+ if (!objectId) {
2424
+ const label2 = space ? space.properties.name || [
2425
+ "unnamed space label",
2426
+ {
2427
+ ns: SPACE_PLUGIN
2428
+ }
2429
+ ] : [
2430
+ "unnamed object settings label",
2431
+ {
2432
+ ns: SPACE_PLUGIN
2433
+ }
2434
+ ];
2435
+ return {
2436
+ id,
2437
+ type,
2438
+ data: null,
2439
+ properties: {
2440
+ icon,
2441
+ label: label2,
2442
+ showResolvedThreads: false,
2443
+ object: null,
2444
+ space
2445
+ }
2446
+ };
2447
+ }
2350
2448
  const object = toSignal((onChange) => {
2351
2449
  const timeout = setTimeout(async () => {
2352
2450
  await space?.db.loadObjectById(objectId);
@@ -2366,10 +2464,10 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2366
2464
  ];
2367
2465
  return {
2368
2466
  id,
2369
- type: "orphan-settings-for-subject",
2467
+ type,
2370
2468
  data: null,
2371
2469
  properties: {
2372
- icon: "ph--gear--regular",
2470
+ icon,
2373
2471
  label,
2374
2472
  object
2375
2473
  }
@@ -2908,10 +3006,11 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2908
3006
  case SpaceAction.DUPLICATE_OBJECT: {
2909
3007
  const originalObject = intent.data?.object ?? intent.data?.result;
2910
3008
  const resolve = resolvePlugin(plugins, parseMetadataResolverPlugin)?.provides.metadata.resolver;
2911
- if (!isEchoObject2(originalObject) || !resolve) {
3009
+ const space = isSpace2(intent.data?.target) ? intent.data?.target : getSpace4(intent.data?.target);
3010
+ if (!isEchoObject2(originalObject) || !resolve || !space) {
2912
3011
  return;
2913
3012
  }
2914
- const newObject = await cloneObject(originalObject, resolve);
3013
+ const newObject = await cloneObject(originalObject, resolve, space);
2915
3014
  return {
2916
3015
  intents: [
2917
3016
  [
@@ -2975,6 +3074,7 @@ export {
2975
3074
  SpacePlugin,
2976
3075
  SpacePresence,
2977
3076
  SpaceSettings,
3077
+ SpaceSettingsPanel,
2978
3078
  SyncStatus,
2979
3079
  SyncStatusDetail,
2980
3080
  SyncStatusIndicator,