@dxos/plugin-space 0.6.13 → 0.6.14-main.69511f5

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-LZEGRS7H.mjs → chunk-AVLRQF6L.mjs} +1 -1
  2. package/dist/lib/browser/chunk-AVLRQF6L.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-DTVUOG2C.mjs → chunk-FOI7DAUV.mjs} +24 -5
  4. package/dist/lib/browser/chunk-FOI7DAUV.mjs.map +7 -0
  5. package/dist/lib/browser/index.mjs +757 -298
  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 +1 -1
  9. package/dist/lib/browser/types/index.mjs +7 -3
  10. package/dist/lib/node/{chunk-CVZPI2P3.cjs → chunk-OTDRTHT4.cjs} +30 -9
  11. package/dist/lib/node/chunk-OTDRTHT4.cjs.map +7 -0
  12. package/dist/lib/node/{chunk-6CNYF6YU.cjs → chunk-P4XUXM7Y.cjs} +4 -4
  13. package/dist/lib/node/chunk-P4XUXM7Y.cjs.map +7 -0
  14. package/dist/lib/node/index.cjs +953 -498
  15. package/dist/lib/node/index.cjs.map +4 -4
  16. package/dist/lib/node/meta.cjs +5 -5
  17. package/dist/lib/node/meta.cjs.map +1 -1
  18. package/dist/lib/node/meta.json +1 -1
  19. package/dist/lib/node/types/index.cjs +14 -10
  20. package/dist/lib/node/types/index.cjs.map +2 -2
  21. package/dist/lib/node-esm/chunk-FYDGMPSC.mjs +116 -0
  22. package/dist/lib/node-esm/chunk-FYDGMPSC.mjs.map +7 -0
  23. package/dist/lib/node-esm/chunk-YPQGKWHJ.mjs +37 -0
  24. package/dist/lib/node-esm/chunk-YPQGKWHJ.mjs.map +7 -0
  25. package/dist/lib/node-esm/index.mjs +3100 -0
  26. package/dist/lib/node-esm/index.mjs.map +7 -0
  27. package/dist/lib/node-esm/meta.json +1 -0
  28. package/dist/lib/node-esm/meta.mjs +14 -0
  29. package/dist/lib/node-esm/meta.mjs.map +7 -0
  30. package/dist/lib/node-esm/types/index.mjs +26 -0
  31. package/dist/lib/node-esm/types/index.mjs.map +7 -0
  32. package/dist/types/src/SpacePlugin.d.ts.map +1 -1
  33. package/dist/types/src/components/DefaultObjectSettings.d.ts +7 -0
  34. package/dist/types/src/components/DefaultObjectSettings.d.ts.map +1 -0
  35. package/dist/types/src/components/MenuFooter.d.ts +1 -1
  36. package/dist/types/src/components/MenuFooter.d.ts.map +1 -1
  37. package/dist/types/src/components/SaveStatus.d.ts +3 -0
  38. package/dist/types/src/components/SaveStatus.d.ts.map +1 -0
  39. package/dist/types/src/components/ShareSpaceButton.stories.d.ts +3 -91
  40. package/dist/types/src/components/ShareSpaceButton.stories.d.ts.map +1 -1
  41. package/dist/types/src/components/SpaceMain/SpaceMain.d.ts.map +1 -1
  42. package/dist/types/src/components/SpacePresence.d.ts +4 -2
  43. package/dist/types/src/components/SpacePresence.d.ts.map +1 -1
  44. package/dist/types/src/components/SpacePresence.stories.d.ts +4 -92
  45. package/dist/types/src/components/SpacePresence.stories.d.ts.map +1 -1
  46. package/dist/types/src/components/SpaceSettings.d.ts.map +1 -1
  47. package/dist/types/src/components/SpaceSettingsPanel.d.ts +7 -0
  48. package/dist/types/src/components/SpaceSettingsPanel.d.ts.map +1 -0
  49. package/dist/types/src/components/SyncStatus/SyncStatus.d.ts +13 -0
  50. package/dist/types/src/components/SyncStatus/SyncStatus.d.ts.map +1 -0
  51. package/dist/types/src/components/SyncStatus/SyncStatus.stories.d.ts +24 -0
  52. package/dist/types/src/components/SyncStatus/SyncStatus.stories.d.ts.map +1 -0
  53. package/dist/types/src/components/SyncStatus/index.d.ts +2 -0
  54. package/dist/types/src/components/SyncStatus/index.d.ts.map +1 -0
  55. package/dist/types/src/components/SyncStatus/types.d.ts +14 -0
  56. package/dist/types/src/components/SyncStatus/types.d.ts.map +1 -0
  57. package/dist/types/src/components/index.d.ts +4 -2
  58. package/dist/types/src/components/index.d.ts.map +1 -1
  59. package/dist/types/src/meta.d.ts.map +1 -1
  60. package/dist/types/src/translations.d.ts +8 -0
  61. package/dist/types/src/translations.d.ts.map +1 -1
  62. package/dist/types/src/types/thread.d.ts +15 -1
  63. package/dist/types/src/types/thread.d.ts.map +1 -1
  64. package/dist/types/src/types/types.d.ts +21 -1
  65. package/dist/types/src/types/types.d.ts.map +1 -1
  66. package/dist/types/src/util.d.ts +4 -7
  67. package/dist/types/src/util.d.ts.map +1 -1
  68. package/package.json +45 -45
  69. package/src/SpacePlugin.tsx +229 -116
  70. package/src/components/DefaultObjectSettings.tsx +33 -0
  71. package/src/components/MenuFooter.tsx +2 -2
  72. package/src/components/SaveStatus.tsx +95 -0
  73. package/src/components/ShareSpaceButton.stories.tsx +11 -7
  74. package/src/components/SpaceMain/SpaceMain.tsx +1 -22
  75. package/src/components/SpacePresence.stories.tsx +11 -9
  76. package/src/components/SpacePresence.tsx +34 -23
  77. package/src/components/SpaceSettings.tsx +35 -6
  78. package/src/components/SpaceSettingsPanel.tsx +59 -0
  79. package/src/components/SyncStatus/SyncStatus.stories.tsx +65 -0
  80. package/src/components/SyncStatus/SyncStatus.tsx +188 -0
  81. package/src/components/SyncStatus/index.ts +5 -0
  82. package/src/components/SyncStatus/types.ts +77 -0
  83. package/src/components/index.ts +4 -2
  84. package/src/meta.ts +3 -1
  85. package/src/translations.ts +10 -2
  86. package/src/types/collection.ts +1 -1
  87. package/src/types/thread.ts +12 -2
  88. package/src/types/types.ts +28 -2
  89. package/src/util.tsx +23 -58
  90. package/dist/lib/browser/chunk-DTVUOG2C.mjs.map +0 -7
  91. package/dist/lib/browser/chunk-LZEGRS7H.mjs.map +0 -7
  92. package/dist/lib/node/chunk-6CNYF6YU.cjs.map +0 -7
  93. package/dist/lib/node/chunk-CVZPI2P3.cjs.map +0 -7
  94. package/dist/types/src/components/EmptySpace.d.ts +0 -3
  95. package/dist/types/src/components/EmptySpace.d.ts.map +0 -1
  96. package/dist/types/src/components/EmptyTree.d.ts +0 -3
  97. package/dist/types/src/components/EmptyTree.d.ts.map +0 -1
  98. package/src/components/EmptySpace.tsx +0 -25
  99. package/src/components/EmptyTree.tsx +0 -25
@@ -3,36 +3,38 @@ import {
3
3
  SPACE_PLUGIN_SHORT_ID,
4
4
  SpaceAction,
5
5
  meta_default
6
- } from "./chunk-LZEGRS7H.mjs";
6
+ } from "./chunk-AVLRQF6L.mjs";
7
7
  import {
8
8
  ActorSchema,
9
9
  ChannelType,
10
10
  CollectionType,
11
11
  ContactType,
12
+ MessageState,
12
13
  MessageType,
13
14
  SPACE_DIRECTORY_HANDLE,
14
15
  ThreadStatus,
15
- ThreadType
16
- } from "./chunk-DTVUOG2C.mjs";
16
+ ThreadType,
17
+ parseSpaceInitPlugin
18
+ } from "./chunk-FOI7DAUV.mjs";
17
19
 
18
20
  // packages/plugins/plugin-space/src/SpacePlugin.tsx
19
- import { Plus as Plus2, SignIn, CardsThree as CardsThree2, Warning as Warning2 } from "@phosphor-icons/react";
20
- import { effect, signal } from "@preact/signals-core";
21
- import React17 from "react";
22
- import { LayoutAction as LayoutAction2, Surface as Surface2, NavigationAction as NavigationAction3, openIds, firstIdInPart, parseIntentPlugin as parseIntentPlugin3, parseNavigationPlugin as parseNavigationPlugin2, parseMetadataResolverPlugin, resolvePlugin, parseGraphPlugin } from "@dxos/app-framework";
21
+ import { signal } from "@preact/signals-core";
22
+ import React18 from "react";
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";
23
24
  import { EventSubscriptions } from "@dxos/async";
24
25
  import { isReactiveObject as isReactiveObject2 } from "@dxos/echo-schema";
26
+ import { scheduledEffect } from "@dxos/echo-signals/core";
25
27
  import { LocalStorageStore } from "@dxos/local-storage";
26
- import { log as log2 } from "@dxos/log";
28
+ import { log as log3 } from "@dxos/log";
27
29
  import { Migrations as Migrations2 } from "@dxos/migrations";
28
30
  import { parseAttentionPlugin } from "@dxos/plugin-attention";
29
31
  import { parseClientPlugin } from "@dxos/plugin-client";
30
- import { createExtension, isGraphNode, memoize as memoize2, toSignal } from "@dxos/plugin-graph";
32
+ import { createExtension, memoize as memoize2, toSignal } from "@dxos/plugin-graph";
31
33
  import { ObservabilityAction } from "@dxos/plugin-observability/meta";
32
34
  import { PublicKey as PublicKey2 } from "@dxos/react-client";
33
- import { create as create2, Expando, Filter, fullyQualifiedId as fullyQualifiedId4, getSpace as getSpace4, getTypename as getTypename2, isEchoObject as isEchoObject2, isSpace as isSpace2, loadObjectReferences, SpaceState as SpaceState3 } 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";
34
36
  import { Dialog } from "@dxos/react-ui";
35
- import { InvitationManager, osTranslations, ClipboardProvider as ClipboardProvider2 } from "@dxos/shell/react";
37
+ import { ClipboardProvider as ClipboardProvider2, InvitationManager, osTranslations } from "@dxos/shell/react";
36
38
  import { ComplexMap as ComplexMap2, nonNullable, reduceGroupBy } from "@dxos/util";
37
39
 
38
40
  // packages/plugins/plugin-space/src/components/AwaitingObject.tsx
@@ -158,46 +160,37 @@ var CollectionSection = ({ collection }) => {
158
160
  }, collection.name ?? t("unnamed collection label")));
159
161
  };
160
162
 
161
- // packages/plugins/plugin-space/src/components/EmptySpace.tsx
163
+ // packages/plugins/plugin-space/src/components/DefaultObjectSettings.tsx
162
164
  import React4 from "react";
163
- import { useTranslation as useTranslation4 } from "@dxos/react-ui";
164
- import { descriptionText as descriptionText2, mx as mx3 } from "@dxos/react-ui-theme";
165
- var EmptySpace = () => {
165
+ import { Input, useTranslation as useTranslation4 } from "@dxos/react-ui";
166
+ var DefaultObjectSettings = ({ object }) => {
166
167
  const { t } = useTranslation4(SPACE_PLUGIN);
167
168
  return /* @__PURE__ */ React4.createElement("div", {
168
- role: "none",
169
- className: mx3("p-2 mli-2 mbe-2 text-center border border-dashed border-neutral-400/50 rounded-lg", descriptionText2)
170
- }, t("empty space message"));
171
- };
172
-
173
- // packages/plugins/plugin-space/src/components/EmptyTree.tsx
174
- import React5 from "react";
175
- import { useTranslation as useTranslation5 } from "@dxos/react-ui";
176
- import { descriptionText as descriptionText3, mx as mx4 } from "@dxos/react-ui-theme";
177
- var EmptyTree = () => {
178
- const { t } = useTranslation5(SPACE_PLUGIN);
179
- return /* @__PURE__ */ React5.createElement("div", {
180
- role: "none",
181
- className: mx4("p-2 mli-2 mbe-2 text-center border border-dashed border-neutral-400/50 rounded-lg", descriptionText3)
182
- }, t("empty tree message"));
169
+ role: "form",
170
+ className: "flex flex-col w-full p-2 gap-1"
171
+ }, /* @__PURE__ */ React4.createElement(Input.Root, null, /* @__PURE__ */ React4.createElement(Input.Label, null, t("name label")), /* @__PURE__ */ React4.createElement(Input.TextInput, {
172
+ placeholder: t("name placeholder"),
173
+ value: object.name ?? "",
174
+ onChange: (event) => {
175
+ object.name = event.target.value;
176
+ }
177
+ })));
183
178
  };
184
179
 
185
180
  // packages/plugins/plugin-space/src/components/MenuFooter.tsx
186
- import { Planet as Planet2 } from "@phosphor-icons/react";
187
- import React7 from "react";
181
+ import { Planet } from "@phosphor-icons/react";
182
+ import React5 from "react";
188
183
  import { getSpace as getSpace2 } from "@dxos/client/echo";
189
184
  import { useClient as useClient2 } from "@dxos/react-client";
