@dxos/plugin-space 0.7.1 → 0.7.2-staging.6d26b2a
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.
- package/dist/lib/browser/index.mjs +98 -48
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +96 -46
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +98 -48
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/SpacePlugin.d.ts.map +1 -1
- package/dist/types/src/components/DefaultObjectSettings.d.ts +2 -2
- package/dist/types/src/components/MenuFooter.d.ts +2 -2
- package/dist/types/src/util.d.ts +9 -7
- package/dist/types/src/util.d.ts.map +1 -1
- package/package.json +35 -35
- package/src/SpacePlugin.tsx +96 -41
- package/src/components/DefaultObjectSettings.tsx +2 -2
- package/src/components/MenuFooter.tsx +2 -2
- package/src/util.tsx +13 -11
package/src/SpacePlugin.tsx
CHANGED
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
resolvePlugin,
|
|
28
28
|
} from '@dxos/app-framework';
|
|
29
29
|
import { EventSubscriptions, type Trigger, type UnsubscribeCallback } from '@dxos/async';
|
|
30
|
-
import { type HasId, isReactiveObject } from '@dxos/echo-schema';
|
|
30
|
+
import { type HasId, isDeleted, isReactiveObject } from '@dxos/echo-schema';
|
|
31
31
|
import { scheduledEffect } from '@dxos/echo-signals/core';
|
|
32
32
|
import { invariant } from '@dxos/invariant';
|
|
33
33
|
import { LocalStorageStore } from '@dxos/local-storage';
|
|
@@ -39,7 +39,7 @@ import { type Node, createExtension, memoize, toSignal } from '@dxos/plugin-grap
|
|
|
39
39
|
import { ObservabilityAction } from '@dxos/plugin-observability/meta';
|
|
40
40
|
import { type Client, PublicKey } from '@dxos/react-client';
|
|
41
41
|
import {
|
|
42
|
-
type
|
|
42
|
+
type ReactiveEchoObject,
|
|
43
43
|
Expando,
|
|
44
44
|
Filter,
|
|
45
45
|
type PropertiesTypeProps,
|
|
@@ -54,6 +54,8 @@ import {
|
|
|
54
54
|
loadObjectReferences,
|
|
55
55
|
parseId,
|
|
56
56
|
FQ_ID_LENGTH,
|
|
57
|
+
SPACE_ID_LENGTH,
|
|
58
|
+
OBJECT_ID_LENGTH,
|
|
57
59
|
} from '@dxos/react-client/echo';
|
|
58
60
|
import { type JoinPanelProps, osTranslations } from '@dxos/shell/react';
|
|
59
61
|
import { ComplexMap, nonNullable, reduceGroupBy } from '@dxos/util';
|
|
@@ -571,6 +573,7 @@ export const SpacePlugin = ({
|
|
|
571
573
|
{
|
|
572
574
|
id: SPACES,
|
|
573
575
|
type: SPACES,
|
|
576
|
+
cacheable: ['label', 'role'],
|
|
574
577
|
properties: {
|
|
575
578
|
label: ['spaces label', { ns: SPACE_PLUGIN }],
|
|
576
579
|
testId: 'spacePlugin.spaces',
|
|
@@ -679,39 +682,41 @@ export const SpacePlugin = ({
|
|
|
679
682
|
);
|
|
680
683
|
} catch {}
|
|
681
684
|
},
|
|
682
|
-
}),
|
|
683
|
-
|
|
684
|
-
// Find an object by its fully qualified id.
|
|
685
|
-
createExtension({
|
|
686
|
-
id: `${SPACE_PLUGIN}/objects`,
|
|
687
685
|
resolver: ({ id }) => {
|
|
688
|
-
|
|
689
|
-
const space = client.spaces.get().find((space) => space.id === spaceId);
|
|
690
|
-
if (!space) {
|
|
686
|
+
if (id.length !== SPACE_ID_LENGTH) {
|
|
691
687
|
return;
|
|
692
688
|
}
|
|
693
689
|
|
|
694
|
-
const
|
|
695
|
-
(onChange) =>
|
|
696
|
-
() =>
|
|
697
|
-
space.id,
|
|
690
|
+
const spaces = toSignal(
|
|
691
|
+
(onChange) => client.spaces.subscribe(() => onChange()).unsubscribe,
|
|
692
|
+
() => client.spaces.get(),
|
|
698
693
|
);
|
|
699
|
-
|
|
694
|
+
|
|
695
|
+
const isReady = toSignal(
|
|
696
|
+
(onChange) => client.spaces.isReady.subscribe(() => onChange()).unsubscribe,
|
|
697
|
+
() => client.spaces.isReady.get(),
|
|
698
|
+
);
|
|
699
|
+
|
|
700
|
+
if (!spaces || !isReady) {
|
|
700
701
|
return;
|
|
701
702
|
}
|
|
702
703
|
|
|
703
|
-
const
|
|
704
|
-
|
|
705
|
-
if (!store.value) {
|
|
706
|
-
void space.db.loadObjectById(objectId).then((o) => (store.value = o));
|
|
707
|
-
}
|
|
708
|
-
}, id);
|
|
709
|
-
const object = store.value;
|
|
710
|
-
if (!object) {
|
|
704
|
+
const space = spaces.find((space) => space.id === id);
|
|
705
|
+
if (!space) {
|
|
711
706
|
return;
|
|
712
707
|
}
|
|
713
708
|
|
|
714
|
-
|
|
709
|
+
if (space.state.get() === SpaceState.SPACE_INACTIVE) {
|
|
710
|
+
return false;
|
|
711
|
+
} else {
|
|
712
|
+
return constructSpaceNode({
|
|
713
|
+
space,
|
|
714
|
+
navigable: state.values.navigableCollections,
|
|
715
|
+
personal: space === client.spaces.default,
|
|
716
|
+
namesCache: state.values.spaceNames,
|
|
717
|
+
resolve,
|
|
718
|
+
});
|
|
719
|
+
}
|
|
715
720
|
},
|
|
716
721
|
}),
|
|
717
722
|
|
|
@@ -765,22 +770,9 @@ export const SpacePlugin = ({
|
|
|
765
770
|
},
|
|
766
771
|
}),
|
|
767
772
|
|
|
768
|
-
// Create collection
|
|
773
|
+
// Create nodes for objects in a collection or by its fully qualified id.
|
|
769
774
|
createExtension({
|
|
770
|
-
id: `${SPACE_PLUGIN}/
|
|
771
|
-
filter: (node): node is Node<EchoReactiveObject<any>> => isEchoObject(node.data),
|
|
772
|
-
actionGroups: ({ node }) =>
|
|
773
|
-
constructObjectActionGroups({
|
|
774
|
-
object: node.data,
|
|
775
|
-
dispatch,
|
|
776
|
-
navigable: state.values.navigableCollections,
|
|
777
|
-
}),
|
|
778
|
-
actions: ({ node }) => constructObjectActions({ node, dispatch }),
|
|
779
|
-
}),
|
|
780
|
-
|
|
781
|
-
// Create nodes for objects in collections.
|
|
782
|
-
createExtension({
|
|
783
|
-
id: `${SPACE_PLUGIN}/collection-objects`,
|
|
775
|
+
id: `${SPACE_PLUGIN}/objects`,
|
|
784
776
|
filter: (node): node is Node<CollectionType> => node.data instanceof CollectionType,
|
|
785
777
|
connector: ({ node }) => {
|
|
786
778
|
const collection = node.data;
|
|
@@ -796,6 +788,63 @@ export const SpacePlugin = ({
|
|
|
796
788
|
)
|
|
797
789
|
.filter(nonNullable);
|
|
798
790
|
},
|
|
791
|
+
resolver: ({ id }) => {
|
|
792
|
+
if (id.length !== FQ_ID_LENGTH) {
|
|
793
|
+
return;
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
const [spaceId, objectId] = id.split(':');
|
|
797
|
+
if (spaceId.length !== SPACE_ID_LENGTH && objectId.length !== OBJECT_ID_LENGTH) {
|
|
798
|
+
return;
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
const space = client.spaces.get().find((space) => space.id === spaceId);
|
|
802
|
+
if (!space) {
|
|
803
|
+
return;
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
const spaceState = toSignal(
|
|
807
|
+
(onChange) => space.state.subscribe(() => onChange()).unsubscribe,
|
|
808
|
+
() => space.state.get(),
|
|
809
|
+
space.id,
|
|
810
|
+
);
|
|
811
|
+
if (spaceState !== SpaceState.SPACE_READY) {
|
|
812
|
+
return;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
const store = memoize(() => signal(space.db.getObjectById(objectId)), id);
|
|
816
|
+
memoize(() => {
|
|
817
|
+
if (!store.value) {
|
|
818
|
+
void space.db
|
|
819
|
+
.query({ id: objectId })
|
|
820
|
+
.first()
|
|
821
|
+
.then((o) => (store.value = o));
|
|
822
|
+
}
|
|
823
|
+
}, id);
|
|
824
|
+
const object = store.value;
|
|
825
|
+
if (!object) {
|
|
826
|
+
return;
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
if (isDeleted(object)) {
|
|
830
|
+
return false;
|
|
831
|
+
} else {
|
|
832
|
+
return createObjectNode({ object, space, resolve, navigable: state.values.navigableCollections });
|
|
833
|
+
}
|
|
834
|
+
},
|
|
835
|
+
}),
|
|
836
|
+
|
|
837
|
+
// Create collection actions and action groups.
|
|
838
|
+
createExtension({
|
|
839
|
+
id: `${SPACE_PLUGIN}/object-actions`,
|
|
840
|
+
filter: (node): node is Node<ReactiveEchoObject<any>> => isEchoObject(node.data),
|
|
841
|
+
actionGroups: ({ node }) =>
|
|
842
|
+
constructObjectActionGroups({
|
|
843
|
+
object: node.data,
|
|
844
|
+
dispatch,
|
|
845
|
+
navigable: state.values.navigableCollections,
|
|
846
|
+
}),
|
|
847
|
+
actions: ({ node }) => constructObjectActions({ node, dispatch }),
|
|
799
848
|
}),
|
|
800
849
|
|
|
801
850
|
// Create nodes for object settings.
|
|
@@ -812,7 +861,13 @@ export const SpacePlugin = ({
|
|
|
812
861
|
|
|
813
862
|
const [subjectId] = id.split('~');
|
|
814
863
|
const { spaceId, objectId } = parseId(subjectId);
|
|
815
|
-
const
|
|
864
|
+
const spaces = toSignal(
|
|
865
|
+
(onChange) => client.spaces.subscribe(() => onChange()).unsubscribe,
|
|
866
|
+
() => client.spaces.get(),
|
|
867
|
+
);
|
|
868
|
+
const space = spaces?.find(
|
|
869
|
+
(space) => space.id === spaceId && space.state.get() === SpaceState.SPACE_READY,
|
|
870
|
+
);
|
|
816
871
|
if (!objectId) {
|
|
817
872
|
const label = space
|
|
818
873
|
? space.properties.name || ['unnamed space label', { ns: SPACE_PLUGIN }]
|
|
@@ -837,7 +892,7 @@ export const SpacePlugin = ({
|
|
|
837
892
|
const object = toSignal(
|
|
838
893
|
(onChange) => {
|
|
839
894
|
const timeout = setTimeout(async () => {
|
|
840
|
-
await space?.db.
|
|
895
|
+
await space?.db.query({ id: objectId }).first();
|
|
841
896
|
onChange();
|
|
842
897
|
});
|
|
843
898
|
|
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
import React from 'react';
|
|
6
6
|
|
|
7
|
-
import { type
|
|
7
|
+
import { type ReactiveEchoObject } from '@dxos/react-client/echo';
|
|
8
8
|
import { Input, useTranslation } from '@dxos/react-ui';
|
|
9
9
|
|
|
10
10
|
import { SPACE_PLUGIN } from '../meta';
|
|
11
11
|
|
|
12
12
|
export type DefaultObjectSettingsProps = {
|
|
13
|
-
object:
|
|
13
|
+
object: ReactiveEchoObject<any>;
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
export const DefaultObjectSettings = ({ object }: DefaultObjectSettingsProps) => {
|
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
import { Planet } from '@phosphor-icons/react';
|
|
6
6
|
import React from 'react';
|
|
7
7
|
|
|
8
|
-
import { type
|
|
8
|
+
import { type ReactiveEchoObject, getSpace } from '@dxos/client/echo';
|
|
9
9
|
import { useClient } from '@dxos/react-client';
|
|
10
10
|
import { DropdownMenu, toLocalizedString, useTranslation } from '@dxos/react-ui';
|
|
11
11
|
|
|
12
12
|
import { SPACE_PLUGIN } from '../meta';
|
|
13
13
|
import { getSpaceDisplayName } from '../util';
|
|
14
14
|
|
|
15
|
-
export const MenuFooter = ({ object }: { object:
|
|
15
|
+
export const MenuFooter = ({ object }: { object: ReactiveEchoObject<any> }) => {
|
|
16
16
|
const { t } = useTranslation(SPACE_PLUGIN);
|
|
17
17
|
const client = useClient();
|
|
18
18
|
const space = getSpace(object);
|
package/src/util.tsx
CHANGED
|
@@ -33,7 +33,7 @@ import {
|
|
|
33
33
|
isEchoObject,
|
|
34
34
|
isSpace,
|
|
35
35
|
type Echo,
|
|
36
|
-
type
|
|
36
|
+
type ReactiveEchoObject,
|
|
37
37
|
type FilterSource,
|
|
38
38
|
type Query,
|
|
39
39
|
type QueryOptions,
|
|
@@ -59,7 +59,7 @@ const EMPTY_ARRAY: never[] = [];
|
|
|
59
59
|
* @param options
|
|
60
60
|
* @returns
|
|
61
61
|
*/
|
|
62
|
-
export const memoizeQuery = <T extends
|
|
62
|
+
export const memoizeQuery = <T extends ReactiveEchoObject<any>>(
|
|
63
63
|
spaceOrEcho?: Space | Echo,
|
|
64
64
|
filter?: FilterSource<T>,
|
|
65
65
|
options?: QueryOptions,
|
|
@@ -111,7 +111,7 @@ const getCollectionGraphNodePartials = ({
|
|
|
111
111
|
// Change on disk.
|
|
112
112
|
collection.objects = nextOrder.filter(isEchoObject);
|
|
113
113
|
},
|
|
114
|
-
onTransferStart: (child: Node<
|
|
114
|
+
onTransferStart: (child: Node<ReactiveEchoObject<any>>, index?: number) => {
|
|
115
115
|
// TODO(wittjosiah): Support transfer between spaces.
|
|
116
116
|
// const childSpace = getSpace(child.data);
|
|
117
117
|
// if (space && childSpace && !childSpace.key.equals(space.key)) {
|
|
@@ -139,7 +139,7 @@ const getCollectionGraphNodePartials = ({
|
|
|
139
139
|
|
|
140
140
|
// }
|
|
141
141
|
},
|
|
142
|
-
onTransferEnd: (child: Node<
|
|
142
|
+
onTransferEnd: (child: Node<ReactiveEchoObject<any>>, destination: Node) => {
|
|
143
143
|
// Remove child from origin collection.
|
|
144
144
|
const index = collection.objects.indexOf(child.data);
|
|
145
145
|
if (index > -1) {
|
|
@@ -155,7 +155,7 @@ const getCollectionGraphNodePartials = ({
|
|
|
155
155
|
// childSpace.db.remove(child.data);
|
|
156
156
|
// }
|
|
157
157
|
},
|
|
158
|
-
onCopy: async (child: Node<
|
|
158
|
+
onCopy: async (child: Node<ReactiveEchoObject<any>>, index?: number) => {
|
|
159
159
|
// Create clone of child and add to destination space.
|
|
160
160
|
const newObject = await cloneObject(child.data, resolve, space);
|
|
161
161
|
space.db.add(newObject);
|
|
@@ -200,6 +200,7 @@ export const constructSpaceNode = ({
|
|
|
200
200
|
return {
|
|
201
201
|
id: space.id,
|
|
202
202
|
type: SPACE_TYPE,
|
|
203
|
+
cacheable: ['label', 'icon', 'role'],
|
|
203
204
|
data: space,
|
|
204
205
|
properties: {
|
|
205
206
|
...partials,
|
|
@@ -412,7 +413,7 @@ export const createObjectNode = ({
|
|
|
412
413
|
navigable = false,
|
|
413
414
|
resolve,
|
|
414
415
|
}: {
|
|
415
|
-
object:
|
|
416
|
+
object: ReactiveEchoObject<any>;
|
|
416
417
|
space: Space;
|
|
417
418
|
navigable?: boolean;
|
|
418
419
|
resolve: MetadataResolver;
|
|
@@ -435,6 +436,7 @@ export const createObjectNode = ({
|
|
|
435
436
|
return {
|
|
436
437
|
id: fullyQualifiedId(object),
|
|
437
438
|
type,
|
|
439
|
+
cacheable: ['label', 'icon', 'role'],
|
|
438
440
|
data: object,
|
|
439
441
|
properties: {
|
|
440
442
|
...partials,
|
|
@@ -454,7 +456,7 @@ export const constructObjectActionGroups = ({
|
|
|
454
456
|
navigable,
|
|
455
457
|
dispatch,
|
|
456
458
|
}: {
|
|
457
|
-
object:
|
|
459
|
+
object: ReactiveEchoObject<any>;
|
|
458
460
|
navigable: boolean;
|
|
459
461
|
dispatch: IntentDispatcher;
|
|
460
462
|
}) => {
|
|
@@ -512,7 +514,7 @@ export const constructObjectActions = ({
|
|
|
512
514
|
node,
|
|
513
515
|
dispatch,
|
|
514
516
|
}: {
|
|
515
|
-
node: Node<
|
|
517
|
+
node: Node<ReactiveEchoObject<any>>;
|
|
516
518
|
dispatch: IntentDispatcher;
|
|
517
519
|
}) => {
|
|
518
520
|
const object = node.data;
|
|
@@ -601,9 +603,9 @@ export const getActiveSpace = (graph: Graph, active?: string) => {
|
|
|
601
603
|
* @deprecated This is a temporary solution.
|
|
602
604
|
*/
|
|
603
605
|
export const getNestedObjects = async (
|
|
604
|
-
object:
|
|
606
|
+
object: ReactiveEchoObject<any>,
|
|
605
607
|
resolve: MetadataResolver,
|
|
606
|
-
): Promise<
|
|
608
|
+
): Promise<ReactiveEchoObject<any>[]> => {
|
|
607
609
|
const type = getTypename(object);
|
|
608
610
|
if (!type) {
|
|
609
611
|
return [];
|
|
@@ -615,7 +617,7 @@ export const getNestedObjects = async (
|
|
|
615
617
|
return [];
|
|
616
618
|
}
|
|
617
619
|
|
|
618
|
-
const objects:
|
|
620
|
+
const objects: ReactiveEchoObject<any>[] = await loadReferences(object);
|
|
619
621
|
const nested = await Promise.all(objects.map((object) => getNestedObjects(object, resolve)));
|
|
620
622
|
return [...objects, ...nested.flat()];
|
|
621
623
|
};
|