190
- import { DropdownMenu, toLocalizedString, useTranslation as useTranslation6 } from "@dxos/react-ui";
185
+ import { DropdownMenu, toLocalizedString, useTranslation as useTranslation5 } from "@dxos/react-ui";
191
186
 
192
187
  // packages/plugins/plugin-space/src/util.tsx
193
- import { CardsThree, Database, PencilSimpleLine, Planet, Plus, Trash, Users, X, ClockCounterClockwise, LockSimpleOpen, LockSimple, Placeholder, Link } from "@phosphor-icons/react";
194
- import React6 from "react";
195
188
  import { NavigationAction as NavigationAction2 } from "@dxos/app-framework";
196
- import { create, isReactiveObject, getTypename, getSchema, getEchoObjectAnnotation, EXPANDO_TYPENAME } from "@dxos/echo-schema";
189
+ import { create, isReactiveObject, getTypename, getSchema, getObjectAnnotation, EXPANDO_TYPENAME } from "@dxos/echo-schema";
197
190
  import { invariant } from "@dxos/invariant";
198
191
  import { Migrations } from "@dxos/migrations";
199
192
  import { ACTION_TYPE, ACTION_GROUP_TYPE, actionGroupSymbol, getGraph, cleanup, memoize } from "@dxos/plugin-graph";
200
- import { SpaceState, fullyQualifiedId as fullyQualifiedId2, getSpace, isEchoObject, isSpace } from "@dxos/react-client/echo";
193
+ import { fullyQualifiedId as fullyQualifiedId2, getSpace, isEchoObject, isSpace, SpaceState } from "@dxos/react-client/echo";
201
194
  var __dxlog_file = "/home/runner/work/dxos/dxos/packages/plugins/plugin-space/src/util.tsx";
202
195
  var SPACES = `${SPACE_PLUGIN}-spaces`;
203
196
  var SPACE_TYPE = "dxos.org/type/Space";
@@ -252,7 +245,7 @@ var getCollectionGraphNodePartials = ({ collection, space, resolve }) => {
252
245
  }
253
246
  },
254
247
  onCopy: async (child, index) => {
255
- const newObject = await cloneObject(child.data, resolve);
248
+ const newObject = await cloneObject(child.data, resolve, space);
256
249
  space.db.add(newObject);
257
250
  if (typeof index !== "undefined") {
258
251
  collection.objects.splice(index, 0, newObject);
@@ -284,8 +277,7 @@ var constructSpaceNode = ({ space, personal, namesCache, resolve }) => {
284
277
  namesCache
285
278
  }),
286
279
  description: space.state.get() === SpaceState.SPACE_READY && space.properties.description,
287
- icon: (props) => /* @__PURE__ */ React6.createElement(Planet, props),
288
- iconSymbol: "ph--planet--regular",
280
+ icon: "ph--planet--regular",
289
281
  disabled: space.state.get() !== SpaceState.SPACE_READY || hasPendingMigration,
290
282
  testId: "spacePlugin.space"
291
283
  }
@@ -311,8 +303,7 @@ var constructSpaceActionGroups = ({ space, dispatch }) => {
311
303
  ns: SPACE_PLUGIN
312
304
  }
313
305
  ],
314
- icon: (props) => /* @__PURE__ */ React6.createElement(Plus, props),
315
- iconSymbol: "ph--plus--regular",
306
+ icon: "ph--plus--regular",
316
307
  disposition: "toolbar",
317
308
  // TODO(wittjosiah): This is currently a navtree feature. Address this with cmd+k integration.
318
309
  // mainAreaDisposition: 'in-flow',
@@ -346,8 +337,7 @@ var constructSpaceActionGroups = ({ space, dispatch }) => {
346
337
  ns: SPACE_PLUGIN
347
338
  }
348
339
  ],
349
- icon: (props) => /* @__PURE__ */ React6.createElement(CardsThree, props),
350
- iconSymbol: "ph--cards-three--regular",
340
+ icon: "ph--cards-three--regular",
351
341
  testId: "spacePlugin.createCollection"
352
342
  }
353
343
  }
@@ -381,8 +371,7 @@ var constructSpaceActions = ({ space, dispatch, personal, migrating }) => {
381
371
  ns: SPACE_PLUGIN
382
372
  }
383
373
  ],
384
- icon: (props) => /* @__PURE__ */ React6.createElement(Database, props),
385
- iconSymbol: "ph--database--regular",
374
+ icon: "ph--database--regular",
386
375
  disposition: "toolbar",
387
376
  mainAreaDisposition: "in-flow",
388
377
  disabled: migrating || Migrations.running(space)
@@ -413,8 +402,7 @@ var constructSpaceActions = ({ space, dispatch, personal, migrating }) => {
413
402
  ns: SPACE_PLUGIN
414
403
  }
415
404
  ],
416
- icon: (props) => /* @__PURE__ */ React6.createElement(Users, props),
417
- iconSymbol: "ph--users--regular",
405
+ icon: "ph--users--regular",
418
406
  disabled: locked,
419
407
  keyBinding: {
420
408
  macos: "meta+.",
@@ -441,8 +429,7 @@ var constructSpaceActions = ({ space, dispatch, personal, migrating }) => {
441
429
  ns: SPACE_PLUGIN
442
430
  }
443
431
  ],
444
- icon: locked ? (props) => /* @__PURE__ */ React6.createElement(LockSimpleOpen, props) : (props) => /* @__PURE__ */ React6.createElement(LockSimple, props),
445
- iconSymbol: locked ? "ph--lock-simple-open--regular" : "ph--lock-simple--regular"
432
+ icon: locked ? "ph--lock-simple-open--regular" : "ph--lock-simple--regular"
446
433
  }
447
434
  }, {
448
435
  id: getId(SpaceAction.RENAME),
@@ -464,8 +451,7 @@ var constructSpaceActions = ({ space, dispatch, personal, migrating }) => {
464
451
  ns: SPACE_PLUGIN
465
452
  }
466
453
  ],
467
- icon: (props) => /* @__PURE__ */ React6.createElement(PencilSimpleLine, props),
468
- iconSymbol: "ph--pencil-simple-line--regular",
454
+ icon: "ph--pencil-simple-line--regular",
469
455
  keyBinding: {
470
456
  macos: "shift+F6",
471
457
  windows: "shift+F6"
@@ -494,8 +480,7 @@ var constructSpaceActions = ({ space, dispatch, personal, migrating }) => {
494
480
  ns: SPACE_PLUGIN
495
481
  }
496
482
  ],
497
- icon: (props) => /* @__PURE__ */ React6.createElement(X, props),
498
- iconSymbol: "ph--x--regular",
483
+ icon: "ph--x--regular",
499
484
  mainAreaDisposition: "menu",
500
485
  disabled: personal
501
486
  }
@@ -521,8 +506,7 @@ var constructSpaceActions = ({ space, dispatch, personal, migrating }) => {
521
506
  ns: SPACE_PLUGIN
522
507
  }
523
508
  ],
524
- icon: (props) => /* @__PURE__ */ React6.createElement(ClockCounterClockwise, props),
525
- iconSymbol: "ph--clock-counter-clockwise--regular",
509
+ icon: "ph--clock-counter-clockwise--regular",
526
510
  disposition: "toolbar",
527
511
  mainAreaDisposition: "in-flow"
528
512
  }
@@ -556,8 +540,7 @@ var createObjectNode = ({ object, space, resolve }) => {
556
540
  ns: SPACE_PLUGIN
557
541
  }
558
542
  ],
559
- icon: metadata.icon ?? (() => /* @__PURE__ */ React6.createElement(Placeholder, null)),
560
- iconSymbol: metadata.iconSymbol ?? "ph--placeholder--regular",
543
+ icon: metadata.icon ?? "ph--placeholder--regular",
561
544
  testId: "spacePlugin.object",
562
545
  persistenceClass: "echo",
563
546
  persistenceKey: space?.id
@@ -582,8 +565,7 @@ var constructObjectActionGroups = ({ object, dispatch }) => {
582
565
  ns: SPACE_PLUGIN
583
566
  }
584
567
  ],
585
- icon: (props) => /* @__PURE__ */ React6.createElement(Plus, props),
586
- iconSymbol: "ph--plus--regular",
568
+ icon: "ph--plus--regular",
587
569
  disposition: "toolbar",
588
570
  // TODO(wittjosiah): This is currently a navtree feature. Address this with cmd+k integration.
589
571
  // mainAreaDisposition: 'in-flow',
@@ -617,8 +599,7 @@ var constructObjectActionGroups = ({ object, dispatch }) => {
617
599
  ns: SPACE_PLUGIN
618
600
  }
619
601
  ],
620
- icon: (props) => /* @__PURE__ */ React6.createElement(CardsThree, props),
621
- iconSymbol: "ph--cards-three--regular",
602
+ icon: "ph--cards-three--regular",
622
603
  testId: "spacePlugin.createCollection"
623
604
  }
624
605
  }
@@ -650,8 +631,7 @@ var constructObjectActions = ({ node, dispatch }) => {
650
631
  ns: SPACE_PLUGIN
651
632
  }
652
633
  ],
653
- icon: (props) => /* @__PURE__ */ React6.createElement(PencilSimpleLine, props),
654
- iconSymbol: "ph--pencil-simple-line--regular",
634
+ icon: "ph--pencil-simple-line--regular",
655
635
  // TODO(wittjosiah): Doesn't work.
656
636
  // keyBinding: 'shift+F6',
657
637
  testId: "spacePlugin.renameObject"
@@ -682,8 +662,7 @@ var constructObjectActions = ({ node, dispatch }) => {
682
662
  ns: SPACE_PLUGIN
683
663
  }
684
664
  ],
685
- icon: (props) => /* @__PURE__ */ React6.createElement(Trash, props),
686
- iconSymbol: "ph--trash--regular",
665
+ icon: "ph--trash--regular",
687
666
  keyBinding: object instanceof CollectionType ? void 0 : "shift+meta+Backspace",
688
667
  testId: "spacePlugin.deleteObject"
689
668
  }
@@ -702,8 +681,7 @@ var constructObjectActions = ({ node, dispatch }) => {
702
681
  ns: SPACE_PLUGIN
703
682
  }
704
683
  ],
705
- icon: (props) => /* @__PURE__ */ React6.createElement(Link, props),
706
- iconSymbol: "ph--link--regular",
684
+ icon: "ph--link--regular",
707
685
  testId: "spacePlugin.copyLink"
708
686
  }
709
687
  }
@@ -737,14 +715,14 @@ var getNestedObjects = async (object, resolve) => {
737
715
  ...nested.flat()
738
716
  ];
739
717
  };
740
- var cloneObject = async (object, resolve) => {
718
+ var cloneObject = async (object, resolve, newSpace) => {
741
719
  const schema = getSchema(object);
742
- const typename = schema ? getEchoObjectAnnotation(schema)?.typename ?? EXPANDO_TYPENAME : EXPANDO_TYPENAME;
720
+ const typename = schema ? getObjectAnnotation(schema)?.typename ?? EXPANDO_TYPENAME : EXPANDO_TYPENAME;
743
721
  const metadata = resolve(typename);
744
722
  const serializer = metadata.serializer;
745
723
  invariant(serializer, `No serializer for type: ${typename}`, {
746
724
  F: __dxlog_file,
747
- L: 639,
725
+ L: 604,
748
726
  S: void 0,
749
727
  A: [
750
728
  "serializer",
@@ -756,37 +734,38 @@ var cloneObject = async (object, resolve) => {
756
734
  });
757
735
  return serializer.deserialize({
758
736
  content,
737
+ space: newSpace,
759
738
  newId: true
760
739
  });
761
740
  };
762
741
 
763
742
  // packages/plugins/plugin-space/src/components/MenuFooter.tsx
764
743
  var MenuFooter = ({ object }) => {
765
- const { t } = useTranslation6(SPACE_PLUGIN);
744
+ const { t } = useTranslation5(SPACE_PLUGIN);
766
745
  const client = useClient2();
767
746
  const space = getSpace2(object);
768
747
  const spaceName = space ? getSpaceDisplayName(space, {
769
748
  personal: client.spaces.default === space
770
749
  }) : "";
771
- return space ? /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(DropdownMenu.Separator, null), /* @__PURE__ */ React7.createElement(DropdownMenu.GroupLabel, null, t("menu footer label")), /* @__PURE__ */ React7.createElement("dl", {
750
+ return space ? /* @__PURE__ */ React5.createElement(React5.Fragment, null, /* @__PURE__ */ React5.createElement(DropdownMenu.Separator, null), /* @__PURE__ */ React5.createElement(DropdownMenu.GroupLabel, null, t("menu footer label")), /* @__PURE__ */ React5.createElement("dl", {
772
751
  className: "pis-2 mbe-2 text-xs grid grid-cols-[max-content_1fr] gap-2"
773
- }, /* @__PURE__ */ React7.createElement("dt", {
752
+ }, /* @__PURE__ */ React5.createElement("dt", {
774
753
  className: "uppercase text-[.75em] tracking-wide font-medium mbs-px self-start"
775
- }, t("location label")), /* @__PURE__ */ React7.createElement("dd", {
754
+ }, t("location label")), /* @__PURE__ */ React5.createElement("dd", {
776
755
  className: "line-clamp-3"
777
- }, /* @__PURE__ */ React7.createElement(Planet2, {
756
+ }, /* @__PURE__ */ React5.createElement(Planet, {
778
757
  className: "inline-block mie-1"
779
758
  }), toLocalizedString(spaceName, t)))) : null;
780
759
  };
781
760
 
782
761
  // packages/plugins/plugin-space/src/components/MissingObject.tsx
783
- import React8, { useEffect as useEffect2, useState as useState2 } from "react";
762
+ import React6, { useEffect as useEffect2, useState as useState2 } from "react";
784
763
  import { parseIntentPlugin as parseIntentPlugin2, useResolvePlugin as useResolvePlugin2 } from "@dxos/app-framework";
785
- import { Status, useTranslation as useTranslation7 } from "@dxos/react-ui";
786
- import { baseSurface as baseSurface2, descriptionText as descriptionText4, mx as mx5 } from "@dxos/react-ui-theme";
764
+ import { Status, useTranslation as useTranslation6 } from "@dxos/react-ui";
765
+ import { baseSurface as baseSurface2, descriptionText as descriptionText2, mx as mx3 } from "@dxos/react-ui-theme";
787
766
  var WAIT_FOR_OBJECT_TIMEOUT2 = 1e3;
788
767
  var MissingObject = ({ id }) => {
789
- const { t } = useTranslation7(SPACE_PLUGIN);
768
+ const { t } = useTranslation6(SPACE_PLUGIN);
790
769
  const [waiting, setWaiting] = useState2(false);
791
770
  const intentPlugin = useResolvePlugin2(parseIntentPlugin2);
792
771
  useEffect2(() => {
@@ -808,13 +787,13 @@ var MissingObject = ({ id }) => {
808
787
  intentPlugin,
809
788
  id
810
789
  ]);
811
- return /* @__PURE__ */ React8.createElement("div", {
790
+ return /* @__PURE__ */ React6.createElement("div", {
812
791
  role: "none",
813
- className: mx5(baseSurface2, "min-bs-screen is-full flex items-center justify-center p-8")
814
- }, waiting ? /* @__PURE__ */ React8.createElement("p", {
792
+ className: mx3(baseSurface2, "min-bs-screen is-full flex items-center justify-center p-8")
793
+ }, waiting ? /* @__PURE__ */ React6.createElement("p", {
815
794
  role: "alert",
816
- className: mx5(descriptionText4, "border border-dashed border-neutral-400/50 rounded-lg flex items-center justify-center p-8 font-normal text-lg")
817
- }, t("missing object message")) : /* @__PURE__ */ React8.createElement(Status, {
795
+ className: mx3(descriptionText2, "border border-dashed border-neutral-400/50 rounded-lg flex items-center justify-center p-8 font-normal text-lg")
796
+ }, t("missing object message")) : /* @__PURE__ */ React6.createElement(Status, {
818
797
  indeterminate: true,
819
798
  "aria-label": "Initializing"
820
799
  }));
@@ -822,10 +801,10 @@ var MissingObject = ({ id }) => {
822
801
 
823
802
  // packages/plugins/plugin-space/src/components/PersistenceStatus.tsx
824
803
  import { ArrowsCounterClockwise, CheckCircle as CheckCircle2, Warning } from "@phosphor-icons/react";
825
- import React9, { useEffect as useEffect3, useState as useState3 } from "react";
804
+ import React7, { useEffect as useEffect3, useState as useState3 } from "react";
826
805
  import { debounce } from "@dxos/async";
827
- import { Tooltip, useTranslation as useTranslation8 } from "@dxos/react-ui";
828
- import { getSize as getSize2, mx as mx6, staticPlaceholderText, warningText } from "@dxos/react-ui-theme";
806
+ import { Tooltip, useTranslation as useTranslation7 } from "@dxos/react-ui";
807
+ import { getSize as getSize2, mx as mx4, staticPlaceholderText, warningText } from "@dxos/react-ui-theme";
829
808
  var Status2;
830
809
  (function(Status3) {
831
810
  Status3[Status3["PERSISTED_LOCALLY"] = 0] = "PERSISTED_LOCALLY";
@@ -833,7 +812,7 @@ var Status2;
833
812
  Status3[Status3["ERROR"] = 2] = "ERROR";
834
813
  })(Status2 || (Status2 = {}));
835
814
  var PersistenceStatus = ({ db }) => {
836
- const { t } = useTranslation8(SPACE_PLUGIN);
815
+ const { t } = useTranslation7(SPACE_PLUGIN);
837
816
  const [displayMessage, setDisplayMessage] = useState3(false);
838
817
  const [status, naturalSetStatus] = useState3(0);
839
818
  const [prevStatus, setPrevStatus] = useState3(0);
@@ -850,45 +829,45 @@ var PersistenceStatus = ({ db }) => {
850
829
  ]);
851
830
  switch (status) {
852
831
  case 2:
853
- return /* @__PURE__ */ React9.createElement("div", {
832
+ return /* @__PURE__ */ React7.createElement("div", {
854
833
  className: "flex items-center"
855
- }, /* @__PURE__ */ React9.createElement(Warning, {
856
- className: mx6(getSize2(4), "me-1")
857
- }), /* @__PURE__ */ React9.createElement("span", {
858
- className: mx6("text-sm", warningText)
834
+ }, /* @__PURE__ */ React7.createElement(Warning, {
835
+ className: mx4(getSize2(4), "me-1")
836
+ }), /* @__PURE__ */ React7.createElement("span", {
837
+ className: mx4("text-sm", warningText)
859
838
  }, t("persistence error label")));
860
839
  case 1:
861
- return /* @__PURE__ */ React9.createElement("div", {
840
+ return /* @__PURE__ */ React7.createElement("div", {
862
841
  className: "flex items-center"
863
- }, /* @__PURE__ */ React9.createElement(ArrowsCounterClockwise, {
864
- className: mx6(getSize2(4), "me-1")
865
- }), /* @__PURE__ */ React9.createElement("span", {
866
- className: mx6("text-sm", staticPlaceholderText)
842
+ }, /* @__PURE__ */ React7.createElement(ArrowsCounterClockwise, {
843
+ className: mx4(getSize2(4), "me-1")
844
+ }), /* @__PURE__ */ React7.createElement("span", {
845
+ className: mx4("text-sm", staticPlaceholderText)
867
846
  }, t("persistence pending label")));
868
847
  case 0:
869
848
  default:
870
- return /* @__PURE__ */ React9.createElement(Tooltip.Root, {
849
+ return /* @__PURE__ */ React7.createElement(Tooltip.Root, {
871
850
  delayDuration: 400
872
- }, /* @__PURE__ */ React9.createElement(Tooltip.Trigger, {
851
+ }, /* @__PURE__ */ React7.createElement(Tooltip.Trigger, {
873
852
  role: "status",
874
853
  className: "flex items-center"
875
- }, /* @__PURE__ */ React9.createElement(CheckCircle2, {
876
- className: mx6(getSize2(4), "me-1")
877
- }), displayMessage && /* @__PURE__ */ React9.createElement("span", {
878
- className: mx6("text-sm", staticPlaceholderText)
879
- }, t("persisted locally label"))), /* @__PURE__ */ React9.createElement(Tooltip.Portal, null, /* @__PURE__ */ React9.createElement(Tooltip.Content, {
854
+ }, /* @__PURE__ */ React7.createElement(CheckCircle2, {
855
+ className: mx4(getSize2(4), "me-1")
856
+ }), displayMessage && /* @__PURE__ */ React7.createElement("span", {
857
+ className: mx4("text-sm", staticPlaceholderText)
858
+ }, t("persisted locally label"))), /* @__PURE__ */ React7.createElement(Tooltip.Portal, null, /* @__PURE__ */ React7.createElement(Tooltip.Content, {
880
859
  classNames: "z-10"
881
- }, t("persisted locally message"), /* @__PURE__ */ React9.createElement(Tooltip.Arrow, null))));
860
+ }, t("persisted locally message"), /* @__PURE__ */ React7.createElement(Tooltip.Arrow, null))));
882
861
  }
883
862
  };
884
863
 
885
864
  // packages/plugins/plugin-space/src/components/PopoverRenameObject.tsx
886
- import React10, { useCallback, useRef, useState as useState4 } from "react";
865
+ import React8, { useCallback, useRef, useState as useState4 } from "react";
887
866
  import { log } from "@dxos/log";
888
- import { Button as Button2, Input, Popover, useTranslation as useTranslation9 } from "@dxos/react-ui";
867
+ import { Button as Button2, Input as Input2, Popover, useTranslation as useTranslation8 } from "@dxos/react-ui";
889
868
  var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-space/src/components/PopoverRenameObject.tsx";
890
869
  var PopoverRenameObject = ({ object: obj }) => {
891
- const { t } = useTranslation9(SPACE_PLUGIN);
870
+ const { t } = useTranslation8(SPACE_PLUGIN);
892
871
  const doneButton = useRef(null);
893
872
  const object = obj;
894
873
  const [name, setName] = useState4(object.name || object.title || "");
@@ -913,23 +892,23 @@ var PopoverRenameObject = ({ object: obj }) => {
913
892
  object,
914
893
  name
915
894
  ]);
916
- return /* @__PURE__ */ React10.createElement("div", {
895
+ return /* @__PURE__ */ React8.createElement("div", {
917
896
  role: "none",
918
897
  className: "p-1 flex gap-2"
919
- }, /* @__PURE__ */ React10.createElement("div", {
898
+ }, /* @__PURE__ */ React8.createElement("div", {
920
899
  role: "none",
921
900
  className: "flex-1"
922
- }, /* @__PURE__ */ React10.createElement(Input.Root, null, /* @__PURE__ */ React10.createElement(Input.Label, {
901
+ }, /* @__PURE__ */ React8.createElement(Input2.Root, null, /* @__PURE__ */ React8.createElement(Input2.Label, {
923
902
  srOnly: true
924
- }, t("object name label")), /* @__PURE__ */ React10.createElement(Input.TextInput, {
903
+ }, t("object name label")), /* @__PURE__ */ React8.createElement(Input2.TextInput, {
925
904
  placeholder: t("object title placeholder"),
926
905
  value: name,
927
906
  "data-testid": "spacePlugin.renameObject.input",
928
907
  onChange: ({ target: { value } }) => setName(value),
929
908
  onKeyDown: ({ key }) => key === "Enter" && doneButton.current?.click()
930
- }))), /* @__PURE__ */ React10.createElement(Popover.Close, {
909
+ }))), /* @__PURE__ */ React8.createElement(Popover.Close, {
931
910
  asChild: true
932
- }, /* @__PURE__ */ React10.createElement(Button2, {
911
+ }, /* @__PURE__ */ React8.createElement(Button2, {
933
912
  ref: doneButton,
934
913
  classNames: "self-stretch",
935
914
  onClick: handleDone
@@ -939,10 +918,10 @@ var PopoverRenameObject = ({ object: obj }) => {
939
918
  };
940
919
 
941
920
  // packages/plugins/plugin-space/src/components/PopoverRenameSpace.tsx
942
- import React11, { useCallback as useCallback2, useRef as useRef2, useState as useState5 } from "react";
943
- import { Button as Button3, Input as Input2, Popover as Popover2, useTranslation as useTranslation10 } from "@dxos/react-ui";
921
+ import React9, { useCallback as useCallback2, useRef as useRef2, useState as useState5 } from "react";
922
+ import { Button as Button3, Input as Input3, Popover as Popover2, useTranslation as useTranslation9 } from "@dxos/react-ui";
944
923
  var PopoverRenameSpace = ({ space }) => {
945
- const { t } = useTranslation10(SPACE_PLUGIN);
924
+ const { t } = useTranslation9(SPACE_PLUGIN);
946
925
  const doneButton = useRef2(null);
947
926
  const [name, setName] = useState5(space.properties.name ?? "");
948
927
  const handleDone = useCallback2(() => {
@@ -951,24 +930,24 @@ var PopoverRenameSpace = ({ space }) => {
951
930
  space,
952
931
  name
953
932
  ]);
954
- return /* @__PURE__ */ React11.createElement("div", {
933
+ return /* @__PURE__ */ React9.createElement("div", {
955
934
  role: "none",
956
935
  className: "p-1 flex gap-2"
957
- }, /* @__PURE__ */ React11.createElement("div", {
936
+ }, /* @__PURE__ */ React9.createElement("div", {
958
937
  role: "none",
959
938
  className: "flex-1"
960
- }, /* @__PURE__ */ React11.createElement(Input2.Root, null, /* @__PURE__ */ React11.createElement(Input2.Label, {
939
+ }, /* @__PURE__ */ React9.createElement(Input3.Root, null, /* @__PURE__ */ React9.createElement(Input3.Label, {
961
940
  srOnly: true
962
- }, t("space name label")), /* @__PURE__ */ React11.createElement(Input2.TextInput, {
941
+ }, t("space name label")), /* @__PURE__ */ React9.createElement(Input3.TextInput, {
963
942
  defaultValue: space.properties.name ?? "",
964
943
  placeholder: t("unnamed space label"),
965
944
  onChange: ({ target: { value } }) => setName(value),
966
945
  // TODO(wittjosiah): Ideally this should access the popover context to close the popover.
967
946
  // Currently this is not possible because Radix does not expose the popover context.
968
947
  onKeyDown: ({ key }) => key === "Enter" && doneButton.current?.click()
969
- }))), /* @__PURE__ */ React11.createElement(Popover2.Close, {
948
+ }))), /* @__PURE__ */ React9.createElement(Popover2.Close, {
970
949
  asChild: true
971
- }, /* @__PURE__ */ React11.createElement(Button3, {
950
+ }, /* @__PURE__ */ React9.createElement(Button3, {
972
951
  ref: doneButton,
973
952
  classNames: "self-stretch",
974
953
  onClick: handleDone
@@ -978,12 +957,12 @@ var PopoverRenameSpace = ({ space }) => {
978
957
  };
979
958
 
980
959
  // packages/plugins/plugin-space/src/components/ShareSpaceButton.tsx
981
- import React12 from "react";
960
+ import React10 from "react";
982
961
  import { useIntentDispatcher } from "@dxos/app-framework";
983
- import { Button as Button4, useTranslation as useTranslation11 } from "@dxos/react-ui";
962
+ import { Button as Button4, useTranslation as useTranslation10 } from "@dxos/react-ui";
984
963
  var ShareSpaceButton = ({ spaceId }) => {
985
964
  const dispatch = useIntentDispatcher();
986
- return /* @__PURE__ */ React12.createElement(ShareSpaceButtonImpl, {
965
+ return /* @__PURE__ */ React10.createElement(ShareSpaceButtonImpl, {
987
966
  onClick: () => dispatch({
988
967
  action: SpaceAction.SHARE,
989
968
  data: {
@@ -993,8 +972,8 @@ var ShareSpaceButton = ({ spaceId }) => {
993
972
  });
994
973
  };
995
974
  var ShareSpaceButtonImpl = ({ onClick }) => {
996
- const { t } = useTranslation11(SPACE_PLUGIN);
997
- return /* @__PURE__ */ React12.createElement(Button4, {
975
+ const { t } = useTranslation10(SPACE_PLUGIN);
976
+ return /* @__PURE__ */ React10.createElement(Button4, {
998
977
  "data-testid": "spacePlugin.shareSpaceButton",
999
978
  onClick,
1000
979
  classNames: "mli-1"
@@ -1003,30 +982,30 @@ var ShareSpaceButtonImpl = ({ onClick }) => {
1003
982
 
1004
983
  // packages/plugins/plugin-space/src/components/SpaceMain/SpaceMain.tsx
1005
984
  import { Command } from "@phosphor-icons/react";
1006
- import React14 from "react";
985
+ import React12 from "react";
1007
986
  import { Surface } from "@dxos/app-framework";
1008
987
  import { SpaceState as SpaceState2 } from "@dxos/react-client/echo";
1009
- import { Button as Button6, Main, useTranslation as useTranslation13, toLocalizedString as toLocalizedString2 } from "@dxos/react-ui";
1010
- import { getSize as getSize4, mx as mx8, topbarBlockPaddingStart } from "@dxos/react-ui-theme";
988
+ import { Main, useTranslation as useTranslation12 } from "@dxos/react-ui";
989
+ import { getSize as getSize4, mx as mx6, topbarBlockPaddingStart } from "@dxos/react-ui-theme";
1011
990
  import { ClipboardProvider } from "@dxos/shell/react";
1012
991
 
1013
992
  // packages/plugins/plugin-space/src/components/SpaceMain/SpaceMembersSection.tsx
1014
993
  import { CaretDown, Check, UserPlus, UsersThree } from "@phosphor-icons/react";
1015
- import React13, { useCallback as useCallback3, useState as useState6 } from "react";
994
+ import React11, { useCallback as useCallback3, useState as useState6 } from "react";
1016
995
  import { LayoutAction, useIntent } from "@dxos/app-framework";
1017
996
  import { useMembers, SpaceMember, useSpaceInvitations } from "@dxos/react-client/echo";
1018
997
  import { InvitationEncoder } from "@dxos/react-client/invitations";
1019
998
  import { Invitation } from "@dxos/react-client/invitations";
1020
- import { Button as Button5, ButtonGroup, DropdownMenu as DropdownMenu2, List, useTranslation as useTranslation12 } from "@dxos/react-ui";
1021
- import { descriptionText as descriptionText5, getSize as getSize3, mx as mx7 } from "@dxos/react-ui-theme";
999
+ import { Button as Button5, ButtonGroup, DropdownMenu as DropdownMenu2, List, useTranslation as useTranslation11 } from "@dxos/react-ui";
1000
+ import { descriptionText as descriptionText3, getSize as getSize3, mx as mx5 } from "@dxos/react-ui-theme";
1022
1001
  import { InvitationListItem, IdentityListItem } from "@dxos/shell/react";
1023
1002
  var activeActionKeyStorageKey = "dxos:react-shell/space-manager/active-action";
1024
1003
  var Presence = SpaceMember.PresenceState;
1025
1004
  var handleCreateInvitationUrl = (invitationCode) => `${origin}?spaceInvitationCode=${invitationCode}`;
1026
1005
  var SpaceMemberList = ({ members }) => {
1027
- return members.length > 0 ? /* @__PURE__ */ React13.createElement(List, {
1006
+ return members.length > 0 ? /* @__PURE__ */ React11.createElement(List, {
1028
1007
  classNames: "col-start-2 col-end-5 gap-y-1 grid grid-cols-subgrid items-center"
1029
- }, members.map((member) => /* @__PURE__ */ React13.createElement(IdentityListItem, {
1008
+ }, members.map((member) => /* @__PURE__ */ React11.createElement(IdentityListItem, {
1030
1009
  classNames: "contents",
1031
1010
  key: member.identity.identityKey.toHex(),
1032
1011
  identity: member.identity,
@@ -1034,7 +1013,7 @@ var SpaceMemberList = ({ members }) => {
1034
1013
  }))) : null;
1035
1014
  };
1036
1015
  var SpaceMembersSection = ({ space }) => {
1037
- const { t } = useTranslation12(SPACE_PLUGIN);
1016
+ const { t } = useTranslation11(SPACE_PLUGIN);
1038
1017
  const invitations = useSpaceInvitations(space.key);
1039
1018
  const { dispatch } = useIntent();
1040
1019
  const handleCloseDialog = () => dispatch({
@@ -1112,103 +1091,103 @@ var SpaceMembersSection = ({ space }) => {
1112
1091
  [Presence.ONLINE]: [],
1113
1092
  [Presence.OFFLINE]: []
1114
1093
  });
1115
- return /* @__PURE__ */ React13.createElement("section", {
1094
+ return /* @__PURE__ */ React11.createElement("section", {
1116
1095
  className: "mbe-4 col-span-3 grid gap-y-2 grid-cols-subgrid auto-rows-min"
1117
- }, /* @__PURE__ */ React13.createElement("h2", {
1096
+ }, /* @__PURE__ */ React11.createElement("h2", {
1118
1097
  className: "contents"
1119
- }, /* @__PURE__ */ React13.createElement(UsersThree, {
1098
+ }, /* @__PURE__ */ React11.createElement(UsersThree, {
1120
1099
  weight: "duotone",
1121
- className: mx7(getSize3(5), "place-self-center")
1122
- }), /* @__PURE__ */ React13.createElement("span", {
1100
+ className: mx5(getSize3(5), "place-self-center")
1101
+ }), /* @__PURE__ */ React11.createElement("span", {
1123
1102
  className: "text-lg col-span-2"
1124
- }, t("space members label"))), /* @__PURE__ */ React13.createElement("h3", {
1103
+ }, t("space members label"))), /* @__PURE__ */ React11.createElement("h3", {
1125
1104
  className: "col-start-2 col-span-3 text-sm italic text-description"
1126
- }, t("invitations heading")), invitations.length > 0 && /* @__PURE__ */ React13.createElement(List, {
1105
+ }, t("invitations heading")), invitations.length > 0 && /* @__PURE__ */ React11.createElement(List, {
1127
1106
  classNames: "col-start-2 col-span-2 gap-y-2 grid grid-cols-[var(--rail-size)_1fr_var(--rail-action)_var(--rail-action)]"
1128
- }, invitations.map((invitation) => /* @__PURE__ */ React13.createElement(InvitationListItem, {
1107
+ }, invitations.map((invitation) => /* @__PURE__ */ React11.createElement(InvitationListItem, {
1129
1108
  reverseEffects: true,
1130
1109
  classNames: "pis-0 pie-0 gap-0 col-span-4 grid grid-cols-subgrid",
1131
1110
  key: invitation.get().invitationId,
1132
1111
  invitation,
1133
1112
  send: handleInvitationSelect,
1134
1113
  createInvitationUrl: handleCreateInvitationUrl
1135
- }))), /* @__PURE__ */ React13.createElement(ButtonGroup, {
1114
+ }))), /* @__PURE__ */ React11.createElement(ButtonGroup, {
1136
1115
  classNames: "col-start-2 col-end-4 grid grid-cols-[1fr_var(--rail-action)] place-self-grow gap-px"
1137
- }, /* @__PURE__ */ React13.createElement(Button5, {
1116
+ }, /* @__PURE__ */ React11.createElement(Button5, {
1138
1117
  classNames: "gap-2",
1139
1118
  onClick: activeAction.onClick
1140
- }, /* @__PURE__ */ React13.createElement(activeAction.icon, {
1119
+ }, /* @__PURE__ */ React11.createElement(activeAction.icon, {
1141
1120
  className: getSize3(5)
1142
- }), /* @__PURE__ */ React13.createElement("span", null, t(activeAction.label, {
1121
+ }), /* @__PURE__ */ React11.createElement("span", null, t(activeAction.label, {
1143
1122
  ns: "os"
1144
- }))), /* @__PURE__ */ React13.createElement(DropdownMenu2.Root, null, /* @__PURE__ */ React13.createElement(DropdownMenu2.Trigger, {
1123
+ }))), /* @__PURE__ */ React11.createElement(DropdownMenu2.Root, null, /* @__PURE__ */ React11.createElement(DropdownMenu2.Trigger, {
1145
1124
  asChild: true
1146
- }, /* @__PURE__ */ React13.createElement(Button5, {
1125
+ }, /* @__PURE__ */ React11.createElement(Button5, {
1147
1126
  classNames: "pli-0"
1148
- }, /* @__PURE__ */ React13.createElement(CaretDown, {
1127
+ }, /* @__PURE__ */ React11.createElement(CaretDown, {
1149
1128
  className: getSize3(4)
1150
- }))), /* @__PURE__ */ React13.createElement(DropdownMenu2.Content, null, /* @__PURE__ */ React13.createElement(DropdownMenu2.Viewport, null, Object.entries(inviteActions).map(([id, action]) => {
1151
- return /* @__PURE__ */ React13.createElement(DropdownMenu2.CheckboxItem, {
1129
+ }))), /* @__PURE__ */ React11.createElement(DropdownMenu2.Content, null, /* @__PURE__ */ React11.createElement(DropdownMenu2.Viewport, null, Object.entries(inviteActions).map(([id, action]) => {
1130
+ return /* @__PURE__ */ React11.createElement(DropdownMenu2.CheckboxItem, {
1152
1131
  key: id,
1153
1132
  "aria-labelledby": `${id}__label`,
1154
1133
  "aria-describedby": `${id}__description`,
1155
1134
  checked: activeActionKey === id,
1156
1135
  onCheckedChange: (checked) => checked && setActiveActionKey(id),
1157
1136
  classNames: "gap-2"
1158
- }, action.icon && /* @__PURE__ */ React13.createElement(action.icon, {
1137
+ }, action.icon && /* @__PURE__ */ React11.createElement(action.icon, {
1159
1138
  className: getSize3(5)
1160
- }), /* @__PURE__ */ React13.createElement("div", {
1139
+ }), /* @__PURE__ */ React11.createElement("div", {
1161
1140
  role: "none",
1162
1141
  className: "flex-1 min-is-0 space-b-1"
1163
- }, /* @__PURE__ */ React13.createElement("p", {
1142
+ }, /* @__PURE__ */ React11.createElement("p", {
1164
1143
  id: `${id}__label`
1165
1144
  }, t(action.label, {
1166
1145
  ns: "os"
1167
- })), action.description && /* @__PURE__ */ React13.createElement("p", {
1146
+ })), action.description && /* @__PURE__ */ React11.createElement("p", {
1168
1147
  id: `${id}__description`,
1169
- className: descriptionText5
1148
+ className: descriptionText3
1170
1149
  }, t(action.description, {
1171
1150
  ns: "os"
1172
- }))), /* @__PURE__ */ React13.createElement(DropdownMenu2.ItemIndicator, {
1151
+ }))), /* @__PURE__ */ React11.createElement(DropdownMenu2.ItemIndicator, {
1173
1152
  asChild: true
1174
- }, /* @__PURE__ */ React13.createElement(Check, {
1153
+ }, /* @__PURE__ */ React11.createElement(Check, {
1175
1154
  className: getSize3(4)
1176
1155
  })));
1177
- })), /* @__PURE__ */ React13.createElement(DropdownMenu2.Arrow, null)))), members[Presence.ONLINE].length + members[Presence.OFFLINE].length < 1 ? /* @__PURE__ */ React13.createElement("p", {
1178
- className: mx7(descriptionText5, "text-center is-full mlb-2")
1156
+ })), /* @__PURE__ */ React11.createElement(DropdownMenu2.Arrow, null)))), members[Presence.ONLINE].length + members[Presence.OFFLINE].length < 1 ? /* @__PURE__ */ React11.createElement("p", {
1157
+ className: mx5(descriptionText3, "text-center is-full mlb-2")
1179
1158
  }, t("empty space members message", {
1180
1159
  ns: "os"
1181
- })) : /* @__PURE__ */ React13.createElement(React13.Fragment, null, /* @__PURE__ */ React13.createElement("h3", {
1160
+ })) : /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement("h3", {
1182
1161
  className: "col-start-2 col-end-5 text-sm italic text-description"
1183
1162
  }, t("active space members heading", {
1184
1163
  count: members[Presence.ONLINE].length
1185
- })), /* @__PURE__ */ React13.createElement(SpaceMemberList, {
1164
+ })), /* @__PURE__ */ React11.createElement(SpaceMemberList, {
1186
1165
  members: members[Presence.ONLINE]
1187
- }), /* @__PURE__ */ React13.createElement("h3", {
1166
+ }), /* @__PURE__ */ React11.createElement("h3", {
1188
1167
  className: "col-start-2 col-end-5 text-sm italic text-description"
1189
1168
  }, t("inactive space members heading", {
1190
1169
  count: members[Presence.OFFLINE].length
1191
- })), /* @__PURE__ */ React13.createElement(SpaceMemberList, {
1170
+ })), /* @__PURE__ */ React11.createElement(SpaceMemberList, {
1192
1171
  members: members[Presence.OFFLINE]
1193
1172
  })));
1194
1173
  };
1195
1174
 
1196
1175
  // packages/plugins/plugin-space/src/components/SpaceMain/SpaceMain.tsx
1197
1176
  var KeyShortcuts = () => {
1198
- const { t } = useTranslation13(SPACE_PLUGIN);
1199
- return /* @__PURE__ */ React14.createElement("section", {
1177
+ const { t } = useTranslation12(SPACE_PLUGIN);
1178
+ return /* @__PURE__ */ React12.createElement("section", {
1200
1179
  className: "mbe-4 col-span-4 md:col-start-5 md:col-end-7 grid grid-cols-subgrid gap-y-2 auto-rows-min"
1201
- }, /* @__PURE__ */ React14.createElement("h2", {
1180
+ }, /* @__PURE__ */ React12.createElement("h2", {
1202
1181
  className: "contents"
1203
- }, /* @__PURE__ */ React14.createElement(Command, {
1182
+ }, /* @__PURE__ */ React12.createElement(Command, {
1204
1183
  weight: "duotone",
1205
- className: mx8(getSize4(5), "place-self-center")
1206
- }), /* @__PURE__ */ React14.createElement("span", {
1184
+ className: mx6(getSize4(5), "place-self-center")
1185
+ }), /* @__PURE__ */ React12.createElement("span", {
1207
1186
  className: "text-lg col-span-2 md:col-span-1"
1208
- }, t("keyshortcuts label"))), /* @__PURE__ */ React14.createElement("div", {
1187
+ }, t("keyshortcuts label"))), /* @__PURE__ */ React12.createElement("div", {
1209
1188
  role: "none",
1210
1189
  className: "col-start-2 col-end-4 md:col-end-5 pie-2"
1211
- }, /* @__PURE__ */ React14.createElement(Surface, {
1190
+ }, /* @__PURE__ */ React12.createElement(Surface, {
1212
1191
  role: "keyshortcuts"
1213
1192
  })));
1214
1193
  };
@@ -1217,7 +1196,7 @@ var SpaceMain = ({ space, role }) => {
1217
1196
  const state = space.state.get();
1218
1197
  const ready = state === SpaceState2.SPACE_READY;
1219
1198
  const Root = role === "main" ? Main.Content : "div";
1220
- return /* @__PURE__ */ React14.createElement(ClipboardProvider, null, /* @__PURE__ */ React14.createElement(Root, {
1199
+ return /* @__PURE__ */ React12.createElement(ClipboardProvider, null, /* @__PURE__ */ React12.createElement(Root, {
1221
1200
  ...role === "main" ? {
1222
1201
  classNames: [
1223
1202
  topbarBlockPaddingStart,
@@ -1226,31 +1205,30 @@ var SpaceMain = ({ space, role }) => {
1226
1205
  ]
1227
1206
  } : {
1228
1207
  role: "none",
1229
- className: mx8(topbarBlockPaddingStart, "row-span-2", spaceMainLayout)
1208
+ className: mx6(topbarBlockPaddingStart, "row-span-2", spaceMainLayout)
1230
1209
  },
1231
1210
  "data-testid": `spacePlugin.${role}`,
1232
1211
  "data-isready": ready ? "true" : "false"
1233
- }, ready && /* @__PURE__ */ React14.createElement(SpaceMembersSection, {
1212
+ }, ready && /* @__PURE__ */ React12.createElement(SpaceMembersSection, {
1234
1213
  space
1235
- }), /* @__PURE__ */ React14.createElement(KeyShortcuts, null)));
1214
+ }), /* @__PURE__ */ React12.createElement(KeyShortcuts, null)));
1236
1215
  };
1237
1216
 
1238
1217
  // packages/plugins/plugin-space/src/components/SpacePresence.tsx
1239
- import React15, { useCallback as useCallback4, useEffect as useEffect4, useState as useState7 } from "react";
1218
+ import React13, { useCallback as useCallback4, useEffect as useEffect4, useState as useState7 } from "react";
1240
1219
  import { usePlugin } from "@dxos/app-framework";
1241
1220
  import { generateName } from "@dxos/display-name";
1242
1221
  import { PublicKey, useClient as useClient3 } from "@dxos/react-client";
1243
1222
  import { getSpace as getSpace3, useMembers as useMembers2, fullyQualifiedId as fullyQualifiedId3 } from "@dxos/react-client/echo";
1244
1223
  import { useIdentity } from "@dxos/react-client/halo";
1245
- import { Avatar, AvatarGroup, AvatarGroupItem, Tooltip as Tooltip2, useDensityContext, useTranslation as useTranslation14, List as List2, ListItem, useDefaultValue } from "@dxos/react-ui";
1246
- 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";
1247
1226
  import { ComplexMap, keyToFallback } from "@dxos/util";
1248
1227
  var REFRESH_INTERVAL = 5e3;
1249
1228
  var ACTIVITY_DURATION = 3e4;
1250
1229
  var noViewers = new ComplexMap(PublicKey.hash);
1251
1230
  var getName = (identity) => identity.profile?.displayName ?? generateName(identity.identityKey.toHex());
1252
1231
  var SpacePresence = ({ object, spaceKey }) => {
1253
- const density = useDensityContext();
1254
1232
  const spacePlugin = usePlugin(SPACE_PLUGIN);
1255
1233
  const client = useClient3();
1256
1234
  const identity = useIdentity();
@@ -1280,50 +1258,48 @@ var SpacePresence = ({ object, spaceKey }) => {
1280
1258
  lastSeen
1281
1259
  };
1282
1260
  }).toSorted((a, b) => a.lastSeen - b.lastSeen);
1283
- return density === "fine" ? /* @__PURE__ */ React15.createElement(SmallPresence, {
1284
- count: membersForObject.length
1285
- }) : /* @__PURE__ */ React15.createElement(FullPresence, {
1261
+ return /* @__PURE__ */ React13.createElement(FullPresence, {
1286
1262
  members: membersForObject
1287
1263
  });
1288
1264
  };
1289
1265
  var FullPresence = (props) => {
1290
1266
  const { size = 9, onMemberClick } = props;
1291
- const members = useDefaultValue(props.members, []);
1267
+ const members = useDefaultValue(props.members, () => []);
1292
1268
  if (members.length === 0) {
1293
1269
  return null;
1294
1270
  }
1295
- return /* @__PURE__ */ React15.createElement(AvatarGroup.Root, {
1271
+ return /* @__PURE__ */ React13.createElement(AvatarGroup.Root, {
1296
1272
  size,
1297
1273
  classNames: "mbs-2 mie-4",
1298
1274
  "data-testid": "spacePlugin.presence"
1299
- }, members.slice(0, 3).map((member, i) => /* @__PURE__ */ React15.createElement(Tooltip2.Root, {
1275
+ }, members.slice(0, 3).map((member, i) => /* @__PURE__ */ React13.createElement(Tooltip2.Root, {
1300
1276
  key: member.identity.identityKey.toHex()
1301
- }, /* @__PURE__ */ React15.createElement(Tooltip2.Trigger, null, /* @__PURE__ */ React15.createElement(PrensenceAvatar, {
1277
+ }, /* @__PURE__ */ React13.createElement(Tooltip2.Trigger, null, /* @__PURE__ */ React13.createElement(PrensenceAvatar, {
1302
1278
  identity: member.identity,
1303
1279
  group: true,
1304
1280
  match: member.currentlyAttended,
1305
1281
  index: members.length - i,
1306
1282
  onClick: () => onMemberClick?.(member)
1307
- })), /* @__PURE__ */ React15.createElement(Tooltip2.Portal, null, /* @__PURE__ */ React15.createElement(Tooltip2.Content, {
1283
+ })), /* @__PURE__ */ React13.createElement(Tooltip2.Portal, null, /* @__PURE__ */ React13.createElement(Tooltip2.Content, {
1308
1284
  side: "bottom"
1309
- }, /* @__PURE__ */ React15.createElement("span", null, getName(member.identity)), /* @__PURE__ */ React15.createElement(Tooltip2.Arrow, null))))), members.length > 3 && /* @__PURE__ */ React15.createElement(Tooltip2.Root, null, /* @__PURE__ */ React15.createElement(Tooltip2.Trigger, null, /* @__PURE__ */ React15.createElement(AvatarGroupItem.Root, {
1285
+ }, /* @__PURE__ */ React13.createElement("span", null, getName(member.identity)), /* @__PURE__ */ React13.createElement(Tooltip2.Arrow, null))))), members.length > 3 && /* @__PURE__ */ React13.createElement(Tooltip2.Root, null, /* @__PURE__ */ React13.createElement(Tooltip2.Trigger, null, /* @__PURE__ */ React13.createElement(AvatarGroupItem.Root, {
1310
1286
  status: "inactive"
1311
- }, /* @__PURE__ */ React15.createElement(Avatar.Frame, {
1287
+ }, /* @__PURE__ */ React13.createElement(Avatar.Frame, {
1312
1288
  style: {
1313
1289
  zIndex: members.length - 4
1314
1290
  }
1315
- }, /* @__PURE__ */ React15.createElement(Avatar.Fallback, {
1291
+ }, /* @__PURE__ */ React13.createElement(Avatar.Fallback, {
1316
1292
  text: `+${members.length - 3}`
1317
- })))), /* @__PURE__ */ React15.createElement(Tooltip2.Portal, null, /* @__PURE__ */ React15.createElement(Tooltip2.Content, {
1293
+ })))), /* @__PURE__ */ React13.createElement(Tooltip2.Portal, null, /* @__PURE__ */ React13.createElement(Tooltip2.Content, {
1318
1294
  side: "bottom"
1319
- }, /* @__PURE__ */ React15.createElement(Tooltip2.Arrow, null), /* @__PURE__ */ React15.createElement(List2, {
1295
+ }, /* @__PURE__ */ React13.createElement(Tooltip2.Arrow, null), /* @__PURE__ */ React13.createElement(List2, {
1320
1296
  classNames: "max-h-56 overflow-y-auto"
1321
- }, members.map((member) => /* @__PURE__ */ React15.createElement(ListItem.Root, {
1297
+ }, members.map((member) => /* @__PURE__ */ React13.createElement(ListItem.Root, {
1322
1298
  key: member.identity.identityKey.toHex(),
1323
1299
  classNames: "flex gap-2 items-center cursor-pointer mbe-2",
1324
1300
  onClick: () => onMemberClick?.(member),
1325
1301
  "data-testid": "identity-list-item"
1326
- }, /* @__PURE__ */ React15.createElement(PrensenceAvatar, {
1302
+ }, /* @__PURE__ */ React13.createElement(PrensenceAvatar, {
1327
1303
  identity: member.identity,
1328
1304
  showName: true,
1329
1305
  match: member.currentlyAttended
@@ -1333,10 +1309,10 @@ var PrensenceAvatar = ({ identity, showName, match, group, index, onClick }) =>
1333
1309
  const Root = group ? AvatarGroupItem.Root : Avatar.Root;
1334
1310
  const status = match ? "current" : "active";
1335
1311
  const fallbackValue = keyToFallback(identity.identityKey);
1336
- return /* @__PURE__ */ React15.createElement(Root, {
1312
+ return /* @__PURE__ */ React13.createElement(Root, {
1337
1313
  status,
1338
1314
  hue: identity.profile?.data?.hue || fallbackValue.hue
1339
- }, /* @__PURE__ */ React15.createElement(Avatar.Frame, {
1315
+ }, /* @__PURE__ */ React13.createElement(Avatar.Frame, {
1340
1316
  "data-testid": "spacePlugin.presence.member",
1341
1317
  "data-status": status,
1342
1318
  ...index ? {
@@ -1345,49 +1321,67 @@ var PrensenceAvatar = ({ identity, showName, match, group, index, onClick }) =>
1345
1321
  }
1346
1322
  } : {},
1347
1323
  onClick: () => onClick?.()
1348
- }, /* @__PURE__ */ React15.createElement(Avatar.Fallback, {
1324
+ }, /* @__PURE__ */ React13.createElement(Avatar.Fallback, {
1349
1325
  text: identity.profile?.data?.emoji || fallbackValue.emoji
1350
- })), showName && /* @__PURE__ */ React15.createElement(Avatar.Label, {
1326
+ })), showName && /* @__PURE__ */ React13.createElement(Avatar.Label, {
1351
1327
  classNames: "text-sm truncate pli-2"
1352
1328
  }, getName(identity)));
1353
1329
  };
1354
- var SmallPresenceLive = ({ viewers }) => {
1355
- 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) : []);
1356
1336
  useEffect4(() => {
1357
- const interval = setInterval(() => setMoment(Date.now()), REFRESH_INTERVAL);
1358
- return () => clearInterval(interval);
1359
- }, []);
1360
- const activeViewers = viewers ? Array.from(viewers.values()).filter(({ lastSeen }) => moment - lastSeen < ACTIVITY_DURATION) : [];
1361
- return /* @__PURE__ */ React15.createElement(SmallPresence, {
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
+ ]);
1347
+ return /* @__PURE__ */ React13.createElement(SmallPresence, {
1348
+ id,
1362
1349
  count: activeViewers.length
1363
1350
  });
1364
1351
  };
1365
- var SmallPresence = ({ count }) => {
1366
- const { t } = useTranslation14(SPACE_PLUGIN);
1367
- return /* @__PURE__ */ React15.createElement(Tooltip2.Root, null, /* @__PURE__ */ React15.createElement(Tooltip2.Trigger, {
1352
+ var SmallPresence = ({ id, count }) => {
1353
+ const { t } = useTranslation13(SPACE_PLUGIN);
1354
+ const { hasAttention, isAncestor, isRelated } = useAttention(id);
1355
+ const attention = hasAttention || isAncestor || isRelated;
1356
+ return /* @__PURE__ */ React13.createElement(Tooltip2.Root, null, /* @__PURE__ */ React13.createElement(Tooltip2.Trigger, {
1368
1357
  asChild: true
1369
- }, /* @__PURE__ */ React15.createElement(AttentionGlyph, {
1358
+ }, /* @__PURE__ */ React13.createElement("div", {
1359
+ role: "none",
1360
+ className: "flex",
1361
+ "data-attention": attention
1362
+ }, /* @__PURE__ */ React13.createElement(AttentionGlyph, {
1370
1363
  presence: count > 1 ? "many" : count === 1 ? "one" : "none",
1371
1364
  classNames: "self-center mie-1"
1372
- })), /* @__PURE__ */ React15.createElement(Tooltip2.Portal, null, /* @__PURE__ */ React15.createElement(Tooltip2.Content, {
1365
+ }))), /* @__PURE__ */ React13.createElement(Tooltip2.Portal, null, /* @__PURE__ */ React13.createElement(Tooltip2.Content, {
1373
1366
  side: "bottom",
1374
1367
  classNames: "z-[70]"
1375
- }, /* @__PURE__ */ React15.createElement("span", null, t("presence label", {
1368
+ }, /* @__PURE__ */ React13.createElement("span", null, t("presence label", {
1376
1369
  count
1377
- })), /* @__PURE__ */ React15.createElement(Tooltip2.Arrow, null))));
1370
+ })), /* @__PURE__ */ React13.createElement(Tooltip2.Arrow, null))));
1378
1371
  };
1379
1372
 
1380
1373
  // packages/plugins/plugin-space/src/components/SpaceSettings.tsx
1381
- import React16 from "react";
1382
- import { useIntentDispatcher as useIntentDispatcher2 } from "@dxos/app-framework";
1383
- import { SettingsValue } from "@dxos/plugin-settings";
1384
- import { Input as Input3, useTranslation as useTranslation15 } from "@dxos/react-ui";
1374
+ import React14 from "react";
1375
+ import { useIntentDispatcher as useIntentDispatcher2, useResolvePlugins } from "@dxos/app-framework";
1376
+ import { Input as Input4, Select, toLocalizedString as toLocalizedString2, useTranslation as useTranslation14 } from "@dxos/react-ui";
1377
+ import { FormInput } from "@dxos/react-ui-data";
1385
1378
  var SpaceSettings = ({ settings }) => {
1386
- const { t } = useTranslation15(SPACE_PLUGIN);
1379
+ const { t } = useTranslation14(SPACE_PLUGIN);
1387
1380
  const dispatch = useIntentDispatcher2();
1388
- return /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(SettingsValue, {
1381
+ const plugins = useResolvePlugins(parseSpaceInitPlugin);
1382
+ return /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(FormInput, {
1389
1383
  label: t("show hidden spaces label")
1390
- }, /* @__PURE__ */ React16.createElement(Input3.Switch, {
1384
+ }, /* @__PURE__ */ React14.createElement(Input4.Switch, {
1391
1385
  checked: settings.showHidden,
1392
1386
  onCheckedChange: (checked) => dispatch({
1393
1387
  plugin: SPACE_PLUGIN,
@@ -1396,7 +1390,353 @@ var SpaceSettings = ({ settings }) => {
1396
1390
  state: !!checked
1397
1391
  }
1398
1392
  })
1399
- })));
1393
+ })), /* @__PURE__ */ React14.createElement(FormInput, {
1394
+ label: t("default on space create label")
1395
+ }, /* @__PURE__ */ React14.createElement(Select.Root, {
1396
+ value: settings.onSpaceCreate,
1397
+ onValueChange: (value) => {
1398
+ settings.onSpaceCreate = value;
1399
+ }
1400
+ }, /* @__PURE__ */ React14.createElement(Select.TriggerButton, null), /* @__PURE__ */ React14.createElement(Select.Portal, null, /* @__PURE__ */ React14.createElement(Select.Content, null, /* @__PURE__ */ React14.createElement(Select.Viewport, null, plugins.map(({ provides: { space: { onSpaceCreate } } }) => /* @__PURE__ */ React14.createElement(Select.Option, {
1401
+ key: onSpaceCreate.action,
1402
+ value: onSpaceCreate.action
1403
+ }, toLocalizedString2(onSpaceCreate.label, t)))))))));
1404
+ };
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
+
1450
+ // packages/plugins/plugin-space/src/components/SaveStatus.tsx
1451
+ import React16, { useEffect as useEffect5, useState as useState9 } from "react";
1452
+ import { Context } from "@dxos/context";
1453
+ import { StatusBar } from "@dxos/plugin-status-bar";
1454
+ import { useClient as useClient4 } from "@dxos/react-client";
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";
1457
+ var SaveStatus = () => {
1458
+ const { t } = useTranslation16(SPACE_PLUGIN);
1459
+ const client = useClient4();
1460
+ const [state, setState] = useState9("saved");
1461
+ useEffect5(() => {
1462
+ return createClientSaveTracker(client, (state2) => {
1463
+ setState(state2);
1464
+ });
1465
+ }, []);
1466
+ return /* @__PURE__ */ React16.createElement(StatusBar.Item, {
1467
+ title: state === "saving" ? t("saving label") : t("saved label")
1468
+ }, /* @__PURE__ */ React16.createElement(Icon, {
1469
+ icon: state === "saving" ? "ph--arrows-clockwise--regular" : "ph--check-circle--regular",
1470
+ size: 4
1471
+ }));
1472
+ };
1473
+ var createClientSaveTracker = (client, cb) => {
1474
+ const unsubscribeCallbacks = {};
1475
+ const state = {};
1476
+ const install = (spaces) => {
1477
+ for (const space of spaces) {
1478
+ if (state[space.id]) {
1479
+ continue;
1480
+ }
1481
+ state[space.id] = "saved";
1482
+ unsubscribeCallbacks[space.id] = createSpaceSaveTracker(space, (s) => {
1483
+ state[space.id] = s;
1484
+ cb(Object.values(state).some((s2) => s2 === "saving") ? "saving" : "saved");
1485
+ });
1486
+ }
1487
+ };
1488
+ client.spaces.subscribe((spaces) => {
1489
+ install(spaces);
1490
+ });
1491
+ install(client.spaces.get());
1492
+ return () => {
1493
+ for (const unsubscribe of Object.values(unsubscribeCallbacks)) {
1494
+ unsubscribe();
1495
+ }
1496
+ };
1497
+ };
1498
+ var createSpaceSaveTracker = (space, cb) => {
1499
+ const ctx = new Context(void 0, {
1500
+ F: __dxlog_file4,
1501
+ L: 64
1502
+ });
1503
+ void space.waitUntilReady().then(() => {
1504
+ if (ctx.disposed) {
1505
+ return;
1506
+ }
1507
+ let hasUnsavedChanges = false;
1508
+ let lastFlushPromise;
1509
+ space.crud.saveStateChanged.on(ctx, ({ unsavedDocuments }) => {
1510
+ hasUnsavedChanges = unsavedDocuments.length > 0;
1511
+ });
1512
+ space.crud.saveStateChanged.debounce(500).on(ctx, () => {
1513
+ if (hasUnsavedChanges) {
1514
+ lastFlushPromise = void 0;
1515
+ cb("saving");
1516
+ } else {
1517
+ const flushPromise = space.crud.flush();
1518
+ lastFlushPromise = flushPromise;
1519
+ void flushPromise.then(() => {
1520
+ if (lastFlushPromise === flushPromise) {
1521
+ cb("saved");
1522
+ }
1523
+ });
1524
+ }
1525
+ });
1526
+ });
1527
+ return () => {
1528
+ void ctx.dispose();
1529
+ };
1530
+ };
1531
+
1532
+ // packages/plugins/plugin-space/src/components/SyncStatus/SyncStatus.tsx
1533
+ import React17, { useEffect as useEffect7, useState as useState11 } from "react";
1534
+ import { StatusBar as StatusBar2 } from "@dxos/plugin-status-bar";
1535
+ import { Icon as Icon2, Popover as Popover3, useTranslation as useTranslation17 } from "@dxos/react-ui";
1536
+ import { SyntaxHighlighter } from "@dxos/react-ui-syntax-highlighter";
1537
+ import { mx as mx7 } from "@dxos/react-ui-theme";
1538
+
1539
+ // packages/plugins/plugin-space/src/components/SyncStatus/types.ts
1540
+ import { useEffect as useEffect6, useState as useState10 } from "react";
1541
+ import { Context as Context2 } from "@dxos/context";
1542
+ import { EdgeService } from "@dxos/protocols";
1543
+ import { useClient as useClient5 } from "@dxos/react-client";
1544
+ var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-space/src/components/SyncStatus/types.ts";
1545
+ var createEmptyEdgeSyncState = () => ({
1546
+ missingOnLocal: 0,
1547
+ missingOnRemote: 0,
1548
+ localDocumentCount: 0,
1549
+ remoteDocumentCount: 0,
1550
+ differentDocuments: 0
1551
+ });
1552
+ var getSyncSummary = (syncMap) => {
1553
+ return Object.entries(syncMap).reduce((summary, [_spaceId, peerState]) => {
1554
+ summary.missingOnLocal += peerState.missingOnLocal;
1555
+ summary.missingOnRemote += peerState.missingOnRemote;
1556
+ summary.localDocumentCount += peerState.localDocumentCount;
1557
+ summary.remoteDocumentCount += peerState.remoteDocumentCount;
1558
+ summary.differentDocuments += peerState.differentDocuments;
1559
+ return summary;
1560
+ }, createEmptyEdgeSyncState());
1561
+ };
1562
+ var isEdgePeerId = (peerId, spaceId) => peerId.startsWith(`${EdgeService.AUTOMERGE_REPLICATOR}:${spaceId}`);
1563
+ var useSyncState = () => {
1564
+ const client = useClient5();
1565
+ const [spaceState, setSpaceState] = useState10({});
1566
+ useEffect6(() => {
1567
+ const ctx = new Context2(void 0, {
1568
+ F: __dxlog_file5,
1569
+ L: 48
1570
+ });
1571
+ const createSubscriptions = (spaces) => {
1572
+ for (const space of spaces) {
1573
+ if (spaceState[space.id]) {
1574
+ continue;
1575
+ }
1576
+ ctx.onDispose(space.crud.subscribeToSyncState(ctx, ({ peers = [] }) => {
1577
+ const syncState = peers.find((state) => isEdgePeerId(state.peerId, space.id));
1578
+ if (syncState) {
1579
+ setSpaceState((spaceState2) => ({
1580
+ ...spaceState2,
1581
+ [space.id]: syncState
1582
+ }));
1583
+ }
1584
+ }));
1585
+ }
1586
+ };
1587
+ createSubscriptions(client.spaces.get());
1588
+ client.spaces.subscribe((spaces) => {
1589
+ createSubscriptions(spaces);
1590
+ });
1591
+ return () => {
1592
+ void ctx.dispose();
1593
+ };
1594
+ }, [
1595
+ client
1596
+ ]);
1597
+ return spaceState;
1598
+ };
1599
+
1600
+ // packages/plugins/plugin-space/src/components/SyncStatus/SyncStatus.tsx
1601
+ var SYNC_STALLED_TIMEOUT = 5e3;
1602
+ var styles = {
1603
+ barBg: "bg-neutral-50 dark:bg-green-900 text-black",
1604
+ barFg: "bg-neutral-100 bg-green-500",
1605
+ barHover: "dark:hover:bg-green-500"
1606
+ };
1607
+ var SyncStatus = () => {
1608
+ const state = useSyncState();
1609
+ return /* @__PURE__ */ React17.createElement(SyncStatusIndicator, {
1610
+ state
1611
+ });
1612
+ };
1613
+ var SyncStatusIndicator = ({ state }) => {
1614
+ const summary = getSyncSummary(state);
1615
+ const offline = false;
1616
+ const needsToUpload = summary.differentDocuments > 0 || summary.missingOnRemote > 0;
1617
+ const needsToDownload = summary.differentDocuments > 0 || summary.missingOnLocal > 0;
1618
+ const [classNames, setClassNames] = useState11();
1619
+ useEffect7(() => {
1620
+ setClassNames(void 0);
1621
+ if (!needsToUpload && !needsToDownload) {
1622
+ return;
1623
+ }
1624
+ const t = setTimeout(() => {
1625
+ setClassNames("text-orange-500");
1626
+ }, SYNC_STALLED_TIMEOUT);
1627
+ return () => clearTimeout(t);
1628
+ }, [
1629
+ needsToUpload,
1630
+ needsToDownload
1631
+ ]);
1632
+ return /* @__PURE__ */ React17.createElement(StatusBar2.Item, null, /* @__PURE__ */ React17.createElement(Popover3.Root, null, /* @__PURE__ */ React17.createElement(Popover3.Trigger, null, /* @__PURE__ */ React17.createElement(Icon2, {
1633
+ icon: offline ? "ph--cloud-x--regular" : needsToUpload ? "ph--cloud-arrow-up--regular" : needsToDownload ? "ph--cloud-arrow-down--regular" : "ph--cloud-check--regular",
1634
+ size: 4,
1635
+ classNames
1636
+ })), /* @__PURE__ */ React17.createElement(Popover3.Content, {
1637
+ sideOffset: 16
1638
+ }, /* @__PURE__ */ React17.createElement(SyncStatusDetail, {
1639
+ state,
1640
+ summary,
1641
+ debug: false
1642
+ }))));
1643
+ };
1644
+ var SyncStatusDetail = ({ classNames, state, summary, debug }) => {
1645
+ const { t } = useTranslation17(SPACE_PLUGIN);
1646
+ const entries = Object.entries(state).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
1647
+ return /* @__PURE__ */ React17.createElement("div", {
1648
+ className: mx7("flex flex-col text-xs min-w-[16rem]", classNames)
1649
+ }, /* @__PURE__ */ React17.createElement("h1", {
1650
+ className: "p-2"
1651
+ }, t("sync status title")), /* @__PURE__ */ React17.createElement("div", {
1652
+ className: "flex flex-col gap-[2px] my-[2px]"
1653
+ }, entries.map(([spaceId, state2]) => /* @__PURE__ */ React17.createElement(SpaceRow, {
1654
+ key: spaceId,
1655
+ spaceId,
1656
+ state: state2
1657
+ }))), debug && /* @__PURE__ */ React17.createElement(SyntaxHighlighter, {
1658
+ language: "json"
1659
+ }, JSON.stringify(summary, null, 2)));
1660
+ };
1661
+ var useActive = (count) => {
1662
+ const [current, setCurrent] = useState11(count);
1663
+ const [active, setActive] = useState11(false);
1664
+ useEffect7(() => {
1665
+ let t;
1666
+ if (count !== current) {
1667
+ setActive(true);
1668
+ setCurrent(count);
1669
+ t && clearTimeout(t);
1670
+ t = setTimeout(() => {
1671
+ setActive(false);
1672
+ }, SYNC_STALLED_TIMEOUT);
1673
+ }
1674
+ return () => {
1675
+ setActive(false);
1676
+ clearTimeout(t);
1677
+ };
1678
+ }, [
1679
+ count,
1680
+ current
1681
+ ]);
1682
+ return active;
1683
+ };
1684
+ var SpaceRow = ({ spaceId, state: { localDocumentCount, remoteDocumentCount, missingOnLocal, missingOnRemote } }) => {
1685
+ const downActive = useActive(localDocumentCount);
1686
+ const upActive = useActive(remoteDocumentCount);
1687
+ return /* @__PURE__ */ React17.createElement("div", {
1688
+ className: mx7("flex items-center mx-[2px] gap-[2px] cursor-pointer", styles.barHover),
1689
+ title: spaceId,
1690
+ onClick: () => {
1691
+ void navigator.clipboard.writeText(spaceId);
1692
+ }
1693
+ }, /* @__PURE__ */ React17.createElement(Icon2, {
1694
+ icon: "ph--arrow-fat-line-left--regular",
1695
+ size: 3,
1696
+ classNames: mx7(downActive && "animate-[pulse_1s_infinite]")
1697
+ }), /* @__PURE__ */ React17.createElement(Candle, {
1698
+ up: {
1699
+ count: remoteDocumentCount,
1700
+ total: remoteDocumentCount + missingOnRemote
1701
+ },
1702
+ down: {
1703
+ count: localDocumentCount,
1704
+ total: localDocumentCount + missingOnLocal
1705
+ },
1706
+ title: spaceId
1707
+ }), /* @__PURE__ */ React17.createElement(Icon2, {
1708
+ icon: "ph--arrow-fat-line-right--regular",
1709
+ size: 3,
1710
+ classNames: mx7(upActive && "animate-[pulse_1s_step-start_infinite]")
1711
+ }));
1712
+ };
1713
+ var Candle = ({ classNames, up, down }) => {
1714
+ return /* @__PURE__ */ React17.createElement("div", {
1715
+ className: mx7("grid grid-cols-[1fr_2rem_1fr] w-full h-3", classNames)
1716
+ }, /* @__PURE__ */ React17.createElement(Bar, {
1717
+ classNames: "justify-end",
1718
+ ...up
1719
+ }), /* @__PURE__ */ React17.createElement("div", {
1720
+ className: "relative"
1721
+ }, /* @__PURE__ */ React17.createElement("div", {
1722
+ className: mx7("absolute inset-0 flex items-center justify-center text-xs", styles.barBg)
1723
+ }, up.total)), /* @__PURE__ */ React17.createElement(Bar, down));
1724
+ };
1725
+ var Bar = ({ classNames, count, total }) => {
1726
+ let p = count / total * 100;
1727
+ if (count < total) {
1728
+ p = Math.min(p, 95);
1729
+ }
1730
+ return /* @__PURE__ */ React17.createElement("div", {
1731
+ className: mx7("relative flex w-full", styles.barBg, classNames)
1732
+ }, /* @__PURE__ */ React17.createElement("div", {
1733
+ className: mx7("shrink-0", styles.barFg),
1734
+ style: {
1735
+ width: `${p}%`
1736
+ }
1737
+ }), count !== total && /* @__PURE__ */ React17.createElement("div", {
1738
+ className: "absolute top-0 bottom-0 flex items-center mx-0.5 text-black text-xs"
1739
+ }, count));
1400
1740
  };
1401
1741
 
1402
1742
  // packages/plugins/plugin-space/src/translations.ts
@@ -1406,8 +1746,8 @@ var translations_default = [
1406
1746
  [SPACE_PLUGIN]: {
1407
1747
  "plugin name": "Spaces",
1408
1748
  "first run message": "Nothing selected.",
1409
- "create space label": "Create a new space",
1410
- "join space label": "Join a space",
1749
+ "create space label": "Create space",
1750
+ "join space label": "Join space",
1411
1751
  "empty space message": "No documents",
1412
1752
  "empty tree message": "No spaces",
1413
1753
  "unnamed space label": "New space",
@@ -1478,25 +1818,36 @@ var translations_default = [
1478
1818
  "space limit close label": "Close",
1479
1819
  "remove deleted objects label": "Cleanup",
1480
1820
  "remove deleted objects alt": "Permanently remove deleted objects to free up space.",
1481
- "copy link label": "Copy link"
1821
+ "copy link label": "Copy link",
1822
+ "default on space create label": "On space create",
1823
+ "sync status title": "Sync status",
1824
+ "dismiss label": "Dismiss",
1825
+ "join success label": "Successfully joined space",
1826
+ "name label": "Name",
1827
+ "name placeholder": "Name",
1828
+ "unnamed object settings label": "Settings",
1829
+ "edge replication label": "Enable EDGE Replication"
1482
1830
  }
1483
1831
  }
1484
1832
  }
1485
1833
  ];
1486
1834
 
1487
1835
  // packages/plugins/plugin-space/src/SpacePlugin.tsx
1488
- var __dxlog_file3 = "/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";
1489
1837
  var ACTIVE_NODE_BROADCAST_INTERVAL = 3e4;
1490
1838
  var OBJECT_ID_LENGTH = 60;
1491
1839
  var SPACE_MAX_OBJECTS = 500;
1492
1840
  var DIRECTORY_TYPE = "text/directory";
1493
1841
  var parseSpacePlugin = (plugin) => Array.isArray(plugin?.provides.space?.enabled) ? plugin : void 0;
1494
1842
  var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
1495
- const settings = new LocalStorageStore(SPACE_PLUGIN);
1843
+ const settings = new LocalStorageStore(SPACE_PLUGIN, {
1844
+ onSpaceCreate: "dxos.org/plugin/markdown/action/create"
1845
+ });
1496
1846
  const state = new LocalStorageStore(SPACE_PLUGIN, {
1497
1847
  awaiting: void 0,
1498
1848
  spaceNames: {},
1499
1849
  viewersByObject: {},
1850
+ // TODO(wittjosiah): Stop using (Complex)Map inside reactive object.
1500
1851
  viewersByIdentity: new ComplexMap2(PublicKey2.hash),
1501
1852
  sdkMigrationRunning: {}
1502
1853
  });
@@ -1532,17 +1883,21 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
1532
1883
  await defaultSpace.internal.migrate();
1533
1884
  }
1534
1885
  spaces.filter((space) => space.state.get() === SpaceState3.SPACE_READY).forEach((space) => {
1535
- subscriptions.add(effect(() => {
1536
- state.values.spaceNames[space.id] = space.properties.name;
1537
- }));
1886
+ subscriptions.add(scheduledEffect(() => ({
1887
+ name: space.properties.name
1888
+ }), ({ name }) => state.values.spaceNames[space.id] = name));
1538
1889
  });
1539
1890
  }).unsubscribe);
1540
- subscriptions.add(effect(() => {
1891
+ subscriptions.add(scheduledEffect(() => ({
1892
+ ids: openIds(location.active),
1893
+ removed: location.closed ? [
1894
+ location.closed
1895
+ ].flat() : []
1896
+ }), ({ ids, removed }) => {
1541
1897
  const send = () => {
1542
1898
  const spaces = client.spaces.get();
1543
1899
  const identity = client.halo.identity.get();
1544
1900
  if (identity && location.active) {
1545
- const ids = openIds(location.active);
1546
1901
  const idsBySpace = reduceGroupBy(ids, (id) => {
1547
1902
  const [spaceId] = id.split(":");
1548
1903
  return spaceId;
@@ -1557,9 +1912,6 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
1557
1912
  if (!space) {
1558
1913
  continue;
1559
1914
  }
1560
- const removed = location.closed ? [
1561
- location.closed
1562
- ].flat() : [];
1563
1915
  void space.postMessage("viewing", {
1564
1916
  identityKey: identity.identityKey.toHex(),
1565
1917
  attended: attention.attended ? [
@@ -1569,11 +1921,11 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
1569
1921
  // TODO(Zan): When we re-open a part, we should remove it from the removed list in the navigation plugin.
1570
1922
  removed: removed.filter((id) => !ids2.includes(id))
1571
1923
  }).catch((err) => {
1572
- log2.warn("Failed to broadcast active node for presence.", {
1924
+ log3.warn("Failed to broadcast active node for presence.", {
1573
1925
  err: err.message
1574
1926
  }, {
1575
- F: __dxlog_file3,
1576
- L: 222,
1927
+ F: __dxlog_file6,
1928
+ L: 231,
1577
1929
  S: void 0,
1578
1930
  C: (f, a) => f(...a)
1579
1931
  });
@@ -1623,14 +1975,12 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
1623
1975
  ready: async (plugins) => {
1624
1976
  settings.prop({
1625
1977
  key: "showHidden",
1626
- storageKey: "show-hidden",
1627
1978
  type: LocalStorageStore.bool({
1628
1979
  allowUndefined: true
1629
1980
  })
1630
1981
  });
1631
1982
  state.prop({
1632
1983
  key: "spaceNames",
1633
- storageKey: "space-names",
1634
1984
  type: LocalStorageStore.json()
1635
1985
  });
1636
1986
  navigationPlugin = resolvePlugin(plugins, parseNavigationPlugin2);
@@ -1682,7 +2032,7 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
1682
2032
  ...translations_default,
1683
2033
  osTranslations
1684
2034
  ],
1685
- root: () => state.values.awaiting ? /* @__PURE__ */ React17.createElement(AwaitingObject, {
2035
+ root: () => state.values.awaiting ? /* @__PURE__ */ React18.createElement(AwaitingObject, {
1686
2036
  id: state.values.awaiting
1687
2037
  }) : null,
1688
2038
  metadata: {
@@ -1694,8 +2044,7 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
1694
2044
  ns: SPACE_PLUGIN
1695
2045
  }
1696
2046
  ],
1697
- icon: (props) => /* @__PURE__ */ React17.createElement(CardsThree2, props),
1698
- iconSymbol: "ph--cards-three--regular",
2047
+ icon: "ph--cards-three--regular",
1699
2048
  // TODO(wittjosiah): Move out of metadata.
1700
2049
  loadReferences: (collection) => loadObjectReferences(collection, (collection2) => [
1701
2050
  ...collection2.objects,
@@ -1715,55 +2064,58 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
1715
2064
  switch (role) {
1716
2065
  case "article":
1717
2066
  case "main":
1718
- 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, {
1719
2068
  data: {
1720
- active: primary.properties[CollectionType.typename]
2069
+ active: primary.properties[CollectionType.typename],
2070
+ id: primary.id
1721
2071
  },
1722
2072
  role,
1723
2073
  ...rest
1724
2074
  }) : primary instanceof CollectionType ? {
1725
- node: /* @__PURE__ */ React17.createElement(CollectionMain, {
2075
+ node: /* @__PURE__ */ React18.createElement(CollectionMain, {
1726
2076
  collection: primary
1727
2077
  }),
1728
2078
  disposition: "fallback"
1729
- } : 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, {
1730
2080
  id: primary
1731
2081
  }) : null;
1732
- // TODO(burdon): Add role name syntax to minimal plugin docs.
1733
- case "tree--empty":
1734
- switch (true) {
1735
- case data.plugin === SPACE_PLUGIN:
1736
- return /* @__PURE__ */ React17.createElement(EmptyTree, null);
1737
- case (isGraphNode(data.activeNode) && isSpace2(data.activeNode.data)):
1738
- return /* @__PURE__ */ React17.createElement(EmptySpace, null);
1739
- default:
1740
- return null;
1741
- }
2082
+ case "complementary--settings":
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;
1742
2091
  case "dialog":
1743
2092
  if (data.component === "dxos.org/plugin/space/InvitationManagerDialog") {
1744
- 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, {
1745
2094
  active: true,
1746
2095
  ...data.subject
1747
2096
  })));
1748
- } else {
1749
- return null;
1750
2097
  }
1751
- case "popover":
2098
+ return null;
2099
+ case "popover": {
1752
2100
  if (data.component === "dxos.org/plugin/space/RenameSpacePopover" && isSpace2(data.subject)) {
1753
- return /* @__PURE__ */ React17.createElement(PopoverRenameSpace, {
2101
+ return /* @__PURE__ */ React18.createElement(PopoverRenameSpace, {
1754
2102
  space: data.subject
1755
2103
  });
1756
2104
  }
1757
2105
  if (data.component === "dxos.org/plugin/space/RenameObjectPopover" && isReactiveObject2(data.subject)) {
1758
- return /* @__PURE__ */ React17.createElement(PopoverRenameObject, {
2106
+ return /* @__PURE__ */ React18.createElement(PopoverRenameObject, {
1759
2107
  object: data.subject
1760
2108
  });
1761
2109
  }
1762
2110
  return null;
2111
+ }
2112
+ // TODO(burdon): Add role name syntax to minimal plugin docs.
1763
2113
  case "presence--glyph": {
1764
- return isReactiveObject2(data.object) ? /* @__PURE__ */ React17.createElement(SmallPresenceLive, {
2114
+ return isReactiveObject2(data.object) ? /* @__PURE__ */ React18.createElement(SmallPresenceLive, {
2115
+ id: data.id,
1765
2116
  viewers: state.values.viewersByObject[fullyQualifiedId4(data.object)]
1766
- }) : /* @__PURE__ */ React17.createElement(SmallPresence, {
2117
+ }) : /* @__PURE__ */ React18.createElement(SmallPresence, {
2118
+ id: data.id,
1767
2119
  count: 0
1768
2120
  });
1769
2121
  }
@@ -1777,30 +2129,33 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
1777
2129
  const space = isSpace2(data.object) ? data.object : getSpace4(data.object);
1778
2130
  const object = isSpace2(data.object) ? data.object.state.get() === SpaceState3.SPACE_READY ? space?.properties[CollectionType.typename] : void 0 : data.object;
1779
2131
  return space && object ? {
1780
- node: /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement(SpacePresence, {
2132
+ node: /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement(SpacePresence, {
1781
2133
  object
1782
- }), space.properties[COMPOSER_SPACE_LOCK] ? null : /* @__PURE__ */ React17.createElement(ShareSpaceButton, {
2134
+ }), space.properties[COMPOSER_SPACE_LOCK] ? null : /* @__PURE__ */ React18.createElement(ShareSpaceButton, {
1783
2135
  spaceId: space.id
1784
2136
  })),
1785
2137
  disposition: "hoist"
1786
2138
  } : null;
1787
2139
  }
1788
2140
  case "section":
1789
- return data.object instanceof CollectionType ? /* @__PURE__ */ React17.createElement(CollectionSection, {
2141
+ return data.object instanceof CollectionType ? /* @__PURE__ */ React18.createElement(CollectionSection, {
1790
2142
  collection: data.object
1791
2143
  }) : null;
1792
2144
  case "settings":
1793
- return data.plugin === meta_default.id ? /* @__PURE__ */ React17.createElement(SpaceSettings, {
2145
+ return data.plugin === meta_default.id ? /* @__PURE__ */ React18.createElement(SpaceSettings, {
1794
2146
  settings: settings.values
1795
2147
  }) : null;
1796
2148
  case "menu-footer":
1797
- if (!isEchoObject2(data.object)) {
1798
- return null;
1799
- } else {
1800
- return /* @__PURE__ */ React17.createElement(MenuFooter, {
2149
+ if (isEchoObject2(data.object)) {
2150
+ return /* @__PURE__ */ React18.createElement(MenuFooter, {
1801
2151
  object: data.object
1802
2152
  });
2153
+ } else {
2154
+ return null;
1803
2155
  }
2156
+ case "status": {
2157
+ return /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement(SyncStatus, null), /* @__PURE__ */ React18.createElement(SaveStatus, null));
2158
+ }
1804
2159
  default:
1805
2160
  return null;
1806
2161
  }
@@ -1815,7 +2170,7 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
1815
2170
  const dispatch = intentPlugin?.provides.intent.dispatch;
1816
2171
  const resolve = metadataPlugin?.provides.metadata.resolver;
1817
2172
  const graph = graphPlugin?.provides.graph;
1818
- if (!graph || !dispatch || !resolve || !client) {
2173
+ if (!client || !dispatch || !resolve || !graph) {
1819
2174
  return [];
1820
2175
  }
1821
2176
  return [
@@ -1847,7 +2202,6 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
1847
2202
  ns: SPACE_PLUGIN
1848
2203
  }
1849
2204
  ],
1850
- palette: "teal",
1851
2205
  testId: "spacePlugin.spaces",
1852
2206
  role: "branch",
1853
2207
  childrenPersistenceClass: "echo",
@@ -1859,9 +2213,9 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
1859
2213
  if (spacesOrder) {
1860
2214
  spacesOrder.order = nextOrder.map(({ id }) => id);
1861
2215
  } else {
1862
- log2.warn("spaces order object not found", void 0, {
1863
- F: __dxlog_file3,
1864
- L: 514,
2216
+ log3.warn("spaces order object not found", void 0, {
2217
+ F: __dxlog_file6,
2218
+ L: 528,
1865
2219
  S: void 0,
1866
2220
  C: (f, a) => f(...a)
1867
2221
  });
@@ -1897,10 +2251,10 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
1897
2251
  ns: SPACE_PLUGIN
1898
2252
  }
1899
2253
  ],
1900
- icon: (props) => /* @__PURE__ */ React17.createElement(Plus2, props),
1901
- iconSymbol: "ph--plus--regular",
1902
- disposition: "toolbar",
1903
- testId: "spacePlugin.createSpace"
2254
+ icon: "ph--plus--regular",
2255
+ disposition: "item",
2256
+ testId: "spacePlugin.createSpace",
2257
+ className: "pbs-4"
1904
2258
  }
1905
2259
  },
1906
2260
  {
@@ -1923,9 +2277,10 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
1923
2277
  ns: SPACE_PLUGIN
1924
2278
  }
1925
2279
  ],
1926
- icon: (props) => /* @__PURE__ */ React17.createElement(SignIn, props),
1927
- iconSymbol: "ph--sign-in--regular",
1928
- testId: "spacePlugin.joinSpace"
2280
+ icon: "ph--sign-in--regular",
2281
+ disposition: "item",
2282
+ testId: "spacePlugin.joinSpace",
2283
+ className: "pbe-4"
1929
2284
  }
1930
2285
  }
1931
2286
  ],
@@ -2052,6 +2407,72 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2052
2407
  resolve
2053
2408
  })).filter(nonNullable);
2054
2409
  }
2410
+ }),
2411
+ // Create nodes for object settings.
2412
+ createExtension({
2413
+ id: `${SPACE_PLUGIN}/settings-for-subject`,
2414
+ resolver: ({ id }) => {
2415
+ if (!id.endsWith("~settings")) {
2416
+ return;
2417
+ }
2418
+ const type = "orphan-settings-for-subject";
2419
+ const icon = "ph--gear--regular";
2420
+ const [subjectId] = id.split("~");
2421
+ const { spaceId, objectId } = parseId(subjectId);
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
+ }
2448
+ const object = toSignal((onChange) => {
2449
+ const timeout = setTimeout(async () => {
2450
+ await space?.db.loadObjectById(objectId);
2451
+ onChange();
2452
+ });
2453
+ return () => clearTimeout(timeout);
2454
+ }, () => space?.db.getObjectById(objectId), subjectId);
2455
+ if (!object || !subjectId) {
2456
+ return;
2457
+ }
2458
+ const meta = resolve(getTypename2(object) ?? "");
2459
+ const label = meta.label?.(object) || object.name || meta.placeholder || [
2460
+ "unnamed object settings label",
2461
+ {
2462
+ ns: SPACE_PLUGIN
2463
+ }
2464
+ ];
2465
+ return {
2466
+ id,
2467
+ type,
2468
+ data: null,
2469
+ properties: {
2470
+ icon,
2471
+ label,
2472
+ object
2473
+ }
2474
+ };
2475
+ }
2055
2476
  })
2056
2477
  ];
2057
2478
  },
@@ -2159,6 +2580,25 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2159
2580
  }
2160
2581
  },
2161
2582
  intents: [
2583
+ ...settings.values.onSpaceCreate ? [
2584
+ [
2585
+ {
2586
+ action: settings.values.onSpaceCreate,
2587
+ data: {
2588
+ space
2589
+ }
2590
+ },
2591
+ {
2592
+ action: SpaceAction.ADD_OBJECT,
2593
+ data: {
2594
+ target: space
2595
+ }
2596
+ },
2597
+ {
2598
+ action: NavigationAction3.EXPOSE
2599
+ }
2600
+ ]
2601
+ ] : [],
2162
2602
  [
2163
2603
  {
2164
2604
  action: ObservabilityAction.SEND_EVENT,
@@ -2190,6 +2630,20 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2190
2630
  }
2191
2631
  },
2192
2632
  intents: [
2633
+ [
2634
+ {
2635
+ action: LayoutAction2.SET_LAYOUT,
2636
+ data: {
2637
+ element: "toast",
2638
+ subject: {
2639
+ id: `${SPACE_PLUGIN}/join-success`,
2640
+ duration: 1e4,
2641
+ title: translations_default[0]["en-US"][SPACE_PLUGIN]["join success label"],
2642
+ closeLabel: translations_default[0]["en-US"][SPACE_PLUGIN]["dismiss label"]
2643
+ }
2644
+ }
2645
+ }
2646
+ ],
2193
2647
  [
2194
2648
  {
2195
2649
  action: ObservabilityAction.SEND_EVENT,
@@ -2379,8 +2833,7 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2379
2833
  title: translations_default[0]["en-US"][SPACE_PLUGIN]["space limit label"],
2380
2834
  description: translations_default[0]["en-US"][SPACE_PLUGIN]["space limit description"],
2381
2835
  duration: 5e3,
2382
- icon: (props) => /* @__PURE__ */ React17.createElement(Warning2, props),
2383
- iconSymbol: "ph--warning--regular",
2836
+ icon: "ph--warning--regular",
2384
2837
  actionLabel: translations_default[0]["en-US"][SPACE_PLUGIN]["remove deleted objects label"],
2385
2838
  actionAlt: translations_default[0]["en-US"][SPACE_PLUGIN]["remove deleted objects alt"],
2386
2839
  // TODO(wittjosiah): Use OS namespace.
@@ -2422,7 +2875,7 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2422
2875
  }
2423
2876
  return {
2424
2877
  data: {
2425
- id: object.id,
2878
+ id: fullyQualifiedId4(object),
2426
2879
  object,
2427
2880
  activeParts: {
2428
2881
  main: [
@@ -2475,8 +2928,7 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2475
2928
  data: {
2476
2929
  activeParts: {
2477
2930
  main: deletionData.wasActive,
2478
- sidebar: deletionData.wasActive,
2479
- complementary: deletionData.wasActive
2931
+ sidebar: deletionData.wasActive
2480
2932
  }
2481
2933
  }
2482
2934
  });
@@ -2554,10 +3006,11 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2554
3006
  case SpaceAction.DUPLICATE_OBJECT: {
2555
3007
  const originalObject = intent.data?.object ?? intent.data?.result;
2556
3008
  const resolve = resolvePlugin(plugins, parseMetadataResolverPlugin)?.provides.metadata.resolver;
2557
- if (!isEchoObject2(originalObject) || !resolve) {
3009
+ const space = isSpace2(intent.data?.target) ? intent.data?.target : getSpace4(intent.data?.target);
3010
+ if (!isEchoObject2(originalObject) || !resolve || !space) {
2558
3011
  return;
2559
3012
  }
2560
- const newObject = await cloneObject(originalObject, resolve);
3013
+ const newObject = await cloneObject(originalObject, resolve, space);
2561
3014
  return {
2562
3015
  intents: [
2563
3016
  [
@@ -2596,10 +3049,10 @@ export {
2596
3049
  CollectionSection,
2597
3050
  CollectionType,
2598
3051
  ContactType,
2599
- EmptySpace,
2600
- EmptyTree,
3052
+ DefaultObjectSettings,
2601
3053
  FullPresence,
2602
3054
  MenuFooter,
3055
+ MessageState,
2603
3056
  MessageType,
2604
3057
  MissingObject,
2605
3058
  PersistenceStatus,
@@ -2611,6 +3064,7 @@ export {
2611
3064
  SPACE_PLUGIN,
2612
3065
  SPACE_PLUGIN_SHORT_ID,
2613
3066
  SPACE_TYPE,
3067
+ SaveStatus,
2614
3068
  ShareSpaceButton,
2615
3069
  ShareSpaceButtonImpl,
2616
3070
  SmallPresence,
@@ -2620,6 +3074,10 @@ export {
2620
3074
  SpacePlugin,
2621
3075
  SpacePresence,
2622
3076
  SpaceSettings,
3077
+ SpaceSettingsPanel,
3078
+ SyncStatus,
3079
+ SyncStatusDetail,
3080
+ SyncStatusIndicator,
2623
3081
  ThreadStatus,
2624
3082
  ThreadType,
2625
3083
  cloneObject,
@@ -2634,6 +3092,7 @@ export {
2634
3092
  getNestedObjects,
2635
3093
  getSpaceDisplayName,
2636
3094
  memoizeQuery,
3095
+ parseSpaceInitPlugin,
2637
3096
  parseSpacePlugin,
2638
3097
  translations_default as translations
2639
3098
  };